@diagrammo/dgmo 0.15.0 → 0.15.1
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/README.md +14 -1
- package/dist/advanced.cjs +53069 -0
- package/dist/advanced.d.cts +4691 -0
- package/dist/advanced.d.ts +4691 -0
- package/dist/advanced.js +52823 -0
- package/dist/auto.cjs +1495 -1288
- package/dist/auto.js +132 -109
- package/dist/auto.mjs +1491 -1284
- package/dist/cli.cjs +173 -150
- package/dist/index.cjs +1486 -1276
- package/dist/index.d.cts +45 -1
- package/dist/index.d.ts +45 -1
- package/dist/index.js +1481 -1272
- package/dist/internal.cjs +1497 -1289
- package/dist/internal.d.cts +80 -79
- package/dist/internal.d.ts +80 -79
- package/dist/internal.js +1492 -1285
- package/dist/pert.cjs +325 -0
- package/dist/pert.d.cts +542 -0
- package/dist/pert.d.ts +542 -0
- package/dist/pert.js +294 -0
- package/package.json +28 -3
- package/src/advanced.ts +731 -0
- package/src/auto/index.ts +14 -13
- package/src/boxes-and-lines/layout.ts +481 -445
- package/src/c4/parser.ts +7 -7
- package/src/chart-types.ts +0 -5
- package/src/class/parser.ts +1 -9
- package/src/cli.ts +9 -7
- package/src/completion-types.ts +28 -0
- package/src/completion.ts +15 -18
- package/src/cycle/layout.ts +2 -2
- package/src/d3.ts +1455 -1122
- package/src/echarts.ts +11 -11
- package/src/er/parser.ts +1 -9
- package/src/er/renderer.ts +1 -1
- package/src/gantt/calculator.ts +1 -11
- package/src/gantt/parser.ts +16 -16
- package/src/gantt/renderer.ts +2 -2
- package/src/graph/flowchart-parser.ts +1 -1
- package/src/graph/flowchart-renderer.ts +1 -1
- package/src/graph/state-renderer.ts +1 -1
- package/src/index.ts +17 -1
- package/src/infra/parser.ts +19 -19
- package/src/infra/renderer.ts +2 -2
- package/src/internal.ts +9 -721
- package/src/kanban/parser.ts +2 -2
- package/src/mindmap/layout.ts +1 -1
- package/src/mindmap/parser.ts +1 -1
- package/src/org/parser.ts +1 -1
- package/src/org/renderer.ts +1 -1
- package/src/pert/layout.ts +1 -1
- package/src/pert/monte-carlo.ts +2 -2
- package/src/pert/parser.ts +3 -3
- package/src/raci/parser.ts +4 -4
- package/src/raci/renderer.ts +1 -1
- package/src/sequence/renderer.ts +1 -4
- package/src/sitemap/parser.ts +1 -1
- package/src/tech-radar/interactive.ts +1 -1
- package/src/tech-radar/renderer.ts +1 -1
- package/src/utils/tag-groups.ts +11 -12
- package/src/wireframe/layout.ts +11 -7
- package/src/wireframe/parser.ts +2 -2
- package/src/wireframe/renderer.ts +5 -2
package/dist/index.js
CHANGED
|
@@ -2236,7 +2236,7 @@ function injectDefaultTagMetadata(entities, tagGroups, skip) {
|
|
|
2236
2236
|
}
|
|
2237
2237
|
}
|
|
2238
2238
|
}
|
|
2239
|
-
function resolveActiveTagGroup(
|
|
2239
|
+
function resolveActiveTagGroup(tagGroups, explicitActiveTag, programmaticOverride) {
|
|
2240
2240
|
if (programmaticOverride !== void 0) {
|
|
2241
2241
|
if (!programmaticOverride) return null;
|
|
2242
2242
|
if (programmaticOverride.toLowerCase() === "none") return null;
|
|
@@ -2246,6 +2246,7 @@ function resolveActiveTagGroup(_tagGroups, explicitActiveTag, programmaticOverri
|
|
|
2246
2246
|
if (explicitActiveTag.toLowerCase() === "none") return null;
|
|
2247
2247
|
return explicitActiveTag;
|
|
2248
2248
|
}
|
|
2249
|
+
if (tagGroups.length > 0) return tagGroups[0].name;
|
|
2249
2250
|
return null;
|
|
2250
2251
|
}
|
|
2251
2252
|
function matchTagBlockHeading(trimmed) {
|
|
@@ -5326,12 +5327,6 @@ function parseClassDiagram(content, palette) {
|
|
|
5326
5327
|
diagnostics: [],
|
|
5327
5328
|
error: null
|
|
5328
5329
|
};
|
|
5329
|
-
const _fail = (line12, message) => {
|
|
5330
|
-
const diag = makeDgmoError(line12, message);
|
|
5331
|
-
result.diagnostics.push(diag);
|
|
5332
|
-
result.error = formatDgmoError(diag);
|
|
5333
|
-
return result;
|
|
5334
|
-
};
|
|
5335
5330
|
const classMap = /* @__PURE__ */ new Map();
|
|
5336
5331
|
const nameAliasMap = /* @__PURE__ */ new Map();
|
|
5337
5332
|
function resolveAliasName(token) {
|
|
@@ -5726,12 +5721,6 @@ function parseERDiagram(content, palette) {
|
|
|
5726
5721
|
diagnostics: [],
|
|
5727
5722
|
error: null
|
|
5728
5723
|
};
|
|
5729
|
-
const _fail = (line12, message) => {
|
|
5730
|
-
const diag = makeDgmoError(line12, message);
|
|
5731
|
-
result.diagnostics.push(diag);
|
|
5732
|
-
result.error = formatDgmoError(diag);
|
|
5733
|
-
return result;
|
|
5734
|
-
};
|
|
5735
5724
|
const pushError = (line12, message) => {
|
|
5736
5725
|
const diag = makeDgmoError(line12, message);
|
|
5737
5726
|
result.diagnostics.push(diag);
|
|
@@ -7190,7 +7179,7 @@ function buildSankeyOption(parsed, textColor, colors, bg, titleConfig) {
|
|
|
7190
7179
|
]
|
|
7191
7180
|
};
|
|
7192
7181
|
}
|
|
7193
|
-
function buildChordOption(parsed, palette, isDark, textColor, colors,
|
|
7182
|
+
function buildChordOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
7194
7183
|
const nodeSet = /* @__PURE__ */ new Set();
|
|
7195
7184
|
if (parsed.links) {
|
|
7196
7185
|
for (const link of parsed.links) {
|
|
@@ -7304,7 +7293,7 @@ function evaluateExpression(expr, x) {
|
|
|
7304
7293
|
return NaN;
|
|
7305
7294
|
}
|
|
7306
7295
|
}
|
|
7307
|
-
function buildFunctionOption(parsed, palette,
|
|
7296
|
+
function buildFunctionOption(parsed, palette, _isDark, textColor, axisLineColor, gridOpacity, colors, titleConfig) {
|
|
7308
7297
|
const xRange = parsed.xRange ?? { min: -10, max: 10 };
|
|
7309
7298
|
const samples = 200;
|
|
7310
7299
|
const step = (xRange.max - xRange.min) / samples;
|
|
@@ -7977,7 +7966,7 @@ function buildHeatmapOption(parsed, palette, isDark, textColor, axisLineColor, t
|
|
|
7977
7966
|
]
|
|
7978
7967
|
};
|
|
7979
7968
|
}
|
|
7980
|
-
function buildFunnelOption(parsed, palette, isDark, textColor, colors,
|
|
7969
|
+
function buildFunnelOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
7981
7970
|
const sorted = [...parsed.data].sort((a, b) => b.value - a.value);
|
|
7982
7971
|
const data = sorted.map((d) => {
|
|
7983
7972
|
const stroke2 = d.color ?? colors[parsed.data.indexOf(d) % colors.length];
|
|
@@ -8260,7 +8249,7 @@ function wrapLabel(text, maxChars) {
|
|
|
8260
8249
|
if (current) lines.push(current);
|
|
8261
8250
|
return lines.join("\n");
|
|
8262
8251
|
}
|
|
8263
|
-
function buildBarOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors,
|
|
8252
|
+
function buildBarOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors, _bg, titleConfig, chartWidth) {
|
|
8264
8253
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
8265
8254
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
8266
8255
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -8587,7 +8576,7 @@ function pieLabelLayout(parsed) {
|
|
|
8587
8576
|
if (maxLen > 18) return { outerRadius: 55, fontSize: 13 };
|
|
8588
8577
|
return { outerRadius: 70, fontSize: 14 };
|
|
8589
8578
|
}
|
|
8590
|
-
function buildPieOption(parsed, palette, isDark, textColor, colors,
|
|
8579
|
+
function buildPieOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig, isDoughnut) {
|
|
8591
8580
|
const HIDE_AXES = { xAxis: { show: false }, yAxis: { show: false } };
|
|
8592
8581
|
const data = parsed.data.map((d, i) => {
|
|
8593
8582
|
const stroke2 = d.color ?? colors[i % colors.length];
|
|
@@ -8686,7 +8675,7 @@ function buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, title
|
|
|
8686
8675
|
]
|
|
8687
8676
|
};
|
|
8688
8677
|
}
|
|
8689
|
-
function buildPolarAreaOption(parsed, palette, isDark, textColor, colors,
|
|
8678
|
+
function buildPolarAreaOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
8690
8679
|
const data = parsed.data.map((d, i) => {
|
|
8691
8680
|
const stroke2 = d.color ?? colors[i % colors.length];
|
|
8692
8681
|
return {
|
|
@@ -8729,7 +8718,7 @@ function buildPolarAreaOption(parsed, palette, isDark, textColor, colors, bg, ti
|
|
|
8729
8718
|
]
|
|
8730
8719
|
};
|
|
8731
8720
|
}
|
|
8732
|
-
function buildBarStackedOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors,
|
|
8721
|
+
function buildBarStackedOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors, _bg, titleConfig, chartWidth) {
|
|
8733
8722
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
8734
8723
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
8735
8724
|
const seriesNames = parsed.seriesNames ?? [];
|
|
@@ -8869,8 +8858,8 @@ async function renderExtendedChartForExport(content, theme, palette) {
|
|
|
8869
8858
|
const titleHeight = option.title && option.title.text ? 40 : 0;
|
|
8870
8859
|
const legendY = 8 + titleHeight;
|
|
8871
8860
|
const grid = option.grid;
|
|
8872
|
-
const gridLeftPct = grid?.left ? parseFloat(String(grid
|
|
8873
|
-
const gridRightPct = grid?.right ? parseFloat(String(grid
|
|
8861
|
+
const gridLeftPct = grid?.["left"] ? parseFloat(String(grid["left"])) : void 0;
|
|
8862
|
+
const gridRightPct = grid?.["right"] ? parseFloat(String(grid["right"])) : void 0;
|
|
8874
8863
|
const { svg: legendSvgStr } = renderLegendSvg(legendGroups, {
|
|
8875
8864
|
palette: effectivePalette,
|
|
8876
8865
|
isDark,
|
|
@@ -9216,7 +9205,7 @@ function parseOrg(content, palette) {
|
|
|
9216
9205
|
}
|
|
9217
9206
|
return result;
|
|
9218
9207
|
}
|
|
9219
|
-
function parseNodeLabel(trimmed, _indent, lineNumber,
|
|
9208
|
+
function parseNodeLabel(trimmed, _indent, lineNumber, _palette, counter, metaAliasMap = /* @__PURE__ */ new Map(), warnFn, nameAliasMap) {
|
|
9220
9209
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
9221
9210
|
let label = segments[0];
|
|
9222
9211
|
const asMatch = label.match(/^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/);
|
|
@@ -9465,8 +9454,8 @@ function parseKanban(content, palette) {
|
|
|
9465
9454
|
columnMetadata,
|
|
9466
9455
|
parsePipeMetadata(pipeSegments, metaAliasMap)
|
|
9467
9456
|
);
|
|
9468
|
-
if (columnMetadata
|
|
9469
|
-
const wipVal = parseInt(columnMetadata
|
|
9457
|
+
if (columnMetadata["wip"]) {
|
|
9458
|
+
const wipVal = parseInt(columnMetadata["wip"], 10);
|
|
9470
9459
|
if (!isNaN(wipVal)) {
|
|
9471
9460
|
wipLimit = wipVal;
|
|
9472
9461
|
}
|
|
@@ -9845,7 +9834,7 @@ function parseC4(content, palette) {
|
|
|
9845
9834
|
);
|
|
9846
9835
|
const shape = inferC4Shape(
|
|
9847
9836
|
nodeName,
|
|
9848
|
-
metadata
|
|
9837
|
+
metadata["tech"] ?? metadata["technology"]
|
|
9849
9838
|
);
|
|
9850
9839
|
const dNode = {
|
|
9851
9840
|
name: nodeName,
|
|
@@ -9948,11 +9937,11 @@ function parseC4(content, palette) {
|
|
|
9948
9937
|
target = targetBody.substring(0, pipeIdx).trim();
|
|
9949
9938
|
const metaPart = targetBody.substring(pipeIdx + 1).trim();
|
|
9950
9939
|
const meta = parsePipeMetadata(["", metaPart], metaAliasMap);
|
|
9951
|
-
if (meta
|
|
9952
|
-
technology = meta
|
|
9940
|
+
if (meta["tech"]) {
|
|
9941
|
+
technology = meta["tech"];
|
|
9953
9942
|
}
|
|
9954
|
-
if (meta
|
|
9955
|
-
technology = meta
|
|
9943
|
+
if (meta["technology"]) {
|
|
9944
|
+
technology = meta["technology"];
|
|
9956
9945
|
}
|
|
9957
9946
|
}
|
|
9958
9947
|
const rel = {
|
|
@@ -10086,7 +10075,7 @@ function parseC4(content, palette) {
|
|
|
10086
10075
|
metaAliasMap,
|
|
10087
10076
|
() => pushError(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
10088
10077
|
);
|
|
10089
|
-
const shape = explicitShape ?? inferC4Shape(namePart, metadata
|
|
10078
|
+
const shape = explicitShape ?? inferC4Shape(namePart, metadata["tech"] ?? metadata["technology"]);
|
|
10090
10079
|
let isADescription;
|
|
10091
10080
|
if ("description" in metadata) {
|
|
10092
10081
|
const descVal = metadata["description"].trim();
|
|
@@ -10146,7 +10135,7 @@ function parseC4(content, palette) {
|
|
|
10146
10135
|
metaAliasMap,
|
|
10147
10136
|
() => pushError(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
10148
10137
|
);
|
|
10149
|
-
const shape = explicitShape ?? inferC4Shape(namePart, metadata
|
|
10138
|
+
const shape = explicitShape ?? inferC4Shape(namePart, metadata["tech"] ?? metadata["technology"]);
|
|
10150
10139
|
let prefixDescription;
|
|
10151
10140
|
if ("description" in metadata) {
|
|
10152
10141
|
const descVal = metadata["description"].trim();
|
|
@@ -10755,7 +10744,7 @@ function parseSitemap(content, palette) {
|
|
|
10755
10744
|
}
|
|
10756
10745
|
return result;
|
|
10757
10746
|
}
|
|
10758
|
-
function parseNodeLabel2(trimmed, lineNumber,
|
|
10747
|
+
function parseNodeLabel2(trimmed, lineNumber, _palette, counter, metaAliasMap = /* @__PURE__ */ new Map(), warnFn, _diagnostics, nameAliasMap) {
|
|
10759
10748
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
10760
10749
|
let label = segments[0];
|
|
10761
10750
|
const asMatch = label.match(/^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/);
|
|
@@ -11046,11 +11035,11 @@ function parseInfra(content) {
|
|
|
11046
11035
|
continue;
|
|
11047
11036
|
}
|
|
11048
11037
|
if (trimmed === "animate") {
|
|
11049
|
-
result.options
|
|
11038
|
+
result.options["animate"] = "on";
|
|
11050
11039
|
continue;
|
|
11051
11040
|
}
|
|
11052
11041
|
if (trimmed === "no-animate") {
|
|
11053
|
-
result.options
|
|
11042
|
+
result.options["animate"] = "off";
|
|
11054
11043
|
continue;
|
|
11055
11044
|
}
|
|
11056
11045
|
if (tryParseSharedOption(trimmed, result.options)) {
|
|
@@ -11204,8 +11193,8 @@ function parseInfra(content) {
|
|
|
11204
11193
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11205
11194
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11206
11195
|
warnUnparsedPipeMeta(targetName, lineNumber, warn);
|
|
11207
|
-
const split = pipeMeta.tags
|
|
11208
|
-
const fanoutRaw = pipeMeta.tags
|
|
11196
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11197
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11209
11198
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11210
11199
|
warn(
|
|
11211
11200
|
lineNumber,
|
|
@@ -11236,8 +11225,8 @@ function parseInfra(content) {
|
|
|
11236
11225
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11237
11226
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11238
11227
|
warnUnparsedPipeMeta(targetName, lineNumber, warn);
|
|
11239
|
-
const split = pipeMeta.tags
|
|
11240
|
-
const fanoutRaw = pipeMeta.tags
|
|
11228
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11229
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11241
11230
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11242
11231
|
warn(
|
|
11243
11232
|
lineNumber,
|
|
@@ -11271,8 +11260,8 @@ function parseInfra(content) {
|
|
|
11271
11260
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11272
11261
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11273
11262
|
warnUnparsedPipeMeta(targetName, lineNumber, warn);
|
|
11274
|
-
const split = pipeMeta.tags
|
|
11275
|
-
const fanoutRaw = pipeMeta.tags
|
|
11263
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11264
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11276
11265
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11277
11266
|
warn(
|
|
11278
11267
|
lineNumber,
|
|
@@ -11303,8 +11292,8 @@ function parseInfra(content) {
|
|
|
11303
11292
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11304
11293
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11305
11294
|
warnUnparsedPipeMeta(targetName, lineNumber, warn);
|
|
11306
|
-
const split = pipeMeta.tags
|
|
11307
|
-
const fanoutRaw = pipeMeta.tags
|
|
11295
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11296
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11308
11297
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11309
11298
|
warn(
|
|
11310
11299
|
lineNumber,
|
|
@@ -12011,15 +12000,15 @@ function parseGantt(content, palette) {
|
|
|
12011
12000
|
metaAliasMap,
|
|
12012
12001
|
() => warn(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
12013
12002
|
);
|
|
12014
|
-
if (meta
|
|
12015
|
-
const key = meta
|
|
12003
|
+
if (meta["lag"] || meta["lead"]) {
|
|
12004
|
+
const key = meta["lag"] ? "lag" : "lead";
|
|
12016
12005
|
softError(
|
|
12017
12006
|
lineNumber,
|
|
12018
12007
|
`"${key}" is no longer supported \u2014 use "offset: ${meta[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
12019
12008
|
);
|
|
12020
12009
|
}
|
|
12021
|
-
if (meta
|
|
12022
|
-
const raw = meta
|
|
12010
|
+
if (meta["offset"]) {
|
|
12011
|
+
const raw = meta["offset"];
|
|
12023
12012
|
if (raw.trim().startsWith("+")) {
|
|
12024
12013
|
warn(
|
|
12025
12014
|
lineNumber,
|
|
@@ -12406,15 +12395,15 @@ function parseGantt(content, palette) {
|
|
|
12406
12395
|
metaAliasMap,
|
|
12407
12396
|
() => warn(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
12408
12397
|
);
|
|
12409
|
-
if (meta
|
|
12410
|
-
const key = meta
|
|
12398
|
+
if (meta["lag"] || meta["lead"]) {
|
|
12399
|
+
const key = meta["lag"] ? "lag" : "lead";
|
|
12411
12400
|
softError(
|
|
12412
12401
|
lineNumber,
|
|
12413
12402
|
`"${key}" is no longer supported \u2014 use "offset: ${meta[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
12414
12403
|
);
|
|
12415
12404
|
}
|
|
12416
|
-
if (meta
|
|
12417
|
-
const raw = meta
|
|
12405
|
+
if (meta["offset"]) {
|
|
12406
|
+
const raw = meta["offset"];
|
|
12418
12407
|
if (raw.trim().startsWith("+")) {
|
|
12419
12408
|
warn(
|
|
12420
12409
|
lineNumber,
|
|
@@ -12485,9 +12474,9 @@ function parseGantt(content, palette) {
|
|
|
12485
12474
|
() => warn(ln, MULTIPLE_PIPE_ERROR)
|
|
12486
12475
|
) : {};
|
|
12487
12476
|
let progress = null;
|
|
12488
|
-
if (metadata
|
|
12489
|
-
progress = parseFloat(metadata
|
|
12490
|
-
delete metadata
|
|
12477
|
+
if (metadata["progress"]) {
|
|
12478
|
+
progress = parseFloat(metadata["progress"]);
|
|
12479
|
+
delete metadata["progress"];
|
|
12491
12480
|
}
|
|
12492
12481
|
for (const part of segments.slice(1).join(",").split(",")) {
|
|
12493
12482
|
const seg = part.trim();
|
|
@@ -12496,16 +12485,16 @@ function parseGantt(content, palette) {
|
|
|
12496
12485
|
progress = parseInt(progressMatch[1], 10);
|
|
12497
12486
|
}
|
|
12498
12487
|
}
|
|
12499
|
-
if (metadata
|
|
12500
|
-
const key = metadata
|
|
12488
|
+
if (metadata["lag"] || metadata["lead"]) {
|
|
12489
|
+
const key = metadata["lag"] ? "lag" : "lead";
|
|
12501
12490
|
softError(
|
|
12502
12491
|
ln,
|
|
12503
12492
|
`"${key}" is no longer supported \u2014 use "offset: ${metadata[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
12504
12493
|
);
|
|
12505
12494
|
}
|
|
12506
12495
|
let taskOffset;
|
|
12507
|
-
if (metadata
|
|
12508
|
-
const raw = metadata
|
|
12496
|
+
if (metadata["offset"]) {
|
|
12497
|
+
const raw = metadata["offset"];
|
|
12509
12498
|
if (raw.trim().startsWith("+")) {
|
|
12510
12499
|
warn(
|
|
12511
12500
|
ln,
|
|
@@ -12520,7 +12509,7 @@ function parseGantt(content, palette) {
|
|
|
12520
12509
|
);
|
|
12521
12510
|
}
|
|
12522
12511
|
}
|
|
12523
|
-
delete metadata
|
|
12512
|
+
delete metadata["offset"];
|
|
12524
12513
|
}
|
|
12525
12514
|
const groupPath = currentGroupPath();
|
|
12526
12515
|
const inheritedMeta = {};
|
|
@@ -13043,7 +13032,7 @@ function parsePert(content, parseOpts = {}) {
|
|
|
13043
13032
|
id,
|
|
13044
13033
|
name,
|
|
13045
13034
|
activityIds: [],
|
|
13046
|
-
collapsed: meta
|
|
13035
|
+
collapsed: meta["collapsed"] === "true",
|
|
13047
13036
|
lineNumber,
|
|
13048
13037
|
...Object.keys(tags).length > 0 && { tags }
|
|
13049
13038
|
});
|
|
@@ -13305,7 +13294,7 @@ function parsePert(content, parseOpts = {}) {
|
|
|
13305
13294
|
name: decl.name,
|
|
13306
13295
|
...decl.alias !== void 0 && { alias: decl.alias },
|
|
13307
13296
|
duration: estimate,
|
|
13308
|
-
...meta
|
|
13297
|
+
...meta["confidence"] && { confidence: meta["confidence"] },
|
|
13309
13298
|
...decl.groupHint !== void 0 && { groupId: decl.groupHint },
|
|
13310
13299
|
lineNumber: decl.lineNumber,
|
|
13311
13300
|
isMilestone,
|
|
@@ -14636,7 +14625,7 @@ function parseMindmap(content, palette) {
|
|
|
14636
14625
|
}
|
|
14637
14626
|
return result;
|
|
14638
14627
|
}
|
|
14639
|
-
function parseNodeLine2(trimmed, lineNumber,
|
|
14628
|
+
function parseNodeLine2(trimmed, lineNumber, _palette, counter, aliasMap, warnFn) {
|
|
14640
14629
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
14641
14630
|
const label = segments[0];
|
|
14642
14631
|
const metadata = parsePipeMetadata(
|
|
@@ -15080,7 +15069,7 @@ function parseWireframe(content) {
|
|
|
15080
15069
|
wrapper.isContainer = true;
|
|
15081
15070
|
wrapper.orientation = "horizontal";
|
|
15082
15071
|
wrapper.children = children;
|
|
15083
|
-
wrapper.metadata
|
|
15072
|
+
wrapper.metadata["_inlineRow"] = "true";
|
|
15084
15073
|
pushElement(wrapper);
|
|
15085
15074
|
}
|
|
15086
15075
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -15231,7 +15220,7 @@ function parseWireframe(content) {
|
|
|
15231
15220
|
wrapper.isContainer = true;
|
|
15232
15221
|
wrapper.orientation = "horizontal";
|
|
15233
15222
|
wrapper.children.push(labelEl, fieldEl);
|
|
15234
|
-
wrapper.metadata
|
|
15223
|
+
wrapper.metadata["_labelField"] = "true";
|
|
15235
15224
|
pushElement(wrapper);
|
|
15236
15225
|
}
|
|
15237
15226
|
} else {
|
|
@@ -17052,9 +17041,9 @@ function parseRaci(content, palette) {
|
|
|
17052
17041
|
let roleColor;
|
|
17053
17042
|
if (segments.length > 1) {
|
|
17054
17043
|
const meta = parsePipeMetadata(segments);
|
|
17055
|
-
if (meta
|
|
17044
|
+
if (meta["color"]) {
|
|
17056
17045
|
roleColor = resolveColorWithDiagnostic(
|
|
17057
|
-
meta
|
|
17046
|
+
meta["color"],
|
|
17058
17047
|
j + 1,
|
|
17059
17048
|
result.diagnostics,
|
|
17060
17049
|
palette
|
|
@@ -17121,9 +17110,9 @@ function parseRaci(content, palette) {
|
|
|
17121
17110
|
let phaseColor;
|
|
17122
17111
|
if (phaseMatch[2]) {
|
|
17123
17112
|
const meta = parsePipeMetadata(["", phaseMatch[2]]);
|
|
17124
|
-
if (meta
|
|
17113
|
+
if (meta["color"]) {
|
|
17125
17114
|
phaseColor = resolveColorWithDiagnostic(
|
|
17126
|
-
meta
|
|
17115
|
+
meta["color"],
|
|
17127
17116
|
lineNumber,
|
|
17128
17117
|
result.diagnostics,
|
|
17129
17118
|
palette
|
|
@@ -19133,7 +19122,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
19133
19122
|
displayNames.set(group.name.toLowerCase(), group.name);
|
|
19134
19123
|
}
|
|
19135
19124
|
const rootNodeIds = new Set(parsed.roots.map((r) => r.id));
|
|
19136
|
-
const colorOff = parsed.options?.color === "off";
|
|
19125
|
+
const colorOff = parsed.options?.["color"] === "off";
|
|
19137
19126
|
for (const c of layout.containers) {
|
|
19138
19127
|
const cG = contentG.append("g").attr("transform", `translate(${c.x}, ${c.y})`).attr("class", "org-container").attr("data-line-number", String(c.lineNumber));
|
|
19139
19128
|
if (activeTagGroup) {
|
|
@@ -22234,7 +22223,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
|
|
|
22234
22223
|
const seriesColors2 = getSeriesColors(palette);
|
|
22235
22224
|
const semanticRoles = useSemanticColors ? classifyEREntities(parsed.tables, parsed.relationships) : null;
|
|
22236
22225
|
const semanticActive = semanticRoles !== null && (semanticColorsActive ?? true);
|
|
22237
|
-
const useLabels = parsed.options
|
|
22226
|
+
const useLabels = parsed.options["notation"] === "labels";
|
|
22238
22227
|
for (const edge of layout.edges) {
|
|
22239
22228
|
if (edge.points.length < 2) continue;
|
|
22240
22229
|
const edgeG = contentG.append("g").attr("class", "er-edge-group").attr("data-line-number", String(edge.lineNumber));
|
|
@@ -22447,495 +22436,6 @@ var init_renderer5 = __esm({
|
|
|
22447
22436
|
}
|
|
22448
22437
|
});
|
|
22449
22438
|
|
|
22450
|
-
// src/boxes-and-lines/layout.ts
|
|
22451
|
-
var layout_exports5 = {};
|
|
22452
|
-
__export(layout_exports5, {
|
|
22453
|
-
layoutBoxesAndLines: () => layoutBoxesAndLines
|
|
22454
|
-
});
|
|
22455
|
-
import dagre4 from "@dagrejs/dagre";
|
|
22456
|
-
function clipToRectBorder2(cx, cy, w, h, tx, ty) {
|
|
22457
|
-
const dx = tx - cx;
|
|
22458
|
-
const dy = ty - cy;
|
|
22459
|
-
if (dx === 0 && dy === 0) return { x: cx, y: cy };
|
|
22460
|
-
const hw = w / 2;
|
|
22461
|
-
const hh = h / 2;
|
|
22462
|
-
const sx = dx !== 0 ? hw / Math.abs(dx) : Infinity;
|
|
22463
|
-
const sy = dy !== 0 ? hh / Math.abs(dy) : Infinity;
|
|
22464
|
-
const s = Math.min(sx, sy);
|
|
22465
|
-
return { x: cx + dx * s, y: cy + dy * s };
|
|
22466
|
-
}
|
|
22467
|
-
function splitCamelCase(word) {
|
|
22468
|
-
const parts = [];
|
|
22469
|
-
let start = 0;
|
|
22470
|
-
for (let i = 1; i < word.length; i++) {
|
|
22471
|
-
const prev = word[i - 1];
|
|
22472
|
-
const curr = word[i];
|
|
22473
|
-
const next = i + 1 < word.length ? word[i + 1] : "";
|
|
22474
|
-
const lowerToUpper = prev >= "a" && prev <= "z" && curr >= "A" && curr <= "Z";
|
|
22475
|
-
const upperRunEnd = prev >= "A" && prev <= "Z" && curr >= "A" && curr <= "Z" && next >= "a" && next <= "z";
|
|
22476
|
-
if (lowerToUpper || upperRunEnd) {
|
|
22477
|
-
parts.push(word.slice(start, i));
|
|
22478
|
-
start = i;
|
|
22479
|
-
}
|
|
22480
|
-
}
|
|
22481
|
-
parts.push(word.slice(start));
|
|
22482
|
-
return parts.length > 1 ? parts : [word];
|
|
22483
|
-
}
|
|
22484
|
-
function estimateLabelLines(label, nodeWidth2 = NODE_WIDTH) {
|
|
22485
|
-
const rawParts = label.split(/[\s-]+/);
|
|
22486
|
-
const words = [];
|
|
22487
|
-
for (const part of rawParts) {
|
|
22488
|
-
if (!part) continue;
|
|
22489
|
-
words.push(...splitCamelCase(part));
|
|
22490
|
-
}
|
|
22491
|
-
for (let fontSize = 13; fontSize >= 9; fontSize--) {
|
|
22492
|
-
const charWidth = fontSize * 0.6;
|
|
22493
|
-
const maxChars = Math.floor((nodeWidth2 - 24) / charWidth);
|
|
22494
|
-
if (maxChars < 2) continue;
|
|
22495
|
-
let lines = 1;
|
|
22496
|
-
let current = "";
|
|
22497
|
-
for (const word of words) {
|
|
22498
|
-
const test = current ? `${current} ${word}` : word;
|
|
22499
|
-
if (test.length <= maxChars) {
|
|
22500
|
-
current = test;
|
|
22501
|
-
} else {
|
|
22502
|
-
lines++;
|
|
22503
|
-
current = word;
|
|
22504
|
-
}
|
|
22505
|
-
}
|
|
22506
|
-
if (lines <= MAX_LABEL_LINES) return Math.min(lines, MAX_LABEL_LINES);
|
|
22507
|
-
}
|
|
22508
|
-
return MAX_LABEL_LINES;
|
|
22509
|
-
}
|
|
22510
|
-
function computeNodeSize(node) {
|
|
22511
|
-
if (!node.description || node.description.length === 0) {
|
|
22512
|
-
return { width: NODE_WIDTH, height: NODE_HEIGHT };
|
|
22513
|
-
}
|
|
22514
|
-
const w = DESC_NODE_WIDTH;
|
|
22515
|
-
const labelLines = estimateLabelLines(node.label, w);
|
|
22516
|
-
const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT + LABEL_PAD;
|
|
22517
|
-
const charsPerLine = Math.floor((w - 24) / (DESC_FONT_SIZE * 0.6));
|
|
22518
|
-
let totalRenderedLines = 0;
|
|
22519
|
-
for (const line12 of node.description) {
|
|
22520
|
-
if (line12.length <= charsPerLine) {
|
|
22521
|
-
totalRenderedLines += 1;
|
|
22522
|
-
} else {
|
|
22523
|
-
const words = line12.split(/\s+/);
|
|
22524
|
-
let current = "";
|
|
22525
|
-
let lineCount = 0;
|
|
22526
|
-
for (const word of words) {
|
|
22527
|
-
const fitted = word.length > charsPerLine ? word.slice(0, charsPerLine) : word;
|
|
22528
|
-
const test = current ? `${current} ${fitted}` : fitted;
|
|
22529
|
-
if (test.length <= charsPerLine) {
|
|
22530
|
-
current = test;
|
|
22531
|
-
} else {
|
|
22532
|
-
if (current) lineCount++;
|
|
22533
|
-
current = fitted;
|
|
22534
|
-
}
|
|
22535
|
-
}
|
|
22536
|
-
if (current) lineCount++;
|
|
22537
|
-
totalRenderedLines += lineCount;
|
|
22538
|
-
}
|
|
22539
|
-
}
|
|
22540
|
-
totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES);
|
|
22541
|
-
const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE * DESC_LINE_HEIGHT;
|
|
22542
|
-
const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING;
|
|
22543
|
-
return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
|
|
22544
|
-
}
|
|
22545
|
-
function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
|
|
22546
|
-
const hideDescriptions = layoutOptions?.hideDescriptions ?? false;
|
|
22547
|
-
const g = new dagre4.graphlib.Graph({ compound: true, multigraph: true });
|
|
22548
|
-
g.setGraph({
|
|
22549
|
-
rankdir: parsed.direction,
|
|
22550
|
-
nodesep: NODESEP,
|
|
22551
|
-
ranksep: RANKSEP,
|
|
22552
|
-
marginx: MARGIN3,
|
|
22553
|
-
marginy: MARGIN3
|
|
22554
|
-
});
|
|
22555
|
-
g.setDefaultEdgeLabel(() => ({}));
|
|
22556
|
-
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
22557
|
-
if (collapseInfo) {
|
|
22558
|
-
const missingGroups = /* @__PURE__ */ new Set();
|
|
22559
|
-
for (const og of collapseInfo.originalGroups) {
|
|
22560
|
-
if (!parsed.groups.some((g2) => g2.label === og.label)) {
|
|
22561
|
-
missingGroups.add(og.label);
|
|
22562
|
-
}
|
|
22563
|
-
}
|
|
22564
|
-
for (const label of missingGroups) {
|
|
22565
|
-
const og = collapseInfo.originalGroups.find((g2) => g2.label === label);
|
|
22566
|
-
const parentLabel = og?.parentGroup;
|
|
22567
|
-
if (!parentLabel || !missingGroups.has(parentLabel)) {
|
|
22568
|
-
collapsedGroupLabels.add(label);
|
|
22569
|
-
}
|
|
22570
|
-
}
|
|
22571
|
-
}
|
|
22572
|
-
for (const label of collapsedGroupLabels) {
|
|
22573
|
-
const gid = `__group_${label}`;
|
|
22574
|
-
g.setNode(gid, { label, width: NODE_WIDTH, height: NODE_HEIGHT });
|
|
22575
|
-
}
|
|
22576
|
-
for (const group of parsed.groups) {
|
|
22577
|
-
const gid = `__group_${group.label}`;
|
|
22578
|
-
g.setNode(gid, {
|
|
22579
|
-
label: group.label,
|
|
22580
|
-
paddingLeft: CONTAINER_PAD_X3,
|
|
22581
|
-
paddingRight: CONTAINER_PAD_X3,
|
|
22582
|
-
paddingTop: CONTAINER_PAD_TOP2,
|
|
22583
|
-
paddingBottom: CONTAINER_PAD_BOTTOM3
|
|
22584
|
-
});
|
|
22585
|
-
}
|
|
22586
|
-
const originalGroupByLabel = /* @__PURE__ */ new Map();
|
|
22587
|
-
if (collapseInfo) {
|
|
22588
|
-
for (const og of collapseInfo.originalGroups) {
|
|
22589
|
-
originalGroupByLabel.set(og.label, og);
|
|
22590
|
-
}
|
|
22591
|
-
}
|
|
22592
|
-
for (const label of collapsedGroupLabels) {
|
|
22593
|
-
const og = originalGroupByLabel.get(label);
|
|
22594
|
-
if (og?.parentGroup && !collapsedGroupLabels.has(og.parentGroup)) {
|
|
22595
|
-
const gid = `__group_${label}`;
|
|
22596
|
-
const parentGid = `__group_${og.parentGroup}`;
|
|
22597
|
-
if (g.hasNode(parentGid)) {
|
|
22598
|
-
g.setParent(gid, parentGid);
|
|
22599
|
-
}
|
|
22600
|
-
}
|
|
22601
|
-
}
|
|
22602
|
-
const nodeSizes = /* @__PURE__ */ new Map();
|
|
22603
|
-
let maxDescHeight = 0;
|
|
22604
|
-
for (const node of parsed.nodes) {
|
|
22605
|
-
const size = hideDescriptions ? { width: NODE_WIDTH, height: NODE_HEIGHT } : computeNodeSize(node);
|
|
22606
|
-
nodeSizes.set(node.label, size);
|
|
22607
|
-
if (!hideDescriptions && node.description && node.description.length > 0) {
|
|
22608
|
-
maxDescHeight = Math.max(maxDescHeight, size.height);
|
|
22609
|
-
}
|
|
22610
|
-
}
|
|
22611
|
-
if (maxDescHeight > 0) {
|
|
22612
|
-
for (const node of parsed.nodes) {
|
|
22613
|
-
if (node.description && node.description.length > 0) {
|
|
22614
|
-
const size = nodeSizes.get(node.label);
|
|
22615
|
-
nodeSizes.set(node.label, { width: size.width, height: maxDescHeight });
|
|
22616
|
-
}
|
|
22617
|
-
}
|
|
22618
|
-
}
|
|
22619
|
-
for (const node of parsed.nodes) {
|
|
22620
|
-
const size = nodeSizes.get(node.label);
|
|
22621
|
-
g.setNode(node.label, {
|
|
22622
|
-
label: node.label,
|
|
22623
|
-
width: size.width,
|
|
22624
|
-
height: size.height
|
|
22625
|
-
});
|
|
22626
|
-
}
|
|
22627
|
-
for (const group of parsed.groups) {
|
|
22628
|
-
if (group.parentGroup) {
|
|
22629
|
-
const childGid = `__group_${group.label}`;
|
|
22630
|
-
const parentGid = `__group_${group.parentGroup}`;
|
|
22631
|
-
if (g.hasNode(childGid) && g.hasNode(parentGid)) {
|
|
22632
|
-
g.setParent(childGid, parentGid);
|
|
22633
|
-
}
|
|
22634
|
-
}
|
|
22635
|
-
}
|
|
22636
|
-
const groupLabelSet = new Set(parsed.groups.map((gr) => gr.label));
|
|
22637
|
-
for (const group of parsed.groups) {
|
|
22638
|
-
const gid = `__group_${group.label}`;
|
|
22639
|
-
for (const child of group.children) {
|
|
22640
|
-
if (groupLabelSet.has(child)) continue;
|
|
22641
|
-
if (g.hasNode(child)) {
|
|
22642
|
-
g.setParent(child, gid);
|
|
22643
|
-
}
|
|
22644
|
-
}
|
|
22645
|
-
}
|
|
22646
|
-
const expandedGroupIds = /* @__PURE__ */ new Set();
|
|
22647
|
-
for (const group of parsed.groups) {
|
|
22648
|
-
expandedGroupIds.add(`__group_${group.label}`);
|
|
22649
|
-
}
|
|
22650
|
-
const groupFirstChild = /* @__PURE__ */ new Map();
|
|
22651
|
-
for (const group of parsed.groups) {
|
|
22652
|
-
const gid = `__group_${group.label}`;
|
|
22653
|
-
const firstChild = group.children.find(
|
|
22654
|
-
(c) => !groupLabelSet.has(c) && g.hasNode(c)
|
|
22655
|
-
);
|
|
22656
|
-
if (firstChild) {
|
|
22657
|
-
groupFirstChild.set(gid, firstChild);
|
|
22658
|
-
}
|
|
22659
|
-
}
|
|
22660
|
-
const deferredEdgeIndices = [];
|
|
22661
|
-
let proxyIdx = 0;
|
|
22662
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22663
|
-
const edge = parsed.edges[i];
|
|
22664
|
-
const src = edge.source;
|
|
22665
|
-
const tgt = edge.target;
|
|
22666
|
-
if (!g.hasNode(src) || !g.hasNode(tgt)) continue;
|
|
22667
|
-
if (expandedGroupIds.has(src) || expandedGroupIds.has(tgt)) {
|
|
22668
|
-
deferredEdgeIndices.push(i);
|
|
22669
|
-
const proxySrc = expandedGroupIds.has(src) ? groupFirstChild.get(src) : src;
|
|
22670
|
-
const proxyTgt = expandedGroupIds.has(tgt) ? groupFirstChild.get(tgt) : tgt;
|
|
22671
|
-
if (proxySrc && proxyTgt && proxySrc !== proxyTgt) {
|
|
22672
|
-
g.setEdge(
|
|
22673
|
-
proxySrc,
|
|
22674
|
-
proxyTgt,
|
|
22675
|
-
{ label: "", minlen: 1 },
|
|
22676
|
-
`proxy${proxyIdx++}`
|
|
22677
|
-
);
|
|
22678
|
-
}
|
|
22679
|
-
continue;
|
|
22680
|
-
}
|
|
22681
|
-
g.setEdge(src, tgt, { label: edge.label ?? "", minlen: 1 }, `e${i}`);
|
|
22682
|
-
}
|
|
22683
|
-
dagre4.layout(g);
|
|
22684
|
-
const layoutNodes = [];
|
|
22685
|
-
for (const node of parsed.nodes) {
|
|
22686
|
-
const dagreNode = g.node(node.label);
|
|
22687
|
-
if (!dagreNode) continue;
|
|
22688
|
-
layoutNodes.push({
|
|
22689
|
-
label: node.label,
|
|
22690
|
-
x: dagreNode.x,
|
|
22691
|
-
y: dagreNode.y,
|
|
22692
|
-
width: dagreNode.width,
|
|
22693
|
-
height: dagreNode.height
|
|
22694
|
-
});
|
|
22695
|
-
}
|
|
22696
|
-
const layoutGroups = [];
|
|
22697
|
-
for (const group of parsed.groups) {
|
|
22698
|
-
const gid = `__group_${group.label}`;
|
|
22699
|
-
const dagreNode = g.node(gid);
|
|
22700
|
-
if (!dagreNode) continue;
|
|
22701
|
-
layoutGroups.push({
|
|
22702
|
-
label: group.label,
|
|
22703
|
-
lineNumber: group.lineNumber,
|
|
22704
|
-
x: dagreNode.x,
|
|
22705
|
-
y: dagreNode.y,
|
|
22706
|
-
width: dagreNode.width,
|
|
22707
|
-
height: dagreNode.height,
|
|
22708
|
-
collapsed: false
|
|
22709
|
-
});
|
|
22710
|
-
}
|
|
22711
|
-
for (const label of collapsedGroupLabels) {
|
|
22712
|
-
const gid = `__group_${label}`;
|
|
22713
|
-
const dagreNode = g.node(gid);
|
|
22714
|
-
if (!dagreNode) continue;
|
|
22715
|
-
const og = collapseInfo?.originalGroups.find((g2) => g2.label === label);
|
|
22716
|
-
layoutGroups.push({
|
|
22717
|
-
label,
|
|
22718
|
-
lineNumber: og?.lineNumber ?? 0,
|
|
22719
|
-
x: dagreNode.x,
|
|
22720
|
-
y: dagreNode.y,
|
|
22721
|
-
width: dagreNode.width,
|
|
22722
|
-
height: dagreNode.height,
|
|
22723
|
-
collapsed: true,
|
|
22724
|
-
childCount: collapseInfo?.collapsedChildCounts.get(label) ?? 0
|
|
22725
|
-
});
|
|
22726
|
-
}
|
|
22727
|
-
const groupAlignShifts = /* @__PURE__ */ new Map();
|
|
22728
|
-
{
|
|
22729
|
-
const groupEdges = [];
|
|
22730
|
-
for (const edge of parsed.edges) {
|
|
22731
|
-
if (edge.source.startsWith("__group_") && edge.target.startsWith("__group_")) {
|
|
22732
|
-
groupEdges.push(edge);
|
|
22733
|
-
}
|
|
22734
|
-
}
|
|
22735
|
-
if (groupEdges.length > 0) {
|
|
22736
|
-
const groupParent = /* @__PURE__ */ new Map();
|
|
22737
|
-
const find = (x) => {
|
|
22738
|
-
while (groupParent.has(x) && groupParent.get(x) !== x) {
|
|
22739
|
-
groupParent.set(x, groupParent.get(groupParent.get(x)));
|
|
22740
|
-
x = groupParent.get(x);
|
|
22741
|
-
}
|
|
22742
|
-
return x;
|
|
22743
|
-
};
|
|
22744
|
-
const union = (a, b) => {
|
|
22745
|
-
const ra = find(a), rb = find(b);
|
|
22746
|
-
if (ra !== rb) groupParent.set(ra, rb);
|
|
22747
|
-
};
|
|
22748
|
-
for (const edge of groupEdges) {
|
|
22749
|
-
if (!groupParent.has(edge.source))
|
|
22750
|
-
groupParent.set(edge.source, edge.source);
|
|
22751
|
-
if (!groupParent.has(edge.target))
|
|
22752
|
-
groupParent.set(edge.target, edge.target);
|
|
22753
|
-
union(edge.source, edge.target);
|
|
22754
|
-
}
|
|
22755
|
-
const components = /* @__PURE__ */ new Map();
|
|
22756
|
-
for (const lg of layoutGroups) {
|
|
22757
|
-
const gid = `__group_${lg.label}`;
|
|
22758
|
-
if (!groupParent.has(gid)) continue;
|
|
22759
|
-
const root = find(gid);
|
|
22760
|
-
if (!components.has(root)) components.set(root, []);
|
|
22761
|
-
components.get(root).push(lg);
|
|
22762
|
-
}
|
|
22763
|
-
const axis = parsed.direction === "TB" ? "x" : "y";
|
|
22764
|
-
for (const groups of components.values()) {
|
|
22765
|
-
if (groups.length < 2) continue;
|
|
22766
|
-
const dim = axis === "x" ? "width" : "height";
|
|
22767
|
-
let widest = groups[0];
|
|
22768
|
-
for (const g2 of groups) {
|
|
22769
|
-
if (g2[dim] > widest[dim]) widest = g2;
|
|
22770
|
-
}
|
|
22771
|
-
const targetCenter = widest[axis];
|
|
22772
|
-
for (const grp of groups) {
|
|
22773
|
-
const dx = targetCenter - grp[axis];
|
|
22774
|
-
if (dx === 0) continue;
|
|
22775
|
-
grp[axis] += dx;
|
|
22776
|
-
groupAlignShifts.set(`__group_${grp.label}`, dx);
|
|
22777
|
-
const parsedGroup = parsed.groups.find(
|
|
22778
|
-
(pg) => pg.label === grp.label
|
|
22779
|
-
);
|
|
22780
|
-
if (parsedGroup) {
|
|
22781
|
-
for (const childLabel of parsedGroup.children) {
|
|
22782
|
-
const childNode = layoutNodes.find((n) => n.label === childLabel);
|
|
22783
|
-
if (childNode) childNode[axis] += dx;
|
|
22784
|
-
}
|
|
22785
|
-
}
|
|
22786
|
-
}
|
|
22787
|
-
}
|
|
22788
|
-
}
|
|
22789
|
-
}
|
|
22790
|
-
const edgeYOffsets = new Array(parsed.edges.length).fill(0);
|
|
22791
|
-
const edgeParallelCounts = new Array(parsed.edges.length).fill(1);
|
|
22792
|
-
const parallelGroups = /* @__PURE__ */ new Map();
|
|
22793
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22794
|
-
const edge = parsed.edges[i];
|
|
22795
|
-
const [a, b] = edge.source < edge.target ? [edge.source, edge.target] : [edge.target, edge.source];
|
|
22796
|
-
const key = `${a}\0${b}`;
|
|
22797
|
-
if (!parallelGroups.has(key)) parallelGroups.set(key, []);
|
|
22798
|
-
parallelGroups.get(key).push(i);
|
|
22799
|
-
}
|
|
22800
|
-
for (const group of parallelGroups.values()) {
|
|
22801
|
-
const capped = group.slice(0, MAX_PARALLEL_EDGES);
|
|
22802
|
-
for (const idx of group.slice(MAX_PARALLEL_EDGES)) {
|
|
22803
|
-
edgeParallelCounts[idx] = 0;
|
|
22804
|
-
}
|
|
22805
|
-
if (capped.length < 2) continue;
|
|
22806
|
-
const effectiveSpacing = PARALLEL_SPACING;
|
|
22807
|
-
for (let j = 0; j < capped.length; j++) {
|
|
22808
|
-
edgeYOffsets[capped[j]] = (j - (capped.length - 1) / 2) * effectiveSpacing;
|
|
22809
|
-
edgeParallelCounts[capped[j]] = capped.length;
|
|
22810
|
-
}
|
|
22811
|
-
}
|
|
22812
|
-
const deferredSet = new Set(deferredEdgeIndices);
|
|
22813
|
-
const layoutEdges = [];
|
|
22814
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22815
|
-
const edge = parsed.edges[i];
|
|
22816
|
-
if (edgeParallelCounts[i] === 0) continue;
|
|
22817
|
-
let points;
|
|
22818
|
-
if (deferredSet.has(i)) {
|
|
22819
|
-
const srcLayout = layoutGroups.find(
|
|
22820
|
-
(lg) => `__group_${lg.label}` === edge.source
|
|
22821
|
-
);
|
|
22822
|
-
const tgtLayout = layoutGroups.find(
|
|
22823
|
-
(lg) => `__group_${lg.label}` === edge.target
|
|
22824
|
-
);
|
|
22825
|
-
if (!srcLayout || !tgtLayout) {
|
|
22826
|
-
const srcNode = g.node(edge.source);
|
|
22827
|
-
const tgtNode = g.node(edge.target);
|
|
22828
|
-
if (!srcNode || !tgtNode) continue;
|
|
22829
|
-
const srcPt = clipToRectBorder2(
|
|
22830
|
-
srcNode.x,
|
|
22831
|
-
srcNode.y,
|
|
22832
|
-
srcNode.width,
|
|
22833
|
-
srcNode.height,
|
|
22834
|
-
tgtNode.x,
|
|
22835
|
-
tgtNode.y
|
|
22836
|
-
);
|
|
22837
|
-
const tgtPt = clipToRectBorder2(
|
|
22838
|
-
tgtNode.x,
|
|
22839
|
-
tgtNode.y,
|
|
22840
|
-
tgtNode.width,
|
|
22841
|
-
tgtNode.height,
|
|
22842
|
-
srcNode.x,
|
|
22843
|
-
srcNode.y
|
|
22844
|
-
);
|
|
22845
|
-
const midX = (srcPt.x + tgtPt.x) / 2;
|
|
22846
|
-
const midY = (srcPt.y + tgtPt.y) / 2;
|
|
22847
|
-
points = [srcPt, { x: midX, y: midY }, tgtPt];
|
|
22848
|
-
} else if (parsed.direction === "TB") {
|
|
22849
|
-
const cx = (srcLayout.x + tgtLayout.x) / 2;
|
|
22850
|
-
const srcPt = { x: cx, y: srcLayout.y + srcLayout.height / 2 };
|
|
22851
|
-
const tgtPt = { x: cx, y: tgtLayout.y - tgtLayout.height / 2 };
|
|
22852
|
-
const midY = (srcPt.y + tgtPt.y) / 2;
|
|
22853
|
-
points = [srcPt, { x: cx, y: midY }, tgtPt];
|
|
22854
|
-
} else {
|
|
22855
|
-
const cy = (srcLayout.y + tgtLayout.y) / 2;
|
|
22856
|
-
const srcPt = { x: srcLayout.x + srcLayout.width / 2, y: cy };
|
|
22857
|
-
const tgtPt = { x: tgtLayout.x - tgtLayout.width / 2, y: cy };
|
|
22858
|
-
const midX = (srcPt.x + tgtPt.x) / 2;
|
|
22859
|
-
points = [srcPt, { x: midX, y: cy }, tgtPt];
|
|
22860
|
-
}
|
|
22861
|
-
} else {
|
|
22862
|
-
const dagreEdge = g.edge(edge.source, edge.target, `e${i}`);
|
|
22863
|
-
points = dagreEdge?.points ?? [];
|
|
22864
|
-
const srcShift = groupAlignShifts.get(edge.source) ?? 0;
|
|
22865
|
-
const tgtShift = groupAlignShifts.get(edge.target) ?? 0;
|
|
22866
|
-
if (srcShift !== 0 || tgtShift !== 0) {
|
|
22867
|
-
const avgShift = (srcShift + tgtShift) / 2;
|
|
22868
|
-
const prop = parsed.direction === "TB" ? "x" : "y";
|
|
22869
|
-
points = points.map((p) => ({ ...p, [prop]: p[prop] + avgShift }));
|
|
22870
|
-
}
|
|
22871
|
-
}
|
|
22872
|
-
let labelX;
|
|
22873
|
-
let labelY;
|
|
22874
|
-
if (edge.label && points.length >= 2) {
|
|
22875
|
-
const mid = Math.floor(points.length / 2);
|
|
22876
|
-
labelX = points[mid].x;
|
|
22877
|
-
labelY = points[mid].y - 10;
|
|
22878
|
-
}
|
|
22879
|
-
layoutEdges.push({
|
|
22880
|
-
source: edge.source,
|
|
22881
|
-
target: edge.target,
|
|
22882
|
-
label: edge.label,
|
|
22883
|
-
bidirectional: edge.bidirectional,
|
|
22884
|
-
lineNumber: edge.lineNumber,
|
|
22885
|
-
points,
|
|
22886
|
-
labelX,
|
|
22887
|
-
labelY,
|
|
22888
|
-
yOffset: edgeYOffsets[i],
|
|
22889
|
-
parallelCount: edgeParallelCounts[i],
|
|
22890
|
-
metadata: edge.metadata,
|
|
22891
|
-
deferred: deferredSet.has(i) || void 0
|
|
22892
|
-
});
|
|
22893
|
-
}
|
|
22894
|
-
let maxX = 0;
|
|
22895
|
-
let maxY = 0;
|
|
22896
|
-
for (const node of layoutNodes) {
|
|
22897
|
-
maxX = Math.max(maxX, node.x + node.width / 2);
|
|
22898
|
-
maxY = Math.max(maxY, node.y + node.height / 2);
|
|
22899
|
-
}
|
|
22900
|
-
for (const group of layoutGroups) {
|
|
22901
|
-
maxX = Math.max(maxX, group.x + group.width / 2);
|
|
22902
|
-
maxY = Math.max(maxY, group.y + group.height / 2);
|
|
22903
|
-
}
|
|
22904
|
-
return {
|
|
22905
|
-
nodes: layoutNodes,
|
|
22906
|
-
edges: layoutEdges,
|
|
22907
|
-
groups: layoutGroups,
|
|
22908
|
-
width: maxX + MARGIN3,
|
|
22909
|
-
height: maxY + MARGIN3
|
|
22910
|
-
};
|
|
22911
|
-
}
|
|
22912
|
-
var NODESEP, RANKSEP, MARGIN3, CONTAINER_PAD_X3, CONTAINER_PAD_TOP2, CONTAINER_PAD_BOTTOM3, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE, DESC_LINE_HEIGHT, DESC_PADDING, SEPARATOR_GAP5, MAX_DESC_LINES, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, LABEL_PAD;
|
|
22913
|
-
var init_layout5 = __esm({
|
|
22914
|
-
"src/boxes-and-lines/layout.ts"() {
|
|
22915
|
-
"use strict";
|
|
22916
|
-
NODESEP = 60;
|
|
22917
|
-
RANKSEP = 100;
|
|
22918
|
-
MARGIN3 = 40;
|
|
22919
|
-
CONTAINER_PAD_X3 = 30;
|
|
22920
|
-
CONTAINER_PAD_TOP2 = 40;
|
|
22921
|
-
CONTAINER_PAD_BOTTOM3 = 24;
|
|
22922
|
-
MAX_PARALLEL_EDGES = 5;
|
|
22923
|
-
PARALLEL_SPACING = 22;
|
|
22924
|
-
PHI = 1.618;
|
|
22925
|
-
NODE_HEIGHT = 60;
|
|
22926
|
-
NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
|
|
22927
|
-
DESC_NODE_WIDTH = 140;
|
|
22928
|
-
DESC_FONT_SIZE = 10;
|
|
22929
|
-
DESC_LINE_HEIGHT = 1.4;
|
|
22930
|
-
DESC_PADDING = 8;
|
|
22931
|
-
SEPARATOR_GAP5 = 4;
|
|
22932
|
-
MAX_DESC_LINES = 6;
|
|
22933
|
-
MAX_LABEL_LINES = 3;
|
|
22934
|
-
LABEL_LINE_HEIGHT = 1.3;
|
|
22935
|
-
LABEL_PAD = 12;
|
|
22936
|
-
}
|
|
22937
|
-
});
|
|
22938
|
-
|
|
22939
22439
|
// src/utils/wrapped-desc.ts
|
|
22940
22440
|
function wrapDescriptionLines(lines, charsPerLine, lengthFn = (s) => s.length) {
|
|
22941
22441
|
const result = [];
|
|
@@ -22987,7 +22487,7 @@ __export(renderer_exports6, {
|
|
|
22987
22487
|
});
|
|
22988
22488
|
import * as d3Selection6 from "d3-selection";
|
|
22989
22489
|
import * as d3Shape4 from "d3-shape";
|
|
22990
|
-
function
|
|
22490
|
+
function splitCamelCase(word) {
|
|
22991
22491
|
const parts = [];
|
|
22992
22492
|
let start = 0;
|
|
22993
22493
|
for (let i = 1; i < word.length; i++) {
|
|
@@ -23010,7 +22510,7 @@ function fitLabelToHeader(label, nodeWidth2, maxLines) {
|
|
|
23010
22510
|
const words = [];
|
|
23011
22511
|
for (const part of rawParts) {
|
|
23012
22512
|
if (!part || /^\s+$/.test(part) || part === "-") continue;
|
|
23013
|
-
words.push(...
|
|
22513
|
+
words.push(...splitCamelCase(part));
|
|
23014
22514
|
}
|
|
23015
22515
|
for (let fontSize = NODE_FONT_SIZE; fontSize >= MIN_NODE_FONT_SIZE; fontSize--) {
|
|
23016
22516
|
const charWidth2 = fontSize * CHAR_WIDTH_RATIO2;
|
|
@@ -23386,12 +22886,12 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23386
22886
|
}
|
|
23387
22887
|
const sepY = -ln.height / 2 + headerH;
|
|
23388
22888
|
nodeG.append("line").attr("x1", -ln.width / 2).attr("y1", sepY).attr("x2", ln.width / 2).attr("y2", sepY).attr("stroke", colors.stroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
|
|
23389
|
-
const descStartY = sepY + 4 +
|
|
22889
|
+
const descStartY = sepY + 4 + DESC_FONT_SIZE;
|
|
23390
22890
|
const maxTextWidth = ln.width - NODE_TEXT_PADDING * 2;
|
|
23391
22891
|
const charsPerLine = Math.floor(
|
|
23392
|
-
maxTextWidth / (
|
|
22892
|
+
maxTextWidth / (DESC_FONT_SIZE * CHAR_WIDTH_RATIO2)
|
|
23393
22893
|
);
|
|
23394
|
-
const descLineH =
|
|
22894
|
+
const descLineH = DESC_FONT_SIZE * DESC_LINE_HEIGHT;
|
|
23395
22895
|
const displayLen = (text) => text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*(.+?)\*\*/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/`(.+?)`/g, "$1").replace(/https?:\/\/\S+/g, (u) => u.slice(0, 20)).length;
|
|
23396
22896
|
const normalizedLines = [];
|
|
23397
22897
|
for (const descLine of desc) {
|
|
@@ -23407,8 +22907,8 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23407
22907
|
charsPerLine,
|
|
23408
22908
|
displayLen
|
|
23409
22909
|
);
|
|
23410
|
-
const truncated = wrappedLinesShared.length >
|
|
23411
|
-
const visibleLines = truncated ? wrappedLinesShared.slice(0,
|
|
22910
|
+
const truncated = wrappedLinesShared.length > MAX_DESC_LINES;
|
|
22911
|
+
const visibleLines = truncated ? wrappedLinesShared.slice(0, MAX_DESC_LINES) : wrappedLinesShared;
|
|
23412
22912
|
const BULLET_GLYPH_X = -ln.width / 2 + 6;
|
|
23413
22913
|
const BULLET_BODY_X = BULLET_GLYPH_X + 10;
|
|
23414
22914
|
for (let li = 0; li < visibleLines.length; li++) {
|
|
@@ -23419,11 +22919,11 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23419
22919
|
}
|
|
23420
22920
|
const y2 = descStartY + li * descLineH;
|
|
23421
22921
|
if (line12.kind === "bullet-first") {
|
|
23422
|
-
nodeG.append("text").attr("x", BULLET_GLYPH_X).attr("y", y2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("font-size",
|
|
22922
|
+
nodeG.append("text").attr("x", BULLET_GLYPH_X).attr("y", y2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("font-size", DESC_FONT_SIZE).attr("fill", palette.textMuted).text("\u2022");
|
|
23423
22923
|
}
|
|
23424
22924
|
const isBullet = line12.kind === "bullet-first" || line12.kind === "bullet-cont";
|
|
23425
|
-
const textEl = nodeG.append("text").attr("x", isBullet ? BULLET_BODY_X : 0).attr("y", y2).attr("text-anchor", isBullet ? "start" : "middle").attr("dominant-baseline", "central").attr("font-size",
|
|
23426
|
-
renderInlineText(textEl, lineText, palette,
|
|
22925
|
+
const textEl = nodeG.append("text").attr("x", isBullet ? BULLET_BODY_X : 0).attr("y", y2).attr("text-anchor", isBullet ? "start" : "middle").attr("dominant-baseline", "central").attr("font-size", DESC_FONT_SIZE).attr("fill", palette.textMuted);
|
|
22926
|
+
renderInlineText(textEl, lineText, palette, DESC_FONT_SIZE);
|
|
23427
22927
|
}
|
|
23428
22928
|
if (truncated) {
|
|
23429
22929
|
const fullText = desc.join(" ");
|
|
@@ -23501,7 +23001,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
|
|
|
23501
23001
|
hiddenTagValues: options?.hiddenTagValues
|
|
23502
23002
|
});
|
|
23503
23003
|
}
|
|
23504
|
-
var DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2,
|
|
23004
|
+
var DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, CHAR_WIDTH_RATIO2, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, lineGeneratorLR, lineGeneratorTB;
|
|
23505
23005
|
var init_renderer6 = __esm({
|
|
23506
23006
|
"src/boxes-and-lines/renderer.ts"() {
|
|
23507
23007
|
"use strict";
|
|
@@ -23523,9 +23023,9 @@ var init_renderer6 = __esm({
|
|
|
23523
23023
|
COLLAPSE_BAR_HEIGHT3 = 4;
|
|
23524
23024
|
ARROWHEAD_W2 = 5;
|
|
23525
23025
|
ARROWHEAD_H2 = 4;
|
|
23526
|
-
|
|
23527
|
-
|
|
23528
|
-
|
|
23026
|
+
DESC_FONT_SIZE = 10;
|
|
23027
|
+
DESC_LINE_HEIGHT = 1.4;
|
|
23028
|
+
MAX_DESC_LINES = 6;
|
|
23529
23029
|
CHAR_WIDTH_RATIO2 = 0.6;
|
|
23530
23030
|
NODE_TEXT_PADDING = 12;
|
|
23531
23031
|
GROUP_RX = 8;
|
|
@@ -23536,6 +23036,523 @@ var init_renderer6 = __esm({
|
|
|
23536
23036
|
}
|
|
23537
23037
|
});
|
|
23538
23038
|
|
|
23039
|
+
// src/boxes-and-lines/layout.ts
|
|
23040
|
+
var layout_exports5 = {};
|
|
23041
|
+
__export(layout_exports5, {
|
|
23042
|
+
layoutBoxesAndLines: () => layoutBoxesAndLines
|
|
23043
|
+
});
|
|
23044
|
+
import ELK from "elkjs/lib/elk.bundled.js";
|
|
23045
|
+
function splitCamelCase2(word) {
|
|
23046
|
+
const parts = [];
|
|
23047
|
+
let start = 0;
|
|
23048
|
+
for (let i = 1; i < word.length; i++) {
|
|
23049
|
+
const prev = word[i - 1];
|
|
23050
|
+
const curr = word[i];
|
|
23051
|
+
const next = i + 1 < word.length ? word[i + 1] : "";
|
|
23052
|
+
const lowerToUpper = prev >= "a" && prev <= "z" && curr >= "A" && curr <= "Z";
|
|
23053
|
+
const upperRunEnd = prev >= "A" && prev <= "Z" && curr >= "A" && curr <= "Z" && next >= "a" && next <= "z";
|
|
23054
|
+
if (lowerToUpper || upperRunEnd) {
|
|
23055
|
+
parts.push(word.slice(start, i));
|
|
23056
|
+
start = i;
|
|
23057
|
+
}
|
|
23058
|
+
}
|
|
23059
|
+
parts.push(word.slice(start));
|
|
23060
|
+
return parts.length > 1 ? parts : [word];
|
|
23061
|
+
}
|
|
23062
|
+
function estimateLabelLines(label, nodeWidth2 = NODE_WIDTH) {
|
|
23063
|
+
const rawParts = label.split(/[\s-]+/);
|
|
23064
|
+
const words = [];
|
|
23065
|
+
for (const part of rawParts) {
|
|
23066
|
+
if (!part) continue;
|
|
23067
|
+
words.push(...splitCamelCase2(part));
|
|
23068
|
+
}
|
|
23069
|
+
for (let fontSize = 13; fontSize >= 9; fontSize--) {
|
|
23070
|
+
const charWidth = fontSize * 0.6;
|
|
23071
|
+
const maxChars = Math.floor((nodeWidth2 - 24) / charWidth);
|
|
23072
|
+
if (maxChars < 2) continue;
|
|
23073
|
+
let lines = 1;
|
|
23074
|
+
let current = "";
|
|
23075
|
+
for (const word of words) {
|
|
23076
|
+
const test = current ? `${current} ${word}` : word;
|
|
23077
|
+
if (test.length <= maxChars) {
|
|
23078
|
+
current = test;
|
|
23079
|
+
} else {
|
|
23080
|
+
lines++;
|
|
23081
|
+
current = word;
|
|
23082
|
+
}
|
|
23083
|
+
}
|
|
23084
|
+
if (lines <= MAX_LABEL_LINES) return Math.min(lines, MAX_LABEL_LINES);
|
|
23085
|
+
}
|
|
23086
|
+
return MAX_LABEL_LINES;
|
|
23087
|
+
}
|
|
23088
|
+
function computeNodeSize(node) {
|
|
23089
|
+
if (!node.description || node.description.length === 0) {
|
|
23090
|
+
return { width: NODE_WIDTH, height: NODE_HEIGHT };
|
|
23091
|
+
}
|
|
23092
|
+
const w = DESC_NODE_WIDTH;
|
|
23093
|
+
const labelLines = estimateLabelLines(node.label, w);
|
|
23094
|
+
const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT + LABEL_PAD;
|
|
23095
|
+
const charsPerLine = Math.floor((w - 24) / (DESC_FONT_SIZE2 * 0.6));
|
|
23096
|
+
let totalRenderedLines = 0;
|
|
23097
|
+
for (const line12 of node.description) {
|
|
23098
|
+
if (line12.length <= charsPerLine) {
|
|
23099
|
+
totalRenderedLines += 1;
|
|
23100
|
+
} else {
|
|
23101
|
+
const words = line12.split(/\s+/);
|
|
23102
|
+
let current = "";
|
|
23103
|
+
let lineCount = 0;
|
|
23104
|
+
for (const word of words) {
|
|
23105
|
+
const fitted = word.length > charsPerLine ? word.slice(0, charsPerLine) : word;
|
|
23106
|
+
const test = current ? `${current} ${fitted}` : fitted;
|
|
23107
|
+
if (test.length <= charsPerLine) {
|
|
23108
|
+
current = test;
|
|
23109
|
+
} else {
|
|
23110
|
+
if (current) lineCount++;
|
|
23111
|
+
current = fitted;
|
|
23112
|
+
}
|
|
23113
|
+
}
|
|
23114
|
+
if (current) lineCount++;
|
|
23115
|
+
totalRenderedLines += lineCount;
|
|
23116
|
+
}
|
|
23117
|
+
}
|
|
23118
|
+
totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES2);
|
|
23119
|
+
const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE2 * DESC_LINE_HEIGHT2;
|
|
23120
|
+
const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING;
|
|
23121
|
+
return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
|
|
23122
|
+
}
|
|
23123
|
+
function getElk() {
|
|
23124
|
+
if (!elkInstance) elkInstance = new ELK();
|
|
23125
|
+
return elkInstance;
|
|
23126
|
+
}
|
|
23127
|
+
function baseOptions() {
|
|
23128
|
+
return {
|
|
23129
|
+
"elk.algorithm": "layered",
|
|
23130
|
+
// INCLUDE_CHILDREN lets ELK route edges across container boundaries.
|
|
23131
|
+
"elk.hierarchyHandling": "INCLUDE_CHILDREN",
|
|
23132
|
+
"elk.edgeRouting": "ORTHOGONAL",
|
|
23133
|
+
"elk.layered.unnecessaryBendpoints": "true",
|
|
23134
|
+
// Let edges leave from top/bottom of nodes (not just the flow-direction
|
|
23135
|
+
// sides) when it reduces crossings.
|
|
23136
|
+
"elk.layered.allowNonFlowPortsToSwitchSides": "true"
|
|
23137
|
+
};
|
|
23138
|
+
}
|
|
23139
|
+
function bkBaseline() {
|
|
23140
|
+
return {
|
|
23141
|
+
...baseOptions(),
|
|
23142
|
+
"elk.layered.nodePlacement.strategy": "BRANDES_KOEPF",
|
|
23143
|
+
"elk.layered.nodePlacement.bk.fixedAlignment": "BALANCED",
|
|
23144
|
+
"elk.layered.nodePlacement.bk.edgeStraightening": "IMPROVE_STRAIGHTNESS",
|
|
23145
|
+
"elk.layered.compaction.connectedComponents": "true",
|
|
23146
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": "90",
|
|
23147
|
+
"elk.spacing.nodeNode": "55",
|
|
23148
|
+
"elk.spacing.edgeNode": "55",
|
|
23149
|
+
"elk.spacing.edgeEdge": "18"
|
|
23150
|
+
};
|
|
23151
|
+
}
|
|
23152
|
+
function getVariants() {
|
|
23153
|
+
const bk = bkBaseline();
|
|
23154
|
+
return [
|
|
23155
|
+
{
|
|
23156
|
+
name: "bk-baseline",
|
|
23157
|
+
options: {
|
|
23158
|
+
...bk,
|
|
23159
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "ONE_SIDED"
|
|
23160
|
+
}
|
|
23161
|
+
},
|
|
23162
|
+
{
|
|
23163
|
+
name: "bk-aggressive",
|
|
23164
|
+
options: {
|
|
23165
|
+
...bk,
|
|
23166
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23167
|
+
"elk.layered.thoroughness": "50"
|
|
23168
|
+
}
|
|
23169
|
+
},
|
|
23170
|
+
{
|
|
23171
|
+
name: "bk-wide",
|
|
23172
|
+
options: {
|
|
23173
|
+
...bk,
|
|
23174
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23175
|
+
"elk.layered.thoroughness": "50",
|
|
23176
|
+
"elk.spacing.nodeNode": "70",
|
|
23177
|
+
"elk.spacing.edgeNode": "75",
|
|
23178
|
+
"elk.spacing.edgeEdge": "22",
|
|
23179
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": "120"
|
|
23180
|
+
}
|
|
23181
|
+
},
|
|
23182
|
+
{
|
|
23183
|
+
name: "longest-path",
|
|
23184
|
+
options: {
|
|
23185
|
+
...bk,
|
|
23186
|
+
"elk.layered.layering.strategy": "LONGEST_PATH",
|
|
23187
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23188
|
+
"elk.layered.thoroughness": "50"
|
|
23189
|
+
}
|
|
23190
|
+
},
|
|
23191
|
+
{
|
|
23192
|
+
name: "bounded-width",
|
|
23193
|
+
options: {
|
|
23194
|
+
...bk,
|
|
23195
|
+
"elk.layered.layering.strategy": "COFFMAN_GRAHAM",
|
|
23196
|
+
"elk.layered.layering.coffmanGraham.layerBound": "3",
|
|
23197
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23198
|
+
"elk.layered.thoroughness": "50"
|
|
23199
|
+
}
|
|
23200
|
+
}
|
|
23201
|
+
];
|
|
23202
|
+
}
|
|
23203
|
+
function countCrossings(edges) {
|
|
23204
|
+
let count = 0;
|
|
23205
|
+
for (let i = 0; i < edges.length; i++) {
|
|
23206
|
+
const a = edges[i].points;
|
|
23207
|
+
if (a.length < 2) continue;
|
|
23208
|
+
for (let j = i + 1; j < edges.length; j++) {
|
|
23209
|
+
const b = edges[j].points;
|
|
23210
|
+
if (b.length < 2) continue;
|
|
23211
|
+
if (edges[i].source === edges[j].source) continue;
|
|
23212
|
+
if (edges[i].source === edges[j].target) continue;
|
|
23213
|
+
if (edges[i].target === edges[j].source) continue;
|
|
23214
|
+
if (edges[i].target === edges[j].target) continue;
|
|
23215
|
+
for (let ai = 0; ai < a.length - 1; ai++) {
|
|
23216
|
+
for (let bi = 0; bi < b.length - 1; bi++) {
|
|
23217
|
+
if (segmentsCross(a[ai], a[ai + 1], b[bi], b[bi + 1])) count++;
|
|
23218
|
+
}
|
|
23219
|
+
}
|
|
23220
|
+
}
|
|
23221
|
+
}
|
|
23222
|
+
return count;
|
|
23223
|
+
}
|
|
23224
|
+
function segmentsCross(p1, p2, p3, p4) {
|
|
23225
|
+
const d1x = p2.x - p1.x;
|
|
23226
|
+
const d1y = p2.y - p1.y;
|
|
23227
|
+
const d2x = p4.x - p3.x;
|
|
23228
|
+
const d2y = p4.y - p3.y;
|
|
23229
|
+
const denom = d1x * d2y - d1y * d2x;
|
|
23230
|
+
if (Math.abs(denom) < 1e-9) return false;
|
|
23231
|
+
const t = ((p3.x - p1.x) * d2y - (p3.y - p1.y) * d2x) / denom;
|
|
23232
|
+
const s = ((p3.x - p1.x) * d1y - (p3.y - p1.y) * d1x) / denom;
|
|
23233
|
+
const EPS = 1e-3;
|
|
23234
|
+
return t > EPS && t < 1 - EPS && s > EPS && s < 1 - EPS;
|
|
23235
|
+
}
|
|
23236
|
+
function countTotalBends(edges) {
|
|
23237
|
+
let bends = 0;
|
|
23238
|
+
for (const e of edges) bends += Math.max(0, e.points.length - 2);
|
|
23239
|
+
return bends;
|
|
23240
|
+
}
|
|
23241
|
+
function scoreLayout(layout) {
|
|
23242
|
+
return {
|
|
23243
|
+
crossings: countCrossings(layout.edges),
|
|
23244
|
+
bends: countTotalBends(layout.edges),
|
|
23245
|
+
area: layout.width * layout.height
|
|
23246
|
+
};
|
|
23247
|
+
}
|
|
23248
|
+
function cmpScore(a, b) {
|
|
23249
|
+
const aBucket = a.crossings <= CROSSINGS_FORGIVENESS ? 0 : a.crossings;
|
|
23250
|
+
const bBucket = b.crossings <= CROSSINGS_FORGIVENESS ? 0 : b.crossings;
|
|
23251
|
+
if (aBucket !== bBucket) return aBucket - bBucket;
|
|
23252
|
+
if (a.area !== b.area) return a.area - b.area;
|
|
23253
|
+
return a.bends - b.bends;
|
|
23254
|
+
}
|
|
23255
|
+
async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
|
|
23256
|
+
const hideDescriptions = layoutOptions?.hideDescriptions ?? false;
|
|
23257
|
+
const direction = parsed.direction === "TB" ? "DOWN" : "RIGHT";
|
|
23258
|
+
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
23259
|
+
if (collapseInfo) {
|
|
23260
|
+
const missingGroups = /* @__PURE__ */ new Set();
|
|
23261
|
+
for (const og of collapseInfo.originalGroups) {
|
|
23262
|
+
if (!parsed.groups.some((g) => g.label === og.label)) {
|
|
23263
|
+
missingGroups.add(og.label);
|
|
23264
|
+
}
|
|
23265
|
+
}
|
|
23266
|
+
for (const label of missingGroups) {
|
|
23267
|
+
const og = collapseInfo.originalGroups.find((g) => g.label === label);
|
|
23268
|
+
const parentLabel = og?.parentGroup;
|
|
23269
|
+
if (!parentLabel || !missingGroups.has(parentLabel)) {
|
|
23270
|
+
collapsedGroupLabels.add(label);
|
|
23271
|
+
}
|
|
23272
|
+
}
|
|
23273
|
+
}
|
|
23274
|
+
const nodeSizes = /* @__PURE__ */ new Map();
|
|
23275
|
+
let maxDescHeight = 0;
|
|
23276
|
+
for (const node of parsed.nodes) {
|
|
23277
|
+
const size = hideDescriptions ? { width: NODE_WIDTH, height: NODE_HEIGHT } : computeNodeSize(node);
|
|
23278
|
+
nodeSizes.set(node.label, size);
|
|
23279
|
+
if (!hideDescriptions && node.description && node.description.length > 0) {
|
|
23280
|
+
maxDescHeight = Math.max(maxDescHeight, size.height);
|
|
23281
|
+
}
|
|
23282
|
+
}
|
|
23283
|
+
if (maxDescHeight > 0) {
|
|
23284
|
+
for (const node of parsed.nodes) {
|
|
23285
|
+
if (node.description && node.description.length > 0) {
|
|
23286
|
+
const size = nodeSizes.get(node.label);
|
|
23287
|
+
nodeSizes.set(node.label, { width: size.width, height: maxDescHeight });
|
|
23288
|
+
}
|
|
23289
|
+
}
|
|
23290
|
+
}
|
|
23291
|
+
const expandedGroupSet = new Set(parsed.groups.map((g) => g.label));
|
|
23292
|
+
const gid = (label) => `__group_${label}`;
|
|
23293
|
+
function buildGraph() {
|
|
23294
|
+
const nodeById = /* @__PURE__ */ new Map();
|
|
23295
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
23296
|
+
for (const node of parsed.nodes) {
|
|
23297
|
+
const size = nodeSizes.get(node.label);
|
|
23298
|
+
nodeById.set(node.label, {
|
|
23299
|
+
id: node.label,
|
|
23300
|
+
width: size.width,
|
|
23301
|
+
height: size.height,
|
|
23302
|
+
labels: [{ text: node.label }]
|
|
23303
|
+
});
|
|
23304
|
+
}
|
|
23305
|
+
for (const group of parsed.groups) {
|
|
23306
|
+
nodeById.set(gid(group.label), {
|
|
23307
|
+
id: gid(group.label),
|
|
23308
|
+
labels: [{ text: group.label }],
|
|
23309
|
+
layoutOptions: {
|
|
23310
|
+
"elk.padding": `[top=${CONTAINER_PAD_TOP2},left=${CONTAINER_PAD_X3},bottom=${CONTAINER_PAD_BOTTOM3},right=${CONTAINER_PAD_X3}]`,
|
|
23311
|
+
// Suggest square-ish containers — has limited effect with
|
|
23312
|
+
// INCLUDE_CHILDREN but doesn't hurt.
|
|
23313
|
+
"elk.aspectRatio": "1.4"
|
|
23314
|
+
},
|
|
23315
|
+
children: [],
|
|
23316
|
+
edges: []
|
|
23317
|
+
});
|
|
23318
|
+
}
|
|
23319
|
+
for (const label of collapsedGroupLabels) {
|
|
23320
|
+
nodeById.set(gid(label), {
|
|
23321
|
+
id: gid(label),
|
|
23322
|
+
width: NODE_WIDTH,
|
|
23323
|
+
height: NODE_HEIGHT,
|
|
23324
|
+
labels: [{ text: label }]
|
|
23325
|
+
});
|
|
23326
|
+
}
|
|
23327
|
+
for (const group of parsed.groups) {
|
|
23328
|
+
if (group.parentGroup && nodeById.has(gid(group.parentGroup))) {
|
|
23329
|
+
parentOf.set(gid(group.label), gid(group.parentGroup));
|
|
23330
|
+
}
|
|
23331
|
+
}
|
|
23332
|
+
if (collapseInfo) {
|
|
23333
|
+
for (const label of collapsedGroupLabels) {
|
|
23334
|
+
const og = collapseInfo.originalGroups.find((g) => g.label === label);
|
|
23335
|
+
if (og?.parentGroup && !collapsedGroupLabels.has(og.parentGroup) && nodeById.has(gid(og.parentGroup))) {
|
|
23336
|
+
parentOf.set(gid(label), gid(og.parentGroup));
|
|
23337
|
+
}
|
|
23338
|
+
}
|
|
23339
|
+
}
|
|
23340
|
+
for (const group of parsed.groups) {
|
|
23341
|
+
for (const child of group.children) {
|
|
23342
|
+
if (expandedGroupSet.has(child)) continue;
|
|
23343
|
+
if (nodeById.has(child)) {
|
|
23344
|
+
parentOf.set(child, gid(group.label));
|
|
23345
|
+
}
|
|
23346
|
+
}
|
|
23347
|
+
}
|
|
23348
|
+
const roots = [];
|
|
23349
|
+
for (const [id, node] of nodeById) {
|
|
23350
|
+
const parentId = parentOf.get(id);
|
|
23351
|
+
if (parentId) {
|
|
23352
|
+
const parent = nodeById.get(parentId);
|
|
23353
|
+
parent.children = parent.children ?? [];
|
|
23354
|
+
parent.children.push(node);
|
|
23355
|
+
} else {
|
|
23356
|
+
roots.push(node);
|
|
23357
|
+
}
|
|
23358
|
+
}
|
|
23359
|
+
const rootEdges = [];
|
|
23360
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23361
|
+
const edge = parsed.edges[i];
|
|
23362
|
+
if (!nodeById.has(edge.source) || !nodeById.has(edge.target)) continue;
|
|
23363
|
+
rootEdges.push({
|
|
23364
|
+
id: `e${i}`,
|
|
23365
|
+
sources: [edge.source],
|
|
23366
|
+
targets: [edge.target]
|
|
23367
|
+
});
|
|
23368
|
+
}
|
|
23369
|
+
return { roots, rootEdges };
|
|
23370
|
+
}
|
|
23371
|
+
async function runVariant(variant) {
|
|
23372
|
+
const { roots, rootEdges } = buildGraph();
|
|
23373
|
+
const elkRoot = {
|
|
23374
|
+
id: "root",
|
|
23375
|
+
layoutOptions: {
|
|
23376
|
+
...variant.options,
|
|
23377
|
+
"elk.direction": direction,
|
|
23378
|
+
"elk.padding": `[top=${MARGIN3},left=${MARGIN3},bottom=${MARGIN3},right=${MARGIN3}]`
|
|
23379
|
+
},
|
|
23380
|
+
children: roots,
|
|
23381
|
+
edges: rootEdges
|
|
23382
|
+
};
|
|
23383
|
+
const result = await getElk().layout(elkRoot);
|
|
23384
|
+
return extractLayout(result);
|
|
23385
|
+
}
|
|
23386
|
+
function extractLayout(result) {
|
|
23387
|
+
const layoutNodes = [];
|
|
23388
|
+
const layoutGroups = [];
|
|
23389
|
+
const allEdges = [];
|
|
23390
|
+
const containerAbs = /* @__PURE__ */ new Map();
|
|
23391
|
+
function walk(n, offsetX, offsetY, isRoot) {
|
|
23392
|
+
const nx = (n.x ?? 0) + offsetX;
|
|
23393
|
+
const ny = (n.y ?? 0) + offsetY;
|
|
23394
|
+
const nw = n.width ?? 0;
|
|
23395
|
+
const nh = n.height ?? 0;
|
|
23396
|
+
if (isRoot) {
|
|
23397
|
+
containerAbs.set("root", { x: nx, y: ny });
|
|
23398
|
+
} else {
|
|
23399
|
+
const isGroup = n.id.startsWith("__group_");
|
|
23400
|
+
if (isGroup) {
|
|
23401
|
+
const label = n.id.slice("__group_".length);
|
|
23402
|
+
const collapsed = collapsedGroupLabels.has(label);
|
|
23403
|
+
const og = collapseInfo?.originalGroups.find(
|
|
23404
|
+
(g) => g.label === label
|
|
23405
|
+
);
|
|
23406
|
+
const pg = parsed.groups.find((g) => g.label === label);
|
|
23407
|
+
layoutGroups.push({
|
|
23408
|
+
label,
|
|
23409
|
+
lineNumber: pg?.lineNumber ?? og?.lineNumber ?? 0,
|
|
23410
|
+
x: nx + nw / 2,
|
|
23411
|
+
y: ny + nh / 2,
|
|
23412
|
+
width: nw,
|
|
23413
|
+
height: nh,
|
|
23414
|
+
collapsed,
|
|
23415
|
+
childCount: collapsed ? collapseInfo?.collapsedChildCounts.get(label) ?? 0 : void 0
|
|
23416
|
+
});
|
|
23417
|
+
if (!collapsed) containerAbs.set(n.id, { x: nx, y: ny });
|
|
23418
|
+
} else {
|
|
23419
|
+
layoutNodes.push({
|
|
23420
|
+
label: n.id,
|
|
23421
|
+
x: nx + nw / 2,
|
|
23422
|
+
y: ny + nh / 2,
|
|
23423
|
+
width: nw,
|
|
23424
|
+
height: nh
|
|
23425
|
+
});
|
|
23426
|
+
}
|
|
23427
|
+
}
|
|
23428
|
+
if (n.edges) for (const e of n.edges) allEdges.push(e);
|
|
23429
|
+
if (n.children) for (const c of n.children) walk(c, nx, ny, false);
|
|
23430
|
+
}
|
|
23431
|
+
walk(result, 0, 0, true);
|
|
23432
|
+
const edgeYOffsets = new Array(parsed.edges.length).fill(0);
|
|
23433
|
+
const edgeParallelCounts = new Array(parsed.edges.length).fill(1);
|
|
23434
|
+
const parallelGroups = /* @__PURE__ */ new Map();
|
|
23435
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23436
|
+
const edge = parsed.edges[i];
|
|
23437
|
+
const [a, b] = edge.source < edge.target ? [edge.source, edge.target] : [edge.target, edge.source];
|
|
23438
|
+
const key = `${a}\0${b}`;
|
|
23439
|
+
if (!parallelGroups.has(key)) parallelGroups.set(key, []);
|
|
23440
|
+
parallelGroups.get(key).push(i);
|
|
23441
|
+
}
|
|
23442
|
+
for (const group of parallelGroups.values()) {
|
|
23443
|
+
const capped = group.slice(0, MAX_PARALLEL_EDGES);
|
|
23444
|
+
for (const idx of group.slice(MAX_PARALLEL_EDGES)) {
|
|
23445
|
+
edgeParallelCounts[idx] = 0;
|
|
23446
|
+
}
|
|
23447
|
+
if (capped.length < 2) continue;
|
|
23448
|
+
for (let j = 0; j < capped.length; j++) {
|
|
23449
|
+
edgeYOffsets[capped[j]] = (j - (capped.length - 1) / 2) * PARALLEL_SPACING;
|
|
23450
|
+
edgeParallelCounts[capped[j]] = capped.length;
|
|
23451
|
+
}
|
|
23452
|
+
}
|
|
23453
|
+
const edgeById = /* @__PURE__ */ new Map();
|
|
23454
|
+
for (const e of allEdges) edgeById.set(e.id, e);
|
|
23455
|
+
const layoutEdges = [];
|
|
23456
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23457
|
+
const edge = parsed.edges[i];
|
|
23458
|
+
if (edgeParallelCounts[i] === 0) continue;
|
|
23459
|
+
const elkEdge = edgeById.get(`e${i}`);
|
|
23460
|
+
if (!elkEdge || !elkEdge.sections || elkEdge.sections.length === 0)
|
|
23461
|
+
continue;
|
|
23462
|
+
const container = elkEdge.container ?? "root";
|
|
23463
|
+
const off = containerAbs.get(container) ?? { x: 0, y: 0 };
|
|
23464
|
+
const s = elkEdge.sections[0];
|
|
23465
|
+
const points = [
|
|
23466
|
+
{ x: s.startPoint.x + off.x, y: s.startPoint.y + off.y },
|
|
23467
|
+
...(s.bendPoints ?? []).map((p) => ({
|
|
23468
|
+
x: p.x + off.x,
|
|
23469
|
+
y: p.y + off.y
|
|
23470
|
+
})),
|
|
23471
|
+
{ x: s.endPoint.x + off.x, y: s.endPoint.y + off.y }
|
|
23472
|
+
];
|
|
23473
|
+
let labelX;
|
|
23474
|
+
let labelY;
|
|
23475
|
+
if (edge.label && points.length >= 2) {
|
|
23476
|
+
const mid = Math.floor(points.length / 2);
|
|
23477
|
+
labelX = points[mid].x;
|
|
23478
|
+
labelY = points[mid].y - 10;
|
|
23479
|
+
}
|
|
23480
|
+
layoutEdges.push({
|
|
23481
|
+
source: edge.source,
|
|
23482
|
+
target: edge.target,
|
|
23483
|
+
label: edge.label,
|
|
23484
|
+
bidirectional: edge.bidirectional,
|
|
23485
|
+
lineNumber: edge.lineNumber,
|
|
23486
|
+
points,
|
|
23487
|
+
labelX,
|
|
23488
|
+
labelY,
|
|
23489
|
+
yOffset: edgeYOffsets[i],
|
|
23490
|
+
parallelCount: edgeParallelCounts[i],
|
|
23491
|
+
metadata: edge.metadata,
|
|
23492
|
+
deferred: true
|
|
23493
|
+
});
|
|
23494
|
+
}
|
|
23495
|
+
let maxX = 0;
|
|
23496
|
+
let maxY = 0;
|
|
23497
|
+
for (const node of layoutNodes) {
|
|
23498
|
+
maxX = Math.max(maxX, node.x + node.width / 2);
|
|
23499
|
+
maxY = Math.max(maxY, node.y + node.height / 2);
|
|
23500
|
+
}
|
|
23501
|
+
for (const group of layoutGroups) {
|
|
23502
|
+
maxX = Math.max(maxX, group.x + group.width / 2);
|
|
23503
|
+
maxY = Math.max(maxY, group.y + group.height / 2);
|
|
23504
|
+
}
|
|
23505
|
+
return {
|
|
23506
|
+
nodes: layoutNodes,
|
|
23507
|
+
edges: layoutEdges,
|
|
23508
|
+
groups: layoutGroups,
|
|
23509
|
+
width: maxX + MARGIN3,
|
|
23510
|
+
height: maxY + MARGIN3
|
|
23511
|
+
};
|
|
23512
|
+
}
|
|
23513
|
+
const N = parsed.nodes.length + parsed.groups.length;
|
|
23514
|
+
const E = parsed.edges.length;
|
|
23515
|
+
const trivial = N < 8 && E < 10;
|
|
23516
|
+
const variants = trivial ? [getVariants()[1]] : getVariants();
|
|
23517
|
+
const results = await Promise.all(variants.map((v) => runVariant(v)));
|
|
23518
|
+
let best = results[0];
|
|
23519
|
+
let bestScore = scoreLayout(best);
|
|
23520
|
+
for (let i = 1; i < results.length; i++) {
|
|
23521
|
+
const s = scoreLayout(results[i]);
|
|
23522
|
+
if (cmpScore(s, bestScore) < 0) {
|
|
23523
|
+
best = results[i];
|
|
23524
|
+
bestScore = s;
|
|
23525
|
+
}
|
|
23526
|
+
}
|
|
23527
|
+
return best;
|
|
23528
|
+
}
|
|
23529
|
+
var MARGIN3, CONTAINER_PAD_X3, CONTAINER_PAD_TOP2, CONTAINER_PAD_BOTTOM3, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE2, DESC_LINE_HEIGHT2, DESC_PADDING, SEPARATOR_GAP5, MAX_DESC_LINES2, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, LABEL_PAD, elkInstance, CROSSINGS_FORGIVENESS;
|
|
23530
|
+
var init_layout5 = __esm({
|
|
23531
|
+
"src/boxes-and-lines/layout.ts"() {
|
|
23532
|
+
"use strict";
|
|
23533
|
+
MARGIN3 = 40;
|
|
23534
|
+
CONTAINER_PAD_X3 = 30;
|
|
23535
|
+
CONTAINER_PAD_TOP2 = 40;
|
|
23536
|
+
CONTAINER_PAD_BOTTOM3 = 24;
|
|
23537
|
+
MAX_PARALLEL_EDGES = 5;
|
|
23538
|
+
PARALLEL_SPACING = 22;
|
|
23539
|
+
PHI = 1.618;
|
|
23540
|
+
NODE_HEIGHT = 60;
|
|
23541
|
+
NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
|
|
23542
|
+
DESC_NODE_WIDTH = 140;
|
|
23543
|
+
DESC_FONT_SIZE2 = 10;
|
|
23544
|
+
DESC_LINE_HEIGHT2 = 1.4;
|
|
23545
|
+
DESC_PADDING = 8;
|
|
23546
|
+
SEPARATOR_GAP5 = 4;
|
|
23547
|
+
MAX_DESC_LINES2 = 6;
|
|
23548
|
+
MAX_LABEL_LINES = 3;
|
|
23549
|
+
LABEL_LINE_HEIGHT = 1.3;
|
|
23550
|
+
LABEL_PAD = 12;
|
|
23551
|
+
elkInstance = null;
|
|
23552
|
+
CROSSINGS_FORGIVENESS = 1;
|
|
23553
|
+
}
|
|
23554
|
+
});
|
|
23555
|
+
|
|
23539
23556
|
// src/mindmap/text-wrap.ts
|
|
23540
23557
|
function tokenize(text) {
|
|
23541
23558
|
const tokens = [];
|
|
@@ -23674,7 +23691,7 @@ var layout_exports6 = {};
|
|
|
23674
23691
|
__export(layout_exports6, {
|
|
23675
23692
|
layoutMindmap: () => layoutMindmap
|
|
23676
23693
|
});
|
|
23677
|
-
function layoutMindmap(parsed,
|
|
23694
|
+
function layoutMindmap(parsed, _palette, options) {
|
|
23678
23695
|
const roots = parsed.roots;
|
|
23679
23696
|
if (roots.length === 0) {
|
|
23680
23697
|
return { nodes: [], edges: [], width: 0, height: 0 };
|
|
@@ -24570,7 +24587,7 @@ function layoutElement(el, x, y, width) {
|
|
|
24570
24587
|
node.height = getElementHeight(el);
|
|
24571
24588
|
return node;
|
|
24572
24589
|
}
|
|
24573
|
-
const isInlineRow = el.metadata
|
|
24590
|
+
const isInlineRow = el.metadata["_inlineRow"] === "true" || el.metadata["_labelField"] === "true";
|
|
24574
24591
|
const padTop = isInlineRow ? 0 : GROUP_PADDING_TOP;
|
|
24575
24592
|
const padBottom = isInlineRow ? 0 : GROUP_PADDING_BOTTOM;
|
|
24576
24593
|
const padX = isInlineRow ? 0 : GROUP_PADDING_X;
|
|
@@ -24619,7 +24636,7 @@ function allocateEqualWidths(children, totalWidth) {
|
|
|
24619
24636
|
}
|
|
24620
24637
|
function getElementHeight(el) {
|
|
24621
24638
|
if (el.type === "heading") {
|
|
24622
|
-
return el.headingLevel === 2 ? ELEMENT_HEIGHTS
|
|
24639
|
+
return el.headingLevel === 2 ? ELEMENT_HEIGHTS["subheading"] ?? 36 : ELEMENT_HEIGHTS["heading"] ?? 48;
|
|
24623
24640
|
}
|
|
24624
24641
|
if (el.type === "textInput" && el.fieldVariant === "textarea") {
|
|
24625
24642
|
return 80;
|
|
@@ -24633,16 +24650,16 @@ function getElementHeight(el) {
|
|
|
24633
24650
|
if (el.type === "image") {
|
|
24634
24651
|
if (el.imageHint === "round") return 80;
|
|
24635
24652
|
if (el.imageHint === "wide") return 80;
|
|
24636
|
-
return ELEMENT_HEIGHTS
|
|
24653
|
+
return ELEMENT_HEIGHTS["image"] ?? 120;
|
|
24637
24654
|
}
|
|
24638
|
-
if (el.metadata
|
|
24655
|
+
if (el.metadata["_labelField"] === "true") {
|
|
24639
24656
|
return 36;
|
|
24640
24657
|
}
|
|
24641
24658
|
return ELEMENT_HEIGHTS[el.type] ?? 24;
|
|
24642
24659
|
}
|
|
24643
24660
|
function getSpacingAfter(el) {
|
|
24644
24661
|
if (el.type === "heading" && el.headingLevel === 2) {
|
|
24645
|
-
return SPACING_AFTER
|
|
24662
|
+
return SPACING_AFTER["subheading"] ?? 12;
|
|
24646
24663
|
}
|
|
24647
24664
|
return SPACING_AFTER[el.type] ?? 8;
|
|
24648
24665
|
}
|
|
@@ -24650,7 +24667,7 @@ function computeFieldAlignX(children) {
|
|
|
24650
24667
|
let maxLabelWidth = 0;
|
|
24651
24668
|
let labelFieldCount = 0;
|
|
24652
24669
|
for (const child of children) {
|
|
24653
|
-
if (child.metadata
|
|
24670
|
+
if (child.metadata["_labelField"] === "true" && child.children.length >= 2) {
|
|
24654
24671
|
const labelEl = child.children[0];
|
|
24655
24672
|
const labelWidth = labelEl.label.length * CHAR_WIDTH5;
|
|
24656
24673
|
maxLabelWidth = Math.max(maxLabelWidth, labelWidth);
|
|
@@ -24862,7 +24879,7 @@ function renderNode(parent, node, ctx, depth) {
|
|
|
24862
24879
|
function renderGroup(g, node, ctx, depth) {
|
|
24863
24880
|
const { palette, isTransparent } = ctx;
|
|
24864
24881
|
const el = node.element;
|
|
24865
|
-
if (el.metadata
|
|
24882
|
+
if (el.metadata["_inlineRow"] === "true" || el.metadata["_labelField"] === "true") {
|
|
24866
24883
|
for (const child of node.children) {
|
|
24867
24884
|
renderNode(g, child, ctx, depth);
|
|
24868
24885
|
}
|
|
@@ -24990,7 +25007,7 @@ function renderDivider(g, node, ctx) {
|
|
|
24990
25007
|
function renderText(g, node, ctx) {
|
|
24991
25008
|
const { palette } = ctx;
|
|
24992
25009
|
const el = node.element;
|
|
24993
|
-
if (el.metadata
|
|
25010
|
+
if (el.metadata["_labelField"] === "true" && el.children.length >= 2) {
|
|
24994
25011
|
for (const child of node.children) {
|
|
24995
25012
|
renderNode(g, child, ctx, 0);
|
|
24996
25013
|
}
|
|
@@ -25284,7 +25301,7 @@ __export(layout_exports8, {
|
|
|
25284
25301
|
layoutC4Deployment: () => layoutC4Deployment,
|
|
25285
25302
|
rollUpContextRelationships: () => rollUpContextRelationships
|
|
25286
25303
|
});
|
|
25287
|
-
import
|
|
25304
|
+
import dagre4 from "@dagrejs/dagre";
|
|
25288
25305
|
function computeEdgePenalty(edgeList, nodePositions, degrees, nodeGeometry) {
|
|
25289
25306
|
let penalty = 0;
|
|
25290
25307
|
for (const edge of edgeList) {
|
|
@@ -25725,7 +25742,7 @@ function layoutC4Context(parsed, activeTagGroup) {
|
|
|
25725
25742
|
}
|
|
25726
25743
|
const contextRels = rollUpContextRelationships(parsed);
|
|
25727
25744
|
const spacing = computeAdaptiveSpacing(contextRels);
|
|
25728
|
-
const g = new
|
|
25745
|
+
const g = new dagre4.graphlib.Graph();
|
|
25729
25746
|
g.setGraph({
|
|
25730
25747
|
rankdir: "TB",
|
|
25731
25748
|
nodesep: spacing.nodesep,
|
|
@@ -25746,7 +25763,7 @@ function layoutC4Context(parsed, activeTagGroup) {
|
|
|
25746
25763
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
25747
25764
|
}
|
|
25748
25765
|
}
|
|
25749
|
-
|
|
25766
|
+
dagre4.layout(g);
|
|
25750
25767
|
reduceCrossings(
|
|
25751
25768
|
g,
|
|
25752
25769
|
validRels.map((r) => ({ source: r.sourceName, target: r.targetName }))
|
|
@@ -25918,7 +25935,7 @@ function layoutC4Containers(parsed, systemName, activeTagGroup) {
|
|
|
25918
25935
|
}
|
|
25919
25936
|
}
|
|
25920
25937
|
const hasGroups = elementToGroup.size > 0;
|
|
25921
|
-
const g = hasGroups ? new
|
|
25938
|
+
const g = hasGroups ? new dagre4.graphlib.Graph({ compound: true }) : new dagre4.graphlib.Graph();
|
|
25922
25939
|
g.setDefaultEdgeLabel(() => ({}));
|
|
25923
25940
|
if (hasGroups) {
|
|
25924
25941
|
const seenGroups = /* @__PURE__ */ new Set();
|
|
@@ -25996,7 +26013,7 @@ function layoutC4Containers(parsed, systemName, activeTagGroup) {
|
|
|
25996
26013
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
25997
26014
|
}
|
|
25998
26015
|
}
|
|
25999
|
-
|
|
26016
|
+
dagre4.layout(g);
|
|
26000
26017
|
const nodeGroupMap = hasGroups ? new Map([...elementToGroup.entries()].map(([k, v]) => [k, v.name])) : void 0;
|
|
26001
26018
|
reduceCrossings(
|
|
26002
26019
|
g,
|
|
@@ -26322,7 +26339,7 @@ function layoutC4Components(parsed, systemName, containerName, activeTagGroup) {
|
|
|
26322
26339
|
}
|
|
26323
26340
|
}
|
|
26324
26341
|
const hasGroups = elementToGroup.size > 0;
|
|
26325
|
-
const g = hasGroups ? new
|
|
26342
|
+
const g = hasGroups ? new dagre4.graphlib.Graph({ compound: true }) : new dagre4.graphlib.Graph();
|
|
26326
26343
|
g.setDefaultEdgeLabel(() => ({}));
|
|
26327
26344
|
if (hasGroups) {
|
|
26328
26345
|
const seenGroups = /* @__PURE__ */ new Set();
|
|
@@ -26406,7 +26423,7 @@ function layoutC4Components(parsed, systemName, containerName, activeTagGroup) {
|
|
|
26406
26423
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
26407
26424
|
}
|
|
26408
26425
|
}
|
|
26409
|
-
|
|
26426
|
+
dagre4.layout(g);
|
|
26410
26427
|
const nodeGroupMap = hasGroups ? new Map([...elementToGroup.entries()].map(([k, v]) => [k, v.name])) : void 0;
|
|
26411
26428
|
reduceCrossings(
|
|
26412
26429
|
g,
|
|
@@ -26695,7 +26712,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
26695
26712
|
for (const r of refEntries) {
|
|
26696
26713
|
nameToElement.set(r.element.name, r.element);
|
|
26697
26714
|
}
|
|
26698
|
-
const g = new
|
|
26715
|
+
const g = new dagre4.graphlib.Graph({ compound: true });
|
|
26699
26716
|
g.setDefaultEdgeLabel(() => ({}));
|
|
26700
26717
|
for (const [infraId] of infraIds) {
|
|
26701
26718
|
g.setNode(infraId, {});
|
|
@@ -26739,7 +26756,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
26739
26756
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
26740
26757
|
}
|
|
26741
26758
|
}
|
|
26742
|
-
|
|
26759
|
+
dagre4.layout(g);
|
|
26743
26760
|
const nodeInfraMap = /* @__PURE__ */ new Map();
|
|
26744
26761
|
for (const r of refEntries) nodeInfraMap.set(r.element.name, r.infraId);
|
|
26745
26762
|
reduceCrossings(
|
|
@@ -27971,7 +27988,7 @@ var layout_exports9 = {};
|
|
|
27971
27988
|
__export(layout_exports9, {
|
|
27972
27989
|
layoutGraph: () => layoutGraph
|
|
27973
27990
|
});
|
|
27974
|
-
import
|
|
27991
|
+
import dagre5 from "@dagrejs/dagre";
|
|
27975
27992
|
function computeNodeWidth(label, shape) {
|
|
27976
27993
|
if (shape === "pseudostate") return 24;
|
|
27977
27994
|
const base = Math.max(120, label.length * 9 + 40);
|
|
@@ -28004,7 +28021,7 @@ function layoutGraph(graph, options) {
|
|
|
28004
28021
|
if (allNodes.length === 0) {
|
|
28005
28022
|
return { nodes: [], edges: [], groups: [], width: 0, height: 0 };
|
|
28006
28023
|
}
|
|
28007
|
-
const g = new
|
|
28024
|
+
const g = new dagre5.graphlib.Graph({ compound: true });
|
|
28008
28025
|
g.setGraph({
|
|
28009
28026
|
rankdir: graph.direction,
|
|
28010
28027
|
nodesep: 50,
|
|
@@ -28040,7 +28057,7 @@ function layoutGraph(graph, options) {
|
|
|
28040
28057
|
label: edge.label ?? ""
|
|
28041
28058
|
});
|
|
28042
28059
|
}
|
|
28043
|
-
|
|
28060
|
+
dagre5.layout(g);
|
|
28044
28061
|
const collapsedGroupIds = collapsedChildCounts ? new Set(collapsedChildCounts.keys()) : /* @__PURE__ */ new Set();
|
|
28045
28062
|
const layoutNodes = allNodes.map((node) => {
|
|
28046
28063
|
const pos = g.node(node.id);
|
|
@@ -28474,7 +28491,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
28474
28491
|
endTerminalIds.add(node.id);
|
|
28475
28492
|
}
|
|
28476
28493
|
}
|
|
28477
|
-
const colorOff = graph.options?.color === "off";
|
|
28494
|
+
const colorOff = graph.options?.["color"] === "off";
|
|
28478
28495
|
const solid = graph.options?.["solid-fill"] === "on";
|
|
28479
28496
|
for (const node of layout.nodes) {
|
|
28480
28497
|
const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", "fc-node").attr("data-line-number", String(node.lineNumber)).attr("data-node-id", node.id);
|
|
@@ -29403,7 +29420,7 @@ __export(layout_exports10, {
|
|
|
29403
29420
|
layoutInfra: () => layoutInfra,
|
|
29404
29421
|
separateGroups: () => separateGroups
|
|
29405
29422
|
});
|
|
29406
|
-
import
|
|
29423
|
+
import dagre6 from "@dagrejs/dagre";
|
|
29407
29424
|
function countDisplayProps(node, expanded, options) {
|
|
29408
29425
|
if (!expanded) return 0;
|
|
29409
29426
|
let count = node.properties.filter((p) => DISPLAY_KEYS.has(p.key)).length;
|
|
@@ -29706,7 +29723,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
29706
29723
|
};
|
|
29707
29724
|
}
|
|
29708
29725
|
const isLR = computed.direction !== "TB";
|
|
29709
|
-
const g = new
|
|
29726
|
+
const g = new dagre6.graphlib.Graph();
|
|
29710
29727
|
g.setGraph({
|
|
29711
29728
|
rankdir: computed.direction === "TB" ? "TB" : "LR",
|
|
29712
29729
|
nodesep: isLR ? 70 : 60,
|
|
@@ -29757,7 +29774,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
29757
29774
|
g.setEdge(edge.sourceId, edge.targetId, { label: edge.label });
|
|
29758
29775
|
}
|
|
29759
29776
|
}
|
|
29760
|
-
|
|
29777
|
+
dagre6.layout(g);
|
|
29761
29778
|
const layoutNodes = computed.nodes.map((node) => {
|
|
29762
29779
|
const pos = g.node(node.id);
|
|
29763
29780
|
return {
|
|
@@ -30666,7 +30683,7 @@ function renderGroups(svg, groups, palette, _isDark) {
|
|
|
30666
30683
|
}
|
|
30667
30684
|
}
|
|
30668
30685
|
}
|
|
30669
|
-
function renderEdgePaths(svg, edges, nodes, groups, palette,
|
|
30686
|
+
function renderEdgePaths(svg, edges, nodes, groups, palette, _isDark, animate, direction, speedMultiplier = 1) {
|
|
30670
30687
|
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
30671
30688
|
const maxRps = Math.max(...edges.map((e) => e.computedRps), 1);
|
|
30672
30689
|
const { srcPts, tgtPts } = computePortPts(edges, nodeMap, direction);
|
|
@@ -30707,7 +30724,7 @@ function renderEdgePaths(svg, edges, nodes, groups, palette, isDark, animate, di
|
|
|
30707
30724
|
}
|
|
30708
30725
|
}
|
|
30709
30726
|
}
|
|
30710
|
-
function renderEdgeLabels(svg, edges, nodes, groups, palette,
|
|
30727
|
+
function renderEdgeLabels(svg, edges, nodes, groups, palette, _isDark, animate, direction) {
|
|
30711
30728
|
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
30712
30729
|
const { srcPts, tgtPts } = computePortPts(edges, nodeMap, direction);
|
|
30713
30730
|
for (const edge of edges) {
|
|
@@ -31446,7 +31463,7 @@ function sampleBetaPert(o, m, p, rng) {
|
|
|
31446
31463
|
const beta = 1 + 4 * (p - m) / range;
|
|
31447
31464
|
return o + sampleBeta(alpha, beta, rng) * range;
|
|
31448
31465
|
}
|
|
31449
|
-
function simulate(resolved, expanded,
|
|
31466
|
+
function simulate(resolved, expanded, _predecessors, _successors, topo, terminals, poisoned, opts) {
|
|
31450
31467
|
const rng = mulberry32(opts.seed);
|
|
31451
31468
|
const expById = /* @__PURE__ */ new Map();
|
|
31452
31469
|
for (const e of expanded) expById.set(e.id, e);
|
|
@@ -32459,7 +32476,7 @@ __export(layout_exports11, {
|
|
|
32459
32476
|
layoutPert: () => layoutPert,
|
|
32460
32477
|
relayoutPert: () => relayoutPert
|
|
32461
32478
|
});
|
|
32462
|
-
import
|
|
32479
|
+
import dagre7 from "@dagrejs/dagre";
|
|
32463
32480
|
function computeNodeSizing(resolved) {
|
|
32464
32481
|
const unit = resolved.options.timeUnit;
|
|
32465
32482
|
const sprintMode = resolved.options.sprintMode;
|
|
@@ -32567,7 +32584,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32567
32584
|
}
|
|
32568
32585
|
}
|
|
32569
32586
|
const dagreId = (id) => memberToGroup.get(id) ?? id;
|
|
32570
|
-
const g = new
|
|
32587
|
+
const g = new dagre7.graphlib.Graph();
|
|
32571
32588
|
g.setGraph({
|
|
32572
32589
|
rankdir: resolved.options.direction,
|
|
32573
32590
|
nodesep: 50,
|
|
@@ -32606,7 +32623,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32606
32623
|
seenEdges.add(k);
|
|
32607
32624
|
g.setEdge(src, tgt, {});
|
|
32608
32625
|
}
|
|
32609
|
-
|
|
32626
|
+
dagre7.layout(g);
|
|
32610
32627
|
const swimApplied = applySwimLanes(
|
|
32611
32628
|
g,
|
|
32612
32629
|
resolved,
|
|
@@ -32726,7 +32743,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32726
32743
|
height: totalH + DIAGRAM_PADDING10
|
|
32727
32744
|
};
|
|
32728
32745
|
}
|
|
32729
|
-
function applySwimLanes(g, resolved,
|
|
32746
|
+
function applySwimLanes(g, resolved, _memberToGroup, collapsedGroupIds) {
|
|
32730
32747
|
const expanded = resolved.groups.filter(
|
|
32731
32748
|
(rg) => !collapsedGroupIds.has(rg.group.id)
|
|
32732
32749
|
);
|
|
@@ -32952,7 +32969,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32952
32969
|
buckets.get(key).push(id);
|
|
32953
32970
|
}
|
|
32954
32971
|
const edges = g.edges().map((e) => ({ v: e.v, w: e.w }));
|
|
32955
|
-
const
|
|
32972
|
+
const countCrossings2 = () => {
|
|
32956
32973
|
let total = 0;
|
|
32957
32974
|
for (let i = 0; i < edges.length; i++) {
|
|
32958
32975
|
const a = edges[i];
|
|
@@ -32965,13 +32982,13 @@ function reduceCrossings2(g, direction) {
|
|
|
32965
32982
|
const b1 = g.node(b.v);
|
|
32966
32983
|
const b2 = g.node(b.w);
|
|
32967
32984
|
if (!b1 || !b2) continue;
|
|
32968
|
-
if (
|
|
32985
|
+
if (segmentsCross2(a1, a2, b1, b2)) total++;
|
|
32969
32986
|
}
|
|
32970
32987
|
}
|
|
32971
32988
|
return total;
|
|
32972
32989
|
};
|
|
32973
32990
|
const MAX_ITER = 8;
|
|
32974
|
-
let baseline =
|
|
32991
|
+
let baseline = countCrossings2();
|
|
32975
32992
|
if (baseline === 0) return;
|
|
32976
32993
|
for (let iter = 0; iter < MAX_ITER; iter++) {
|
|
32977
32994
|
let improved = false;
|
|
@@ -32989,7 +33006,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32989
33006
|
const bv = bn[slotAxis];
|
|
32990
33007
|
an[slotAxis] = bv;
|
|
32991
33008
|
bn[slotAxis] = av;
|
|
32992
|
-
const after =
|
|
33009
|
+
const after = countCrossings2();
|
|
32993
33010
|
if (after < baseline) {
|
|
32994
33011
|
baseline = after;
|
|
32995
33012
|
improved = true;
|
|
@@ -33010,7 +33027,7 @@ function reduceCrossings2(g, direction) {
|
|
|
33010
33027
|
data.points = smoothEdge(src, tgt, direction);
|
|
33011
33028
|
}
|
|
33012
33029
|
}
|
|
33013
|
-
function
|
|
33030
|
+
function segmentsCross2(a1, a2, b1, b2) {
|
|
33014
33031
|
const ccw = (p, q, r) => (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
|
|
33015
33032
|
const d1 = ccw(b1, b2, a1);
|
|
33016
33033
|
const d2 = ccw(b1, b2, a2);
|
|
@@ -35018,12 +35035,6 @@ function calculateSchedule(parsed) {
|
|
|
35018
35035
|
const warn = (line12, message) => {
|
|
35019
35036
|
diagnostics.push(makeDgmoError(line12, message, "warning"));
|
|
35020
35037
|
};
|
|
35021
|
-
const _fail = (line12, message) => {
|
|
35022
|
-
const diag = makeDgmoError(line12, message);
|
|
35023
|
-
diagnostics.push(diag);
|
|
35024
|
-
result.error = formatDgmoError(diag);
|
|
35025
|
-
return result;
|
|
35026
|
-
};
|
|
35027
35038
|
const holidaySet = buildHolidaySet(parsed.holidays);
|
|
35028
35039
|
let projectStart;
|
|
35029
35040
|
if (parsed.options.start) {
|
|
@@ -35048,7 +35059,6 @@ function calculateSchedule(parsed) {
|
|
|
35048
35059
|
}
|
|
35049
35060
|
buildImplicitDeps(parsed.nodes, taskMap);
|
|
35050
35061
|
for (const task of allTasks2) {
|
|
35051
|
-
const _node = taskMap.get(task.id);
|
|
35052
35062
|
for (const dep of task.dependencies) {
|
|
35053
35063
|
const resolved = resolveTaskName(dep.targetName, allTasks2);
|
|
35054
35064
|
if (isResolverError(resolved)) {
|
|
@@ -36589,7 +36599,7 @@ function buildControlsToggles(hasCriticalPath, criticalPathActive, hasDependenci
|
|
|
36589
36599
|
}
|
|
36590
36600
|
return toggles;
|
|
36591
36601
|
}
|
|
36592
|
-
function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive,
|
|
36602
|
+
function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive, _optionLineNumbers, onToggle, onToggleControlsExpand, currentSwimlaneGroup, onSwimlaneChange, legendViewMode, resolvedTasks, controlsExpanded = false, hasDependencies = false, dependenciesActive = false, onControlsToggle) {
|
|
36593
36603
|
let visibleGroups;
|
|
36594
36604
|
if (activeGroupName) {
|
|
36595
36605
|
const activeGroup = tagGroups.filter(
|
|
@@ -37552,7 +37562,7 @@ function resolveTaskColor(rt, activeTagGroup, resolved, seriesColors2, palette)
|
|
|
37552
37562
|
}
|
|
37553
37563
|
return palette.accent || seriesColors2[0] || "#4a90d9";
|
|
37554
37564
|
}
|
|
37555
|
-
function renderTimeScaleHorizontal(g, scale,
|
|
37565
|
+
function renderTimeScaleHorizontal(g, scale, _innerWidth, innerHeight, textColor) {
|
|
37556
37566
|
const [domainMin, domainMax] = scale.domain();
|
|
37557
37567
|
const ticks = computeTimeTicks(domainMin, domainMax, scale);
|
|
37558
37568
|
if (ticks.length < 2) return;
|
|
@@ -37799,7 +37809,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
|
|
|
37799
37809
|
for (const group of layout.groups) {
|
|
37800
37810
|
if (group.collapsed) collapsedGroupIds.add(group.id);
|
|
37801
37811
|
}
|
|
37802
|
-
const colorOff = graph.options?.color === "off";
|
|
37812
|
+
const colorOff = graph.options?.["color"] === "off";
|
|
37803
37813
|
const solid = graph.options?.["solid-fill"] === "on";
|
|
37804
37814
|
for (const node of layout.nodes) {
|
|
37805
37815
|
const isCollapsedGroup = collapsedGroupIds.has(node.id);
|
|
@@ -38198,7 +38208,7 @@ function renderQuadrantFocus(container, parsed, quadrantPosition, palette, isDar
|
|
|
38198
38208
|
}
|
|
38199
38209
|
}
|
|
38200
38210
|
}
|
|
38201
|
-
function renderQuarterCircle(svg, parsed, quadrant, qColor, palette, isDark, width, height, mutedColor,
|
|
38211
|
+
function renderQuarterCircle(svg, parsed, quadrant, qColor, palette, isDark, width, height, mutedColor, _tooltip, rootContainer, onClickItem) {
|
|
38202
38212
|
const padding = 8;
|
|
38203
38213
|
const size = Math.min(width - padding, height - padding);
|
|
38204
38214
|
const maxRadius = size * 0.95;
|
|
@@ -39068,7 +39078,7 @@ function estimateListingHeight(parsed) {
|
|
|
39068
39078
|
);
|
|
39069
39079
|
return LISTING_LINE_HEIGHT * (maxBlipsInQuadrant + 1) + LISTING_LINE_HEIGHT + LISTING_TOP_MARGIN;
|
|
39070
39080
|
}
|
|
39071
|
-
function createBlipPopover(container,
|
|
39081
|
+
function createBlipPopover(container, _palette, isDark) {
|
|
39072
39082
|
container.style.position = "relative";
|
|
39073
39083
|
const existing = container.querySelector(
|
|
39074
39084
|
"[data-blip-popover]"
|
|
@@ -40935,7 +40945,7 @@ function computeEdgeLabelPosition(midAngle, radius, cx, cy, lineCount, maxCharLe
|
|
|
40935
40945
|
labelAngle: best.labelAngle
|
|
40936
40946
|
};
|
|
40937
40947
|
}
|
|
40938
|
-
function fitToCanvas(nodes, edges, parsed,
|
|
40948
|
+
function fitToCanvas(nodes, edges, parsed, _cx, _cy, radius, width, height, _isClockwise) {
|
|
40939
40949
|
const PADDING3 = 30;
|
|
40940
40950
|
let contentMinX = Infinity, contentMaxX = -Infinity;
|
|
40941
40951
|
let contentMinY = Infinity, contentMaxY = -Infinity;
|
|
@@ -42445,7 +42455,7 @@ function renderPhaseBar(svg, phase, x, y, width, palette, collapsed, autoColor,
|
|
|
42445
42455
|
});
|
|
42446
42456
|
}
|
|
42447
42457
|
}
|
|
42448
|
-
function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette, surfaceBg, solid, taskDiagnostics,
|
|
42458
|
+
function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette, surfaceBg, solid, taskDiagnostics, _hasAnyDiagnostic, rowContent, onClickLine, _onMarkerDragStart) {
|
|
42449
42459
|
const rowG = svg.append("g").attr("class", "raci-task-row").attr("data-task-id", task.id).attr("data-line-number", String(task.lineNumber));
|
|
42450
42460
|
const labelX = x + 8;
|
|
42451
42461
|
const labelMaxW = labelW - 16;
|
|
@@ -43251,7 +43261,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
43251
43261
|
const messages = collapsed ? collapsed.messages : parsed.messages;
|
|
43252
43262
|
const elements = collapsed ? collapsed.elements : parsed.elements;
|
|
43253
43263
|
const groups = collapsed ? collapsed.groups : parsed.groups;
|
|
43254
|
-
const collapsedGroupIds = collapsed?.collapsedGroupIds ?? /* @__PURE__ */ new Map();
|
|
43255
43264
|
const collapsedSections = options?.collapsedSections;
|
|
43256
43265
|
const sourceParticipants = collapsed ? collapsed.participants : parsed.participants;
|
|
43257
43266
|
const participants = applyPositionOverrides(
|
|
@@ -43279,7 +43288,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
43279
43288
|
return Math.min(NOTE_MAX_W, laneMax);
|
|
43280
43289
|
};
|
|
43281
43290
|
const charsForWidth = (maxW) => Math.floor((maxW - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W);
|
|
43282
|
-
const activationsOff = parsedOptions
|
|
43291
|
+
const activationsOff = parsedOptions["activations"]?.toLowerCase() === "off";
|
|
43283
43292
|
const activeTagGroup = resolveActiveTagGroup(
|
|
43284
43293
|
parsed.tagGroups,
|
|
43285
43294
|
parsedOptions["active-tag"],
|
|
@@ -46235,7 +46244,7 @@ function renderTimelineGroupLegend(g, groups, groupColorMap, textColor, palette,
|
|
|
46235
46244
|
legendX += pillW + GAP;
|
|
46236
46245
|
}
|
|
46237
46246
|
}
|
|
46238
|
-
function
|
|
46247
|
+
function setupTimeline(container, parsed, palette, isDark, exportDims, activeTagGroup, swimlaneTagGroup) {
|
|
46239
46248
|
d3Selection22.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
46240
46249
|
const solid = parsed.solidFill === true;
|
|
46241
46250
|
const {
|
|
@@ -46244,19 +46253,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46244
46253
|
timelineEras,
|
|
46245
46254
|
timelineMarkers,
|
|
46246
46255
|
timelineSort,
|
|
46247
|
-
timelineScale,
|
|
46248
|
-
timelineSwimlanes,
|
|
46249
46256
|
orientation
|
|
46250
46257
|
} = parsed;
|
|
46251
|
-
|
|
46252
|
-
|
|
46253
|
-
if (
|
|
46254
|
-
|
|
46258
|
+
if (timelineEvents.length === 0) return null;
|
|
46259
|
+
let resolvedSwimlaneTG = swimlaneTagGroup ?? null;
|
|
46260
|
+
if (resolvedSwimlaneTG == null && timelineSort === "tag" && parsed.timelineDefaultSwimlaneTG) {
|
|
46261
|
+
resolvedSwimlaneTG = parsed.timelineDefaultSwimlaneTG;
|
|
46255
46262
|
}
|
|
46256
46263
|
const tooltip = createTooltip2(container, palette, isDark);
|
|
46257
46264
|
const width = exportDims?.width ?? container.clientWidth;
|
|
46258
46265
|
const height = exportDims?.height ?? container.clientHeight;
|
|
46259
|
-
if (width <= 0 || height <= 0) return;
|
|
46266
|
+
if (width <= 0 || height <= 0) return null;
|
|
46260
46267
|
const isVertical = orientation === "vertical";
|
|
46261
46268
|
const textColor = palette.text;
|
|
46262
46269
|
const mutedColor = palette.border;
|
|
@@ -46268,8 +46275,8 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46268
46275
|
groupColorMap.set(grp.name, grp.color ?? colors[i % colors.length]);
|
|
46269
46276
|
});
|
|
46270
46277
|
let tagLanes = null;
|
|
46271
|
-
if (
|
|
46272
|
-
const tagKey =
|
|
46278
|
+
if (resolvedSwimlaneTG) {
|
|
46279
|
+
const tagKey = resolvedSwimlaneTG.toLowerCase();
|
|
46273
46280
|
const tagGroup = parsed.timelineTagGroups.find(
|
|
46274
46281
|
(g) => g.name.toLowerCase() === tagKey
|
|
46275
46282
|
);
|
|
@@ -46300,7 +46307,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46300
46307
|
}
|
|
46301
46308
|
}
|
|
46302
46309
|
}
|
|
46303
|
-
const effectiveColorTG = activeTagGroup ??
|
|
46310
|
+
const effectiveColorTG = activeTagGroup ?? resolvedSwimlaneTG ?? null;
|
|
46304
46311
|
function eventColor(ev) {
|
|
46305
46312
|
if (effectiveColorTG) {
|
|
46306
46313
|
const tagColor = resolveTagColor(
|
|
@@ -46356,6 +46363,30 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46356
46363
|
}
|
|
46357
46364
|
}
|
|
46358
46365
|
const datePadding = (maxDate - minDate) * 0.05 || 0.5;
|
|
46366
|
+
const tagLegendReserve = parsed.timelineTagGroups.length > 0 ? 36 : 0;
|
|
46367
|
+
return {
|
|
46368
|
+
width,
|
|
46369
|
+
height,
|
|
46370
|
+
isVertical,
|
|
46371
|
+
tooltip,
|
|
46372
|
+
solid,
|
|
46373
|
+
textColor,
|
|
46374
|
+
mutedColor,
|
|
46375
|
+
bgColor,
|
|
46376
|
+
bg,
|
|
46377
|
+
swimlaneTagGroup: resolvedSwimlaneTG,
|
|
46378
|
+
groupColorMap,
|
|
46379
|
+
tagLanes,
|
|
46380
|
+
eventColor,
|
|
46381
|
+
minDate,
|
|
46382
|
+
maxDate,
|
|
46383
|
+
datePadding,
|
|
46384
|
+
earliestStartDateStr,
|
|
46385
|
+
latestEndDateStr,
|
|
46386
|
+
tagLegendReserve
|
|
46387
|
+
};
|
|
46388
|
+
}
|
|
46389
|
+
function makeTimelineHoverHelpers() {
|
|
46359
46390
|
const FADE_OPACITY3 = 0.1;
|
|
46360
46391
|
function fadeToGroup(g, groupName) {
|
|
46361
46392
|
g.selectAll(".tl-event").each(function() {
|
|
@@ -46455,337 +46486,683 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46455
46486
|
evG.attr(`data-tag-${key}`, value.toLowerCase());
|
|
46456
46487
|
}
|
|
46457
46488
|
}
|
|
46458
|
-
|
|
46459
|
-
|
|
46460
|
-
|
|
46461
|
-
|
|
46462
|
-
|
|
46463
|
-
|
|
46464
|
-
|
|
46465
|
-
|
|
46466
|
-
|
|
46467
|
-
|
|
46468
|
-
|
|
46469
|
-
|
|
46470
|
-
|
|
46471
|
-
|
|
46472
|
-
|
|
46473
|
-
|
|
46474
|
-
|
|
46475
|
-
|
|
46476
|
-
|
|
46477
|
-
|
|
46478
|
-
|
|
46479
|
-
|
|
46480
|
-
|
|
46489
|
+
return {
|
|
46490
|
+
FADE_OPACITY: FADE_OPACITY3,
|
|
46491
|
+
fadeToGroup,
|
|
46492
|
+
fadeToEra,
|
|
46493
|
+
fadeToMarker,
|
|
46494
|
+
fadeReset,
|
|
46495
|
+
fadeToTagValue,
|
|
46496
|
+
setTagAttrs
|
|
46497
|
+
};
|
|
46498
|
+
}
|
|
46499
|
+
function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, swimlaneTagGroup, activeTagGroup, onTagStateChange, viewMode) {
|
|
46500
|
+
if (parsed.timelineTagGroups.length === 0) return;
|
|
46501
|
+
const { width, textColor, groupColorMap, solid } = setup;
|
|
46502
|
+
const { FADE_OPACITY: FADE_OPACITY3, fadeReset, fadeToTagValue } = hovers;
|
|
46503
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46504
|
+
const { timelineEvents } = parsed;
|
|
46505
|
+
const LG_HEIGHT = LEGEND_HEIGHT;
|
|
46506
|
+
const LG_PILL_PAD = LEGEND_PILL_PAD;
|
|
46507
|
+
const LG_PILL_FONT_SIZE = LEGEND_PILL_FONT_SIZE;
|
|
46508
|
+
const LG_CAPSULE_PAD = LEGEND_CAPSULE_PAD;
|
|
46509
|
+
const LG_DOT_R = LEGEND_DOT_R;
|
|
46510
|
+
const LG_ENTRY_FONT_SIZE = LEGEND_ENTRY_FONT_SIZE;
|
|
46511
|
+
const LG_ENTRY_DOT_GAP = LEGEND_ENTRY_DOT_GAP;
|
|
46512
|
+
const LG_ENTRY_TRAIL = LEGEND_ENTRY_TRAIL;
|
|
46513
|
+
const LG_ICON_W = 20;
|
|
46514
|
+
const mainSvg = d3Selection22.select(container).select("svg");
|
|
46515
|
+
const mainG = mainSvg.select("g");
|
|
46516
|
+
if (!mainSvg.empty() && !mainG.empty()) {
|
|
46517
|
+
let drawSwimlaneIcon4 = function(parent, x, y, isSwimActive) {
|
|
46518
|
+
const iconG = parent.append("g").attr("class", "tl-swimlane-icon").attr("transform", `translate(${x}, ${y})`).style("cursor", "pointer");
|
|
46519
|
+
const barColor = isSwimActive ? palette.primary : palette.textMuted;
|
|
46520
|
+
const barOpacity = isSwimActive ? 1 : 0.35;
|
|
46521
|
+
const bars = [
|
|
46522
|
+
{ y: 0, w: 8 },
|
|
46523
|
+
{ y: 4, w: 12 },
|
|
46524
|
+
{ y: 8, w: 6 }
|
|
46525
|
+
];
|
|
46526
|
+
for (const bar of bars) {
|
|
46527
|
+
iconG.append("rect").attr("x", 0).attr("y", bar.y).attr("width", bar.w).attr("height", 2).attr("rx", 1).attr("fill", barColor).attr("opacity", barOpacity);
|
|
46481
46528
|
}
|
|
46482
|
-
|
|
46483
|
-
|
|
46484
|
-
|
|
46485
|
-
|
|
46486
|
-
|
|
46487
|
-
|
|
46488
|
-
|
|
46489
|
-
|
|
46490
|
-
|
|
46491
|
-
|
|
46492
|
-
|
|
46493
|
-
|
|
46494
|
-
|
|
46495
|
-
const svg = d3Selection22.select(container).append("svg").attr("viewBox", `0 0 ${width} ${height}`).attr("width", exportDims ? width : "100%").attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
46496
|
-
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46497
|
-
renderChartTitle(
|
|
46498
|
-
svg,
|
|
46499
|
-
title,
|
|
46500
|
-
parsed.titleLineNumber,
|
|
46501
|
-
width,
|
|
46502
|
-
textColor,
|
|
46503
|
-
onClickItem
|
|
46504
|
-
);
|
|
46505
|
-
renderEras(
|
|
46506
|
-
g,
|
|
46507
|
-
timelineEras,
|
|
46508
|
-
yScale,
|
|
46509
|
-
true,
|
|
46510
|
-
innerWidth,
|
|
46511
|
-
innerHeight,
|
|
46512
|
-
(s, e) => fadeToEra(g, s, e),
|
|
46513
|
-
() => fadeReset(g),
|
|
46514
|
-
timelineScale,
|
|
46515
|
-
tooltip,
|
|
46516
|
-
palette
|
|
46517
|
-
);
|
|
46518
|
-
renderMarkers(
|
|
46519
|
-
g,
|
|
46520
|
-
timelineMarkers,
|
|
46521
|
-
yScale,
|
|
46522
|
-
true,
|
|
46523
|
-
innerWidth,
|
|
46524
|
-
innerHeight,
|
|
46525
|
-
(d) => fadeToMarker(g, d),
|
|
46526
|
-
() => fadeReset(g),
|
|
46527
|
-
timelineScale,
|
|
46528
|
-
tooltip,
|
|
46529
|
-
palette
|
|
46529
|
+
return iconG;
|
|
46530
|
+
}, relayout2 = function() {
|
|
46531
|
+
renderTimeline(
|
|
46532
|
+
container,
|
|
46533
|
+
parsed,
|
|
46534
|
+
palette,
|
|
46535
|
+
isDark,
|
|
46536
|
+
onClickItem,
|
|
46537
|
+
exportDims,
|
|
46538
|
+
currentActiveGroup,
|
|
46539
|
+
currentSwimlaneGroup,
|
|
46540
|
+
onTagStateChange,
|
|
46541
|
+
viewMode
|
|
46530
46542
|
);
|
|
46531
|
-
|
|
46532
|
-
|
|
46533
|
-
|
|
46534
|
-
|
|
46535
|
-
|
|
46536
|
-
|
|
46537
|
-
|
|
46538
|
-
|
|
46539
|
-
|
|
46540
|
-
|
|
46541
|
-
|
|
46542
|
-
|
|
46543
|
+
}, drawLegend2 = function() {
|
|
46544
|
+
mainSvg.selectAll(".tl-tag-legend-group").remove();
|
|
46545
|
+
mainSvg.selectAll(".tl-tag-legend-container").remove();
|
|
46546
|
+
const effectiveColorKey = (currentActiveGroup ?? currentSwimlaneGroup)?.toLowerCase() ?? null;
|
|
46547
|
+
const visibleGroups = viewMode ? legendGroups.filter(
|
|
46548
|
+
(lg) => effectiveColorKey != null && lg.group.name.toLowerCase() === effectiveColorKey
|
|
46549
|
+
) : legendGroups;
|
|
46550
|
+
if (visibleGroups.length === 0) return;
|
|
46551
|
+
const legendContainer = mainSvg.append("g").attr("class", "tl-tag-legend-container");
|
|
46552
|
+
if (currentActiveGroup) {
|
|
46553
|
+
legendContainer.attr(
|
|
46554
|
+
"data-legend-active",
|
|
46555
|
+
currentActiveGroup.toLowerCase()
|
|
46543
46556
|
);
|
|
46544
46557
|
}
|
|
46545
|
-
|
|
46546
|
-
|
|
46547
|
-
|
|
46548
|
-
|
|
46549
|
-
|
|
46550
|
-
|
|
46551
|
-
|
|
46552
|
-
|
|
46553
|
-
|
|
46554
|
-
|
|
46555
|
-
|
|
46556
|
-
|
|
46557
|
-
|
|
46558
|
-
|
|
46559
|
-
|
|
46560
|
-
|
|
46561
|
-
|
|
46562
|
-
|
|
46563
|
-
|
|
46564
|
-
|
|
46565
|
-
|
|
46566
|
-
|
|
46567
|
-
|
|
46568
|
-
|
|
46569
|
-
|
|
46570
|
-
|
|
46571
|
-
|
|
46572
|
-
|
|
46573
|
-
|
|
46574
|
-
|
|
46575
|
-
|
|
46576
|
-
|
|
46577
|
-
|
|
46578
|
-
|
|
46579
|
-
|
|
46580
|
-
|
|
46581
|
-
|
|
46582
|
-
let stroke2 = evColor;
|
|
46583
|
-
if (ev.uncertain) {
|
|
46584
|
-
const gradientId = `uncertain-vg-${ev.lineNumber}`;
|
|
46585
|
-
const strokeGradientId = `uncertain-vg-s-${ev.lineNumber}`;
|
|
46586
|
-
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46587
|
-
const defsEl = d3Selection22.select(defs);
|
|
46588
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46589
|
-
{ offset: "0%", opacity: 1 },
|
|
46590
|
-
{ offset: "80%", opacity: 1 },
|
|
46591
|
-
{ offset: "100%", opacity: 0 }
|
|
46592
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
46593
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46594
|
-
{ offset: "0%", opacity: 1 },
|
|
46595
|
-
{ offset: "80%", opacity: 1 },
|
|
46596
|
-
{ offset: "100%", opacity: 0 }
|
|
46597
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", evColor).attr("stop-opacity", (d) => d.opacity);
|
|
46598
|
-
fill2 = `url(#${gradientId})`;
|
|
46599
|
-
stroke2 = `url(#${strokeGradientId})`;
|
|
46600
|
-
}
|
|
46601
|
-
evG.append("rect").attr("x", laneCenter - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
46602
|
-
evG.append("text").attr("x", laneCenter + 14).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
|
|
46558
|
+
const iconAddon = viewMode ? 0 : LG_ICON_W;
|
|
46559
|
+
const centralGroups = visibleGroups.map((lg) => ({
|
|
46560
|
+
name: lg.group.name,
|
|
46561
|
+
entries: lg.group.entries.map((e) => ({
|
|
46562
|
+
value: e.value,
|
|
46563
|
+
color: e.color
|
|
46564
|
+
}))
|
|
46565
|
+
}));
|
|
46566
|
+
const centralActive = viewMode ? effectiveColorKey : currentActiveGroup;
|
|
46567
|
+
const centralConfig = {
|
|
46568
|
+
groups: centralGroups,
|
|
46569
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
46570
|
+
mode: "fixed",
|
|
46571
|
+
capsulePillAddonWidth: iconAddon
|
|
46572
|
+
};
|
|
46573
|
+
const centralState = { activeGroup: centralActive };
|
|
46574
|
+
const centralCallbacks = viewMode ? {} : {
|
|
46575
|
+
onGroupToggle: (groupName) => {
|
|
46576
|
+
currentActiveGroup = currentActiveGroup === groupName.toLowerCase() ? null : groupName.toLowerCase();
|
|
46577
|
+
drawLegend2();
|
|
46578
|
+
recolorEvents2();
|
|
46579
|
+
onTagStateChange?.(currentActiveGroup, currentSwimlaneGroup);
|
|
46580
|
+
},
|
|
46581
|
+
onEntryHover: (groupName, entryValue) => {
|
|
46582
|
+
const tagKey = groupName.toLowerCase();
|
|
46583
|
+
if (entryValue) {
|
|
46584
|
+
const tagVal = entryValue.toLowerCase();
|
|
46585
|
+
fadeToTagValue(mainG, tagKey, tagVal);
|
|
46586
|
+
mainSvg.selectAll("[data-legend-entry]").each(function() {
|
|
46587
|
+
const el = d3Selection22.select(this);
|
|
46588
|
+
const ev = el.attr("data-legend-entry");
|
|
46589
|
+
const eg = el.attr("data-tag-group") ?? el.node()?.closest?.("[data-tag-group]")?.getAttribute("data-tag-group");
|
|
46590
|
+
el.attr(
|
|
46591
|
+
"opacity",
|
|
46592
|
+
eg === tagKey && ev === tagVal ? 1 : FADE_OPACITY3
|
|
46593
|
+
);
|
|
46594
|
+
});
|
|
46603
46595
|
} else {
|
|
46604
|
-
|
|
46605
|
-
|
|
46596
|
+
fadeReset(mainG);
|
|
46597
|
+
mainSvg.selectAll("[data-legend-entry]").attr("opacity", 1);
|
|
46598
|
+
}
|
|
46599
|
+
},
|
|
46600
|
+
onGroupRendered: (groupName, groupEl, isActive) => {
|
|
46601
|
+
const groupKey = groupName.toLowerCase();
|
|
46602
|
+
groupEl.attr("data-tag-group", groupKey);
|
|
46603
|
+
if (isActive && !viewMode) {
|
|
46604
|
+
const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
|
|
46605
|
+
const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
46606
|
+
const pillXOff = LG_CAPSULE_PAD;
|
|
46607
|
+
const iconX = pillXOff + pillWidth3 + 5;
|
|
46608
|
+
const iconY = (LG_HEIGHT - 10) / 2;
|
|
46609
|
+
const iconEl = drawSwimlaneIcon4(
|
|
46610
|
+
groupEl,
|
|
46611
|
+
iconX,
|
|
46612
|
+
iconY,
|
|
46613
|
+
isSwimActive
|
|
46614
|
+
);
|
|
46615
|
+
iconEl.attr("data-swimlane-toggle", groupKey).on("click", (event) => {
|
|
46616
|
+
event.stopPropagation();
|
|
46617
|
+
currentSwimlaneGroup = currentSwimlaneGroup === groupKey ? null : groupKey;
|
|
46618
|
+
onTagStateChange?.(
|
|
46619
|
+
currentActiveGroup,
|
|
46620
|
+
currentSwimlaneGroup
|
|
46621
|
+
);
|
|
46622
|
+
relayout2();
|
|
46623
|
+
});
|
|
46606
46624
|
}
|
|
46607
46625
|
}
|
|
46608
|
-
});
|
|
46609
|
-
} else {
|
|
46610
|
-
const scaleMargin = timelineScale ? 40 : 0;
|
|
46611
|
-
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46612
|
-
const margin = {
|
|
46613
|
-
top: 104 + markerMargin + tagLegendReserve,
|
|
46614
|
-
right: 200,
|
|
46615
|
-
bottom: 40,
|
|
46616
|
-
left: 60 + scaleMargin
|
|
46617
46626
|
};
|
|
46618
|
-
const
|
|
46619
|
-
|
|
46620
|
-
|
|
46621
|
-
|
|
46622
|
-
|
|
46623
|
-
|
|
46624
|
-
|
|
46625
|
-
|
|
46626
|
-
|
|
46627
|
-
title,
|
|
46628
|
-
parsed.titleLineNumber,
|
|
46629
|
-
width,
|
|
46630
|
-
textColor,
|
|
46631
|
-
onClickItem
|
|
46632
|
-
);
|
|
46633
|
-
renderEras(
|
|
46634
|
-
g,
|
|
46635
|
-
timelineEras,
|
|
46636
|
-
yScale,
|
|
46637
|
-
true,
|
|
46638
|
-
innerWidth,
|
|
46639
|
-
innerHeight,
|
|
46640
|
-
(s, e) => fadeToEra(g, s, e),
|
|
46641
|
-
() => fadeReset(g),
|
|
46642
|
-
timelineScale,
|
|
46643
|
-
tooltip,
|
|
46644
|
-
palette
|
|
46645
|
-
);
|
|
46646
|
-
renderMarkers(
|
|
46647
|
-
g,
|
|
46648
|
-
timelineMarkers,
|
|
46649
|
-
yScale,
|
|
46650
|
-
true,
|
|
46651
|
-
innerWidth,
|
|
46652
|
-
innerHeight,
|
|
46653
|
-
(d) => fadeToMarker(g, d),
|
|
46654
|
-
() => fadeReset(g),
|
|
46655
|
-
timelineScale,
|
|
46656
|
-
tooltip,
|
|
46657
|
-
palette
|
|
46627
|
+
const legendInnerG = legendContainer.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
46628
|
+
renderLegendD3(
|
|
46629
|
+
legendInnerG,
|
|
46630
|
+
centralConfig,
|
|
46631
|
+
centralState,
|
|
46632
|
+
palette,
|
|
46633
|
+
isDark,
|
|
46634
|
+
centralCallbacks,
|
|
46635
|
+
width
|
|
46658
46636
|
);
|
|
46637
|
+
}, recolorEvents2 = function() {
|
|
46638
|
+
const colorTG = currentActiveGroup ?? swimlaneTagGroup ?? null;
|
|
46639
|
+
mainG.selectAll(".tl-event").each(function() {
|
|
46640
|
+
const el = d3Selection22.select(this);
|
|
46641
|
+
const lineNum = el.attr("data-line-number");
|
|
46642
|
+
const ev = lineNum ? eventByLine.get(lineNum) : void 0;
|
|
46643
|
+
if (!ev) return;
|
|
46644
|
+
let color;
|
|
46645
|
+
if (colorTG) {
|
|
46646
|
+
const tagColor = resolveTagColor(
|
|
46647
|
+
ev.metadata,
|
|
46648
|
+
parsed.timelineTagGroups,
|
|
46649
|
+
colorTG
|
|
46650
|
+
);
|
|
46651
|
+
color = tagColor ?? (ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor);
|
|
46652
|
+
} else {
|
|
46653
|
+
color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
|
|
46654
|
+
}
|
|
46655
|
+
el.selectAll("rect").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
46656
|
+
el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
46657
|
+
});
|
|
46658
|
+
};
|
|
46659
|
+
var drawSwimlaneIcon3 = drawSwimlaneIcon4, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
|
|
46660
|
+
const legendY = title ? 50 : 10;
|
|
46661
|
+
const legendGroups = parsed.timelineTagGroups.map((g) => {
|
|
46662
|
+
const pillW = measureLegendText(g.name, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
46663
|
+
const iconSpace = viewMode ? 8 : LG_ICON_W + 4;
|
|
46664
|
+
let entryX = LG_CAPSULE_PAD + pillW + iconSpace;
|
|
46665
|
+
for (const entry of g.entries) {
|
|
46666
|
+
const textX = entryX + LG_DOT_R * 2 + LG_ENTRY_DOT_GAP;
|
|
46667
|
+
entryX = textX + measureLegendText(entry.value, LG_ENTRY_FONT_SIZE) + LG_ENTRY_TRAIL;
|
|
46668
|
+
}
|
|
46669
|
+
return {
|
|
46670
|
+
group: g,
|
|
46671
|
+
minifiedWidth: pillW,
|
|
46672
|
+
expandedWidth: entryX + LG_CAPSULE_PAD
|
|
46673
|
+
};
|
|
46674
|
+
});
|
|
46675
|
+
let currentActiveGroup = activeTagGroup ?? null;
|
|
46676
|
+
let currentSwimlaneGroup = swimlaneTagGroup ?? null;
|
|
46677
|
+
const eventByLine = /* @__PURE__ */ new Map();
|
|
46678
|
+
for (const ev of timelineEvents) {
|
|
46679
|
+
eventByLine.set(String(ev.lineNumber), ev);
|
|
46680
|
+
}
|
|
46681
|
+
drawLegend2();
|
|
46682
|
+
}
|
|
46683
|
+
}
|
|
46684
|
+
function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
46685
|
+
const {
|
|
46686
|
+
width,
|
|
46687
|
+
height,
|
|
46688
|
+
tooltip,
|
|
46689
|
+
solid,
|
|
46690
|
+
textColor,
|
|
46691
|
+
bgColor,
|
|
46692
|
+
bg,
|
|
46693
|
+
groupColorMap,
|
|
46694
|
+
eventColor,
|
|
46695
|
+
minDate,
|
|
46696
|
+
maxDate,
|
|
46697
|
+
datePadding,
|
|
46698
|
+
earliestStartDateStr,
|
|
46699
|
+
latestEndDateStr,
|
|
46700
|
+
tagLegendReserve
|
|
46701
|
+
} = setup;
|
|
46702
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
46703
|
+
const {
|
|
46704
|
+
timelineEvents,
|
|
46705
|
+
timelineGroups,
|
|
46706
|
+
timelineEras,
|
|
46707
|
+
timelineMarkers,
|
|
46708
|
+
timelineScale
|
|
46709
|
+
} = parsed;
|
|
46710
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46711
|
+
const BAR_H2 = 22;
|
|
46712
|
+
const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
|
|
46713
|
+
const scaleMargin = timelineScale ? 24 : 0;
|
|
46714
|
+
const ERA_ROW_H = 22;
|
|
46715
|
+
const MARKER_ROW_H = 22;
|
|
46716
|
+
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46717
|
+
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46718
|
+
const topScaleH = timelineScale ? 40 : 0;
|
|
46719
|
+
const margin = {
|
|
46720
|
+
top: 104 + topScaleH + eraReserve + markerReserve + tagLegendReserve,
|
|
46721
|
+
right: 40,
|
|
46722
|
+
bottom: 40 + scaleMargin,
|
|
46723
|
+
left: 60
|
|
46724
|
+
};
|
|
46725
|
+
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46726
|
+
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46727
|
+
const innerWidth = width - margin.left - margin.right;
|
|
46728
|
+
const innerHeight = height - margin.top - margin.bottom;
|
|
46729
|
+
const rowH = Math.min(28, innerHeight / sorted.length);
|
|
46730
|
+
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
46731
|
+
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
46732
|
+
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46733
|
+
renderChartTitle(
|
|
46734
|
+
svg,
|
|
46735
|
+
title,
|
|
46736
|
+
parsed.titleLineNumber,
|
|
46737
|
+
width,
|
|
46738
|
+
textColor,
|
|
46739
|
+
onClickItem
|
|
46740
|
+
);
|
|
46741
|
+
renderEras(
|
|
46742
|
+
g,
|
|
46743
|
+
timelineEras,
|
|
46744
|
+
xScale,
|
|
46745
|
+
false,
|
|
46746
|
+
innerWidth,
|
|
46747
|
+
innerHeight,
|
|
46748
|
+
(s, e) => fadeToEra(g, s, e),
|
|
46749
|
+
() => fadeReset(g),
|
|
46750
|
+
timelineScale,
|
|
46751
|
+
tooltip,
|
|
46752
|
+
palette,
|
|
46753
|
+
eraReserve ? eraLabelY : void 0
|
|
46754
|
+
);
|
|
46755
|
+
renderMarkers(
|
|
46756
|
+
g,
|
|
46757
|
+
timelineMarkers,
|
|
46758
|
+
xScale,
|
|
46759
|
+
false,
|
|
46760
|
+
innerWidth,
|
|
46761
|
+
innerHeight,
|
|
46762
|
+
(d) => fadeToMarker(g, d),
|
|
46763
|
+
() => fadeReset(g),
|
|
46764
|
+
timelineScale,
|
|
46765
|
+
tooltip,
|
|
46766
|
+
palette,
|
|
46767
|
+
markerReserve ? markerLabelY : void 0
|
|
46768
|
+
);
|
|
46769
|
+
if (timelineScale) {
|
|
46770
|
+
renderTimeScale(
|
|
46771
|
+
g,
|
|
46772
|
+
xScale,
|
|
46773
|
+
false,
|
|
46774
|
+
innerWidth,
|
|
46775
|
+
innerHeight,
|
|
46776
|
+
textColor,
|
|
46777
|
+
minDate,
|
|
46778
|
+
maxDate,
|
|
46779
|
+
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46780
|
+
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46781
|
+
);
|
|
46782
|
+
}
|
|
46783
|
+
if (timelineGroups.length > 0) {
|
|
46784
|
+
const legendY = timelineScale ? -75 : -55;
|
|
46785
|
+
renderTimelineGroupLegend(
|
|
46786
|
+
g,
|
|
46787
|
+
timelineGroups,
|
|
46788
|
+
groupColorMap,
|
|
46789
|
+
textColor,
|
|
46790
|
+
palette,
|
|
46791
|
+
isDark,
|
|
46792
|
+
legendY,
|
|
46793
|
+
(name) => fadeToGroup(g, name),
|
|
46794
|
+
() => fadeReset(g)
|
|
46795
|
+
);
|
|
46796
|
+
}
|
|
46797
|
+
sorted.forEach((ev, i) => {
|
|
46798
|
+
const y = i * rowH + rowH / 2;
|
|
46799
|
+
const x = xScale(parseTimelineDate(ev.date));
|
|
46800
|
+
const color = eventColor(ev);
|
|
46801
|
+
const evG = g.append("g").attr("class", "tl-event").attr("data-group", ev.group || "").attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
46802
|
+
"data-end-date",
|
|
46803
|
+
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
46804
|
+
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
46805
|
+
if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);
|
|
46659
46806
|
if (timelineScale) {
|
|
46660
|
-
|
|
46807
|
+
showEventDatesOnScale(
|
|
46661
46808
|
g,
|
|
46662
|
-
|
|
46663
|
-
|
|
46664
|
-
|
|
46809
|
+
xScale,
|
|
46810
|
+
ev.date,
|
|
46811
|
+
ev.endDate,
|
|
46665
46812
|
innerHeight,
|
|
46666
|
-
|
|
46667
|
-
minDate,
|
|
46668
|
-
maxDate,
|
|
46669
|
-
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46670
|
-
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46813
|
+
color
|
|
46671
46814
|
);
|
|
46815
|
+
} else {
|
|
46816
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46672
46817
|
}
|
|
46673
|
-
|
|
46674
|
-
|
|
46675
|
-
|
|
46676
|
-
|
|
46677
|
-
|
|
46678
|
-
|
|
46679
|
-
palette,
|
|
46680
|
-
isDark,
|
|
46681
|
-
-55,
|
|
46682
|
-
(name) => fadeToGroup(g, name),
|
|
46683
|
-
() => fadeReset(g)
|
|
46684
|
-
);
|
|
46818
|
+
}).on("mouseleave", function() {
|
|
46819
|
+
fadeReset(g);
|
|
46820
|
+
if (timelineScale) {
|
|
46821
|
+
hideEventDatesOnScale(g);
|
|
46822
|
+
} else {
|
|
46823
|
+
hideTooltip(tooltip);
|
|
46685
46824
|
}
|
|
46686
|
-
|
|
46687
|
-
|
|
46688
|
-
|
|
46689
|
-
|
|
46690
|
-
|
|
46691
|
-
|
|
46692
|
-
|
|
46693
|
-
|
|
46694
|
-
|
|
46825
|
+
}).on("mousemove", function(event) {
|
|
46826
|
+
if (!timelineScale) {
|
|
46827
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46828
|
+
}
|
|
46829
|
+
}).on("click", () => {
|
|
46830
|
+
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
46831
|
+
});
|
|
46832
|
+
setTagAttrs(evG, ev);
|
|
46833
|
+
if (ev.endDate) {
|
|
46834
|
+
const x2 = xScale(parseTimelineDate(ev.endDate));
|
|
46835
|
+
const rectW = Math.max(x2 - x, 4);
|
|
46836
|
+
const estLabelWidth = ev.label.length * 7 + 16;
|
|
46837
|
+
const labelFitsInside = rectW >= estLabelWidth;
|
|
46838
|
+
let fill2 = shapeFill(palette, color, isDark, { solid });
|
|
46839
|
+
let stroke2 = color;
|
|
46840
|
+
if (ev.uncertain) {
|
|
46841
|
+
const gradientId = `uncertain-ts-${ev.lineNumber}`;
|
|
46842
|
+
const strokeGradientId = `uncertain-ts-s-${ev.lineNumber}`;
|
|
46843
|
+
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46844
|
+
const defsEl = d3Selection22.select(defs);
|
|
46845
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
46846
|
+
{ offset: "0%", opacity: 1 },
|
|
46847
|
+
{ offset: "80%", opacity: 1 },
|
|
46848
|
+
{ offset: "100%", opacity: 0 }
|
|
46849
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
46850
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
46851
|
+
{ offset: "0%", opacity: 1 },
|
|
46852
|
+
{ offset: "80%", opacity: 1 },
|
|
46853
|
+
{ offset: "100%", opacity: 0 }
|
|
46854
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", color).attr("stop-opacity", (d) => d.opacity);
|
|
46855
|
+
fill2 = `url(#${gradientId})`;
|
|
46856
|
+
stroke2 = `url(#${strokeGradientId})`;
|
|
46857
|
+
}
|
|
46858
|
+
evG.append("rect").attr("x", x).attr("y", y - BAR_H2 / 2).attr("width", rectW).attr("height", BAR_H2).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
46859
|
+
if (labelFitsInside) {
|
|
46860
|
+
evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46861
|
+
} else {
|
|
46862
|
+
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
46863
|
+
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
46864
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46865
|
+
evG.append("text").attr("x", flipLeft ? x - 6 : x + rectW + 6).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46866
|
+
}
|
|
46867
|
+
} else {
|
|
46868
|
+
const estLabelWidth = ev.label.length * 7;
|
|
46869
|
+
const wouldFlipLeft = x > innerWidth * 0.6;
|
|
46870
|
+
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
46871
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46872
|
+
evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color).attr("stroke-width", 2);
|
|
46873
|
+
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
46874
|
+
}
|
|
46875
|
+
});
|
|
46876
|
+
}
|
|
46877
|
+
function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
46878
|
+
const {
|
|
46879
|
+
width,
|
|
46880
|
+
height,
|
|
46881
|
+
tooltip,
|
|
46882
|
+
solid,
|
|
46883
|
+
textColor,
|
|
46884
|
+
bgColor,
|
|
46885
|
+
bg,
|
|
46886
|
+
groupColorMap,
|
|
46887
|
+
tagLanes,
|
|
46888
|
+
eventColor,
|
|
46889
|
+
minDate,
|
|
46890
|
+
maxDate,
|
|
46891
|
+
datePadding,
|
|
46892
|
+
earliestStartDateStr,
|
|
46893
|
+
latestEndDateStr,
|
|
46894
|
+
tagLegendReserve
|
|
46895
|
+
} = setup;
|
|
46896
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
46897
|
+
const {
|
|
46898
|
+
timelineEvents,
|
|
46899
|
+
timelineGroups,
|
|
46900
|
+
timelineEras,
|
|
46901
|
+
timelineMarkers,
|
|
46902
|
+
timelineScale,
|
|
46903
|
+
timelineSwimlanes
|
|
46904
|
+
} = parsed;
|
|
46905
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46906
|
+
const BAR_H2 = 22;
|
|
46907
|
+
const GROUP_GAP3 = 12;
|
|
46908
|
+
let lanes;
|
|
46909
|
+
if (tagLanes) {
|
|
46910
|
+
lanes = tagLanes;
|
|
46911
|
+
} else {
|
|
46912
|
+
const groupNames = timelineGroups.map((gr) => gr.name);
|
|
46913
|
+
const ungroupedEvents = timelineEvents.filter(
|
|
46914
|
+
(ev) => ev.group === null || !groupNames.includes(ev.group)
|
|
46915
|
+
);
|
|
46916
|
+
const laneNames = ungroupedEvents.length > 0 ? [...groupNames, "(Other)"] : groupNames;
|
|
46917
|
+
lanes = laneNames.map((name) => ({
|
|
46918
|
+
name,
|
|
46919
|
+
events: timelineEvents.filter(
|
|
46920
|
+
(ev) => name === "(Other)" ? ev.group === null || !groupNames.includes(ev.group) : ev.group === name
|
|
46921
|
+
)
|
|
46922
|
+
}));
|
|
46923
|
+
}
|
|
46924
|
+
const totalEventRows = lanes.reduce((s, l) => s + l.events.length, 0);
|
|
46925
|
+
const scaleMargin = timelineScale ? 24 : 0;
|
|
46926
|
+
const ERA_ROW_H = 22;
|
|
46927
|
+
const MARKER_ROW_H = 22;
|
|
46928
|
+
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46929
|
+
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46930
|
+
const topScaleH = timelineScale ? 40 : 0;
|
|
46931
|
+
const maxGroupNameLen = Math.max(...lanes.map((l) => l.name.length));
|
|
46932
|
+
const dynamicLeftMargin = Math.max(120, maxGroupNameLen * 7 + 30);
|
|
46933
|
+
const baseTopMargin = title ? 50 : 20;
|
|
46934
|
+
const margin = {
|
|
46935
|
+
top: baseTopMargin + topScaleH + eraReserve + markerReserve + tagLegendReserve,
|
|
46936
|
+
right: 40,
|
|
46937
|
+
bottom: 40 + scaleMargin,
|
|
46938
|
+
left: dynamicLeftMargin
|
|
46939
|
+
};
|
|
46940
|
+
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46941
|
+
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46942
|
+
const innerWidth = width - margin.left - margin.right;
|
|
46943
|
+
const innerHeight = height - margin.top - margin.bottom;
|
|
46944
|
+
const totalGaps = (lanes.length - 1) * GROUP_GAP3;
|
|
46945
|
+
const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);
|
|
46946
|
+
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
46947
|
+
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
46948
|
+
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46949
|
+
renderChartTitle(
|
|
46950
|
+
svg,
|
|
46951
|
+
title,
|
|
46952
|
+
parsed.titleLineNumber,
|
|
46953
|
+
width,
|
|
46954
|
+
textColor,
|
|
46955
|
+
onClickItem
|
|
46956
|
+
);
|
|
46957
|
+
renderEras(
|
|
46958
|
+
g,
|
|
46959
|
+
timelineEras,
|
|
46960
|
+
xScale,
|
|
46961
|
+
false,
|
|
46962
|
+
innerWidth,
|
|
46963
|
+
innerHeight,
|
|
46964
|
+
(s, e) => fadeToEra(g, s, e),
|
|
46965
|
+
() => fadeReset(g),
|
|
46966
|
+
timelineScale,
|
|
46967
|
+
tooltip,
|
|
46968
|
+
palette,
|
|
46969
|
+
eraReserve ? eraLabelY : void 0
|
|
46970
|
+
);
|
|
46971
|
+
renderMarkers(
|
|
46972
|
+
g,
|
|
46973
|
+
timelineMarkers,
|
|
46974
|
+
xScale,
|
|
46975
|
+
false,
|
|
46976
|
+
innerWidth,
|
|
46977
|
+
innerHeight,
|
|
46978
|
+
(d) => fadeToMarker(g, d),
|
|
46979
|
+
() => fadeReset(g),
|
|
46980
|
+
timelineScale,
|
|
46981
|
+
tooltip,
|
|
46982
|
+
palette,
|
|
46983
|
+
markerReserve ? markerLabelY : void 0
|
|
46984
|
+
);
|
|
46985
|
+
if (timelineScale) {
|
|
46986
|
+
renderTimeScale(
|
|
46987
|
+
g,
|
|
46988
|
+
xScale,
|
|
46989
|
+
false,
|
|
46990
|
+
innerWidth,
|
|
46991
|
+
innerHeight,
|
|
46992
|
+
textColor,
|
|
46993
|
+
minDate,
|
|
46994
|
+
maxDate,
|
|
46995
|
+
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46996
|
+
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46997
|
+
);
|
|
46998
|
+
}
|
|
46999
|
+
let curY = 0;
|
|
47000
|
+
if (timelineSwimlanes || tagLanes) {
|
|
47001
|
+
let swimY = 0;
|
|
47002
|
+
lanes.forEach((lane, idx) => {
|
|
47003
|
+
const laneSpan = lane.events.length * rowH;
|
|
47004
|
+
const fillColor = idx % 2 === 0 ? textColor : "transparent";
|
|
47005
|
+
g.append("rect").attr("class", "tl-swimlane").attr("data-group", lane.name).attr("x", -margin.left).attr("y", swimY).attr("width", innerWidth + margin.left).attr("height", laneSpan + (idx < lanes.length - 1 ? GROUP_GAP3 : 0)).attr("fill", fillColor).attr("opacity", 0.06);
|
|
47006
|
+
swimY += laneSpan + GROUP_GAP3;
|
|
47007
|
+
});
|
|
47008
|
+
}
|
|
47009
|
+
for (const lane of lanes) {
|
|
47010
|
+
const laneColor = groupColorMap.get(lane.name) ?? textColor;
|
|
47011
|
+
const laneSpan = lane.events.length * rowH;
|
|
47012
|
+
const group = timelineGroups.find((grp) => grp.name === lane.name);
|
|
47013
|
+
const headerG = g.append("g").attr("class", "tl-lane-header").attr("data-group", lane.name).style("cursor", "pointer").on("mouseenter", () => fadeToGroup(g, lane.name)).on("mouseleave", () => fadeReset(g)).on("click", () => {
|
|
47014
|
+
if (onClickItem && group?.lineNumber) onClickItem(group.lineNumber);
|
|
47015
|
+
});
|
|
47016
|
+
headerG.append("text").attr("x", -margin.left + 10).attr("y", curY + laneSpan / 2).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", laneColor).attr("font-size", "12px").attr("font-weight", "600").text(lane.name);
|
|
47017
|
+
lane.events.forEach((ev, i) => {
|
|
47018
|
+
const y = curY + i * rowH + rowH / 2;
|
|
47019
|
+
const x = xScale(parseTimelineDate(ev.date));
|
|
47020
|
+
const evG = g.append("g").attr("class", "tl-event").attr("data-group", lane.name).attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
47021
|
+
"data-end-date",
|
|
47022
|
+
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
47023
|
+
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
47024
|
+
fadeToGroup(g, lane.name);
|
|
47025
|
+
if (timelineScale) {
|
|
47026
|
+
showEventDatesOnScale(
|
|
47027
|
+
g,
|
|
47028
|
+
xScale,
|
|
47029
|
+
ev.date,
|
|
47030
|
+
ev.endDate,
|
|
47031
|
+
innerHeight,
|
|
47032
|
+
laneColor
|
|
47033
|
+
);
|
|
47034
|
+
} else {
|
|
46695
47035
|
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46696
|
-
}
|
|
46697
|
-
|
|
47036
|
+
}
|
|
47037
|
+
}).on("mouseleave", function() {
|
|
47038
|
+
fadeReset(g);
|
|
47039
|
+
if (timelineScale) {
|
|
47040
|
+
hideEventDatesOnScale(g);
|
|
47041
|
+
} else {
|
|
46698
47042
|
hideTooltip(tooltip);
|
|
46699
|
-
}
|
|
47043
|
+
}
|
|
47044
|
+
}).on("mousemove", function(event) {
|
|
47045
|
+
if (!timelineScale) {
|
|
46700
47046
|
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46701
|
-
}
|
|
46702
|
-
|
|
46703
|
-
|
|
46704
|
-
|
|
46705
|
-
|
|
46706
|
-
|
|
46707
|
-
|
|
46708
|
-
|
|
46709
|
-
|
|
46710
|
-
|
|
46711
|
-
|
|
46712
|
-
|
|
46713
|
-
|
|
46714
|
-
|
|
46715
|
-
|
|
46716
|
-
|
|
46717
|
-
|
|
46718
|
-
|
|
46719
|
-
|
|
46720
|
-
|
|
46721
|
-
|
|
46722
|
-
|
|
46723
|
-
|
|
46724
|
-
|
|
46725
|
-
|
|
46726
|
-
|
|
46727
|
-
|
|
46728
|
-
|
|
46729
|
-
|
|
47047
|
+
}
|
|
47048
|
+
}).on("click", () => {
|
|
47049
|
+
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
47050
|
+
});
|
|
47051
|
+
setTagAttrs(evG, ev);
|
|
47052
|
+
const evColor = eventColor(ev);
|
|
47053
|
+
if (ev.endDate) {
|
|
47054
|
+
const x2 = xScale(parseTimelineDate(ev.endDate));
|
|
47055
|
+
const rectW = Math.max(x2 - x, 4);
|
|
47056
|
+
const estLabelWidth = ev.label.length * 7 + 16;
|
|
47057
|
+
const labelFitsInside = rectW >= estLabelWidth;
|
|
47058
|
+
let fill2 = shapeFill(palette, evColor, isDark, { solid });
|
|
47059
|
+
let stroke2 = evColor;
|
|
47060
|
+
if (ev.uncertain) {
|
|
47061
|
+
const gradientId = `uncertain-${ev.lineNumber}`;
|
|
47062
|
+
const strokeGradientId = `uncertain-s-${ev.lineNumber}`;
|
|
47063
|
+
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
47064
|
+
const defsEl = d3Selection22.select(defs);
|
|
47065
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
47066
|
+
{ offset: "0%", opacity: 1 },
|
|
47067
|
+
{ offset: "80%", opacity: 1 },
|
|
47068
|
+
{ offset: "100%", opacity: 0 }
|
|
47069
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(evColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47070
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
47071
|
+
{ offset: "0%", opacity: 1 },
|
|
47072
|
+
{ offset: "80%", opacity: 1 },
|
|
47073
|
+
{ offset: "100%", opacity: 0 }
|
|
47074
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", evColor).attr("stop-opacity", (d) => d.opacity);
|
|
47075
|
+
fill2 = `url(#${gradientId})`;
|
|
47076
|
+
stroke2 = `url(#${strokeGradientId})`;
|
|
47077
|
+
}
|
|
47078
|
+
evG.append("rect").attr("x", x).attr("y", y - BAR_H2 / 2).attr("width", rectW).attr("height", BAR_H2).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
47079
|
+
if (labelFitsInside) {
|
|
47080
|
+
evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46730
47081
|
} else {
|
|
46731
|
-
|
|
46732
|
-
|
|
47082
|
+
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
47083
|
+
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
47084
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47085
|
+
evG.append("text").attr("x", flipLeft ? x - 6 : x + rectW + 6).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46733
47086
|
}
|
|
46734
|
-
|
|
46735
|
-
|
|
46736
|
-
|
|
46737
|
-
|
|
46738
|
-
|
|
46739
|
-
|
|
46740
|
-
).attr("dy", "0.35em").attr("text-anchor", "end").attr("fill",
|
|
47087
|
+
} else {
|
|
47088
|
+
const estLabelWidth = ev.label.length * 7;
|
|
47089
|
+
const wouldFlipLeft = x > innerWidth * 0.6;
|
|
47090
|
+
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
47091
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47092
|
+
evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", shapeFill(palette, evColor, isDark, { solid })).attr("stroke", evColor).attr("stroke-width", 2);
|
|
47093
|
+
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
46741
47094
|
}
|
|
46742
|
-
}
|
|
46743
|
-
|
|
47095
|
+
});
|
|
47096
|
+
curY += laneSpan + GROUP_GAP3;
|
|
46744
47097
|
}
|
|
46745
|
-
|
|
46746
|
-
|
|
46747
|
-
const
|
|
46748
|
-
|
|
46749
|
-
|
|
47098
|
+
}
|
|
47099
|
+
function renderTimelineVertical(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
47100
|
+
const {
|
|
47101
|
+
width,
|
|
47102
|
+
height,
|
|
47103
|
+
tooltip,
|
|
47104
|
+
solid,
|
|
47105
|
+
textColor,
|
|
47106
|
+
mutedColor,
|
|
47107
|
+
bgColor,
|
|
47108
|
+
bg,
|
|
47109
|
+
groupColorMap,
|
|
47110
|
+
tagLanes,
|
|
47111
|
+
eventColor,
|
|
47112
|
+
minDate,
|
|
47113
|
+
maxDate,
|
|
47114
|
+
datePadding,
|
|
47115
|
+
earliestStartDateStr,
|
|
47116
|
+
latestEndDateStr,
|
|
47117
|
+
tagLegendReserve
|
|
47118
|
+
} = setup;
|
|
47119
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
47120
|
+
const {
|
|
47121
|
+
timelineEvents,
|
|
47122
|
+
timelineGroups,
|
|
47123
|
+
timelineEras,
|
|
47124
|
+
timelineMarkers,
|
|
47125
|
+
timelineSort,
|
|
47126
|
+
timelineScale,
|
|
47127
|
+
timelineSwimlanes
|
|
47128
|
+
} = parsed;
|
|
47129
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
47130
|
+
const useGroupedVertical = tagLanes != null || timelineSort === "group" && timelineGroups.length > 0;
|
|
47131
|
+
if (useGroupedVertical) {
|
|
47132
|
+
let laneNames;
|
|
47133
|
+
let laneEventsByName;
|
|
46750
47134
|
if (tagLanes) {
|
|
46751
|
-
|
|
47135
|
+
laneNames = tagLanes.map((l) => l.name);
|
|
47136
|
+
laneEventsByName = new Map(tagLanes.map((l) => [l.name, l.events]));
|
|
46752
47137
|
} else {
|
|
46753
47138
|
const groupNames = timelineGroups.map((gr) => gr.name);
|
|
46754
47139
|
const ungroupedEvents = timelineEvents.filter(
|
|
46755
47140
|
(ev) => ev.group === null || !groupNames.includes(ev.group)
|
|
46756
47141
|
);
|
|
46757
|
-
|
|
46758
|
-
|
|
46759
|
-
name
|
|
46760
|
-
|
|
46761
|
-
|
|
46762
|
-
|
|
46763
|
-
|
|
47142
|
+
laneNames = ungroupedEvents.length > 0 ? [...groupNames, "(Other)"] : groupNames;
|
|
47143
|
+
laneEventsByName = new Map(
|
|
47144
|
+
laneNames.map((name) => [
|
|
47145
|
+
name,
|
|
47146
|
+
timelineEvents.filter(
|
|
47147
|
+
(ev) => name === "(Other)" ? ev.group === null || !groupNames.includes(ev.group) : ev.group === name
|
|
47148
|
+
)
|
|
47149
|
+
])
|
|
47150
|
+
);
|
|
46764
47151
|
}
|
|
46765
|
-
const
|
|
46766
|
-
const scaleMargin = timelineScale ?
|
|
46767
|
-
const
|
|
46768
|
-
const MARKER_ROW_H = 22;
|
|
46769
|
-
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46770
|
-
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46771
|
-
const topScaleH = timelineScale ? 40 : 0;
|
|
46772
|
-
const maxGroupNameLen = Math.max(...lanes.map((l) => l.name.length));
|
|
46773
|
-
const dynamicLeftMargin = Math.max(120, maxGroupNameLen * 7 + 30);
|
|
46774
|
-
const baseTopMargin = title ? 50 : 20;
|
|
47152
|
+
const laneCount = laneNames.length;
|
|
47153
|
+
const scaleMargin = timelineScale ? 40 : 0;
|
|
47154
|
+
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46775
47155
|
const margin = {
|
|
46776
|
-
top:
|
|
46777
|
-
right: 40,
|
|
46778
|
-
bottom: 40
|
|
46779
|
-
left:
|
|
47156
|
+
top: 104 + markerMargin + tagLegendReserve,
|
|
47157
|
+
right: 40 + scaleMargin,
|
|
47158
|
+
bottom: 40,
|
|
47159
|
+
left: 60 + scaleMargin
|
|
46780
47160
|
};
|
|
46781
|
-
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46782
|
-
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46783
47161
|
const innerWidth = width - margin.left - margin.right;
|
|
46784
47162
|
const innerHeight = height - margin.top - margin.bottom;
|
|
46785
|
-
const
|
|
46786
|
-
const
|
|
46787
|
-
const
|
|
46788
|
-
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
47163
|
+
const laneWidth = innerWidth / laneCount;
|
|
47164
|
+
const yScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
|
|
47165
|
+
const svg = d3Selection22.select(container).append("svg").attr("viewBox", `0 0 ${width} ${height}`).attr("width", exportDims ? width : "100%").attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
46789
47166
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46790
47167
|
renderChartTitle(
|
|
46791
47168
|
svg,
|
|
@@ -46798,36 +47175,34 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46798
47175
|
renderEras(
|
|
46799
47176
|
g,
|
|
46800
47177
|
timelineEras,
|
|
46801
|
-
|
|
46802
|
-
|
|
47178
|
+
yScale,
|
|
47179
|
+
true,
|
|
46803
47180
|
innerWidth,
|
|
46804
47181
|
innerHeight,
|
|
46805
47182
|
(s, e) => fadeToEra(g, s, e),
|
|
46806
47183
|
() => fadeReset(g),
|
|
46807
47184
|
timelineScale,
|
|
46808
47185
|
tooltip,
|
|
46809
|
-
palette
|
|
46810
|
-
eraReserve ? eraLabelY : void 0
|
|
47186
|
+
palette
|
|
46811
47187
|
);
|
|
46812
47188
|
renderMarkers(
|
|
46813
47189
|
g,
|
|
46814
47190
|
timelineMarkers,
|
|
46815
|
-
|
|
46816
|
-
|
|
47191
|
+
yScale,
|
|
47192
|
+
true,
|
|
46817
47193
|
innerWidth,
|
|
46818
47194
|
innerHeight,
|
|
46819
47195
|
(d) => fadeToMarker(g, d),
|
|
46820
47196
|
() => fadeReset(g),
|
|
46821
47197
|
timelineScale,
|
|
46822
47198
|
tooltip,
|
|
46823
|
-
palette
|
|
46824
|
-
markerReserve ? markerLabelY : void 0
|
|
47199
|
+
palette
|
|
46825
47200
|
);
|
|
46826
47201
|
if (timelineScale) {
|
|
46827
47202
|
renderTimeScale(
|
|
46828
47203
|
g,
|
|
46829
|
-
|
|
46830
|
-
|
|
47204
|
+
yScale,
|
|
47205
|
+
true,
|
|
46831
47206
|
innerWidth,
|
|
46832
47207
|
innerHeight,
|
|
46833
47208
|
textColor,
|
|
@@ -46837,78 +47212,55 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46837
47212
|
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46838
47213
|
);
|
|
46839
47214
|
}
|
|
46840
|
-
let curY = 0;
|
|
46841
47215
|
if (timelineSwimlanes || tagLanes) {
|
|
46842
|
-
|
|
46843
|
-
|
|
46844
|
-
const
|
|
46845
|
-
|
|
46846
|
-
g.append("rect").attr("class", "tl-swimlane").attr("data-group", lane.name).attr("x", -margin.left).attr("y", swimY).attr("width", innerWidth + margin.left).attr("height", laneSpan + (idx < lanes.length - 1 ? GROUP_GAP3 : 0)).attr("fill", fillColor).attr("opacity", 0.06);
|
|
46847
|
-
swimY += laneSpan + GROUP_GAP3;
|
|
47216
|
+
laneNames.forEach((laneName, laneIdx) => {
|
|
47217
|
+
const laneX = laneIdx * laneWidth;
|
|
47218
|
+
const fillColor = laneIdx % 2 === 0 ? textColor : "transparent";
|
|
47219
|
+
g.append("rect").attr("class", "tl-swimlane").attr("data-group", laneName).attr("x", laneX).attr("y", 0).attr("width", laneWidth).attr("height", innerHeight).attr("fill", fillColor).attr("opacity", 0.06);
|
|
46848
47220
|
});
|
|
46849
47221
|
}
|
|
46850
|
-
|
|
46851
|
-
const
|
|
46852
|
-
const
|
|
46853
|
-
const
|
|
46854
|
-
const headerG = g.append("g").attr("class", "tl-lane-header").attr("data-group",
|
|
46855
|
-
|
|
46856
|
-
|
|
46857
|
-
|
|
46858
|
-
|
|
46859
|
-
const y =
|
|
46860
|
-
const
|
|
46861
|
-
const evG = g.append("g").attr("class", "tl-event").attr("data-group", lane.name).attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
47222
|
+
laneNames.forEach((laneName, laneIdx) => {
|
|
47223
|
+
const laneX = laneIdx * laneWidth;
|
|
47224
|
+
const laneColor = groupColorMap.get(laneName) ?? textColor;
|
|
47225
|
+
const laneCenter = laneX + laneWidth / 2;
|
|
47226
|
+
const headerG = g.append("g").attr("class", "tl-lane-header").attr("data-group", laneName).style("cursor", "pointer").on("mouseenter", () => fadeToGroup(g, laneName)).on("mouseleave", () => fadeReset(g));
|
|
47227
|
+
headerG.append("text").attr("x", laneCenter).attr("y", -15).attr("text-anchor", "middle").attr("fill", laneColor).attr("font-size", "12px").attr("font-weight", "600").text(laneName);
|
|
47228
|
+
g.append("line").attr("x1", laneCenter).attr("y1", 0).attr("x2", laneCenter).attr("y2", innerHeight).attr("stroke", mutedColor).attr("stroke-width", 1).attr("stroke-dasharray", "4,4");
|
|
47229
|
+
const laneEvents = laneEventsByName.get(laneName) ?? [];
|
|
47230
|
+
for (const ev of laneEvents) {
|
|
47231
|
+
const y = yScale(parseTimelineDate(ev.date));
|
|
47232
|
+
const evG = g.append("g").attr("class", "tl-event").attr("data-group", laneName).attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
46862
47233
|
"data-end-date",
|
|
46863
47234
|
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
46864
47235
|
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
46865
|
-
fadeToGroup(g,
|
|
46866
|
-
|
|
46867
|
-
showEventDatesOnScale(
|
|
46868
|
-
g,
|
|
46869
|
-
xScale,
|
|
46870
|
-
ev.date,
|
|
46871
|
-
ev.endDate,
|
|
46872
|
-
innerHeight,
|
|
46873
|
-
laneColor
|
|
46874
|
-
);
|
|
46875
|
-
} else {
|
|
46876
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46877
|
-
}
|
|
47236
|
+
fadeToGroup(g, laneName);
|
|
47237
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46878
47238
|
}).on("mouseleave", function() {
|
|
46879
47239
|
fadeReset(g);
|
|
46880
|
-
|
|
46881
|
-
hideEventDatesOnScale(g);
|
|
46882
|
-
} else {
|
|
46883
|
-
hideTooltip(tooltip);
|
|
46884
|
-
}
|
|
47240
|
+
hideTooltip(tooltip);
|
|
46885
47241
|
}).on("mousemove", function(event) {
|
|
46886
|
-
|
|
46887
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46888
|
-
}
|
|
47242
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46889
47243
|
}).on("click", () => {
|
|
46890
47244
|
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
46891
47245
|
});
|
|
46892
47246
|
setTagAttrs(evG, ev);
|
|
46893
47247
|
const evColor = eventColor(ev);
|
|
46894
47248
|
if (ev.endDate) {
|
|
46895
|
-
const
|
|
46896
|
-
const
|
|
46897
|
-
const estLabelWidth = ev.label.length * 7 + 16;
|
|
46898
|
-
const labelFitsInside = rectW >= estLabelWidth;
|
|
47249
|
+
const y2 = yScale(parseTimelineDate(ev.endDate));
|
|
47250
|
+
const rectH = Math.max(y2 - y, 4);
|
|
46899
47251
|
let fill2 = shapeFill(palette, evColor, isDark, { solid });
|
|
46900
47252
|
let stroke2 = evColor;
|
|
46901
47253
|
if (ev.uncertain) {
|
|
46902
|
-
const gradientId = `uncertain-${ev.lineNumber}`;
|
|
46903
|
-
const strokeGradientId = `uncertain-s-${ev.lineNumber}`;
|
|
47254
|
+
const gradientId = `uncertain-vg-${ev.lineNumber}`;
|
|
47255
|
+
const strokeGradientId = `uncertain-vg-s-${ev.lineNumber}`;
|
|
46904
47256
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46905
47257
|
const defsEl = d3Selection22.select(defs);
|
|
46906
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47258
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46907
47259
|
{ offset: "0%", opacity: 1 },
|
|
46908
47260
|
{ offset: "80%", opacity: 1 },
|
|
46909
47261
|
{ offset: "100%", opacity: 0 }
|
|
46910
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(
|
|
46911
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47262
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47263
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46912
47264
|
{ offset: "0%", opacity: 1 },
|
|
46913
47265
|
{ offset: "80%", opacity: 1 },
|
|
46914
47266
|
{ offset: "100%", opacity: 0 }
|
|
@@ -46916,47 +47268,29 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46916
47268
|
fill2 = `url(#${gradientId})`;
|
|
46917
47269
|
stroke2 = `url(#${strokeGradientId})`;
|
|
46918
47270
|
}
|
|
46919
|
-
evG.append("rect").attr("x",
|
|
46920
|
-
|
|
46921
|
-
evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46922
|
-
} else {
|
|
46923
|
-
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
46924
|
-
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
46925
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46926
|
-
evG.append("text").attr("x", flipLeft ? x - 6 : x + rectW + 6).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46927
|
-
}
|
|
47271
|
+
evG.append("rect").attr("x", laneCenter - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
47272
|
+
evG.append("text").attr("x", laneCenter + 14).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
|
|
46928
47273
|
} else {
|
|
46929
|
-
|
|
46930
|
-
|
|
46931
|
-
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
46932
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46933
|
-
evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", shapeFill(palette, evColor, isDark, { solid })).attr("stroke", evColor).attr("stroke-width", 2);
|
|
46934
|
-
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
47274
|
+
evG.append("circle").attr("cx", laneCenter).attr("cy", y).attr("r", 4).attr("fill", shapeFill(palette, evColor, isDark, { solid })).attr("stroke", evColor).attr("stroke-width", 2);
|
|
47275
|
+
evG.append("text").attr("x", laneCenter + 10).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
|
|
46935
47276
|
}
|
|
46936
|
-
}
|
|
46937
|
-
|
|
46938
|
-
}
|
|
47277
|
+
}
|
|
47278
|
+
});
|
|
46939
47279
|
} else {
|
|
46940
|
-
const
|
|
46941
|
-
const
|
|
46942
|
-
const ERA_ROW_H = 22;
|
|
46943
|
-
const MARKER_ROW_H = 22;
|
|
46944
|
-
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46945
|
-
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46946
|
-
const topScaleH = timelineScale ? 40 : 0;
|
|
47280
|
+
const scaleMargin = timelineScale ? 40 : 0;
|
|
47281
|
+
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46947
47282
|
const margin = {
|
|
46948
|
-
top: 104 +
|
|
46949
|
-
right:
|
|
46950
|
-
bottom: 40
|
|
46951
|
-
left: 60
|
|
47283
|
+
top: 104 + markerMargin + tagLegendReserve,
|
|
47284
|
+
right: 200,
|
|
47285
|
+
bottom: 40,
|
|
47286
|
+
left: 60 + scaleMargin
|
|
46952
47287
|
};
|
|
46953
|
-
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46954
|
-
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46955
47288
|
const innerWidth = width - margin.left - margin.right;
|
|
46956
47289
|
const innerHeight = height - margin.top - margin.bottom;
|
|
46957
|
-
const
|
|
46958
|
-
const
|
|
46959
|
-
const
|
|
47290
|
+
const axisX = 20;
|
|
47291
|
+
const yScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
|
|
47292
|
+
const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
|
|
47293
|
+
const svg = d3Selection22.select(container).append("svg").attr("viewBox", `0 0 ${width} ${height}`).attr("width", exportDims ? width : "100%").attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
46960
47294
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46961
47295
|
renderChartTitle(
|
|
46962
47296
|
svg,
|
|
@@ -46969,36 +47303,34 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46969
47303
|
renderEras(
|
|
46970
47304
|
g,
|
|
46971
47305
|
timelineEras,
|
|
46972
|
-
|
|
46973
|
-
|
|
47306
|
+
yScale,
|
|
47307
|
+
true,
|
|
46974
47308
|
innerWidth,
|
|
46975
47309
|
innerHeight,
|
|
46976
47310
|
(s, e) => fadeToEra(g, s, e),
|
|
46977
47311
|
() => fadeReset(g),
|
|
46978
47312
|
timelineScale,
|
|
46979
47313
|
tooltip,
|
|
46980
|
-
palette
|
|
46981
|
-
eraReserve ? eraLabelY : void 0
|
|
47314
|
+
palette
|
|
46982
47315
|
);
|
|
46983
47316
|
renderMarkers(
|
|
46984
47317
|
g,
|
|
46985
47318
|
timelineMarkers,
|
|
46986
|
-
|
|
46987
|
-
|
|
47319
|
+
yScale,
|
|
47320
|
+
true,
|
|
46988
47321
|
innerWidth,
|
|
46989
47322
|
innerHeight,
|
|
46990
47323
|
(d) => fadeToMarker(g, d),
|
|
46991
47324
|
() => fadeReset(g),
|
|
46992
47325
|
timelineScale,
|
|
46993
47326
|
tooltip,
|
|
46994
|
-
palette
|
|
46995
|
-
markerReserve ? markerLabelY : void 0
|
|
47327
|
+
palette
|
|
46996
47328
|
);
|
|
46997
47329
|
if (timelineScale) {
|
|
46998
47330
|
renderTimeScale(
|
|
46999
47331
|
g,
|
|
47000
|
-
|
|
47001
|
-
|
|
47332
|
+
yScale,
|
|
47333
|
+
true,
|
|
47002
47334
|
innerWidth,
|
|
47003
47335
|
innerHeight,
|
|
47004
47336
|
textColor,
|
|
@@ -47009,7 +47341,6 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
47009
47341
|
);
|
|
47010
47342
|
}
|
|
47011
47343
|
if (timelineGroups.length > 0) {
|
|
47012
|
-
const legendY = timelineScale ? -75 : -55;
|
|
47013
47344
|
renderTimelineGroupLegend(
|
|
47014
47345
|
g,
|
|
47015
47346
|
timelineGroups,
|
|
@@ -47017,65 +47348,46 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
47017
47348
|
textColor,
|
|
47018
47349
|
palette,
|
|
47019
47350
|
isDark,
|
|
47020
|
-
|
|
47351
|
+
-55,
|
|
47021
47352
|
(name) => fadeToGroup(g, name),
|
|
47022
47353
|
() => fadeReset(g)
|
|
47023
47354
|
);
|
|
47024
47355
|
}
|
|
47025
|
-
|
|
47026
|
-
|
|
47027
|
-
const
|
|
47356
|
+
g.append("line").attr("x1", axisX).attr("y1", 0).attr("x2", axisX).attr("y2", innerHeight).attr("stroke", mutedColor).attr("stroke-width", 1).attr("stroke-dasharray", "4,4");
|
|
47357
|
+
for (const ev of sorted) {
|
|
47358
|
+
const y = yScale(parseTimelineDate(ev.date));
|
|
47028
47359
|
const color = eventColor(ev);
|
|
47029
47360
|
const evG = g.append("g").attr("class", "tl-event").attr("data-group", ev.group || "").attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
47030
47361
|
"data-end-date",
|
|
47031
47362
|
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
47032
47363
|
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
47033
47364
|
if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);
|
|
47034
|
-
|
|
47035
|
-
showEventDatesOnScale(
|
|
47036
|
-
g,
|
|
47037
|
-
xScale,
|
|
47038
|
-
ev.date,
|
|
47039
|
-
ev.endDate,
|
|
47040
|
-
innerHeight,
|
|
47041
|
-
color
|
|
47042
|
-
);
|
|
47043
|
-
} else {
|
|
47044
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47045
|
-
}
|
|
47365
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47046
47366
|
}).on("mouseleave", function() {
|
|
47047
47367
|
fadeReset(g);
|
|
47048
|
-
|
|
47049
|
-
hideEventDatesOnScale(g);
|
|
47050
|
-
} else {
|
|
47051
|
-
hideTooltip(tooltip);
|
|
47052
|
-
}
|
|
47368
|
+
hideTooltip(tooltip);
|
|
47053
47369
|
}).on("mousemove", function(event) {
|
|
47054
|
-
|
|
47055
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47056
|
-
}
|
|
47370
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47057
47371
|
}).on("click", () => {
|
|
47058
47372
|
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
47059
47373
|
});
|
|
47060
47374
|
setTagAttrs(evG, ev);
|
|
47061
47375
|
if (ev.endDate) {
|
|
47062
|
-
const
|
|
47063
|
-
const
|
|
47064
|
-
const estLabelWidth = ev.label.length * 7 + 16;
|
|
47065
|
-
const labelFitsInside = rectW >= estLabelWidth;
|
|
47376
|
+
const y2 = yScale(parseTimelineDate(ev.endDate));
|
|
47377
|
+
const rectH = Math.max(y2 - y, 4);
|
|
47066
47378
|
let fill2 = shapeFill(palette, color, isDark, { solid });
|
|
47067
47379
|
let stroke2 = color;
|
|
47068
47380
|
if (ev.uncertain) {
|
|
47069
|
-
const gradientId = `uncertain-
|
|
47070
|
-
const strokeGradientId = `uncertain-
|
|
47381
|
+
const gradientId = `uncertain-v-${ev.lineNumber}`;
|
|
47382
|
+
const strokeGradientId = `uncertain-v-s-${ev.lineNumber}`;
|
|
47071
47383
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
47072
47384
|
const defsEl = d3Selection22.select(defs);
|
|
47073
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47385
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
47074
47386
|
{ offset: "0%", opacity: 1 },
|
|
47075
47387
|
{ offset: "80%", opacity: 1 },
|
|
47076
47388
|
{ offset: "100%", opacity: 0 }
|
|
47077
47389
|
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47078
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47390
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
47079
47391
|
{ offset: "0%", opacity: 1 },
|
|
47080
47392
|
{ offset: "80%", opacity: 1 },
|
|
47081
47393
|
{ offset: "100%", opacity: 0 }
|
|
@@ -47083,206 +47395,100 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
47083
47395
|
fill2 = `url(#${gradientId})`;
|
|
47084
47396
|
stroke2 = `url(#${strokeGradientId})`;
|
|
47085
47397
|
}
|
|
47086
|
-
evG.append("rect").attr("x",
|
|
47087
|
-
|
|
47088
|
-
evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
47089
|
-
} else {
|
|
47090
|
-
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
47091
|
-
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
47092
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47093
|
-
evG.append("text").attr("x", flipLeft ? x - 6 : x + rectW + 6).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
47094
|
-
}
|
|
47398
|
+
evG.append("rect").attr("x", axisX - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
47399
|
+
evG.append("text").attr("x", axisX + 16).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "11px").text(ev.label);
|
|
47095
47400
|
} else {
|
|
47096
|
-
|
|
47097
|
-
|
|
47098
|
-
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
47099
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47100
|
-
evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color).attr("stroke-width", 2);
|
|
47101
|
-
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
47401
|
+
evG.append("circle").attr("cx", axisX).attr("cy", y).attr("r", 4).attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color).attr("stroke-width", 2);
|
|
47402
|
+
evG.append("text").attr("x", axisX + 16).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "11px").text(ev.label);
|
|
47102
47403
|
}
|
|
47103
|
-
|
|
47104
|
-
|
|
47105
|
-
|
|
47106
|
-
|
|
47107
|
-
|
|
47108
|
-
|
|
47109
|
-
|
|
47110
|
-
const LG_DOT_R = LEGEND_DOT_R;
|
|
47111
|
-
const LG_ENTRY_FONT_SIZE = LEGEND_ENTRY_FONT_SIZE;
|
|
47112
|
-
const LG_ENTRY_DOT_GAP = LEGEND_ENTRY_DOT_GAP;
|
|
47113
|
-
const LG_ENTRY_TRAIL = LEGEND_ENTRY_TRAIL;
|
|
47114
|
-
const LG_ICON_W = 20;
|
|
47115
|
-
const mainSvg = d3Selection22.select(container).select("svg");
|
|
47116
|
-
const mainG = mainSvg.select("g");
|
|
47117
|
-
if (!mainSvg.empty() && !mainG.empty()) {
|
|
47118
|
-
let drawSwimlaneIcon4 = function(parent, x, y, isSwimActive) {
|
|
47119
|
-
const iconG = parent.append("g").attr("class", "tl-swimlane-icon").attr("transform", `translate(${x}, ${y})`).style("cursor", "pointer");
|
|
47120
|
-
const barColor = isSwimActive ? palette.primary : palette.textMuted;
|
|
47121
|
-
const barOpacity = isSwimActive ? 1 : 0.35;
|
|
47122
|
-
const bars = [
|
|
47123
|
-
{ y: 0, w: 8 },
|
|
47124
|
-
{ y: 4, w: 12 },
|
|
47125
|
-
{ y: 8, w: 6 }
|
|
47126
|
-
];
|
|
47127
|
-
for (const bar of bars) {
|
|
47128
|
-
iconG.append("rect").attr("x", 0).attr("y", bar.y).attr("width", bar.w).attr("height", 2).attr("rx", 1).attr("fill", barColor).attr("opacity", barOpacity);
|
|
47129
|
-
}
|
|
47130
|
-
return iconG;
|
|
47131
|
-
}, relayout2 = function() {
|
|
47132
|
-
renderTimeline(
|
|
47133
|
-
container,
|
|
47134
|
-
parsed,
|
|
47135
|
-
palette,
|
|
47136
|
-
isDark,
|
|
47137
|
-
onClickItem,
|
|
47138
|
-
exportDims,
|
|
47139
|
-
currentActiveGroup,
|
|
47140
|
-
currentSwimlaneGroup,
|
|
47141
|
-
onTagStateChange,
|
|
47142
|
-
viewMode
|
|
47143
|
-
);
|
|
47144
|
-
}, drawLegend2 = function() {
|
|
47145
|
-
mainSvg.selectAll(".tl-tag-legend-group").remove();
|
|
47146
|
-
mainSvg.selectAll(".tl-tag-legend-container").remove();
|
|
47147
|
-
const effectiveColorKey = (currentActiveGroup ?? currentSwimlaneGroup)?.toLowerCase() ?? null;
|
|
47148
|
-
const visibleGroups = viewMode ? legendGroups.filter(
|
|
47149
|
-
(lg) => effectiveColorKey != null && lg.group.name.toLowerCase() === effectiveColorKey
|
|
47150
|
-
) : legendGroups;
|
|
47151
|
-
if (visibleGroups.length === 0) return;
|
|
47152
|
-
const legendContainer = mainSvg.append("g").attr("class", "tl-tag-legend-container");
|
|
47153
|
-
if (currentActiveGroup) {
|
|
47154
|
-
legendContainer.attr(
|
|
47155
|
-
"data-legend-active",
|
|
47156
|
-
currentActiveGroup.toLowerCase()
|
|
47157
|
-
);
|
|
47158
|
-
}
|
|
47159
|
-
const iconAddon = viewMode ? 0 : LG_ICON_W;
|
|
47160
|
-
const centralGroups = visibleGroups.map((lg) => ({
|
|
47161
|
-
name: lg.group.name,
|
|
47162
|
-
entries: lg.group.entries.map((e) => ({
|
|
47163
|
-
value: e.value,
|
|
47164
|
-
color: e.color
|
|
47165
|
-
}))
|
|
47166
|
-
}));
|
|
47167
|
-
const centralActive = viewMode ? effectiveColorKey : currentActiveGroup;
|
|
47168
|
-
const centralConfig = {
|
|
47169
|
-
groups: centralGroups,
|
|
47170
|
-
position: { placement: "top-center", titleRelation: "below-title" },
|
|
47171
|
-
mode: "fixed",
|
|
47172
|
-
capsulePillAddonWidth: iconAddon
|
|
47173
|
-
};
|
|
47174
|
-
const centralState = { activeGroup: centralActive };
|
|
47175
|
-
const centralCallbacks = viewMode ? {} : {
|
|
47176
|
-
onGroupToggle: (groupName) => {
|
|
47177
|
-
currentActiveGroup = currentActiveGroup === groupName.toLowerCase() ? null : groupName.toLowerCase();
|
|
47178
|
-
drawLegend2();
|
|
47179
|
-
recolorEvents2();
|
|
47180
|
-
onTagStateChange?.(currentActiveGroup, currentSwimlaneGroup);
|
|
47181
|
-
},
|
|
47182
|
-
onEntryHover: (groupName, entryValue) => {
|
|
47183
|
-
const tagKey = groupName.toLowerCase();
|
|
47184
|
-
if (entryValue) {
|
|
47185
|
-
const tagVal = entryValue.toLowerCase();
|
|
47186
|
-
fadeToTagValue(mainG, tagKey, tagVal);
|
|
47187
|
-
mainSvg.selectAll("[data-legend-entry]").each(function() {
|
|
47188
|
-
const el = d3Selection22.select(this);
|
|
47189
|
-
const ev = el.attr("data-legend-entry");
|
|
47190
|
-
const eg = el.attr("data-tag-group") ?? el.node()?.closest?.("[data-tag-group]")?.getAttribute("data-tag-group");
|
|
47191
|
-
el.attr(
|
|
47192
|
-
"opacity",
|
|
47193
|
-
eg === tagKey && ev === tagVal ? 1 : FADE_OPACITY3
|
|
47194
|
-
);
|
|
47195
|
-
});
|
|
47196
|
-
} else {
|
|
47197
|
-
fadeReset(mainG);
|
|
47198
|
-
mainSvg.selectAll("[data-legend-entry]").attr("opacity", 1);
|
|
47199
|
-
}
|
|
47200
|
-
},
|
|
47201
|
-
onGroupRendered: (groupName, groupEl, isActive) => {
|
|
47202
|
-
const groupKey = groupName.toLowerCase();
|
|
47203
|
-
groupEl.attr("data-tag-group", groupKey);
|
|
47204
|
-
if (isActive && !viewMode) {
|
|
47205
|
-
const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
|
|
47206
|
-
const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
47207
|
-
const pillXOff = LG_CAPSULE_PAD;
|
|
47208
|
-
const iconX = pillXOff + pillWidth3 + 5;
|
|
47209
|
-
const iconY = (LG_HEIGHT - 10) / 2;
|
|
47210
|
-
const iconEl = drawSwimlaneIcon4(
|
|
47211
|
-
groupEl,
|
|
47212
|
-
iconX,
|
|
47213
|
-
iconY,
|
|
47214
|
-
isSwimActive
|
|
47215
|
-
);
|
|
47216
|
-
iconEl.attr("data-swimlane-toggle", groupKey).on("click", (event) => {
|
|
47217
|
-
event.stopPropagation();
|
|
47218
|
-
currentSwimlaneGroup = currentSwimlaneGroup === groupKey ? null : groupKey;
|
|
47219
|
-
onTagStateChange?.(
|
|
47220
|
-
currentActiveGroup,
|
|
47221
|
-
currentSwimlaneGroup
|
|
47222
|
-
);
|
|
47223
|
-
relayout2();
|
|
47224
|
-
});
|
|
47225
|
-
}
|
|
47226
|
-
}
|
|
47227
|
-
};
|
|
47228
|
-
const legendInnerG = legendContainer.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
47229
|
-
renderLegendD3(
|
|
47230
|
-
legendInnerG,
|
|
47231
|
-
centralConfig,
|
|
47232
|
-
centralState,
|
|
47233
|
-
palette,
|
|
47234
|
-
isDark,
|
|
47235
|
-
centralCallbacks,
|
|
47236
|
-
width
|
|
47237
|
-
);
|
|
47238
|
-
}, recolorEvents2 = function() {
|
|
47239
|
-
const colorTG = currentActiveGroup ?? swimlaneTagGroup ?? null;
|
|
47240
|
-
mainG.selectAll(".tl-event").each(function() {
|
|
47241
|
-
const el = d3Selection22.select(this);
|
|
47242
|
-
const lineNum = el.attr("data-line-number");
|
|
47243
|
-
const ev = lineNum ? eventByLine.get(lineNum) : void 0;
|
|
47244
|
-
if (!ev) return;
|
|
47245
|
-
let color;
|
|
47246
|
-
if (colorTG) {
|
|
47247
|
-
const tagColor = resolveTagColor(
|
|
47248
|
-
ev.metadata,
|
|
47249
|
-
parsed.timelineTagGroups,
|
|
47250
|
-
colorTG
|
|
47251
|
-
);
|
|
47252
|
-
color = tagColor ?? (ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor);
|
|
47253
|
-
} else {
|
|
47254
|
-
color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
|
|
47255
|
-
}
|
|
47256
|
-
el.selectAll("rect").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
47257
|
-
el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
47258
|
-
});
|
|
47259
|
-
};
|
|
47260
|
-
var drawSwimlaneIcon3 = drawSwimlaneIcon4, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
|
|
47261
|
-
const legendY = title ? 50 : 10;
|
|
47262
|
-
const legendGroups = parsed.timelineTagGroups.map((g) => {
|
|
47263
|
-
const pillW = measureLegendText(g.name, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
47264
|
-
const iconSpace = viewMode ? 8 : LG_ICON_W + 4;
|
|
47265
|
-
let entryX = LG_CAPSULE_PAD + pillW + iconSpace;
|
|
47266
|
-
for (const entry of g.entries) {
|
|
47267
|
-
const textX = entryX + LG_DOT_R * 2 + LG_ENTRY_DOT_GAP;
|
|
47268
|
-
entryX = textX + measureLegendText(entry.value, LG_ENTRY_FONT_SIZE) + LG_ENTRY_TRAIL;
|
|
47269
|
-
}
|
|
47270
|
-
return {
|
|
47271
|
-
group: g,
|
|
47272
|
-
minifiedWidth: pillW,
|
|
47273
|
-
expandedWidth: entryX + LG_CAPSULE_PAD
|
|
47274
|
-
};
|
|
47275
|
-
});
|
|
47276
|
-
let currentActiveGroup = activeTagGroup ?? null;
|
|
47277
|
-
let currentSwimlaneGroup = swimlaneTagGroup ?? null;
|
|
47278
|
-
const eventByLine = /* @__PURE__ */ new Map();
|
|
47279
|
-
for (const ev of timelineEvents) {
|
|
47280
|
-
eventByLine.set(String(ev.lineNumber), ev);
|
|
47281
|
-
}
|
|
47282
|
-
drawLegend2();
|
|
47404
|
+
evG.append("text").attr("x", axisX - 14).attr(
|
|
47405
|
+
"y",
|
|
47406
|
+
ev.endDate ? yScale(parseTimelineDate(ev.date)) + Math.max(
|
|
47407
|
+
yScale(parseTimelineDate(ev.endDate)) - yScale(parseTimelineDate(ev.date)),
|
|
47408
|
+
4
|
|
47409
|
+
) / 2 : y
|
|
47410
|
+
).attr("dy", "0.35em").attr("text-anchor", "end").attr("fill", mutedColor).attr("font-size", "10px").text(ev.date + (ev.endDate ? `\u2192${ev.endDate}` : ""));
|
|
47283
47411
|
}
|
|
47284
47412
|
}
|
|
47285
47413
|
}
|
|
47414
|
+
function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims, activeTagGroup, swimlaneTagGroup, onTagStateChange, viewMode) {
|
|
47415
|
+
const setup = setupTimeline(
|
|
47416
|
+
container,
|
|
47417
|
+
parsed,
|
|
47418
|
+
palette,
|
|
47419
|
+
isDark,
|
|
47420
|
+
exportDims,
|
|
47421
|
+
activeTagGroup,
|
|
47422
|
+
swimlaneTagGroup
|
|
47423
|
+
);
|
|
47424
|
+
if (!setup) return;
|
|
47425
|
+
swimlaneTagGroup = setup.swimlaneTagGroup;
|
|
47426
|
+
const { isVertical, tagLanes } = setup;
|
|
47427
|
+
const hovers = makeTimelineHoverHelpers();
|
|
47428
|
+
if (isVertical) {
|
|
47429
|
+
renderTimelineVertical(
|
|
47430
|
+
container,
|
|
47431
|
+
parsed,
|
|
47432
|
+
palette,
|
|
47433
|
+
isDark,
|
|
47434
|
+
setup,
|
|
47435
|
+
hovers,
|
|
47436
|
+
onClickItem,
|
|
47437
|
+
exportDims,
|
|
47438
|
+
swimlaneTagGroup,
|
|
47439
|
+
activeTagGroup,
|
|
47440
|
+
onTagStateChange,
|
|
47441
|
+
viewMode
|
|
47442
|
+
);
|
|
47443
|
+
return;
|
|
47444
|
+
}
|
|
47445
|
+
const useGroupedHorizontal = tagLanes != null || parsed.timelineSort === "group" && parsed.timelineGroups.length > 0;
|
|
47446
|
+
if (useGroupedHorizontal) {
|
|
47447
|
+
renderTimelineHorizontalGrouped(
|
|
47448
|
+
container,
|
|
47449
|
+
parsed,
|
|
47450
|
+
palette,
|
|
47451
|
+
isDark,
|
|
47452
|
+
setup,
|
|
47453
|
+
hovers,
|
|
47454
|
+
onClickItem,
|
|
47455
|
+
exportDims,
|
|
47456
|
+
swimlaneTagGroup,
|
|
47457
|
+
activeTagGroup,
|
|
47458
|
+
onTagStateChange,
|
|
47459
|
+
viewMode
|
|
47460
|
+
);
|
|
47461
|
+
} else {
|
|
47462
|
+
renderTimelineHorizontalTimeSort(
|
|
47463
|
+
container,
|
|
47464
|
+
parsed,
|
|
47465
|
+
palette,
|
|
47466
|
+
isDark,
|
|
47467
|
+
setup,
|
|
47468
|
+
hovers,
|
|
47469
|
+
onClickItem,
|
|
47470
|
+
exportDims,
|
|
47471
|
+
swimlaneTagGroup,
|
|
47472
|
+
activeTagGroup,
|
|
47473
|
+
onTagStateChange,
|
|
47474
|
+
viewMode
|
|
47475
|
+
);
|
|
47476
|
+
}
|
|
47477
|
+
renderTimelineTagLegendOverlay(
|
|
47478
|
+
container,
|
|
47479
|
+
parsed,
|
|
47480
|
+
palette,
|
|
47481
|
+
isDark,
|
|
47482
|
+
setup,
|
|
47483
|
+
hovers,
|
|
47484
|
+
onClickItem,
|
|
47485
|
+
exportDims,
|
|
47486
|
+
swimlaneTagGroup,
|
|
47487
|
+
activeTagGroup,
|
|
47488
|
+
onTagStateChange,
|
|
47489
|
+
viewMode
|
|
47490
|
+
);
|
|
47491
|
+
}
|
|
47286
47492
|
function getRotateFn(mode) {
|
|
47287
47493
|
if (mode === "mixed") return () => Math.random() > 0.5 ? 0 : 90;
|
|
47288
47494
|
if (mode === "angled") return () => Math.round(Math.random() * 30 - 15);
|
|
@@ -47406,7 +47612,7 @@ function regionCentroid(circles, inside) {
|
|
|
47406
47612
|
}
|
|
47407
47613
|
return { x: sx / count, y: sy / count };
|
|
47408
47614
|
}
|
|
47409
|
-
function renderVenn(container, parsed, palette,
|
|
47615
|
+
function renderVenn(container, parsed, palette, _isDark, onClickItem, exportDims) {
|
|
47410
47616
|
const { vennSets, vennOverlaps } = parsed;
|
|
47411
47617
|
const title = parsed.noTitle ? null : parsed.title;
|
|
47412
47618
|
if (vennSets.length < 2 || vennSets.length > 3) return;
|
|
@@ -47640,7 +47846,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
47640
47846
|
};
|
|
47641
47847
|
const gcx = circles.reduce((s, c) => s + c.x, 0) / n;
|
|
47642
47848
|
const gcy = circles.reduce((s, c) => s + c.y, 0) / n;
|
|
47643
|
-
function exclusiveHSpan(
|
|
47849
|
+
function exclusiveHSpan(_px, py, ci) {
|
|
47644
47850
|
const dy = py - circles[ci].y;
|
|
47645
47851
|
const halfChord = Math.sqrt(
|
|
47646
47852
|
Math.max(0, circles[ci].r * circles[ci].r - dy * dy)
|
|
@@ -48553,9 +48759,9 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
48553
48759
|
blHiddenTagValues.set(k, new Set(v));
|
|
48554
48760
|
}
|
|
48555
48761
|
}
|
|
48556
|
-
const { layoutBoxesAndLines: layoutBoxesAndLines2 } = await Promise.resolve().then(() => (init_layout5(), layout_exports5));
|
|
48557
48762
|
const { renderBoxesAndLinesForExport: renderBoxesAndLinesForExport2 } = await Promise.resolve().then(() => (init_renderer6(), renderer_exports6));
|
|
48558
|
-
const
|
|
48763
|
+
const { layoutBoxesAndLines: layoutBoxesAndLines2 } = await Promise.resolve().then(() => (init_layout5(), layout_exports5));
|
|
48764
|
+
const blLayout = await layoutBoxesAndLines2(blParsed);
|
|
48559
48765
|
const PADDING3 = 20;
|
|
48560
48766
|
const titleOffset = blParsed.title ? 40 : 0;
|
|
48561
48767
|
const exportWidth = blLayout.width + PADDING3 * 2;
|
|
@@ -49813,7 +50019,8 @@ async function render2(text, options) {
|
|
|
49813
50019
|
const onError = options?.onError ?? "svg";
|
|
49814
50020
|
const result = await render(text, {
|
|
49815
50021
|
theme: options?.theme,
|
|
49816
|
-
palette: palette.id
|
|
50022
|
+
palette: palette.id,
|
|
50023
|
+
viewState: options?.viewState
|
|
49817
50024
|
});
|
|
49818
50025
|
const errors = result.diagnostics.filter((d) => d.severity === "error");
|
|
49819
50026
|
if (errors.length === 0) {
|
|
@@ -49853,7 +50060,8 @@ function encodeDiagramUrl2(text, options) {
|
|
|
49853
50060
|
baseUrl: options?.baseUrl,
|
|
49854
50061
|
palette: options?.palette?.id,
|
|
49855
50062
|
theme: internalTheme,
|
|
49856
|
-
filename: options?.filename
|
|
50063
|
+
filename: options?.filename,
|
|
50064
|
+
viewState: options?.viewState
|
|
49857
50065
|
});
|
|
49858
50066
|
return "error" in result && result.error ? null : result.url ?? null;
|
|
49859
50067
|
}
|
|
@@ -49871,6 +50079,7 @@ export {
|
|
|
49871
50079
|
decodeDiagramUrl2 as decodeDiagramUrl,
|
|
49872
50080
|
encodeDiagramUrl2 as encodeDiagramUrl,
|
|
49873
50081
|
formatDgmoError,
|
|
50082
|
+
getPalette,
|
|
49874
50083
|
palettes,
|
|
49875
50084
|
render2 as render,
|
|
49876
50085
|
themes,
|