mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-14 06:43:25 +08:00
Merge pull request #2912 from el-mapache/feat/gantt-diagram-accessibility
Adds accDescription to Gantt, draws tags to svg
This commit is contained in:
commit
266bce45f2
@ -291,4 +291,36 @@ describe('Gantt diagram', () => {
|
||||
{ gantt: { topAxis: true } }
|
||||
);
|
||||
});
|
||||
|
||||
it('should render accessibility tags', function () {
|
||||
const expectedTitle = 'Gantt Diagram';
|
||||
const expectedAccDescription = 'Tasks for Q4';
|
||||
renderGraph(
|
||||
`
|
||||
gantt
|
||||
title ${expectedTitle}
|
||||
accDescription ${expectedAccDescription}
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
A task :a1, 2014-01-01, 30d
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg').should((svg) => {
|
||||
const el = svg.get(0);
|
||||
const children = Array.from(el.children);
|
||||
|
||||
const titleEl = children.find(function (node) {
|
||||
return node.tagName === 'title';
|
||||
});
|
||||
const descriptionEl = children.find(function (node) {
|
||||
return node.tagName === 'desc';
|
||||
});
|
||||
|
||||
expect(titleEl).to.exist;
|
||||
expect(titleEl.textContent).to.equal(expectedTitle);
|
||||
expect(descriptionEl).to.exist;
|
||||
expect(descriptionEl.textContent).to.equal(expectedAccDescription);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
43
demos/gantt.html
Normal file
43
demos/gantt.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Mermaid Quick Test Page</title>
|
||||
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
|
||||
<style>
|
||||
div.mermaid {
|
||||
font-family: 'Courier New', Courier, monospace !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- accDescription Tasks for Q4 -->
|
||||
<div class="mermaid">
|
||||
gantt
|
||||
title A Gantt Diagram
|
||||
accDescription Remaining Q4 Tasks
|
||||
dateFormat YYYY-MM-DD
|
||||
section Section
|
||||
A task :a1, 2014-01-01, 30d
|
||||
Another task :after a1 , 20d
|
||||
section Another
|
||||
Task in sec :2014-01-12 , 12d
|
||||
another task : 24d
|
||||
</div>
|
||||
|
||||
<script src="./mermaid.js"></script>
|
||||
<script>
|
||||
mermaid.initialize({
|
||||
logLevel: 3,
|
||||
securityLevel: 'loose',
|
||||
gantt: { axisFormat: '%m/%d/%Y' },
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1,17 +1,21 @@
|
||||
/**
|
||||
* 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.
|
||||
* which is generally not displayed and the accDescription is the description element on the chart,
|
||||
* which is never displayed.
|
||||
*
|
||||
* The following charts display their title as a visual and accessibility element:
|
||||
* gantt
|
||||
*
|
||||
* @param yy_parser
|
||||
* @param svg
|
||||
* @param id
|
||||
*/
|
||||
export default function addSVGAccessibilityFields(yy_parser, svg, id) {
|
||||
if (typeof svg.insert == 'undefined') {
|
||||
if (typeof svg.insert === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
let title_string = yy_parser.getTitle();
|
||||
let description = yy_parser.getAccDescription();
|
||||
svg.attr('role', 'img').attr('aria-labelledby', 'chart-title-' + id + ' chart-desc-' + id);
|
||||
|
@ -4,6 +4,7 @@ import { log } from '../../logger';
|
||||
import * as configApi from '../../config';
|
||||
import utils from '../../utils';
|
||||
import mermaidAPI from '../../mermaidAPI';
|
||||
import common from '../common/common';
|
||||
|
||||
let dateFormat = '';
|
||||
let axisFormat = '';
|
||||
@ -12,6 +13,7 @@ let includes = [];
|
||||
let excludes = [];
|
||||
let links = {};
|
||||
let title = '';
|
||||
let accDescription = '';
|
||||
let sections = [];
|
||||
let tasks = [];
|
||||
let currentSection = '';
|
||||
@ -23,6 +25,10 @@ let topAxis = false;
|
||||
// The serial order of the task in the script
|
||||
let lastOrder = 0;
|
||||
|
||||
const sanitizeText = function (txt) {
|
||||
return common.sanitizeText(txt, configApi.getConfig());
|
||||
};
|
||||
|
||||
export const parseDirective = function (statement, context, type) {
|
||||
mermaidAPI.parseDirective(this, statement, context, type);
|
||||
};
|
||||
@ -108,13 +114,21 @@ export const getLinks = function () {
|
||||
};
|
||||
|
||||
export const setTitle = function (txt) {
|
||||
title = txt;
|
||||
title = sanitizeText(txt);
|
||||
};
|
||||
|
||||
export const getTitle = function () {
|
||||
return title;
|
||||
};
|
||||
|
||||
export const setAccDescription = function (txt) {
|
||||
accDescription = sanitizeText(txt);
|
||||
};
|
||||
|
||||
export const getAccDescription = function () {
|
||||
return accDescription;
|
||||
};
|
||||
|
||||
export const addSection = function (txt) {
|
||||
currentSection = txt;
|
||||
sections.push(txt);
|
||||
@ -637,6 +651,8 @@ export default {
|
||||
getTodayMarker,
|
||||
setTitle,
|
||||
getTitle,
|
||||
setAccDescription,
|
||||
getAccDescription,
|
||||
addSection,
|
||||
getSections,
|
||||
getTasks,
|
||||
|
@ -32,6 +32,7 @@ describe('when using the ganttDb', function () {
|
||||
fn | expected
|
||||
${'getTasks'} | ${[]}
|
||||
${'getTitle'} | ${''}
|
||||
${'getAccDescription'} | ${''}
|
||||
${'getDateFormat'} | ${''}
|
||||
${'getAxisFormat'} | ${''}
|
||||
${'getTodayMarker'} | ${''}
|
||||
|
@ -15,6 +15,7 @@ import common from '../common/common';
|
||||
import ganttDb from './ganttDb';
|
||||
import { getConfig } from '../../config';
|
||||
import { configureSvgSize } from '../../utils';
|
||||
import addSVGAccessibilityFields from '../../accessibility'
|
||||
|
||||
parser.yy = ganttDb;
|
||||
export const setConf = function () {
|
||||
@ -114,6 +115,8 @@ export const draw = function (text, id) {
|
||||
.attr('y', conf.titleTopMargin)
|
||||
.attr('class', 'titleText');
|
||||
|
||||
addSVGAccessibilityFields(parser.yy, svg, id);
|
||||
|
||||
/**
|
||||
* @param tasks
|
||||
* @param pageWidth
|
||||
|
@ -65,22 +65,23 @@ that id.
|
||||
<click>[\s\n] this.popState();
|
||||
<click>[^\s\n]* return 'click';
|
||||
|
||||
"gantt" return 'gantt';
|
||||
"dateFormat"\s[^#\n;]+ return 'dateFormat';
|
||||
"inclusiveEndDates" return 'inclusiveEndDates';
|
||||
"topAxis" return 'topAxis';
|
||||
"axisFormat"\s[^#\n;]+ return 'axisFormat';
|
||||
"includes"\s[^#\n;]+ return 'includes';
|
||||
"excludes"\s[^#\n;]+ return 'excludes';
|
||||
"todayMarker"\s[^\n;]+ return 'todayMarker';
|
||||
\d\d\d\d"-"\d\d"-"\d\d return 'date';
|
||||
"title"\s[^#\n;]+ return 'title';
|
||||
"section"\s[^#:\n;]+ return 'section';
|
||||
[^#:\n;]+ return 'taskTxt';
|
||||
":"[^#\n;]+ return 'taskData';
|
||||
":" return ':';
|
||||
<<EOF>> return 'EOF';
|
||||
. return 'INVALID';
|
||||
"gantt" return 'gantt';
|
||||
"dateFormat"\s[^#\n;]+ return 'dateFormat';
|
||||
"inclusiveEndDates" return 'inclusiveEndDates';
|
||||
"topAxis" return 'topAxis';
|
||||
"axisFormat"\s[^#\n;]+ return 'axisFormat';
|
||||
"includes"\s[^#\n;]+ return 'includes';
|
||||
"excludes"\s[^#\n;]+ return 'excludes';
|
||||
"todayMarker"\s[^\n;]+ return 'todayMarker';
|
||||
\d\d\d\d"-"\d\d"-"\d\d return 'date';
|
||||
"title"\s[^#\n;]+ return 'title';
|
||||
"accDescription"\s[^#\n;]+ return 'accDescription'
|
||||
"section"\s[^#:\n;]+ return 'section';
|
||||
[^#:\n;]+ return 'taskTxt';
|
||||
":"[^#\n;]+ return 'taskData';
|
||||
":" return ':';
|
||||
<<EOF>> return 'EOF';
|
||||
. return 'INVALID';
|
||||
|
||||
/lex
|
||||
|
||||
@ -116,6 +117,7 @@ statement
|
||||
| includes {yy.setIncludes($1.substr(9));$$=$1.substr(9);}
|
||||
| todayMarker {yy.setTodayMarker($1.substr(12));$$=$1.substr(12);}
|
||||
| title {yy.setTitle($1.substr(6));$$=$1.substr(6);}
|
||||
| accDescription {yy.setAccDescription($1.substr(15));$$=$1.substr(15);}
|
||||
| section {yy.addSection($1.substr(8));$$=$1.substr(8);}
|
||||
| clickStatement
|
||||
| taskTxt taskData {yy.addTask($1,$2);$$='task';}
|
||||
|
@ -156,4 +156,21 @@ describe('when parsing a gantt diagram it', function () {
|
||||
'"test0", test1, test2'
|
||||
);
|
||||
});
|
||||
|
||||
it('should allow for a title and accDescription', function () {
|
||||
const expectedTitle = 'Gantt Diagram';
|
||||
const expectedAccDescription = 'Tasks for Q4';
|
||||
const ganttString =
|
||||
'gantt\n' +
|
||||
`title ${expectedTitle}\n` +
|
||||
`accDescription ${expectedAccDescription}\n` +
|
||||
'dateFormat YYYY-MM-DD\n' +
|
||||
'section Section\n' +
|
||||
'A task :a1, 2014-01-01, 30d\n';
|
||||
|
||||
const output = parser.parse(ganttString);
|
||||
|
||||
expect(ganttDb.getTitle()).toBe(expectedTitle);
|
||||
expect(ganttDb.getAccDescription()).toBe(expectedAccDescription);
|
||||
});
|
||||
});
|
||||
|
@ -21,7 +21,7 @@ describe('when parsing a sequenceDiagram', function () {
|
||||
parser.yy = sequenceDb;
|
||||
parser.yy.clear();
|
||||
});
|
||||
it('it should handle a sequenceDiagram definition', function () {
|
||||
it('should handle a sequenceDiagram definition', function () {
|
||||
const str = `
|
||||
sequenceDiagram
|
||||
Alice->Bob:Hello Bob, how are you?
|
||||
|
Loading…
x
Reference in New Issue
Block a user