1 | import { b as baseClone, a as isUndefined, m as map, G as Graph, l as layout } from "./layout-e57aec3f.js";
|
2 | import { c as createLabel, i as intersectRect, a as insertMarkers, b as clear$2, d as clear$3, u as updateNodeBounds, s as setNodeElem, e as insertNode, f as insertEdgeLabel, p as positionNode, g as insertEdge, h as positionEdgeLabel } from "./edges-a0c69811.js";
|
3 | import { l as log, q as evaluate, c as getConfig, j as select } from "./mermaid-4b4b971d.js";
|
4 | import { c as createText } from "./createText-b06b2794.js";
|
5 | var CLONE_SYMBOLS_FLAG = 4;
|
6 | function clone(value) {
|
7 | return baseClone(value, CLONE_SYMBOLS_FLAG);
|
8 | }
|
9 | function write(g) {
|
10 | var json = {
|
11 | options: {
|
12 | directed: g.isDirected(),
|
13 | multigraph: g.isMultigraph(),
|
14 | compound: g.isCompound()
|
15 | },
|
16 | nodes: writeNodes(g),
|
17 | edges: writeEdges(g)
|
18 | };
|
19 | if (!isUndefined(g.graph())) {
|
20 | json.value = clone(g.graph());
|
21 | }
|
22 | return json;
|
23 | }
|
24 | function writeNodes(g) {
|
25 | return map(g.nodes(), function(v) {
|
26 | var nodeValue = g.node(v);
|
27 | var parent = g.parent(v);
|
28 | var node = { v };
|
29 | if (!isUndefined(nodeValue)) {
|
30 | node.value = nodeValue;
|
31 | }
|
32 | if (!isUndefined(parent)) {
|
33 | node.parent = parent;
|
34 | }
|
35 | return node;
|
36 | });
|
37 | }
|
38 | function writeEdges(g) {
|
39 | return map(g.edges(), function(e) {
|
40 | var edgeValue = g.edge(e);
|
41 | var edge = { v: e.v, w: e.w };
|
42 | if (!isUndefined(e.name)) {
|
43 | edge.name = e.name;
|
44 | }
|
45 | if (!isUndefined(edgeValue)) {
|
46 | edge.value = edgeValue;
|
47 | }
|
48 | return edge;
|
49 | });
|
50 | }
|
51 | let clusterDb = {};
|
52 | let descendants = {};
|
53 | let parents = {};
|
54 | const clear$1 = () => {
|
55 | descendants = {};
|
56 | parents = {};
|
57 | clusterDb = {};
|
58 | };
|
59 | const isDescendant = (id, ancenstorId) => {
|
60 | log.trace("In isDecendant", ancenstorId, " ", id, " = ", descendants[ancenstorId].includes(id));
|
61 | if (descendants[ancenstorId].includes(id)) {
|
62 | return true;
|
63 | }
|
64 | return false;
|
65 | };
|
66 | const edgeInCluster = (edge, clusterId) => {
|
67 | log.info("Decendants of ", clusterId, " is ", descendants[clusterId]);
|
68 | log.info("Edge is ", edge);
|
69 | if (edge.v === clusterId) {
|
70 | return false;
|
71 | }
|
72 | if (edge.w === clusterId) {
|
73 | return false;
|
74 | }
|
75 | if (!descendants[clusterId]) {
|
76 | log.debug("Tilt, ", clusterId, ",not in decendants");
|
77 | return false;
|
78 | }
|
79 | return descendants[clusterId].includes(edge.v) || isDescendant(edge.v, clusterId) || isDescendant(edge.w, clusterId) || descendants[clusterId].includes(edge.w);
|
80 | };
|
81 | const copy = (clusterId, graph, newGraph, rootId) => {
|
82 | log.warn(
|
83 | "Copying children of ",
|
84 | clusterId,
|
85 | "root",
|
86 | rootId,
|
87 | "data",
|
88 | graph.node(clusterId),
|
89 | rootId
|
90 | );
|
91 | const nodes = graph.children(clusterId) || [];
|
92 | if (clusterId !== rootId) {
|
93 | nodes.push(clusterId);
|
94 | }
|
95 | log.warn("Copying (nodes) clusterId", clusterId, "nodes", nodes);
|
96 | nodes.forEach((node) => {
|
97 | if (graph.children(node).length > 0) {
|
98 | copy(node, graph, newGraph, rootId);
|
99 | } else {
|
100 | const data = graph.node(node);
|
101 | log.info("cp ", node, " to ", rootId, " with parent ", clusterId);
|
102 | newGraph.setNode(node, data);
|
103 | if (rootId !== graph.parent(node)) {
|
104 | log.warn("Setting parent", node, graph.parent(node));
|
105 | newGraph.setParent(node, graph.parent(node));
|
106 | }
|
107 | if (clusterId !== rootId && node !== clusterId) {
|
108 | log.debug("Setting parent", node, clusterId);
|
109 | newGraph.setParent(node, clusterId);
|
110 | } else {
|
111 | log.info("In copy ", clusterId, "root", rootId, "data", graph.node(clusterId), rootId);
|
112 | log.debug(
|
113 | "Not Setting parent for node=",
|
114 | node,
|
115 | "cluster!==rootId",
|
116 | clusterId !== rootId,
|
117 | "node!==clusterId",
|
118 | node !== clusterId
|
119 | );
|
120 | }
|
121 | const edges = graph.edges(node);
|
122 | log.debug("Copying Edges", edges);
|
123 | edges.forEach((edge) => {
|
124 | log.info("Edge", edge);
|
125 | const data2 = graph.edge(edge.v, edge.w, edge.name);
|
126 | log.info("Edge data", data2, rootId);
|
127 | try {
|
128 | if (edgeInCluster(edge, rootId)) {
|
129 | log.info("Copying as ", edge.v, edge.w, data2, edge.name);
|
130 | newGraph.setEdge(edge.v, edge.w, data2, edge.name);
|
131 | log.info("newGraph edges ", newGraph.edges(), newGraph.edge(newGraph.edges()[0]));
|
132 | } else {
|
133 | log.info(
|
134 | "Skipping copy of edge ",
|
135 | edge.v,
|
136 | "-->",
|
137 | edge.w,
|
138 | " rootId: ",
|
139 | rootId,
|
140 | " clusterId:",
|
141 | clusterId
|
142 | );
|
143 | }
|
144 | } catch (e) {
|
145 | log.error(e);
|
146 | }
|
147 | });
|
148 | }
|
149 | log.debug("Removing node", node);
|
150 | graph.removeNode(node);
|
151 | });
|
152 | };
|
153 | const extractDescendants = (id, graph) => {
|
154 | const children = graph.children(id);
|
155 | let res = [...children];
|
156 | for (const child of children) {
|
157 | parents[child] = id;
|
158 | res = [...res, ...extractDescendants(child, graph)];
|
159 | }
|
160 | return res;
|
161 | };
|
162 | const findNonClusterChild = (id, graph) => {
|
163 | log.trace("Searching", id);
|
164 | const children = graph.children(id);
|
165 | log.trace("Searching children of id ", id, children);
|
166 | if (children.length < 1) {
|
167 | log.trace("This is a valid node", id);
|
168 | return id;
|
169 | }
|
170 | for (const child of children) {
|
171 | const _id = findNonClusterChild(child, graph);
|
172 | if (_id) {
|
173 | log.trace("Found replacement for", id, " => ", _id);
|
174 | return _id;
|
175 | }
|
176 | }
|
177 | };
|
178 | const getAnchorId = (id) => {
|
179 | if (!clusterDb[id]) {
|
180 | return id;
|
181 | }
|
182 | if (!clusterDb[id].externalConnections) {
|
183 | return id;
|
184 | }
|
185 | if (clusterDb[id]) {
|
186 | return clusterDb[id].id;
|
187 | }
|
188 | return id;
|
189 | };
|
190 | const adjustClustersAndEdges = (graph, depth) => {
|
191 | if (!graph || depth > 10) {
|
192 | log.debug("Opting out, no graph ");
|
193 | return;
|
194 | } else {
|
195 | log.debug("Opting in, graph ");
|
196 | }
|
197 | graph.nodes().forEach(function(id) {
|
198 | const children = graph.children(id);
|
199 | if (children.length > 0) {
|
200 | log.warn(
|
201 | "Cluster identified",
|
202 | id,
|
203 | " Replacement id in edges: ",
|
204 | findNonClusterChild(id, graph)
|
205 | );
|
206 | descendants[id] = extractDescendants(id, graph);
|
207 | clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) };
|
208 | }
|
209 | });
|
210 | graph.nodes().forEach(function(id) {
|
211 | const children = graph.children(id);
|
212 | const edges = graph.edges();
|
213 | if (children.length > 0) {
|
214 | log.debug("Cluster identified", id, descendants);
|
215 | edges.forEach((edge) => {
|
216 | if (edge.v !== id && edge.w !== id) {
|
217 | const d1 = isDescendant(edge.v, id);
|
218 | const d2 = isDescendant(edge.w, id);
|
219 | if (d1 ^ d2) {
|
220 | log.warn("Edge: ", edge, " leaves cluster ", id);
|
221 | log.warn("Decendants of XXX ", id, ": ", descendants[id]);
|
222 | clusterDb[id].externalConnections = true;
|
223 | }
|
224 | }
|
225 | });
|
226 | } else {
|
227 | log.debug("Not a cluster ", id, descendants);
|
228 | }
|
229 | });
|
230 | graph.edges().forEach(function(e) {
|
231 | const edge = graph.edge(e);
|
232 | log.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e));
|
233 | log.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e)));
|
234 | let v = e.v;
|
235 | let w = e.w;
|
236 | log.warn(
|
237 | "Fix XXX",
|
238 | clusterDb,
|
239 | "ids:",
|
240 | e.v,
|
241 | e.w,
|
242 | "Translating: ",
|
243 | clusterDb[e.v],
|
244 | " --- ",
|
245 | clusterDb[e.w]
|
246 | );
|
247 | if (clusterDb[e.v] && clusterDb[e.w] && clusterDb[e.v] === clusterDb[e.w]) {
|
248 | log.warn("Fixing and trixing link to self - removing XXX", e.v, e.w, e.name);
|
249 | log.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name);
|
250 | v = getAnchorId(e.v);
|
251 | w = getAnchorId(e.w);
|
252 | graph.removeEdge(e.v, e.w, e.name);
|
253 | const specialId = e.w + "---" + e.v;
|
254 | graph.setNode(specialId, {
|
255 | domId: specialId,
|
256 | id: specialId,
|
257 | labelStyle: "",
|
258 | labelText: edge.label,
|
259 | padding: 0,
|
260 | shape: "labelRect",
|
261 | style: ""
|
262 | });
|
263 | const edge1 = JSON.parse(JSON.stringify(edge));
|
264 | const edge2 = JSON.parse(JSON.stringify(edge));
|
265 | edge1.label = "";
|
266 | edge1.arrowTypeEnd = "none";
|
267 | edge2.label = "";
|
268 | edge1.fromCluster = e.v;
|
269 | edge2.toCluster = e.v;
|
270 | graph.setEdge(v, specialId, edge1, e.name + "-cyclic-special");
|
271 | graph.setEdge(specialId, w, edge2, e.name + "-cyclic-special");
|
272 | } else if (clusterDb[e.v] || clusterDb[e.w]) {
|
273 | log.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name);
|
274 | v = getAnchorId(e.v);
|
275 | w = getAnchorId(e.w);
|
276 | graph.removeEdge(e.v, e.w, e.name);
|
277 | if (v !== e.v) {
|
278 | edge.fromCluster = e.v;
|
279 | }
|
280 | if (w !== e.w) {
|
281 | edge.toCluster = e.w;
|
282 | }
|
283 | log.warn("Fix Replacing with XXX", v, w, e.name);
|
284 | graph.setEdge(v, w, edge, e.name);
|
285 | }
|
286 | });
|
287 | log.warn("Adjusted Graph", write(graph));
|
288 | extractor(graph, 0);
|
289 | log.trace(clusterDb);
|
290 | };
|
291 | const extractor = (graph, depth) => {
|
292 | log.warn("extractor - ", depth, write(graph), graph.children("D"));
|
293 | if (depth > 10) {
|
294 | log.error("Bailing out");
|
295 | return;
|
296 | }
|
297 | let nodes = graph.nodes();
|
298 | let hasChildren = false;
|
299 | for (const node of nodes) {
|
300 | const children = graph.children(node);
|
301 | hasChildren = hasChildren || children.length > 0;
|
302 | }
|
303 | if (!hasChildren) {
|
304 | log.debug("Done, no node has children", graph.nodes());
|
305 | return;
|
306 | }
|
307 | log.debug("Nodes = ", nodes, depth);
|
308 | for (const node of nodes) {
|
309 | log.debug(
|
310 | "Extracting node",
|
311 | node,
|
312 | clusterDb,
|
313 | clusterDb[node] && !clusterDb[node].externalConnections,
|
314 | !graph.parent(node),
|
315 | graph.node(node),
|
316 | graph.children("D"),
|
317 | " Depth ",
|
318 | depth
|
319 | );
|
320 | if (!clusterDb[node]) {
|
321 | log.debug("Not a cluster", node, depth);
|
322 | } else if (!clusterDb[node].externalConnections &&
|
323 | graph.children(node) && graph.children(node).length > 0) {
|
324 | log.warn(
|
325 | "Cluster without external connections, without a parent and with children",
|
326 | node,
|
327 | depth
|
328 | );
|
329 | const graphSettings = graph.graph();
|
330 | let dir = graphSettings.rankdir === "TB" ? "LR" : "TB";
|
331 | if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) {
|
332 | dir = clusterDb[node].clusterData.dir;
|
333 | log.warn("Fixing dir", clusterDb[node].clusterData.dir, dir);
|
334 | }
|
335 | const clusterGraph = new Graph({
|
336 | multigraph: true,
|
337 | compound: true
|
338 | }).setGraph({
|
339 | rankdir: dir,
|
340 |
|
341 | nodesep: 50,
|
342 | ranksep: 50,
|
343 | marginx: 8,
|
344 | marginy: 8
|
345 | }).setDefaultEdgeLabel(function() {
|
346 | return {};
|
347 | });
|
348 | log.warn("Old graph before copy", write(graph));
|
349 | copy(node, graph, clusterGraph, node);
|
350 | graph.setNode(node, {
|
351 | clusterNode: true,
|
352 | id: node,
|
353 | clusterData: clusterDb[node].clusterData,
|
354 | labelText: clusterDb[node].labelText,
|
355 | graph: clusterGraph
|
356 | });
|
357 | log.warn("New graph after copy node: (", node, ")", write(clusterGraph));
|
358 | log.debug("Old graph after copy", write(graph));
|
359 | } else {
|
360 | log.warn(
|
361 | "Cluster ** ",
|
362 | node,
|
363 | " **not meeting the criteria !externalConnections:",
|
364 | !clusterDb[node].externalConnections,
|
365 | " no parent: ",
|
366 | !graph.parent(node),
|
367 | " children ",
|
368 | graph.children(node) && graph.children(node).length > 0,
|
369 | graph.children("D"),
|
370 | depth
|
371 | );
|
372 | log.debug(clusterDb);
|
373 | }
|
374 | }
|
375 | nodes = graph.nodes();
|
376 | log.warn("New list of nodes", nodes);
|
377 | for (const node of nodes) {
|
378 | const data = graph.node(node);
|
379 | log.warn(" Now next level", node, data);
|
380 | if (data.clusterNode) {
|
381 | extractor(data.graph, depth + 1);
|
382 | }
|
383 | }
|
384 | };
|
385 | const sorter = (graph, nodes) => {
|
386 | if (nodes.length === 0) {
|
387 | return [];
|
388 | }
|
389 | let result = Object.assign(nodes);
|
390 | nodes.forEach((node) => {
|
391 | const children = graph.children(node);
|
392 | const sorted = sorter(graph, children);
|
393 | result = [...result, ...sorted];
|
394 | });
|
395 | return result;
|
396 | };
|
397 | const sortNodesByHierarchy = (graph) => sorter(graph, graph.children());
|
398 | const rect = (parent, node) => {
|
399 | log.info("Creating subgraph rect for ", node.id, node);
|
400 | const shapeSvg = parent.insert("g").attr("class", "cluster" + (node.class ? " " + node.class : "")).attr("id", node.id);
|
401 | const rect2 = shapeSvg.insert("rect", ":first-child");
|
402 | const useHtmlLabels = evaluate(getConfig().flowchart.htmlLabels);
|
403 | const label = shapeSvg.insert("g").attr("class", "cluster-label");
|
404 | const text = node.labelType === "markdown" ? createText(label, node.labelText, { style: node.labelStyle, useHtmlLabels }) : label.node().appendChild(createLabel(node.labelText, node.labelStyle, void 0, true));
|
405 | let bbox = text.getBBox();
|
406 | if (evaluate(getConfig().flowchart.htmlLabels)) {
|
407 | const div = text.children[0];
|
408 | const dv = select(text);
|
409 | bbox = div.getBoundingClientRect();
|
410 | dv.attr("width", bbox.width);
|
411 | dv.attr("height", bbox.height);
|
412 | }
|
413 | const padding = 0 * node.padding;
|
414 | const halfPadding = padding / 2;
|
415 | const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width;
|
416 | if (node.width <= bbox.width + padding) {
|
417 | node.diff = (bbox.width - node.width) / 2 - node.padding / 2;
|
418 | } else {
|
419 | node.diff = -node.padding / 2;
|
420 | }
|
421 | log.trace("Data ", node, JSON.stringify(node));
|
422 | rect2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - width / 2).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width).attr("height", node.height + padding);
|
423 | if (useHtmlLabels) {
|
424 | label.attr(
|
425 | "transform",
|
426 |
|
427 | "translate(" + (node.x - bbox.width / 2) + ", " + (node.y - node.height / 2) + ")"
|
428 | );
|
429 | } else {
|
430 | label.attr(
|
431 | "transform",
|
432 |
|
433 | "translate(" + node.x + ", " + (node.y - node.height / 2) + ")"
|
434 | );
|
435 | }
|
436 | const rectBox = rect2.node().getBBox();
|
437 | node.width = rectBox.width;
|
438 | node.height = rectBox.height;
|
439 | node.intersect = function(point) {
|
440 | return intersectRect(node, point);
|
441 | };
|
442 | return shapeSvg;
|
443 | };
|
444 | const noteGroup = (parent, node) => {
|
445 | const shapeSvg = parent.insert("g").attr("class", "note-cluster").attr("id", node.id);
|
446 | const rect2 = shapeSvg.insert("rect", ":first-child");
|
447 | const padding = 0 * node.padding;
|
448 | const halfPadding = padding / 2;
|
449 | rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", node.width + padding).attr("height", node.height + padding).attr("fill", "none");
|
450 | const rectBox = rect2.node().getBBox();
|
451 | node.width = rectBox.width;
|
452 | node.height = rectBox.height;
|
453 | node.intersect = function(point) {
|
454 | return intersectRect(node, point);
|
455 | };
|
456 | return shapeSvg;
|
457 | };
|
458 | const roundedWithTitle = (parent, node) => {
|
459 | const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id);
|
460 | const rect2 = shapeSvg.insert("rect", ":first-child");
|
461 | const label = shapeSvg.insert("g").attr("class", "cluster-label");
|
462 | const innerRect = shapeSvg.append("rect");
|
463 | const text = label.node().appendChild(createLabel(node.labelText, node.labelStyle, void 0, true));
|
464 | let bbox = text.getBBox();
|
465 | if (evaluate(getConfig().flowchart.htmlLabels)) {
|
466 | const div = text.children[0];
|
467 | const dv = select(text);
|
468 | bbox = div.getBoundingClientRect();
|
469 | dv.attr("width", bbox.width);
|
470 | dv.attr("height", bbox.height);
|
471 | }
|
472 | bbox = text.getBBox();
|
473 | const padding = 0 * node.padding;
|
474 | const halfPadding = padding / 2;
|
475 | const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width;
|
476 | if (node.width <= bbox.width + node.padding) {
|
477 | node.diff = (bbox.width + node.padding * 0 - node.width) / 2;
|
478 | } else {
|
479 | node.diff = -node.padding / 2;
|
480 | }
|
481 | rect2.attr("class", "outer").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width + padding).attr("height", node.height + padding);
|
482 | innerRect.attr("class", "inner").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding + bbox.height - 1).attr("width", width + padding).attr("height", node.height + padding - bbox.height - 3);
|
483 | label.attr(
|
484 | "transform",
|
485 | "translate(" + (node.x - bbox.width / 2) + ", " + (node.y - node.height / 2 - node.padding / 3 + (evaluate(getConfig().flowchart.htmlLabels) ? 5 : 3)) + ")"
|
486 | );
|
487 | const rectBox = rect2.node().getBBox();
|
488 | node.height = rectBox.height;
|
489 | node.intersect = function(point) {
|
490 | return intersectRect(node, point);
|
491 | };
|
492 | return shapeSvg;
|
493 | };
|
494 | const divider = (parent, node) => {
|
495 | const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id);
|
496 | const rect2 = shapeSvg.insert("rect", ":first-child");
|
497 | const padding = 0 * node.padding;
|
498 | const halfPadding = padding / 2;
|
499 | rect2.attr("class", "divider").attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2).attr("width", node.width + padding).attr("height", node.height + padding);
|
500 | const rectBox = rect2.node().getBBox();
|
501 | node.width = rectBox.width;
|
502 | node.height = rectBox.height;
|
503 | node.diff = -node.padding / 2;
|
504 | node.intersect = function(point) {
|
505 | return intersectRect(node, point);
|
506 | };
|
507 | return shapeSvg;
|
508 | };
|
509 | const shapes = { rect, roundedWithTitle, noteGroup, divider };
|
510 | let clusterElems = {};
|
511 | const insertCluster = (elem, node) => {
|
512 | log.trace("Inserting cluster");
|
513 | const shape = node.shape || "rect";
|
514 | clusterElems[node.id] = shapes[shape](elem, node);
|
515 | };
|
516 | const clear = () => {
|
517 | clusterElems = {};
|
518 | };
|
519 | const recursiveRender = async (_elem, graph, diagramtype, parentCluster) => {
|
520 | log.info("Graph in recursive render: XXX", write(graph), parentCluster);
|
521 | const dir = graph.graph().rankdir;
|
522 | log.trace("Dir in recursive render - dir:", dir);
|
523 | const elem = _elem.insert("g").attr("class", "root");
|
524 | if (!graph.nodes()) {
|
525 | log.info("No nodes found for", graph);
|
526 | } else {
|
527 | log.info("Recursive render XXX", graph.nodes());
|
528 | }
|
529 | if (graph.edges().length > 0) {
|
530 | log.trace("Recursive edges", graph.edge(graph.edges()[0]));
|
531 | }
|
532 | const clusters = elem.insert("g").attr("class", "clusters");
|
533 | const edgePaths = elem.insert("g").attr("class", "edgePaths");
|
534 | const edgeLabels = elem.insert("g").attr("class", "edgeLabels");
|
535 | const nodes = elem.insert("g").attr("class", "nodes");
|
536 | await Promise.all(
|
537 | graph.nodes().map(async function(v) {
|
538 | const node = graph.node(v);
|
539 | if (parentCluster !== void 0) {
|
540 | const data = JSON.parse(JSON.stringify(parentCluster.clusterData));
|
541 | log.info("Setting data for cluster XXX (", v, ") ", data, parentCluster);
|
542 | graph.setNode(parentCluster.id, data);
|
543 | if (!graph.parent(v)) {
|
544 | log.trace("Setting parent", v, parentCluster.id);
|
545 | graph.setParent(v, parentCluster.id, data);
|
546 | }
|
547 | }
|
548 | log.info("(Insert) Node XXX" + v + ": " + JSON.stringify(graph.node(v)));
|
549 | if (node && node.clusterNode) {
|
550 | log.info("Cluster identified", v, node.width, graph.node(v));
|
551 | const o = await recursiveRender(nodes, node.graph, diagramtype, graph.node(v));
|
552 | const newEl = o.elem;
|
553 | updateNodeBounds(node, newEl);
|
554 | node.diff = o.diff || 0;
|
555 | log.info("Node bounds (abc123)", v, node, node.width, node.x, node.y);
|
556 | setNodeElem(newEl, node);
|
557 | log.warn("Recursive render complete ", newEl, node);
|
558 | } else {
|
559 | if (graph.children(v).length > 0) {
|
560 | log.info("Cluster - the non recursive path XXX", v, node.id, node, graph);
|
561 | log.info(findNonClusterChild(node.id, graph));
|
562 | clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node };
|
563 | } else {
|
564 | log.info("Node - the non recursive path", v, node.id, node);
|
565 | await insertNode(nodes, graph.node(v), dir);
|
566 | }
|
567 | }
|
568 | })
|
569 | );
|
570 | graph.edges().forEach(function(e) {
|
571 | const edge = graph.edge(e.v, e.w, e.name);
|
572 | log.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e));
|
573 | log.info("Edge " + e.v + " -> " + e.w + ": ", e, " ", JSON.stringify(graph.edge(e)));
|
574 | log.info("Fix", clusterDb, "ids:", e.v, e.w, "Translateing: ", clusterDb[e.v], clusterDb[e.w]);
|
575 | insertEdgeLabel(edgeLabels, edge);
|
576 | });
|
577 | graph.edges().forEach(function(e) {
|
578 | log.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e));
|
579 | });
|
580 | log.info("#############################################");
|
581 | log.info("### Layout ###");
|
582 | log.info("#############################################");
|
583 | log.info(graph);
|
584 | layout(graph);
|
585 | log.info("Graph after layout:", write(graph));
|
586 | let diff = 0;
|
587 | sortNodesByHierarchy(graph).forEach(function(v) {
|
588 | const node = graph.node(v);
|
589 | log.info("Position " + v + ": " + JSON.stringify(graph.node(v)));
|
590 | log.info(
|
591 | "Position " + v + ": (" + node.x,
|
592 | "," + node.y,
|
593 | ") width: ",
|
594 | node.width,
|
595 | " height: ",
|
596 | node.height
|
597 | );
|
598 | if (node && node.clusterNode) {
|
599 | positionNode(node);
|
600 | } else {
|
601 | if (graph.children(v).length > 0) {
|
602 | insertCluster(clusters, node);
|
603 | clusterDb[node.id].node = node;
|
604 | } else {
|
605 | positionNode(node);
|
606 | }
|
607 | }
|
608 | });
|
609 | graph.edges().forEach(function(e) {
|
610 | const edge = graph.edge(e);
|
611 | log.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(edge), edge);
|
612 | const paths = insertEdge(edgePaths, e, edge, clusterDb, diagramtype, graph);
|
613 | positionEdgeLabel(edge, paths);
|
614 | });
|
615 | graph.nodes().forEach(function(v) {
|
616 | const n = graph.node(v);
|
617 | log.info(v, n.type, n.diff);
|
618 | if (n.type === "group") {
|
619 | diff = n.diff;
|
620 | }
|
621 | });
|
622 | return { elem, diff };
|
623 | };
|
624 | const render = async (elem, graph, markers, diagramtype, id) => {
|
625 | insertMarkers(elem, markers, diagramtype, id);
|
626 | clear$2();
|
627 | clear$3();
|
628 | clear();
|
629 | clear$1();
|
630 | log.warn("Graph at first:", write(graph));
|
631 | adjustClustersAndEdges(graph);
|
632 | log.warn("Graph after:", write(graph));
|
633 | await recursiveRender(elem, graph, diagramtype);
|
634 | };
|
635 | export {
|
636 | render as r
|
637 | };
|