diff --git a/cypress/integration/rendering/gantt.spec.js b/cypress/integration/rendering/gantt.spec.js
index dd521f779..c77c26109 100644
--- a/cypress/integration/rendering/gantt.spec.js
+++ b/cypress/integration/rendering/gantt.spec.js
@@ -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);
+ });
+ });
});
diff --git a/demos/gantt.html b/demos/gantt.html
new file mode 100644
index 000000000..68bf4a961
--- /dev/null
+++ b/demos/gantt.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+Mermaid Quick Test Page
+
+
+
+
+
+
+
+
+gantt
+ title A Gantt Diagram
+
+ 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
+
+
+
+
+
+
+
+
diff --git a/src/accessibility.js b/src/accessibility.js
index 046fea6ad..05720500b 100644
--- a/src/accessibility.js
+++ b/src/accessibility.js
@@ -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);
diff --git a/src/diagrams/gantt/ganttDb.js b/src/diagrams/gantt/ganttDb.js
index 88c591520..0d4bd594d 100644
--- a/src/diagrams/gantt/ganttDb.js
+++ b/src/diagrams/gantt/ganttDb.js
@@ -12,6 +12,7 @@ let includes = [];
let excludes = [];
let links = {};
let title = '';
+let accDescription = '';
let sections = [];
let tasks = [];
let currentSection = '';
@@ -115,6 +116,14 @@ export const getTitle = function () {
return title;
};
+export const setAccDescription = function (txt) {
+ accDescription = txt;
+};
+
+export const getAccDescription = function () {
+ return accDescription;
+};
+
export const addSection = function (txt) {
currentSection = txt;
sections.push(txt);
@@ -637,6 +646,8 @@ export default {
getTodayMarker,
setTitle,
getTitle,
+ setAccDescription,
+ getAccDescription,
addSection,
getSections,
getTasks,
diff --git a/src/diagrams/gantt/ganttDb.spec.js b/src/diagrams/gantt/ganttDb.spec.js
index b94ba9617..a6960aaf2 100644
--- a/src/diagrams/gantt/ganttDb.spec.js
+++ b/src/diagrams/gantt/ganttDb.spec.js
@@ -32,6 +32,7 @@ describe('when using the ganttDb', function () {
fn | expected
${'getTasks'} | ${[]}
${'getTitle'} | ${''}
+ ${'getAccDescription'} | ${''}
${'getDateFormat'} | ${''}
${'getAxisFormat'} | ${''}
${'getTodayMarker'} | ${''}
diff --git a/src/diagrams/gantt/ganttRenderer.js b/src/diagrams/gantt/ganttRenderer.js
index 899c61e02..b9a253ae1 100644
--- a/src/diagrams/gantt/ganttRenderer.js
+++ b/src/diagrams/gantt/ganttRenderer.js
@@ -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
diff --git a/src/diagrams/gantt/parser/gantt.jison b/src/diagrams/gantt/parser/gantt.jison
index a206da0b1..e6390c250 100644
--- a/src/diagrams/gantt/parser/gantt.jison
+++ b/src/diagrams/gantt/parser/gantt.jison
@@ -65,22 +65,23 @@ that id.
[\s\n] this.popState();
[^\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 ':';
-<> 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 ':';
+<> 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';}
diff --git a/src/diagrams/gantt/parser/gantt.spec.js b/src/diagrams/gantt/parser/gantt.spec.js
index bb2a3a540..ca535ebb8 100644
--- a/src/diagrams/gantt/parser/gantt.spec.js
+++ b/src/diagrams/gantt/parser/gantt.spec.js
@@ -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);
+ });
});
diff --git a/src/diagrams/sequence/sequenceDiagram.spec.js b/src/diagrams/sequence/sequenceDiagram.spec.js
index aa73bf28a..06662c8be 100644
--- a/src/diagrams/sequence/sequenceDiagram.spec.js
+++ b/src/diagrams/sequence/sequenceDiagram.spec.js
@@ -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?