UNPKG

14.7 kBJavaScriptView Raw
1import { p as parser, d as db, s as styles } from "./styles-36a1a2e8.js";
2import { F as curveBasis, A as utils, l as log, G as parseGenericTypes, c as getConfig, j as d3select, k as configureSvgSize } from "./mermaid-dcacb631.js";
3import { G as Graph } from "./graph-fe24fab6.js";
4import { l as layout } from "./layout-163b9689.js";
5import { l as line } from "./line-87f517ef.js";
6import "./array-b7dcf730.js";
7import "./path-39bad7e2.js";
8let edgeCount = 0;
9const drawEdge = function(elem, path, relation, conf, diagObj) {
10 const getRelationType = function(type) {
11 switch (type) {
12 case diagObj.db.relationType.AGGREGATION:
13 return "aggregation";
14 case diagObj.db.relationType.EXTENSION:
15 return "extension";
16 case diagObj.db.relationType.COMPOSITION:
17 return "composition";
18 case diagObj.db.relationType.DEPENDENCY:
19 return "dependency";
20 case diagObj.db.relationType.LOLLIPOP:
21 return "lollipop";
22 }
23 };
24 path.points = path.points.filter((p) => !Number.isNaN(p.y));
25 const lineData = path.points;
26 const lineFunction = line().x(function(d) {
27 return d.x;
28 }).y(function(d) {
29 return d.y;
30 }).curve(curveBasis);
31 const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", "edge" + edgeCount).attr("class", "relation");
32 let url = "";
33 if (conf.arrowMarkerAbsolute) {
34 url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search;
35 url = url.replace(/\(/g, "\\(");
36 url = url.replace(/\)/g, "\\)");
37 }
38 if (relation.relation.lineType == 1) {
39 svgPath.attr("class", "relation dashed-line");
40 }
41 if (relation.relation.lineType == 10) {
42 svgPath.attr("class", "relation dotted-line");
43 }
44 if (relation.relation.type1 !== "none") {
45 svgPath.attr(
46 "marker-start",
47 "url(" + url + "#" + getRelationType(relation.relation.type1) + "Start)"
48 );
49 }
50 if (relation.relation.type2 !== "none") {
51 svgPath.attr(
52 "marker-end",
53 "url(" + url + "#" + getRelationType(relation.relation.type2) + "End)"
54 );
55 }
56 let x, y;
57 const l = path.points.length;
58 let labelPosition = utils.calcLabelPosition(path.points);
59 x = labelPosition.x;
60 y = labelPosition.y;
61 let p1_card_x, p1_card_y;
62 let p2_card_x, p2_card_y;
63 if (l % 2 !== 0 && l > 1) {
64 let cardinality_1_point = utils.calcCardinalityPosition(
65 relation.relation.type1 !== "none",
66 path.points,
67 path.points[0]
68 );
69 let cardinality_2_point = utils.calcCardinalityPosition(
70 relation.relation.type2 !== "none",
71 path.points,
72 path.points[l - 1]
73 );
74 log.debug("cardinality_1_point " + JSON.stringify(cardinality_1_point));
75 log.debug("cardinality_2_point " + JSON.stringify(cardinality_2_point));
76 p1_card_x = cardinality_1_point.x;
77 p1_card_y = cardinality_1_point.y;
78 p2_card_x = cardinality_2_point.x;
79 p2_card_y = cardinality_2_point.y;
80 }
81 if (relation.title !== void 0) {
82 const g = elem.append("g").attr("class", "classLabel");
83 const label = g.append("text").attr("class", "label").attr("x", x).attr("y", y).attr("fill", "red").attr("text-anchor", "middle").text(relation.title);
84 window.label = label;
85 const bounds = label.node().getBBox();
86 g.insert("rect", ":first-child").attr("class", "box").attr("x", bounds.x - conf.padding / 2).attr("y", bounds.y - conf.padding / 2).attr("width", bounds.width + conf.padding).attr("height", bounds.height + conf.padding);
87 }
88 log.info("Rendering relation " + JSON.stringify(relation));
89 if (relation.relationTitle1 !== void 0 && relation.relationTitle1 !== "none") {
90 const g = elem.append("g").attr("class", "cardinality");
91 g.append("text").attr("class", "type1").attr("x", p1_card_x).attr("y", p1_card_y).attr("fill", "black").attr("font-size", "6").text(relation.relationTitle1);
92 }
93 if (relation.relationTitle2 !== void 0 && relation.relationTitle2 !== "none") {
94 const g = elem.append("g").attr("class", "cardinality");
95 g.append("text").attr("class", "type2").attr("x", p2_card_x).attr("y", p2_card_y).attr("fill", "black").attr("font-size", "6").text(relation.relationTitle2);
96 }
97 edgeCount++;
98};
99const drawClass = function(elem, classDef, conf, diagObj) {
100 log.debug("Rendering class ", classDef, conf);
101 const id = classDef.id;
102 const classInfo = {
103 id,
104 label: classDef.id,
105 width: 0,
106 height: 0
107 };
108 const g = elem.append("g").attr("id", diagObj.db.lookUpDomId(id)).attr("class", "classGroup");
109 let title;
110 if (classDef.link) {
111 title = g.append("svg:a").attr("xlink:href", classDef.link).attr("target", classDef.linkTarget).append("text").attr("y", conf.textHeight + conf.padding).attr("x", 0);
112 } else {
113 title = g.append("text").attr("y", conf.textHeight + conf.padding).attr("x", 0);
114 }
115 let isFirst = true;
116 classDef.annotations.forEach(function(member) {
117 const titleText2 = title.append("tspan").text("«" + member + "»");
118 if (!isFirst) {
119 titleText2.attr("dy", conf.textHeight);
120 }
121 isFirst = false;
122 });
123 let classTitleString = getClassTitleString(classDef);
124 const classTitle = title.append("tspan").text(classTitleString).attr("class", "title");
125 if (!isFirst) {
126 classTitle.attr("dy", conf.textHeight);
127 }
128 const titleHeight = title.node().getBBox().height;
129 let membersLine;
130 let membersBox;
131 let methodsLine;
132 if (classDef.members.length > 0) {
133 membersLine = g.append("line").attr("x1", 0).attr("y1", conf.padding + titleHeight + conf.dividerMargin / 2).attr("y2", conf.padding + titleHeight + conf.dividerMargin / 2);
134 const members = g.append("text").attr("x", conf.padding).attr("y", titleHeight + conf.dividerMargin + conf.textHeight).attr("fill", "white").attr("class", "classText");
135 isFirst = true;
136 classDef.members.forEach(function(member) {
137 addTspan(members, member, isFirst, conf);
138 isFirst = false;
139 });
140 membersBox = members.node().getBBox();
141 }
142 if (classDef.methods.length > 0) {
143 methodsLine = g.append("line").attr("x1", 0).attr("y1", conf.padding + titleHeight + conf.dividerMargin + membersBox.height).attr("y2", conf.padding + titleHeight + conf.dividerMargin + membersBox.height);
144 const methods = g.append("text").attr("x", conf.padding).attr("y", titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight).attr("fill", "white").attr("class", "classText");
145 isFirst = true;
146 classDef.methods.forEach(function(method) {
147 addTspan(methods, method, isFirst, conf);
148 isFirst = false;
149 });
150 }
151 const classBox = g.node().getBBox();
152 var cssClassStr = " ";
153 if (classDef.cssClasses.length > 0) {
154 cssClassStr = cssClassStr + classDef.cssClasses.join(" ");
155 }
156 const rect = g.insert("rect", ":first-child").attr("x", 0).attr("y", 0).attr("width", classBox.width + 2 * conf.padding).attr("height", classBox.height + conf.padding + 0.5 * conf.dividerMargin).attr("class", cssClassStr);
157 const rectWidth = rect.node().getBBox().width;
158 title.node().childNodes.forEach(function(x) {
159 x.setAttribute("x", (rectWidth - x.getBBox().width) / 2);
160 });
161 if (classDef.tooltip) {
162 title.insert("title").text(classDef.tooltip);
163 }
164 if (membersLine) {
165 membersLine.attr("x2", rectWidth);
166 }
167 if (methodsLine) {
168 methodsLine.attr("x2", rectWidth);
169 }
170 classInfo.width = rectWidth;
171 classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin;
172 return classInfo;
173};
174const getClassTitleString = function(classDef) {
175 let classTitleString = classDef.id;
176 if (classDef.type) {
177 classTitleString += "<" + parseGenericTypes(classDef.type) + ">";
178 }
179 return classTitleString;
180};
181const drawNote = function(elem, note, conf, diagObj) {
182 log.debug("Rendering note ", note, conf);
183 const id = note.id;
184 const noteInfo = {
185 id,
186 text: note.text,
187 width: 0,
188 height: 0
189 };
190 const g = elem.append("g").attr("id", id).attr("class", "classGroup");
191 let text = g.append("text").attr("y", conf.textHeight + conf.padding).attr("x", 0);
192 const lines = JSON.parse(`"${note.text}"`).split("\n");
193 lines.forEach(function(line2) {
194 log.debug(`Adding line: ${line2}`);
195 text.append("tspan").text(line2).attr("class", "title").attr("dy", conf.textHeight);
196 });
197 const noteBox = g.node().getBBox();
198 const rect = g.insert("rect", ":first-child").attr("x", 0).attr("y", 0).attr("width", noteBox.width + 2 * conf.padding).attr(
199 "height",
200 noteBox.height + lines.length * conf.textHeight + conf.padding + 0.5 * conf.dividerMargin
201 );
202 const rectWidth = rect.node().getBBox().width;
203 text.node().childNodes.forEach(function(x) {
204 x.setAttribute("x", (rectWidth - x.getBBox().width) / 2);
205 });
206 noteInfo.width = rectWidth;
207 noteInfo.height = noteBox.height + lines.length * conf.textHeight + conf.padding + 0.5 * conf.dividerMargin;
208 return noteInfo;
209};
210const addTspan = function(textEl, member, isFirst, conf) {
211 const { displayText, cssStyle } = member.getDisplayDetails();
212 const tSpan = textEl.append("tspan").attr("x", conf.padding).text(displayText);
213 if (cssStyle !== "") {
214 tSpan.attr("style", member.cssStyle);
215 }
216 if (!isFirst) {
217 tSpan.attr("dy", conf.textHeight);
218 }
219};
220const svgDraw = {
221 getClassTitleString,
222 drawClass,
223 drawEdge,
224 drawNote
225};
226let idCache = {};
227const padding = 20;
228const getGraphId = function(label) {
229 const foundEntry = Object.entries(idCache).find((entry) => entry[1].label === label);
230 if (foundEntry) {
231 return foundEntry[0];
232 }
233};
234const insertMarkers = function(elem) {
235 elem.append("defs").append("marker").attr("id", "extensionStart").attr("class", "extension").attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z");
236 elem.append("defs").append("marker").attr("id", "extensionEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z");
237 elem.append("defs").append("marker").attr("id", "compositionStart").attr("class", "extension").attr("refX", 0).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");
238 elem.append("defs").append("marker").attr("id", "compositionEnd").attr("refX", 19).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");
239 elem.append("defs").append("marker").attr("id", "aggregationStart").attr("class", "extension").attr("refX", 0).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");
240 elem.append("defs").append("marker").attr("id", "aggregationEnd").attr("refX", 19).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");
241 elem.append("defs").append("marker").attr("id", "dependencyStart").attr("class", "extension").attr("refX", 0).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");
242 elem.append("defs").append("marker").attr("id", "dependencyEnd").attr("refX", 19).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");
243};
244const draw = function(text, id, _version, diagObj) {
245 const conf = getConfig().class;
246 idCache = {};
247 log.info("Rendering diagram " + text);
248 const securityLevel = getConfig().securityLevel;
249 let sandboxElement;
250 if (securityLevel === "sandbox") {
251 sandboxElement = d3select("#i" + id);
252 }
253 const root = securityLevel === "sandbox" ? d3select(sandboxElement.nodes()[0].contentDocument.body) : d3select("body");
254 const diagram2 = root.select(`[id='${id}']`);
255 insertMarkers(diagram2);
256 const g = new Graph({
257 multigraph: true
258 });
259 g.setGraph({
260 isMultiGraph: true
261 });
262 g.setDefaultEdgeLabel(function() {
263 return {};
264 });
265 const classes = diagObj.db.getClasses();
266 const keys = Object.keys(classes);
267 for (const key of keys) {
268 const classDef = classes[key];
269 const node = svgDraw.drawClass(diagram2, classDef, conf, diagObj);
270 idCache[node.id] = node;
271 g.setNode(node.id, node);
272 log.info("Org height: " + node.height);
273 }
274 const relations = diagObj.db.getRelations();
275 relations.forEach(function(relation) {
276 log.info(
277 // cspell:ignore tjoho
278 "tjoho" + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation)
279 );
280 g.setEdge(
281 getGraphId(relation.id1),
282 getGraphId(relation.id2),
283 {
284 relation
285 },
286 relation.title || "DEFAULT"
287 );
288 });
289 const notes = diagObj.db.getNotes();
290 notes.forEach(function(note) {
291 log.debug(`Adding note: ${JSON.stringify(note)}`);
292 const node = svgDraw.drawNote(diagram2, note, conf, diagObj);
293 idCache[node.id] = node;
294 g.setNode(node.id, node);
295 if (note.class && note.class in classes) {
296 g.setEdge(
297 note.id,
298 getGraphId(note.class),
299 {
300 relation: {
301 id1: note.id,
302 id2: note.class,
303 relation: {
304 type1: "none",
305 type2: "none",
306 lineType: 10
307 }
308 }
309 },
310 "DEFAULT"
311 );
312 }
313 });
314 layout(g);
315 g.nodes().forEach(function(v) {
316 if (v !== void 0 && g.node(v) !== void 0) {
317 log.debug("Node " + v + ": " + JSON.stringify(g.node(v)));
318 root.select("#" + (diagObj.db.lookUpDomId(v) || v)).attr(
319 "transform",
320 "translate(" + (g.node(v).x - g.node(v).width / 2) + "," + (g.node(v).y - g.node(v).height / 2) + " )"
321 );
322 }
323 });
324 g.edges().forEach(function(e) {
325 if (e !== void 0 && g.edge(e) !== void 0) {
326 log.debug("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(g.edge(e)));
327 svgDraw.drawEdge(diagram2, g.edge(e), g.edge(e).relation, conf, diagObj);
328 }
329 });
330 const svgBounds = diagram2.node().getBBox();
331 const width = svgBounds.width + padding * 2;
332 const height = svgBounds.height + padding * 2;
333 configureSvgSize(diagram2, height, width, conf.useMaxWidth);
334 const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`;
335 log.debug(`viewBox ${vBox}`);
336 diagram2.attr("viewBox", vBox);
337};
338const renderer = {
339 draw
340};
341const diagram = {
342 parser,
343 db,
344 renderer,
345 styles,
346 init: (cnf) => {
347 if (!cnf.class) {
348 cnf.class = {};
349 }
350 cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;
351 db.clear();
352 }
353};
354export {
355 diagram
356};