|
import { |
|
render |
|
} from "./chunk-JZCXFM6M.js"; |
|
import { |
|
Graph |
|
} from "./chunk-5METK6HB.js"; |
|
import { |
|
channel_default, |
|
common$1, |
|
evaluate, |
|
getConfig, |
|
getStylesFromArray, |
|
interpolateToCurve, |
|
isFunction_default, |
|
isPlainObject_default, |
|
linear_default, |
|
log$1, |
|
renderKatex, |
|
rgba_default, |
|
setupGraphViewbox$1, |
|
utils |
|
} from "./chunk-3PMDUHG4.js"; |
|
import { |
|
selectAll_default, |
|
select_default |
|
} from "./chunk-5KLUPWDV.js"; |
|
|
|
|
|
function isSubgraph(g, v) { |
|
return !!g.children(v).length; |
|
} |
|
function edgeToId(e) { |
|
return escapeId(e.v) + ":" + escapeId(e.w) + ":" + escapeId(e.name); |
|
} |
|
var ID_DELIM = /:/g; |
|
function escapeId(str) { |
|
return str ? String(str).replace(ID_DELIM, "\\:") : ""; |
|
} |
|
function applyStyle(dom, styleFn) { |
|
if (styleFn) { |
|
dom.attr("style", styleFn); |
|
} |
|
} |
|
function applyClass(dom, classFn, otherClasses) { |
|
if (classFn) { |
|
dom.attr("class", classFn).attr("class", otherClasses + " " + dom.attr("class")); |
|
} |
|
} |
|
function applyTransition(selection, g) { |
|
var graph = g.graph(); |
|
if (isPlainObject_default(graph)) { |
|
var transition = graph.transition; |
|
if (isFunction_default(transition)) { |
|
return transition(selection); |
|
} |
|
} |
|
return selection; |
|
} |
|
|
|
|
|
function addHtmlLabel(root, node) { |
|
var fo = root.append("foreignObject").attr("width", "100000"); |
|
var div = fo.append("xhtml:div"); |
|
div.attr("xmlns", "http://www.w3.org/1999/xhtml"); |
|
var label = node.label; |
|
switch (typeof label) { |
|
case "function": |
|
div.insert(label); |
|
break; |
|
case "object": |
|
div.insert(function() { |
|
return label; |
|
}); |
|
break; |
|
default: |
|
div.html(label); |
|
} |
|
applyStyle(div, node.labelStyle); |
|
div.style("display", "inline-block"); |
|
div.style("white-space", "nowrap"); |
|
var client = div.node().getBoundingClientRect(); |
|
fo.attr("width", client.width).attr("height", client.height); |
|
return fo; |
|
} |
|
|
|
|
|
var conf = {}; |
|
var setConf = function(cnf) { |
|
const keys = Object.keys(cnf); |
|
for (const key of keys) { |
|
conf[key] = cnf[key]; |
|
} |
|
}; |
|
var addVertices = async function(vert, g, svgId, root, doc, diagObj) { |
|
const svg = root.select(`[id="${svgId}"]`); |
|
const keys = Object.keys(vert); |
|
for (const id of keys) { |
|
const vertex = vert[id]; |
|
let classStr = "default"; |
|
if (vertex.classes.length > 0) { |
|
classStr = vertex.classes.join(" "); |
|
} |
|
classStr = classStr + " flowchart-label"; |
|
const styles = getStylesFromArray(vertex.styles); |
|
let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id; |
|
let vertexNode; |
|
log$1.info("vertex", vertex, vertex.labelType); |
|
if (vertex.labelType === "markdown") { |
|
log$1.info("vertex", vertex, vertex.labelType); |
|
} else { |
|
if (evaluate(getConfig().flowchart.htmlLabels)) { |
|
const node = { |
|
label: vertexText |
|
}; |
|
vertexNode = addHtmlLabel(svg, node).node(); |
|
vertexNode.parentNode.removeChild(vertexNode); |
|
} else { |
|
const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text"); |
|
svgLabel.setAttribute("style", styles.labelStyle.replace("color:", "fill:")); |
|
const rows = vertexText.split(common$1.lineBreakRegex); |
|
for (const row of rows) { |
|
const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); |
|
tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); |
|
tspan.setAttribute("dy", "1em"); |
|
tspan.setAttribute("x", "1"); |
|
tspan.textContent = row; |
|
svgLabel.appendChild(tspan); |
|
} |
|
vertexNode = svgLabel; |
|
} |
|
} |
|
let radius = 0; |
|
let _shape = ""; |
|
switch (vertex.type) { |
|
case "round": |
|
radius = 5; |
|
_shape = "rect"; |
|
break; |
|
case "square": |
|
_shape = "rect"; |
|
break; |
|
case "diamond": |
|
_shape = "question"; |
|
break; |
|
case "hexagon": |
|
_shape = "hexagon"; |
|
break; |
|
case "odd": |
|
_shape = "rect_left_inv_arrow"; |
|
break; |
|
case "lean_right": |
|
_shape = "lean_right"; |
|
break; |
|
case "lean_left": |
|
_shape = "lean_left"; |
|
break; |
|
case "trapezoid": |
|
_shape = "trapezoid"; |
|
break; |
|
case "inv_trapezoid": |
|
_shape = "inv_trapezoid"; |
|
break; |
|
case "odd_right": |
|
_shape = "rect_left_inv_arrow"; |
|
break; |
|
case "circle": |
|
_shape = "circle"; |
|
break; |
|
case "ellipse": |
|
_shape = "ellipse"; |
|
break; |
|
case "stadium": |
|
_shape = "stadium"; |
|
break; |
|
case "subroutine": |
|
_shape = "subroutine"; |
|
break; |
|
case "cylinder": |
|
_shape = "cylinder"; |
|
break; |
|
case "group": |
|
_shape = "rect"; |
|
break; |
|
case "doublecircle": |
|
_shape = "doublecircle"; |
|
break; |
|
default: |
|
_shape = "rect"; |
|
} |
|
const labelText = await renderKatex(vertexText, getConfig()); |
|
g.setNode(vertex.id, { |
|
labelStyle: styles.labelStyle, |
|
shape: _shape, |
|
labelText, |
|
labelType: vertex.labelType, |
|
rx: radius, |
|
ry: radius, |
|
class: classStr, |
|
style: styles.style, |
|
id: vertex.id, |
|
link: vertex.link, |
|
linkTarget: vertex.linkTarget, |
|
tooltip: diagObj.db.getTooltip(vertex.id) || "", |
|
domId: diagObj.db.lookUpDomId(vertex.id), |
|
haveCallback: vertex.haveCallback, |
|
width: vertex.type === "group" ? 500 : void 0, |
|
dir: vertex.dir, |
|
type: vertex.type, |
|
props: vertex.props, |
|
padding: getConfig().flowchart.padding |
|
}); |
|
log$1.info("setNode", { |
|
labelStyle: styles.labelStyle, |
|
labelType: vertex.labelType, |
|
shape: _shape, |
|
labelText, |
|
rx: radius, |
|
ry: radius, |
|
class: classStr, |
|
style: styles.style, |
|
id: vertex.id, |
|
domId: diagObj.db.lookUpDomId(vertex.id), |
|
width: vertex.type === "group" ? 500 : void 0, |
|
type: vertex.type, |
|
dir: vertex.dir, |
|
props: vertex.props, |
|
padding: getConfig().flowchart.padding |
|
}); |
|
} |
|
}; |
|
var addEdges = async function(edges, g, diagObj) { |
|
log$1.info("abc78 edges = ", edges); |
|
let cnt = 0; |
|
let linkIdCnt = {}; |
|
let defaultStyle; |
|
let defaultLabelStyle; |
|
if (edges.defaultStyle !== void 0) { |
|
const defaultStyles = getStylesFromArray(edges.defaultStyle); |
|
defaultStyle = defaultStyles.style; |
|
defaultLabelStyle = defaultStyles.labelStyle; |
|
} |
|
for (const edge of edges) { |
|
cnt++; |
|
const linkIdBase = "L-" + edge.start + "-" + edge.end; |
|
if (linkIdCnt[linkIdBase] === void 0) { |
|
linkIdCnt[linkIdBase] = 0; |
|
log$1.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); |
|
} else { |
|
linkIdCnt[linkIdBase]++; |
|
log$1.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); |
|
} |
|
let linkId = linkIdBase + "-" + linkIdCnt[linkIdBase]; |
|
log$1.info("abc78 new link id to be used is", linkIdBase, linkId, linkIdCnt[linkIdBase]); |
|
const linkNameStart = "LS-" + edge.start; |
|
const linkNameEnd = "LE-" + edge.end; |
|
const edgeData = { style: "", labelStyle: "" }; |
|
edgeData.minlen = edge.length || 1; |
|
if (edge.type === "arrow_open") { |
|
edgeData.arrowhead = "none"; |
|
} else { |
|
edgeData.arrowhead = "normal"; |
|
} |
|
edgeData.arrowTypeStart = "arrow_open"; |
|
edgeData.arrowTypeEnd = "arrow_open"; |
|
switch (edge.type) { |
|
case "double_arrow_cross": |
|
edgeData.arrowTypeStart = "arrow_cross"; |
|
case "arrow_cross": |
|
edgeData.arrowTypeEnd = "arrow_cross"; |
|
break; |
|
case "double_arrow_point": |
|
edgeData.arrowTypeStart = "arrow_point"; |
|
case "arrow_point": |
|
edgeData.arrowTypeEnd = "arrow_point"; |
|
break; |
|
case "double_arrow_circle": |
|
edgeData.arrowTypeStart = "arrow_circle"; |
|
case "arrow_circle": |
|
edgeData.arrowTypeEnd = "arrow_circle"; |
|
break; |
|
} |
|
let style = ""; |
|
let labelStyle = ""; |
|
switch (edge.stroke) { |
|
case "normal": |
|
style = "fill:none;"; |
|
if (defaultStyle !== void 0) { |
|
style = defaultStyle; |
|
} |
|
if (defaultLabelStyle !== void 0) { |
|
labelStyle = defaultLabelStyle; |
|
} |
|
edgeData.thickness = "normal"; |
|
edgeData.pattern = "solid"; |
|
break; |
|
case "dotted": |
|
edgeData.thickness = "normal"; |
|
edgeData.pattern = "dotted"; |
|
edgeData.style = "fill:none;stroke-width:2px;stroke-dasharray:3;"; |
|
break; |
|
case "thick": |
|
edgeData.thickness = "thick"; |
|
edgeData.pattern = "solid"; |
|
edgeData.style = "stroke-width: 3.5px;fill:none;"; |
|
break; |
|
case "invisible": |
|
edgeData.thickness = "invisible"; |
|
edgeData.pattern = "solid"; |
|
edgeData.style = "stroke-width: 0;fill:none;"; |
|
break; |
|
} |
|
if (edge.style !== void 0) { |
|
const styles = getStylesFromArray(edge.style); |
|
style = styles.style; |
|
labelStyle = styles.labelStyle; |
|
} |
|
edgeData.style = edgeData.style += style; |
|
edgeData.labelStyle = edgeData.labelStyle += labelStyle; |
|
if (edge.interpolate !== void 0) { |
|
edgeData.curve = interpolateToCurve(edge.interpolate, linear_default); |
|
} else if (edges.defaultInterpolate !== void 0) { |
|
edgeData.curve = interpolateToCurve(edges.defaultInterpolate, linear_default); |
|
} else { |
|
edgeData.curve = interpolateToCurve(conf.curve, linear_default); |
|
} |
|
if (edge.text === void 0) { |
|
if (edge.style !== void 0) { |
|
edgeData.arrowheadStyle = "fill: #333"; |
|
} |
|
} else { |
|
edgeData.arrowheadStyle = "fill: #333"; |
|
edgeData.labelpos = "c"; |
|
} |
|
edgeData.labelType = edge.labelType; |
|
edgeData.label = await renderKatex(edge.text.replace(common$1.lineBreakRegex, "\n"), getConfig()); |
|
if (edge.style === void 0) { |
|
edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none;"; |
|
} |
|
edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); |
|
edgeData.id = linkId; |
|
edgeData.classes = "flowchart-link " + linkNameStart + " " + linkNameEnd; |
|
g.setEdge(edge.start, edge.end, edgeData, cnt); |
|
} |
|
}; |
|
var getClasses = function(text, diagObj) { |
|
return diagObj.db.getClasses(); |
|
}; |
|
var draw = async function(text, id, _version, diagObj) { |
|
log$1.info("Drawing flowchart"); |
|
let dir = diagObj.db.getDirection(); |
|
if (dir === void 0) { |
|
dir = "TD"; |
|
} |
|
const { securityLevel, flowchart: conf2 } = getConfig(); |
|
const nodeSpacing = conf2.nodeSpacing || 50; |
|
const rankSpacing = conf2.rankSpacing || 50; |
|
let sandboxElement; |
|
if (securityLevel === "sandbox") { |
|
sandboxElement = select_default("#i" + id); |
|
} |
|
const root = securityLevel === "sandbox" ? select_default(sandboxElement.nodes()[0].contentDocument.body) : select_default("body"); |
|
const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; |
|
const g = new Graph({ |
|
multigraph: true, |
|
compound: true |
|
}).setGraph({ |
|
rankdir: dir, |
|
nodesep: nodeSpacing, |
|
ranksep: rankSpacing, |
|
marginx: 0, |
|
marginy: 0 |
|
}).setDefaultEdgeLabel(function() { |
|
return {}; |
|
}); |
|
let subG; |
|
const subGraphs = diagObj.db.getSubGraphs(); |
|
log$1.info("Subgraphs - ", subGraphs); |
|
for (let i2 = subGraphs.length - 1; i2 >= 0; i2--) { |
|
subG = subGraphs[i2]; |
|
log$1.info("Subgraph - ", subG); |
|
diagObj.db.addVertex( |
|
subG.id, |
|
{ text: subG.title, type: subG.labelType }, |
|
"group", |
|
void 0, |
|
subG.classes, |
|
subG.dir |
|
); |
|
} |
|
const vert = diagObj.db.getVertices(); |
|
const edges = diagObj.db.getEdges(); |
|
log$1.info("Edges", edges); |
|
let i = 0; |
|
for (i = subGraphs.length - 1; i >= 0; i--) { |
|
subG = subGraphs[i]; |
|
selectAll_default("cluster").append("text"); |
|
for (let j = 0; j < subG.nodes.length; j++) { |
|
log$1.info("Setting up subgraphs", subG.nodes[j], subG.id); |
|
g.setParent(subG.nodes[j], subG.id); |
|
} |
|
} |
|
await addVertices(vert, g, id, root, doc, diagObj); |
|
await addEdges(edges, g); |
|
const svg = root.select(`[id="${id}"]`); |
|
const element = root.select("#" + id + " g"); |
|
await render(element, g, ["point", "circle", "cross"], "flowchart", id); |
|
utils.insertTitle(svg, "flowchartTitleText", conf2.titleTopMargin, diagObj.db.getDiagramTitle()); |
|
setupGraphViewbox$1(g, svg, conf2.diagramPadding, conf2.useMaxWidth); |
|
diagObj.db.indexNodes("subGraph" + i); |
|
if (!conf2.htmlLabels) { |
|
const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); |
|
for (const label of labels) { |
|
const dim = label.getBBox(); |
|
const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect"); |
|
rect.setAttribute("rx", 0); |
|
rect.setAttribute("ry", 0); |
|
rect.setAttribute("width", dim.width); |
|
rect.setAttribute("height", dim.height); |
|
label.insertBefore(rect, label.firstChild); |
|
} |
|
} |
|
const keys = Object.keys(vert); |
|
keys.forEach(function(key) { |
|
const vertex = vert[key]; |
|
if (vertex.link) { |
|
const node = select_default("#" + id + ' [id="' + key + '"]'); |
|
if (node) { |
|
const link = doc.createElementNS("http://www.w3.org/2000/svg", "a"); |
|
link.setAttributeNS("http://www.w3.org/2000/svg", "class", vertex.classes.join(" ")); |
|
link.setAttributeNS("http://www.w3.org/2000/svg", "href", vertex.link); |
|
link.setAttributeNS("http://www.w3.org/2000/svg", "rel", "noopener"); |
|
if (securityLevel === "sandbox") { |
|
link.setAttributeNS("http://www.w3.org/2000/svg", "target", "_top"); |
|
} else if (vertex.linkTarget) { |
|
link.setAttributeNS("http://www.w3.org/2000/svg", "target", vertex.linkTarget); |
|
} |
|
const linkNode = node.insert(function() { |
|
return link; |
|
}, ":first-child"); |
|
const shape = node.select(".label-container"); |
|
if (shape) { |
|
linkNode.append(function() { |
|
return shape.node(); |
|
}); |
|
} |
|
const label = node.select(".label"); |
|
if (label) { |
|
linkNode.append(function() { |
|
return label.node(); |
|
}); |
|
} |
|
} |
|
} |
|
}); |
|
}; |
|
var flowRendererV2 = { |
|
setConf, |
|
addVertices, |
|
addEdges, |
|
getClasses, |
|
draw |
|
}; |
|
var fade = (color, opacity) => { |
|
const channel = channel_default; |
|
const r = channel(color, "r"); |
|
const g = channel(color, "g"); |
|
const b = channel(color, "b"); |
|
return rgba_default(r, g, b, opacity); |
|
}; |
|
var getStyles = (options) => `.label { |
|
font-family: ${options.fontFamily}; |
|
color: ${options.nodeTextColor || options.textColor}; |
|
} |
|
.cluster-label text { |
|
fill: ${options.titleColor}; |
|
} |
|
.cluster-label span,p { |
|
color: ${options.titleColor}; |
|
} |
|
|
|
.label text,span,p { |
|
fill: ${options.nodeTextColor || options.textColor}; |
|
color: ${options.nodeTextColor || options.textColor}; |
|
} |
|
|
|
.node rect, |
|
.node circle, |
|
.node ellipse, |
|
.node polygon, |
|
.node path { |
|
fill: ${options.mainBkg}; |
|
stroke: ${options.nodeBorder}; |
|
stroke-width: 1px; |
|
} |
|
.flowchart-label text { |
|
text-anchor: middle; |
|
} |
|
// .flowchart-label .text-outer-tspan { |
|
// text-anchor: middle; |
|
// } |
|
// .flowchart-label .text-inner-tspan { |
|
// text-anchor: start; |
|
// } |
|
|
|
.node .katex path { |
|
fill: #000; |
|
stroke: #000; |
|
stroke-width: 1px; |
|
} |
|
|
|
.node .label { |
|
text-align: center; |
|
} |
|
.node.clickable { |
|
cursor: pointer; |
|
} |
|
|
|
.arrowheadPath { |
|
fill: ${options.arrowheadColor}; |
|
} |
|
|
|
.edgePath .path { |
|
stroke: ${options.lineColor}; |
|
stroke-width: 2.0px; |
|
} |
|
|
|
.flowchart-link { |
|
stroke: ${options.lineColor}; |
|
fill: none; |
|
} |
|
|
|
.edgeLabel { |
|
background-color: ${options.edgeLabelBackground}; |
|
rect { |
|
opacity: 0.5; |
|
background-color: ${options.edgeLabelBackground}; |
|
fill: ${options.edgeLabelBackground}; |
|
} |
|
text-align: center; |
|
} |
|
|
|
/* For html labels only */ |
|
.labelBkg { |
|
background-color: ${fade(options.edgeLabelBackground, 0.5)}; |
|
// background-color: |
|
} |
|
|
|
.cluster rect { |
|
fill: ${options.clusterBkg}; |
|
stroke: ${options.clusterBorder}; |
|
stroke-width: 1px; |
|
} |
|
|
|
.cluster text { |
|
fill: ${options.titleColor}; |
|
} |
|
|
|
.cluster span,p { |
|
color: ${options.titleColor}; |
|
} |
|
/* .cluster div { |
|
color: ${options.titleColor}; |
|
} */ |
|
|
|
div.mermaidTooltip { |
|
position: absolute; |
|
text-align: center; |
|
max-width: 200px; |
|
padding: 2px; |
|
font-family: ${options.fontFamily}; |
|
font-size: 12px; |
|
background: ${options.tertiaryColor}; |
|
border: 1px solid ${options.border2}; |
|
border-radius: 2px; |
|
pointer-events: none; |
|
z-index: 100; |
|
} |
|
|
|
.flowchartTitleText { |
|
text-anchor: middle; |
|
font-size: 18px; |
|
fill: ${options.textColor}; |
|
} |
|
`; |
|
var flowStyles = getStyles; |
|
|
|
export { |
|
isSubgraph, |
|
edgeToId, |
|
applyStyle, |
|
applyClass, |
|
applyTransition, |
|
addHtmlLabel, |
|
flowRendererV2, |
|
flowStyles |
|
}; |
|
|
|
|