mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-11-03 12:25:22 +01:00
Compare commits
22 Commits
sidv/2685_
...
fixElkTest
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
212b368ffd | ||
|
|
773abbe7e2 | ||
|
|
bcd03151e8 | ||
|
|
c212490248 | ||
|
|
abcf2a2eab | ||
|
|
ebaabbf19a | ||
|
|
e5e44dbd39 | ||
|
|
7cc76505a8 | ||
|
|
8f3bcf401d | ||
|
|
bc770c48c7 | ||
|
|
82404dd0f6 | ||
|
|
bdaf58a322 | ||
|
|
49446940f5 | ||
|
|
650d712bd8 | ||
|
|
a61887f5a2 | ||
|
|
e84ee32408 | ||
|
|
4efac6721d | ||
|
|
8f340094d9 | ||
|
|
d2ed52461e | ||
|
|
9a5cae9c63 | ||
|
|
0b8dce4b82 | ||
|
|
37c18eb4c0 |
@@ -1,6 +1,6 @@
|
||||
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
|
||||
|
||||
describe.skip('Flowchart ELK', () => {
|
||||
describe('Flowchart ELK', () => {
|
||||
it('1-elk: should render a simple flowchart', () => {
|
||||
imgSnapshotTest(
|
||||
`flowchart-elk TD
|
||||
|
||||
@@ -330,6 +330,48 @@ describe('Gantt diagram', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a gantt diagram with tick is 2 milliseconds', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
title A Gantt Diagram
|
||||
dateFormat SSS
|
||||
axisFormat %Lms
|
||||
tickInterval 2millisecond
|
||||
excludes weekends
|
||||
|
||||
section Section
|
||||
A task : a1, 000, 6ms
|
||||
Another task : after a1, 6ms
|
||||
section Another
|
||||
Task in sec : a2, 006, 3ms
|
||||
another task : 3ms
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a gantt diagram with tick is 2 seconds', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
gantt
|
||||
title A Gantt Diagram
|
||||
dateFormat ss
|
||||
axisFormat %Ss
|
||||
tickInterval 2second
|
||||
excludes weekends
|
||||
|
||||
section Section
|
||||
A task : a1, 00, 6s
|
||||
Another task : after a1, 6s
|
||||
section Another
|
||||
Task in sec : 06, 3s
|
||||
another task : 3s
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
|
||||
it('should render a gantt diagram with tick is 15 minutes', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
|
||||
@@ -62,10 +62,10 @@ from IPython.display import Image, display
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def mm(graph):
|
||||
graphbytes = graph.encode("ascii")
|
||||
base64_bytes = base64.b64encode(graphbytes)
|
||||
base64_string = base64_bytes.decode("ascii")
|
||||
display(Image(url="https://mermaid.ink/img/" + base64_string))
|
||||
graphbytes = graph.encode("utf8")
|
||||
base64_bytes = base64.b64encode(graphbytes)
|
||||
base64_string = base64_bytes.decode("ascii")
|
||||
display(Image(url="https://mermaid.ink/img/" + base64_string))
|
||||
|
||||
mm("""
|
||||
graph LR;
|
||||
|
||||
@@ -241,7 +241,7 @@ The following formatting strings are supported:
|
||||
|
||||
More info in: <https://github.com/d3/d3-time-format/tree/v4.0.0#locale_format>
|
||||
|
||||
### Axis ticks
|
||||
### Axis ticks (v10.3.0+)
|
||||
|
||||
The default output ticks are auto. You can custom your `tickInterval`, like `1day` or `1week`.
|
||||
|
||||
@@ -252,7 +252,7 @@ tickInterval 1day
|
||||
The pattern is:
|
||||
|
||||
```javascript
|
||||
/^([1-9][0-9]*)(minute|hour|day|week|month)$/;
|
||||
/^([1-9][0-9]*)(millisecond|second|minute|hour|day|week|month)$/;
|
||||
```
|
||||
|
||||
More info in: <https://github.com/d3/d3-time#interval_every>
|
||||
@@ -271,7 +271,7 @@ gantt
|
||||
weekday monday
|
||||
```
|
||||
|
||||
Support: v10.3.0+
|
||||
> **Warning** > `millisecond` and `second` support was added in vMERMAID_RELEASE_VERSION
|
||||
|
||||
## Output in compact mode
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
import { sanitizeText as _sanitizeText } from './diagrams/common/common.js';
|
||||
import { getConfig } from './config.js';
|
||||
let title = '';
|
||||
let diagramTitle = '';
|
||||
let description = '';
|
||||
|
||||
const sanitizeText = (txt: string): string => _sanitizeText(txt, getConfig());
|
||||
|
||||
export const clear = function (): void {
|
||||
title = '';
|
||||
description = '';
|
||||
diagramTitle = '';
|
||||
};
|
||||
|
||||
export const setAccTitle = function (txt: string): void {
|
||||
title = sanitizeText(txt).replace(/^\s+/g, '');
|
||||
};
|
||||
|
||||
export const getAccTitle = function (): string {
|
||||
return title || diagramTitle;
|
||||
};
|
||||
|
||||
export const setAccDescription = function (txt: string): void {
|
||||
description = sanitizeText(txt).replace(/\n\s+/g, '\n');
|
||||
};
|
||||
|
||||
export const getAccDescription = function (): string {
|
||||
return description;
|
||||
};
|
||||
|
||||
export const setDiagramTitle = function (txt: string): void {
|
||||
diagramTitle = sanitizeText(txt);
|
||||
};
|
||||
|
||||
export const getDiagramTitle = function (): string {
|
||||
return diagramTitle;
|
||||
};
|
||||
|
||||
export default {
|
||||
getAccTitle,
|
||||
setAccTitle,
|
||||
getDiagramTitle,
|
||||
setDiagramTitle,
|
||||
getAccDescription,
|
||||
setAccDescription,
|
||||
clear,
|
||||
};
|
||||
@@ -1048,7 +1048,7 @@ export interface GanttDiagramConfig extends BaseDiagramConfig {
|
||||
* Pattern is:
|
||||
*
|
||||
* ```javascript
|
||||
* /^([1-9][0-9]*)(minute|hour|day|week|month)$/
|
||||
* /^([1-9][0-9]*)(millisecond|second|minute|hour|day|week|month)$/
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@ import { sanitizeText as _sanitizeText } from '../diagrams/common/common.js';
|
||||
import { setupGraphViewbox as _setupGraphViewbox } from '../setupGraphViewbox.js';
|
||||
import { addStylesForDiagram } from '../styles.js';
|
||||
import type { DiagramDefinition, DiagramDetector } from './types.js';
|
||||
import * as _commonDb from '../commonDb.js';
|
||||
import * as _commonDb from '../diagrams/common/commonDb.js';
|
||||
import { parseDirective as _parseDirective } from '../directiveUtils.js';
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import mermaidAPI from '../../mermaidAPI.js';
|
||||
import * as configApi from '../../config.js';
|
||||
import { sanitizeText } from '../common/common.js';
|
||||
import { setAccTitle, getAccTitle, getAccDescription, setAccDescription } from '../../commonDb.js';
|
||||
import {
|
||||
setAccTitle,
|
||||
getAccTitle,
|
||||
getAccDescription,
|
||||
setAccDescription,
|
||||
} from '../common/commonDb.js';
|
||||
|
||||
let c4ShapeArray = [];
|
||||
let boundaryParseStack = [''];
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
clear as commonClear,
|
||||
setDiagramTitle,
|
||||
getDiagramTitle,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
import { ClassMember } from './classTypes.js';
|
||||
import type {
|
||||
ClassRelation,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sanitizeText, removeScript, parseGenericTypes } from './common.js';
|
||||
import { sanitizeText, removeScript, parseGenericTypes, countOccurrence } from './common.js';
|
||||
|
||||
describe('when securityLevel is antiscript, all script must be removed', () => {
|
||||
/**
|
||||
@@ -59,15 +59,29 @@ describe('Sanitize text', () => {
|
||||
});
|
||||
|
||||
describe('generic parser', () => {
|
||||
it('should parse generic types', () => {
|
||||
expect(parseGenericTypes('test~T~')).toEqual('test<T>');
|
||||
expect(parseGenericTypes('test~Array~Array~string~~~')).toEqual('test<Array<Array<string>>>');
|
||||
expect(parseGenericTypes('test~Array~Array~string[]~~~')).toEqual(
|
||||
'test<Array<Array<string[]>>>'
|
||||
);
|
||||
expect(parseGenericTypes('test ~Array~Array~string[]~~~')).toEqual(
|
||||
'test <Array<Array<string[]>>>'
|
||||
);
|
||||
expect(parseGenericTypes('~test')).toEqual('~test');
|
||||
it.each([
|
||||
['test~T~', 'test<T>'],
|
||||
['test~Array~Array~string~~~', 'test<Array<Array<string>>>'],
|
||||
['test~Array~Array~string[]~~~', 'test<Array<Array<string[]>>>'],
|
||||
['test ~Array~Array~string[]~~~', 'test <Array<Array<string[]>>>'],
|
||||
['~test', '~test'],
|
||||
['~test~T~', '~test<T>'],
|
||||
])('should parse generic types: %s to %s', (input: string, expected: string) => {
|
||||
expect(parseGenericTypes(input)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it.each([
|
||||
['', '', 0],
|
||||
['', 'x', 0],
|
||||
['test', 'x', 0],
|
||||
['test', 't', 2],
|
||||
['test', 'te', 1],
|
||||
['test~T~', '~', 2],
|
||||
['test~Array~Array~string~~~', '~', 6],
|
||||
])(
|
||||
'should count `%s` to contain occurrences of `%s` to be `%i`',
|
||||
(str: string, substring: string, count: number) => {
|
||||
expect(countOccurrence(str, substring)).toEqual(count);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -208,21 +208,33 @@ export const parseGenericTypes = function (input: string): string {
|
||||
return output.join('');
|
||||
};
|
||||
|
||||
export const countOccurrence = (string: string, substring: string): number => {
|
||||
return Math.max(0, string.split(substring).length - 1);
|
||||
};
|
||||
|
||||
const shouldCombineSets = (previousSet: string, nextSet: string): boolean => {
|
||||
const prevCount = [...previousSet].reduce((count, char) => (char === '~' ? count + 1 : count), 0);
|
||||
const nextCount = [...nextSet].reduce((count, char) => (char === '~' ? count + 1 : count), 0);
|
||||
const prevCount = countOccurrence(previousSet, '~');
|
||||
const nextCount = countOccurrence(nextSet, '~');
|
||||
|
||||
return prevCount === 1 && nextCount === 1;
|
||||
};
|
||||
|
||||
const processSet = (input: string): string => {
|
||||
const chars = [...input];
|
||||
const tildeCount = chars.reduce((count, char) => (char === '~' ? count + 1 : count), 0);
|
||||
const tildeCount = countOccurrence(input, '~');
|
||||
let hasStartingTilde = false;
|
||||
|
||||
if (tildeCount <= 1) {
|
||||
return input;
|
||||
}
|
||||
|
||||
// If there is an odd number of tildes, and the input starts with a tilde, we need to remove it and add it back in later
|
||||
if (tildeCount % 2 !== 0 && input.startsWith('~')) {
|
||||
input = input.substring(1);
|
||||
hasStartingTilde = true;
|
||||
}
|
||||
|
||||
const chars = [...input];
|
||||
|
||||
let first = chars.indexOf('~');
|
||||
let last = chars.lastIndexOf('~');
|
||||
|
||||
@@ -234,6 +246,11 @@ const processSet = (input: string): string => {
|
||||
last = chars.lastIndexOf('~');
|
||||
}
|
||||
|
||||
// Add the starting tilde back in if we removed it
|
||||
if (hasStartingTilde) {
|
||||
chars.unshift('~');
|
||||
}
|
||||
|
||||
return chars.join('');
|
||||
};
|
||||
|
||||
|
||||
32
packages/mermaid/src/diagrams/common/commonDb.ts
Normal file
32
packages/mermaid/src/diagrams/common/commonDb.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { sanitizeText as _sanitizeText } from './common.js';
|
||||
import { getConfig } from '../../config.js';
|
||||
|
||||
let accTitle = '';
|
||||
let diagramTitle = '';
|
||||
let accDescription = '';
|
||||
|
||||
const sanitizeText = (txt: string): string => _sanitizeText(txt, getConfig());
|
||||
|
||||
export const clear = (): void => {
|
||||
accTitle = '';
|
||||
accDescription = '';
|
||||
diagramTitle = '';
|
||||
};
|
||||
|
||||
export const setAccTitle = (txt: string): void => {
|
||||
accTitle = sanitizeText(txt).replace(/^\s+/g, '');
|
||||
};
|
||||
|
||||
export const getAccTitle = (): string => accTitle;
|
||||
|
||||
export const setAccDescription = (txt: string): void => {
|
||||
accDescription = sanitizeText(txt).replace(/\n\s+/g, '\n');
|
||||
};
|
||||
|
||||
export const getAccDescription = (): string => accDescription;
|
||||
|
||||
export const setDiagramTitle = (txt: string): void => {
|
||||
diagramTitle = sanitizeText(txt);
|
||||
};
|
||||
|
||||
export const getDiagramTitle = (): string => diagramTitle;
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
clear as commonClear,
|
||||
setDiagramTitle,
|
||||
getDiagramTitle,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
|
||||
let entities = {};
|
||||
let relationships = [];
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
clear as commonClear,
|
||||
setDiagramTitle,
|
||||
getDiagramTitle,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
|
||||
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
|
||||
let vertexCounter = 0;
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
clear as commonClear,
|
||||
setDiagramTitle,
|
||||
getDiagramTitle,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
|
||||
dayjs.extend(dayjsIsoWeek);
|
||||
dayjs.extend(dayjsCustomParseFormat);
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
axisBottom,
|
||||
axisTop,
|
||||
timeFormat,
|
||||
timeMillisecond,
|
||||
timeSecond,
|
||||
timeMinute,
|
||||
timeHour,
|
||||
timeDay,
|
||||
@@ -573,7 +575,7 @@ 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]\d*)(minute|hour|day|week|month)$/;
|
||||
const reTickInterval = /^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/;
|
||||
const resultTickInterval = reTickInterval.exec(
|
||||
diagObj.db.getTickInterval() || conf.tickInterval
|
||||
);
|
||||
@@ -584,6 +586,12 @@ export const draw = function (text, id, version, diagObj) {
|
||||
const weekday = diagObj.db.getWeekday() || conf.weekday;
|
||||
|
||||
switch (interval) {
|
||||
case 'millisecond':
|
||||
bottomXAxis.ticks(timeMillisecond.every(every));
|
||||
break;
|
||||
case 'second':
|
||||
bottomXAxis.ticks(timeSecond.every(every));
|
||||
break;
|
||||
case 'minute':
|
||||
bottomXAxis.ticks(timeMinute.every(every));
|
||||
break;
|
||||
@@ -625,6 +633,12 @@ export const draw = function (text, id, version, diagObj) {
|
||||
const weekday = diagObj.db.getWeekday() || conf.weekday;
|
||||
|
||||
switch (interval) {
|
||||
case 'millisecond':
|
||||
topXAxis.ticks(timeMillisecond.every(every));
|
||||
break;
|
||||
case 'second':
|
||||
topXAxis.ticks(timeSecond.every(every));
|
||||
break;
|
||||
case 'minute':
|
||||
topXAxis.ticks(timeMinute.every(every));
|
||||
break;
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
clear as commonClear,
|
||||
setDiagramTitle,
|
||||
getDiagramTitle,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
|
||||
let mainBranchName = getConfig().gitGraph.mainBranchName;
|
||||
let mainBranchOrder = getConfig().gitGraph.mainBranchOrder;
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
getAccDescription,
|
||||
setAccDescription,
|
||||
clear as commonClear,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
import type { ParseDirectiveDefinition } from '../../diagram-api/types.js';
|
||||
import type { PieFields, PieDB, Sections } from './pieTypes.js';
|
||||
import type { RequiredDeep } from 'type-fest';
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
getAccDescription,
|
||||
setAccDescription,
|
||||
clear as commonClear,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
import { QuadrantBuilder } from './quadrantBuilder.js';
|
||||
|
||||
const config = configApi.getConfig();
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
getAccDescription,
|
||||
setAccDescription,
|
||||
clear as commonClear,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
|
||||
let relations = [];
|
||||
let latestRequirement = {};
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
setDiagramTitle,
|
||||
getDiagramTitle,
|
||||
clear as commonClear,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
|
||||
// Sankey diagram represented by nodes and links between those nodes
|
||||
let links: SankeyLink[] = [];
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
getAccDescription,
|
||||
setAccDescription,
|
||||
clear as commonClear,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
|
||||
let prevActor = undefined;
|
||||
let actors = {};
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
clear as commonClear,
|
||||
setDiagramTitle,
|
||||
getDiagramTitle,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
|
||||
import {
|
||||
DEFAULT_DIAGRAM_DIRECTION,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { parser as timeline } from './parser/timeline.jison';
|
||||
import * as timelineDB from './timelineDb.js';
|
||||
// import { injectUtils } from './mermaidUtils.js';
|
||||
import * as _commonDb from '../../commonDb.js';
|
||||
import { parseDirective as _parseDirective } from '../../directiveUtils.js';
|
||||
|
||||
import {
|
||||
@@ -18,7 +17,6 @@ import {
|
||||
// getConfig,
|
||||
// sanitizeText,
|
||||
// setupGraphViewBox,
|
||||
// _commonDb,
|
||||
// _parseDirective
|
||||
// );
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { parseDirective as _parseDirective } from '../../directiveUtils.js';
|
||||
import * as commonDb from '../../commonDb.js';
|
||||
import * as commonDb from '../common/commonDb.js';
|
||||
let currentSection = '';
|
||||
let currentTaskId = 0;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
getAccDescription,
|
||||
setAccDescription,
|
||||
clear as commonClear,
|
||||
} from '../../commonDb.js';
|
||||
} from '../common/commonDb.js';
|
||||
|
||||
let currentSection = '';
|
||||
|
||||
|
||||
@@ -56,10 +56,10 @@ from IPython.display import Image, display
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def mm(graph):
|
||||
graphbytes = graph.encode("ascii")
|
||||
base64_bytes = base64.b64encode(graphbytes)
|
||||
base64_string = base64_bytes.decode("ascii")
|
||||
display(Image(url="https://mermaid.ink/img/" + base64_string))
|
||||
graphbytes = graph.encode("utf8")
|
||||
base64_bytes = base64.b64encode(graphbytes)
|
||||
base64_string = base64_bytes.decode("ascii")
|
||||
display(Image(url="https://mermaid.ink/img/" + base64_string))
|
||||
|
||||
mm("""
|
||||
graph LR;
|
||||
|
||||
@@ -173,7 +173,7 @@ The following formatting strings are supported:
|
||||
|
||||
More info in: [https://github.com/d3/d3-time-format/tree/v4.0.0#locale_format](https://github.com/d3/d3-time-format/tree/v4.0.0#locale_format)
|
||||
|
||||
### Axis ticks
|
||||
### Axis ticks (v10.3.0+)
|
||||
|
||||
The default output ticks are auto. You can custom your `tickInterval`, like `1day` or `1week`.
|
||||
|
||||
@@ -184,7 +184,7 @@ tickInterval 1day
|
||||
The pattern is:
|
||||
|
||||
```javascript
|
||||
/^([1-9][0-9]*)(minute|hour|day|week|month)$/;
|
||||
/^([1-9][0-9]*)(millisecond|second|minute|hour|day|week|month)$/;
|
||||
```
|
||||
|
||||
More info in: [https://github.com/d3/d3-time#interval_every](https://github.com/d3/d3-time#interval_every)
|
||||
@@ -197,7 +197,9 @@ gantt
|
||||
weekday monday
|
||||
```
|
||||
|
||||
Support: v10.3.0+
|
||||
```warning
|
||||
`millisecond` and `second` support was added in vMERMAID_RELEASE_VERSION
|
||||
```
|
||||
|
||||
## Output in compact mode
|
||||
|
||||
|
||||
@@ -1524,10 +1524,10 @@ $defs: # JSON Schema definition (maybe we should move these to a seperate file)
|
||||
Pattern is:
|
||||
|
||||
```javascript
|
||||
/^([1-9][0-9]*)(minute|hour|day|week|month)$/
|
||||
/^([1-9][0-9]*)(millisecond|second|minute|hour|day|week|month)$/
|
||||
```
|
||||
type: string
|
||||
pattern: ^([1-9][0-9]*)(minute|hour|day|week|month)$
|
||||
pattern: ^([1-9][0-9]*)(millisecond|second|minute|hour|day|week|month)$
|
||||
topAxis:
|
||||
description: |
|
||||
When this flag is set, date labels will be added to the top of the chart
|
||||
|
||||
Reference in New Issue
Block a user