Bugfixes, refactor, add compact

This commit is contained in:
Jeremy Funk 2023-03-23 22:38:04 +01:00
parent b3b7108d59
commit a535fe1679
7 changed files with 96 additions and 54 deletions

View File

@ -78,7 +78,7 @@
axisFormat %d/%m
todayMarker off
section Section1
Today: 1, -01:00, 5min
Today: 1, 08-08-09-01:00, 5min
</pre>
<hr />
@ -89,7 +89,7 @@
axisFormat %d/%m
todayMarker stroke-width:5px,stroke:#00f,opacity:0.5
section Section1
Today: 1, -01:00, 5min
Today: 1, 08-08-09-01:00, 5min
</pre>
<hr />
@ -166,6 +166,35 @@
</pre>
<hr />
<pre class="mermaid">
gantt
title GANTT compact
dateFormat HH:mm:ss
axisFormat %Hh%M
compact
section DB Clean
Clean: 12:00:00 , 10m
Clean: 12:30:00 , 12m
Clean: 13:00:00 , 8m
Clean: 13:30:00 , 9m
Clean: 14:00:00 , 13m
Clean: 14:30:00 , 10m
Clean: 15:00:00 , 11m
section Sessions
A: 12:00:00 , 63m
B: 12:30:00 , 12m
C: 13:05:00 , 12m
D: 13:06:00 , 33m
E: 13:15:00 , 55m
F: 13:20:00 , 12m
G: 13:32:00 , 18m
H: 13:50:00 , 20m
I: 14:10:00 , 10m
</pre>
<hr />
<script>
function ganttTestClick(a, b, c) {
console.log('a:', a);

View File

@ -14,7 +14,7 @@
#### Defined in
[defaultConfig.ts:2093](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2093)
[defaultConfig.ts:2107](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2107)
---

View File

@ -335,7 +335,7 @@ export interface GanttDiagramConfig extends BaseDiagramConfig {
axisFormat?: string;
tickInterval?: string;
topAxis?: boolean;
verticalDisplayMode?: 'default' | 'merged' | 'compact';
compact?: boolean;
}
export interface SequenceDiagramConfig extends BaseDiagramConfig {

View File

@ -685,6 +685,20 @@ const config: Partial<MermaidConfig> = {
*/
tickInterval: undefined,
/**
* | Parameter | Description | Type | Required | Values |
* | --------- | ------------------------- | ------- | -------- | ----------- |
* | compact | displays in compact mode | boolean | Optional | true, false |
*
* **Notes:**
*
* When this flag is set to true, it allows multiple tasks to be displayed on the same
* row.
*
* Default value: false
*/
compact: undefined,
/**
* | Parameter | Description | Type | Required | Values |
* | ----------- | ----------- | ------- | -------- | ----------- |

View File

@ -25,6 +25,7 @@ dayjs.extend(dayjsAdvancedFormat);
let dateFormat = '';
let axisFormat = '';
let tickInterval = undefined;
let compact = false;
let todayMarker = '';
let includes = [];
let excludes = [];
@ -56,6 +57,7 @@ export const clear = function () {
dateFormat = '';
axisFormat = '';
tickInterval = undefined;
compact = false;
todayMarker = '';
includes = [];
excludes = [];
@ -82,6 +84,14 @@ export const getTickInterval = function () {
return tickInterval;
};
export const enableCompact = function () {
compact = true;
};
export const compactEnabled = function () {
return compact;
};
export const setTodayMarker = function (txt) {
todayMarker = txt;
};
@ -713,6 +723,8 @@ export default {
getAxisFormat,
setTickInterval,
getTickInterval,
enableCompact,
compactEnabled,
setTodayMarker,
getTodayMarker,
setAccTitle,

View File

@ -24,26 +24,6 @@ export const setConf = function () {
log.debug('Something is calling, setConf, remove the call');
};
const getMaxIntersections = (tasks, orderOffset) => {
let timeline = [...tasks].map(() => 0);
let sorted = [...tasks].sort((a, b) => a.startTime - b.startTime || a.order - b.order);
let maxIntersections = 0;
for (const element of sorted) {
for (let j = 0; j < timeline.length; j++) {
if (element.startTime >= timeline[j]) {
timeline[j] = element.endTime;
element.order = j + orderOffset;
if (j > maxIntersections) {
maxIntersections = j;
}
break;
}
}
}
return maxIntersections;
};
let w;
export const draw = function (text, id, version, diagObj) {
const conf = getConfig().gantt;
@ -76,23 +56,17 @@ export const draw = function (text, id, version, diagObj) {
// Set height based on number of tasks
conf.verticalDisplayMode = 'compact';
let categories = [];
for (const element of taskArray) {
categories.push(element.type);
}
const catsUnfiltered = categories; // for vert labels
categories = checkUnique(categories);
const categoryHeights = {};
let h = 2 * conf.topPadding;
if (conf.verticalDisplayMode === undefined || conf.verticalDisplayMode === 'default') {
h = taskArray.length * (conf.barHeight + conf.barGap);
} else if (conf.verticalDisplayMode === 'compact') {
if (diagObj.db.compactEnabled()) {
const categoryElements = {};
for (const element of taskArray) {
if (categoryElements[element.section] === undefined) {
@ -109,6 +83,11 @@ export const draw = function (text, id, version, diagObj) {
h += categoryHeight * (conf.barHeight + conf.barGap);
categoryHeights[category] = categoryHeight;
}
} else {
h += taskArray.length * (conf.barHeight + conf.barGap);
for (const category of categories) {
categoryHeights[category] = taskArray.filter((task) => task.type === category).length;
}
}
// Set viewBox
@ -669,7 +648,6 @@ export const draw = function (text, id, version, diagObj) {
}
})
.attr('font-size', conf.sectionFontSize)
.attr('font-size', conf.sectionFontSize)
.attr('class', function (d) {
for (const [i, category] of categories.entries()) {
if (d[0] === category) {
@ -728,29 +706,35 @@ export const draw = function (text, id, version, diagObj) {
}
/**
* From this stack exchange question:
* http://stackoverflow.com/questions/14227981/count-how-many-strings-in-an-array-have-duplicates-in-the-same-array
* For this issue:
* https://github.com/mermaid-js/mermaid/issues/1618
*
* @param arr
* Finds the number of intersections between tasks that happen at any point in time.
* Used to figure out how many rows are needed to display the tasks when the compact
* flag is set to true.
*
* @param tasks
* @param orderOffset
*/
function getCounts(arr) {
let i = arr.length; // const to loop over
const obj = {}; // obj to store results
while (i) {
obj[arr[--i]] = (obj[arr[i]] || 0) + 1; // count occurrences
const getMaxIntersections = (tasks, orderOffset) => {
let timeline = [...tasks].map(() => -1);
let sorted = [...tasks].sort((a, b) => a.startTime - b.startTime || a.order - b.order);
let maxIntersections = 0;
for (const element of sorted) {
for (let j = 0; j < timeline.length; j++) {
if (element.startTime >= timeline[j]) {
timeline[j] = element.endTime;
element.order = j + orderOffset;
if (j > maxIntersections) {
maxIntersections = j;
}
break;
}
}
}
return obj;
}
/**
* Get specific from everything
*
* @param word
* @param arr
*/
function getCount(word, arr) {
return getCounts(arr)[word] || 0;
}
return maxIntersections;
};
};
export default {

View File

@ -79,6 +79,7 @@ that id.
"gantt" return 'gantt';
"dateFormat"\s[^#\n;]+ return 'dateFormat';
"compact" return 'compact';
"inclusiveEndDates" return 'inclusiveEndDates';
"topAxis" return 'topAxis';
"axisFormat"\s[^#\n;]+ return 'axisFormat';
@ -131,9 +132,11 @@ statement
| includes {yy.setIncludes($1.substr(9));$$=$1.substr(9);}
| todayMarker {yy.setTodayMarker($1.substr(12));$$=$1.substr(12);}
| 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($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } | section {yy.addSection($1.substr(8));$$=$1.substr(8);}
| compact { yy.enableCompact();$$=$1.substr(8); }
| acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
| section { yy.addSection($1.substr(8));$$=$1.substr(8); }
| clickStatement
| taskTxt taskData {yy.addTask($1,$2);$$='task';}
| directive