UNPKG

mermaid

Version:

Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.

455 lines (449 loc) 20.6 kB
import { createLabel_default } from "./chunk-DGPT5PPI.mjs"; import { getLineFunctionsWithOffset, getSubGraphTitleMargins } from "./chunk-23ATMZXV.mjs"; import { createText } from "./chunk-RAVNKOQV.mjs"; import { utils_default } from "./chunk-2EDTWDYI.mjs"; import { __name, evaluate, getConfig2 as getConfig, log } from "./chunk-IIKMQLIC.mjs"; // src/dagre-wrapper/markers.js var insertMarkers = /* @__PURE__ */ __name((elem, markerArray, type, id) => { markerArray.forEach((markerName) => { markers[markerName](elem, type, id); }); }, "insertMarkers"); var extension = /* @__PURE__ */ __name((elem, type, id) => { log.trace("Making markers for ", id); elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); }, "extension"); var composition = /* @__PURE__ */ __name((elem, type, id) => { elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); }, "composition"); var aggregation = /* @__PURE__ */ __name((elem, type, id) => { elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); }, "aggregation"); var dependency = /* @__PURE__ */ __name((elem, type, id) => { elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); }, "dependency"); var lollipop = /* @__PURE__ */ __name((elem, type, id) => { elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); }, "lollipop"); var point = /* @__PURE__ */ __name((elem, type, id) => { elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); }, "point"); var circle = /* @__PURE__ */ __name((elem, type, id) => { elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); }, "circle"); var cross = /* @__PURE__ */ __name((elem, type, id) => { elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); }, "cross"); var barb = /* @__PURE__ */ __name((elem, type, id) => { elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); }, "barb"); var markers = { extension, composition, aggregation, dependency, lollipop, point, circle, cross, barb }; var markers_default = insertMarkers; // src/dagre-wrapper/edges.js import { line, curveBasis, select } from "d3"; // src/dagre-wrapper/edgeMarker.ts var addEdgeMarkers = /* @__PURE__ */ __name((svgPath, edge, url, id, diagramType) => { if (edge.arrowTypeStart) { addEdgeMarker(svgPath, "start", edge.arrowTypeStart, url, id, diagramType); } if (edge.arrowTypeEnd) { addEdgeMarker(svgPath, "end", edge.arrowTypeEnd, url, id, diagramType); } }, "addEdgeMarkers"); var arrowTypesMap = { arrow_cross: "cross", arrow_point: "point", arrow_barb: "barb", arrow_circle: "circle", aggregation: "aggregation", extension: "extension", composition: "composition", dependency: "dependency", lollipop: "lollipop" }; var addEdgeMarker = /* @__PURE__ */ __name((svgPath, position, arrowType, url, id, diagramType) => { const endMarkerType = arrowTypesMap[arrowType]; if (!endMarkerType) { log.warn(`Unknown arrow type: ${arrowType}`); return; } const suffix = position === "start" ? "Start" : "End"; svgPath.attr(`marker-${position}`, `url(${url}#${id}_${diagramType}-${endMarkerType}${suffix})`); }, "addEdgeMarker"); // src/dagre-wrapper/edges.js var edgeLabels = {}; var terminalLabels = {}; var clear = /* @__PURE__ */ __name(() => { edgeLabels = {}; terminalLabels = {}; }, "clear"); var insertEdgeLabel = /* @__PURE__ */ __name((elem, edge) => { const config = getConfig(); const useHtmlLabels = evaluate(config.flowchart.htmlLabels); const labelElement = edge.labelType === "markdown" ? createText( elem, edge.label, { style: edge.labelStyle, useHtmlLabels, addSvgBackground: true }, config ) : createLabel_default(edge.label, edge.labelStyle); const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); const label = edgeLabel.insert("g").attr("class", "label"); label.node().appendChild(labelElement); let bbox = labelElement.getBBox(); if (useHtmlLabels) { const div = labelElement.children[0]; const dv = select(labelElement); bbox = div.getBoundingClientRect(); dv.attr("width", bbox.width); dv.attr("height", bbox.height); } label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); edgeLabels[edge.id] = edgeLabel; edge.width = bbox.width; edge.height = bbox.height; let fo; if (edge.startLabelLeft) { const startLabelElement = createLabel_default(edge.startLabelLeft, edge.labelStyle); const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); fo = inner.node().appendChild(startLabelElement); const slBox = startLabelElement.getBBox(); inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); if (!terminalLabels[edge.id]) { terminalLabels[edge.id] = {}; } terminalLabels[edge.id].startLeft = startEdgeLabelLeft; setTerminalWidth(fo, edge.startLabelLeft); } if (edge.startLabelRight) { const startLabelElement = createLabel_default(edge.startLabelRight, edge.labelStyle); const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); fo = startEdgeLabelRight.node().appendChild(startLabelElement); inner.node().appendChild(startLabelElement); const slBox = startLabelElement.getBBox(); inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); if (!terminalLabels[edge.id]) { terminalLabels[edge.id] = {}; } terminalLabels[edge.id].startRight = startEdgeLabelRight; setTerminalWidth(fo, edge.startLabelRight); } if (edge.endLabelLeft) { const endLabelElement = createLabel_default(edge.endLabelLeft, edge.labelStyle); const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); fo = inner.node().appendChild(endLabelElement); const slBox = endLabelElement.getBBox(); inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); endEdgeLabelLeft.node().appendChild(endLabelElement); if (!terminalLabels[edge.id]) { terminalLabels[edge.id] = {}; } terminalLabels[edge.id].endLeft = endEdgeLabelLeft; setTerminalWidth(fo, edge.endLabelLeft); } if (edge.endLabelRight) { const endLabelElement = createLabel_default(edge.endLabelRight, edge.labelStyle); const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); fo = inner.node().appendChild(endLabelElement); const slBox = endLabelElement.getBBox(); inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); endEdgeLabelRight.node().appendChild(endLabelElement); if (!terminalLabels[edge.id]) { terminalLabels[edge.id] = {}; } terminalLabels[edge.id].endRight = endEdgeLabelRight; setTerminalWidth(fo, edge.endLabelRight); } return labelElement; }, "insertEdgeLabel"); function setTerminalWidth(fo, value) { if (getConfig().flowchart.htmlLabels && fo) { fo.style.width = value.length * 9 + "px"; fo.style.height = "12px"; } } __name(setTerminalWidth, "setTerminalWidth"); var positionEdgeLabel = /* @__PURE__ */ __name((edge, paths) => { log.debug("Moving label abc88 ", edge.id, edge.label, edgeLabels[edge.id], paths); let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; const siteConfig = getConfig(); const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig); if (edge.label) { const el = edgeLabels[edge.id]; let x = edge.x; let y = edge.y; if (path) { const pos = utils_default.calcLabelPosition(path); log.debug( "Moving label " + edge.label + " from (", x, ",", y, ") to (", pos.x, ",", pos.y, ") abc88" ); if (paths.updatedPath) { x = pos.x; y = pos.y; } } el.attr("transform", `translate(${x}, ${y + subGraphTitleTotalMargin / 2})`); } if (edge.startLabelLeft) { const el = terminalLabels[edge.id].startLeft; let x = edge.x; let y = edge.y; if (path) { const pos = utils_default.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); x = pos.x; y = pos.y; } el.attr("transform", `translate(${x}, ${y})`); } if (edge.startLabelRight) { const el = terminalLabels[edge.id].startRight; let x = edge.x; let y = edge.y; if (path) { const pos = utils_default.calcTerminalLabelPosition( edge.arrowTypeStart ? 10 : 0, "start_right", path ); x = pos.x; y = pos.y; } el.attr("transform", `translate(${x}, ${y})`); } if (edge.endLabelLeft) { const el = terminalLabels[edge.id].endLeft; let x = edge.x; let y = edge.y; if (path) { const pos = utils_default.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); x = pos.x; y = pos.y; } el.attr("transform", `translate(${x}, ${y})`); } if (edge.endLabelRight) { const el = terminalLabels[edge.id].endRight; let x = edge.x; let y = edge.y; if (path) { const pos = utils_default.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); x = pos.x; y = pos.y; } el.attr("transform", `translate(${x}, ${y})`); } }, "positionEdgeLabel"); var outsideNode = /* @__PURE__ */ __name((node, point2) => { const x = node.x; const y = node.y; const dx = Math.abs(point2.x - x); const dy = Math.abs(point2.y - y); const w = node.width / 2; const h = node.height / 2; if (dx >= w || dy >= h) { return true; } return false; }, "outsideNode"); var intersection = /* @__PURE__ */ __name((node, outsidePoint, insidePoint) => { log.debug(`intersection calc abc89: outsidePoint: ${JSON.stringify(outsidePoint)} insidePoint : ${JSON.stringify(insidePoint)} node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); const x = node.x; const y = node.y; const dx = Math.abs(x - insidePoint.x); const w = node.width / 2; let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; const h = node.height / 2; const Q = Math.abs(outsidePoint.y - insidePoint.y); const R = Math.abs(outsidePoint.x - insidePoint.x); if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; r = R * q / Q; const res = { x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q }; if (r === 0) { res.x = outsidePoint.x; res.y = outsidePoint.y; } if (R === 0) { res.x = outsidePoint.x; } if (Q === 0) { res.y = outsidePoint.y; } log.debug(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); return res; } else { if (insidePoint.x < outsidePoint.x) { r = outsidePoint.x - w - x; } else { r = x - w - outsidePoint.x; } let q = Q * r / R; let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; log.debug(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); if (r === 0) { _x = outsidePoint.x; _y = outsidePoint.y; } if (R === 0) { _x = outsidePoint.x; } if (Q === 0) { _y = outsidePoint.y; } return { x: _x, y: _y }; } }, "intersection"); var cutPathAtIntersect = /* @__PURE__ */ __name((_points, boundaryNode) => { log.debug("abc88 cutPathAtIntersect", _points, boundaryNode); let points = []; let lastPointOutside = _points[0]; let isInside = false; _points.forEach((point2) => { if (!outsideNode(boundaryNode, point2) && !isInside) { const inter = intersection(boundaryNode, lastPointOutside, point2); let pointPresent = false; points.forEach((p) => { pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; }); if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { points.push(inter); } isInside = true; } else { lastPointOutside = point2; if (!isInside) { points.push(point2); } } }); return points; }, "cutPathAtIntersect"); var insertEdge = /* @__PURE__ */ __name(function(elem, e, edge, clusterDb, diagramType, graph, id) { let points = edge.points; log.debug("abc88 InsertEdge: edge=", edge, "e=", e); let pointsHasChanged = false; const tail = graph.node(e.v); var head = graph.node(e.w); if (head?.intersect && tail?.intersect) { points = points.slice(1, edge.points.length - 1); points.unshift(tail.intersect(points[0])); points.push(head.intersect(points[points.length - 1])); } if (edge.toCluster) { log.debug("to cluster abc88", clusterDb[edge.toCluster]); points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); pointsHasChanged = true; } if (edge.fromCluster) { log.debug("from cluster abc88", clusterDb[edge.fromCluster]); points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); pointsHasChanged = true; } const lineData = points.filter((p) => !Number.isNaN(p.y)); let curve = curveBasis; if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { curve = edge.curve; } const { x, y } = getLineFunctionsWithOffset(edge); const lineFunction = line().x(x).y(y).curve(curve); let strokeClasses; switch (edge.thickness) { case "normal": strokeClasses = "edge-thickness-normal"; break; case "thick": strokeClasses = "edge-thickness-thick"; break; case "invisible": strokeClasses = "edge-thickness-thick"; break; default: strokeClasses = ""; } switch (edge.pattern) { case "solid": strokeClasses += " edge-pattern-solid"; break; case "dotted": strokeClasses += " edge-pattern-dotted"; break; case "dashed": strokeClasses += " edge-pattern-dashed"; break; } const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); let url = ""; if (getConfig().flowchart.arrowMarkerAbsolute || getConfig().state.arrowMarkerAbsolute) { url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; url = url.replace(/\(/g, "\\("); url = url.replace(/\)/g, "\\)"); } addEdgeMarkers(svgPath, edge, url, id, diagramType); let paths = {}; if (pointsHasChanged) { paths.updatedPath = points; } paths.originalPath = edge.points; return paths; }, "insertEdge"); export { markers_default, clear, insertEdgeLabel, positionEdgeLabel, insertEdge };