From 03ce2810b53920d7de2b6fa6eae3e5bc1e7ac580 Mon Sep 17 00:00:00 2001 From: Lei Nelissen Date: Wed, 12 Jul 2023 17:23:21 +0200 Subject: [PATCH] feat: allow specifying on which weekday a tickInterval should start --- docs/syntax/gantt.md | 6 ++++ packages/mermaid/src/defaultConfig.ts | 1 + .../mermaid/src/diagrams/gantt/ganttDb.js | 12 +++++++ .../src/diagrams/gantt/ganttRenderer.js | 33 ++++++++++++++++++- .../src/diagrams/gantt/parser/gantt.jison | 2 ++ .../src/diagrams/gantt/parser/gantt.spec.js | 5 +++ 6 files changed, 58 insertions(+), 1 deletion(-) diff --git a/docs/syntax/gantt.md b/docs/syntax/gantt.md index 8e64a268a..ef40aef0f 100644 --- a/docs/syntax/gantt.md +++ b/docs/syntax/gantt.md @@ -257,6 +257,12 @@ The pattern is: More info in: +Week-based `tickInterval`s start the week on sunday by default. If you wish to specify another weekday on which the `tickInterval` should start, use the `weekday` option: + +```markdown +weekday monday +``` + ## Output in compact mode The compact mode allows you to display multiple tasks in the same row. Compact mode can be enabled for a gantt chart by setting the display mode of the graph via preceeding YAML settings. diff --git a/packages/mermaid/src/defaultConfig.ts b/packages/mermaid/src/defaultConfig.ts index 62b361cff..28454e353 100644 --- a/packages/mermaid/src/defaultConfig.ts +++ b/packages/mermaid/src/defaultConfig.ts @@ -50,6 +50,7 @@ const config: Partial = { ...defaultConfigJson.gantt, tickInterval: undefined, useWidth: undefined, // can probably be removed since `configKeys` already includes this + weekday: 'sunday', // the sane default is a monday, but it's set to sunday for legacy reasons }, c4: { ...defaultConfigJson.c4, diff --git a/packages/mermaid/src/diagrams/gantt/ganttDb.js b/packages/mermaid/src/diagrams/gantt/ganttDb.js index 396402702..339cb65ec 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttDb.js +++ b/packages/mermaid/src/diagrams/gantt/ganttDb.js @@ -37,6 +37,7 @@ const tags = ['active', 'done', 'crit', 'milestone']; let funs = []; let inclusiveEndDates = false; let topAxis = false; +let weekday = undefined; // The serial order of the task in the script let lastOrder = 0; @@ -66,6 +67,7 @@ export const clear = function () { lastOrder = 0; links = {}; commonClear(); + weekday = undefined; }; export const setAxisFormat = function (txt) { @@ -179,6 +181,14 @@ export const isInvalidDate = function (date, dateFormat, excludes, includes) { return excludes.includes(date.format(dateFormat.trim())); }; +export const setWeekday = function (txt) { + weekday = txt; +}; + +export const getWeekday = function () { + return weekday; +}; + /** * TODO: fully document what this function does and what types it accepts * @@ -759,6 +769,8 @@ export default { bindFunctions, parseDuration, isInvalidDate, + setWeekday, + getWeekday, }; /** diff --git a/packages/mermaid/src/diagrams/gantt/ganttRenderer.js b/packages/mermaid/src/diagrams/gantt/ganttRenderer.js index 6e34276ed..05ff7f8a9 100644 --- a/packages/mermaid/src/diagrams/gantt/ganttRenderer.js +++ b/packages/mermaid/src/diagrams/gantt/ganttRenderer.js @@ -14,6 +14,12 @@ import { timeHour, timeDay, timeMonday, + timeTuesday, + timeWednesday, + timeThursday, + timeFriday, + timeSaturday, + timeSunday, timeMonth, } from 'd3'; import common from '../common/common.js'; @@ -561,6 +567,8 @@ export const draw = function (text, id, version, diagObj) { if (resultTickInterval !== null) { const every = resultTickInterval[1]; const interval = resultTickInterval[2]; + const weekday = diagObj.db.getWeekday() || conf.weekday; + switch (interval) { case 'minute': bottomXAxis.ticks(timeMinute.every(every)); @@ -572,7 +580,30 @@ export const draw = function (text, id, version, diagObj) { bottomXAxis.ticks(timeDay.every(every)); break; case 'week': - bottomXAxis.ticks(timeMonday.every(every)); + switch (weekday) { + case 'monday': + bottomXAxis.ticks(timeMonday.every(every)); + break; + case 'tuesday': + bottomXAxis.ticks(timeTuesday.every(every)); + break; + case 'wednesday': + bottomXAxis.ticks(timeWednesday.every(every)); + break; + case 'thursday': + bottomXAxis.ticks(timeThursday.every(every)); + break; + case 'friday': + bottomXAxis.ticks(timeFriday.every(every)); + break; + case 'saturday': + bottomXAxis.ticks(timeSaturday.every(every)); + break; + case 'sunday': + default: + bottomXAxis.ticks(timeSunday.every(every)); + break; + } break; case 'month': bottomXAxis.ticks(timeMonth.every(every)); diff --git a/packages/mermaid/src/diagrams/gantt/parser/gantt.jison b/packages/mermaid/src/diagrams/gantt/parser/gantt.jison index 0eb45ec41..d83baeea9 100644 --- a/packages/mermaid/src/diagrams/gantt/parser/gantt.jison +++ b/packages/mermaid/src/diagrams/gantt/parser/gantt.jison @@ -86,6 +86,7 @@ that id. "includes"\s[^#\n;]+ return 'includes'; "excludes"\s[^#\n;]+ return 'excludes'; "todayMarker"\s[^\n;]+ return 'todayMarker'; +"weekday"\s[^#\n;]+ return 'weekday'; \d\d\d\d"-"\d\d"-"\d\d return 'date'; "title"\s[^#\n;]+ return 'title'; "accDescription"\s[^#\n;]+ return 'accDescription' @@ -130,6 +131,7 @@ statement | excludes {yy.setExcludes($1.substr(9));$$=$1.substr(9);} | includes {yy.setIncludes($1.substr(9));$$=$1.substr(9);} | todayMarker {yy.setTodayMarker($1.substr(12));$$=$1.substr(12);} + | weekday { yy.setWeekday($1.substr(8));$$=$1.substr(8);} | title {yy.setDiagramTitle($1.substr(6));$$=$1.substr(6);} | acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); } | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } diff --git a/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js b/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js index 020bab0ed..575833399 100644 --- a/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js +++ b/packages/mermaid/src/diagrams/gantt/parser/gantt.spec.js @@ -180,4 +180,9 @@ row2`; expect(ganttDb.getAccTitle()).toBe(expectedTitle); expect(ganttDb.getAccDescription()).toBe(expectedAccDescription); }); + + it('should allow for customising the weekday for tick intervals', function () { + parser.parse('gantt\nweekday wednesday'); + expect(ganttDb.getWeekday()).toBe('wednesday'); + }); });