#5237 Enabling edges using the unified renderer for flowcharts

This commit is contained in:
Knut Sveidqvist
2024-06-04 16:34:20 +02:00
parent d9d4a677ab
commit a85f36c3be
11 changed files with 89 additions and 69 deletions

View File

@@ -76,47 +76,31 @@
</head> </head>
<body> <body>
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid2">
%%{ stateDiagram-v2
init: { state if_state <<choice>>
"theme":"base", [*] --> IsPositive
"fontFamily": "Kalam", IsPositive --> if_state
"themeVariables": if_state --> False: if n < 0
{ if_state --> True : if n >= 0
"background": "#FFFFFF",
"primaryColor": "#7bdfa7",
"primaryTextColor": "#3c3c3b",
"secondaryColor": "#642470",
"secondaryTextColor": "#3c3c3b",
"tertiaryColor": "#1c736D",
"tertiaryTextColor": "#3c3c3b",
"noteBkgColor": "#9fd8ef",
"loopTextColor": "#636362",
"labelBoxBkgColor": "#642470",
"labelBoxBorderColor": "#642470",
"labelTextColor": "#d4d4d4",
"signalTextColor": "#636362",
"signalColor": "#642470"
}
}
}%%
sequenceDiagram
Alice->>+John: Hello John, how are you?
Alice->>+John: John, can you hear me?
John-->>-Alice: Hi Alice, I can hear you!
John-->>-Alice: I feel great!
</pre </pre
> >
<pre id="diagram" class="mermaid2">
flowchart LR
A[Start] --> B{Is it?} --> B1 & B2
<pre id="diagram" class="mermaid2">
%%{init: {"layout": "dagre", "mergeEdges": true} }%%
stateDiagram
A: This is A
</pre </pre
> >
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid">
%%{init: {"layout": "dagre", "mergeEdges": true} }%% %%{init: {"layout": "dagre", "mergeEdges": false} }%%
flowchart flowchart LR
A --> B(This is B) A ==> B(This is B)
A[Start] --> B(Is it?)
B -- Yes --> C[OK]
C --> D[Rethink]
D --> B
B -. No ...-> E[End]
</pre </pre
> >
<pre id="diagram" class="mermaid2"> <pre id="diagram" class="mermaid2">
@@ -129,7 +113,7 @@ flowchart
if_state --> True : if n >= 0 if_state --> True : if n >= 0
</pre </pre
> >
<pre id="diagram" class="mermaid"> <pre id="diagram" class="mermaid2">
%%{init: {"layout": "elk", "mergeEdges": false, "elk.nodePlacement.strategy": "SIMPLE"} }%% %%{init: {"layout": "elk", "mergeEdges": false, "elk.nodePlacement.strategy": "SIMPLE"} }%%
stateDiagram stateDiagram
state if_state &lt;&lt;choice&gt;&gt; state if_state &lt;&lt;choice&gt;&gt;
@@ -228,11 +212,13 @@ stateDiagram-v2
}; };
mermaid.initialize({ mermaid.initialize({
// theme: 'base', // theme: 'base',
handdrawnSeed: 12, // handdrawnSeed: 12,
look: 'handdrawn', // look: 'handdrawn',
'elk.nodePlacement.strategy': 'NETWORK_SIMPLEX',
// layout: 'dagre', layout: 'dagre',
// layout: 'elk', // layout: 'elk',
// layout: 'fixed',
htmlLabels: false,
flowchart: { titleTopMargin: 10 }, flowchart: { titleTopMargin: 10 },
// fontFamily: 'Caveat', // fontFamily: 'Caveat',
fontFamily: 'Kalam', fontFamily: 'Kalam',

View File

@@ -561,8 +561,8 @@ export const render = async (data4Layout, svg, element, algorithm) => {
drawNodes(0, 0, g.children, svg, subGraphsEl, 0); drawNodes(0, 0, g.children, svg, subGraphsEl, 0);
g.edges?.map((edge) => { g.edges?.map((edge) => {
// (elem, edge, clusterDb, diagramType, graph, id) // (elem, edge, clusterDb, diagramType, graph, id)
edge.start = nodeDb[edge.sources[0]]; const startNode = nodeDb[edge.sources[0]];
edge.end = nodeDb[edge.targets[0]]; const endNode = nodeDb[edge.targets[0]];
const sourceId = edge.start.id; const sourceId = edge.start.id;
const targetId = edge.end.id; const targetId = edge.end.id;
@@ -586,7 +586,8 @@ export const render = async (data4Layout, svg, element, algorithm) => {
edge, edge,
clusterDb, clusterDb,
data4Layout.type, data4Layout.type,
g, startNode,
endNode,
data4Layout.diagramId data4Layout.diagramId
); );

View File

@@ -1,5 +1,5 @@
import { select } from 'd3'; import { select } from 'd3';
import utils from '../../utils.js'; import utils, { getEdgeId } from '../../utils.js';
import { getConfig, defaultConfig } from '../../diagram-api/diagramAPI.js'; import { getConfig, defaultConfig } from '../../diagram-api/diagramAPI.js';
import common from '../common/common.js'; import common from '../common/common.js';
import type { LayoutData, LayoutMethod, Node, Edge } from '../../rendering-util/types.js'; import type { LayoutData, LayoutMethod, Node, Edge } from '../../rendering-util/types.js';
@@ -794,6 +794,37 @@ export const getData = () => {
nodes.push(node); nodes.push(node);
}); });
const e = getEdges();
e.forEach((rawEdge, index) => {
const edge: Edge = {
id: getEdgeId(rawEdge.start, rawEdge.end, { counter: index, prefix: 'edge' }),
start: rawEdge.start,
end: rawEdge.end,
type: rawEdge.type || 'normal',
label: rawEdge.text,
labelpos: 'c',
// labelStyle: '',
// cssStyles: rawEdge.styles.join(' '),
thickness: rawEdge.stroke,
minlen: rawEdge.length,
classes: 'edge-thickness-normal edge-pattern-solid flowchart-link',
arrowhead: 'none',
arrowTypeEnd: 'arrow_point',
arrowheadStyle: 'fill: #333',
// stroke: rawEdge.pattern,
pattern: rawEdge.stroke,
// shape: getTypeFromVertex(rawEdge),
// dir: rawEdge.dir,
// domId: verawEdgertex.domId,
// rawEdge: undefined,
// isGroup: false,
useRough,
};
// console.log('rawEdge SPLIT', rawEdge, index);
edges.push(edge);
});
console.log('edges SPLIT', edges);
//const useRough = config.look === 'handdrawn'; //const useRough = config.look === 'handdrawn';
return { nodes, edges, other: {}, config }; return { nodes, edges, other: {}, config };

View File

@@ -1,7 +1,7 @@
// @ts-ignore: JISON doesn't support types // @ts-ignore: JISON doesn't support types
import flowParser from './parser/flow.jison'; import flowParser from './parser/flow.jison';
import flowDb from './flowDb.js'; import flowDb from './flowDb.js';
// import flowRendererV2 from './flowRenderer-v2.js'; import flowRendererV2 from './flowRenderer-v2.js';
import flowRendererV3 from './flowRenderer-v3-unified.js'; import flowRendererV3 from './flowRenderer-v3-unified.js';
import flowStyles from './styles.js'; import flowStyles from './styles.js';
import type { MermaidConfig } from '../../config.type.js'; import type { MermaidConfig } from '../../config.type.js';

View File

@@ -60,7 +60,8 @@ export const draw = async function (text: string, id: string, _version: string,
data4Layout.direction = DIR; data4Layout.direction = DIR;
data4Layout.nodeSpacing = conf?.nodeSpacing || 50; data4Layout.nodeSpacing = conf?.nodeSpacing || 50;
data4Layout.rankSpacing = conf?.rankSpacing || 50; data4Layout.rankSpacing = conf?.rankSpacing || 50;
data4Layout.markers = ['barb']; data4Layout.markers = ['point', 'circle', 'cross'];
data4Layout.diagramId = id; data4Layout.diagramId = id;
console.log('REF1:', data4Layout); console.log('REF1:', data4Layout);
await render(data4Layout, svg, element); await render(data4Layout, svg, element);

View File

@@ -23,7 +23,7 @@ export interface FlowEdge {
end: string; end: string;
interpolate?: string; interpolate?: string;
type?: string; type?: string;
stroke?: string; stroke?: 'normal' | 'thick' | 'invisible';
style?: string[]; style?: string[];
length?: number; length?: number;
text: string; text: string;

View File

@@ -579,7 +579,6 @@ export const getData = () => {
// nodes.push({...currentDocument.states[key]}); // nodes.push({...currentDocument.states[key]});
// } // }
// } // }
extract(getRootDocV2());
const diagramStates = getStates(); const diagramStates = getStates();
const config = getConfig(); const config = getConfig();
const useRough = config.look === 'handdrawn'; const useRough = config.look === 'handdrawn';

View File

@@ -230,7 +230,9 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge); log.info('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(edge), edge);
edge.points.forEach((point) => (point.y += subGraphTitleTotalMargin / 2)); edge.points.forEach((point) => (point.y += subGraphTitleTotalMargin / 2));
const paths = insertEdge(edgePaths, edge, clusterDb, diagramType, graph, id); const startNode = graph.node(e.v);
var endNode = graph.node(e.w);
const paths = insertEdge(edgePaths, edge, clusterDb, diagramType, startNode, endNode, id);
positionEdgeLabel(edge, paths); positionEdgeLabel(edge, paths);
}); });
@@ -284,7 +286,7 @@ export const render = async (data4Layout, svg, element) => {
log.debug('Edges:', data4Layout.edges); log.debug('Edges:', data4Layout.edges);
data4Layout.edges.forEach((edge) => { data4Layout.edges.forEach((edge) => {
graph.setEdge(edge.start, edge.end, { ...edge }); graph.setEdge(edge.start, edge.end, { ...edge }, edge.id);
}); });
log.warn('Graph at first:', JSON.stringify(graphlibJson.write(graph))); log.warn('Graph at first:', JSON.stringify(graphlibJson.write(graph)));

View File

@@ -493,28 +493,28 @@ function roundedCornersLine(lineData) {
} }
return path; return path;
} }
export const insertEdge = function (elem, edge, clusterDb, diagramType, graph, id) { export const insertEdge = function (elem, edge, clusterDb, diagramType, startNode, endNode, id) {
const { handdrawnSeed } = getConfig(); const { handdrawnSeed } = getConfig();
let points = edge.points; let points = edge.points;
let pointsHasChanged = false; let pointsHasChanged = false;
const tail = edge.start; const tail = startNode;
var head = edge.end; var head = endNode;
log.info('abc88 InsertEdge: ', points); // log.info('abc88 InsertEdge SPLIT: ', points, edge.start, id);
if (head.intersect && tail.intersect) { if (head.intersect && tail.intersect) {
log.info('abc88 InsertEdge: 0.5', points); // log.info('abc88 InsertEdge SPLIT: 0.5', points);
// points = points.slice(1, edge.points.length - 1); points = points.slice(1, edge.points.length - 1);
log.info('abc88 InsertEdge: 0.7', points); // log.info('abc88 InsertEdge SPLIT: 0.7', points);
// points.unshift(tail.intersect(points[0])); points.unshift(tail.intersect(points[0]));
// log.info( log.info(
// 'Last point abc88', 'Last point abc88',
// points[points.length - 1], points[points.length - 1],
// head, head,
// head.intersect(points[points.length - 1]) head.intersect(points[points.length - 1])
// ); );
// points.push(head.intersect(points[points.length - 1])); points.push(head.intersect(points[points.length - 1]));
} }
log.info('abc88 InsertEdge 2: ', points); // log.info('abc88 InsertEdge 2 SPLIT: ', points);
if (edge.toCluster) { if (edge.toCluster) {
log.info('to cluster abc88', clusterDb[edge.toCluster]); log.info('to cluster abc88', clusterDb[edge.toCluster]);
points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node);

View File

@@ -65,7 +65,7 @@ export const question = async (parent: SVGAElement, node: Node): Promise<SVGAEle
updateNodeBounds(node, polygon); updateNodeBounds(node, polygon);
node.intersect = function (point) { node.intersect = function (point) {
log.warn('Intersect called'); log.info('Intersect called SPLIT');
return intersect.polygon(node, points, point); return intersect.polygon(node, points, point);
}; };

View File

@@ -90,7 +90,7 @@ interface Edge {
labelStyle?: string; labelStyle?: string;
minlen?: number; minlen?: number;
pattern?: string; pattern?: string;
thickness?: number; thickness?: 'normal' | 'thick' | 'invisible';
useRough?: boolean; useRough?: boolean;
} }