mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-09-13 20:39:38 +02:00
feat: add accessibility title and description to pie chart
* Reuse the title as the title element * Add description to the parser and then render
This commit is contained in:
@@ -20,6 +20,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
<div class="mermaid">
|
||||||
|
pie
|
||||||
|
title Key elements in Product X
|
||||||
|
accDescription This is a pie chart showing the key elements in Product X.
|
||||||
|
"Calcium" : 42.96
|
||||||
|
"Potassium" : 50.05
|
||||||
|
"Magnesium" : 10.01
|
||||||
|
"Iron" : 5
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mermaid">
|
<div class="mermaid">
|
||||||
gantt
|
gantt
|
||||||
|
25
src/accessibility.js
Normal file
25
src/accessibility.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* This method will add a basic title and description element to a chart. The yy parser will need to
|
||||||
|
* respond to getTitle and getAccDescription, where the title is the title element on the chart,
|
||||||
|
* which is not displayed and the accDescription is the description element on the chart, which is
|
||||||
|
* also not displayed.
|
||||||
|
*
|
||||||
|
* @param yy_parser
|
||||||
|
* @param svg
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export default function addSVGAccessibilityFields(yy_parser, svg, id) {
|
||||||
|
let title_string = yy_parser.getTitle();
|
||||||
|
let description = yy_parser.getAccDescription();
|
||||||
|
svg.attr('role', 'img').attr('aria-labelledby', 'chart-title-' + id + ' chart-desc-' + id);
|
||||||
|
|
||||||
|
svg
|
||||||
|
.insert('desc', ':first-child')
|
||||||
|
.attr('id', 'chart-desc-' + id)
|
||||||
|
.text(description);
|
||||||
|
|
||||||
|
svg
|
||||||
|
.insert('title', ':first-child')
|
||||||
|
.attr('id', 'chart-desc-' + id)
|
||||||
|
.text(title_string);
|
||||||
|
}
|
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
%x string
|
%x string
|
||||||
%x title
|
%x title
|
||||||
|
%x accDescription
|
||||||
%x open_directive
|
%x open_directive
|
||||||
%x type_directive
|
%x type_directive
|
||||||
%x arg_directive
|
%x arg_directive
|
||||||
@@ -26,6 +27,8 @@
|
|||||||
[\s]+ /* ignore */
|
[\s]+ /* ignore */
|
||||||
title { this.begin("title");return 'title'; }
|
title { this.begin("title");return 'title'; }
|
||||||
<title>(?!\n|;|#)*[^\n]* { this.popState(); return "title_value"; }
|
<title>(?!\n|;|#)*[^\n]* { this.popState(); return "title_value"; }
|
||||||
|
accDescription { this.begin("accDescription");return 'accDescription'; }
|
||||||
|
<accDescription>(?!\n|;|#)*[^\n]* { this.popState(); return "description_value"; }
|
||||||
["] { this.begin("string"); }
|
["] { this.begin("string"); }
|
||||||
<string>["] { this.popState(); }
|
<string>["] { this.popState(); }
|
||||||
<string>[^"]* { return "txt"; }
|
<string>[^"]* { return "txt"; }
|
||||||
@@ -34,7 +37,6 @@ title { this.begin("ti
|
|||||||
":"[\s]*[\d]+(?:\.[\d]+)? return "value";
|
":"[\s]*[\d]+(?:\.[\d]+)? return "value";
|
||||||
<<EOF>> return 'EOF';
|
<<EOF>> return 'EOF';
|
||||||
|
|
||||||
|
|
||||||
/lex
|
/lex
|
||||||
|
|
||||||
%start start
|
%start start
|
||||||
@@ -61,6 +63,7 @@ statement
|
|||||||
:
|
:
|
||||||
| txt value { yy.addSection($1,yy.cleanupValue($2)); }
|
| txt value { yy.addSection($1,yy.cleanupValue($2)); }
|
||||||
| title title_value { $$=$2.trim();yy.setTitle($$); }
|
| title title_value { $$=$2.trim();yy.setTitle($$); }
|
||||||
|
| accDescription description_value { $$=$2.trim();yy.setAccDescription($$); }
|
||||||
| directive
|
| directive
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@@ -62,6 +62,37 @@ pie
|
|||||||
expect(title).toBe('a 60/40 pie');
|
expect(title).toBe('a 60/40 pie');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle simple pie without an acc description', function () {
|
||||||
|
const res = pie.parser.parse(`pie title a neat chart
|
||||||
|
"ash" : 60
|
||||||
|
"bat" : 40
|
||||||
|
`);
|
||||||
|
|
||||||
|
const sections = pieDb.getSections();
|
||||||
|
const title = pieDb.getTitle();
|
||||||
|
const description = pieDb.getAccDescription();
|
||||||
|
const section1 = sections['ash'];
|
||||||
|
expect(section1).toBe(60);
|
||||||
|
expect(title).toBe('a neat chart');
|
||||||
|
expect(description).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle simple pie with an acc description', function () {
|
||||||
|
const res = pie.parser.parse(`pie title a neat chart
|
||||||
|
accDescription a neat description
|
||||||
|
"ash" : 60
|
||||||
|
"bat" : 40
|
||||||
|
`);
|
||||||
|
|
||||||
|
const sections = pieDb.getSections();
|
||||||
|
const title = pieDb.getTitle();
|
||||||
|
const description = pieDb.getAccDescription();
|
||||||
|
const section1 = sections['ash'];
|
||||||
|
expect(section1).toBe(60);
|
||||||
|
expect(title).toBe('a neat chart');
|
||||||
|
expect(description).toBe('a neat description');
|
||||||
|
});
|
||||||
|
|
||||||
it('should handle simple pie with positive decimal', function () {
|
it('should handle simple pie with positive decimal', function () {
|
||||||
const res = pie.parser.parse(`pie
|
const res = pie.parser.parse(`pie
|
||||||
"ash" : 60.67
|
"ash" : 60.67
|
||||||
|
@@ -4,6 +4,7 @@ import * as configApi from '../../config';
|
|||||||
|
|
||||||
let sections = {};
|
let sections = {};
|
||||||
let title = '';
|
let title = '';
|
||||||
|
let description = '';
|
||||||
let showData = false;
|
let showData = false;
|
||||||
|
|
||||||
export const parseDirective = function (statement, context, type) {
|
export const parseDirective = function (statement, context, type) {
|
||||||
@@ -33,6 +34,15 @@ const getShowData = function () {
|
|||||||
const getTitle = function () {
|
const getTitle = function () {
|
||||||
return title;
|
return title;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setAccDescription = function (txt) {
|
||||||
|
description = txt;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAccDescription = function () {
|
||||||
|
return description;
|
||||||
|
};
|
||||||
|
|
||||||
const cleanupValue = function (value) {
|
const cleanupValue = function (value) {
|
||||||
if (value.substring(0, 1) === ':') {
|
if (value.substring(0, 1) === ':') {
|
||||||
value = value.substring(1).trim();
|
value = value.substring(1).trim();
|
||||||
@@ -62,5 +72,7 @@ export default {
|
|||||||
getTitle,
|
getTitle,
|
||||||
setShowData,
|
setShowData,
|
||||||
getShowData,
|
getShowData,
|
||||||
|
getAccDescription,
|
||||||
|
setAccDescription,
|
||||||
// parseError
|
// parseError
|
||||||
};
|
};
|
||||||
|
@@ -5,6 +5,7 @@ import pieParser from './parser/pie';
|
|||||||
import { log } from '../../logger';
|
import { log } from '../../logger';
|
||||||
import { configureSvgSize } from '../../utils';
|
import { configureSvgSize } from '../../utils';
|
||||||
import * as configApi from '../../config';
|
import * as configApi from '../../config';
|
||||||
|
import addSVGAccessibilityFields from '../../accessibility';
|
||||||
|
|
||||||
let conf = configApi.getConfig();
|
let conf = configApi.getConfig();
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ export const draw = (txt, id) => {
|
|||||||
const diagram = select('#' + id);
|
const diagram = select('#' + id);
|
||||||
configureSvgSize(diagram, height, width, conf.pie.useMaxWidth);
|
configureSvgSize(diagram, height, width, conf.pie.useMaxWidth);
|
||||||
|
|
||||||
|
addSVGAccessibilityFields(parser.yy, diagram, id);
|
||||||
// Set viewBox
|
// Set viewBox
|
||||||
elem.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
|
elem.setAttribute('viewBox', '0 0 ' + width + ' ' + height);
|
||||||
|
|
||||||
|
@@ -42,6 +42,7 @@ import infoParser from './diagrams/info/parser/info';
|
|||||||
import pieParser from './diagrams/pie/parser/pie';
|
import pieParser from './diagrams/pie/parser/pie';
|
||||||
import pieDb from './diagrams/pie/pieDb';
|
import pieDb from './diagrams/pie/pieDb';
|
||||||
import pieRenderer from './diagrams/pie/pieRenderer';
|
import pieRenderer from './diagrams/pie/pieRenderer';
|
||||||
|
import addSVGAccessibilityFields from './diagrams/pie/pieRenderer';
|
||||||
import requirementParser from './diagrams/requirement/parser/requirementDiagram';
|
import requirementParser from './diagrams/requirement/parser/requirementDiagram';
|
||||||
import requirementDb from './diagrams/requirement/requirementDb';
|
import requirementDb from './diagrams/requirement/requirementDb';
|
||||||
import requirementRenderer from './diagrams/requirement/requirementRenderer';
|
import requirementRenderer from './diagrams/requirement/requirementRenderer';
|
||||||
|
Reference in New Issue
Block a user