From 5f0c53c8a71427bad1426f5f976b5f61600bde7a Mon Sep 17 00:00:00 2001 From: darshanr0107 Date: Wed, 9 Jul 2025 20:02:18 +0530 Subject: [PATCH 1/4] fix excluded dates ignored in YYYY-MM-DD HH:mm:ss date format --- cypress/integration/rendering/gantt.spec.js | 14 +++++++++++++ .../src/diagrams/gantt/ganttRenderer.js | 20 ++++++++----------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/cypress/integration/rendering/gantt.spec.js b/cypress/integration/rendering/gantt.spec.js index 2cc67918c..ec33e01aa 100644 --- a/cypress/integration/rendering/gantt.spec.js +++ b/cypress/integration/rendering/gantt.spec.js @@ -647,6 +647,20 @@ describe('Gantt diagram', () => { ); }); + it('should render a gantt diagram excluding a specific date in YYYY-MM-DD HH:mm:ss format', () => { + imgSnapshotTest( + ` + gantt + dateFormat YYYY-MM-DD HH:mm:ss + excludes 2025-07-07 + section Section + A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30 + Another task:after a1, 20h + `, + {} + ); + }); + it("should render when there's a semicolon in the title", () => { imgSnapshotTest( ` diff --git a/packages/mermaid/src/diagrams/gantt/ganttRenderer.js b/packages/mermaid/src/diagrams/gantt/ganttRenderer.js index f5c8c2e38..0695544ce 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttRenderer.js +++ b/packages/mermaid/src/diagrams/gantt/ganttRenderer.js @@ -554,12 +554,14 @@ export const draw = function (text, id, version, diagObj) { return; } - const dateFormat = diagObj.db.getDateFormat(); + const normalizedExcludes = excludes.map((d) => dayjs(d).format('YYYY-MM-DD')); + const normalizedIncludes = includes.map((d) => dayjs(d).format('YYYY-MM-DD')); const excludeRanges = []; let range = null; let d = dayjs(minTime); while (d.valueOf() <= maxTime) { - if (diagObj.db.isInvalidDate(d, dateFormat, excludes, includes)) { + const dStr = d.format('YYYY-MM-DD'); + if (normalizedExcludes.includes(dStr) && !normalizedIncludes.includes(dStr)) { if (!range) { range = { start: d, @@ -581,17 +583,11 @@ export const draw = function (text, id, version, diagObj) { rectangles .append('rect') - .attr('id', function (d) { - return 'exclude-' + d.start.format('YYYY-MM-DD'); - }) - .attr('x', function (d) { - return timeScale(d.start) + theSidePad; - }) + .attr('id', (d) => 'exclude-' + d.start.format('YYYY-MM-DD')) + .attr('x', (d) => timeScale(d.start.startOf('day')) + theSidePad) .attr('y', conf.gridLineStartPadding) - .attr('width', function (d) { - const renderEnd = d.end.add(1, 'day'); - return timeScale(renderEnd) - timeScale(d.start); - }) + .attr('width', (d) => timeScale(d.end.endOf('day')) - timeScale(d.start.startOf('day'))) + .attr('height', h - theTopPad - conf.gridLineStartPadding) .attr('transform-origin', function (d, i) { return ( From fce7cabb71d68a20a66246fe23d066512126a412 Mon Sep 17 00:00:00 2001 From: darshanr0107 Date: Wed, 9 Jul 2025 20:18:49 +0530 Subject: [PATCH 2/4] add changeset --- .changeset/fuzzy-pears-cough.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fuzzy-pears-cough.md diff --git a/.changeset/fuzzy-pears-cough.md b/.changeset/fuzzy-pears-cough.md new file mode 100644 index 000000000..3d3af19ff --- /dev/null +++ b/.changeset/fuzzy-pears-cough.md @@ -0,0 +1,5 @@ +--- +'mermaid': patch +--- + +Fix: an issue where exclude dates in Gantt charts were ignored when using dateFormat: 'YYYY-MM-DD HH:mm:ss'. From 35a92efcdcc8eb990703f948a20556577856253c Mon Sep 17 00:00:00 2001 From: darshanr0107 Date: Thu, 10 Jul 2025 15:49:53 +0530 Subject: [PATCH 3/4] resolve PR comments --- cypress/integration/rendering/gantt.spec.js | 29 +++++++++++++++++++ .../mermaid/src/diagrams/gantt/ganttDb.js | 7 +++-- .../src/diagrams/gantt/ganttRenderer.js | 6 ++-- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/cypress/integration/rendering/gantt.spec.js b/cypress/integration/rendering/gantt.spec.js index ec33e01aa..979c27540 100644 --- a/cypress/integration/rendering/gantt.spec.js +++ b/cypress/integration/rendering/gantt.spec.js @@ -661,6 +661,35 @@ describe('Gantt diagram', () => { ); }); + it('should render a gantt diagram excluding saturday and sunday in YYYY-MM-DD HH:mm:ss format', () => { + imgSnapshotTest( + ` + gantt + dateFormat YYYY-MM-DD HH:mm:ss + excludes weekends + weekend saturday + section Section + A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30 + Another task:after a1, 20h + `, + {} + ); + }); + it('should render a gantt diagram excluding friday and saturday in YYYY-MM-DD HH:mm:ss format', () => { + imgSnapshotTest( + ` + gantt + dateFormat YYYY-MM-DD HH:mm:ss + excludes weekends + weekend friday + section Section + A task :a1, 2025-07-04 20:30:30, 2025-07-08 10:30:30 + Another task:after a1, 20h + `, + {} + ); + }); + it("should render when there's a semicolon in the title", () => { imgSnapshotTest( ` diff --git a/packages/mermaid/src/diagrams/gantt/ganttDb.js b/packages/mermaid/src/diagrams/gantt/ganttDb.js index 3ae55fb25..b2b5b0566 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttDb.js +++ b/packages/mermaid/src/diagrams/gantt/ganttDb.js @@ -167,7 +167,10 @@ export const getTasks = function () { }; export const isInvalidDate = function (date, dateFormat, excludes, includes) { - if (includes.includes(date.format(dateFormat.trim()))) { + const formattedDate = date.format(dateFormat.trim()); + const dateOnly = date.format('YYYY-MM-DD'); + + if (includes.includes(formattedDate) || includes.includes(dateOnly)) { return false; } if ( @@ -180,7 +183,7 @@ export const isInvalidDate = function (date, dateFormat, excludes, includes) { if (excludes.includes(date.format('dddd').toLowerCase())) { return true; } - return excludes.includes(date.format(dateFormat.trim())); + return excludes.includes(formattedDate) || excludes.includes(dateOnly); }; export const setWeekday = function (txt) { diff --git a/packages/mermaid/src/diagrams/gantt/ganttRenderer.js b/packages/mermaid/src/diagrams/gantt/ganttRenderer.js index 0695544ce..dd4824d6b 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttRenderer.js +++ b/packages/mermaid/src/diagrams/gantt/ganttRenderer.js @@ -554,14 +554,12 @@ export const draw = function (text, id, version, diagObj) { return; } - const normalizedExcludes = excludes.map((d) => dayjs(d).format('YYYY-MM-DD')); - const normalizedIncludes = includes.map((d) => dayjs(d).format('YYYY-MM-DD')); + const dateFormat = diagObj.db.getDateFormat(); const excludeRanges = []; let range = null; let d = dayjs(minTime); while (d.valueOf() <= maxTime) { - const dStr = d.format('YYYY-MM-DD'); - if (normalizedExcludes.includes(dStr) && !normalizedIncludes.includes(dStr)) { + if (diagObj.db.isInvalidDate(d, dateFormat, excludes, includes)) { if (!range) { range = { start: d, From 1176d306688323592879b11199ecbf0b69255358 Mon Sep 17 00:00:00 2001 From: darshanr0107 Date: Wed, 16 Jul 2025 12:38:35 +0530 Subject: [PATCH 4/4] fix: update changeset on-behalf-of: @Mermaid-Chart --- .changeset/fuzzy-pears-cough.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/fuzzy-pears-cough.md b/.changeset/fuzzy-pears-cough.md index 3d3af19ff..6ed777506 100644 --- a/.changeset/fuzzy-pears-cough.md +++ b/.changeset/fuzzy-pears-cough.md @@ -2,4 +2,4 @@ 'mermaid': patch --- -Fix: an issue where exclude dates in Gantt charts were ignored when using dateFormat: 'YYYY-MM-DD HH:mm:ss'. +fix: handle exclude dates properly in Gantt charts when using dateFormat: 'YYYY-MM-DD HH:mm:ss'