feat(gantt): Add option 'tickInterval' for custom tick interval

See issue #1598
This commit is contained in:
DarkNami
2022-10-27 16:43:44 +08:00
parent 2e571a18bd
commit 3166f689f9
8 changed files with 236 additions and 0 deletions

View File

@@ -341,4 +341,130 @@ describe('Gantt diagram', () => {
expect(descriptionEl.textContent).to.equal(expectedAccDescription);
});
});
it('should render a gantt diagram with tick is 15 minutes', () => {
imgSnapshotTest(
`
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
axisFormat %H:%M
tickInterval 15minute
excludes weekends
section Section
A task : a1, 2022-10-03, 6h
Another task : after a1, 6h
section Another
Task in sec : 2022-10-03, 3h
another task : 3h
`,
{}
);
});
it('should render a gantt diagram with tick is 6 hours', () => {
imgSnapshotTest(
`
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
axisFormat %d %H:%M
tickInterval 6hour
excludes weekends
section Section
A task : a1, 2022-10-03, 1d
Another task : after a1, 2d
section Another
Task in sec : 2022-10-04, 2d
another task : 2d
`,
{}
);
});
it('should render a gantt diagram with tick is 1 day', () => {
imgSnapshotTest(
`
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
axisFormat %m-%d
tickInterval 1day
excludes weekends
section Section
A task : a1, 2022-10-01, 30d
Another task : after a1, 20d
section Another
Task in sec : 2022-10-20, 12d
another task : 24d
`,
{}
);
});
it('should render a gantt diagram with tick is 1 week', () => {
imgSnapshotTest(
`
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
axisFormat %m-%d
tickInterval 1week
excludes weekends
section Section
A task : a1, 2022-10-01, 30d
Another task : after a1, 20d
section Another
Task in sec : 2022-10-20, 12d
another task : 24d
`,
{}
);
});
it('should render a gantt diagram with tick is 1 month', () => {
imgSnapshotTest(
`
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
axisFormat %m-%d
tickInterval 1month
excludes weekends
section Section
A task : a1, 2022-10-01, 30d
Another task : after a1, 20d
section Another
Task in sec : 2022-10-20, 12d
another task : 24d
`,
{}
);
});
it('should render a gantt diagram with tick is 1 day and topAxis is true', () => {
imgSnapshotTest(
`
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
axisFormat %m-%d
tickInterval 1day
excludes weekends
section Section
A task : a1, 2022-10-01, 30d
Another task : after a1, 20d
section Another
Task in sec : 2022-10-20, 12d
another task : 24d
`,
{ gantt: { topAxis: true } }
);
});
});

View File

@@ -230,6 +230,18 @@ The following formatting strings are supported:
More info in: https://github.com/mbostock/d3/wiki/Time-Formatting
### Axis ticks
The default output ticks are auto. You can custom your `tickInterval`, like `1day` or `1week`.
tickInterval 1day
The pattern is:
/^([1-9][0-9]*)(minute|hour|day|week|month)$/
More info in: <https://github.com/d3/d3-time#interval_every>
## Comments
Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax

View File

@@ -297,6 +297,7 @@ export interface GanttDiagramConfig extends BaseDiagramConfig {
sectionFontSize?: string | number;
numberSectionStyles?: number;
axisFormat?: string;
tickInterval?: string;
topAxis?: boolean;
}

View File

@@ -661,6 +661,19 @@ const config: Partial<MermaidConfig> = {
*/
axisFormat: '%Y-%m-%d',
/**
* | Parameter | Description | Type | Required | Values |
* | ------------ | ------------| ------ | -------- | ------- |
* | tickInterval | axis ticks | string | Optional | string |
*
* **Notes:**
*
* Pattern is /^([1-9][0-9]*)(minute|hour|day|week|month)$/
*
* Default value: undefined
*/
tickInterval: undefined,
/**
* | Parameter | Description | Type | Required | Values |
* | ----------- | ----------- | ------- | -------- | ----------- |

View File

@@ -17,6 +17,7 @@ import {
let dateFormat = '';
let axisFormat = '';
let tickInterval = undefined;
let todayMarker = '';
let includes = [];
let excludes = [];
@@ -47,6 +48,7 @@ export const clear = function () {
rawTasks = [];
dateFormat = '';
axisFormat = '';
tickInterval = undefined;
todayMarker = '';
includes = [];
excludes = [];
@@ -65,6 +67,14 @@ export const getAxisFormat = function () {
return axisFormat;
};
export const setTickInterval = function (txt) {
tickInterval = txt;
};
export const getTickInterval = function () {
return tickInterval;
};
export const setTodayMarker = function (txt) {
todayMarker = txt;
};
@@ -647,6 +657,8 @@ export default {
topAxisEnabled,
setAxisFormat,
getAxisFormat,
setTickInterval,
getTickInterval,
setTodayMarker,
getTodayMarker,
setAccTitle,

View File

@@ -10,6 +10,11 @@ import {
axisBottom,
axisTop,
timeFormat,
timeMinute,
timeHour,
timeDay,
timeWeek,
timeMonth,
} from 'd3';
import common from '../common/common';
import { getConfig } from '../../config';
@@ -495,6 +500,33 @@ export const draw = function (text, id, version, diagObj) {
.tickSize(-h + theTopPad + conf.gridLineStartPadding)
.tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d'));
const reTickInterval = /^([1-9][0-9]*)(minute|hour|day|week|month)$/;
const resultTickInterval = reTickInterval.exec(
diagObj.db.getTickInterval() || conf.tickInterval
);
if (resultTickInterval !== null) {
const every = resultTickInterval[1];
const interval = resultTickInterval[2];
switch (interval) {
case 'minute':
bottomXAxis.ticks(timeMinute.every(every));
break;
case 'hour':
bottomXAxis.ticks(timeHour.every(every));
break;
case 'day':
bottomXAxis.ticks(timeDay.every(every));
break;
case 'week':
bottomXAxis.ticks(timeWeek.every(every));
break;
case 'month':
bottomXAxis.ticks(timeMonth.every(every));
break;
}
}
svg
.append('g')
.attr('class', 'grid')
@@ -512,6 +544,28 @@ export const draw = function (text, id, version, diagObj) {
.tickSize(-h + theTopPad + conf.gridLineStartPadding)
.tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || '%Y-%m-%d'));
if (resultTickInterval !== null) {
const every = resultTickInterval[1];
const interval = resultTickInterval[2];
switch (interval) {
case 'minute':
topXAxis.ticks(timeMinute.every(every));
break;
case 'hour':
topXAxis.ticks(timeHour.every(every));
break;
case 'day':
topXAxis.ticks(timeDay.every(every));
break;
case 'week':
topXAxis.ticks(timeWeek.every(every));
break;
case 'month':
topXAxis.ticks(timeMonth.every(every));
break;
}
}
svg
.append('g')
.attr('class', 'grid')

View File

@@ -82,6 +82,7 @@ that id.
"inclusiveEndDates" return 'inclusiveEndDates';
"topAxis" return 'topAxis';
"axisFormat"\s[^#\n;]+ return 'axisFormat';
"tickInterval"\s[^#\n;]+ return 'tickInterval';
"includes"\s[^#\n;]+ return 'includes';
"excludes"\s[^#\n;]+ return 'excludes';
"todayMarker"\s[^\n;]+ return 'todayMarker';
@@ -125,6 +126,7 @@ statement
| inclusiveEndDates {yy.enableInclusiveEndDates();$$=$1.substr(18);}
| topAxis {yy.TopAxis();$$=$1.substr(8);}
| axisFormat {yy.setAxisFormat($1.substr(11));$$=$1.substr(11);}
| tickInterval {yy.setTickInterval($1.substr(13));$$=$1.substr(13);}
| 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);}

View File

@@ -174,6 +174,22 @@ The following formatting strings are supported:
More info in: https://github.com/mbostock/d3/wiki/Time-Formatting
### Axis ticks
The default output ticks are auto. You can custom your `tickInterval`, like `1day` or `1week`.
```
tickInterval 1day
```
The pattern is:
```
/^([1-9][0-9]*)(minute|hour|day|week|month)$/
```
More info in: [https://github.com/d3/d3-time#interval_every](https://github.com/d3/d3-time#interval_every)
## Comments
Comments can be entered within a gantt chart, which will be ignored by the parser. Comments need to be on their own line and must be prefaced with `%%` (double percent signs). Any text after the start of the comment to the next newline will be treated as a comment, including any diagram syntax