1 | import { d as db, p as parser } from "./flowDb-a707052f.js";
|
2 | import { select, curveLinear, line } from "d3";
|
3 | import { a as insertMarkers, e as insertNode, l as labelHelper, f as insertEdgeLabel } from "./edges-97052da4.js";
|
4 | import "dagre-d3-es/src/dagre-js/label/add-html-label.js";
|
5 | import { l as log, c as getConfig, p as setupGraphViewbox, k as getStylesFromArray, o as interpolateToCurve, e as common } from "./mermaid-a953d906.js";
|
6 | import ELK from "elkjs/lib/elk.bundled.js";
|
7 | import "./createText-2f679d62.js";
|
8 | import "mdast-util-from-markdown";
|
9 | import "ts-dedent";
|
10 | import "./svgDraw-6750006d.js";
|
11 | import "dayjs/esm/index.js";
|
12 | import "@braintree/sanitize-url";
|
13 | import "dompurify";
|
14 | import "khroma";
|
15 | import "lodash-es/memoize.js";
|
16 | import "stylis";
|
17 | import "lodash-es/isEmpty.js";
|
18 | const findCommonAncestor = (id1, id2, treeData) => {
|
19 | const { parentById } = treeData;
|
20 | const visited = new Set();
|
21 | let currentId = id1;
|
22 | while (currentId) {
|
23 | visited.add(currentId);
|
24 | if (currentId === id2) {
|
25 | return currentId;
|
26 | }
|
27 | currentId = parentById[currentId];
|
28 | }
|
29 | currentId = id2;
|
30 | while (currentId) {
|
31 | if (visited.has(currentId)) {
|
32 | return currentId;
|
33 | }
|
34 | currentId = parentById[currentId];
|
35 | }
|
36 | return "root";
|
37 | };
|
38 | const elk = new ELK();
|
39 | let portPos = {};
|
40 | const conf = {};
|
41 | let nodeDb = {};
|
42 | const addVertices = async function(vert, svgId, root, doc, diagObj, parentLookupDb, graph) {
|
43 | const svg = root.select(`[id="${svgId}"]`);
|
44 | const nodes = svg.insert("g").attr("class", "nodes");
|
45 | const keys = Object.keys(vert);
|
46 | await Promise.all(
|
47 | keys.map(async function(id) {
|
48 | const vertex = vert[id];
|
49 | let classStr = "default";
|
50 | if (vertex.classes.length > 0) {
|
51 | classStr = vertex.classes.join(" ");
|
52 | }
|
53 | classStr = classStr + " flowchart-label";
|
54 | const styles2 = getStylesFromArray(vertex.styles);
|
55 | let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id;
|
56 | const labelData = { width: 0, height: 0 };
|
57 | const ports = [
|
58 | {
|
59 | id: vertex.id + "-west",
|
60 | layoutOptions: {
|
61 | "port.side": "WEST"
|
62 | }
|
63 | },
|
64 | {
|
65 | id: vertex.id + "-east",
|
66 | layoutOptions: {
|
67 | "port.side": "EAST"
|
68 | }
|
69 | },
|
70 | {
|
71 | id: vertex.id + "-south",
|
72 | layoutOptions: {
|
73 | "port.side": "SOUTH"
|
74 | }
|
75 | },
|
76 | {
|
77 | id: vertex.id + "-north",
|
78 | layoutOptions: {
|
79 | "port.side": "NORTH"
|
80 | }
|
81 | }
|
82 | ];
|
83 | let radious = 0;
|
84 | let _shape = "";
|
85 | let layoutOptions = {};
|
86 | switch (vertex.type) {
|
87 | case "round":
|
88 | radious = 5;
|
89 | _shape = "rect";
|
90 | break;
|
91 | case "square":
|
92 | _shape = "rect";
|
93 | break;
|
94 | case "diamond":
|
95 | _shape = "question";
|
96 | layoutOptions = {
|
97 | portConstraints: "FIXED_SIDE"
|
98 | };
|
99 | break;
|
100 | case "hexagon":
|
101 | _shape = "hexagon";
|
102 | break;
|
103 | case "odd":
|
104 | _shape = "rect_left_inv_arrow";
|
105 | break;
|
106 | case "lean_right":
|
107 | _shape = "lean_right";
|
108 | break;
|
109 | case "lean_left":
|
110 | _shape = "lean_left";
|
111 | break;
|
112 | case "trapezoid":
|
113 | _shape = "trapezoid";
|
114 | break;
|
115 | case "inv_trapezoid":
|
116 | _shape = "inv_trapezoid";
|
117 | break;
|
118 | case "odd_right":
|
119 | _shape = "rect_left_inv_arrow";
|
120 | break;
|
121 | case "circle":
|
122 | _shape = "circle";
|
123 | break;
|
124 | case "ellipse":
|
125 | _shape = "ellipse";
|
126 | break;
|
127 | case "stadium":
|
128 | _shape = "stadium";
|
129 | break;
|
130 | case "subroutine":
|
131 | _shape = "subroutine";
|
132 | break;
|
133 | case "cylinder":
|
134 | _shape = "cylinder";
|
135 | break;
|
136 | case "group":
|
137 | _shape = "rect";
|
138 | break;
|
139 | case "doublecircle":
|
140 | _shape = "doublecircle";
|
141 | break;
|
142 | default:
|
143 | _shape = "rect";
|
144 | }
|
145 | const node = {
|
146 | labelStyle: styles2.labelStyle,
|
147 | shape: _shape,
|
148 | labelText: vertexText,
|
149 | labelType: vertex.labelType,
|
150 | rx: radious,
|
151 | ry: radious,
|
152 | class: classStr,
|
153 | style: styles2.style,
|
154 | id: vertex.id,
|
155 | link: vertex.link,
|
156 | linkTarget: vertex.linkTarget,
|
157 | tooltip: diagObj.db.getTooltip(vertex.id) || "",
|
158 | domId: diagObj.db.lookUpDomId(vertex.id),
|
159 | haveCallback: vertex.haveCallback,
|
160 | width: vertex.type === "group" ? 500 : void 0,
|
161 | dir: vertex.dir,
|
162 | type: vertex.type,
|
163 | props: vertex.props,
|
164 | padding: getConfig().flowchart.padding
|
165 | };
|
166 | let boundingBox;
|
167 | let nodeEl;
|
168 | if (node.type !== "group") {
|
169 | nodeEl = await insertNode(nodes, node, vertex.dir);
|
170 | boundingBox = nodeEl.node().getBBox();
|
171 | } else {
|
172 | doc.createElementNS("http://www.w3.org/2000/svg", "text");
|
173 | const { shapeSvg, bbox } = await labelHelper(nodes, node, void 0, true);
|
174 | labelData.width = bbox.width;
|
175 | labelData.wrappingWidth = getConfig().flowchart.wrappingWidth;
|
176 | labelData.height = bbox.height;
|
177 | labelData.labelNode = shapeSvg.node();
|
178 | node.labelData = labelData;
|
179 | }
|
180 | const data = {
|
181 | id: vertex.id,
|
182 | ports: vertex.type === "diamond" ? ports : [],
|
183 |
|
184 |
|
185 | layoutOptions,
|
186 | labelText: vertexText,
|
187 | labelData,
|
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 | domId: diagObj.db.lookUpDomId(vertex.id),
|
197 |
|
198 | width: boundingBox == null ? void 0 : boundingBox.width,
|
199 | height: boundingBox == null ? void 0 : boundingBox.height,
|
200 |
|
201 | type: vertex.type,
|
202 |
|
203 |
|
204 |
|
205 | el: nodeEl,
|
206 | parent: parentLookupDb.parentById[vertex.id]
|
207 | };
|
208 | nodeDb[node.id] = data;
|
209 | })
|
210 | );
|
211 | return graph;
|
212 | };
|
213 | const getNextPosition = (position, edgeDirection, graphDirection) => {
|
214 | const portPos2 = {
|
215 | TB: {
|
216 | in: {
|
217 | north: "north"
|
218 | },
|
219 | out: {
|
220 | south: "west",
|
221 | west: "east",
|
222 | east: "south"
|
223 | }
|
224 | },
|
225 | LR: {
|
226 | in: {
|
227 | west: "west"
|
228 | },
|
229 | out: {
|
230 | east: "south",
|
231 | south: "north",
|
232 | north: "east"
|
233 | }
|
234 | },
|
235 | RL: {
|
236 | in: {
|
237 | east: "east"
|
238 | },
|
239 | out: {
|
240 | west: "north",
|
241 | north: "south",
|
242 | south: "west"
|
243 | }
|
244 | },
|
245 | BT: {
|
246 | in: {
|
247 | south: "south"
|
248 | },
|
249 | out: {
|
250 | north: "east",
|
251 | east: "west",
|
252 | west: "north"
|
253 | }
|
254 | }
|
255 | };
|
256 | portPos2.TD = portPos2.TB;
|
257 | log.info("abc88", graphDirection, edgeDirection, position);
|
258 | return portPos2[graphDirection][edgeDirection][position];
|
259 | };
|
260 | const getNextPort = (node, edgeDirection, graphDirection) => {
|
261 | log.info("getNextPort abc88", { node, edgeDirection, graphDirection });
|
262 | if (!portPos[node]) {
|
263 | switch (graphDirection) {
|
264 | case "TB":
|
265 | case "TD":
|
266 | portPos[node] = {
|
267 | inPosition: "north",
|
268 | outPosition: "south"
|
269 | };
|
270 | break;
|
271 | case "BT":
|
272 | portPos[node] = {
|
273 | inPosition: "south",
|
274 | outPosition: "north"
|
275 | };
|
276 | break;
|
277 | case "RL":
|
278 | portPos[node] = {
|
279 | inPosition: "east",
|
280 | outPosition: "west"
|
281 | };
|
282 | break;
|
283 | case "LR":
|
284 | portPos[node] = {
|
285 | inPosition: "west",
|
286 | outPosition: "east"
|
287 | };
|
288 | break;
|
289 | }
|
290 | }
|
291 | const result = edgeDirection === "in" ? portPos[node].inPosition : portPos[node].outPosition;
|
292 | if (edgeDirection === "in") {
|
293 | portPos[node].inPosition = getNextPosition(
|
294 | portPos[node].inPosition,
|
295 | edgeDirection,
|
296 | graphDirection
|
297 | );
|
298 | } else {
|
299 | portPos[node].outPosition = getNextPosition(
|
300 | portPos[node].outPosition,
|
301 | edgeDirection,
|
302 | graphDirection
|
303 | );
|
304 | }
|
305 | return result;
|
306 | };
|
307 | const getEdgeStartEndPoint = (edge, dir) => {
|
308 | let source = edge.start;
|
309 | let target = edge.end;
|
310 | const sourceId = source;
|
311 | const targetId = target;
|
312 | const startNode = nodeDb[source];
|
313 | const endNode = nodeDb[target];
|
314 | if (!startNode || !endNode) {
|
315 | return { source, target };
|
316 | }
|
317 | if (startNode.type === "diamond") {
|
318 | source = `${source}-${getNextPort(source, "out", dir)}`;
|
319 | }
|
320 | if (endNode.type === "diamond") {
|
321 | target = `${target}-${getNextPort(target, "in", dir)}`;
|
322 | }
|
323 | return { source, target, sourceId, targetId };
|
324 | };
|
325 | const addEdges = function(edges, diagObj, graph, svg) {
|
326 | log.info("abc78 edges = ", edges);
|
327 | const labelsEl = svg.insert("g").attr("class", "edgeLabels");
|
328 | let linkIdCnt = {};
|
329 | let dir = diagObj.db.getDirection();
|
330 | let defaultStyle;
|
331 | let defaultLabelStyle;
|
332 | if (edges.defaultStyle !== void 0) {
|
333 | const defaultStyles = getStylesFromArray(edges.defaultStyle);
|
334 | defaultStyle = defaultStyles.style;
|
335 | defaultLabelStyle = defaultStyles.labelStyle;
|
336 | }
|
337 | edges.forEach(function(edge) {
|
338 | const linkIdBase = "L-" + edge.start + "-" + edge.end;
|
339 | if (linkIdCnt[linkIdBase] === void 0) {
|
340 | linkIdCnt[linkIdBase] = 0;
|
341 | log.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]);
|
342 | } else {
|
343 | linkIdCnt[linkIdBase]++;
|
344 | log.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]);
|
345 | }
|
346 | let linkId = linkIdBase + "-" + linkIdCnt[linkIdBase];
|
347 | log.info("abc78 new link id to be used is", linkIdBase, linkId, linkIdCnt[linkIdBase]);
|
348 | const linkNameStart = "LS-" + edge.start;
|
349 | const linkNameEnd = "LE-" + edge.end;
|
350 | const edgeData = { style: "", labelStyle: "" };
|
351 | edgeData.minlen = edge.length || 1;
|
352 | if (edge.type === "arrow_open") {
|
353 | edgeData.arrowhead = "none";
|
354 | } else {
|
355 | edgeData.arrowhead = "normal";
|
356 | }
|
357 | edgeData.arrowTypeStart = "arrow_open";
|
358 | edgeData.arrowTypeEnd = "arrow_open";
|
359 | switch (edge.type) {
|
360 | case "double_arrow_cross":
|
361 | edgeData.arrowTypeStart = "arrow_cross";
|
362 | case "arrow_cross":
|
363 | edgeData.arrowTypeEnd = "arrow_cross";
|
364 | break;
|
365 | case "double_arrow_point":
|
366 | edgeData.arrowTypeStart = "arrow_point";
|
367 | case "arrow_point":
|
368 | edgeData.arrowTypeEnd = "arrow_point";
|
369 | break;
|
370 | case "double_arrow_circle":
|
371 | edgeData.arrowTypeStart = "arrow_circle";
|
372 | case "arrow_circle":
|
373 | edgeData.arrowTypeEnd = "arrow_circle";
|
374 | break;
|
375 | }
|
376 | let style = "";
|
377 | let labelStyle = "";
|
378 | switch (edge.stroke) {
|
379 | case "normal":
|
380 | style = "fill:none;";
|
381 | if (defaultStyle !== void 0) {
|
382 | style = defaultStyle;
|
383 | }
|
384 | if (defaultLabelStyle !== void 0) {
|
385 | labelStyle = defaultLabelStyle;
|
386 | }
|
387 | edgeData.thickness = "normal";
|
388 | edgeData.pattern = "solid";
|
389 | break;
|
390 | case "dotted":
|
391 | edgeData.thickness = "normal";
|
392 | edgeData.pattern = "dotted";
|
393 | edgeData.style = "fill:none;stroke-width:2px;stroke-dasharray:3;";
|
394 | break;
|
395 | case "thick":
|
396 | edgeData.thickness = "thick";
|
397 | edgeData.pattern = "solid";
|
398 | edgeData.style = "stroke-width: 3.5px;fill:none;";
|
399 | break;
|
400 | }
|
401 | if (edge.style !== void 0) {
|
402 | const styles2 = getStylesFromArray(edge.style);
|
403 | style = styles2.style;
|
404 | labelStyle = styles2.labelStyle;
|
405 | }
|
406 | edgeData.style = edgeData.style += style;
|
407 | edgeData.labelStyle = edgeData.labelStyle += labelStyle;
|
408 | if (edge.interpolate !== void 0) {
|
409 | edgeData.curve = interpolateToCurve(edge.interpolate, curveLinear);
|
410 | } else if (edges.defaultInterpolate !== void 0) {
|
411 | edgeData.curve = interpolateToCurve(edges.defaultInterpolate, curveLinear);
|
412 | } else {
|
413 | edgeData.curve = interpolateToCurve(conf.curve, curveLinear);
|
414 | }
|
415 | if (edge.text === void 0) {
|
416 | if (edge.style !== void 0) {
|
417 | edgeData.arrowheadStyle = "fill: #333";
|
418 | }
|
419 | } else {
|
420 | edgeData.arrowheadStyle = "fill: #333";
|
421 | edgeData.labelpos = "c";
|
422 | }
|
423 | edgeData.labelType = edge.labelType;
|
424 | edgeData.label = edge.text.replace(common.lineBreakRegex, "\n");
|
425 | if (edge.style === void 0) {
|
426 | edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none;";
|
427 | }
|
428 | edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:");
|
429 | edgeData.id = linkId;
|
430 | edgeData.classes = "flowchart-link " + linkNameStart + " " + linkNameEnd;
|
431 | const labelEl = insertEdgeLabel(labelsEl, edgeData);
|
432 | const { source, target, sourceId, targetId } = getEdgeStartEndPoint(edge, dir);
|
433 | log.debug("abc78 source and target", source, target);
|
434 | graph.edges.push({
|
435 | id: "e" + edge.start + edge.end,
|
436 | sources: [source],
|
437 | targets: [target],
|
438 | sourceId,
|
439 | targetId,
|
440 | labelEl,
|
441 | labels: [
|
442 | {
|
443 | width: edgeData.width,
|
444 | height: edgeData.height,
|
445 | orgWidth: edgeData.width,
|
446 | orgHeight: edgeData.height,
|
447 | text: edgeData.label,
|
448 | layoutOptions: {
|
449 | "edgeLabels.inline": "true",
|
450 | "edgeLabels.placement": "CENTER"
|
451 | }
|
452 | }
|
453 | ],
|
454 | edgeData
|
455 | });
|
456 | });
|
457 | return graph;
|
458 | };
|
459 | const addMarkersToEdge = function(svgPath, edgeData, diagramType, arrowMarkerAbsolute) {
|
460 | let url = "";
|
461 | if (arrowMarkerAbsolute) {
|
462 | url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search;
|
463 | url = url.replace(/\(/g, "\\(");
|
464 | url = url.replace(/\)/g, "\\)");
|
465 | }
|
466 | switch (edgeData.arrowTypeStart) {
|
467 | case "arrow_cross":
|
468 | svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-crossStart)");
|
469 | break;
|
470 | case "arrow_point":
|
471 | svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-pointStart)");
|
472 | break;
|
473 | case "arrow_barb":
|
474 | svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-barbStart)");
|
475 | break;
|
476 | case "arrow_circle":
|
477 | svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-circleStart)");
|
478 | break;
|
479 | case "aggregation":
|
480 | svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-aggregationStart)");
|
481 | break;
|
482 | case "extension":
|
483 | svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-extensionStart)");
|
484 | break;
|
485 | case "composition":
|
486 | svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-compositionStart)");
|
487 | break;
|
488 | case "dependency":
|
489 | svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-dependencyStart)");
|
490 | break;
|
491 | case "lollipop":
|
492 | svgPath.attr("marker-start", "url(" + url + "#" + diagramType + "-lollipopStart)");
|
493 | break;
|
494 | }
|
495 | switch (edgeData.arrowTypeEnd) {
|
496 | case "arrow_cross":
|
497 | svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-crossEnd)");
|
498 | break;
|
499 | case "arrow_point":
|
500 | svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-pointEnd)");
|
501 | break;
|
502 | case "arrow_barb":
|
503 | svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-barbEnd)");
|
504 | break;
|
505 | case "arrow_circle":
|
506 | svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-circleEnd)");
|
507 | break;
|
508 | case "aggregation":
|
509 | svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-aggregationEnd)");
|
510 | break;
|
511 | case "extension":
|
512 | svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-extensionEnd)");
|
513 | break;
|
514 | case "composition":
|
515 | svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-compositionEnd)");
|
516 | break;
|
517 | case "dependency":
|
518 | svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-dependencyEnd)");
|
519 | break;
|
520 | case "lollipop":
|
521 | svgPath.attr("marker-end", "url(" + url + "#" + diagramType + "-lollipopEnd)");
|
522 | break;
|
523 | }
|
524 | };
|
525 | const getClasses = function(text, diagObj) {
|
526 | log.info("Extracting classes");
|
527 | diagObj.db.clear("ver-2");
|
528 | try {
|
529 | diagObj.parse(text);
|
530 | return diagObj.db.getClasses();
|
531 | } catch (e) {
|
532 | return {};
|
533 | }
|
534 | };
|
535 | const addSubGraphs = function(db2) {
|
536 | const parentLookupDb = { parentById: {}, childrenById: {} };
|
537 | const subgraphs = db2.getSubGraphs();
|
538 | log.info("Subgraphs - ", subgraphs);
|
539 | subgraphs.forEach(function(subgraph) {
|
540 | subgraph.nodes.forEach(function(node) {
|
541 | parentLookupDb.parentById[node] = subgraph.id;
|
542 | if (parentLookupDb.childrenById[subgraph.id] === void 0) {
|
543 | parentLookupDb.childrenById[subgraph.id] = [];
|
544 | }
|
545 | parentLookupDb.childrenById[subgraph.id].push(node);
|
546 | });
|
547 | });
|
548 | subgraphs.forEach(function(subgraph) {
|
549 | ({ id: subgraph.id });
|
550 | if (parentLookupDb.parentById[subgraph.id] !== void 0) {
|
551 | parentLookupDb.parentById[subgraph.id];
|
552 | }
|
553 | });
|
554 | return parentLookupDb;
|
555 | };
|
556 | const calcOffset = function(src, dest, parentLookupDb) {
|
557 | const ancestor = findCommonAncestor(src, dest, parentLookupDb);
|
558 | if (ancestor === void 0 || ancestor === "root") {
|
559 | return { x: 0, y: 0 };
|
560 | }
|
561 | const ancestorOffset = nodeDb[ancestor].offset;
|
562 | return { x: ancestorOffset.posX, y: ancestorOffset.posY };
|
563 | };
|
564 | const insertEdge = function(edgesEl, edge, edgeData, diagObj, parentLookupDb) {
|
565 | const offset = calcOffset(edge.sourceId, edge.targetId, parentLookupDb);
|
566 | const src = edge.sections[0].startPoint;
|
567 | const dest = edge.sections[0].endPoint;
|
568 | const segments = edge.sections[0].bendPoints ? edge.sections[0].bendPoints : [];
|
569 | const segPoints = segments.map((segment) => [segment.x + offset.x, segment.y + offset.y]);
|
570 | const points = [
|
571 | [src.x + offset.x, src.y + offset.y],
|
572 | ...segPoints,
|
573 | [dest.x + offset.x, dest.y + offset.y]
|
574 | ];
|
575 | const curve = line().curve(curveLinear);
|
576 | const edgePath = edgesEl.insert("path").attr("d", curve(points)).attr("class", "path").attr("fill", "none");
|
577 | const edgeG = edgesEl.insert("g").attr("class", "edgeLabel");
|
578 | const edgeWithLabel = select(edgeG.node().appendChild(edge.labelEl));
|
579 | const box = edgeWithLabel.node().firstChild.getBoundingClientRect();
|
580 | edgeWithLabel.attr("width", box.width);
|
581 | edgeWithLabel.attr("height", box.height);
|
582 | edgeG.attr(
|
583 | "transform",
|
584 | `translate(${edge.labels[0].x + offset.x}, ${edge.labels[0].y + offset.y})`
|
585 | );
|
586 | addMarkersToEdge(edgePath, edgeData, diagObj.type, diagObj.arrowMarkerAbsolute);
|
587 | };
|
588 | const insertChildren = (nodeArray, parentLookupDb) => {
|
589 | nodeArray.forEach((node) => {
|
590 | if (!node.children) {
|
591 | node.children = [];
|
592 | }
|
593 | const childIds = parentLookupDb.childrenById[node.id];
|
594 | if (childIds) {
|
595 | childIds.forEach((childId) => {
|
596 | node.children.push(nodeDb[childId]);
|
597 | });
|
598 | }
|
599 | insertChildren(node.children, parentLookupDb);
|
600 | });
|
601 | };
|
602 | const draw = async function(text, id, _version, diagObj) {
|
603 | var _a;
|
604 | diagObj.db.clear();
|
605 | nodeDb = {};
|
606 | portPos = {};
|
607 | diagObj.db.setGen("gen-2");
|
608 | diagObj.parser.parse(text);
|
609 | const renderEl = select("body").append("div").attr("style", "height:400px").attr("id", "cy");
|
610 | let graph = {
|
611 | id: "root",
|
612 | layoutOptions: {
|
613 | "elk.hierarchyHandling": "INCLUDE_CHILDREN",
|
614 | "org.eclipse.elk.padding": "[top=100, left=100, bottom=110, right=110]",
|
615 | "elk.layered.spacing.edgeNodeBetweenLayers": "30",
|
616 |
|
617 | "elk.direction": "DOWN"
|
618 |
|
619 |
|
620 | },
|
621 | children: [],
|
622 | edges: []
|
623 | };
|
624 | log.info("Drawing flowchart using v3 renderer", elk);
|
625 | let dir = diagObj.db.getDirection();
|
626 | switch (dir) {
|
627 | case "BT":
|
628 | graph.layoutOptions["elk.direction"] = "UP";
|
629 | break;
|
630 | case "TB":
|
631 | graph.layoutOptions["elk.direction"] = "DOWN";
|
632 | break;
|
633 | case "LR":
|
634 | graph.layoutOptions["elk.direction"] = "RIGHT";
|
635 | break;
|
636 | case "RL":
|
637 | graph.layoutOptions["elk.direction"] = "LEFT";
|
638 | break;
|
639 | }
|
640 | const { securityLevel, flowchart: conf2 } = getConfig();
|
641 | let sandboxElement;
|
642 | if (securityLevel === "sandbox") {
|
643 | sandboxElement = select("#i" + id);
|
644 | }
|
645 | const root = securityLevel === "sandbox" ? select(sandboxElement.nodes()[0].contentDocument.body) : select("body");
|
646 | const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document;
|
647 | const svg = root.select(`[id="${id}"]`);
|
648 | const markers = ["point", "circle", "cross"];
|
649 | insertMarkers(svg, markers, diagObj.type, diagObj.arrowMarkerAbsolute);
|
650 | const vert = diagObj.db.getVertices();
|
651 | let subG;
|
652 | const subGraphs = diagObj.db.getSubGraphs();
|
653 | log.info("Subgraphs - ", subGraphs);
|
654 | for (let i = subGraphs.length - 1; i >= 0; i--) {
|
655 | subG = subGraphs[i];
|
656 | diagObj.db.addVertex(
|
657 | subG.id,
|
658 | { text: subG.title, type: subG.labelType },
|
659 | "group",
|
660 | void 0,
|
661 | subG.classes,
|
662 | subG.dir
|
663 | );
|
664 | }
|
665 | const subGraphsEl = svg.insert("g").attr("class", "subgraphs");
|
666 | const parentLookupDb = addSubGraphs(diagObj.db);
|
667 | graph = await addVertices(vert, id, root, doc, diagObj, parentLookupDb, graph);
|
668 | const edgesEl = svg.insert("g").attr("class", "edges edgePath");
|
669 | const edges = diagObj.db.getEdges();
|
670 | graph = addEdges(edges, diagObj, graph, svg);
|
671 | const nodes = Object.keys(nodeDb);
|
672 | nodes.forEach((nodeId) => {
|
673 | const node = nodeDb[nodeId];
|
674 | if (!node.parent) {
|
675 | graph.children.push(node);
|
676 | }
|
677 | if (parentLookupDb.childrenById[nodeId] !== void 0) {
|
678 | node.labels = [
|
679 | {
|
680 | text: node.labelText,
|
681 | layoutOptions: {
|
682 | "nodeLabels.placement": "[H_CENTER, V_TOP, INSIDE]"
|
683 | },
|
684 | width: node.labelData.width,
|
685 | height: node.labelData.height
|
686 |
|
687 |
|
688 | }
|
689 | ];
|
690 | delete node.x;
|
691 | delete node.y;
|
692 | delete node.width;
|
693 | delete node.height;
|
694 | }
|
695 | });
|
696 | insertChildren(graph.children, parentLookupDb);
|
697 | log.info("after layout", JSON.stringify(graph, null, 2));
|
698 | const g = await elk.layout(graph);
|
699 | drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0);
|
700 | log.info("after layout", g);
|
701 | (_a = g.edges) == null ? void 0 : _a.map((edge) => {
|
702 | insertEdge(edgesEl, edge, edge.edgeData, diagObj, parentLookupDb);
|
703 | });
|
704 | setupGraphViewbox({}, svg, conf2.diagramPadding, conf2.useMaxWidth);
|
705 | renderEl.remove();
|
706 | };
|
707 | const drawNodes = (relX, relY, nodeArray, svg, subgraphsEl, diagObj, depth) => {
|
708 | nodeArray.forEach(function(node) {
|
709 | if (node) {
|
710 | nodeDb[node.id].offset = {
|
711 | posX: node.x + relX,
|
712 | posY: node.y + relY,
|
713 | x: relX,
|
714 | y: relY,
|
715 | depth,
|
716 | width: node.width,
|
717 | height: node.height
|
718 | };
|
719 | if (node.type === "group") {
|
720 | const subgraphEl = subgraphsEl.insert("g").attr("class", "subgraph");
|
721 | subgraphEl.insert("rect").attr("class", "subgraph subgraph-lvl-" + depth % 5 + " node").attr("x", node.x + relX).attr("y", node.y + relY).attr("width", node.width).attr("height", node.height);
|
722 | const label = subgraphEl.insert("g").attr("class", "label");
|
723 | const labelCentering = getConfig().flowchart.htmlLabels ? node.labelData.width / 2 : 0;
|
724 | label.attr(
|
725 | "transform",
|
726 | `translate(${node.labels[0].x + relX + node.x + labelCentering}, ${node.labels[0].y + relY + node.y + 3})`
|
727 | );
|
728 | label.node().appendChild(node.labelData.labelNode);
|
729 | log.info("Id (UGH)= ", node.type, node.labels);
|
730 | } else {
|
731 | log.info("Id (UGH)= ", node.id);
|
732 | node.el.attr(
|
733 | "transform",
|
734 | `translate(${node.x + relX + node.width / 2}, ${node.y + relY + node.height / 2})`
|
735 | );
|
736 | }
|
737 | }
|
738 | });
|
739 | nodeArray.forEach(function(node) {
|
740 | if (node && node.type === "group") {
|
741 | drawNodes(relX + node.x, relY + node.y, node.children, svg, subgraphsEl, diagObj, depth + 1);
|
742 | }
|
743 | });
|
744 | };
|
745 | const renderer = {
|
746 | getClasses,
|
747 | draw
|
748 | };
|
749 | const genSections = (options) => {
|
750 | let sections = "";
|
751 | for (let i = 0; i < 5; i++) {
|
752 | sections += `
|
753 | .subgraph-lvl-${i} {
|
754 | fill: ${options[`surface${i}`]};
|
755 | stroke: ${options[`surfacePeer${i}`]};
|
756 | }
|
757 | `;
|
758 | }
|
759 | return sections;
|
760 | };
|
761 | const getStyles = (options) => `.label {
|
762 | font-family: ${options.fontFamily};
|
763 | color: ${options.nodeTextColor || options.textColor};
|
764 | }
|
765 | .cluster-label text {
|
766 | fill: ${options.titleColor};
|
767 | }
|
768 | .cluster-label span {
|
769 | color: ${options.titleColor};
|
770 | }
|
771 |
|
772 | .label text,span {
|
773 | fill: ${options.nodeTextColor || options.textColor};
|
774 | color: ${options.nodeTextColor || options.textColor};
|
775 | }
|
776 |
|
777 | .node rect,
|
778 | .node circle,
|
779 | .node ellipse,
|
780 | .node polygon,
|
781 | .node path {
|
782 | fill: ${options.mainBkg};
|
783 | stroke: ${options.nodeBorder};
|
784 | stroke-width: 1px;
|
785 | }
|
786 |
|
787 | .node .label {
|
788 | text-align: center;
|
789 | }
|
790 | .node.clickable {
|
791 | cursor: pointer;
|
792 | }
|
793 |
|
794 | .arrowheadPath {
|
795 | fill: ${options.arrowheadColor};
|
796 | }
|
797 |
|
798 | .edgePath .path {
|
799 | stroke: ${options.lineColor};
|
800 | stroke-width: 2.0px;
|
801 | }
|
802 |
|
803 | .flowchart-link {
|
804 | stroke: ${options.lineColor};
|
805 | fill: none;
|
806 | }
|
807 |
|
808 | .edgeLabel {
|
809 | background-color: ${options.edgeLabelBackground};
|
810 | rect {
|
811 | opacity: 0.85;
|
812 | background-color: ${options.edgeLabelBackground};
|
813 | fill: ${options.edgeLabelBackground};
|
814 | }
|
815 | text-align: center;
|
816 | }
|
817 |
|
818 | .cluster rect {
|
819 | fill: ${options.clusterBkg};
|
820 | stroke: ${options.clusterBorder};
|
821 | stroke-width: 1px;
|
822 | }
|
823 |
|
824 | .cluster text {
|
825 | fill: ${options.titleColor};
|
826 | }
|
827 |
|
828 | .cluster span {
|
829 | color: ${options.titleColor};
|
830 | }
|
831 | /* .cluster div {
|
832 | color: ${options.titleColor};
|
833 | } */
|
834 |
|
835 | div.mermaidTooltip {
|
836 | position: absolute;
|
837 | text-align: center;
|
838 | max-width: 200px;
|
839 | padding: 2px;
|
840 | font-family: ${options.fontFamily};
|
841 | font-size: 12px;
|
842 | background: ${options.tertiaryColor};
|
843 | border: 1px solid ${options.border2};
|
844 | border-radius: 2px;
|
845 | pointer-events: none;
|
846 | z-index: 100;
|
847 | }
|
848 |
|
849 | .flowchartTitleText {
|
850 | text-anchor: middle;
|
851 | font-size: 18px;
|
852 | fill: ${options.textColor};
|
853 | }
|
854 | .subgraph {
|
855 | stroke-width:2;
|
856 | rx:3;
|
857 | }
|
858 | // .subgraph-lvl-1 {
|
859 | // fill:#ccc;
|
860 | // // stroke:black;
|
861 | // }
|
862 |
|
863 | .flowchart-label text {
|
864 | text-anchor: middle;
|
865 | }
|
866 |
|
867 | ${genSections(options)}
|
868 | `;
|
869 | const styles = getStyles;
|
870 | const diagram = {
|
871 | db,
|
872 | renderer,
|
873 | parser,
|
874 | styles
|
875 | };
|
876 | export {
|
877 | diagram
|
878 | };
|