mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-23 07:59:39 +02:00
Compare commits
1 Commits
fix-flowch
...
6790-Fix-n
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2ee7ef09c4 |
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Support edge animation in hand drawn look
|
|
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Resolved parsing error where direction TD was not recognized within subgraphs
|
|
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Improve participant parsing and prevent recursive loops on invalid syntax
|
|
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
'mermaid': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
fix: Handle backslash parsing in math formulas within new flowchart shape syntax
|
|
@@ -6,7 +6,6 @@ interface CypressConfig {
|
|||||||
listUrl?: boolean;
|
listUrl?: boolean;
|
||||||
listId?: string;
|
listId?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
screenshot?: boolean;
|
|
||||||
}
|
}
|
||||||
type CypressMermaidConfig = MermaidConfig & CypressConfig;
|
type CypressMermaidConfig = MermaidConfig & CypressConfig;
|
||||||
|
|
||||||
@@ -91,7 +90,7 @@ export const renderGraph = (
|
|||||||
|
|
||||||
export const openURLAndVerifyRendering = (
|
export const openURLAndVerifyRendering = (
|
||||||
url: string,
|
url: string,
|
||||||
{ screenshot = true, ...options }: CypressMermaidConfig,
|
options: CypressMermaidConfig,
|
||||||
validation?: any
|
validation?: any
|
||||||
): void => {
|
): void => {
|
||||||
const name: string = (options.name ?? cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
|
const name: string = (options.name ?? cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
|
||||||
@@ -104,9 +103,7 @@ export const openURLAndVerifyRendering = (
|
|||||||
cy.get('svg').should(validation);
|
cy.get('svg').should(validation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (screenshot) {
|
verifyScreenshot(name);
|
||||||
verifyScreenshot(name);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const verifyScreenshot = (name: string): void => {
|
export const verifyScreenshot = (name: string): void => {
|
||||||
|
@@ -1029,19 +1029,4 @@ graph TD
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('FDH49: should add edge animation', () => {
|
|
||||||
renderGraph(
|
|
||||||
`
|
|
||||||
flowchart TD
|
|
||||||
A(["Start"]) L_A_B_0@--> B{"Decision"}
|
|
||||||
B --> C["Option A"] & D["Option B"]
|
|
||||||
style C stroke-width:4px,stroke-dasharray: 5
|
|
||||||
L_A_B_0@{ animation: slow }
|
|
||||||
L_B_D_0@{ animation: fast }`,
|
|
||||||
{ look: 'handDrawn', screenshot: false }
|
|
||||||
);
|
|
||||||
cy.get('path#L_A_B_0').should('have.class', 'edge-animation-slow');
|
|
||||||
cy.get('path#L_B_D_0').should('have.class', 'edge-animation-fast');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@@ -774,21 +774,6 @@ describe('Graph', () => {
|
|||||||
expect(svg).to.not.have.attr('style');
|
expect(svg).to.not.have.attr('style');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('40: should add edge animation', () => {
|
|
||||||
renderGraph(
|
|
||||||
`
|
|
||||||
flowchart TD
|
|
||||||
A(["Start"]) L_A_B_0@--> B{"Decision"}
|
|
||||||
B --> C["Option A"] & D["Option B"]
|
|
||||||
style C stroke-width:4px,stroke-dasharray: 5
|
|
||||||
L_A_B_0@{ animation: slow }
|
|
||||||
L_B_D_0@{ animation: fast }`,
|
|
||||||
{ screenshot: false }
|
|
||||||
);
|
|
||||||
// Verify animation classes are applied to both edges
|
|
||||||
cy.get('path#L_A_B_0').should('have.class', 'edge-animation-slow');
|
|
||||||
cy.get('path#L_B_D_0').should('have.class', 'edge-animation-fast');
|
|
||||||
});
|
|
||||||
it('58: handle styling with style expressions', () => {
|
it('58: handle styling with style expressions', () => {
|
||||||
imgSnapshotTest(
|
imgSnapshotTest(
|
||||||
`
|
`
|
||||||
@@ -988,19 +973,4 @@ graph TD
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('70: should render a subgraph with direction TD', () => {
|
|
||||||
imgSnapshotTest(
|
|
||||||
`
|
|
||||||
flowchart LR
|
|
||||||
subgraph A
|
|
||||||
direction TD
|
|
||||||
a --> b
|
|
||||||
end
|
|
||||||
`,
|
|
||||||
{
|
|
||||||
fontFamily: 'courier',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@@ -603,10 +603,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="test">
|
<div class="test">
|
||||||
<pre class="mermaid">
|
<pre class="mermaid">
|
||||||
---
|
|
||||||
config:
|
|
||||||
theme: dark
|
|
||||||
---
|
|
||||||
classDiagram
|
classDiagram
|
||||||
test ()--() test2
|
test ()--() test2
|
||||||
</pre>
|
</pre>
|
||||||
|
@@ -21,7 +21,7 @@ title: Animal example
|
|||||||
classDiagram
|
classDiagram
|
||||||
note "From Duck till Zebra"
|
note "From Duck till Zebra"
|
||||||
Animal <|-- Duck
|
Animal <|-- Duck
|
||||||
note for Duck "can fly<br>can swim<br>can dive<br>can help in debugging"
|
note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging"
|
||||||
Animal <|-- Fish
|
Animal <|-- Fish
|
||||||
Animal <|-- Zebra
|
Animal <|-- Zebra
|
||||||
Animal : +int age
|
Animal : +int age
|
||||||
@@ -50,7 +50,7 @@ title: Animal example
|
|||||||
classDiagram
|
classDiagram
|
||||||
note "From Duck till Zebra"
|
note "From Duck till Zebra"
|
||||||
Animal <|-- Duck
|
Animal <|-- Duck
|
||||||
note for Duck "can fly<br>can swim<br>can dive<br>can help in debugging"
|
note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging"
|
||||||
Animal <|-- Fish
|
Animal <|-- Fish
|
||||||
Animal <|-- Zebra
|
Animal <|-- Zebra
|
||||||
Animal : +int age
|
Animal : +int age
|
||||||
|
@@ -627,7 +627,7 @@ export class ClassDB implements DiagramDB {
|
|||||||
padding: config.class!.padding ?? 16,
|
padding: config.class!.padding ?? 16,
|
||||||
// parent node must be one of [rect, roundedWithTitle, noteGroup, divider]
|
// parent node must be one of [rect, roundedWithTitle, noteGroup, divider]
|
||||||
shape: 'rect',
|
shape: 'rect',
|
||||||
cssStyles: [],
|
cssStyles: ['fill: none', 'stroke: black'],
|
||||||
look: config.look,
|
look: config.look,
|
||||||
};
|
};
|
||||||
nodes.push(node);
|
nodes.push(node);
|
||||||
|
@@ -13,30 +13,6 @@ const getStyles = (options) =>
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cluster-label text {
|
|
||||||
fill: ${options.titleColor};
|
|
||||||
}
|
|
||||||
.cluster-label span {
|
|
||||||
color: ${options.titleColor};
|
|
||||||
}
|
|
||||||
.cluster-label span p {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cluster rect {
|
|
||||||
fill: ${options.clusterBkg};
|
|
||||||
stroke: ${options.clusterBorder};
|
|
||||||
stroke-width: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cluster text {
|
|
||||||
fill: ${options.titleColor};
|
|
||||||
}
|
|
||||||
|
|
||||||
.cluster span {
|
|
||||||
color: ${options.titleColor};
|
|
||||||
}
|
|
||||||
|
|
||||||
.nodeLabel, .edgeLabel {
|
.nodeLabel, .edgeLabel {
|
||||||
color: ${options.classText};
|
color: ${options.classText};
|
||||||
}
|
}
|
||||||
|
@@ -144,16 +144,6 @@ describe('when parsing directions', function () {
|
|||||||
expect(data4Layout.nodes[0].shape).toEqual('rounded');
|
expect(data4Layout.nodes[0].shape).toEqual('rounded');
|
||||||
expect(data4Layout.nodes[0].label).toEqual('DD');
|
expect(data4Layout.nodes[0].label).toEqual('DD');
|
||||||
});
|
});
|
||||||
it('should handle mathematical formulas with backslashes in quoted strings', function () {
|
|
||||||
const res = flow.parser.parse(`flowchart TB
|
|
||||||
A@{ shape: rect, label: "$$\\sin x$$"}`);
|
|
||||||
|
|
||||||
const data4Layout = flow.parser.yy.getData();
|
|
||||||
|
|
||||||
expect(data4Layout.nodes.length).toBe(1);
|
|
||||||
expect(data4Layout.nodes[0].shape).toEqual('rect');
|
|
||||||
expect(data4Layout.nodes[0].label).toEqual('$$\\sin x$$');
|
|
||||||
});
|
|
||||||
it('should be possible to link to a node with more data', function () {
|
it('should be possible to link to a node with more data', function () {
|
||||||
const res = flow.parser.parse(`flowchart TB
|
const res = flow.parser.parse(`flowchart TB
|
||||||
A --> D@{
|
A --> D@{
|
||||||
|
@@ -53,7 +53,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multilin
|
|||||||
// console.log('shapeData', yytext);
|
// console.log('shapeData', yytext);
|
||||||
const re = /\n\s*/g;
|
const re = /\n\s*/g;
|
||||||
yytext = yytext.replace(re,"<br/>");
|
yytext = yytext.replace(re,"<br/>");
|
||||||
yytext = yytext.replace(/\\/g, "\\\\");
|
|
||||||
return 'SHAPE_DATA'}
|
return 'SHAPE_DATA'}
|
||||||
<shapeData>[^}^"]+ {
|
<shapeData>[^}^"]+ {
|
||||||
// console.log('shapeData', yytext);
|
// console.log('shapeData', yytext);
|
||||||
@@ -141,7 +140,6 @@ that id.
|
|||||||
.*direction\s+BT[^\n]* return 'direction_bt';
|
.*direction\s+BT[^\n]* return 'direction_bt';
|
||||||
.*direction\s+RL[^\n]* return 'direction_rl';
|
.*direction\s+RL[^\n]* return 'direction_rl';
|
||||||
.*direction\s+LR[^\n]* return 'direction_lr';
|
.*direction\s+LR[^\n]* return 'direction_lr';
|
||||||
.*direction\s+TD[^\n]* return 'direction_td';
|
|
||||||
|
|
||||||
[^\s\"]+\@(?=[^\{\"]) { return 'LINK_ID'; }
|
[^\s\"]+\@(?=[^\{\"]) { return 'LINK_ID'; }
|
||||||
[0-9]+ return 'NUM';
|
[0-9]+ return 'NUM';
|
||||||
@@ -628,8 +626,6 @@ direction
|
|||||||
{ $$={stmt:'dir', value:'RL'};}
|
{ $$={stmt:'dir', value:'RL'};}
|
||||||
| direction_lr
|
| direction_lr
|
||||||
{ $$={stmt:'dir', value:'LR'};}
|
{ $$={stmt:'dir', value:'LR'};}
|
||||||
| direction_td
|
|
||||||
{ $$={stmt:'dir', value:'TD'};}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
@@ -309,21 +309,4 @@ describe('when parsing subgraphs', function () {
|
|||||||
expect(subgraphA.nodes).toContain('a');
|
expect(subgraphA.nodes).toContain('a');
|
||||||
expect(subgraphA.nodes).not.toContain('c');
|
expect(subgraphA.nodes).not.toContain('c');
|
||||||
});
|
});
|
||||||
it('should correctly parse direction TD inside a subgraph', function () {
|
|
||||||
const res = flow.parser.parse(`
|
|
||||||
graph LR
|
|
||||||
subgraph WithTD
|
|
||||||
direction TD
|
|
||||||
A1 --> A2
|
|
||||||
end
|
|
||||||
`);
|
|
||||||
|
|
||||||
const subgraphs = flow.parser.yy.getSubGraphs();
|
|
||||||
expect(subgraphs.length).toBe(1);
|
|
||||||
const subgraph = subgraphs[0];
|
|
||||||
|
|
||||||
expect(subgraph.dir).toBe('TD');
|
|
||||||
expect(subgraph.nodes).toContain('A1');
|
|
||||||
expect(subgraph.nodes).toContain('A2');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@@ -32,14 +32,13 @@
|
|||||||
<CONFIG>[^\}]+ { return 'CONFIG_CONTENT'; }
|
<CONFIG>[^\}]+ { return 'CONFIG_CONTENT'; }
|
||||||
<CONFIG>\} { this.popState(); this.popState(); return 'CONFIG_END'; }
|
<CONFIG>\} { this.popState(); this.popState(); return 'CONFIG_END'; }
|
||||||
<ID>[^\<->\->:\n,;@\s]+(?=\@\{) { yytext = yytext.trim(); return 'ACTOR'; }
|
<ID>[^\<->\->:\n,;@\s]+(?=\@\{) { yytext = yytext.trim(); return 'ACTOR'; }
|
||||||
<ID>[^<>:\n,;@\s]+(?=\s+as\s) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
|
<ID>[^\<->\->:\n,;@]+?([\-]*[^\<->\->:\n,;@]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
|
||||||
<ID>[^<>:\n,;@]+(?=\s*[\n;#]|$) { yytext = yytext.trim(); this.popState(); return 'ACTOR'; }
|
|
||||||
<ID>[^<>:\n,;@]*\<[^\n]* { this.popState(); return 'INVALID'; }
|
|
||||||
"box" { this.begin('LINE'); return 'box'; }
|
"box" { this.begin('LINE'); return 'box'; }
|
||||||
"participant" { this.begin('ID'); return 'participant'; }
|
"participant" { this.begin('ID'); return 'participant'; }
|
||||||
"actor" { this.begin('ID'); return 'participant_actor'; }
|
"actor" { this.begin('ID'); return 'participant_actor'; }
|
||||||
"create" return 'create';
|
"create" return 'create';
|
||||||
"destroy" { this.begin('ID'); return 'destroy'; }
|
"destroy" { this.begin('ID'); return 'destroy'; }
|
||||||
|
<ID>[^<\->\->:\n,;]+?([\-]*[^<\->\->:\n,;]+?)*?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$) { yytext = yytext.trim(); this.begin('ALIAS'); return 'ACTOR'; }
|
||||||
<ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }
|
<ALIAS>"as" { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }
|
||||||
<ALIAS>(?:) { this.popState(); this.popState(); return 'NEWLINE'; }
|
<ALIAS>(?:) { this.popState(); this.popState(); return 'NEWLINE'; }
|
||||||
"loop" { this.begin('LINE'); return 'loop'; }
|
"loop" { this.begin('LINE'); return 'loop'; }
|
||||||
@@ -146,7 +145,6 @@ line
|
|||||||
: SPACE statement { $$ = $2 }
|
: SPACE statement { $$ = $2 }
|
||||||
| statement { $$ = $1 }
|
| statement { $$ = $1 }
|
||||||
| NEWLINE { $$=[]; }
|
| NEWLINE { $$=[]; }
|
||||||
| INVALID { $$=[]; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
box_section
|
box_section
|
||||||
@@ -413,4 +411,4 @@ text2
|
|||||||
: TXT {$$ = yy.parseMessage($1.trim().substring(1)) }
|
: TXT {$$ = yy.parseMessage($1.trim().substring(1)) }
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
@@ -2609,17 +2609,5 @@ Bob->>Alice:Got it!
|
|||||||
expect(actors.get('E').type).toBe('entity');
|
expect(actors.get('E').type).toBe('entity');
|
||||||
expect(actors.get('E').description).toBe('E');
|
expect(actors.get('E').description).toBe('E');
|
||||||
});
|
});
|
||||||
it('should handle fail parsing when alias token causes conflicts in participant definition', async () => {
|
|
||||||
let error = false;
|
|
||||||
try {
|
|
||||||
await Diagram.fromText(`
|
|
||||||
sequenceDiagram
|
|
||||||
participant SAS MyServiceWithMoreThan20Chars <br> service decription
|
|
||||||
`);
|
|
||||||
} catch (e) {
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
expect(error).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -15,7 +15,7 @@ title: Animal example
|
|||||||
classDiagram
|
classDiagram
|
||||||
note "From Duck till Zebra"
|
note "From Duck till Zebra"
|
||||||
Animal <|-- Duck
|
Animal <|-- Duck
|
||||||
note for Duck "can fly<br>can swim<br>can dive<br>can help in debugging"
|
note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging"
|
||||||
Animal <|-- Fish
|
Animal <|-- Fish
|
||||||
Animal <|-- Zebra
|
Animal <|-- Zebra
|
||||||
Animal : +int age
|
Animal : +int age
|
||||||
|
@@ -27,6 +27,53 @@ import { log } from '../../../logger.js';
|
|||||||
import { getSubGraphTitleMargins } from '../../../utils/subGraphTitleMargins.js';
|
import { getSubGraphTitleMargins } from '../../../utils/subGraphTitleMargins.js';
|
||||||
import { getConfig } from '../../../diagram-api/diagramAPI.js';
|
import { getConfig } from '../../../diagram-api/diagramAPI.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply absolute note positioning after dagre layout
|
||||||
|
* This fixes the issue where TB and LR directions position notes differently
|
||||||
|
* by making note positioning truly absolute
|
||||||
|
*/
|
||||||
|
const positionNotes = (graph) => {
|
||||||
|
const noteStatePairs = [];
|
||||||
|
|
||||||
|
graph.nodes().forEach((nodeId) => {
|
||||||
|
const node = graph.node(nodeId);
|
||||||
|
if (node.position && node.shape === 'note') {
|
||||||
|
const edges = graph.nodeEdges(nodeId);
|
||||||
|
|
||||||
|
for (const edge of edges) {
|
||||||
|
const otherNodeId = edge.v === nodeId ? edge.w : edge.v;
|
||||||
|
const otherNode = graph.node(otherNodeId);
|
||||||
|
|
||||||
|
if (otherNode && otherNode.shape !== 'note' && otherNode.shape !== 'noteGroup') {
|
||||||
|
noteStatePairs.push({
|
||||||
|
noteId: nodeId,
|
||||||
|
noteNode: node,
|
||||||
|
stateId: otherNodeId,
|
||||||
|
stateNode: otherNode,
|
||||||
|
position: node.position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
noteStatePairs.forEach(({ noteNode, stateNode, position }) => {
|
||||||
|
const spacing = 60;
|
||||||
|
|
||||||
|
let noteX = noteNode.x;
|
||||||
|
let noteY = stateNode.y;
|
||||||
|
|
||||||
|
if (position === 'right of') {
|
||||||
|
noteX = stateNode.x + stateNode.width / 2 + spacing + noteNode.width / 2;
|
||||||
|
} else if (position === 'left of') {
|
||||||
|
noteX = stateNode.x - stateNode.width / 2 - spacing - noteNode.width / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
noteNode.x = noteX;
|
||||||
|
noteNode.y = noteY;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, siteConfig) => {
|
const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, siteConfig) => {
|
||||||
log.warn('Graph in recursive render:XAX', graphlibJson.write(graph), parentCluster);
|
log.warn('Graph in recursive render:XAX', graphlibJson.write(graph), parentCluster);
|
||||||
const dir = graph.graph().rankdir;
|
const dir = graph.graph().rankdir;
|
||||||
@@ -164,6 +211,9 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
|
|||||||
|
|
||||||
dagreLayout(graph);
|
dagreLayout(graph);
|
||||||
|
|
||||||
|
// Apply absolute note positioning after dagre layout
|
||||||
|
positionNotes(graph);
|
||||||
|
|
||||||
log.info('Graph after layout:', JSON.stringify(graphlibJson.write(graph)));
|
log.info('Graph after layout:', JSON.stringify(graphlibJson.write(graph)));
|
||||||
// Move the nodes to the correct place
|
// Move the nodes to the correct place
|
||||||
let diff = 0;
|
let diff = 0;
|
||||||
|
@@ -605,14 +605,6 @@ export const insertEdge = function (
|
|||||||
const edgeStyles = Array.isArray(edge.style) ? edge.style : [edge.style];
|
const edgeStyles = Array.isArray(edge.style) ? edge.style : [edge.style];
|
||||||
let strokeColor = edgeStyles.find((style) => style?.startsWith('stroke:'));
|
let strokeColor = edgeStyles.find((style) => style?.startsWith('stroke:'));
|
||||||
|
|
||||||
let animationClass = '';
|
|
||||||
if (edge.animate) {
|
|
||||||
animationClass = 'edge-animation-fast';
|
|
||||||
}
|
|
||||||
if (edge.animation) {
|
|
||||||
animationClass = 'edge-animation-' + edge.animation;
|
|
||||||
}
|
|
||||||
|
|
||||||
let animatedEdge = false;
|
let animatedEdge = false;
|
||||||
if (edge.look === 'handDrawn') {
|
if (edge.look === 'handDrawn') {
|
||||||
const rc = rough.svg(elem);
|
const rc = rough.svg(elem);
|
||||||
@@ -628,13 +620,7 @@ export const insertEdge = function (
|
|||||||
svgPath = select(svgPathNode)
|
svgPath = select(svgPathNode)
|
||||||
.select('path')
|
.select('path')
|
||||||
.attr('id', edge.id)
|
.attr('id', edge.id)
|
||||||
.attr(
|
.attr('class', ' ' + strokeClasses + (edge.classes ? ' ' + edge.classes : ''))
|
||||||
'class',
|
|
||||||
' ' +
|
|
||||||
strokeClasses +
|
|
||||||
(edge.classes ? ' ' + edge.classes : '') +
|
|
||||||
(animationClass ? ' ' + animationClass : '')
|
|
||||||
)
|
|
||||||
.attr('style', edgeStyles ? edgeStyles.reduce((acc, style) => acc + ';' + style, '') : '');
|
.attr('style', edgeStyles ? edgeStyles.reduce((acc, style) => acc + ';' + style, '') : '');
|
||||||
let d = svgPath.attr('d');
|
let d = svgPath.attr('d');
|
||||||
svgPath.attr('d', d);
|
svgPath.attr('d', d);
|
||||||
@@ -642,6 +628,13 @@ export const insertEdge = function (
|
|||||||
} else {
|
} else {
|
||||||
const stylesFromClasses = edgeClassStyles.join(';');
|
const stylesFromClasses = edgeClassStyles.join(';');
|
||||||
const styles = edgeStyles ? edgeStyles.reduce((acc, style) => acc + style + ';', '') : '';
|
const styles = edgeStyles ? edgeStyles.reduce((acc, style) => acc + style + ';', '') : '';
|
||||||
|
let animationClass = '';
|
||||||
|
if (edge.animate) {
|
||||||
|
animationClass = ' edge-animation-fast';
|
||||||
|
}
|
||||||
|
if (edge.animation) {
|
||||||
|
animationClass = ' edge-animation-' + edge.animation;
|
||||||
|
}
|
||||||
|
|
||||||
const pathStyle =
|
const pathStyle =
|
||||||
(stylesFromClasses ? stylesFromClasses + ';' + styles + ';' : styles) +
|
(stylesFromClasses ? stylesFromClasses + ';' + styles + ';' : styles) +
|
||||||
@@ -653,10 +646,7 @@ export const insertEdge = function (
|
|||||||
.attr('id', edge.id)
|
.attr('id', edge.id)
|
||||||
.attr(
|
.attr(
|
||||||
'class',
|
'class',
|
||||||
' ' +
|
' ' + strokeClasses + (edge.classes ? ' ' + edge.classes : '') + (animationClass ?? '')
|
||||||
strokeClasses +
|
|
||||||
(edge.classes ? ' ' + edge.classes : '') +
|
|
||||||
(animationClass ? ' ' + animationClass : '')
|
|
||||||
)
|
)
|
||||||
.attr('style', pathStyle);
|
.attr('style', pathStyle);
|
||||||
|
|
||||||
|
@@ -130,6 +130,7 @@ const lollipop = (elem, type, id) => {
|
|||||||
.attr('markerHeight', 240)
|
.attr('markerHeight', 240)
|
||||||
.attr('orient', 'auto')
|
.attr('orient', 'auto')
|
||||||
.append('circle')
|
.append('circle')
|
||||||
|
.attr('stroke', 'black')
|
||||||
.attr('fill', 'transparent')
|
.attr('fill', 'transparent')
|
||||||
.attr('cx', 7)
|
.attr('cx', 7)
|
||||||
.attr('cy', 7)
|
.attr('cy', 7)
|
||||||
@@ -146,6 +147,7 @@ const lollipop = (elem, type, id) => {
|
|||||||
.attr('markerHeight', 240)
|
.attr('markerHeight', 240)
|
||||||
.attr('orient', 'auto')
|
.attr('orient', 'auto')
|
||||||
.append('circle')
|
.append('circle')
|
||||||
|
.attr('stroke', 'black')
|
||||||
.attr('fill', 'transparent')
|
.attr('fill', 'transparent')
|
||||||
.attr('cx', 7)
|
.attr('cx', 7)
|
||||||
.attr('cy', 7)
|
.attr('cy', 7)
|
||||||
|
Reference in New Issue
Block a user