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