@vanduo-oss/vd3-flowchart 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +32 -8
- package/SKILL.md +28 -35
- package/dist/core.d.ts +11 -0
- package/dist/index.cjs +279 -15
- package/dist/index.cjs.map +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +279 -15
- package/dist/index.js.map +2 -2
- package/dist/meta.json +13 -12
- package/dist/vd3-flowchart.css +44 -3
- package/package.json +12 -6
- package/recipes/editor.vue +17 -0
- package/styles.d.ts +2 -0
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -258,7 +258,8 @@ var EDGE_STROKE_PRESETS = [
|
|
|
258
258
|
{ id: "medium", label: "Medium", width: DEFAULT_EDGE_STROKE_WIDTH },
|
|
259
259
|
{ id: "bold", label: "Bold", width: 3.5 }
|
|
260
260
|
];
|
|
261
|
-
var VD_FLOWCHART_VERSION = "1.
|
|
261
|
+
var VD_FLOWCHART_VERSION = "1.3.0";
|
|
262
|
+
var FLOWCHART_DOCUMENT_VERSION = "1.2.0";
|
|
262
263
|
var FLOWCHART_NODE_TYPES = [
|
|
263
264
|
"rounded-rect",
|
|
264
265
|
"rect",
|
|
@@ -495,17 +496,45 @@ function normalizeEdge(rawEdge, index, nodeIds, usedIds) {
|
|
|
495
496
|
syncEdgeKind(edge);
|
|
496
497
|
return edge;
|
|
497
498
|
}
|
|
499
|
+
function parseDocumentVersion(value) {
|
|
500
|
+
const raw = typeof value === "number" && Number.isFinite(value) ? String(value) : typeof value === "string" ? value.trim() : "";
|
|
501
|
+
const match = /^(\d+)(?:\.(\d+))?(?:\.(\d+))?$/.exec(raw);
|
|
502
|
+
if (!match) return null;
|
|
503
|
+
return {
|
|
504
|
+
major: Number(match[1]),
|
|
505
|
+
minor: Number(match[2] ?? 0),
|
|
506
|
+
patch: Number(match[3] ?? 0)
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
function isSupportedDocumentVersion(value) {
|
|
510
|
+
const parsed = parseDocumentVersion(value);
|
|
511
|
+
const max = parseDocumentVersion(FLOWCHART_DOCUMENT_VERSION);
|
|
512
|
+
if (!parsed || !max || parsed.major !== max.major) return false;
|
|
513
|
+
if (parsed.minor > max.minor) return false;
|
|
514
|
+
if (parsed.minor === max.minor && parsed.patch > max.patch) return false;
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
498
517
|
function normalizeDocument(input) {
|
|
499
518
|
let source = input;
|
|
500
519
|
if (typeof source === "string") {
|
|
501
520
|
try {
|
|
502
521
|
source = JSON.parse(source);
|
|
503
522
|
} catch {
|
|
504
|
-
|
|
523
|
+
throw new TypeError("Invalid flowchart JSON. The current document was not changed.");
|
|
505
524
|
}
|
|
506
525
|
}
|
|
507
526
|
if (!isPlainObject(source)) {
|
|
508
|
-
|
|
527
|
+
throw new TypeError("A flowchart document must be an object.");
|
|
528
|
+
}
|
|
529
|
+
if (source.version !== void 0 && !isSupportedDocumentVersion(source.version)) {
|
|
530
|
+
throw new RangeError(
|
|
531
|
+
`Unsupported flowchart document version: ${String(source.version)}. Supported through ${FLOWCHART_DOCUMENT_VERSION}.`
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
for (const key of ["nodes", "edges"]) {
|
|
535
|
+
if (source[key] !== void 0 && !Array.isArray(source[key])) {
|
|
536
|
+
throw new TypeError(`Flowchart ${key} must be an array.`);
|
|
537
|
+
}
|
|
509
538
|
}
|
|
510
539
|
const usedNodeIds = /* @__PURE__ */ new Set();
|
|
511
540
|
const nodes = (Array.isArray(source.nodes) ? source.nodes : []).slice(0, MAX_NODES).map((node, index) => normalizeNode(node, index, usedNodeIds));
|
|
@@ -513,7 +542,7 @@ function normalizeDocument(input) {
|
|
|
513
542
|
const usedEdgeIds = /* @__PURE__ */ new Set();
|
|
514
543
|
const edges = (Array.isArray(source.edges) ? source.edges : []).slice(0, MAX_EDGES).map((edge, index) => normalizeEdge(edge, index, nodeIds, usedEdgeIds)).filter(Boolean);
|
|
515
544
|
return {
|
|
516
|
-
version:
|
|
545
|
+
version: FLOWCHART_DOCUMENT_VERSION,
|
|
517
546
|
viewport: normalizeViewport(source.viewport),
|
|
518
547
|
nodes,
|
|
519
548
|
edges
|
|
@@ -968,6 +997,8 @@ function getBounds(nodes) {
|
|
|
968
997
|
function createField(labelText, control) {
|
|
969
998
|
const wrapper = createElement("div", { className: "vd-flowchart-field" });
|
|
970
999
|
const label = createElement("label", { text: labelText });
|
|
1000
|
+
control.id || (control.id = nextId("flowchart-field"));
|
|
1001
|
+
label.htmlFor = control.id;
|
|
971
1002
|
wrapper.appendChild(label);
|
|
972
1003
|
wrapper.appendChild(control);
|
|
973
1004
|
return wrapper;
|
|
@@ -1352,14 +1383,127 @@ var VdFlowchart = class {
|
|
|
1352
1383
|
this.jsonActions.appendChild(this.loadJsonButton);
|
|
1353
1384
|
this.jsonPanel.appendChild(this.jsonTextarea);
|
|
1354
1385
|
this.jsonPanel.appendChild(this.jsonActions);
|
|
1386
|
+
this.jsonStatus = createElement("p", { className: "vd-flowchart-json-status" });
|
|
1387
|
+
this.jsonStatus.setAttribute("role", "status");
|
|
1388
|
+
this.jsonPanel.appendChild(this.jsonStatus);
|
|
1355
1389
|
this.inspectorPanel.appendChild(this.jsonPanel);
|
|
1356
1390
|
this.body.appendChild(this.palettePanel);
|
|
1357
1391
|
this.body.appendChild(this.canvasEl);
|
|
1358
1392
|
this.body.appendChild(this.inspectorPanel);
|
|
1359
1393
|
this.root.appendChild(this.toolbar);
|
|
1360
1394
|
this.root.appendChild(this.body);
|
|
1395
|
+
this.buildGraphOutline();
|
|
1361
1396
|
this.element.appendChild(this.root);
|
|
1362
1397
|
}
|
|
1398
|
+
buildGraphOutline() {
|
|
1399
|
+
this.graphOutline = createElement("details", { className: "vd-flowchart-outline" });
|
|
1400
|
+
this.graphOutline.appendChild(createElement("summary", { text: "Graph outline" }));
|
|
1401
|
+
this.graphOutline.addEventListener("toggle", () => {
|
|
1402
|
+
if (this.graphOutline.open) this.renderGraphOutline();
|
|
1403
|
+
});
|
|
1404
|
+
this.graphStatus = createElement("p", { className: "vd-flowchart-sr-only" });
|
|
1405
|
+
this.graphStatus.setAttribute("role", "status");
|
|
1406
|
+
this.canvasEl.appendChild(this.graphStatus);
|
|
1407
|
+
this.graphControls = createElement("div", { className: "vd-flowchart-outline-controls" });
|
|
1408
|
+
this.graphNodeSelect = createElement("select");
|
|
1409
|
+
this.graphNodeSelect.setAttribute("aria-label", "Selected node");
|
|
1410
|
+
this.graphNodeSelect.addEventListener(
|
|
1411
|
+
"change",
|
|
1412
|
+
() => this.selectNode(this.graphNodeSelect.value)
|
|
1413
|
+
);
|
|
1414
|
+
this.graphTargetSelect = createElement("select");
|
|
1415
|
+
this.graphTargetSelect.setAttribute("aria-label", "Connection target");
|
|
1416
|
+
this.graphTargetSelect.addEventListener("change", () => this.renderGraphOutline());
|
|
1417
|
+
this.graphConnectButton = createElement("button", {
|
|
1418
|
+
text: "Connect nodes",
|
|
1419
|
+
type: "button",
|
|
1420
|
+
className: "vd-flowchart-btn"
|
|
1421
|
+
});
|
|
1422
|
+
this.graphConnectButton.addEventListener("click", () => {
|
|
1423
|
+
if (this.readonly || this.graphNodeSelect.value === this.graphTargetSelect.value) {
|
|
1424
|
+
return;
|
|
1425
|
+
}
|
|
1426
|
+
this.addEdge({
|
|
1427
|
+
from: this.graphNodeSelect.value,
|
|
1428
|
+
to: this.graphTargetSelect.value,
|
|
1429
|
+
autoPort: true
|
|
1430
|
+
});
|
|
1431
|
+
});
|
|
1432
|
+
this.graphEditButton = createElement("button", {
|
|
1433
|
+
text: "Edit selected label",
|
|
1434
|
+
type: "button",
|
|
1435
|
+
className: "vd-flowchart-btn"
|
|
1436
|
+
});
|
|
1437
|
+
this.graphEditButton.addEventListener(
|
|
1438
|
+
"click",
|
|
1439
|
+
() => this.startTextEdit(this.graphNodeSelect.value)
|
|
1440
|
+
);
|
|
1441
|
+
this.graphControls.append(
|
|
1442
|
+
createField("Selected node", this.graphNodeSelect),
|
|
1443
|
+
createField("Connection target", this.graphTargetSelect),
|
|
1444
|
+
this.graphConnectButton,
|
|
1445
|
+
this.graphEditButton
|
|
1446
|
+
);
|
|
1447
|
+
this.graphOutline.appendChild(this.graphControls);
|
|
1448
|
+
this.graphList = createElement("ul");
|
|
1449
|
+
this.graphList.setAttribute("aria-label", "Nodes and connections");
|
|
1450
|
+
this.graphOutline.appendChild(this.graphList);
|
|
1451
|
+
this.root.appendChild(this.graphOutline);
|
|
1452
|
+
this.canvasEl.setAttribute("role", "group");
|
|
1453
|
+
this.canvasEl.setAttribute(
|
|
1454
|
+
"aria-label",
|
|
1455
|
+
"Diagram canvas. Arrow keys select nodes; Enter edits a label. Graph outline provides connections."
|
|
1456
|
+
);
|
|
1457
|
+
this.jsonTextarea.setAttribute("aria-label", "Flowchart JSON");
|
|
1458
|
+
}
|
|
1459
|
+
renderGraphOutline() {
|
|
1460
|
+
if (!this.graphOutline) return;
|
|
1461
|
+
const nodes = this.documentData.nodes;
|
|
1462
|
+
const edges = this.documentData.edges;
|
|
1463
|
+
const labels = new Map(nodes.map((node) => [node.id, node.text || node.id]));
|
|
1464
|
+
const selected = this.selection?.kind === "node" ? this.selection.id : null;
|
|
1465
|
+
this.graphStatus.textContent = selected ? `Selected: ${labels.get(selected)}. ${nodes.length} nodes, ${edges.length} connections.` : `${nodes.length} nodes, ${edges.length} connections.`;
|
|
1466
|
+
if (!this.graphOutline.open) return;
|
|
1467
|
+
const signature = JSON.stringify([
|
|
1468
|
+
nodes.map((node) => [node.id, node.text]),
|
|
1469
|
+
edges.map((edge) => [edge.id, edge.from.nodeId, edge.to.nodeId, edge.label])
|
|
1470
|
+
]);
|
|
1471
|
+
if (signature !== this.graphSignature) {
|
|
1472
|
+
this.graphSignature = signature;
|
|
1473
|
+
for (const select of [this.graphNodeSelect, this.graphTargetSelect]) {
|
|
1474
|
+
const previous = select.value;
|
|
1475
|
+
select.replaceChildren();
|
|
1476
|
+
for (const node of nodes)
|
|
1477
|
+
select.appendChild(
|
|
1478
|
+
createElement("option", { value: node.id, text: labels.get(node.id) })
|
|
1479
|
+
);
|
|
1480
|
+
if (labels.has(previous)) select.value = previous;
|
|
1481
|
+
}
|
|
1482
|
+
this.graphList.replaceChildren();
|
|
1483
|
+
const outgoing = new Map(nodes.map((node) => [node.id, []]));
|
|
1484
|
+
const incoming = new Map(nodes.map((node) => [node.id, []]));
|
|
1485
|
+
for (const edge of edges) {
|
|
1486
|
+
outgoing.get(edge.from.nodeId)?.push(`${labels.get(edge.to.nodeId)}${edge.label ? ` (${edge.label})` : ""}`);
|
|
1487
|
+
incoming.get(edge.to.nodeId)?.push(labels.get(edge.from.nodeId));
|
|
1488
|
+
}
|
|
1489
|
+
for (const node of nodes) {
|
|
1490
|
+
const to = outgoing.get(node.id);
|
|
1491
|
+
const from = incoming.get(node.id);
|
|
1492
|
+
const relationships = [
|
|
1493
|
+
to.length ? `Connects to ${to.join(", ")}.` : "No outgoing connections.",
|
|
1494
|
+
from.length ? `Connected from ${from.join(", ")}.` : ""
|
|
1495
|
+
];
|
|
1496
|
+
this.graphList.appendChild(
|
|
1497
|
+
createElement("li", { text: `${labels.get(node.id)}. ${relationships.join(" ")}` })
|
|
1498
|
+
);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
if (selected) this.graphNodeSelect.value = selected;
|
|
1502
|
+
this.graphNodeSelect.disabled = nodes.length === 0;
|
|
1503
|
+
this.graphTargetSelect.disabled = this.readonly || nodes.length < 2;
|
|
1504
|
+
this.graphConnectButton.disabled = this.readonly || nodes.length < 2 || this.graphNodeSelect.value === this.graphTargetSelect.value;
|
|
1505
|
+
this.graphEditButton.disabled = this.readonly || nodes.length === 0;
|
|
1506
|
+
}
|
|
1363
1507
|
bindEvents() {
|
|
1364
1508
|
this.toolbar.addEventListener("click", this.handleToolbarClick);
|
|
1365
1509
|
this.arrangeSelect.addEventListener("change", this.handleArrangeChange);
|
|
@@ -1466,7 +1610,12 @@ var VdFlowchart = class {
|
|
|
1466
1610
|
return;
|
|
1467
1611
|
}
|
|
1468
1612
|
if (action === "load" && !this.readonly) {
|
|
1469
|
-
|
|
1613
|
+
try {
|
|
1614
|
+
this.load(this.jsonTextarea.value);
|
|
1615
|
+
this.jsonStatus.textContent = "";
|
|
1616
|
+
} catch (error) {
|
|
1617
|
+
this.jsonStatus.textContent = error.message;
|
|
1618
|
+
}
|
|
1470
1619
|
}
|
|
1471
1620
|
}
|
|
1472
1621
|
handleSelectionFieldInput(event) {
|
|
@@ -1537,10 +1686,31 @@ var VdFlowchart = class {
|
|
|
1537
1686
|
}
|
|
1538
1687
|
}
|
|
1539
1688
|
handleKeyDown(event) {
|
|
1540
|
-
if (this.readonly) return;
|
|
1541
1689
|
if (event.target && (event.target.tagName === "INPUT" || event.target.tagName === "TEXTAREA" || event.target.tagName === "SELECT")) {
|
|
1542
1690
|
return;
|
|
1543
1691
|
}
|
|
1692
|
+
if (event.target === this.canvasEl) {
|
|
1693
|
+
const nodes = this.documentData.nodes;
|
|
1694
|
+
const index = nodes.findIndex((node) => node.id === this.selection?.id);
|
|
1695
|
+
let next = -1;
|
|
1696
|
+
if (event.key === "ArrowDown" || event.key === "ArrowRight")
|
|
1697
|
+
next = (index + 1) % nodes.length;
|
|
1698
|
+
if (event.key === "ArrowUp" || event.key === "ArrowLeft")
|
|
1699
|
+
next = index < 0 ? nodes.length - 1 : (index - 1 + nodes.length) % nodes.length;
|
|
1700
|
+
if (event.key === "Home") next = 0;
|
|
1701
|
+
if (event.key === "End") next = nodes.length - 1;
|
|
1702
|
+
if (nodes[next]) {
|
|
1703
|
+
event.preventDefault();
|
|
1704
|
+
this.selectNode(nodes[next].id);
|
|
1705
|
+
return;
|
|
1706
|
+
}
|
|
1707
|
+
if (event.key === "Enter" && !this.readonly && this.selection?.kind === "node") {
|
|
1708
|
+
event.preventDefault();
|
|
1709
|
+
this.startTextEdit(this.selection.id);
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
if (this.readonly) return;
|
|
1544
1714
|
if (event.key === "Escape" && this.activeTool) {
|
|
1545
1715
|
event.preventDefault();
|
|
1546
1716
|
this.setActiveTool(null);
|
|
@@ -1831,7 +2001,7 @@ var VdFlowchart = class {
|
|
|
1831
2001
|
node.x = nextX;
|
|
1832
2002
|
node.y = nextY;
|
|
1833
2003
|
this.interaction.moved = true;
|
|
1834
|
-
this.
|
|
2004
|
+
this.renderDraggedNode(node);
|
|
1835
2005
|
}
|
|
1836
2006
|
return;
|
|
1837
2007
|
}
|
|
@@ -2206,11 +2376,13 @@ var VdFlowchart = class {
|
|
|
2206
2376
|
if (event.key === "Escape") {
|
|
2207
2377
|
event.preventDefault();
|
|
2208
2378
|
this.stopTextEdit({ commit: false });
|
|
2379
|
+
this.canvasEl.focus();
|
|
2209
2380
|
return;
|
|
2210
2381
|
}
|
|
2211
2382
|
if (event.key === "Enter" && (event.ctrlKey || event.metaKey)) {
|
|
2212
2383
|
event.preventDefault();
|
|
2213
2384
|
this.stopTextEdit({ commit: true });
|
|
2385
|
+
this.canvasEl.focus();
|
|
2214
2386
|
}
|
|
2215
2387
|
});
|
|
2216
2388
|
textarea.addEventListener("blur", () => {
|
|
@@ -2284,6 +2456,7 @@ var VdFlowchart = class {
|
|
|
2284
2456
|
if (shouldRenderScene) this.renderScene();
|
|
2285
2457
|
if (shouldRenderInspector) this.renderSelectionPanel();
|
|
2286
2458
|
if (shouldRenderJson) this.syncJsonTextarea();
|
|
2459
|
+
if (shouldRenderInspector) this.renderGraphOutline();
|
|
2287
2460
|
this.updateToolbarLabel();
|
|
2288
2461
|
this.updatePaletteState();
|
|
2289
2462
|
this.positionTextEditor();
|
|
@@ -2299,15 +2472,28 @@ var VdFlowchart = class {
|
|
|
2299
2472
|
clearChildren(this.nodesLayer);
|
|
2300
2473
|
clearChildren(this.overlayLayer);
|
|
2301
2474
|
const nodeMap = new Map(this.documentData.nodes.map((node) => [node.id, node]));
|
|
2475
|
+
this.sceneNodeMap = nodeMap;
|
|
2476
|
+
this.nodeElements = /* @__PURE__ */ new Map();
|
|
2477
|
+
this.edgeElements = /* @__PURE__ */ new Map();
|
|
2478
|
+
this.incidentEdges = /* @__PURE__ */ new Map();
|
|
2302
2479
|
this.documentData.edges.forEach((edge) => {
|
|
2303
2480
|
const edgeElement = this.renderEdge(edge, nodeMap);
|
|
2304
|
-
if (edgeElement)
|
|
2481
|
+
if (edgeElement) {
|
|
2482
|
+
this.edgesLayer.appendChild(edgeElement);
|
|
2483
|
+
this.edgeElements.set(edge.id, edgeElement);
|
|
2484
|
+
for (const id of /* @__PURE__ */ new Set([edge.from.nodeId, edge.to.nodeId])) {
|
|
2485
|
+
if (!this.incidentEdges.has(id)) this.incidentEdges.set(id, []);
|
|
2486
|
+
this.incidentEdges.get(id).push(edge);
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2305
2489
|
});
|
|
2306
2490
|
if (this.interaction?.kind === "connect" || this.interaction?.kind === "reconnect") {
|
|
2307
2491
|
this.previewLayer.appendChild(this.renderPreviewEdge(this.interaction));
|
|
2308
2492
|
}
|
|
2309
2493
|
this.documentData.nodes.forEach((node) => {
|
|
2310
|
-
this.
|
|
2494
|
+
const element = this.renderNode(node);
|
|
2495
|
+
this.nodesLayer.appendChild(element);
|
|
2496
|
+
this.nodeElements.set(node.id, element);
|
|
2311
2497
|
});
|
|
2312
2498
|
if (this.reconnectEdgeId && !this.readonly) {
|
|
2313
2499
|
const reconnectEdge = this.findEdge(this.reconnectEdgeId);
|
|
@@ -2323,6 +2509,25 @@ var VdFlowchart = class {
|
|
|
2323
2509
|
}
|
|
2324
2510
|
this.syncConnectingState();
|
|
2325
2511
|
}
|
|
2512
|
+
// Drag frames change one translation and its connected paths. Keep unrelated
|
|
2513
|
+
// SVG elements intact; the release event still refreshes inspector/history.
|
|
2514
|
+
renderDraggedNode(node) {
|
|
2515
|
+
const element = this.nodeElements?.get(node.id);
|
|
2516
|
+
if (!element) {
|
|
2517
|
+
this.render({ inspector: false, json: false });
|
|
2518
|
+
return;
|
|
2519
|
+
}
|
|
2520
|
+
element.setAttribute("transform", `translate(${formatNumber(node.x)} ${formatNumber(node.y)})`);
|
|
2521
|
+
element.classList.add("is-dragging");
|
|
2522
|
+
for (const edge of this.incidentEdges.get(node.id) || []) {
|
|
2523
|
+
const previous = this.edgeElements.get(edge.id);
|
|
2524
|
+
const next = this.renderEdge(edge, this.sceneNodeMap);
|
|
2525
|
+
if (previous && next) {
|
|
2526
|
+
previous.replaceWith(next);
|
|
2527
|
+
this.edgeElements.set(edge.id, next);
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2326
2531
|
applyEdgeMarkers(pathElement, edge) {
|
|
2327
2532
|
if (edge.startMarker && edge.startMarker !== "none") {
|
|
2328
2533
|
pathElement.setAttribute(
|
|
@@ -3337,20 +3542,69 @@ var VdFlowchart = class {
|
|
|
3337
3542
|
this.emitChange("clear");
|
|
3338
3543
|
return this;
|
|
3339
3544
|
}
|
|
3545
|
+
updateOptions(options = {}) {
|
|
3546
|
+
if (this.destroyed) return this;
|
|
3547
|
+
if ("readonly" in options) {
|
|
3548
|
+
if (options.readonly && !this.readonly) {
|
|
3549
|
+
this.stopTextEdit({ commit: true });
|
|
3550
|
+
this.interaction = null;
|
|
3551
|
+
this.activeTool = null;
|
|
3552
|
+
this.reconnectEdgeId = null;
|
|
3553
|
+
}
|
|
3554
|
+
this.readonly = Boolean(options.readonly);
|
|
3555
|
+
this.root.classList.toggle("vd-flowchart-readonly", this.readonly);
|
|
3556
|
+
this.arrangeSelect.disabled = this.readonly;
|
|
3557
|
+
this.clearButton.disabled = this.readonly;
|
|
3558
|
+
this.loadJsonButton.disabled = this.readonly;
|
|
3559
|
+
}
|
|
3560
|
+
if ("gridSize" in options) {
|
|
3561
|
+
this.gridSize = clamp(toFiniteNumber(options.gridSize, DEFAULT_GRID_SIZE), 12, 64);
|
|
3562
|
+
const pattern = this.svg.querySelector("pattern");
|
|
3563
|
+
pattern.setAttribute("width", this.gridSize);
|
|
3564
|
+
pattern.setAttribute("height", this.gridSize);
|
|
3565
|
+
pattern.querySelector("path").setAttribute("d", `M ${this.gridSize} 0 L 0 0 0 ${this.gridSize}`);
|
|
3566
|
+
}
|
|
3567
|
+
if ("autoFit" in options) this.autoFit = Boolean(options.autoFit);
|
|
3568
|
+
if ("history" in options && options.history !== false !== this.historyEnabled) {
|
|
3569
|
+
this.historyEnabled = options.history !== false;
|
|
3570
|
+
this.history = [];
|
|
3571
|
+
this.historyIndex = -1;
|
|
3572
|
+
this.seedHistory();
|
|
3573
|
+
}
|
|
3574
|
+
if ("historyLimit" in options) {
|
|
3575
|
+
this.historyLimit = Math.max(1, Math.floor(toFiniteNumber(options.historyLimit, 100)));
|
|
3576
|
+
if (this.history.length > this.historyLimit) {
|
|
3577
|
+
const start = Math.max(0, this.historyIndex - this.historyLimit + 1);
|
|
3578
|
+
this.history = this.history.slice(start, start + this.historyLimit);
|
|
3579
|
+
this.historyIndex -= start;
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
this.render();
|
|
3583
|
+
this.updateHistoryButtons();
|
|
3584
|
+
return this;
|
|
3585
|
+
}
|
|
3340
3586
|
load(data, options = {}) {
|
|
3587
|
+
const documentData = normalizeDocument(data);
|
|
3588
|
+
if (options.silent && JSON.stringify(documentData) === JSON.stringify(this.documentData)) {
|
|
3589
|
+
return this;
|
|
3590
|
+
}
|
|
3341
3591
|
this.stopTextEdit({ commit: false });
|
|
3342
3592
|
this.activeTool = null;
|
|
3343
3593
|
this.reconnectEdgeId = null;
|
|
3344
3594
|
const previousSelection = this.selection;
|
|
3345
|
-
this.documentData =
|
|
3595
|
+
this.documentData = documentData;
|
|
3346
3596
|
this.selection = this.resolvePreservedSelection(previousSelection, options.preserveSelection);
|
|
3347
3597
|
this.render();
|
|
3348
|
-
|
|
3598
|
+
if (options.silent) {
|
|
3599
|
+
if (this.historyEnabled) this.recordHistory("load");
|
|
3600
|
+
} else {
|
|
3601
|
+
this.emitChange("load");
|
|
3602
|
+
}
|
|
3349
3603
|
return this;
|
|
3350
3604
|
}
|
|
3351
3605
|
toJSON() {
|
|
3352
3606
|
return deepClone({
|
|
3353
|
-
version:
|
|
3607
|
+
version: FLOWCHART_DOCUMENT_VERSION,
|
|
3354
3608
|
viewport: this.documentData.viewport,
|
|
3355
3609
|
nodes: this.documentData.nodes,
|
|
3356
3610
|
edges: this.documentData.edges
|
|
@@ -3364,6 +3618,10 @@ var VdFlowchart = class {
|
|
|
3364
3618
|
this.resizeObserver?.disconnect();
|
|
3365
3619
|
this.resizeObserver = null;
|
|
3366
3620
|
this.unbindEvents();
|
|
3621
|
+
this.sceneNodeMap?.clear();
|
|
3622
|
+
this.nodeElements?.clear();
|
|
3623
|
+
this.edgeElements?.clear();
|
|
3624
|
+
this.incidentEdges?.clear();
|
|
3367
3625
|
this.element.innerHTML = "";
|
|
3368
3626
|
this.element.classList.remove("vd-flowchart-host");
|
|
3369
3627
|
}
|
|
@@ -3415,7 +3673,7 @@ var VdFlowchart2 = defineComponent({
|
|
|
3415
3673
|
() => props.data,
|
|
3416
3674
|
(next) => {
|
|
3417
3675
|
if (instance && typeof instance.load === "function") {
|
|
3418
|
-
instance.load(next, { preserveSelection: props.preserveSelection });
|
|
3676
|
+
instance.load(next, { preserveSelection: props.preserveSelection, silent: true });
|
|
3419
3677
|
}
|
|
3420
3678
|
},
|
|
3421
3679
|
{ deep: true }
|
|
@@ -3424,8 +3682,13 @@ var VdFlowchart2 = defineComponent({
|
|
|
3424
3682
|
() => [props.readonly, props.gridSize, props.autoFit, props.history, props.historyLimit],
|
|
3425
3683
|
() => {
|
|
3426
3684
|
if (!instance) return;
|
|
3427
|
-
instance.
|
|
3428
|
-
|
|
3685
|
+
instance.updateOptions({
|
|
3686
|
+
readonly: props.readonly,
|
|
3687
|
+
gridSize: props.gridSize,
|
|
3688
|
+
autoFit: props.autoFit,
|
|
3689
|
+
history: props.history,
|
|
3690
|
+
historyLimit: props.historyLimit
|
|
3691
|
+
});
|
|
3429
3692
|
}
|
|
3430
3693
|
);
|
|
3431
3694
|
onBeforeUnmount(() => {
|
|
@@ -3446,6 +3709,7 @@ var VdFlowchart2 = defineComponent({
|
|
|
3446
3709
|
}
|
|
3447
3710
|
});
|
|
3448
3711
|
export {
|
|
3712
|
+
FLOWCHART_DOCUMENT_VERSION,
|
|
3449
3713
|
FLOWCHART_EDGE_MARKERS,
|
|
3450
3714
|
FLOWCHART_EDGE_ROUTES,
|
|
3451
3715
|
FLOWCHART_NODE_TYPES,
|