@diagrammo/dgmo 0.14.1 → 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 +1557 -1295
- package/dist/auto.js +132 -713
- package/dist/auto.mjs +1553 -1291
- package/dist/cli.cjs +173 -150
- package/dist/editor.cjs +1 -0
- package/dist/editor.js +1 -0
- package/dist/highlight.cjs +1 -0
- package/dist/highlight.js +1 -0
- package/dist/index.cjs +2031 -4722
- package/dist/index.d.cts +96 -4464
- package/dist/index.d.ts +96 -4464
- package/dist/index.js +2024 -4475
- package/dist/internal.cjs +51930 -553
- package/dist/internal.d.cts +4526 -102
- package/dist/internal.d.ts +4526 -102
- package/dist/internal.js +51721 -548
- package/dist/pert.cjs +1 -1
- package/dist/pert.js +1 -1
- package/docs/language-reference.md +67 -17
- package/package.json +18 -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/editor/keywords.ts +1 -0
- 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 +213 -690
- package/src/infra/parser.ts +57 -25
- package/src/infra/renderer.ts +2 -2
- package/src/internal.ts +11 -17
- 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/palettes/index.ts +39 -0
- 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/render.ts +17 -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/themes.ts +22 -0
- 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/auto.cjs
CHANGED
|
@@ -1761,6 +1761,7 @@ __export(palettes_exports, {
|
|
|
1761
1761
|
monokaiPalette: () => monokaiPalette,
|
|
1762
1762
|
nordPalette: () => nordPalette,
|
|
1763
1763
|
oneDarkPalette: () => oneDarkPalette,
|
|
1764
|
+
palettes: () => palettes,
|
|
1764
1765
|
registerPalette: () => registerPalette,
|
|
1765
1766
|
rosePinePalette: () => rosePinePalette,
|
|
1766
1767
|
shade: () => shade,
|
|
@@ -1769,6 +1770,7 @@ __export(palettes_exports, {
|
|
|
1769
1770
|
tint: () => tint,
|
|
1770
1771
|
tokyoNightPalette: () => tokyoNightPalette
|
|
1771
1772
|
});
|
|
1773
|
+
var palettes;
|
|
1772
1774
|
var init_palettes = __esm({
|
|
1773
1775
|
"src/palettes/index.ts"() {
|
|
1774
1776
|
"use strict";
|
|
@@ -1784,6 +1786,28 @@ var init_palettes = __esm({
|
|
|
1784
1786
|
init_tokyo_night();
|
|
1785
1787
|
init_dracula();
|
|
1786
1788
|
init_monokai();
|
|
1789
|
+
init_bold();
|
|
1790
|
+
init_catppuccin();
|
|
1791
|
+
init_dracula();
|
|
1792
|
+
init_gruvbox();
|
|
1793
|
+
init_monokai();
|
|
1794
|
+
init_nord();
|
|
1795
|
+
init_one_dark();
|
|
1796
|
+
init_rose_pine();
|
|
1797
|
+
init_solarized();
|
|
1798
|
+
init_tokyo_night();
|
|
1799
|
+
palettes = {
|
|
1800
|
+
nord: nordPalette,
|
|
1801
|
+
catppuccin: catppuccinPalette,
|
|
1802
|
+
solarized: solarizedPalette,
|
|
1803
|
+
gruvbox: gruvboxPalette,
|
|
1804
|
+
tokyoNight: tokyoNightPalette,
|
|
1805
|
+
oneDark: oneDarkPalette,
|
|
1806
|
+
rosePine: rosePinePalette,
|
|
1807
|
+
dracula: draculaPalette,
|
|
1808
|
+
monokai: monokaiPalette,
|
|
1809
|
+
bold: boldPalette
|
|
1810
|
+
};
|
|
1787
1811
|
}
|
|
1788
1812
|
});
|
|
1789
1813
|
|
|
@@ -2214,7 +2238,7 @@ function injectDefaultTagMetadata(entities, tagGroups, skip) {
|
|
|
2214
2238
|
}
|
|
2215
2239
|
}
|
|
2216
2240
|
}
|
|
2217
|
-
function resolveActiveTagGroup(
|
|
2241
|
+
function resolveActiveTagGroup(tagGroups, explicitActiveTag, programmaticOverride) {
|
|
2218
2242
|
if (programmaticOverride !== void 0) {
|
|
2219
2243
|
if (!programmaticOverride) return null;
|
|
2220
2244
|
if (programmaticOverride.toLowerCase() === "none") return null;
|
|
@@ -2224,6 +2248,7 @@ function resolveActiveTagGroup(_tagGroups, explicitActiveTag, programmaticOverri
|
|
|
2224
2248
|
if (explicitActiveTag.toLowerCase() === "none") return null;
|
|
2225
2249
|
return explicitActiveTag;
|
|
2226
2250
|
}
|
|
2251
|
+
if (tagGroups.length > 0) return tagGroups[0].name;
|
|
2227
2252
|
return null;
|
|
2228
2253
|
}
|
|
2229
2254
|
function matchTagBlockHeading(trimmed) {
|
|
@@ -5304,12 +5329,6 @@ function parseClassDiagram(content, palette) {
|
|
|
5304
5329
|
diagnostics: [],
|
|
5305
5330
|
error: null
|
|
5306
5331
|
};
|
|
5307
|
-
const _fail = (line12, message) => {
|
|
5308
|
-
const diag = makeDgmoError(line12, message);
|
|
5309
|
-
result.diagnostics.push(diag);
|
|
5310
|
-
result.error = formatDgmoError(diag);
|
|
5311
|
-
return result;
|
|
5312
|
-
};
|
|
5313
5332
|
const classMap = /* @__PURE__ */ new Map();
|
|
5314
5333
|
const nameAliasMap = /* @__PURE__ */ new Map();
|
|
5315
5334
|
function resolveAliasName(token) {
|
|
@@ -5704,12 +5723,6 @@ function parseERDiagram(content, palette) {
|
|
|
5704
5723
|
diagnostics: [],
|
|
5705
5724
|
error: null
|
|
5706
5725
|
};
|
|
5707
|
-
const _fail = (line12, message) => {
|
|
5708
|
-
const diag = makeDgmoError(line12, message);
|
|
5709
|
-
result.diagnostics.push(diag);
|
|
5710
|
-
result.error = formatDgmoError(diag);
|
|
5711
|
-
return result;
|
|
5712
|
-
};
|
|
5713
5726
|
const pushError = (line12, message) => {
|
|
5714
5727
|
const diag = makeDgmoError(line12, message);
|
|
5715
5728
|
result.diagnostics.push(diag);
|
|
@@ -7146,7 +7159,7 @@ function buildSankeyOption(parsed, textColor, colors, bg, titleConfig) {
|
|
|
7146
7159
|
]
|
|
7147
7160
|
};
|
|
7148
7161
|
}
|
|
7149
|
-
function buildChordOption(parsed, palette, isDark, textColor, colors,
|
|
7162
|
+
function buildChordOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
7150
7163
|
const nodeSet = /* @__PURE__ */ new Set();
|
|
7151
7164
|
if (parsed.links) {
|
|
7152
7165
|
for (const link of parsed.links) {
|
|
@@ -7260,7 +7273,7 @@ function evaluateExpression(expr, x) {
|
|
|
7260
7273
|
return NaN;
|
|
7261
7274
|
}
|
|
7262
7275
|
}
|
|
7263
|
-
function buildFunctionOption(parsed, palette,
|
|
7276
|
+
function buildFunctionOption(parsed, palette, _isDark, textColor, axisLineColor, gridOpacity, colors, titleConfig) {
|
|
7264
7277
|
const xRange = parsed.xRange ?? { min: -10, max: 10 };
|
|
7265
7278
|
const samples = 200;
|
|
7266
7279
|
const step = (xRange.max - xRange.min) / samples;
|
|
@@ -7933,7 +7946,7 @@ function buildHeatmapOption(parsed, palette, isDark, textColor, axisLineColor, t
|
|
|
7933
7946
|
]
|
|
7934
7947
|
};
|
|
7935
7948
|
}
|
|
7936
|
-
function buildFunnelOption(parsed, palette, isDark, textColor, colors,
|
|
7949
|
+
function buildFunnelOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
7937
7950
|
const sorted = [...parsed.data].sort((a, b) => b.value - a.value);
|
|
7938
7951
|
const data = sorted.map((d) => {
|
|
7939
7952
|
const stroke2 = d.color ?? colors[parsed.data.indexOf(d) % colors.length];
|
|
@@ -8216,7 +8229,7 @@ function wrapLabel(text, maxChars) {
|
|
|
8216
8229
|
if (current) lines.push(current);
|
|
8217
8230
|
return lines.join("\n");
|
|
8218
8231
|
}
|
|
8219
|
-
function buildBarOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors,
|
|
8232
|
+
function buildBarOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors, _bg, titleConfig, chartWidth) {
|
|
8220
8233
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
8221
8234
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
8222
8235
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -8543,7 +8556,7 @@ function pieLabelLayout(parsed) {
|
|
|
8543
8556
|
if (maxLen > 18) return { outerRadius: 55, fontSize: 13 };
|
|
8544
8557
|
return { outerRadius: 70, fontSize: 14 };
|
|
8545
8558
|
}
|
|
8546
|
-
function buildPieOption(parsed, palette, isDark, textColor, colors,
|
|
8559
|
+
function buildPieOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig, isDoughnut) {
|
|
8547
8560
|
const HIDE_AXES = { xAxis: { show: false }, yAxis: { show: false } };
|
|
8548
8561
|
const data = parsed.data.map((d, i) => {
|
|
8549
8562
|
const stroke2 = d.color ?? colors[i % colors.length];
|
|
@@ -8642,7 +8655,7 @@ function buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, title
|
|
|
8642
8655
|
]
|
|
8643
8656
|
};
|
|
8644
8657
|
}
|
|
8645
|
-
function buildPolarAreaOption(parsed, palette, isDark, textColor, colors,
|
|
8658
|
+
function buildPolarAreaOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
8646
8659
|
const data = parsed.data.map((d, i) => {
|
|
8647
8660
|
const stroke2 = d.color ?? colors[i % colors.length];
|
|
8648
8661
|
return {
|
|
@@ -8685,7 +8698,7 @@ function buildPolarAreaOption(parsed, palette, isDark, textColor, colors, bg, ti
|
|
|
8685
8698
|
]
|
|
8686
8699
|
};
|
|
8687
8700
|
}
|
|
8688
|
-
function buildBarStackedOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors,
|
|
8701
|
+
function buildBarStackedOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors, _bg, titleConfig, chartWidth) {
|
|
8689
8702
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
8690
8703
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
8691
8704
|
const seriesNames = parsed.seriesNames ?? [];
|
|
@@ -8825,8 +8838,8 @@ async function renderExtendedChartForExport(content, theme, palette) {
|
|
|
8825
8838
|
const titleHeight = option.title && option.title.text ? 40 : 0;
|
|
8826
8839
|
const legendY = 8 + titleHeight;
|
|
8827
8840
|
const grid = option.grid;
|
|
8828
|
-
const gridLeftPct = grid?.left ? parseFloat(String(grid
|
|
8829
|
-
const gridRightPct = grid?.right ? parseFloat(String(grid
|
|
8841
|
+
const gridLeftPct = grid?.["left"] ? parseFloat(String(grid["left"])) : void 0;
|
|
8842
|
+
const gridRightPct = grid?.["right"] ? parseFloat(String(grid["right"])) : void 0;
|
|
8830
8843
|
const { svg: legendSvgStr } = renderLegendSvg(legendGroups, {
|
|
8831
8844
|
palette: effectivePalette,
|
|
8832
8845
|
isDark,
|
|
@@ -9176,7 +9189,7 @@ function parseOrg(content, palette) {
|
|
|
9176
9189
|
}
|
|
9177
9190
|
return result;
|
|
9178
9191
|
}
|
|
9179
|
-
function parseNodeLabel(trimmed, _indent, lineNumber,
|
|
9192
|
+
function parseNodeLabel(trimmed, _indent, lineNumber, _palette, counter, metaAliasMap = /* @__PURE__ */ new Map(), warnFn, nameAliasMap) {
|
|
9180
9193
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
9181
9194
|
let label = segments[0];
|
|
9182
9195
|
const asMatch = label.match(/^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/);
|
|
@@ -9425,8 +9438,8 @@ function parseKanban(content, palette) {
|
|
|
9425
9438
|
columnMetadata,
|
|
9426
9439
|
parsePipeMetadata(pipeSegments, metaAliasMap)
|
|
9427
9440
|
);
|
|
9428
|
-
if (columnMetadata
|
|
9429
|
-
const wipVal = parseInt(columnMetadata
|
|
9441
|
+
if (columnMetadata["wip"]) {
|
|
9442
|
+
const wipVal = parseInt(columnMetadata["wip"], 10);
|
|
9430
9443
|
if (!isNaN(wipVal)) {
|
|
9431
9444
|
wipLimit = wipVal;
|
|
9432
9445
|
}
|
|
@@ -9805,7 +9818,7 @@ function parseC4(content, palette) {
|
|
|
9805
9818
|
);
|
|
9806
9819
|
const shape = inferC4Shape(
|
|
9807
9820
|
nodeName,
|
|
9808
|
-
metadata
|
|
9821
|
+
metadata["tech"] ?? metadata["technology"]
|
|
9809
9822
|
);
|
|
9810
9823
|
const dNode = {
|
|
9811
9824
|
name: nodeName,
|
|
@@ -9908,11 +9921,11 @@ function parseC4(content, palette) {
|
|
|
9908
9921
|
target = targetBody.substring(0, pipeIdx).trim();
|
|
9909
9922
|
const metaPart = targetBody.substring(pipeIdx + 1).trim();
|
|
9910
9923
|
const meta = parsePipeMetadata(["", metaPart], metaAliasMap);
|
|
9911
|
-
if (meta
|
|
9912
|
-
technology = meta
|
|
9924
|
+
if (meta["tech"]) {
|
|
9925
|
+
technology = meta["tech"];
|
|
9913
9926
|
}
|
|
9914
|
-
if (meta
|
|
9915
|
-
technology = meta
|
|
9927
|
+
if (meta["technology"]) {
|
|
9928
|
+
technology = meta["technology"];
|
|
9916
9929
|
}
|
|
9917
9930
|
}
|
|
9918
9931
|
const rel = {
|
|
@@ -10046,7 +10059,7 @@ function parseC4(content, palette) {
|
|
|
10046
10059
|
metaAliasMap,
|
|
10047
10060
|
() => pushError(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
10048
10061
|
);
|
|
10049
|
-
const shape = explicitShape ?? inferC4Shape(namePart, metadata
|
|
10062
|
+
const shape = explicitShape ?? inferC4Shape(namePart, metadata["tech"] ?? metadata["technology"]);
|
|
10050
10063
|
let isADescription;
|
|
10051
10064
|
if ("description" in metadata) {
|
|
10052
10065
|
const descVal = metadata["description"].trim();
|
|
@@ -10106,7 +10119,7 @@ function parseC4(content, palette) {
|
|
|
10106
10119
|
metaAliasMap,
|
|
10107
10120
|
() => pushError(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
10108
10121
|
);
|
|
10109
|
-
const shape = explicitShape ?? inferC4Shape(namePart, metadata
|
|
10122
|
+
const shape = explicitShape ?? inferC4Shape(namePart, metadata["tech"] ?? metadata["technology"]);
|
|
10110
10123
|
let prefixDescription;
|
|
10111
10124
|
if ("description" in metadata) {
|
|
10112
10125
|
const descVal = metadata["description"].trim();
|
|
@@ -10715,7 +10728,7 @@ function parseSitemap(content, palette) {
|
|
|
10715
10728
|
}
|
|
10716
10729
|
return result;
|
|
10717
10730
|
}
|
|
10718
|
-
function parseNodeLabel2(trimmed, lineNumber,
|
|
10731
|
+
function parseNodeLabel2(trimmed, lineNumber, _palette, counter, metaAliasMap = /* @__PURE__ */ new Map(), warnFn, _diagnostics, nameAliasMap) {
|
|
10719
10732
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
10720
10733
|
let label = segments[0];
|
|
10721
10734
|
const asMatch = label.match(/^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/);
|
|
@@ -10892,6 +10905,17 @@ function parseInfra(content) {
|
|
|
10892
10905
|
if (!m) return { label: trimmed };
|
|
10893
10906
|
return { label: m[1].trim(), alias: m[2] };
|
|
10894
10907
|
}
|
|
10908
|
+
const IS_A_SUFFIX = /^(.*?)\s+is\s+an?\s+[A-Za-z][\w-]*\s*$/i;
|
|
10909
|
+
function peelInfraDecorations(rawName, lineNumber) {
|
|
10910
|
+
const peeled = peelAlias2(rawName);
|
|
10911
|
+
const m = peeled.label.match(IS_A_SUFFIX);
|
|
10912
|
+
if (!m) return peeled;
|
|
10913
|
+
warn2(
|
|
10914
|
+
lineNumber,
|
|
10915
|
+
`Infra nodes don't use 'is a <type>' \u2014 types are inferred from properties (cache-hit, buffer, drain-rate, \u2026). Drop the 'is a' suffix.`
|
|
10916
|
+
);
|
|
10917
|
+
return { label: m[1].trim(), alias: peeled.alias };
|
|
10918
|
+
}
|
|
10895
10919
|
function resolveTargetId(rawName) {
|
|
10896
10920
|
const aliasResolved = nameAliasMap.get(rawName.trim());
|
|
10897
10921
|
if (aliasResolved !== void 0) return aliasResolved;
|
|
@@ -10995,11 +11019,11 @@ function parseInfra(content) {
|
|
|
10995
11019
|
continue;
|
|
10996
11020
|
}
|
|
10997
11021
|
if (trimmed === "animate") {
|
|
10998
|
-
result.options
|
|
11022
|
+
result.options["animate"] = "on";
|
|
10999
11023
|
continue;
|
|
11000
11024
|
}
|
|
11001
11025
|
if (trimmed === "no-animate") {
|
|
11002
|
-
result.options
|
|
11026
|
+
result.options["animate"] = "off";
|
|
11003
11027
|
continue;
|
|
11004
11028
|
}
|
|
11005
11029
|
if (tryParseSharedOption(trimmed, result.options)) {
|
|
@@ -11046,7 +11070,7 @@ function parseInfra(content) {
|
|
|
11046
11070
|
finishCurrentNode();
|
|
11047
11071
|
finishCurrentTagGroup();
|
|
11048
11072
|
const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
|
|
11049
|
-
const peeled =
|
|
11073
|
+
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
11050
11074
|
const name = peeled.label;
|
|
11051
11075
|
const rest = compMatch[3] || "";
|
|
11052
11076
|
const { tags } = extractPipeMetadata(rest);
|
|
@@ -11117,7 +11141,7 @@ function parseInfra(content) {
|
|
|
11117
11141
|
if (compMatch) {
|
|
11118
11142
|
finishCurrentTagGroup();
|
|
11119
11143
|
const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
|
|
11120
|
-
const peeled =
|
|
11144
|
+
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
11121
11145
|
const name = peeled.label;
|
|
11122
11146
|
const rest = compMatch[3] || "";
|
|
11123
11147
|
const { tags: nodeTags } = extractPipeMetadata(rest);
|
|
@@ -11153,8 +11177,8 @@ function parseInfra(content) {
|
|
|
11153
11177
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11154
11178
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11155
11179
|
warnUnparsedPipeMeta(targetName, lineNumber, warn2);
|
|
11156
|
-
const split = pipeMeta.tags
|
|
11157
|
-
const fanoutRaw = pipeMeta.tags
|
|
11180
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11181
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11158
11182
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11159
11183
|
warn2(
|
|
11160
11184
|
lineNumber,
|
|
@@ -11185,8 +11209,8 @@ function parseInfra(content) {
|
|
|
11185
11209
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11186
11210
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11187
11211
|
warnUnparsedPipeMeta(targetName, lineNumber, warn2);
|
|
11188
|
-
const split = pipeMeta.tags
|
|
11189
|
-
const fanoutRaw = pipeMeta.tags
|
|
11212
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11213
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11190
11214
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11191
11215
|
warn2(
|
|
11192
11216
|
lineNumber,
|
|
@@ -11220,8 +11244,8 @@ function parseInfra(content) {
|
|
|
11220
11244
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11221
11245
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11222
11246
|
warnUnparsedPipeMeta(targetName, lineNumber, warn2);
|
|
11223
|
-
const split = pipeMeta.tags
|
|
11224
|
-
const fanoutRaw = pipeMeta.tags
|
|
11247
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11248
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11225
11249
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11226
11250
|
warn2(
|
|
11227
11251
|
lineNumber,
|
|
@@ -11252,8 +11276,8 @@ function parseInfra(content) {
|
|
|
11252
11276
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11253
11277
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11254
11278
|
warnUnparsedPipeMeta(targetName, lineNumber, warn2);
|
|
11255
|
-
const split = pipeMeta.tags
|
|
11256
|
-
const fanoutRaw = pipeMeta.tags
|
|
11279
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11280
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11257
11281
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11258
11282
|
warn2(
|
|
11259
11283
|
lineNumber,
|
|
@@ -11336,7 +11360,7 @@ function parseInfra(content) {
|
|
|
11336
11360
|
const compMatch = trimmed.match(COMPONENT_RE);
|
|
11337
11361
|
if (compMatch) {
|
|
11338
11362
|
const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
|
|
11339
|
-
const peeled =
|
|
11363
|
+
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
11340
11364
|
const name = peeled.label;
|
|
11341
11365
|
const rest = compMatch[3] || "";
|
|
11342
11366
|
const { tags: nodeTags } = extractPipeMetadata(rest);
|
|
@@ -11362,10 +11386,13 @@ function parseInfra(content) {
|
|
|
11362
11386
|
finishCurrentNode();
|
|
11363
11387
|
finishCurrentTagGroup();
|
|
11364
11388
|
currentGroup = null;
|
|
11365
|
-
const
|
|
11389
|
+
const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
|
|
11390
|
+
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
11391
|
+
const name = peeled.label;
|
|
11366
11392
|
const rest = compMatch[3] || "";
|
|
11367
11393
|
const { tags } = extractPipeMetadata(rest);
|
|
11368
11394
|
const id = nodeId2(name);
|
|
11395
|
+
if (peeled.alias) nameAliasMap.set(peeled.alias, id);
|
|
11369
11396
|
currentNode = {
|
|
11370
11397
|
id,
|
|
11371
11398
|
label: name,
|
|
@@ -11415,6 +11442,14 @@ function parseInfra(content) {
|
|
|
11415
11442
|
validateTagGroupNames(result.tagGroups, warn2, setError);
|
|
11416
11443
|
return result;
|
|
11417
11444
|
}
|
|
11445
|
+
function stripNodeDecorations(name) {
|
|
11446
|
+
let s = name.trim();
|
|
11447
|
+
const aliasMatch = s.match(/^(.*?)\s+as\s+[A-Za-z][A-Za-z0-9_]{0,11}\s*$/);
|
|
11448
|
+
if (aliasMatch) s = aliasMatch[1].trim();
|
|
11449
|
+
const isAMatch = s.match(/^(.*?)\s+is\s+an?\s+[A-Za-z][\w-]*\s*$/i);
|
|
11450
|
+
if (isAMatch) s = isAMatch[1].trim();
|
|
11451
|
+
return s;
|
|
11452
|
+
}
|
|
11418
11453
|
function extractSymbols4(docText) {
|
|
11419
11454
|
const entities = [];
|
|
11420
11455
|
let inMetadata = true;
|
|
@@ -11448,7 +11483,7 @@ function extractSymbols4(docText) {
|
|
|
11448
11483
|
if (/^\[/.test(line12)) continue;
|
|
11449
11484
|
const m = COMPONENT_RE.exec(line12);
|
|
11450
11485
|
if (m) {
|
|
11451
|
-
const name = (m[1] ?? m[2] ?? "").trim();
|
|
11486
|
+
const name = stripNodeDecorations((m[1] ?? m[2] ?? "").trim());
|
|
11452
11487
|
if (name && !entities.includes(name)) entities.push(name);
|
|
11453
11488
|
}
|
|
11454
11489
|
} else {
|
|
@@ -11463,7 +11498,7 @@ function extractSymbols4(docText) {
|
|
|
11463
11498
|
continue;
|
|
11464
11499
|
const m = COMPONENT_RE.exec(line12);
|
|
11465
11500
|
if (m) {
|
|
11466
|
-
const name = (m[1] ?? m[2] ?? "").trim();
|
|
11501
|
+
const name = stripNodeDecorations((m[1] ?? m[2] ?? "").trim());
|
|
11467
11502
|
if (name && !entities.includes(name)) entities.push(name);
|
|
11468
11503
|
}
|
|
11469
11504
|
}
|
|
@@ -11949,15 +11984,15 @@ function parseGantt(content, palette) {
|
|
|
11949
11984
|
metaAliasMap,
|
|
11950
11985
|
() => warn2(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
11951
11986
|
);
|
|
11952
|
-
if (meta
|
|
11953
|
-
const key = meta
|
|
11987
|
+
if (meta["lag"] || meta["lead"]) {
|
|
11988
|
+
const key = meta["lag"] ? "lag" : "lead";
|
|
11954
11989
|
softError(
|
|
11955
11990
|
lineNumber,
|
|
11956
11991
|
`"${key}" is no longer supported \u2014 use "offset: ${meta[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
11957
11992
|
);
|
|
11958
11993
|
}
|
|
11959
|
-
if (meta
|
|
11960
|
-
const raw = meta
|
|
11994
|
+
if (meta["offset"]) {
|
|
11995
|
+
const raw = meta["offset"];
|
|
11961
11996
|
if (raw.trim().startsWith("+")) {
|
|
11962
11997
|
warn2(
|
|
11963
11998
|
lineNumber,
|
|
@@ -12344,15 +12379,15 @@ function parseGantt(content, palette) {
|
|
|
12344
12379
|
metaAliasMap,
|
|
12345
12380
|
() => warn2(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
12346
12381
|
);
|
|
12347
|
-
if (meta
|
|
12348
|
-
const key = meta
|
|
12382
|
+
if (meta["lag"] || meta["lead"]) {
|
|
12383
|
+
const key = meta["lag"] ? "lag" : "lead";
|
|
12349
12384
|
softError(
|
|
12350
12385
|
lineNumber,
|
|
12351
12386
|
`"${key}" is no longer supported \u2014 use "offset: ${meta[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
12352
12387
|
);
|
|
12353
12388
|
}
|
|
12354
|
-
if (meta
|
|
12355
|
-
const raw = meta
|
|
12389
|
+
if (meta["offset"]) {
|
|
12390
|
+
const raw = meta["offset"];
|
|
12356
12391
|
if (raw.trim().startsWith("+")) {
|
|
12357
12392
|
warn2(
|
|
12358
12393
|
lineNumber,
|
|
@@ -12423,9 +12458,9 @@ function parseGantt(content, palette) {
|
|
|
12423
12458
|
() => warn2(ln, MULTIPLE_PIPE_ERROR)
|
|
12424
12459
|
) : {};
|
|
12425
12460
|
let progress = null;
|
|
12426
|
-
if (metadata
|
|
12427
|
-
progress = parseFloat(metadata
|
|
12428
|
-
delete metadata
|
|
12461
|
+
if (metadata["progress"]) {
|
|
12462
|
+
progress = parseFloat(metadata["progress"]);
|
|
12463
|
+
delete metadata["progress"];
|
|
12429
12464
|
}
|
|
12430
12465
|
for (const part of segments.slice(1).join(",").split(",")) {
|
|
12431
12466
|
const seg = part.trim();
|
|
@@ -12434,16 +12469,16 @@ function parseGantt(content, palette) {
|
|
|
12434
12469
|
progress = parseInt(progressMatch[1], 10);
|
|
12435
12470
|
}
|
|
12436
12471
|
}
|
|
12437
|
-
if (metadata
|
|
12438
|
-
const key = metadata
|
|
12472
|
+
if (metadata["lag"] || metadata["lead"]) {
|
|
12473
|
+
const key = metadata["lag"] ? "lag" : "lead";
|
|
12439
12474
|
softError(
|
|
12440
12475
|
ln,
|
|
12441
12476
|
`"${key}" is no longer supported \u2014 use "offset: ${metadata[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
12442
12477
|
);
|
|
12443
12478
|
}
|
|
12444
12479
|
let taskOffset;
|
|
12445
|
-
if (metadata
|
|
12446
|
-
const raw = metadata
|
|
12480
|
+
if (metadata["offset"]) {
|
|
12481
|
+
const raw = metadata["offset"];
|
|
12447
12482
|
if (raw.trim().startsWith("+")) {
|
|
12448
12483
|
warn2(
|
|
12449
12484
|
ln,
|
|
@@ -12458,7 +12493,7 @@ function parseGantt(content, palette) {
|
|
|
12458
12493
|
);
|
|
12459
12494
|
}
|
|
12460
12495
|
}
|
|
12461
|
-
delete metadata
|
|
12496
|
+
delete metadata["offset"];
|
|
12462
12497
|
}
|
|
12463
12498
|
const groupPath = currentGroupPath();
|
|
12464
12499
|
const inheritedMeta = {};
|
|
@@ -12981,7 +13016,7 @@ function parsePert(content, parseOpts = {}) {
|
|
|
12981
13016
|
id,
|
|
12982
13017
|
name,
|
|
12983
13018
|
activityIds: [],
|
|
12984
|
-
collapsed: meta
|
|
13019
|
+
collapsed: meta["collapsed"] === "true",
|
|
12985
13020
|
lineNumber,
|
|
12986
13021
|
...Object.keys(tags).length > 0 && { tags }
|
|
12987
13022
|
});
|
|
@@ -13243,7 +13278,7 @@ function parsePert(content, parseOpts = {}) {
|
|
|
13243
13278
|
name: decl.name,
|
|
13244
13279
|
...decl.alias !== void 0 && { alias: decl.alias },
|
|
13245
13280
|
duration: estimate,
|
|
13246
|
-
...meta
|
|
13281
|
+
...meta["confidence"] && { confidence: meta["confidence"] },
|
|
13247
13282
|
...decl.groupHint !== void 0 && { groupId: decl.groupHint },
|
|
13248
13283
|
lineNumber: decl.lineNumber,
|
|
13249
13284
|
isMilestone,
|
|
@@ -14574,7 +14609,7 @@ function parseMindmap(content, palette) {
|
|
|
14574
14609
|
}
|
|
14575
14610
|
return result;
|
|
14576
14611
|
}
|
|
14577
|
-
function parseNodeLine2(trimmed, lineNumber,
|
|
14612
|
+
function parseNodeLine2(trimmed, lineNumber, _palette, counter, aliasMap, warnFn) {
|
|
14578
14613
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
14579
14614
|
const label = segments[0];
|
|
14580
14615
|
const metadata = parsePipeMetadata(
|
|
@@ -15018,7 +15053,7 @@ function parseWireframe(content) {
|
|
|
15018
15053
|
wrapper.isContainer = true;
|
|
15019
15054
|
wrapper.orientation = "horizontal";
|
|
15020
15055
|
wrapper.children = children;
|
|
15021
|
-
wrapper.metadata
|
|
15056
|
+
wrapper.metadata["_inlineRow"] = "true";
|
|
15022
15057
|
pushElement(wrapper);
|
|
15023
15058
|
}
|
|
15024
15059
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -15169,7 +15204,7 @@ function parseWireframe(content) {
|
|
|
15169
15204
|
wrapper.isContainer = true;
|
|
15170
15205
|
wrapper.orientation = "horizontal";
|
|
15171
15206
|
wrapper.children.push(labelEl, fieldEl);
|
|
15172
|
-
wrapper.metadata
|
|
15207
|
+
wrapper.metadata["_labelField"] = "true";
|
|
15173
15208
|
pushElement(wrapper);
|
|
15174
15209
|
}
|
|
15175
15210
|
} else {
|
|
@@ -16990,9 +17025,9 @@ function parseRaci(content, palette) {
|
|
|
16990
17025
|
let roleColor;
|
|
16991
17026
|
if (segments.length > 1) {
|
|
16992
17027
|
const meta = parsePipeMetadata(segments);
|
|
16993
|
-
if (meta
|
|
17028
|
+
if (meta["color"]) {
|
|
16994
17029
|
roleColor = resolveColorWithDiagnostic(
|
|
16995
|
-
meta
|
|
17030
|
+
meta["color"],
|
|
16996
17031
|
j + 1,
|
|
16997
17032
|
result.diagnostics,
|
|
16998
17033
|
palette
|
|
@@ -17059,9 +17094,9 @@ function parseRaci(content, palette) {
|
|
|
17059
17094
|
let phaseColor;
|
|
17060
17095
|
if (phaseMatch[2]) {
|
|
17061
17096
|
const meta = parsePipeMetadata(["", phaseMatch[2]]);
|
|
17062
|
-
if (meta
|
|
17097
|
+
if (meta["color"]) {
|
|
17063
17098
|
phaseColor = resolveColorWithDiagnostic(
|
|
17064
|
-
meta
|
|
17099
|
+
meta["color"],
|
|
17065
17100
|
lineNumber,
|
|
17066
17101
|
result.diagnostics,
|
|
17067
17102
|
palette
|
|
@@ -19070,7 +19105,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
19070
19105
|
displayNames.set(group.name.toLowerCase(), group.name);
|
|
19071
19106
|
}
|
|
19072
19107
|
const rootNodeIds = new Set(parsed.roots.map((r) => r.id));
|
|
19073
|
-
const colorOff = parsed.options?.color === "off";
|
|
19108
|
+
const colorOff = parsed.options?.["color"] === "off";
|
|
19074
19109
|
for (const c of layout.containers) {
|
|
19075
19110
|
const cG = contentG.append("g").attr("transform", `translate(${c.x}, ${c.y})`).attr("class", "org-container").attr("data-line-number", String(c.lineNumber));
|
|
19076
19111
|
if (activeTagGroup) {
|
|
@@ -22170,7 +22205,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
|
|
|
22170
22205
|
const seriesColors2 = getSeriesColors(palette);
|
|
22171
22206
|
const semanticRoles = useSemanticColors ? classifyEREntities(parsed.tables, parsed.relationships) : null;
|
|
22172
22207
|
const semanticActive = semanticRoles !== null && (semanticColorsActive ?? true);
|
|
22173
|
-
const useLabels = parsed.options
|
|
22208
|
+
const useLabels = parsed.options["notation"] === "labels";
|
|
22174
22209
|
for (const edge of layout.edges) {
|
|
22175
22210
|
if (edge.points.length < 2) continue;
|
|
22176
22211
|
const edgeG = contentG.append("g").attr("class", "er-edge-group").attr("data-line-number", String(edge.lineNumber));
|
|
@@ -22385,495 +22420,6 @@ var init_renderer5 = __esm({
|
|
|
22385
22420
|
}
|
|
22386
22421
|
});
|
|
22387
22422
|
|
|
22388
|
-
// src/boxes-and-lines/layout.ts
|
|
22389
|
-
var layout_exports5 = {};
|
|
22390
|
-
__export(layout_exports5, {
|
|
22391
|
-
layoutBoxesAndLines: () => layoutBoxesAndLines
|
|
22392
|
-
});
|
|
22393
|
-
function clipToRectBorder2(cx, cy, w, h, tx, ty) {
|
|
22394
|
-
const dx = tx - cx;
|
|
22395
|
-
const dy = ty - cy;
|
|
22396
|
-
if (dx === 0 && dy === 0) return { x: cx, y: cy };
|
|
22397
|
-
const hw = w / 2;
|
|
22398
|
-
const hh = h / 2;
|
|
22399
|
-
const sx = dx !== 0 ? hw / Math.abs(dx) : Infinity;
|
|
22400
|
-
const sy = dy !== 0 ? hh / Math.abs(dy) : Infinity;
|
|
22401
|
-
const s = Math.min(sx, sy);
|
|
22402
|
-
return { x: cx + dx * s, y: cy + dy * s };
|
|
22403
|
-
}
|
|
22404
|
-
function splitCamelCase(word) {
|
|
22405
|
-
const parts = [];
|
|
22406
|
-
let start = 0;
|
|
22407
|
-
for (let i = 1; i < word.length; i++) {
|
|
22408
|
-
const prev = word[i - 1];
|
|
22409
|
-
const curr = word[i];
|
|
22410
|
-
const next = i + 1 < word.length ? word[i + 1] : "";
|
|
22411
|
-
const lowerToUpper = prev >= "a" && prev <= "z" && curr >= "A" && curr <= "Z";
|
|
22412
|
-
const upperRunEnd = prev >= "A" && prev <= "Z" && curr >= "A" && curr <= "Z" && next >= "a" && next <= "z";
|
|
22413
|
-
if (lowerToUpper || upperRunEnd) {
|
|
22414
|
-
parts.push(word.slice(start, i));
|
|
22415
|
-
start = i;
|
|
22416
|
-
}
|
|
22417
|
-
}
|
|
22418
|
-
parts.push(word.slice(start));
|
|
22419
|
-
return parts.length > 1 ? parts : [word];
|
|
22420
|
-
}
|
|
22421
|
-
function estimateLabelLines(label, nodeWidth2 = NODE_WIDTH) {
|
|
22422
|
-
const rawParts = label.split(/[\s-]+/);
|
|
22423
|
-
const words = [];
|
|
22424
|
-
for (const part of rawParts) {
|
|
22425
|
-
if (!part) continue;
|
|
22426
|
-
words.push(...splitCamelCase(part));
|
|
22427
|
-
}
|
|
22428
|
-
for (let fontSize = 13; fontSize >= 9; fontSize--) {
|
|
22429
|
-
const charWidth = fontSize * 0.6;
|
|
22430
|
-
const maxChars = Math.floor((nodeWidth2 - 24) / charWidth);
|
|
22431
|
-
if (maxChars < 2) continue;
|
|
22432
|
-
let lines = 1;
|
|
22433
|
-
let current = "";
|
|
22434
|
-
for (const word of words) {
|
|
22435
|
-
const test = current ? `${current} ${word}` : word;
|
|
22436
|
-
if (test.length <= maxChars) {
|
|
22437
|
-
current = test;
|
|
22438
|
-
} else {
|
|
22439
|
-
lines++;
|
|
22440
|
-
current = word;
|
|
22441
|
-
}
|
|
22442
|
-
}
|
|
22443
|
-
if (lines <= MAX_LABEL_LINES) return Math.min(lines, MAX_LABEL_LINES);
|
|
22444
|
-
}
|
|
22445
|
-
return MAX_LABEL_LINES;
|
|
22446
|
-
}
|
|
22447
|
-
function computeNodeSize(node) {
|
|
22448
|
-
if (!node.description || node.description.length === 0) {
|
|
22449
|
-
return { width: NODE_WIDTH, height: NODE_HEIGHT };
|
|
22450
|
-
}
|
|
22451
|
-
const w = DESC_NODE_WIDTH;
|
|
22452
|
-
const labelLines = estimateLabelLines(node.label, w);
|
|
22453
|
-
const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT + LABEL_PAD;
|
|
22454
|
-
const charsPerLine = Math.floor((w - 24) / (DESC_FONT_SIZE * 0.6));
|
|
22455
|
-
let totalRenderedLines = 0;
|
|
22456
|
-
for (const line12 of node.description) {
|
|
22457
|
-
if (line12.length <= charsPerLine) {
|
|
22458
|
-
totalRenderedLines += 1;
|
|
22459
|
-
} else {
|
|
22460
|
-
const words = line12.split(/\s+/);
|
|
22461
|
-
let current = "";
|
|
22462
|
-
let lineCount = 0;
|
|
22463
|
-
for (const word of words) {
|
|
22464
|
-
const fitted = word.length > charsPerLine ? word.slice(0, charsPerLine) : word;
|
|
22465
|
-
const test = current ? `${current} ${fitted}` : fitted;
|
|
22466
|
-
if (test.length <= charsPerLine) {
|
|
22467
|
-
current = test;
|
|
22468
|
-
} else {
|
|
22469
|
-
if (current) lineCount++;
|
|
22470
|
-
current = fitted;
|
|
22471
|
-
}
|
|
22472
|
-
}
|
|
22473
|
-
if (current) lineCount++;
|
|
22474
|
-
totalRenderedLines += lineCount;
|
|
22475
|
-
}
|
|
22476
|
-
}
|
|
22477
|
-
totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES);
|
|
22478
|
-
const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE * DESC_LINE_HEIGHT;
|
|
22479
|
-
const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING;
|
|
22480
|
-
return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
|
|
22481
|
-
}
|
|
22482
|
-
function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
|
|
22483
|
-
const hideDescriptions = layoutOptions?.hideDescriptions ?? false;
|
|
22484
|
-
const g = new import_dagre4.default.graphlib.Graph({ compound: true, multigraph: true });
|
|
22485
|
-
g.setGraph({
|
|
22486
|
-
rankdir: parsed.direction,
|
|
22487
|
-
nodesep: NODESEP,
|
|
22488
|
-
ranksep: RANKSEP,
|
|
22489
|
-
marginx: MARGIN3,
|
|
22490
|
-
marginy: MARGIN3
|
|
22491
|
-
});
|
|
22492
|
-
g.setDefaultEdgeLabel(() => ({}));
|
|
22493
|
-
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
22494
|
-
if (collapseInfo) {
|
|
22495
|
-
const missingGroups = /* @__PURE__ */ new Set();
|
|
22496
|
-
for (const og of collapseInfo.originalGroups) {
|
|
22497
|
-
if (!parsed.groups.some((g2) => g2.label === og.label)) {
|
|
22498
|
-
missingGroups.add(og.label);
|
|
22499
|
-
}
|
|
22500
|
-
}
|
|
22501
|
-
for (const label of missingGroups) {
|
|
22502
|
-
const og = collapseInfo.originalGroups.find((g2) => g2.label === label);
|
|
22503
|
-
const parentLabel = og?.parentGroup;
|
|
22504
|
-
if (!parentLabel || !missingGroups.has(parentLabel)) {
|
|
22505
|
-
collapsedGroupLabels.add(label);
|
|
22506
|
-
}
|
|
22507
|
-
}
|
|
22508
|
-
}
|
|
22509
|
-
for (const label of collapsedGroupLabels) {
|
|
22510
|
-
const gid = `__group_${label}`;
|
|
22511
|
-
g.setNode(gid, { label, width: NODE_WIDTH, height: NODE_HEIGHT });
|
|
22512
|
-
}
|
|
22513
|
-
for (const group of parsed.groups) {
|
|
22514
|
-
const gid = `__group_${group.label}`;
|
|
22515
|
-
g.setNode(gid, {
|
|
22516
|
-
label: group.label,
|
|
22517
|
-
paddingLeft: CONTAINER_PAD_X3,
|
|
22518
|
-
paddingRight: CONTAINER_PAD_X3,
|
|
22519
|
-
paddingTop: CONTAINER_PAD_TOP2,
|
|
22520
|
-
paddingBottom: CONTAINER_PAD_BOTTOM3
|
|
22521
|
-
});
|
|
22522
|
-
}
|
|
22523
|
-
const originalGroupByLabel = /* @__PURE__ */ new Map();
|
|
22524
|
-
if (collapseInfo) {
|
|
22525
|
-
for (const og of collapseInfo.originalGroups) {
|
|
22526
|
-
originalGroupByLabel.set(og.label, og);
|
|
22527
|
-
}
|
|
22528
|
-
}
|
|
22529
|
-
for (const label of collapsedGroupLabels) {
|
|
22530
|
-
const og = originalGroupByLabel.get(label);
|
|
22531
|
-
if (og?.parentGroup && !collapsedGroupLabels.has(og.parentGroup)) {
|
|
22532
|
-
const gid = `__group_${label}`;
|
|
22533
|
-
const parentGid = `__group_${og.parentGroup}`;
|
|
22534
|
-
if (g.hasNode(parentGid)) {
|
|
22535
|
-
g.setParent(gid, parentGid);
|
|
22536
|
-
}
|
|
22537
|
-
}
|
|
22538
|
-
}
|
|
22539
|
-
const nodeSizes = /* @__PURE__ */ new Map();
|
|
22540
|
-
let maxDescHeight = 0;
|
|
22541
|
-
for (const node of parsed.nodes) {
|
|
22542
|
-
const size = hideDescriptions ? { width: NODE_WIDTH, height: NODE_HEIGHT } : computeNodeSize(node);
|
|
22543
|
-
nodeSizes.set(node.label, size);
|
|
22544
|
-
if (!hideDescriptions && node.description && node.description.length > 0) {
|
|
22545
|
-
maxDescHeight = Math.max(maxDescHeight, size.height);
|
|
22546
|
-
}
|
|
22547
|
-
}
|
|
22548
|
-
if (maxDescHeight > 0) {
|
|
22549
|
-
for (const node of parsed.nodes) {
|
|
22550
|
-
if (node.description && node.description.length > 0) {
|
|
22551
|
-
const size = nodeSizes.get(node.label);
|
|
22552
|
-
nodeSizes.set(node.label, { width: size.width, height: maxDescHeight });
|
|
22553
|
-
}
|
|
22554
|
-
}
|
|
22555
|
-
}
|
|
22556
|
-
for (const node of parsed.nodes) {
|
|
22557
|
-
const size = nodeSizes.get(node.label);
|
|
22558
|
-
g.setNode(node.label, {
|
|
22559
|
-
label: node.label,
|
|
22560
|
-
width: size.width,
|
|
22561
|
-
height: size.height
|
|
22562
|
-
});
|
|
22563
|
-
}
|
|
22564
|
-
for (const group of parsed.groups) {
|
|
22565
|
-
if (group.parentGroup) {
|
|
22566
|
-
const childGid = `__group_${group.label}`;
|
|
22567
|
-
const parentGid = `__group_${group.parentGroup}`;
|
|
22568
|
-
if (g.hasNode(childGid) && g.hasNode(parentGid)) {
|
|
22569
|
-
g.setParent(childGid, parentGid);
|
|
22570
|
-
}
|
|
22571
|
-
}
|
|
22572
|
-
}
|
|
22573
|
-
const groupLabelSet = new Set(parsed.groups.map((gr) => gr.label));
|
|
22574
|
-
for (const group of parsed.groups) {
|
|
22575
|
-
const gid = `__group_${group.label}`;
|
|
22576
|
-
for (const child of group.children) {
|
|
22577
|
-
if (groupLabelSet.has(child)) continue;
|
|
22578
|
-
if (g.hasNode(child)) {
|
|
22579
|
-
g.setParent(child, gid);
|
|
22580
|
-
}
|
|
22581
|
-
}
|
|
22582
|
-
}
|
|
22583
|
-
const expandedGroupIds = /* @__PURE__ */ new Set();
|
|
22584
|
-
for (const group of parsed.groups) {
|
|
22585
|
-
expandedGroupIds.add(`__group_${group.label}`);
|
|
22586
|
-
}
|
|
22587
|
-
const groupFirstChild = /* @__PURE__ */ new Map();
|
|
22588
|
-
for (const group of parsed.groups) {
|
|
22589
|
-
const gid = `__group_${group.label}`;
|
|
22590
|
-
const firstChild = group.children.find(
|
|
22591
|
-
(c) => !groupLabelSet.has(c) && g.hasNode(c)
|
|
22592
|
-
);
|
|
22593
|
-
if (firstChild) {
|
|
22594
|
-
groupFirstChild.set(gid, firstChild);
|
|
22595
|
-
}
|
|
22596
|
-
}
|
|
22597
|
-
const deferredEdgeIndices = [];
|
|
22598
|
-
let proxyIdx = 0;
|
|
22599
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22600
|
-
const edge = parsed.edges[i];
|
|
22601
|
-
const src = edge.source;
|
|
22602
|
-
const tgt = edge.target;
|
|
22603
|
-
if (!g.hasNode(src) || !g.hasNode(tgt)) continue;
|
|
22604
|
-
if (expandedGroupIds.has(src) || expandedGroupIds.has(tgt)) {
|
|
22605
|
-
deferredEdgeIndices.push(i);
|
|
22606
|
-
const proxySrc = expandedGroupIds.has(src) ? groupFirstChild.get(src) : src;
|
|
22607
|
-
const proxyTgt = expandedGroupIds.has(tgt) ? groupFirstChild.get(tgt) : tgt;
|
|
22608
|
-
if (proxySrc && proxyTgt && proxySrc !== proxyTgt) {
|
|
22609
|
-
g.setEdge(
|
|
22610
|
-
proxySrc,
|
|
22611
|
-
proxyTgt,
|
|
22612
|
-
{ label: "", minlen: 1 },
|
|
22613
|
-
`proxy${proxyIdx++}`
|
|
22614
|
-
);
|
|
22615
|
-
}
|
|
22616
|
-
continue;
|
|
22617
|
-
}
|
|
22618
|
-
g.setEdge(src, tgt, { label: edge.label ?? "", minlen: 1 }, `e${i}`);
|
|
22619
|
-
}
|
|
22620
|
-
import_dagre4.default.layout(g);
|
|
22621
|
-
const layoutNodes = [];
|
|
22622
|
-
for (const node of parsed.nodes) {
|
|
22623
|
-
const dagreNode = g.node(node.label);
|
|
22624
|
-
if (!dagreNode) continue;
|
|
22625
|
-
layoutNodes.push({
|
|
22626
|
-
label: node.label,
|
|
22627
|
-
x: dagreNode.x,
|
|
22628
|
-
y: dagreNode.y,
|
|
22629
|
-
width: dagreNode.width,
|
|
22630
|
-
height: dagreNode.height
|
|
22631
|
-
});
|
|
22632
|
-
}
|
|
22633
|
-
const layoutGroups = [];
|
|
22634
|
-
for (const group of parsed.groups) {
|
|
22635
|
-
const gid = `__group_${group.label}`;
|
|
22636
|
-
const dagreNode = g.node(gid);
|
|
22637
|
-
if (!dagreNode) continue;
|
|
22638
|
-
layoutGroups.push({
|
|
22639
|
-
label: group.label,
|
|
22640
|
-
lineNumber: group.lineNumber,
|
|
22641
|
-
x: dagreNode.x,
|
|
22642
|
-
y: dagreNode.y,
|
|
22643
|
-
width: dagreNode.width,
|
|
22644
|
-
height: dagreNode.height,
|
|
22645
|
-
collapsed: false
|
|
22646
|
-
});
|
|
22647
|
-
}
|
|
22648
|
-
for (const label of collapsedGroupLabels) {
|
|
22649
|
-
const gid = `__group_${label}`;
|
|
22650
|
-
const dagreNode = g.node(gid);
|
|
22651
|
-
if (!dagreNode) continue;
|
|
22652
|
-
const og = collapseInfo?.originalGroups.find((g2) => g2.label === label);
|
|
22653
|
-
layoutGroups.push({
|
|
22654
|
-
label,
|
|
22655
|
-
lineNumber: og?.lineNumber ?? 0,
|
|
22656
|
-
x: dagreNode.x,
|
|
22657
|
-
y: dagreNode.y,
|
|
22658
|
-
width: dagreNode.width,
|
|
22659
|
-
height: dagreNode.height,
|
|
22660
|
-
collapsed: true,
|
|
22661
|
-
childCount: collapseInfo?.collapsedChildCounts.get(label) ?? 0
|
|
22662
|
-
});
|
|
22663
|
-
}
|
|
22664
|
-
const groupAlignShifts = /* @__PURE__ */ new Map();
|
|
22665
|
-
{
|
|
22666
|
-
const groupEdges = [];
|
|
22667
|
-
for (const edge of parsed.edges) {
|
|
22668
|
-
if (edge.source.startsWith("__group_") && edge.target.startsWith("__group_")) {
|
|
22669
|
-
groupEdges.push(edge);
|
|
22670
|
-
}
|
|
22671
|
-
}
|
|
22672
|
-
if (groupEdges.length > 0) {
|
|
22673
|
-
const groupParent = /* @__PURE__ */ new Map();
|
|
22674
|
-
const find = (x) => {
|
|
22675
|
-
while (groupParent.has(x) && groupParent.get(x) !== x) {
|
|
22676
|
-
groupParent.set(x, groupParent.get(groupParent.get(x)));
|
|
22677
|
-
x = groupParent.get(x);
|
|
22678
|
-
}
|
|
22679
|
-
return x;
|
|
22680
|
-
};
|
|
22681
|
-
const union = (a, b) => {
|
|
22682
|
-
const ra = find(a), rb = find(b);
|
|
22683
|
-
if (ra !== rb) groupParent.set(ra, rb);
|
|
22684
|
-
};
|
|
22685
|
-
for (const edge of groupEdges) {
|
|
22686
|
-
if (!groupParent.has(edge.source))
|
|
22687
|
-
groupParent.set(edge.source, edge.source);
|
|
22688
|
-
if (!groupParent.has(edge.target))
|
|
22689
|
-
groupParent.set(edge.target, edge.target);
|
|
22690
|
-
union(edge.source, edge.target);
|
|
22691
|
-
}
|
|
22692
|
-
const components = /* @__PURE__ */ new Map();
|
|
22693
|
-
for (const lg of layoutGroups) {
|
|
22694
|
-
const gid = `__group_${lg.label}`;
|
|
22695
|
-
if (!groupParent.has(gid)) continue;
|
|
22696
|
-
const root = find(gid);
|
|
22697
|
-
if (!components.has(root)) components.set(root, []);
|
|
22698
|
-
components.get(root).push(lg);
|
|
22699
|
-
}
|
|
22700
|
-
const axis = parsed.direction === "TB" ? "x" : "y";
|
|
22701
|
-
for (const groups of components.values()) {
|
|
22702
|
-
if (groups.length < 2) continue;
|
|
22703
|
-
const dim = axis === "x" ? "width" : "height";
|
|
22704
|
-
let widest = groups[0];
|
|
22705
|
-
for (const g2 of groups) {
|
|
22706
|
-
if (g2[dim] > widest[dim]) widest = g2;
|
|
22707
|
-
}
|
|
22708
|
-
const targetCenter = widest[axis];
|
|
22709
|
-
for (const grp of groups) {
|
|
22710
|
-
const dx = targetCenter - grp[axis];
|
|
22711
|
-
if (dx === 0) continue;
|
|
22712
|
-
grp[axis] += dx;
|
|
22713
|
-
groupAlignShifts.set(`__group_${grp.label}`, dx);
|
|
22714
|
-
const parsedGroup = parsed.groups.find(
|
|
22715
|
-
(pg) => pg.label === grp.label
|
|
22716
|
-
);
|
|
22717
|
-
if (parsedGroup) {
|
|
22718
|
-
for (const childLabel of parsedGroup.children) {
|
|
22719
|
-
const childNode = layoutNodes.find((n) => n.label === childLabel);
|
|
22720
|
-
if (childNode) childNode[axis] += dx;
|
|
22721
|
-
}
|
|
22722
|
-
}
|
|
22723
|
-
}
|
|
22724
|
-
}
|
|
22725
|
-
}
|
|
22726
|
-
}
|
|
22727
|
-
const edgeYOffsets = new Array(parsed.edges.length).fill(0);
|
|
22728
|
-
const edgeParallelCounts = new Array(parsed.edges.length).fill(1);
|
|
22729
|
-
const parallelGroups = /* @__PURE__ */ new Map();
|
|
22730
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22731
|
-
const edge = parsed.edges[i];
|
|
22732
|
-
const [a, b] = edge.source < edge.target ? [edge.source, edge.target] : [edge.target, edge.source];
|
|
22733
|
-
const key = `${a}\0${b}`;
|
|
22734
|
-
if (!parallelGroups.has(key)) parallelGroups.set(key, []);
|
|
22735
|
-
parallelGroups.get(key).push(i);
|
|
22736
|
-
}
|
|
22737
|
-
for (const group of parallelGroups.values()) {
|
|
22738
|
-
const capped = group.slice(0, MAX_PARALLEL_EDGES);
|
|
22739
|
-
for (const idx of group.slice(MAX_PARALLEL_EDGES)) {
|
|
22740
|
-
edgeParallelCounts[idx] = 0;
|
|
22741
|
-
}
|
|
22742
|
-
if (capped.length < 2) continue;
|
|
22743
|
-
const effectiveSpacing = PARALLEL_SPACING;
|
|
22744
|
-
for (let j = 0; j < capped.length; j++) {
|
|
22745
|
-
edgeYOffsets[capped[j]] = (j - (capped.length - 1) / 2) * effectiveSpacing;
|
|
22746
|
-
edgeParallelCounts[capped[j]] = capped.length;
|
|
22747
|
-
}
|
|
22748
|
-
}
|
|
22749
|
-
const deferredSet = new Set(deferredEdgeIndices);
|
|
22750
|
-
const layoutEdges = [];
|
|
22751
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22752
|
-
const edge = parsed.edges[i];
|
|
22753
|
-
if (edgeParallelCounts[i] === 0) continue;
|
|
22754
|
-
let points;
|
|
22755
|
-
if (deferredSet.has(i)) {
|
|
22756
|
-
const srcLayout = layoutGroups.find(
|
|
22757
|
-
(lg) => `__group_${lg.label}` === edge.source
|
|
22758
|
-
);
|
|
22759
|
-
const tgtLayout = layoutGroups.find(
|
|
22760
|
-
(lg) => `__group_${lg.label}` === edge.target
|
|
22761
|
-
);
|
|
22762
|
-
if (!srcLayout || !tgtLayout) {
|
|
22763
|
-
const srcNode = g.node(edge.source);
|
|
22764
|
-
const tgtNode = g.node(edge.target);
|
|
22765
|
-
if (!srcNode || !tgtNode) continue;
|
|
22766
|
-
const srcPt = clipToRectBorder2(
|
|
22767
|
-
srcNode.x,
|
|
22768
|
-
srcNode.y,
|
|
22769
|
-
srcNode.width,
|
|
22770
|
-
srcNode.height,
|
|
22771
|
-
tgtNode.x,
|
|
22772
|
-
tgtNode.y
|
|
22773
|
-
);
|
|
22774
|
-
const tgtPt = clipToRectBorder2(
|
|
22775
|
-
tgtNode.x,
|
|
22776
|
-
tgtNode.y,
|
|
22777
|
-
tgtNode.width,
|
|
22778
|
-
tgtNode.height,
|
|
22779
|
-
srcNode.x,
|
|
22780
|
-
srcNode.y
|
|
22781
|
-
);
|
|
22782
|
-
const midX = (srcPt.x + tgtPt.x) / 2;
|
|
22783
|
-
const midY = (srcPt.y + tgtPt.y) / 2;
|
|
22784
|
-
points = [srcPt, { x: midX, y: midY }, tgtPt];
|
|
22785
|
-
} else if (parsed.direction === "TB") {
|
|
22786
|
-
const cx = (srcLayout.x + tgtLayout.x) / 2;
|
|
22787
|
-
const srcPt = { x: cx, y: srcLayout.y + srcLayout.height / 2 };
|
|
22788
|
-
const tgtPt = { x: cx, y: tgtLayout.y - tgtLayout.height / 2 };
|
|
22789
|
-
const midY = (srcPt.y + tgtPt.y) / 2;
|
|
22790
|
-
points = [srcPt, { x: cx, y: midY }, tgtPt];
|
|
22791
|
-
} else {
|
|
22792
|
-
const cy = (srcLayout.y + tgtLayout.y) / 2;
|
|
22793
|
-
const srcPt = { x: srcLayout.x + srcLayout.width / 2, y: cy };
|
|
22794
|
-
const tgtPt = { x: tgtLayout.x - tgtLayout.width / 2, y: cy };
|
|
22795
|
-
const midX = (srcPt.x + tgtPt.x) / 2;
|
|
22796
|
-
points = [srcPt, { x: midX, y: cy }, tgtPt];
|
|
22797
|
-
}
|
|
22798
|
-
} else {
|
|
22799
|
-
const dagreEdge = g.edge(edge.source, edge.target, `e${i}`);
|
|
22800
|
-
points = dagreEdge?.points ?? [];
|
|
22801
|
-
const srcShift = groupAlignShifts.get(edge.source) ?? 0;
|
|
22802
|
-
const tgtShift = groupAlignShifts.get(edge.target) ?? 0;
|
|
22803
|
-
if (srcShift !== 0 || tgtShift !== 0) {
|
|
22804
|
-
const avgShift = (srcShift + tgtShift) / 2;
|
|
22805
|
-
const prop = parsed.direction === "TB" ? "x" : "y";
|
|
22806
|
-
points = points.map((p) => ({ ...p, [prop]: p[prop] + avgShift }));
|
|
22807
|
-
}
|
|
22808
|
-
}
|
|
22809
|
-
let labelX;
|
|
22810
|
-
let labelY;
|
|
22811
|
-
if (edge.label && points.length >= 2) {
|
|
22812
|
-
const mid = Math.floor(points.length / 2);
|
|
22813
|
-
labelX = points[mid].x;
|
|
22814
|
-
labelY = points[mid].y - 10;
|
|
22815
|
-
}
|
|
22816
|
-
layoutEdges.push({
|
|
22817
|
-
source: edge.source,
|
|
22818
|
-
target: edge.target,
|
|
22819
|
-
label: edge.label,
|
|
22820
|
-
bidirectional: edge.bidirectional,
|
|
22821
|
-
lineNumber: edge.lineNumber,
|
|
22822
|
-
points,
|
|
22823
|
-
labelX,
|
|
22824
|
-
labelY,
|
|
22825
|
-
yOffset: edgeYOffsets[i],
|
|
22826
|
-
parallelCount: edgeParallelCounts[i],
|
|
22827
|
-
metadata: edge.metadata,
|
|
22828
|
-
deferred: deferredSet.has(i) || void 0
|
|
22829
|
-
});
|
|
22830
|
-
}
|
|
22831
|
-
let maxX = 0;
|
|
22832
|
-
let maxY = 0;
|
|
22833
|
-
for (const node of layoutNodes) {
|
|
22834
|
-
maxX = Math.max(maxX, node.x + node.width / 2);
|
|
22835
|
-
maxY = Math.max(maxY, node.y + node.height / 2);
|
|
22836
|
-
}
|
|
22837
|
-
for (const group of layoutGroups) {
|
|
22838
|
-
maxX = Math.max(maxX, group.x + group.width / 2);
|
|
22839
|
-
maxY = Math.max(maxY, group.y + group.height / 2);
|
|
22840
|
-
}
|
|
22841
|
-
return {
|
|
22842
|
-
nodes: layoutNodes,
|
|
22843
|
-
edges: layoutEdges,
|
|
22844
|
-
groups: layoutGroups,
|
|
22845
|
-
width: maxX + MARGIN3,
|
|
22846
|
-
height: maxY + MARGIN3
|
|
22847
|
-
};
|
|
22848
|
-
}
|
|
22849
|
-
var import_dagre4, 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;
|
|
22850
|
-
var init_layout5 = __esm({
|
|
22851
|
-
"src/boxes-and-lines/layout.ts"() {
|
|
22852
|
-
"use strict";
|
|
22853
|
-
import_dagre4 = __toESM(require("@dagrejs/dagre"), 1);
|
|
22854
|
-
NODESEP = 60;
|
|
22855
|
-
RANKSEP = 100;
|
|
22856
|
-
MARGIN3 = 40;
|
|
22857
|
-
CONTAINER_PAD_X3 = 30;
|
|
22858
|
-
CONTAINER_PAD_TOP2 = 40;
|
|
22859
|
-
CONTAINER_PAD_BOTTOM3 = 24;
|
|
22860
|
-
MAX_PARALLEL_EDGES = 5;
|
|
22861
|
-
PARALLEL_SPACING = 22;
|
|
22862
|
-
PHI = 1.618;
|
|
22863
|
-
NODE_HEIGHT = 60;
|
|
22864
|
-
NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
|
|
22865
|
-
DESC_NODE_WIDTH = 140;
|
|
22866
|
-
DESC_FONT_SIZE = 10;
|
|
22867
|
-
DESC_LINE_HEIGHT = 1.4;
|
|
22868
|
-
DESC_PADDING = 8;
|
|
22869
|
-
SEPARATOR_GAP5 = 4;
|
|
22870
|
-
MAX_DESC_LINES = 6;
|
|
22871
|
-
MAX_LABEL_LINES = 3;
|
|
22872
|
-
LABEL_LINE_HEIGHT = 1.3;
|
|
22873
|
-
LABEL_PAD = 12;
|
|
22874
|
-
}
|
|
22875
|
-
});
|
|
22876
|
-
|
|
22877
22423
|
// src/utils/wrapped-desc.ts
|
|
22878
22424
|
function wrapDescriptionLines(lines, charsPerLine, lengthFn = (s) => s.length) {
|
|
22879
22425
|
const result = [];
|
|
@@ -22923,7 +22469,7 @@ __export(renderer_exports6, {
|
|
|
22923
22469
|
renderBoxesAndLines: () => renderBoxesAndLines,
|
|
22924
22470
|
renderBoxesAndLinesForExport: () => renderBoxesAndLinesForExport
|
|
22925
22471
|
});
|
|
22926
|
-
function
|
|
22472
|
+
function splitCamelCase(word) {
|
|
22927
22473
|
const parts = [];
|
|
22928
22474
|
let start = 0;
|
|
22929
22475
|
for (let i = 1; i < word.length; i++) {
|
|
@@ -22946,7 +22492,7 @@ function fitLabelToHeader(label, nodeWidth2, maxLines) {
|
|
|
22946
22492
|
const words = [];
|
|
22947
22493
|
for (const part of rawParts) {
|
|
22948
22494
|
if (!part || /^\s+$/.test(part) || part === "-") continue;
|
|
22949
|
-
words.push(...
|
|
22495
|
+
words.push(...splitCamelCase(part));
|
|
22950
22496
|
}
|
|
22951
22497
|
for (let fontSize = NODE_FONT_SIZE; fontSize >= MIN_NODE_FONT_SIZE; fontSize--) {
|
|
22952
22498
|
const charWidth2 = fontSize * CHAR_WIDTH_RATIO2;
|
|
@@ -23322,12 +22868,12 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23322
22868
|
}
|
|
23323
22869
|
const sepY = -ln.height / 2 + headerH;
|
|
23324
22870
|
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);
|
|
23325
|
-
const descStartY = sepY + 4 +
|
|
22871
|
+
const descStartY = sepY + 4 + DESC_FONT_SIZE;
|
|
23326
22872
|
const maxTextWidth = ln.width - NODE_TEXT_PADDING * 2;
|
|
23327
22873
|
const charsPerLine = Math.floor(
|
|
23328
|
-
maxTextWidth / (
|
|
22874
|
+
maxTextWidth / (DESC_FONT_SIZE * CHAR_WIDTH_RATIO2)
|
|
23329
22875
|
);
|
|
23330
|
-
const descLineH =
|
|
22876
|
+
const descLineH = DESC_FONT_SIZE * DESC_LINE_HEIGHT;
|
|
23331
22877
|
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;
|
|
23332
22878
|
const normalizedLines = [];
|
|
23333
22879
|
for (const descLine of desc) {
|
|
@@ -23343,8 +22889,8 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23343
22889
|
charsPerLine,
|
|
23344
22890
|
displayLen
|
|
23345
22891
|
);
|
|
23346
|
-
const truncated = wrappedLinesShared.length >
|
|
23347
|
-
const visibleLines = truncated ? wrappedLinesShared.slice(0,
|
|
22892
|
+
const truncated = wrappedLinesShared.length > MAX_DESC_LINES;
|
|
22893
|
+
const visibleLines = truncated ? wrappedLinesShared.slice(0, MAX_DESC_LINES) : wrappedLinesShared;
|
|
23348
22894
|
const BULLET_GLYPH_X = -ln.width / 2 + 6;
|
|
23349
22895
|
const BULLET_BODY_X = BULLET_GLYPH_X + 10;
|
|
23350
22896
|
for (let li = 0; li < visibleLines.length; li++) {
|
|
@@ -23355,11 +22901,11 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23355
22901
|
}
|
|
23356
22902
|
const y2 = descStartY + li * descLineH;
|
|
23357
22903
|
if (line12.kind === "bullet-first") {
|
|
23358
|
-
nodeG.append("text").attr("x", BULLET_GLYPH_X).attr("y", y2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("font-size",
|
|
22904
|
+
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");
|
|
23359
22905
|
}
|
|
23360
22906
|
const isBullet = line12.kind === "bullet-first" || line12.kind === "bullet-cont";
|
|
23361
|
-
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",
|
|
23362
|
-
renderInlineText(textEl, lineText, palette,
|
|
22907
|
+
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);
|
|
22908
|
+
renderInlineText(textEl, lineText, palette, DESC_FONT_SIZE);
|
|
23363
22909
|
}
|
|
23364
22910
|
if (truncated) {
|
|
23365
22911
|
const fullText = desc.join(" ");
|
|
@@ -23437,7 +22983,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
|
|
|
23437
22983
|
hiddenTagValues: options?.hiddenTagValues
|
|
23438
22984
|
});
|
|
23439
22985
|
}
|
|
23440
|
-
var d3Selection6, d3Shape4, 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,
|
|
22986
|
+
var d3Selection6, d3Shape4, 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;
|
|
23441
22987
|
var init_renderer6 = __esm({
|
|
23442
22988
|
"src/boxes-and-lines/renderer.ts"() {
|
|
23443
22989
|
"use strict";
|
|
@@ -23461,9 +23007,9 @@ var init_renderer6 = __esm({
|
|
|
23461
23007
|
COLLAPSE_BAR_HEIGHT3 = 4;
|
|
23462
23008
|
ARROWHEAD_W2 = 5;
|
|
23463
23009
|
ARROWHEAD_H2 = 4;
|
|
23464
|
-
|
|
23465
|
-
|
|
23466
|
-
|
|
23010
|
+
DESC_FONT_SIZE = 10;
|
|
23011
|
+
DESC_LINE_HEIGHT = 1.4;
|
|
23012
|
+
MAX_DESC_LINES = 6;
|
|
23467
23013
|
CHAR_WIDTH_RATIO2 = 0.6;
|
|
23468
23014
|
NODE_TEXT_PADDING = 12;
|
|
23469
23015
|
GROUP_RX = 8;
|
|
@@ -23474,6 +23020,523 @@ var init_renderer6 = __esm({
|
|
|
23474
23020
|
}
|
|
23475
23021
|
});
|
|
23476
23022
|
|
|
23023
|
+
// src/boxes-and-lines/layout.ts
|
|
23024
|
+
var layout_exports5 = {};
|
|
23025
|
+
__export(layout_exports5, {
|
|
23026
|
+
layoutBoxesAndLines: () => layoutBoxesAndLines
|
|
23027
|
+
});
|
|
23028
|
+
function splitCamelCase2(word) {
|
|
23029
|
+
const parts = [];
|
|
23030
|
+
let start = 0;
|
|
23031
|
+
for (let i = 1; i < word.length; i++) {
|
|
23032
|
+
const prev = word[i - 1];
|
|
23033
|
+
const curr = word[i];
|
|
23034
|
+
const next = i + 1 < word.length ? word[i + 1] : "";
|
|
23035
|
+
const lowerToUpper = prev >= "a" && prev <= "z" && curr >= "A" && curr <= "Z";
|
|
23036
|
+
const upperRunEnd = prev >= "A" && prev <= "Z" && curr >= "A" && curr <= "Z" && next >= "a" && next <= "z";
|
|
23037
|
+
if (lowerToUpper || upperRunEnd) {
|
|
23038
|
+
parts.push(word.slice(start, i));
|
|
23039
|
+
start = i;
|
|
23040
|
+
}
|
|
23041
|
+
}
|
|
23042
|
+
parts.push(word.slice(start));
|
|
23043
|
+
return parts.length > 1 ? parts : [word];
|
|
23044
|
+
}
|
|
23045
|
+
function estimateLabelLines(label, nodeWidth2 = NODE_WIDTH) {
|
|
23046
|
+
const rawParts = label.split(/[\s-]+/);
|
|
23047
|
+
const words = [];
|
|
23048
|
+
for (const part of rawParts) {
|
|
23049
|
+
if (!part) continue;
|
|
23050
|
+
words.push(...splitCamelCase2(part));
|
|
23051
|
+
}
|
|
23052
|
+
for (let fontSize = 13; fontSize >= 9; fontSize--) {
|
|
23053
|
+
const charWidth = fontSize * 0.6;
|
|
23054
|
+
const maxChars = Math.floor((nodeWidth2 - 24) / charWidth);
|
|
23055
|
+
if (maxChars < 2) continue;
|
|
23056
|
+
let lines = 1;
|
|
23057
|
+
let current = "";
|
|
23058
|
+
for (const word of words) {
|
|
23059
|
+
const test = current ? `${current} ${word}` : word;
|
|
23060
|
+
if (test.length <= maxChars) {
|
|
23061
|
+
current = test;
|
|
23062
|
+
} else {
|
|
23063
|
+
lines++;
|
|
23064
|
+
current = word;
|
|
23065
|
+
}
|
|
23066
|
+
}
|
|
23067
|
+
if (lines <= MAX_LABEL_LINES) return Math.min(lines, MAX_LABEL_LINES);
|
|
23068
|
+
}
|
|
23069
|
+
return MAX_LABEL_LINES;
|
|
23070
|
+
}
|
|
23071
|
+
function computeNodeSize(node) {
|
|
23072
|
+
if (!node.description || node.description.length === 0) {
|
|
23073
|
+
return { width: NODE_WIDTH, height: NODE_HEIGHT };
|
|
23074
|
+
}
|
|
23075
|
+
const w = DESC_NODE_WIDTH;
|
|
23076
|
+
const labelLines = estimateLabelLines(node.label, w);
|
|
23077
|
+
const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT + LABEL_PAD;
|
|
23078
|
+
const charsPerLine = Math.floor((w - 24) / (DESC_FONT_SIZE2 * 0.6));
|
|
23079
|
+
let totalRenderedLines = 0;
|
|
23080
|
+
for (const line12 of node.description) {
|
|
23081
|
+
if (line12.length <= charsPerLine) {
|
|
23082
|
+
totalRenderedLines += 1;
|
|
23083
|
+
} else {
|
|
23084
|
+
const words = line12.split(/\s+/);
|
|
23085
|
+
let current = "";
|
|
23086
|
+
let lineCount = 0;
|
|
23087
|
+
for (const word of words) {
|
|
23088
|
+
const fitted = word.length > charsPerLine ? word.slice(0, charsPerLine) : word;
|
|
23089
|
+
const test = current ? `${current} ${fitted}` : fitted;
|
|
23090
|
+
if (test.length <= charsPerLine) {
|
|
23091
|
+
current = test;
|
|
23092
|
+
} else {
|
|
23093
|
+
if (current) lineCount++;
|
|
23094
|
+
current = fitted;
|
|
23095
|
+
}
|
|
23096
|
+
}
|
|
23097
|
+
if (current) lineCount++;
|
|
23098
|
+
totalRenderedLines += lineCount;
|
|
23099
|
+
}
|
|
23100
|
+
}
|
|
23101
|
+
totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES2);
|
|
23102
|
+
const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE2 * DESC_LINE_HEIGHT2;
|
|
23103
|
+
const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING;
|
|
23104
|
+
return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
|
|
23105
|
+
}
|
|
23106
|
+
function getElk() {
|
|
23107
|
+
if (!elkInstance) elkInstance = new import_elk_bundled.default();
|
|
23108
|
+
return elkInstance;
|
|
23109
|
+
}
|
|
23110
|
+
function baseOptions() {
|
|
23111
|
+
return {
|
|
23112
|
+
"elk.algorithm": "layered",
|
|
23113
|
+
// INCLUDE_CHILDREN lets ELK route edges across container boundaries.
|
|
23114
|
+
"elk.hierarchyHandling": "INCLUDE_CHILDREN",
|
|
23115
|
+
"elk.edgeRouting": "ORTHOGONAL",
|
|
23116
|
+
"elk.layered.unnecessaryBendpoints": "true",
|
|
23117
|
+
// Let edges leave from top/bottom of nodes (not just the flow-direction
|
|
23118
|
+
// sides) when it reduces crossings.
|
|
23119
|
+
"elk.layered.allowNonFlowPortsToSwitchSides": "true"
|
|
23120
|
+
};
|
|
23121
|
+
}
|
|
23122
|
+
function bkBaseline() {
|
|
23123
|
+
return {
|
|
23124
|
+
...baseOptions(),
|
|
23125
|
+
"elk.layered.nodePlacement.strategy": "BRANDES_KOEPF",
|
|
23126
|
+
"elk.layered.nodePlacement.bk.fixedAlignment": "BALANCED",
|
|
23127
|
+
"elk.layered.nodePlacement.bk.edgeStraightening": "IMPROVE_STRAIGHTNESS",
|
|
23128
|
+
"elk.layered.compaction.connectedComponents": "true",
|
|
23129
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": "90",
|
|
23130
|
+
"elk.spacing.nodeNode": "55",
|
|
23131
|
+
"elk.spacing.edgeNode": "55",
|
|
23132
|
+
"elk.spacing.edgeEdge": "18"
|
|
23133
|
+
};
|
|
23134
|
+
}
|
|
23135
|
+
function getVariants() {
|
|
23136
|
+
const bk = bkBaseline();
|
|
23137
|
+
return [
|
|
23138
|
+
{
|
|
23139
|
+
name: "bk-baseline",
|
|
23140
|
+
options: {
|
|
23141
|
+
...bk,
|
|
23142
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "ONE_SIDED"
|
|
23143
|
+
}
|
|
23144
|
+
},
|
|
23145
|
+
{
|
|
23146
|
+
name: "bk-aggressive",
|
|
23147
|
+
options: {
|
|
23148
|
+
...bk,
|
|
23149
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23150
|
+
"elk.layered.thoroughness": "50"
|
|
23151
|
+
}
|
|
23152
|
+
},
|
|
23153
|
+
{
|
|
23154
|
+
name: "bk-wide",
|
|
23155
|
+
options: {
|
|
23156
|
+
...bk,
|
|
23157
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23158
|
+
"elk.layered.thoroughness": "50",
|
|
23159
|
+
"elk.spacing.nodeNode": "70",
|
|
23160
|
+
"elk.spacing.edgeNode": "75",
|
|
23161
|
+
"elk.spacing.edgeEdge": "22",
|
|
23162
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": "120"
|
|
23163
|
+
}
|
|
23164
|
+
},
|
|
23165
|
+
{
|
|
23166
|
+
name: "longest-path",
|
|
23167
|
+
options: {
|
|
23168
|
+
...bk,
|
|
23169
|
+
"elk.layered.layering.strategy": "LONGEST_PATH",
|
|
23170
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23171
|
+
"elk.layered.thoroughness": "50"
|
|
23172
|
+
}
|
|
23173
|
+
},
|
|
23174
|
+
{
|
|
23175
|
+
name: "bounded-width",
|
|
23176
|
+
options: {
|
|
23177
|
+
...bk,
|
|
23178
|
+
"elk.layered.layering.strategy": "COFFMAN_GRAHAM",
|
|
23179
|
+
"elk.layered.layering.coffmanGraham.layerBound": "3",
|
|
23180
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23181
|
+
"elk.layered.thoroughness": "50"
|
|
23182
|
+
}
|
|
23183
|
+
}
|
|
23184
|
+
];
|
|
23185
|
+
}
|
|
23186
|
+
function countCrossings(edges) {
|
|
23187
|
+
let count = 0;
|
|
23188
|
+
for (let i = 0; i < edges.length; i++) {
|
|
23189
|
+
const a = edges[i].points;
|
|
23190
|
+
if (a.length < 2) continue;
|
|
23191
|
+
for (let j = i + 1; j < edges.length; j++) {
|
|
23192
|
+
const b = edges[j].points;
|
|
23193
|
+
if (b.length < 2) continue;
|
|
23194
|
+
if (edges[i].source === edges[j].source) continue;
|
|
23195
|
+
if (edges[i].source === edges[j].target) continue;
|
|
23196
|
+
if (edges[i].target === edges[j].source) continue;
|
|
23197
|
+
if (edges[i].target === edges[j].target) continue;
|
|
23198
|
+
for (let ai = 0; ai < a.length - 1; ai++) {
|
|
23199
|
+
for (let bi = 0; bi < b.length - 1; bi++) {
|
|
23200
|
+
if (segmentsCross(a[ai], a[ai + 1], b[bi], b[bi + 1])) count++;
|
|
23201
|
+
}
|
|
23202
|
+
}
|
|
23203
|
+
}
|
|
23204
|
+
}
|
|
23205
|
+
return count;
|
|
23206
|
+
}
|
|
23207
|
+
function segmentsCross(p1, p2, p3, p4) {
|
|
23208
|
+
const d1x = p2.x - p1.x;
|
|
23209
|
+
const d1y = p2.y - p1.y;
|
|
23210
|
+
const d2x = p4.x - p3.x;
|
|
23211
|
+
const d2y = p4.y - p3.y;
|
|
23212
|
+
const denom = d1x * d2y - d1y * d2x;
|
|
23213
|
+
if (Math.abs(denom) < 1e-9) return false;
|
|
23214
|
+
const t = ((p3.x - p1.x) * d2y - (p3.y - p1.y) * d2x) / denom;
|
|
23215
|
+
const s = ((p3.x - p1.x) * d1y - (p3.y - p1.y) * d1x) / denom;
|
|
23216
|
+
const EPS = 1e-3;
|
|
23217
|
+
return t > EPS && t < 1 - EPS && s > EPS && s < 1 - EPS;
|
|
23218
|
+
}
|
|
23219
|
+
function countTotalBends(edges) {
|
|
23220
|
+
let bends = 0;
|
|
23221
|
+
for (const e of edges) bends += Math.max(0, e.points.length - 2);
|
|
23222
|
+
return bends;
|
|
23223
|
+
}
|
|
23224
|
+
function scoreLayout(layout) {
|
|
23225
|
+
return {
|
|
23226
|
+
crossings: countCrossings(layout.edges),
|
|
23227
|
+
bends: countTotalBends(layout.edges),
|
|
23228
|
+
area: layout.width * layout.height
|
|
23229
|
+
};
|
|
23230
|
+
}
|
|
23231
|
+
function cmpScore(a, b) {
|
|
23232
|
+
const aBucket = a.crossings <= CROSSINGS_FORGIVENESS ? 0 : a.crossings;
|
|
23233
|
+
const bBucket = b.crossings <= CROSSINGS_FORGIVENESS ? 0 : b.crossings;
|
|
23234
|
+
if (aBucket !== bBucket) return aBucket - bBucket;
|
|
23235
|
+
if (a.area !== b.area) return a.area - b.area;
|
|
23236
|
+
return a.bends - b.bends;
|
|
23237
|
+
}
|
|
23238
|
+
async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
|
|
23239
|
+
const hideDescriptions = layoutOptions?.hideDescriptions ?? false;
|
|
23240
|
+
const direction = parsed.direction === "TB" ? "DOWN" : "RIGHT";
|
|
23241
|
+
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
23242
|
+
if (collapseInfo) {
|
|
23243
|
+
const missingGroups = /* @__PURE__ */ new Set();
|
|
23244
|
+
for (const og of collapseInfo.originalGroups) {
|
|
23245
|
+
if (!parsed.groups.some((g) => g.label === og.label)) {
|
|
23246
|
+
missingGroups.add(og.label);
|
|
23247
|
+
}
|
|
23248
|
+
}
|
|
23249
|
+
for (const label of missingGroups) {
|
|
23250
|
+
const og = collapseInfo.originalGroups.find((g) => g.label === label);
|
|
23251
|
+
const parentLabel = og?.parentGroup;
|
|
23252
|
+
if (!parentLabel || !missingGroups.has(parentLabel)) {
|
|
23253
|
+
collapsedGroupLabels.add(label);
|
|
23254
|
+
}
|
|
23255
|
+
}
|
|
23256
|
+
}
|
|
23257
|
+
const nodeSizes = /* @__PURE__ */ new Map();
|
|
23258
|
+
let maxDescHeight = 0;
|
|
23259
|
+
for (const node of parsed.nodes) {
|
|
23260
|
+
const size = hideDescriptions ? { width: NODE_WIDTH, height: NODE_HEIGHT } : computeNodeSize(node);
|
|
23261
|
+
nodeSizes.set(node.label, size);
|
|
23262
|
+
if (!hideDescriptions && node.description && node.description.length > 0) {
|
|
23263
|
+
maxDescHeight = Math.max(maxDescHeight, size.height);
|
|
23264
|
+
}
|
|
23265
|
+
}
|
|
23266
|
+
if (maxDescHeight > 0) {
|
|
23267
|
+
for (const node of parsed.nodes) {
|
|
23268
|
+
if (node.description && node.description.length > 0) {
|
|
23269
|
+
const size = nodeSizes.get(node.label);
|
|
23270
|
+
nodeSizes.set(node.label, { width: size.width, height: maxDescHeight });
|
|
23271
|
+
}
|
|
23272
|
+
}
|
|
23273
|
+
}
|
|
23274
|
+
const expandedGroupSet = new Set(parsed.groups.map((g) => g.label));
|
|
23275
|
+
const gid = (label) => `__group_${label}`;
|
|
23276
|
+
function buildGraph() {
|
|
23277
|
+
const nodeById = /* @__PURE__ */ new Map();
|
|
23278
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
23279
|
+
for (const node of parsed.nodes) {
|
|
23280
|
+
const size = nodeSizes.get(node.label);
|
|
23281
|
+
nodeById.set(node.label, {
|
|
23282
|
+
id: node.label,
|
|
23283
|
+
width: size.width,
|
|
23284
|
+
height: size.height,
|
|
23285
|
+
labels: [{ text: node.label }]
|
|
23286
|
+
});
|
|
23287
|
+
}
|
|
23288
|
+
for (const group of parsed.groups) {
|
|
23289
|
+
nodeById.set(gid(group.label), {
|
|
23290
|
+
id: gid(group.label),
|
|
23291
|
+
labels: [{ text: group.label }],
|
|
23292
|
+
layoutOptions: {
|
|
23293
|
+
"elk.padding": `[top=${CONTAINER_PAD_TOP2},left=${CONTAINER_PAD_X3},bottom=${CONTAINER_PAD_BOTTOM3},right=${CONTAINER_PAD_X3}]`,
|
|
23294
|
+
// Suggest square-ish containers — has limited effect with
|
|
23295
|
+
// INCLUDE_CHILDREN but doesn't hurt.
|
|
23296
|
+
"elk.aspectRatio": "1.4"
|
|
23297
|
+
},
|
|
23298
|
+
children: [],
|
|
23299
|
+
edges: []
|
|
23300
|
+
});
|
|
23301
|
+
}
|
|
23302
|
+
for (const label of collapsedGroupLabels) {
|
|
23303
|
+
nodeById.set(gid(label), {
|
|
23304
|
+
id: gid(label),
|
|
23305
|
+
width: NODE_WIDTH,
|
|
23306
|
+
height: NODE_HEIGHT,
|
|
23307
|
+
labels: [{ text: label }]
|
|
23308
|
+
});
|
|
23309
|
+
}
|
|
23310
|
+
for (const group of parsed.groups) {
|
|
23311
|
+
if (group.parentGroup && nodeById.has(gid(group.parentGroup))) {
|
|
23312
|
+
parentOf.set(gid(group.label), gid(group.parentGroup));
|
|
23313
|
+
}
|
|
23314
|
+
}
|
|
23315
|
+
if (collapseInfo) {
|
|
23316
|
+
for (const label of collapsedGroupLabels) {
|
|
23317
|
+
const og = collapseInfo.originalGroups.find((g) => g.label === label);
|
|
23318
|
+
if (og?.parentGroup && !collapsedGroupLabels.has(og.parentGroup) && nodeById.has(gid(og.parentGroup))) {
|
|
23319
|
+
parentOf.set(gid(label), gid(og.parentGroup));
|
|
23320
|
+
}
|
|
23321
|
+
}
|
|
23322
|
+
}
|
|
23323
|
+
for (const group of parsed.groups) {
|
|
23324
|
+
for (const child of group.children) {
|
|
23325
|
+
if (expandedGroupSet.has(child)) continue;
|
|
23326
|
+
if (nodeById.has(child)) {
|
|
23327
|
+
parentOf.set(child, gid(group.label));
|
|
23328
|
+
}
|
|
23329
|
+
}
|
|
23330
|
+
}
|
|
23331
|
+
const roots = [];
|
|
23332
|
+
for (const [id, node] of nodeById) {
|
|
23333
|
+
const parentId = parentOf.get(id);
|
|
23334
|
+
if (parentId) {
|
|
23335
|
+
const parent = nodeById.get(parentId);
|
|
23336
|
+
parent.children = parent.children ?? [];
|
|
23337
|
+
parent.children.push(node);
|
|
23338
|
+
} else {
|
|
23339
|
+
roots.push(node);
|
|
23340
|
+
}
|
|
23341
|
+
}
|
|
23342
|
+
const rootEdges = [];
|
|
23343
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23344
|
+
const edge = parsed.edges[i];
|
|
23345
|
+
if (!nodeById.has(edge.source) || !nodeById.has(edge.target)) continue;
|
|
23346
|
+
rootEdges.push({
|
|
23347
|
+
id: `e${i}`,
|
|
23348
|
+
sources: [edge.source],
|
|
23349
|
+
targets: [edge.target]
|
|
23350
|
+
});
|
|
23351
|
+
}
|
|
23352
|
+
return { roots, rootEdges };
|
|
23353
|
+
}
|
|
23354
|
+
async function runVariant(variant) {
|
|
23355
|
+
const { roots, rootEdges } = buildGraph();
|
|
23356
|
+
const elkRoot = {
|
|
23357
|
+
id: "root",
|
|
23358
|
+
layoutOptions: {
|
|
23359
|
+
...variant.options,
|
|
23360
|
+
"elk.direction": direction,
|
|
23361
|
+
"elk.padding": `[top=${MARGIN3},left=${MARGIN3},bottom=${MARGIN3},right=${MARGIN3}]`
|
|
23362
|
+
},
|
|
23363
|
+
children: roots,
|
|
23364
|
+
edges: rootEdges
|
|
23365
|
+
};
|
|
23366
|
+
const result = await getElk().layout(elkRoot);
|
|
23367
|
+
return extractLayout(result);
|
|
23368
|
+
}
|
|
23369
|
+
function extractLayout(result) {
|
|
23370
|
+
const layoutNodes = [];
|
|
23371
|
+
const layoutGroups = [];
|
|
23372
|
+
const allEdges = [];
|
|
23373
|
+
const containerAbs = /* @__PURE__ */ new Map();
|
|
23374
|
+
function walk(n, offsetX, offsetY, isRoot) {
|
|
23375
|
+
const nx = (n.x ?? 0) + offsetX;
|
|
23376
|
+
const ny = (n.y ?? 0) + offsetY;
|
|
23377
|
+
const nw = n.width ?? 0;
|
|
23378
|
+
const nh = n.height ?? 0;
|
|
23379
|
+
if (isRoot) {
|
|
23380
|
+
containerAbs.set("root", { x: nx, y: ny });
|
|
23381
|
+
} else {
|
|
23382
|
+
const isGroup = n.id.startsWith("__group_");
|
|
23383
|
+
if (isGroup) {
|
|
23384
|
+
const label = n.id.slice("__group_".length);
|
|
23385
|
+
const collapsed = collapsedGroupLabels.has(label);
|
|
23386
|
+
const og = collapseInfo?.originalGroups.find(
|
|
23387
|
+
(g) => g.label === label
|
|
23388
|
+
);
|
|
23389
|
+
const pg = parsed.groups.find((g) => g.label === label);
|
|
23390
|
+
layoutGroups.push({
|
|
23391
|
+
label,
|
|
23392
|
+
lineNumber: pg?.lineNumber ?? og?.lineNumber ?? 0,
|
|
23393
|
+
x: nx + nw / 2,
|
|
23394
|
+
y: ny + nh / 2,
|
|
23395
|
+
width: nw,
|
|
23396
|
+
height: nh,
|
|
23397
|
+
collapsed,
|
|
23398
|
+
childCount: collapsed ? collapseInfo?.collapsedChildCounts.get(label) ?? 0 : void 0
|
|
23399
|
+
});
|
|
23400
|
+
if (!collapsed) containerAbs.set(n.id, { x: nx, y: ny });
|
|
23401
|
+
} else {
|
|
23402
|
+
layoutNodes.push({
|
|
23403
|
+
label: n.id,
|
|
23404
|
+
x: nx + nw / 2,
|
|
23405
|
+
y: ny + nh / 2,
|
|
23406
|
+
width: nw,
|
|
23407
|
+
height: nh
|
|
23408
|
+
});
|
|
23409
|
+
}
|
|
23410
|
+
}
|
|
23411
|
+
if (n.edges) for (const e of n.edges) allEdges.push(e);
|
|
23412
|
+
if (n.children) for (const c of n.children) walk(c, nx, ny, false);
|
|
23413
|
+
}
|
|
23414
|
+
walk(result, 0, 0, true);
|
|
23415
|
+
const edgeYOffsets = new Array(parsed.edges.length).fill(0);
|
|
23416
|
+
const edgeParallelCounts = new Array(parsed.edges.length).fill(1);
|
|
23417
|
+
const parallelGroups = /* @__PURE__ */ new Map();
|
|
23418
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23419
|
+
const edge = parsed.edges[i];
|
|
23420
|
+
const [a, b] = edge.source < edge.target ? [edge.source, edge.target] : [edge.target, edge.source];
|
|
23421
|
+
const key = `${a}\0${b}`;
|
|
23422
|
+
if (!parallelGroups.has(key)) parallelGroups.set(key, []);
|
|
23423
|
+
parallelGroups.get(key).push(i);
|
|
23424
|
+
}
|
|
23425
|
+
for (const group of parallelGroups.values()) {
|
|
23426
|
+
const capped = group.slice(0, MAX_PARALLEL_EDGES);
|
|
23427
|
+
for (const idx of group.slice(MAX_PARALLEL_EDGES)) {
|
|
23428
|
+
edgeParallelCounts[idx] = 0;
|
|
23429
|
+
}
|
|
23430
|
+
if (capped.length < 2) continue;
|
|
23431
|
+
for (let j = 0; j < capped.length; j++) {
|
|
23432
|
+
edgeYOffsets[capped[j]] = (j - (capped.length - 1) / 2) * PARALLEL_SPACING;
|
|
23433
|
+
edgeParallelCounts[capped[j]] = capped.length;
|
|
23434
|
+
}
|
|
23435
|
+
}
|
|
23436
|
+
const edgeById = /* @__PURE__ */ new Map();
|
|
23437
|
+
for (const e of allEdges) edgeById.set(e.id, e);
|
|
23438
|
+
const layoutEdges = [];
|
|
23439
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23440
|
+
const edge = parsed.edges[i];
|
|
23441
|
+
if (edgeParallelCounts[i] === 0) continue;
|
|
23442
|
+
const elkEdge = edgeById.get(`e${i}`);
|
|
23443
|
+
if (!elkEdge || !elkEdge.sections || elkEdge.sections.length === 0)
|
|
23444
|
+
continue;
|
|
23445
|
+
const container = elkEdge.container ?? "root";
|
|
23446
|
+
const off = containerAbs.get(container) ?? { x: 0, y: 0 };
|
|
23447
|
+
const s = elkEdge.sections[0];
|
|
23448
|
+
const points = [
|
|
23449
|
+
{ x: s.startPoint.x + off.x, y: s.startPoint.y + off.y },
|
|
23450
|
+
...(s.bendPoints ?? []).map((p) => ({
|
|
23451
|
+
x: p.x + off.x,
|
|
23452
|
+
y: p.y + off.y
|
|
23453
|
+
})),
|
|
23454
|
+
{ x: s.endPoint.x + off.x, y: s.endPoint.y + off.y }
|
|
23455
|
+
];
|
|
23456
|
+
let labelX;
|
|
23457
|
+
let labelY;
|
|
23458
|
+
if (edge.label && points.length >= 2) {
|
|
23459
|
+
const mid = Math.floor(points.length / 2);
|
|
23460
|
+
labelX = points[mid].x;
|
|
23461
|
+
labelY = points[mid].y - 10;
|
|
23462
|
+
}
|
|
23463
|
+
layoutEdges.push({
|
|
23464
|
+
source: edge.source,
|
|
23465
|
+
target: edge.target,
|
|
23466
|
+
label: edge.label,
|
|
23467
|
+
bidirectional: edge.bidirectional,
|
|
23468
|
+
lineNumber: edge.lineNumber,
|
|
23469
|
+
points,
|
|
23470
|
+
labelX,
|
|
23471
|
+
labelY,
|
|
23472
|
+
yOffset: edgeYOffsets[i],
|
|
23473
|
+
parallelCount: edgeParallelCounts[i],
|
|
23474
|
+
metadata: edge.metadata,
|
|
23475
|
+
deferred: true
|
|
23476
|
+
});
|
|
23477
|
+
}
|
|
23478
|
+
let maxX = 0;
|
|
23479
|
+
let maxY = 0;
|
|
23480
|
+
for (const node of layoutNodes) {
|
|
23481
|
+
maxX = Math.max(maxX, node.x + node.width / 2);
|
|
23482
|
+
maxY = Math.max(maxY, node.y + node.height / 2);
|
|
23483
|
+
}
|
|
23484
|
+
for (const group of layoutGroups) {
|
|
23485
|
+
maxX = Math.max(maxX, group.x + group.width / 2);
|
|
23486
|
+
maxY = Math.max(maxY, group.y + group.height / 2);
|
|
23487
|
+
}
|
|
23488
|
+
return {
|
|
23489
|
+
nodes: layoutNodes,
|
|
23490
|
+
edges: layoutEdges,
|
|
23491
|
+
groups: layoutGroups,
|
|
23492
|
+
width: maxX + MARGIN3,
|
|
23493
|
+
height: maxY + MARGIN3
|
|
23494
|
+
};
|
|
23495
|
+
}
|
|
23496
|
+
const N = parsed.nodes.length + parsed.groups.length;
|
|
23497
|
+
const E = parsed.edges.length;
|
|
23498
|
+
const trivial = N < 8 && E < 10;
|
|
23499
|
+
const variants = trivial ? [getVariants()[1]] : getVariants();
|
|
23500
|
+
const results = await Promise.all(variants.map((v) => runVariant(v)));
|
|
23501
|
+
let best = results[0];
|
|
23502
|
+
let bestScore = scoreLayout(best);
|
|
23503
|
+
for (let i = 1; i < results.length; i++) {
|
|
23504
|
+
const s = scoreLayout(results[i]);
|
|
23505
|
+
if (cmpScore(s, bestScore) < 0) {
|
|
23506
|
+
best = results[i];
|
|
23507
|
+
bestScore = s;
|
|
23508
|
+
}
|
|
23509
|
+
}
|
|
23510
|
+
return best;
|
|
23511
|
+
}
|
|
23512
|
+
var import_elk_bundled, 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;
|
|
23513
|
+
var init_layout5 = __esm({
|
|
23514
|
+
"src/boxes-and-lines/layout.ts"() {
|
|
23515
|
+
"use strict";
|
|
23516
|
+
import_elk_bundled = __toESM(require("elkjs/lib/elk.bundled.js"), 1);
|
|
23517
|
+
MARGIN3 = 40;
|
|
23518
|
+
CONTAINER_PAD_X3 = 30;
|
|
23519
|
+
CONTAINER_PAD_TOP2 = 40;
|
|
23520
|
+
CONTAINER_PAD_BOTTOM3 = 24;
|
|
23521
|
+
MAX_PARALLEL_EDGES = 5;
|
|
23522
|
+
PARALLEL_SPACING = 22;
|
|
23523
|
+
PHI = 1.618;
|
|
23524
|
+
NODE_HEIGHT = 60;
|
|
23525
|
+
NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
|
|
23526
|
+
DESC_NODE_WIDTH = 140;
|
|
23527
|
+
DESC_FONT_SIZE2 = 10;
|
|
23528
|
+
DESC_LINE_HEIGHT2 = 1.4;
|
|
23529
|
+
DESC_PADDING = 8;
|
|
23530
|
+
SEPARATOR_GAP5 = 4;
|
|
23531
|
+
MAX_DESC_LINES2 = 6;
|
|
23532
|
+
MAX_LABEL_LINES = 3;
|
|
23533
|
+
LABEL_LINE_HEIGHT = 1.3;
|
|
23534
|
+
LABEL_PAD = 12;
|
|
23535
|
+
elkInstance = null;
|
|
23536
|
+
CROSSINGS_FORGIVENESS = 1;
|
|
23537
|
+
}
|
|
23538
|
+
});
|
|
23539
|
+
|
|
23477
23540
|
// src/mindmap/text-wrap.ts
|
|
23478
23541
|
function tokenize(text) {
|
|
23479
23542
|
const tokens = [];
|
|
@@ -23612,7 +23675,7 @@ var layout_exports6 = {};
|
|
|
23612
23675
|
__export(layout_exports6, {
|
|
23613
23676
|
layoutMindmap: () => layoutMindmap
|
|
23614
23677
|
});
|
|
23615
|
-
function layoutMindmap(parsed,
|
|
23678
|
+
function layoutMindmap(parsed, _palette, options) {
|
|
23616
23679
|
const roots = parsed.roots;
|
|
23617
23680
|
if (roots.length === 0) {
|
|
23618
23681
|
return { nodes: [], edges: [], width: 0, height: 0 };
|
|
@@ -24508,7 +24571,7 @@ function layoutElement(el, x, y, width) {
|
|
|
24508
24571
|
node.height = getElementHeight(el);
|
|
24509
24572
|
return node;
|
|
24510
24573
|
}
|
|
24511
|
-
const isInlineRow = el.metadata
|
|
24574
|
+
const isInlineRow = el.metadata["_inlineRow"] === "true" || el.metadata["_labelField"] === "true";
|
|
24512
24575
|
const padTop = isInlineRow ? 0 : GROUP_PADDING_TOP;
|
|
24513
24576
|
const padBottom = isInlineRow ? 0 : GROUP_PADDING_BOTTOM;
|
|
24514
24577
|
const padX = isInlineRow ? 0 : GROUP_PADDING_X;
|
|
@@ -24557,7 +24620,7 @@ function allocateEqualWidths(children, totalWidth) {
|
|
|
24557
24620
|
}
|
|
24558
24621
|
function getElementHeight(el) {
|
|
24559
24622
|
if (el.type === "heading") {
|
|
24560
|
-
return el.headingLevel === 2 ? ELEMENT_HEIGHTS
|
|
24623
|
+
return el.headingLevel === 2 ? ELEMENT_HEIGHTS["subheading"] ?? 36 : ELEMENT_HEIGHTS["heading"] ?? 48;
|
|
24561
24624
|
}
|
|
24562
24625
|
if (el.type === "textInput" && el.fieldVariant === "textarea") {
|
|
24563
24626
|
return 80;
|
|
@@ -24571,16 +24634,16 @@ function getElementHeight(el) {
|
|
|
24571
24634
|
if (el.type === "image") {
|
|
24572
24635
|
if (el.imageHint === "round") return 80;
|
|
24573
24636
|
if (el.imageHint === "wide") return 80;
|
|
24574
|
-
return ELEMENT_HEIGHTS
|
|
24637
|
+
return ELEMENT_HEIGHTS["image"] ?? 120;
|
|
24575
24638
|
}
|
|
24576
|
-
if (el.metadata
|
|
24639
|
+
if (el.metadata["_labelField"] === "true") {
|
|
24577
24640
|
return 36;
|
|
24578
24641
|
}
|
|
24579
24642
|
return ELEMENT_HEIGHTS[el.type] ?? 24;
|
|
24580
24643
|
}
|
|
24581
24644
|
function getSpacingAfter(el) {
|
|
24582
24645
|
if (el.type === "heading" && el.headingLevel === 2) {
|
|
24583
|
-
return SPACING_AFTER
|
|
24646
|
+
return SPACING_AFTER["subheading"] ?? 12;
|
|
24584
24647
|
}
|
|
24585
24648
|
return SPACING_AFTER[el.type] ?? 8;
|
|
24586
24649
|
}
|
|
@@ -24588,7 +24651,7 @@ function computeFieldAlignX(children) {
|
|
|
24588
24651
|
let maxLabelWidth = 0;
|
|
24589
24652
|
let labelFieldCount = 0;
|
|
24590
24653
|
for (const child of children) {
|
|
24591
|
-
if (child.metadata
|
|
24654
|
+
if (child.metadata["_labelField"] === "true" && child.children.length >= 2) {
|
|
24592
24655
|
const labelEl = child.children[0];
|
|
24593
24656
|
const labelWidth = labelEl.label.length * CHAR_WIDTH5;
|
|
24594
24657
|
maxLabelWidth = Math.max(maxLabelWidth, labelWidth);
|
|
@@ -24799,7 +24862,7 @@ function renderNode(parent, node, ctx, depth) {
|
|
|
24799
24862
|
function renderGroup(g, node, ctx, depth) {
|
|
24800
24863
|
const { palette, isTransparent } = ctx;
|
|
24801
24864
|
const el = node.element;
|
|
24802
|
-
if (el.metadata
|
|
24865
|
+
if (el.metadata["_inlineRow"] === "true" || el.metadata["_labelField"] === "true") {
|
|
24803
24866
|
for (const child of node.children) {
|
|
24804
24867
|
renderNode(g, child, ctx, depth);
|
|
24805
24868
|
}
|
|
@@ -24927,7 +24990,7 @@ function renderDivider(g, node, ctx) {
|
|
|
24927
24990
|
function renderText(g, node, ctx) {
|
|
24928
24991
|
const { palette } = ctx;
|
|
24929
24992
|
const el = node.element;
|
|
24930
|
-
if (el.metadata
|
|
24993
|
+
if (el.metadata["_labelField"] === "true" && el.children.length >= 2) {
|
|
24931
24994
|
for (const child of node.children) {
|
|
24932
24995
|
renderNode(g, child, ctx, 0);
|
|
24933
24996
|
}
|
|
@@ -25662,7 +25725,7 @@ function layoutC4Context(parsed, activeTagGroup) {
|
|
|
25662
25725
|
}
|
|
25663
25726
|
const contextRels = rollUpContextRelationships(parsed);
|
|
25664
25727
|
const spacing = computeAdaptiveSpacing(contextRels);
|
|
25665
|
-
const g = new
|
|
25728
|
+
const g = new import_dagre4.default.graphlib.Graph();
|
|
25666
25729
|
g.setGraph({
|
|
25667
25730
|
rankdir: "TB",
|
|
25668
25731
|
nodesep: spacing.nodesep,
|
|
@@ -25683,7 +25746,7 @@ function layoutC4Context(parsed, activeTagGroup) {
|
|
|
25683
25746
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
25684
25747
|
}
|
|
25685
25748
|
}
|
|
25686
|
-
|
|
25749
|
+
import_dagre4.default.layout(g);
|
|
25687
25750
|
reduceCrossings(
|
|
25688
25751
|
g,
|
|
25689
25752
|
validRels.map((r) => ({ source: r.sourceName, target: r.targetName }))
|
|
@@ -25855,7 +25918,7 @@ function layoutC4Containers(parsed, systemName, activeTagGroup) {
|
|
|
25855
25918
|
}
|
|
25856
25919
|
}
|
|
25857
25920
|
const hasGroups = elementToGroup.size > 0;
|
|
25858
|
-
const g = hasGroups ? new
|
|
25921
|
+
const g = hasGroups ? new import_dagre4.default.graphlib.Graph({ compound: true }) : new import_dagre4.default.graphlib.Graph();
|
|
25859
25922
|
g.setDefaultEdgeLabel(() => ({}));
|
|
25860
25923
|
if (hasGroups) {
|
|
25861
25924
|
const seenGroups = /* @__PURE__ */ new Set();
|
|
@@ -25933,7 +25996,7 @@ function layoutC4Containers(parsed, systemName, activeTagGroup) {
|
|
|
25933
25996
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
25934
25997
|
}
|
|
25935
25998
|
}
|
|
25936
|
-
|
|
25999
|
+
import_dagre4.default.layout(g);
|
|
25937
26000
|
const nodeGroupMap = hasGroups ? new Map([...elementToGroup.entries()].map(([k, v]) => [k, v.name])) : void 0;
|
|
25938
26001
|
reduceCrossings(
|
|
25939
26002
|
g,
|
|
@@ -26259,7 +26322,7 @@ function layoutC4Components(parsed, systemName, containerName, activeTagGroup) {
|
|
|
26259
26322
|
}
|
|
26260
26323
|
}
|
|
26261
26324
|
const hasGroups = elementToGroup.size > 0;
|
|
26262
|
-
const g = hasGroups ? new
|
|
26325
|
+
const g = hasGroups ? new import_dagre4.default.graphlib.Graph({ compound: true }) : new import_dagre4.default.graphlib.Graph();
|
|
26263
26326
|
g.setDefaultEdgeLabel(() => ({}));
|
|
26264
26327
|
if (hasGroups) {
|
|
26265
26328
|
const seenGroups = /* @__PURE__ */ new Set();
|
|
@@ -26343,7 +26406,7 @@ function layoutC4Components(parsed, systemName, containerName, activeTagGroup) {
|
|
|
26343
26406
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
26344
26407
|
}
|
|
26345
26408
|
}
|
|
26346
|
-
|
|
26409
|
+
import_dagre4.default.layout(g);
|
|
26347
26410
|
const nodeGroupMap = hasGroups ? new Map([...elementToGroup.entries()].map(([k, v]) => [k, v.name])) : void 0;
|
|
26348
26411
|
reduceCrossings(
|
|
26349
26412
|
g,
|
|
@@ -26632,7 +26695,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
26632
26695
|
for (const r of refEntries) {
|
|
26633
26696
|
nameToElement.set(r.element.name, r.element);
|
|
26634
26697
|
}
|
|
26635
|
-
const g = new
|
|
26698
|
+
const g = new import_dagre4.default.graphlib.Graph({ compound: true });
|
|
26636
26699
|
g.setDefaultEdgeLabel(() => ({}));
|
|
26637
26700
|
for (const [infraId] of infraIds) {
|
|
26638
26701
|
g.setNode(infraId, {});
|
|
@@ -26676,7 +26739,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
26676
26739
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
26677
26740
|
}
|
|
26678
26741
|
}
|
|
26679
|
-
|
|
26742
|
+
import_dagre4.default.layout(g);
|
|
26680
26743
|
const nodeInfraMap = /* @__PURE__ */ new Map();
|
|
26681
26744
|
for (const r of refEntries) nodeInfraMap.set(r.element.name, r.infraId);
|
|
26682
26745
|
reduceCrossings(
|
|
@@ -26854,11 +26917,11 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
26854
26917
|
height: totalHeight
|
|
26855
26918
|
};
|
|
26856
26919
|
}
|
|
26857
|
-
var
|
|
26920
|
+
var import_dagre4, gNode, gEdge, CHAR_WIDTH6, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, DESC_LINE_HEIGHT5, DESC_CHAR_WIDTH, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT5, META_CHAR_WIDTH, MARGIN5, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, LEGEND_HEIGHT4, LEGEND_PILL_PAD4, LEGEND_DOT_R4, LEGEND_ENTRY_DOT_GAP4, LEGEND_ENTRY_TRAIL4, LEGEND_CAPSULE_PAD4, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
|
|
26858
26921
|
var init_layout8 = __esm({
|
|
26859
26922
|
"src/c4/layout.ts"() {
|
|
26860
26923
|
"use strict";
|
|
26861
|
-
|
|
26924
|
+
import_dagre4 = __toESM(require("@dagrejs/dagre"), 1);
|
|
26862
26925
|
init_legend_constants();
|
|
26863
26926
|
gNode = (g, name) => g.node(name);
|
|
26864
26927
|
gEdge = (g, v, w) => g.edge(v, w);
|
|
@@ -27941,7 +28004,7 @@ function layoutGraph(graph, options) {
|
|
|
27941
28004
|
if (allNodes.length === 0) {
|
|
27942
28005
|
return { nodes: [], edges: [], groups: [], width: 0, height: 0 };
|
|
27943
28006
|
}
|
|
27944
|
-
const g = new
|
|
28007
|
+
const g = new import_dagre5.default.graphlib.Graph({ compound: true });
|
|
27945
28008
|
g.setGraph({
|
|
27946
28009
|
rankdir: graph.direction,
|
|
27947
28010
|
nodesep: 50,
|
|
@@ -27977,7 +28040,7 @@ function layoutGraph(graph, options) {
|
|
|
27977
28040
|
label: edge.label ?? ""
|
|
27978
28041
|
});
|
|
27979
28042
|
}
|
|
27980
|
-
|
|
28043
|
+
import_dagre5.default.layout(g);
|
|
27981
28044
|
const collapsedGroupIds = collapsedChildCounts ? new Set(collapsedChildCounts.keys()) : /* @__PURE__ */ new Set();
|
|
27982
28045
|
const layoutNodes = allNodes.map((node) => {
|
|
27983
28046
|
const pos = g.node(node.id);
|
|
@@ -28094,11 +28157,11 @@ function layoutGraph(graph, options) {
|
|
|
28094
28157
|
height: totalHeight
|
|
28095
28158
|
};
|
|
28096
28159
|
}
|
|
28097
|
-
var
|
|
28160
|
+
var import_dagre5, GROUP_PADDING;
|
|
28098
28161
|
var init_layout9 = __esm({
|
|
28099
28162
|
"src/graph/layout.ts"() {
|
|
28100
28163
|
"use strict";
|
|
28101
|
-
|
|
28164
|
+
import_dagre5 = __toESM(require("@dagrejs/dagre"), 1);
|
|
28102
28165
|
GROUP_PADDING = 20;
|
|
28103
28166
|
}
|
|
28104
28167
|
});
|
|
@@ -28410,7 +28473,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
28410
28473
|
endTerminalIds.add(node.id);
|
|
28411
28474
|
}
|
|
28412
28475
|
}
|
|
28413
|
-
const colorOff = graph.options?.color === "off";
|
|
28476
|
+
const colorOff = graph.options?.["color"] === "off";
|
|
28414
28477
|
const solid = graph.options?.["solid-fill"] === "on";
|
|
28415
28478
|
for (const node of layout.nodes) {
|
|
28416
28479
|
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);
|
|
@@ -29643,7 +29706,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
29643
29706
|
};
|
|
29644
29707
|
}
|
|
29645
29708
|
const isLR = computed.direction !== "TB";
|
|
29646
|
-
const g = new
|
|
29709
|
+
const g = new import_dagre6.default.graphlib.Graph();
|
|
29647
29710
|
g.setGraph({
|
|
29648
29711
|
rankdir: computed.direction === "TB" ? "TB" : "LR",
|
|
29649
29712
|
nodesep: isLR ? 70 : 60,
|
|
@@ -29694,7 +29757,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
29694
29757
|
g.setEdge(edge.sourceId, edge.targetId, { label: edge.label });
|
|
29695
29758
|
}
|
|
29696
29759
|
}
|
|
29697
|
-
|
|
29760
|
+
import_dagre6.default.layout(g);
|
|
29698
29761
|
const layoutNodes = computed.nodes.map((node) => {
|
|
29699
29762
|
const pos = g.node(node.id);
|
|
29700
29763
|
return {
|
|
@@ -29856,11 +29919,11 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
29856
29919
|
height: totalHeight
|
|
29857
29920
|
};
|
|
29858
29921
|
}
|
|
29859
|
-
var
|
|
29922
|
+
var import_dagre6, MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT7, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT5, CHAR_WIDTH7, META_CHAR_WIDTH3, PADDING_X3, GROUP_PADDING2, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP;
|
|
29860
29923
|
var init_layout10 = __esm({
|
|
29861
29924
|
"src/infra/layout.ts"() {
|
|
29862
29925
|
"use strict";
|
|
29863
|
-
|
|
29926
|
+
import_dagre6 = __toESM(require("@dagrejs/dagre"), 1);
|
|
29864
29927
|
MIN_NODE_WIDTH2 = 140;
|
|
29865
29928
|
NODE_HEADER_HEIGHT = 28;
|
|
29866
29929
|
META_LINE_HEIGHT7 = 14;
|
|
@@ -30602,7 +30665,7 @@ function renderGroups(svg, groups, palette, _isDark) {
|
|
|
30602
30665
|
}
|
|
30603
30666
|
}
|
|
30604
30667
|
}
|
|
30605
|
-
function renderEdgePaths(svg, edges, nodes, groups, palette,
|
|
30668
|
+
function renderEdgePaths(svg, edges, nodes, groups, palette, _isDark, animate, direction, speedMultiplier = 1) {
|
|
30606
30669
|
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
30607
30670
|
const maxRps = Math.max(...edges.map((e) => e.computedRps), 1);
|
|
30608
30671
|
const { srcPts, tgtPts } = computePortPts(edges, nodeMap, direction);
|
|
@@ -30643,7 +30706,7 @@ function renderEdgePaths(svg, edges, nodes, groups, palette, isDark, animate, di
|
|
|
30643
30706
|
}
|
|
30644
30707
|
}
|
|
30645
30708
|
}
|
|
30646
|
-
function renderEdgeLabels(svg, edges, nodes, groups, palette,
|
|
30709
|
+
function renderEdgeLabels(svg, edges, nodes, groups, palette, _isDark, animate, direction) {
|
|
30647
30710
|
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
30648
30711
|
const { srcPts, tgtPts } = computePortPts(edges, nodeMap, direction);
|
|
30649
30712
|
for (const edge of edges) {
|
|
@@ -31384,7 +31447,7 @@ function sampleBetaPert(o, m, p, rng) {
|
|
|
31384
31447
|
const beta = 1 + 4 * (p - m) / range;
|
|
31385
31448
|
return o + sampleBeta(alpha, beta, rng) * range;
|
|
31386
31449
|
}
|
|
31387
|
-
function simulate(resolved, expanded,
|
|
31450
|
+
function simulate(resolved, expanded, _predecessors, _successors, topo, terminals, poisoned, opts) {
|
|
31388
31451
|
const rng = mulberry32(opts.seed);
|
|
31389
31452
|
const expById = /* @__PURE__ */ new Map();
|
|
31390
31453
|
for (const e of expanded) expById.set(e.id, e);
|
|
@@ -32504,7 +32567,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32504
32567
|
}
|
|
32505
32568
|
}
|
|
32506
32569
|
const dagreId = (id) => memberToGroup.get(id) ?? id;
|
|
32507
|
-
const g = new
|
|
32570
|
+
const g = new import_dagre7.default.graphlib.Graph();
|
|
32508
32571
|
g.setGraph({
|
|
32509
32572
|
rankdir: resolved.options.direction,
|
|
32510
32573
|
nodesep: 50,
|
|
@@ -32543,7 +32606,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32543
32606
|
seenEdges.add(k);
|
|
32544
32607
|
g.setEdge(src, tgt, {});
|
|
32545
32608
|
}
|
|
32546
|
-
|
|
32609
|
+
import_dagre7.default.layout(g);
|
|
32547
32610
|
const swimApplied = applySwimLanes(
|
|
32548
32611
|
g,
|
|
32549
32612
|
resolved,
|
|
@@ -32663,7 +32726,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32663
32726
|
height: totalH + DIAGRAM_PADDING10
|
|
32664
32727
|
};
|
|
32665
32728
|
}
|
|
32666
|
-
function applySwimLanes(g, resolved,
|
|
32729
|
+
function applySwimLanes(g, resolved, _memberToGroup, collapsedGroupIds) {
|
|
32667
32730
|
const expanded = resolved.groups.filter(
|
|
32668
32731
|
(rg) => !collapsedGroupIds.has(rg.group.id)
|
|
32669
32732
|
);
|
|
@@ -32889,7 +32952,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32889
32952
|
buckets.get(key).push(id);
|
|
32890
32953
|
}
|
|
32891
32954
|
const edges = g.edges().map((e) => ({ v: e.v, w: e.w }));
|
|
32892
|
-
const
|
|
32955
|
+
const countCrossings2 = () => {
|
|
32893
32956
|
let total = 0;
|
|
32894
32957
|
for (let i = 0; i < edges.length; i++) {
|
|
32895
32958
|
const a = edges[i];
|
|
@@ -32902,13 +32965,13 @@ function reduceCrossings2(g, direction) {
|
|
|
32902
32965
|
const b1 = g.node(b.v);
|
|
32903
32966
|
const b2 = g.node(b.w);
|
|
32904
32967
|
if (!b1 || !b2) continue;
|
|
32905
|
-
if (
|
|
32968
|
+
if (segmentsCross2(a1, a2, b1, b2)) total++;
|
|
32906
32969
|
}
|
|
32907
32970
|
}
|
|
32908
32971
|
return total;
|
|
32909
32972
|
};
|
|
32910
32973
|
const MAX_ITER = 8;
|
|
32911
|
-
let baseline =
|
|
32974
|
+
let baseline = countCrossings2();
|
|
32912
32975
|
if (baseline === 0) return;
|
|
32913
32976
|
for (let iter = 0; iter < MAX_ITER; iter++) {
|
|
32914
32977
|
let improved = false;
|
|
@@ -32926,7 +32989,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32926
32989
|
const bv = bn[slotAxis];
|
|
32927
32990
|
an[slotAxis] = bv;
|
|
32928
32991
|
bn[slotAxis] = av;
|
|
32929
|
-
const after =
|
|
32992
|
+
const after = countCrossings2();
|
|
32930
32993
|
if (after < baseline) {
|
|
32931
32994
|
baseline = after;
|
|
32932
32995
|
improved = true;
|
|
@@ -32947,7 +33010,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32947
33010
|
data.points = smoothEdge(src, tgt, direction);
|
|
32948
33011
|
}
|
|
32949
33012
|
}
|
|
32950
|
-
function
|
|
33013
|
+
function segmentsCross2(a1, a2, b1, b2) {
|
|
32951
33014
|
const ccw = (p, q, r) => (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
|
|
32952
33015
|
const d1 = ccw(b1, b2, a1);
|
|
32953
33016
|
const d2 = ccw(b1, b2, a2);
|
|
@@ -32955,11 +33018,11 @@ function segmentsCross(a1, a2, b1, b2) {
|
|
|
32955
33018
|
const d4 = ccw(a1, a2, b2);
|
|
32956
33019
|
return (d1 > 0 && d2 < 0 || d1 < 0 && d2 > 0) && (d32 > 0 && d4 < 0 || d32 < 0 && d4 > 0);
|
|
32957
33020
|
}
|
|
32958
|
-
var
|
|
33021
|
+
var import_dagre7, DEFAULT_NODE_HEIGHT, MILESTONE_NODE_HEIGHT, COLLAPSED_GROUP_HEIGHT, DIAGRAM_PADDING10, GROUP_PADDING3, GROUP_TOP_PADDING, SWIMLANE_SLOT_SEP, SWIMLANE_GAP, NODE_CELL_FONT_SIZE, NODE_NAME_FONT_SIZE, CELL_CHAR_WIDTH_RATIO, CELL_PAD_X, NAME_PAD_X, NAME_PIN_WIDTH, MIN_CELL_WIDTH, MIN_NODE_WIDTH3, MAX_NODE_WIDTH2, MIN_MILESTONE_WIDTH, MAX_MILESTONE_WIDTH;
|
|
32959
33022
|
var init_layout11 = __esm({
|
|
32960
33023
|
"src/pert/layout.ts"() {
|
|
32961
33024
|
"use strict";
|
|
32962
|
-
|
|
33025
|
+
import_dagre7 = __toESM(require("@dagrejs/dagre"), 1);
|
|
32963
33026
|
init_internal();
|
|
32964
33027
|
DEFAULT_NODE_HEIGHT = 90;
|
|
32965
33028
|
MILESTONE_NODE_HEIGHT = DEFAULT_NODE_HEIGHT;
|
|
@@ -34956,12 +35019,6 @@ function calculateSchedule(parsed) {
|
|
|
34956
35019
|
const warn2 = (line12, message) => {
|
|
34957
35020
|
diagnostics.push(makeDgmoError(line12, message, "warning"));
|
|
34958
35021
|
};
|
|
34959
|
-
const _fail = (line12, message) => {
|
|
34960
|
-
const diag = makeDgmoError(line12, message);
|
|
34961
|
-
diagnostics.push(diag);
|
|
34962
|
-
result.error = formatDgmoError(diag);
|
|
34963
|
-
return result;
|
|
34964
|
-
};
|
|
34965
35022
|
const holidaySet = buildHolidaySet(parsed.holidays);
|
|
34966
35023
|
let projectStart;
|
|
34967
35024
|
if (parsed.options.start) {
|
|
@@ -34986,7 +35043,6 @@ function calculateSchedule(parsed) {
|
|
|
34986
35043
|
}
|
|
34987
35044
|
buildImplicitDeps(parsed.nodes, taskMap);
|
|
34988
35045
|
for (const task of allTasks2) {
|
|
34989
|
-
const _node = taskMap.get(task.id);
|
|
34990
35046
|
for (const dep of task.dependencies) {
|
|
34991
35047
|
const resolved = resolveTaskName(dep.targetName, allTasks2);
|
|
34992
35048
|
if (isResolverError(resolved)) {
|
|
@@ -36525,7 +36581,7 @@ function buildControlsToggles(hasCriticalPath, criticalPathActive, hasDependenci
|
|
|
36525
36581
|
}
|
|
36526
36582
|
return toggles;
|
|
36527
36583
|
}
|
|
36528
|
-
function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive,
|
|
36584
|
+
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) {
|
|
36529
36585
|
let visibleGroups;
|
|
36530
36586
|
if (activeGroupName) {
|
|
36531
36587
|
const activeGroup = tagGroups.filter(
|
|
@@ -37488,7 +37544,7 @@ function resolveTaskColor(rt, activeTagGroup, resolved, seriesColors2, palette)
|
|
|
37488
37544
|
}
|
|
37489
37545
|
return palette.accent || seriesColors2[0] || "#4a90d9";
|
|
37490
37546
|
}
|
|
37491
|
-
function renderTimeScaleHorizontal(g, scale,
|
|
37547
|
+
function renderTimeScaleHorizontal(g, scale, _innerWidth, innerHeight, textColor) {
|
|
37492
37548
|
const [domainMin, domainMax] = scale.domain();
|
|
37493
37549
|
const ticks = computeTimeTicks(domainMin, domainMax, scale);
|
|
37494
37550
|
if (ticks.length < 2) return;
|
|
@@ -37735,7 +37791,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
|
|
|
37735
37791
|
for (const group of layout.groups) {
|
|
37736
37792
|
if (group.collapsed) collapsedGroupIds.add(group.id);
|
|
37737
37793
|
}
|
|
37738
|
-
const colorOff = graph.options?.color === "off";
|
|
37794
|
+
const colorOff = graph.options?.["color"] === "off";
|
|
37739
37795
|
const solid = graph.options?.["solid-fill"] === "on";
|
|
37740
37796
|
for (const node of layout.nodes) {
|
|
37741
37797
|
const isCollapsedGroup = collapsedGroupIds.has(node.id);
|
|
@@ -38135,7 +38191,7 @@ function renderQuadrantFocus(container, parsed, quadrantPosition, palette, isDar
|
|
|
38135
38191
|
}
|
|
38136
38192
|
}
|
|
38137
38193
|
}
|
|
38138
|
-
function renderQuarterCircle(svg, parsed, quadrant, qColor, palette, isDark, width, height, mutedColor,
|
|
38194
|
+
function renderQuarterCircle(svg, parsed, quadrant, qColor, palette, isDark, width, height, mutedColor, _tooltip, rootContainer, onClickItem) {
|
|
38139
38195
|
const padding = 8;
|
|
38140
38196
|
const size = Math.min(width - padding, height - padding);
|
|
38141
38197
|
const maxRadius = size * 0.95;
|
|
@@ -39005,7 +39061,7 @@ function estimateListingHeight(parsed) {
|
|
|
39005
39061
|
);
|
|
39006
39062
|
return LISTING_LINE_HEIGHT * (maxBlipsInQuadrant + 1) + LISTING_LINE_HEIGHT + LISTING_TOP_MARGIN;
|
|
39007
39063
|
}
|
|
39008
|
-
function createBlipPopover(container,
|
|
39064
|
+
function createBlipPopover(container, _palette, isDark) {
|
|
39009
39065
|
container.style.position = "relative";
|
|
39010
39066
|
const existing = container.querySelector(
|
|
39011
39067
|
"[data-blip-popover]"
|
|
@@ -40873,7 +40929,7 @@ function computeEdgeLabelPosition(midAngle, radius, cx, cy, lineCount, maxCharLe
|
|
|
40873
40929
|
labelAngle: best.labelAngle
|
|
40874
40930
|
};
|
|
40875
40931
|
}
|
|
40876
|
-
function fitToCanvas(nodes, edges, parsed,
|
|
40932
|
+
function fitToCanvas(nodes, edges, parsed, _cx, _cy, radius, width, height, _isClockwise) {
|
|
40877
40933
|
const PADDING3 = 30;
|
|
40878
40934
|
let contentMinX = Infinity, contentMaxX = -Infinity;
|
|
40879
40935
|
let contentMinY = Infinity, contentMaxY = -Infinity;
|
|
@@ -42382,7 +42438,7 @@ function renderPhaseBar(svg, phase, x, y, width, palette, collapsed, autoColor,
|
|
|
42382
42438
|
});
|
|
42383
42439
|
}
|
|
42384
42440
|
}
|
|
42385
|
-
function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette, surfaceBg, solid, taskDiagnostics,
|
|
42441
|
+
function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette, surfaceBg, solid, taskDiagnostics, _hasAnyDiagnostic, rowContent, onClickLine, _onMarkerDragStart) {
|
|
42386
42442
|
const rowG = svg.append("g").attr("class", "raci-task-row").attr("data-task-id", task.id).attr("data-line-number", String(task.lineNumber));
|
|
42387
42443
|
const labelX = x + 8;
|
|
42388
42444
|
const labelMaxW = labelW - 16;
|
|
@@ -43188,7 +43244,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
43188
43244
|
const messages = collapsed ? collapsed.messages : parsed.messages;
|
|
43189
43245
|
const elements = collapsed ? collapsed.elements : parsed.elements;
|
|
43190
43246
|
const groups = collapsed ? collapsed.groups : parsed.groups;
|
|
43191
|
-
const collapsedGroupIds = collapsed?.collapsedGroupIds ?? /* @__PURE__ */ new Map();
|
|
43192
43247
|
const collapsedSections = options?.collapsedSections;
|
|
43193
43248
|
const sourceParticipants = collapsed ? collapsed.participants : parsed.participants;
|
|
43194
43249
|
const participants = applyPositionOverrides(
|
|
@@ -43216,7 +43271,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
43216
43271
|
return Math.min(NOTE_MAX_W, laneMax);
|
|
43217
43272
|
};
|
|
43218
43273
|
const charsForWidth = (maxW) => Math.floor((maxW - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W);
|
|
43219
|
-
const activationsOff = parsedOptions
|
|
43274
|
+
const activationsOff = parsedOptions["activations"]?.toLowerCase() === "off";
|
|
43220
43275
|
const activeTagGroup = resolveActiveTagGroup(
|
|
43221
43276
|
parsed.tagGroups,
|
|
43222
43277
|
parsedOptions["active-tag"],
|
|
@@ -46168,7 +46223,7 @@ function renderTimelineGroupLegend(g, groups, groupColorMap, textColor, palette,
|
|
|
46168
46223
|
legendX += pillW + GAP;
|
|
46169
46224
|
}
|
|
46170
46225
|
}
|
|
46171
|
-
function
|
|
46226
|
+
function setupTimeline(container, parsed, palette, isDark, exportDims, activeTagGroup, swimlaneTagGroup) {
|
|
46172
46227
|
d3Selection22.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
46173
46228
|
const solid = parsed.solidFill === true;
|
|
46174
46229
|
const {
|
|
@@ -46177,19 +46232,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46177
46232
|
timelineEras,
|
|
46178
46233
|
timelineMarkers,
|
|
46179
46234
|
timelineSort,
|
|
46180
|
-
timelineScale,
|
|
46181
|
-
timelineSwimlanes,
|
|
46182
46235
|
orientation
|
|
46183
46236
|
} = parsed;
|
|
46184
|
-
|
|
46185
|
-
|
|
46186
|
-
if (
|
|
46187
|
-
|
|
46237
|
+
if (timelineEvents.length === 0) return null;
|
|
46238
|
+
let resolvedSwimlaneTG = swimlaneTagGroup ?? null;
|
|
46239
|
+
if (resolvedSwimlaneTG == null && timelineSort === "tag" && parsed.timelineDefaultSwimlaneTG) {
|
|
46240
|
+
resolvedSwimlaneTG = parsed.timelineDefaultSwimlaneTG;
|
|
46188
46241
|
}
|
|
46189
46242
|
const tooltip = createTooltip2(container, palette, isDark);
|
|
46190
46243
|
const width = exportDims?.width ?? container.clientWidth;
|
|
46191
46244
|
const height = exportDims?.height ?? container.clientHeight;
|
|
46192
|
-
if (width <= 0 || height <= 0) return;
|
|
46245
|
+
if (width <= 0 || height <= 0) return null;
|
|
46193
46246
|
const isVertical = orientation === "vertical";
|
|
46194
46247
|
const textColor = palette.text;
|
|
46195
46248
|
const mutedColor = palette.border;
|
|
@@ -46201,8 +46254,8 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46201
46254
|
groupColorMap.set(grp.name, grp.color ?? colors[i % colors.length]);
|
|
46202
46255
|
});
|
|
46203
46256
|
let tagLanes = null;
|
|
46204
|
-
if (
|
|
46205
|
-
const tagKey =
|
|
46257
|
+
if (resolvedSwimlaneTG) {
|
|
46258
|
+
const tagKey = resolvedSwimlaneTG.toLowerCase();
|
|
46206
46259
|
const tagGroup = parsed.timelineTagGroups.find(
|
|
46207
46260
|
(g) => g.name.toLowerCase() === tagKey
|
|
46208
46261
|
);
|
|
@@ -46233,7 +46286,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46233
46286
|
}
|
|
46234
46287
|
}
|
|
46235
46288
|
}
|
|
46236
|
-
const effectiveColorTG = activeTagGroup ??
|
|
46289
|
+
const effectiveColorTG = activeTagGroup ?? resolvedSwimlaneTG ?? null;
|
|
46237
46290
|
function eventColor(ev) {
|
|
46238
46291
|
if (effectiveColorTG) {
|
|
46239
46292
|
const tagColor = resolveTagColor(
|
|
@@ -46289,6 +46342,30 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46289
46342
|
}
|
|
46290
46343
|
}
|
|
46291
46344
|
const datePadding = (maxDate - minDate) * 0.05 || 0.5;
|
|
46345
|
+
const tagLegendReserve = parsed.timelineTagGroups.length > 0 ? 36 : 0;
|
|
46346
|
+
return {
|
|
46347
|
+
width,
|
|
46348
|
+
height,
|
|
46349
|
+
isVertical,
|
|
46350
|
+
tooltip,
|
|
46351
|
+
solid,
|
|
46352
|
+
textColor,
|
|
46353
|
+
mutedColor,
|
|
46354
|
+
bgColor,
|
|
46355
|
+
bg,
|
|
46356
|
+
swimlaneTagGroup: resolvedSwimlaneTG,
|
|
46357
|
+
groupColorMap,
|
|
46358
|
+
tagLanes,
|
|
46359
|
+
eventColor,
|
|
46360
|
+
minDate,
|
|
46361
|
+
maxDate,
|
|
46362
|
+
datePadding,
|
|
46363
|
+
earliestStartDateStr,
|
|
46364
|
+
latestEndDateStr,
|
|
46365
|
+
tagLegendReserve
|
|
46366
|
+
};
|
|
46367
|
+
}
|
|
46368
|
+
function makeTimelineHoverHelpers() {
|
|
46292
46369
|
const FADE_OPACITY3 = 0.1;
|
|
46293
46370
|
function fadeToGroup(g, groupName) {
|
|
46294
46371
|
g.selectAll(".tl-event").each(function() {
|
|
@@ -46388,337 +46465,683 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46388
46465
|
evG.attr(`data-tag-${key}`, value.toLowerCase());
|
|
46389
46466
|
}
|
|
46390
46467
|
}
|
|
46391
|
-
|
|
46392
|
-
|
|
46393
|
-
|
|
46394
|
-
|
|
46395
|
-
|
|
46396
|
-
|
|
46397
|
-
|
|
46398
|
-
|
|
46399
|
-
|
|
46400
|
-
|
|
46401
|
-
|
|
46402
|
-
|
|
46403
|
-
|
|
46404
|
-
|
|
46405
|
-
|
|
46406
|
-
|
|
46407
|
-
|
|
46408
|
-
|
|
46409
|
-
|
|
46410
|
-
|
|
46411
|
-
|
|
46412
|
-
|
|
46413
|
-
|
|
46468
|
+
return {
|
|
46469
|
+
FADE_OPACITY: FADE_OPACITY3,
|
|
46470
|
+
fadeToGroup,
|
|
46471
|
+
fadeToEra,
|
|
46472
|
+
fadeToMarker,
|
|
46473
|
+
fadeReset,
|
|
46474
|
+
fadeToTagValue,
|
|
46475
|
+
setTagAttrs
|
|
46476
|
+
};
|
|
46477
|
+
}
|
|
46478
|
+
function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, swimlaneTagGroup, activeTagGroup, onTagStateChange, viewMode) {
|
|
46479
|
+
if (parsed.timelineTagGroups.length === 0) return;
|
|
46480
|
+
const { width, textColor, groupColorMap, solid } = setup;
|
|
46481
|
+
const { FADE_OPACITY: FADE_OPACITY3, fadeReset, fadeToTagValue } = hovers;
|
|
46482
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46483
|
+
const { timelineEvents } = parsed;
|
|
46484
|
+
const LG_HEIGHT = LEGEND_HEIGHT;
|
|
46485
|
+
const LG_PILL_PAD = LEGEND_PILL_PAD;
|
|
46486
|
+
const LG_PILL_FONT_SIZE = LEGEND_PILL_FONT_SIZE;
|
|
46487
|
+
const LG_CAPSULE_PAD = LEGEND_CAPSULE_PAD;
|
|
46488
|
+
const LG_DOT_R = LEGEND_DOT_R;
|
|
46489
|
+
const LG_ENTRY_FONT_SIZE = LEGEND_ENTRY_FONT_SIZE;
|
|
46490
|
+
const LG_ENTRY_DOT_GAP = LEGEND_ENTRY_DOT_GAP;
|
|
46491
|
+
const LG_ENTRY_TRAIL = LEGEND_ENTRY_TRAIL;
|
|
46492
|
+
const LG_ICON_W = 20;
|
|
46493
|
+
const mainSvg = d3Selection22.select(container).select("svg");
|
|
46494
|
+
const mainG = mainSvg.select("g");
|
|
46495
|
+
if (!mainSvg.empty() && !mainG.empty()) {
|
|
46496
|
+
let drawSwimlaneIcon4 = function(parent, x, y, isSwimActive) {
|
|
46497
|
+
const iconG = parent.append("g").attr("class", "tl-swimlane-icon").attr("transform", `translate(${x}, ${y})`).style("cursor", "pointer");
|
|
46498
|
+
const barColor = isSwimActive ? palette.primary : palette.textMuted;
|
|
46499
|
+
const barOpacity = isSwimActive ? 1 : 0.35;
|
|
46500
|
+
const bars = [
|
|
46501
|
+
{ y: 0, w: 8 },
|
|
46502
|
+
{ y: 4, w: 12 },
|
|
46503
|
+
{ y: 8, w: 6 }
|
|
46504
|
+
];
|
|
46505
|
+
for (const bar of bars) {
|
|
46506
|
+
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);
|
|
46414
46507
|
}
|
|
46415
|
-
|
|
46416
|
-
|
|
46417
|
-
|
|
46418
|
-
|
|
46419
|
-
|
|
46420
|
-
|
|
46421
|
-
|
|
46422
|
-
|
|
46423
|
-
|
|
46424
|
-
|
|
46425
|
-
|
|
46426
|
-
|
|
46427
|
-
|
|
46428
|
-
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);
|
|
46429
|
-
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46430
|
-
renderChartTitle(
|
|
46431
|
-
svg,
|
|
46432
|
-
title,
|
|
46433
|
-
parsed.titleLineNumber,
|
|
46434
|
-
width,
|
|
46435
|
-
textColor,
|
|
46436
|
-
onClickItem
|
|
46437
|
-
);
|
|
46438
|
-
renderEras(
|
|
46439
|
-
g,
|
|
46440
|
-
timelineEras,
|
|
46441
|
-
yScale,
|
|
46442
|
-
true,
|
|
46443
|
-
innerWidth,
|
|
46444
|
-
innerHeight,
|
|
46445
|
-
(s, e) => fadeToEra(g, s, e),
|
|
46446
|
-
() => fadeReset(g),
|
|
46447
|
-
timelineScale,
|
|
46448
|
-
tooltip,
|
|
46449
|
-
palette
|
|
46450
|
-
);
|
|
46451
|
-
renderMarkers(
|
|
46452
|
-
g,
|
|
46453
|
-
timelineMarkers,
|
|
46454
|
-
yScale,
|
|
46455
|
-
true,
|
|
46456
|
-
innerWidth,
|
|
46457
|
-
innerHeight,
|
|
46458
|
-
(d) => fadeToMarker(g, d),
|
|
46459
|
-
() => fadeReset(g),
|
|
46460
|
-
timelineScale,
|
|
46461
|
-
tooltip,
|
|
46462
|
-
palette
|
|
46508
|
+
return iconG;
|
|
46509
|
+
}, relayout2 = function() {
|
|
46510
|
+
renderTimeline(
|
|
46511
|
+
container,
|
|
46512
|
+
parsed,
|
|
46513
|
+
palette,
|
|
46514
|
+
isDark,
|
|
46515
|
+
onClickItem,
|
|
46516
|
+
exportDims,
|
|
46517
|
+
currentActiveGroup,
|
|
46518
|
+
currentSwimlaneGroup,
|
|
46519
|
+
onTagStateChange,
|
|
46520
|
+
viewMode
|
|
46463
46521
|
);
|
|
46464
|
-
|
|
46465
|
-
|
|
46466
|
-
|
|
46467
|
-
|
|
46468
|
-
|
|
46469
|
-
|
|
46470
|
-
|
|
46471
|
-
|
|
46472
|
-
|
|
46473
|
-
|
|
46474
|
-
|
|
46475
|
-
|
|
46522
|
+
}, drawLegend2 = function() {
|
|
46523
|
+
mainSvg.selectAll(".tl-tag-legend-group").remove();
|
|
46524
|
+
mainSvg.selectAll(".tl-tag-legend-container").remove();
|
|
46525
|
+
const effectiveColorKey = (currentActiveGroup ?? currentSwimlaneGroup)?.toLowerCase() ?? null;
|
|
46526
|
+
const visibleGroups = viewMode ? legendGroups.filter(
|
|
46527
|
+
(lg) => effectiveColorKey != null && lg.group.name.toLowerCase() === effectiveColorKey
|
|
46528
|
+
) : legendGroups;
|
|
46529
|
+
if (visibleGroups.length === 0) return;
|
|
46530
|
+
const legendContainer = mainSvg.append("g").attr("class", "tl-tag-legend-container");
|
|
46531
|
+
if (currentActiveGroup) {
|
|
46532
|
+
legendContainer.attr(
|
|
46533
|
+
"data-legend-active",
|
|
46534
|
+
currentActiveGroup.toLowerCase()
|
|
46476
46535
|
);
|
|
46477
46536
|
}
|
|
46478
|
-
|
|
46479
|
-
|
|
46480
|
-
|
|
46481
|
-
|
|
46482
|
-
|
|
46483
|
-
|
|
46484
|
-
|
|
46485
|
-
|
|
46486
|
-
|
|
46487
|
-
|
|
46488
|
-
|
|
46489
|
-
|
|
46490
|
-
|
|
46491
|
-
|
|
46492
|
-
|
|
46493
|
-
|
|
46494
|
-
|
|
46495
|
-
|
|
46496
|
-
|
|
46497
|
-
|
|
46498
|
-
|
|
46499
|
-
|
|
46500
|
-
|
|
46501
|
-
|
|
46502
|
-
|
|
46503
|
-
|
|
46504
|
-
|
|
46505
|
-
|
|
46506
|
-
|
|
46507
|
-
|
|
46508
|
-
|
|
46509
|
-
|
|
46510
|
-
|
|
46511
|
-
|
|
46512
|
-
|
|
46513
|
-
|
|
46514
|
-
|
|
46515
|
-
let stroke2 = evColor;
|
|
46516
|
-
if (ev.uncertain) {
|
|
46517
|
-
const gradientId = `uncertain-vg-${ev.lineNumber}`;
|
|
46518
|
-
const strokeGradientId = `uncertain-vg-s-${ev.lineNumber}`;
|
|
46519
|
-
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46520
|
-
const defsEl = d3Selection22.select(defs);
|
|
46521
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46522
|
-
{ offset: "0%", opacity: 1 },
|
|
46523
|
-
{ offset: "80%", opacity: 1 },
|
|
46524
|
-
{ offset: "100%", opacity: 0 }
|
|
46525
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
46526
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46527
|
-
{ offset: "0%", opacity: 1 },
|
|
46528
|
-
{ offset: "80%", opacity: 1 },
|
|
46529
|
-
{ offset: "100%", opacity: 0 }
|
|
46530
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", evColor).attr("stop-opacity", (d) => d.opacity);
|
|
46531
|
-
fill2 = `url(#${gradientId})`;
|
|
46532
|
-
stroke2 = `url(#${strokeGradientId})`;
|
|
46533
|
-
}
|
|
46534
|
-
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);
|
|
46535
|
-
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);
|
|
46537
|
+
const iconAddon = viewMode ? 0 : LG_ICON_W;
|
|
46538
|
+
const centralGroups = visibleGroups.map((lg) => ({
|
|
46539
|
+
name: lg.group.name,
|
|
46540
|
+
entries: lg.group.entries.map((e) => ({
|
|
46541
|
+
value: e.value,
|
|
46542
|
+
color: e.color
|
|
46543
|
+
}))
|
|
46544
|
+
}));
|
|
46545
|
+
const centralActive = viewMode ? effectiveColorKey : currentActiveGroup;
|
|
46546
|
+
const centralConfig = {
|
|
46547
|
+
groups: centralGroups,
|
|
46548
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
46549
|
+
mode: "fixed",
|
|
46550
|
+
capsulePillAddonWidth: iconAddon
|
|
46551
|
+
};
|
|
46552
|
+
const centralState = { activeGroup: centralActive };
|
|
46553
|
+
const centralCallbacks = viewMode ? {} : {
|
|
46554
|
+
onGroupToggle: (groupName) => {
|
|
46555
|
+
currentActiveGroup = currentActiveGroup === groupName.toLowerCase() ? null : groupName.toLowerCase();
|
|
46556
|
+
drawLegend2();
|
|
46557
|
+
recolorEvents2();
|
|
46558
|
+
onTagStateChange?.(currentActiveGroup, currentSwimlaneGroup);
|
|
46559
|
+
},
|
|
46560
|
+
onEntryHover: (groupName, entryValue) => {
|
|
46561
|
+
const tagKey = groupName.toLowerCase();
|
|
46562
|
+
if (entryValue) {
|
|
46563
|
+
const tagVal = entryValue.toLowerCase();
|
|
46564
|
+
fadeToTagValue(mainG, tagKey, tagVal);
|
|
46565
|
+
mainSvg.selectAll("[data-legend-entry]").each(function() {
|
|
46566
|
+
const el = d3Selection22.select(this);
|
|
46567
|
+
const ev = el.attr("data-legend-entry");
|
|
46568
|
+
const eg = el.attr("data-tag-group") ?? el.node()?.closest?.("[data-tag-group]")?.getAttribute("data-tag-group");
|
|
46569
|
+
el.attr(
|
|
46570
|
+
"opacity",
|
|
46571
|
+
eg === tagKey && ev === tagVal ? 1 : FADE_OPACITY3
|
|
46572
|
+
);
|
|
46573
|
+
});
|
|
46536
46574
|
} else {
|
|
46537
|
-
|
|
46538
|
-
|
|
46575
|
+
fadeReset(mainG);
|
|
46576
|
+
mainSvg.selectAll("[data-legend-entry]").attr("opacity", 1);
|
|
46577
|
+
}
|
|
46578
|
+
},
|
|
46579
|
+
onGroupRendered: (groupName, groupEl, isActive) => {
|
|
46580
|
+
const groupKey = groupName.toLowerCase();
|
|
46581
|
+
groupEl.attr("data-tag-group", groupKey);
|
|
46582
|
+
if (isActive && !viewMode) {
|
|
46583
|
+
const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
|
|
46584
|
+
const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
46585
|
+
const pillXOff = LG_CAPSULE_PAD;
|
|
46586
|
+
const iconX = pillXOff + pillWidth3 + 5;
|
|
46587
|
+
const iconY = (LG_HEIGHT - 10) / 2;
|
|
46588
|
+
const iconEl = drawSwimlaneIcon4(
|
|
46589
|
+
groupEl,
|
|
46590
|
+
iconX,
|
|
46591
|
+
iconY,
|
|
46592
|
+
isSwimActive
|
|
46593
|
+
);
|
|
46594
|
+
iconEl.attr("data-swimlane-toggle", groupKey).on("click", (event) => {
|
|
46595
|
+
event.stopPropagation();
|
|
46596
|
+
currentSwimlaneGroup = currentSwimlaneGroup === groupKey ? null : groupKey;
|
|
46597
|
+
onTagStateChange?.(
|
|
46598
|
+
currentActiveGroup,
|
|
46599
|
+
currentSwimlaneGroup
|
|
46600
|
+
);
|
|
46601
|
+
relayout2();
|
|
46602
|
+
});
|
|
46539
46603
|
}
|
|
46540
46604
|
}
|
|
46541
|
-
});
|
|
46542
|
-
} else {
|
|
46543
|
-
const scaleMargin = timelineScale ? 40 : 0;
|
|
46544
|
-
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46545
|
-
const margin = {
|
|
46546
|
-
top: 104 + markerMargin + tagLegendReserve,
|
|
46547
|
-
right: 200,
|
|
46548
|
-
bottom: 40,
|
|
46549
|
-
left: 60 + scaleMargin
|
|
46550
46605
|
};
|
|
46551
|
-
const
|
|
46552
|
-
|
|
46553
|
-
|
|
46554
|
-
|
|
46555
|
-
|
|
46556
|
-
|
|
46557
|
-
|
|
46558
|
-
|
|
46559
|
-
|
|
46560
|
-
title,
|
|
46561
|
-
parsed.titleLineNumber,
|
|
46562
|
-
width,
|
|
46563
|
-
textColor,
|
|
46564
|
-
onClickItem
|
|
46565
|
-
);
|
|
46566
|
-
renderEras(
|
|
46567
|
-
g,
|
|
46568
|
-
timelineEras,
|
|
46569
|
-
yScale,
|
|
46570
|
-
true,
|
|
46571
|
-
innerWidth,
|
|
46572
|
-
innerHeight,
|
|
46573
|
-
(s, e) => fadeToEra(g, s, e),
|
|
46574
|
-
() => fadeReset(g),
|
|
46575
|
-
timelineScale,
|
|
46576
|
-
tooltip,
|
|
46577
|
-
palette
|
|
46578
|
-
);
|
|
46579
|
-
renderMarkers(
|
|
46580
|
-
g,
|
|
46581
|
-
timelineMarkers,
|
|
46582
|
-
yScale,
|
|
46583
|
-
true,
|
|
46584
|
-
innerWidth,
|
|
46585
|
-
innerHeight,
|
|
46586
|
-
(d) => fadeToMarker(g, d),
|
|
46587
|
-
() => fadeReset(g),
|
|
46588
|
-
timelineScale,
|
|
46589
|
-
tooltip,
|
|
46590
|
-
palette
|
|
46606
|
+
const legendInnerG = legendContainer.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
46607
|
+
renderLegendD3(
|
|
46608
|
+
legendInnerG,
|
|
46609
|
+
centralConfig,
|
|
46610
|
+
centralState,
|
|
46611
|
+
palette,
|
|
46612
|
+
isDark,
|
|
46613
|
+
centralCallbacks,
|
|
46614
|
+
width
|
|
46591
46615
|
);
|
|
46616
|
+
}, recolorEvents2 = function() {
|
|
46617
|
+
const colorTG = currentActiveGroup ?? swimlaneTagGroup ?? null;
|
|
46618
|
+
mainG.selectAll(".tl-event").each(function() {
|
|
46619
|
+
const el = d3Selection22.select(this);
|
|
46620
|
+
const lineNum = el.attr("data-line-number");
|
|
46621
|
+
const ev = lineNum ? eventByLine.get(lineNum) : void 0;
|
|
46622
|
+
if (!ev) return;
|
|
46623
|
+
let color;
|
|
46624
|
+
if (colorTG) {
|
|
46625
|
+
const tagColor = resolveTagColor(
|
|
46626
|
+
ev.metadata,
|
|
46627
|
+
parsed.timelineTagGroups,
|
|
46628
|
+
colorTG
|
|
46629
|
+
);
|
|
46630
|
+
color = tagColor ?? (ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor);
|
|
46631
|
+
} else {
|
|
46632
|
+
color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
|
|
46633
|
+
}
|
|
46634
|
+
el.selectAll("rect").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
46635
|
+
el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
46636
|
+
});
|
|
46637
|
+
};
|
|
46638
|
+
var drawSwimlaneIcon3 = drawSwimlaneIcon4, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
|
|
46639
|
+
const legendY = title ? 50 : 10;
|
|
46640
|
+
const legendGroups = parsed.timelineTagGroups.map((g) => {
|
|
46641
|
+
const pillW = measureLegendText(g.name, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
46642
|
+
const iconSpace = viewMode ? 8 : LG_ICON_W + 4;
|
|
46643
|
+
let entryX = LG_CAPSULE_PAD + pillW + iconSpace;
|
|
46644
|
+
for (const entry of g.entries) {
|
|
46645
|
+
const textX = entryX + LG_DOT_R * 2 + LG_ENTRY_DOT_GAP;
|
|
46646
|
+
entryX = textX + measureLegendText(entry.value, LG_ENTRY_FONT_SIZE) + LG_ENTRY_TRAIL;
|
|
46647
|
+
}
|
|
46648
|
+
return {
|
|
46649
|
+
group: g,
|
|
46650
|
+
minifiedWidth: pillW,
|
|
46651
|
+
expandedWidth: entryX + LG_CAPSULE_PAD
|
|
46652
|
+
};
|
|
46653
|
+
});
|
|
46654
|
+
let currentActiveGroup = activeTagGroup ?? null;
|
|
46655
|
+
let currentSwimlaneGroup = swimlaneTagGroup ?? null;
|
|
46656
|
+
const eventByLine = /* @__PURE__ */ new Map();
|
|
46657
|
+
for (const ev of timelineEvents) {
|
|
46658
|
+
eventByLine.set(String(ev.lineNumber), ev);
|
|
46659
|
+
}
|
|
46660
|
+
drawLegend2();
|
|
46661
|
+
}
|
|
46662
|
+
}
|
|
46663
|
+
function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
46664
|
+
const {
|
|
46665
|
+
width,
|
|
46666
|
+
height,
|
|
46667
|
+
tooltip,
|
|
46668
|
+
solid,
|
|
46669
|
+
textColor,
|
|
46670
|
+
bgColor,
|
|
46671
|
+
bg,
|
|
46672
|
+
groupColorMap,
|
|
46673
|
+
eventColor,
|
|
46674
|
+
minDate,
|
|
46675
|
+
maxDate,
|
|
46676
|
+
datePadding,
|
|
46677
|
+
earliestStartDateStr,
|
|
46678
|
+
latestEndDateStr,
|
|
46679
|
+
tagLegendReserve
|
|
46680
|
+
} = setup;
|
|
46681
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
46682
|
+
const {
|
|
46683
|
+
timelineEvents,
|
|
46684
|
+
timelineGroups,
|
|
46685
|
+
timelineEras,
|
|
46686
|
+
timelineMarkers,
|
|
46687
|
+
timelineScale
|
|
46688
|
+
} = parsed;
|
|
46689
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46690
|
+
const BAR_H2 = 22;
|
|
46691
|
+
const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
|
|
46692
|
+
const scaleMargin = timelineScale ? 24 : 0;
|
|
46693
|
+
const ERA_ROW_H = 22;
|
|
46694
|
+
const MARKER_ROW_H = 22;
|
|
46695
|
+
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46696
|
+
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46697
|
+
const topScaleH = timelineScale ? 40 : 0;
|
|
46698
|
+
const margin = {
|
|
46699
|
+
top: 104 + topScaleH + eraReserve + markerReserve + tagLegendReserve,
|
|
46700
|
+
right: 40,
|
|
46701
|
+
bottom: 40 + scaleMargin,
|
|
46702
|
+
left: 60
|
|
46703
|
+
};
|
|
46704
|
+
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46705
|
+
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46706
|
+
const innerWidth = width - margin.left - margin.right;
|
|
46707
|
+
const innerHeight = height - margin.top - margin.bottom;
|
|
46708
|
+
const rowH = Math.min(28, innerHeight / sorted.length);
|
|
46709
|
+
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
46710
|
+
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
46711
|
+
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46712
|
+
renderChartTitle(
|
|
46713
|
+
svg,
|
|
46714
|
+
title,
|
|
46715
|
+
parsed.titleLineNumber,
|
|
46716
|
+
width,
|
|
46717
|
+
textColor,
|
|
46718
|
+
onClickItem
|
|
46719
|
+
);
|
|
46720
|
+
renderEras(
|
|
46721
|
+
g,
|
|
46722
|
+
timelineEras,
|
|
46723
|
+
xScale,
|
|
46724
|
+
false,
|
|
46725
|
+
innerWidth,
|
|
46726
|
+
innerHeight,
|
|
46727
|
+
(s, e) => fadeToEra(g, s, e),
|
|
46728
|
+
() => fadeReset(g),
|
|
46729
|
+
timelineScale,
|
|
46730
|
+
tooltip,
|
|
46731
|
+
palette,
|
|
46732
|
+
eraReserve ? eraLabelY : void 0
|
|
46733
|
+
);
|
|
46734
|
+
renderMarkers(
|
|
46735
|
+
g,
|
|
46736
|
+
timelineMarkers,
|
|
46737
|
+
xScale,
|
|
46738
|
+
false,
|
|
46739
|
+
innerWidth,
|
|
46740
|
+
innerHeight,
|
|
46741
|
+
(d) => fadeToMarker(g, d),
|
|
46742
|
+
() => fadeReset(g),
|
|
46743
|
+
timelineScale,
|
|
46744
|
+
tooltip,
|
|
46745
|
+
palette,
|
|
46746
|
+
markerReserve ? markerLabelY : void 0
|
|
46747
|
+
);
|
|
46748
|
+
if (timelineScale) {
|
|
46749
|
+
renderTimeScale(
|
|
46750
|
+
g,
|
|
46751
|
+
xScale,
|
|
46752
|
+
false,
|
|
46753
|
+
innerWidth,
|
|
46754
|
+
innerHeight,
|
|
46755
|
+
textColor,
|
|
46756
|
+
minDate,
|
|
46757
|
+
maxDate,
|
|
46758
|
+
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46759
|
+
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46760
|
+
);
|
|
46761
|
+
}
|
|
46762
|
+
if (timelineGroups.length > 0) {
|
|
46763
|
+
const legendY = timelineScale ? -75 : -55;
|
|
46764
|
+
renderTimelineGroupLegend(
|
|
46765
|
+
g,
|
|
46766
|
+
timelineGroups,
|
|
46767
|
+
groupColorMap,
|
|
46768
|
+
textColor,
|
|
46769
|
+
palette,
|
|
46770
|
+
isDark,
|
|
46771
|
+
legendY,
|
|
46772
|
+
(name) => fadeToGroup(g, name),
|
|
46773
|
+
() => fadeReset(g)
|
|
46774
|
+
);
|
|
46775
|
+
}
|
|
46776
|
+
sorted.forEach((ev, i) => {
|
|
46777
|
+
const y = i * rowH + rowH / 2;
|
|
46778
|
+
const x = xScale(parseTimelineDate(ev.date));
|
|
46779
|
+
const color = eventColor(ev);
|
|
46780
|
+
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(
|
|
46781
|
+
"data-end-date",
|
|
46782
|
+
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
46783
|
+
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
46784
|
+
if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);
|
|
46592
46785
|
if (timelineScale) {
|
|
46593
|
-
|
|
46786
|
+
showEventDatesOnScale(
|
|
46594
46787
|
g,
|
|
46595
|
-
|
|
46596
|
-
|
|
46597
|
-
|
|
46788
|
+
xScale,
|
|
46789
|
+
ev.date,
|
|
46790
|
+
ev.endDate,
|
|
46598
46791
|
innerHeight,
|
|
46599
|
-
|
|
46600
|
-
minDate,
|
|
46601
|
-
maxDate,
|
|
46602
|
-
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46603
|
-
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46792
|
+
color
|
|
46604
46793
|
);
|
|
46794
|
+
} else {
|
|
46795
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46605
46796
|
}
|
|
46606
|
-
|
|
46607
|
-
|
|
46608
|
-
|
|
46609
|
-
|
|
46610
|
-
|
|
46611
|
-
|
|
46612
|
-
palette,
|
|
46613
|
-
isDark,
|
|
46614
|
-
-55,
|
|
46615
|
-
(name) => fadeToGroup(g, name),
|
|
46616
|
-
() => fadeReset(g)
|
|
46617
|
-
);
|
|
46797
|
+
}).on("mouseleave", function() {
|
|
46798
|
+
fadeReset(g);
|
|
46799
|
+
if (timelineScale) {
|
|
46800
|
+
hideEventDatesOnScale(g);
|
|
46801
|
+
} else {
|
|
46802
|
+
hideTooltip(tooltip);
|
|
46618
46803
|
}
|
|
46619
|
-
|
|
46620
|
-
|
|
46621
|
-
|
|
46622
|
-
|
|
46623
|
-
|
|
46624
|
-
|
|
46625
|
-
|
|
46626
|
-
|
|
46627
|
-
|
|
46804
|
+
}).on("mousemove", function(event) {
|
|
46805
|
+
if (!timelineScale) {
|
|
46806
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46807
|
+
}
|
|
46808
|
+
}).on("click", () => {
|
|
46809
|
+
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
46810
|
+
});
|
|
46811
|
+
setTagAttrs(evG, ev);
|
|
46812
|
+
if (ev.endDate) {
|
|
46813
|
+
const x2 = xScale(parseTimelineDate(ev.endDate));
|
|
46814
|
+
const rectW = Math.max(x2 - x, 4);
|
|
46815
|
+
const estLabelWidth = ev.label.length * 7 + 16;
|
|
46816
|
+
const labelFitsInside = rectW >= estLabelWidth;
|
|
46817
|
+
let fill2 = shapeFill(palette, color, isDark, { solid });
|
|
46818
|
+
let stroke2 = color;
|
|
46819
|
+
if (ev.uncertain) {
|
|
46820
|
+
const gradientId = `uncertain-ts-${ev.lineNumber}`;
|
|
46821
|
+
const strokeGradientId = `uncertain-ts-s-${ev.lineNumber}`;
|
|
46822
|
+
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46823
|
+
const defsEl = d3Selection22.select(defs);
|
|
46824
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
46825
|
+
{ offset: "0%", opacity: 1 },
|
|
46826
|
+
{ offset: "80%", opacity: 1 },
|
|
46827
|
+
{ offset: "100%", opacity: 0 }
|
|
46828
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
46829
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
46830
|
+
{ offset: "0%", opacity: 1 },
|
|
46831
|
+
{ offset: "80%", opacity: 1 },
|
|
46832
|
+
{ offset: "100%", opacity: 0 }
|
|
46833
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", color).attr("stop-opacity", (d) => d.opacity);
|
|
46834
|
+
fill2 = `url(#${gradientId})`;
|
|
46835
|
+
stroke2 = `url(#${strokeGradientId})`;
|
|
46836
|
+
}
|
|
46837
|
+
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);
|
|
46838
|
+
if (labelFitsInside) {
|
|
46839
|
+
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);
|
|
46840
|
+
} else {
|
|
46841
|
+
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
46842
|
+
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
46843
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46844
|
+
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);
|
|
46845
|
+
}
|
|
46846
|
+
} else {
|
|
46847
|
+
const estLabelWidth = ev.label.length * 7;
|
|
46848
|
+
const wouldFlipLeft = x > innerWidth * 0.6;
|
|
46849
|
+
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
46850
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46851
|
+
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);
|
|
46852
|
+
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);
|
|
46853
|
+
}
|
|
46854
|
+
});
|
|
46855
|
+
}
|
|
46856
|
+
function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
46857
|
+
const {
|
|
46858
|
+
width,
|
|
46859
|
+
height,
|
|
46860
|
+
tooltip,
|
|
46861
|
+
solid,
|
|
46862
|
+
textColor,
|
|
46863
|
+
bgColor,
|
|
46864
|
+
bg,
|
|
46865
|
+
groupColorMap,
|
|
46866
|
+
tagLanes,
|
|
46867
|
+
eventColor,
|
|
46868
|
+
minDate,
|
|
46869
|
+
maxDate,
|
|
46870
|
+
datePadding,
|
|
46871
|
+
earliestStartDateStr,
|
|
46872
|
+
latestEndDateStr,
|
|
46873
|
+
tagLegendReserve
|
|
46874
|
+
} = setup;
|
|
46875
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
46876
|
+
const {
|
|
46877
|
+
timelineEvents,
|
|
46878
|
+
timelineGroups,
|
|
46879
|
+
timelineEras,
|
|
46880
|
+
timelineMarkers,
|
|
46881
|
+
timelineScale,
|
|
46882
|
+
timelineSwimlanes
|
|
46883
|
+
} = parsed;
|
|
46884
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46885
|
+
const BAR_H2 = 22;
|
|
46886
|
+
const GROUP_GAP3 = 12;
|
|
46887
|
+
let lanes;
|
|
46888
|
+
if (tagLanes) {
|
|
46889
|
+
lanes = tagLanes;
|
|
46890
|
+
} else {
|
|
46891
|
+
const groupNames = timelineGroups.map((gr) => gr.name);
|
|
46892
|
+
const ungroupedEvents = timelineEvents.filter(
|
|
46893
|
+
(ev) => ev.group === null || !groupNames.includes(ev.group)
|
|
46894
|
+
);
|
|
46895
|
+
const laneNames = ungroupedEvents.length > 0 ? [...groupNames, "(Other)"] : groupNames;
|
|
46896
|
+
lanes = laneNames.map((name) => ({
|
|
46897
|
+
name,
|
|
46898
|
+
events: timelineEvents.filter(
|
|
46899
|
+
(ev) => name === "(Other)" ? ev.group === null || !groupNames.includes(ev.group) : ev.group === name
|
|
46900
|
+
)
|
|
46901
|
+
}));
|
|
46902
|
+
}
|
|
46903
|
+
const totalEventRows = lanes.reduce((s, l) => s + l.events.length, 0);
|
|
46904
|
+
const scaleMargin = timelineScale ? 24 : 0;
|
|
46905
|
+
const ERA_ROW_H = 22;
|
|
46906
|
+
const MARKER_ROW_H = 22;
|
|
46907
|
+
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46908
|
+
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46909
|
+
const topScaleH = timelineScale ? 40 : 0;
|
|
46910
|
+
const maxGroupNameLen = Math.max(...lanes.map((l) => l.name.length));
|
|
46911
|
+
const dynamicLeftMargin = Math.max(120, maxGroupNameLen * 7 + 30);
|
|
46912
|
+
const baseTopMargin = title ? 50 : 20;
|
|
46913
|
+
const margin = {
|
|
46914
|
+
top: baseTopMargin + topScaleH + eraReserve + markerReserve + tagLegendReserve,
|
|
46915
|
+
right: 40,
|
|
46916
|
+
bottom: 40 + scaleMargin,
|
|
46917
|
+
left: dynamicLeftMargin
|
|
46918
|
+
};
|
|
46919
|
+
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46920
|
+
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46921
|
+
const innerWidth = width - margin.left - margin.right;
|
|
46922
|
+
const innerHeight = height - margin.top - margin.bottom;
|
|
46923
|
+
const totalGaps = (lanes.length - 1) * GROUP_GAP3;
|
|
46924
|
+
const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);
|
|
46925
|
+
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
46926
|
+
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
46927
|
+
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46928
|
+
renderChartTitle(
|
|
46929
|
+
svg,
|
|
46930
|
+
title,
|
|
46931
|
+
parsed.titleLineNumber,
|
|
46932
|
+
width,
|
|
46933
|
+
textColor,
|
|
46934
|
+
onClickItem
|
|
46935
|
+
);
|
|
46936
|
+
renderEras(
|
|
46937
|
+
g,
|
|
46938
|
+
timelineEras,
|
|
46939
|
+
xScale,
|
|
46940
|
+
false,
|
|
46941
|
+
innerWidth,
|
|
46942
|
+
innerHeight,
|
|
46943
|
+
(s, e) => fadeToEra(g, s, e),
|
|
46944
|
+
() => fadeReset(g),
|
|
46945
|
+
timelineScale,
|
|
46946
|
+
tooltip,
|
|
46947
|
+
palette,
|
|
46948
|
+
eraReserve ? eraLabelY : void 0
|
|
46949
|
+
);
|
|
46950
|
+
renderMarkers(
|
|
46951
|
+
g,
|
|
46952
|
+
timelineMarkers,
|
|
46953
|
+
xScale,
|
|
46954
|
+
false,
|
|
46955
|
+
innerWidth,
|
|
46956
|
+
innerHeight,
|
|
46957
|
+
(d) => fadeToMarker(g, d),
|
|
46958
|
+
() => fadeReset(g),
|
|
46959
|
+
timelineScale,
|
|
46960
|
+
tooltip,
|
|
46961
|
+
palette,
|
|
46962
|
+
markerReserve ? markerLabelY : void 0
|
|
46963
|
+
);
|
|
46964
|
+
if (timelineScale) {
|
|
46965
|
+
renderTimeScale(
|
|
46966
|
+
g,
|
|
46967
|
+
xScale,
|
|
46968
|
+
false,
|
|
46969
|
+
innerWidth,
|
|
46970
|
+
innerHeight,
|
|
46971
|
+
textColor,
|
|
46972
|
+
minDate,
|
|
46973
|
+
maxDate,
|
|
46974
|
+
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46975
|
+
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46976
|
+
);
|
|
46977
|
+
}
|
|
46978
|
+
let curY = 0;
|
|
46979
|
+
if (timelineSwimlanes || tagLanes) {
|
|
46980
|
+
let swimY = 0;
|
|
46981
|
+
lanes.forEach((lane, idx) => {
|
|
46982
|
+
const laneSpan = lane.events.length * rowH;
|
|
46983
|
+
const fillColor = idx % 2 === 0 ? textColor : "transparent";
|
|
46984
|
+
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);
|
|
46985
|
+
swimY += laneSpan + GROUP_GAP3;
|
|
46986
|
+
});
|
|
46987
|
+
}
|
|
46988
|
+
for (const lane of lanes) {
|
|
46989
|
+
const laneColor = groupColorMap.get(lane.name) ?? textColor;
|
|
46990
|
+
const laneSpan = lane.events.length * rowH;
|
|
46991
|
+
const group = timelineGroups.find((grp) => grp.name === lane.name);
|
|
46992
|
+
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", () => {
|
|
46993
|
+
if (onClickItem && group?.lineNumber) onClickItem(group.lineNumber);
|
|
46994
|
+
});
|
|
46995
|
+
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);
|
|
46996
|
+
lane.events.forEach((ev, i) => {
|
|
46997
|
+
const y = curY + i * rowH + rowH / 2;
|
|
46998
|
+
const x = xScale(parseTimelineDate(ev.date));
|
|
46999
|
+
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(
|
|
47000
|
+
"data-end-date",
|
|
47001
|
+
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
47002
|
+
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
47003
|
+
fadeToGroup(g, lane.name);
|
|
47004
|
+
if (timelineScale) {
|
|
47005
|
+
showEventDatesOnScale(
|
|
47006
|
+
g,
|
|
47007
|
+
xScale,
|
|
47008
|
+
ev.date,
|
|
47009
|
+
ev.endDate,
|
|
47010
|
+
innerHeight,
|
|
47011
|
+
laneColor
|
|
47012
|
+
);
|
|
47013
|
+
} else {
|
|
46628
47014
|
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46629
|
-
}
|
|
46630
|
-
|
|
47015
|
+
}
|
|
47016
|
+
}).on("mouseleave", function() {
|
|
47017
|
+
fadeReset(g);
|
|
47018
|
+
if (timelineScale) {
|
|
47019
|
+
hideEventDatesOnScale(g);
|
|
47020
|
+
} else {
|
|
46631
47021
|
hideTooltip(tooltip);
|
|
46632
|
-
}
|
|
47022
|
+
}
|
|
47023
|
+
}).on("mousemove", function(event) {
|
|
47024
|
+
if (!timelineScale) {
|
|
46633
47025
|
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46634
|
-
}
|
|
46635
|
-
|
|
46636
|
-
|
|
46637
|
-
|
|
46638
|
-
|
|
46639
|
-
|
|
46640
|
-
|
|
46641
|
-
|
|
46642
|
-
|
|
46643
|
-
|
|
46644
|
-
|
|
46645
|
-
|
|
46646
|
-
|
|
46647
|
-
|
|
46648
|
-
|
|
46649
|
-
|
|
46650
|
-
|
|
46651
|
-
|
|
46652
|
-
|
|
46653
|
-
|
|
46654
|
-
|
|
46655
|
-
|
|
46656
|
-
|
|
46657
|
-
|
|
46658
|
-
|
|
46659
|
-
|
|
46660
|
-
|
|
46661
|
-
|
|
46662
|
-
|
|
47026
|
+
}
|
|
47027
|
+
}).on("click", () => {
|
|
47028
|
+
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
47029
|
+
});
|
|
47030
|
+
setTagAttrs(evG, ev);
|
|
47031
|
+
const evColor = eventColor(ev);
|
|
47032
|
+
if (ev.endDate) {
|
|
47033
|
+
const x2 = xScale(parseTimelineDate(ev.endDate));
|
|
47034
|
+
const rectW = Math.max(x2 - x, 4);
|
|
47035
|
+
const estLabelWidth = ev.label.length * 7 + 16;
|
|
47036
|
+
const labelFitsInside = rectW >= estLabelWidth;
|
|
47037
|
+
let fill2 = shapeFill(palette, evColor, isDark, { solid });
|
|
47038
|
+
let stroke2 = evColor;
|
|
47039
|
+
if (ev.uncertain) {
|
|
47040
|
+
const gradientId = `uncertain-${ev.lineNumber}`;
|
|
47041
|
+
const strokeGradientId = `uncertain-s-${ev.lineNumber}`;
|
|
47042
|
+
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
47043
|
+
const defsEl = d3Selection22.select(defs);
|
|
47044
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
47045
|
+
{ offset: "0%", opacity: 1 },
|
|
47046
|
+
{ offset: "80%", opacity: 1 },
|
|
47047
|
+
{ offset: "100%", opacity: 0 }
|
|
47048
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(evColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47049
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
47050
|
+
{ offset: "0%", opacity: 1 },
|
|
47051
|
+
{ offset: "80%", opacity: 1 },
|
|
47052
|
+
{ offset: "100%", opacity: 0 }
|
|
47053
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", evColor).attr("stop-opacity", (d) => d.opacity);
|
|
47054
|
+
fill2 = `url(#${gradientId})`;
|
|
47055
|
+
stroke2 = `url(#${strokeGradientId})`;
|
|
47056
|
+
}
|
|
47057
|
+
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);
|
|
47058
|
+
if (labelFitsInside) {
|
|
47059
|
+
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);
|
|
46663
47060
|
} else {
|
|
46664
|
-
|
|
46665
|
-
|
|
47061
|
+
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
47062
|
+
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
47063
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47064
|
+
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);
|
|
46666
47065
|
}
|
|
46667
|
-
|
|
46668
|
-
|
|
46669
|
-
|
|
46670
|
-
|
|
46671
|
-
|
|
46672
|
-
|
|
46673
|
-
).attr("dy", "0.35em").attr("text-anchor", "end").attr("fill",
|
|
47066
|
+
} else {
|
|
47067
|
+
const estLabelWidth = ev.label.length * 7;
|
|
47068
|
+
const wouldFlipLeft = x > innerWidth * 0.6;
|
|
47069
|
+
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
47070
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47071
|
+
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);
|
|
47072
|
+
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);
|
|
46674
47073
|
}
|
|
46675
|
-
}
|
|
46676
|
-
|
|
47074
|
+
});
|
|
47075
|
+
curY += laneSpan + GROUP_GAP3;
|
|
46677
47076
|
}
|
|
46678
|
-
|
|
46679
|
-
|
|
46680
|
-
const
|
|
46681
|
-
|
|
46682
|
-
|
|
47077
|
+
}
|
|
47078
|
+
function renderTimelineVertical(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
47079
|
+
const {
|
|
47080
|
+
width,
|
|
47081
|
+
height,
|
|
47082
|
+
tooltip,
|
|
47083
|
+
solid,
|
|
47084
|
+
textColor,
|
|
47085
|
+
mutedColor,
|
|
47086
|
+
bgColor,
|
|
47087
|
+
bg,
|
|
47088
|
+
groupColorMap,
|
|
47089
|
+
tagLanes,
|
|
47090
|
+
eventColor,
|
|
47091
|
+
minDate,
|
|
47092
|
+
maxDate,
|
|
47093
|
+
datePadding,
|
|
47094
|
+
earliestStartDateStr,
|
|
47095
|
+
latestEndDateStr,
|
|
47096
|
+
tagLegendReserve
|
|
47097
|
+
} = setup;
|
|
47098
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
47099
|
+
const {
|
|
47100
|
+
timelineEvents,
|
|
47101
|
+
timelineGroups,
|
|
47102
|
+
timelineEras,
|
|
47103
|
+
timelineMarkers,
|
|
47104
|
+
timelineSort,
|
|
47105
|
+
timelineScale,
|
|
47106
|
+
timelineSwimlanes
|
|
47107
|
+
} = parsed;
|
|
47108
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
47109
|
+
const useGroupedVertical = tagLanes != null || timelineSort === "group" && timelineGroups.length > 0;
|
|
47110
|
+
if (useGroupedVertical) {
|
|
47111
|
+
let laneNames;
|
|
47112
|
+
let laneEventsByName;
|
|
46683
47113
|
if (tagLanes) {
|
|
46684
|
-
|
|
47114
|
+
laneNames = tagLanes.map((l) => l.name);
|
|
47115
|
+
laneEventsByName = new Map(tagLanes.map((l) => [l.name, l.events]));
|
|
46685
47116
|
} else {
|
|
46686
47117
|
const groupNames = timelineGroups.map((gr) => gr.name);
|
|
46687
47118
|
const ungroupedEvents = timelineEvents.filter(
|
|
46688
47119
|
(ev) => ev.group === null || !groupNames.includes(ev.group)
|
|
46689
47120
|
);
|
|
46690
|
-
|
|
46691
|
-
|
|
46692
|
-
name
|
|
46693
|
-
|
|
46694
|
-
|
|
46695
|
-
|
|
46696
|
-
|
|
47121
|
+
laneNames = ungroupedEvents.length > 0 ? [...groupNames, "(Other)"] : groupNames;
|
|
47122
|
+
laneEventsByName = new Map(
|
|
47123
|
+
laneNames.map((name) => [
|
|
47124
|
+
name,
|
|
47125
|
+
timelineEvents.filter(
|
|
47126
|
+
(ev) => name === "(Other)" ? ev.group === null || !groupNames.includes(ev.group) : ev.group === name
|
|
47127
|
+
)
|
|
47128
|
+
])
|
|
47129
|
+
);
|
|
46697
47130
|
}
|
|
46698
|
-
const
|
|
46699
|
-
const scaleMargin = timelineScale ?
|
|
46700
|
-
const
|
|
46701
|
-
const MARKER_ROW_H = 22;
|
|
46702
|
-
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46703
|
-
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46704
|
-
const topScaleH = timelineScale ? 40 : 0;
|
|
46705
|
-
const maxGroupNameLen = Math.max(...lanes.map((l) => l.name.length));
|
|
46706
|
-
const dynamicLeftMargin = Math.max(120, maxGroupNameLen * 7 + 30);
|
|
46707
|
-
const baseTopMargin = title ? 50 : 20;
|
|
47131
|
+
const laneCount = laneNames.length;
|
|
47132
|
+
const scaleMargin = timelineScale ? 40 : 0;
|
|
47133
|
+
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46708
47134
|
const margin = {
|
|
46709
|
-
top:
|
|
46710
|
-
right: 40,
|
|
46711
|
-
bottom: 40
|
|
46712
|
-
left:
|
|
47135
|
+
top: 104 + markerMargin + tagLegendReserve,
|
|
47136
|
+
right: 40 + scaleMargin,
|
|
47137
|
+
bottom: 40,
|
|
47138
|
+
left: 60 + scaleMargin
|
|
46713
47139
|
};
|
|
46714
|
-
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46715
|
-
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46716
47140
|
const innerWidth = width - margin.left - margin.right;
|
|
46717
47141
|
const innerHeight = height - margin.top - margin.bottom;
|
|
46718
|
-
const
|
|
46719
|
-
const
|
|
46720
|
-
const
|
|
46721
|
-
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
47142
|
+
const laneWidth = innerWidth / laneCount;
|
|
47143
|
+
const yScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
|
|
47144
|
+
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);
|
|
46722
47145
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46723
47146
|
renderChartTitle(
|
|
46724
47147
|
svg,
|
|
@@ -46731,36 +47154,34 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46731
47154
|
renderEras(
|
|
46732
47155
|
g,
|
|
46733
47156
|
timelineEras,
|
|
46734
|
-
|
|
46735
|
-
|
|
47157
|
+
yScale,
|
|
47158
|
+
true,
|
|
46736
47159
|
innerWidth,
|
|
46737
47160
|
innerHeight,
|
|
46738
47161
|
(s, e) => fadeToEra(g, s, e),
|
|
46739
47162
|
() => fadeReset(g),
|
|
46740
47163
|
timelineScale,
|
|
46741
47164
|
tooltip,
|
|
46742
|
-
palette
|
|
46743
|
-
eraReserve ? eraLabelY : void 0
|
|
47165
|
+
palette
|
|
46744
47166
|
);
|
|
46745
47167
|
renderMarkers(
|
|
46746
47168
|
g,
|
|
46747
47169
|
timelineMarkers,
|
|
46748
|
-
|
|
46749
|
-
|
|
47170
|
+
yScale,
|
|
47171
|
+
true,
|
|
46750
47172
|
innerWidth,
|
|
46751
47173
|
innerHeight,
|
|
46752
47174
|
(d) => fadeToMarker(g, d),
|
|
46753
47175
|
() => fadeReset(g),
|
|
46754
47176
|
timelineScale,
|
|
46755
47177
|
tooltip,
|
|
46756
|
-
palette
|
|
46757
|
-
markerReserve ? markerLabelY : void 0
|
|
47178
|
+
palette
|
|
46758
47179
|
);
|
|
46759
47180
|
if (timelineScale) {
|
|
46760
47181
|
renderTimeScale(
|
|
46761
47182
|
g,
|
|
46762
|
-
|
|
46763
|
-
|
|
47183
|
+
yScale,
|
|
47184
|
+
true,
|
|
46764
47185
|
innerWidth,
|
|
46765
47186
|
innerHeight,
|
|
46766
47187
|
textColor,
|
|
@@ -46770,78 +47191,55 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46770
47191
|
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46771
47192
|
);
|
|
46772
47193
|
}
|
|
46773
|
-
let curY = 0;
|
|
46774
47194
|
if (timelineSwimlanes || tagLanes) {
|
|
46775
|
-
|
|
46776
|
-
|
|
46777
|
-
const
|
|
46778
|
-
|
|
46779
|
-
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);
|
|
46780
|
-
swimY += laneSpan + GROUP_GAP3;
|
|
47195
|
+
laneNames.forEach((laneName, laneIdx) => {
|
|
47196
|
+
const laneX = laneIdx * laneWidth;
|
|
47197
|
+
const fillColor = laneIdx % 2 === 0 ? textColor : "transparent";
|
|
47198
|
+
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);
|
|
46781
47199
|
});
|
|
46782
47200
|
}
|
|
46783
|
-
|
|
46784
|
-
const
|
|
46785
|
-
const
|
|
46786
|
-
const
|
|
46787
|
-
const headerG = g.append("g").attr("class", "tl-lane-header").attr("data-group",
|
|
46788
|
-
|
|
46789
|
-
|
|
46790
|
-
|
|
46791
|
-
|
|
46792
|
-
const y =
|
|
46793
|
-
const
|
|
46794
|
-
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(
|
|
47201
|
+
laneNames.forEach((laneName, laneIdx) => {
|
|
47202
|
+
const laneX = laneIdx * laneWidth;
|
|
47203
|
+
const laneColor = groupColorMap.get(laneName) ?? textColor;
|
|
47204
|
+
const laneCenter = laneX + laneWidth / 2;
|
|
47205
|
+
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));
|
|
47206
|
+
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);
|
|
47207
|
+
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");
|
|
47208
|
+
const laneEvents = laneEventsByName.get(laneName) ?? [];
|
|
47209
|
+
for (const ev of laneEvents) {
|
|
47210
|
+
const y = yScale(parseTimelineDate(ev.date));
|
|
47211
|
+
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(
|
|
46795
47212
|
"data-end-date",
|
|
46796
47213
|
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
46797
47214
|
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
46798
|
-
fadeToGroup(g,
|
|
46799
|
-
|
|
46800
|
-
showEventDatesOnScale(
|
|
46801
|
-
g,
|
|
46802
|
-
xScale,
|
|
46803
|
-
ev.date,
|
|
46804
|
-
ev.endDate,
|
|
46805
|
-
innerHeight,
|
|
46806
|
-
laneColor
|
|
46807
|
-
);
|
|
46808
|
-
} else {
|
|
46809
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46810
|
-
}
|
|
47215
|
+
fadeToGroup(g, laneName);
|
|
47216
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46811
47217
|
}).on("mouseleave", function() {
|
|
46812
47218
|
fadeReset(g);
|
|
46813
|
-
|
|
46814
|
-
hideEventDatesOnScale(g);
|
|
46815
|
-
} else {
|
|
46816
|
-
hideTooltip(tooltip);
|
|
46817
|
-
}
|
|
47219
|
+
hideTooltip(tooltip);
|
|
46818
47220
|
}).on("mousemove", function(event) {
|
|
46819
|
-
|
|
46820
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46821
|
-
}
|
|
47221
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46822
47222
|
}).on("click", () => {
|
|
46823
47223
|
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
46824
47224
|
});
|
|
46825
47225
|
setTagAttrs(evG, ev);
|
|
46826
47226
|
const evColor = eventColor(ev);
|
|
46827
47227
|
if (ev.endDate) {
|
|
46828
|
-
const
|
|
46829
|
-
const
|
|
46830
|
-
const estLabelWidth = ev.label.length * 7 + 16;
|
|
46831
|
-
const labelFitsInside = rectW >= estLabelWidth;
|
|
47228
|
+
const y2 = yScale(parseTimelineDate(ev.endDate));
|
|
47229
|
+
const rectH = Math.max(y2 - y, 4);
|
|
46832
47230
|
let fill2 = shapeFill(palette, evColor, isDark, { solid });
|
|
46833
47231
|
let stroke2 = evColor;
|
|
46834
47232
|
if (ev.uncertain) {
|
|
46835
|
-
const gradientId = `uncertain-${ev.lineNumber}`;
|
|
46836
|
-
const strokeGradientId = `uncertain-s-${ev.lineNumber}`;
|
|
47233
|
+
const gradientId = `uncertain-vg-${ev.lineNumber}`;
|
|
47234
|
+
const strokeGradientId = `uncertain-vg-s-${ev.lineNumber}`;
|
|
46837
47235
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46838
47236
|
const defsEl = d3Selection22.select(defs);
|
|
46839
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47237
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46840
47238
|
{ offset: "0%", opacity: 1 },
|
|
46841
47239
|
{ offset: "80%", opacity: 1 },
|
|
46842
47240
|
{ offset: "100%", opacity: 0 }
|
|
46843
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(
|
|
46844
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47241
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47242
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46845
47243
|
{ offset: "0%", opacity: 1 },
|
|
46846
47244
|
{ offset: "80%", opacity: 1 },
|
|
46847
47245
|
{ offset: "100%", opacity: 0 }
|
|
@@ -46849,47 +47247,29 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46849
47247
|
fill2 = `url(#${gradientId})`;
|
|
46850
47248
|
stroke2 = `url(#${strokeGradientId})`;
|
|
46851
47249
|
}
|
|
46852
|
-
evG.append("rect").attr("x",
|
|
46853
|
-
|
|
46854
|
-
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);
|
|
46855
|
-
} else {
|
|
46856
|
-
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
46857
|
-
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
46858
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46859
|
-
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);
|
|
46860
|
-
}
|
|
47250
|
+
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);
|
|
47251
|
+
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);
|
|
46861
47252
|
} else {
|
|
46862
|
-
|
|
46863
|
-
|
|
46864
|
-
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
46865
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46866
|
-
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);
|
|
46867
|
-
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);
|
|
47253
|
+
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);
|
|
47254
|
+
evG.append("text").attr("x", laneCenter + 10).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
|
|
46868
47255
|
}
|
|
46869
|
-
}
|
|
46870
|
-
|
|
46871
|
-
}
|
|
47256
|
+
}
|
|
47257
|
+
});
|
|
46872
47258
|
} else {
|
|
46873
|
-
const
|
|
46874
|
-
const
|
|
46875
|
-
const ERA_ROW_H = 22;
|
|
46876
|
-
const MARKER_ROW_H = 22;
|
|
46877
|
-
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46878
|
-
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46879
|
-
const topScaleH = timelineScale ? 40 : 0;
|
|
47259
|
+
const scaleMargin = timelineScale ? 40 : 0;
|
|
47260
|
+
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46880
47261
|
const margin = {
|
|
46881
|
-
top: 104 +
|
|
46882
|
-
right:
|
|
46883
|
-
bottom: 40
|
|
46884
|
-
left: 60
|
|
47262
|
+
top: 104 + markerMargin + tagLegendReserve,
|
|
47263
|
+
right: 200,
|
|
47264
|
+
bottom: 40,
|
|
47265
|
+
left: 60 + scaleMargin
|
|
46885
47266
|
};
|
|
46886
|
-
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46887
|
-
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46888
47267
|
const innerWidth = width - margin.left - margin.right;
|
|
46889
47268
|
const innerHeight = height - margin.top - margin.bottom;
|
|
46890
|
-
const
|
|
46891
|
-
const
|
|
46892
|
-
const
|
|
47269
|
+
const axisX = 20;
|
|
47270
|
+
const yScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
|
|
47271
|
+
const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
|
|
47272
|
+
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);
|
|
46893
47273
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46894
47274
|
renderChartTitle(
|
|
46895
47275
|
svg,
|
|
@@ -46902,36 +47282,34 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46902
47282
|
renderEras(
|
|
46903
47283
|
g,
|
|
46904
47284
|
timelineEras,
|
|
46905
|
-
|
|
46906
|
-
|
|
47285
|
+
yScale,
|
|
47286
|
+
true,
|
|
46907
47287
|
innerWidth,
|
|
46908
47288
|
innerHeight,
|
|
46909
47289
|
(s, e) => fadeToEra(g, s, e),
|
|
46910
47290
|
() => fadeReset(g),
|
|
46911
47291
|
timelineScale,
|
|
46912
47292
|
tooltip,
|
|
46913
|
-
palette
|
|
46914
|
-
eraReserve ? eraLabelY : void 0
|
|
47293
|
+
palette
|
|
46915
47294
|
);
|
|
46916
47295
|
renderMarkers(
|
|
46917
47296
|
g,
|
|
46918
47297
|
timelineMarkers,
|
|
46919
|
-
|
|
46920
|
-
|
|
47298
|
+
yScale,
|
|
47299
|
+
true,
|
|
46921
47300
|
innerWidth,
|
|
46922
47301
|
innerHeight,
|
|
46923
47302
|
(d) => fadeToMarker(g, d),
|
|
46924
47303
|
() => fadeReset(g),
|
|
46925
47304
|
timelineScale,
|
|
46926
47305
|
tooltip,
|
|
46927
|
-
palette
|
|
46928
|
-
markerReserve ? markerLabelY : void 0
|
|
47306
|
+
palette
|
|
46929
47307
|
);
|
|
46930
47308
|
if (timelineScale) {
|
|
46931
47309
|
renderTimeScale(
|
|
46932
47310
|
g,
|
|
46933
|
-
|
|
46934
|
-
|
|
47311
|
+
yScale,
|
|
47312
|
+
true,
|
|
46935
47313
|
innerWidth,
|
|
46936
47314
|
innerHeight,
|
|
46937
47315
|
textColor,
|
|
@@ -46942,7 +47320,6 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46942
47320
|
);
|
|
46943
47321
|
}
|
|
46944
47322
|
if (timelineGroups.length > 0) {
|
|
46945
|
-
const legendY = timelineScale ? -75 : -55;
|
|
46946
47323
|
renderTimelineGroupLegend(
|
|
46947
47324
|
g,
|
|
46948
47325
|
timelineGroups,
|
|
@@ -46950,65 +47327,46 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46950
47327
|
textColor,
|
|
46951
47328
|
palette,
|
|
46952
47329
|
isDark,
|
|
46953
|
-
|
|
47330
|
+
-55,
|
|
46954
47331
|
(name) => fadeToGroup(g, name),
|
|
46955
47332
|
() => fadeReset(g)
|
|
46956
47333
|
);
|
|
46957
47334
|
}
|
|
46958
|
-
|
|
46959
|
-
|
|
46960
|
-
const
|
|
47335
|
+
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");
|
|
47336
|
+
for (const ev of sorted) {
|
|
47337
|
+
const y = yScale(parseTimelineDate(ev.date));
|
|
46961
47338
|
const color = eventColor(ev);
|
|
46962
47339
|
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(
|
|
46963
47340
|
"data-end-date",
|
|
46964
47341
|
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
46965
47342
|
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
46966
47343
|
if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);
|
|
46967
|
-
|
|
46968
|
-
showEventDatesOnScale(
|
|
46969
|
-
g,
|
|
46970
|
-
xScale,
|
|
46971
|
-
ev.date,
|
|
46972
|
-
ev.endDate,
|
|
46973
|
-
innerHeight,
|
|
46974
|
-
color
|
|
46975
|
-
);
|
|
46976
|
-
} else {
|
|
46977
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46978
|
-
}
|
|
47344
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46979
47345
|
}).on("mouseleave", function() {
|
|
46980
47346
|
fadeReset(g);
|
|
46981
|
-
|
|
46982
|
-
hideEventDatesOnScale(g);
|
|
46983
|
-
} else {
|
|
46984
|
-
hideTooltip(tooltip);
|
|
46985
|
-
}
|
|
47347
|
+
hideTooltip(tooltip);
|
|
46986
47348
|
}).on("mousemove", function(event) {
|
|
46987
|
-
|
|
46988
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46989
|
-
}
|
|
47349
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46990
47350
|
}).on("click", () => {
|
|
46991
47351
|
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
46992
47352
|
});
|
|
46993
47353
|
setTagAttrs(evG, ev);
|
|
46994
47354
|
if (ev.endDate) {
|
|
46995
|
-
const
|
|
46996
|
-
const
|
|
46997
|
-
const estLabelWidth = ev.label.length * 7 + 16;
|
|
46998
|
-
const labelFitsInside = rectW >= estLabelWidth;
|
|
47355
|
+
const y2 = yScale(parseTimelineDate(ev.endDate));
|
|
47356
|
+
const rectH = Math.max(y2 - y, 4);
|
|
46999
47357
|
let fill2 = shapeFill(palette, color, isDark, { solid });
|
|
47000
47358
|
let stroke2 = color;
|
|
47001
47359
|
if (ev.uncertain) {
|
|
47002
|
-
const gradientId = `uncertain-
|
|
47003
|
-
const strokeGradientId = `uncertain-
|
|
47360
|
+
const gradientId = `uncertain-v-${ev.lineNumber}`;
|
|
47361
|
+
const strokeGradientId = `uncertain-v-s-${ev.lineNumber}`;
|
|
47004
47362
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
47005
47363
|
const defsEl = d3Selection22.select(defs);
|
|
47006
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47364
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
47007
47365
|
{ offset: "0%", opacity: 1 },
|
|
47008
47366
|
{ offset: "80%", opacity: 1 },
|
|
47009
47367
|
{ offset: "100%", opacity: 0 }
|
|
47010
47368
|
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47011
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47369
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
47012
47370
|
{ offset: "0%", opacity: 1 },
|
|
47013
47371
|
{ offset: "80%", opacity: 1 },
|
|
47014
47372
|
{ offset: "100%", opacity: 0 }
|
|
@@ -47016,206 +47374,100 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
47016
47374
|
fill2 = `url(#${gradientId})`;
|
|
47017
47375
|
stroke2 = `url(#${strokeGradientId})`;
|
|
47018
47376
|
}
|
|
47019
|
-
evG.append("rect").attr("x",
|
|
47020
|
-
|
|
47021
|
-
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);
|
|
47022
|
-
} else {
|
|
47023
|
-
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
47024
|
-
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
47025
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47026
|
-
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);
|
|
47027
|
-
}
|
|
47377
|
+
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);
|
|
47378
|
+
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);
|
|
47028
47379
|
} else {
|
|
47029
|
-
|
|
47030
|
-
|
|
47031
|
-
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
47032
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47033
|
-
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);
|
|
47034
|
-
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);
|
|
47035
|
-
}
|
|
47036
|
-
});
|
|
47037
|
-
}
|
|
47038
|
-
if (parsed.timelineTagGroups.length > 0) {
|
|
47039
|
-
const LG_HEIGHT = LEGEND_HEIGHT;
|
|
47040
|
-
const LG_PILL_PAD = LEGEND_PILL_PAD;
|
|
47041
|
-
const LG_PILL_FONT_SIZE = LEGEND_PILL_FONT_SIZE;
|
|
47042
|
-
const LG_CAPSULE_PAD = LEGEND_CAPSULE_PAD;
|
|
47043
|
-
const LG_DOT_R = LEGEND_DOT_R;
|
|
47044
|
-
const LG_ENTRY_FONT_SIZE = LEGEND_ENTRY_FONT_SIZE;
|
|
47045
|
-
const LG_ENTRY_DOT_GAP = LEGEND_ENTRY_DOT_GAP;
|
|
47046
|
-
const LG_ENTRY_TRAIL = LEGEND_ENTRY_TRAIL;
|
|
47047
|
-
const LG_ICON_W = 20;
|
|
47048
|
-
const mainSvg = d3Selection22.select(container).select("svg");
|
|
47049
|
-
const mainG = mainSvg.select("g");
|
|
47050
|
-
if (!mainSvg.empty() && !mainG.empty()) {
|
|
47051
|
-
let drawSwimlaneIcon4 = function(parent, x, y, isSwimActive) {
|
|
47052
|
-
const iconG = parent.append("g").attr("class", "tl-swimlane-icon").attr("transform", `translate(${x}, ${y})`).style("cursor", "pointer");
|
|
47053
|
-
const barColor = isSwimActive ? palette.primary : palette.textMuted;
|
|
47054
|
-
const barOpacity = isSwimActive ? 1 : 0.35;
|
|
47055
|
-
const bars = [
|
|
47056
|
-
{ y: 0, w: 8 },
|
|
47057
|
-
{ y: 4, w: 12 },
|
|
47058
|
-
{ y: 8, w: 6 }
|
|
47059
|
-
];
|
|
47060
|
-
for (const bar of bars) {
|
|
47061
|
-
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);
|
|
47062
|
-
}
|
|
47063
|
-
return iconG;
|
|
47064
|
-
}, relayout2 = function() {
|
|
47065
|
-
renderTimeline(
|
|
47066
|
-
container,
|
|
47067
|
-
parsed,
|
|
47068
|
-
palette,
|
|
47069
|
-
isDark,
|
|
47070
|
-
onClickItem,
|
|
47071
|
-
exportDims,
|
|
47072
|
-
currentActiveGroup,
|
|
47073
|
-
currentSwimlaneGroup,
|
|
47074
|
-
onTagStateChange,
|
|
47075
|
-
viewMode
|
|
47076
|
-
);
|
|
47077
|
-
}, drawLegend2 = function() {
|
|
47078
|
-
mainSvg.selectAll(".tl-tag-legend-group").remove();
|
|
47079
|
-
mainSvg.selectAll(".tl-tag-legend-container").remove();
|
|
47080
|
-
const effectiveColorKey = (currentActiveGroup ?? currentSwimlaneGroup)?.toLowerCase() ?? null;
|
|
47081
|
-
const visibleGroups = viewMode ? legendGroups.filter(
|
|
47082
|
-
(lg) => effectiveColorKey != null && lg.group.name.toLowerCase() === effectiveColorKey
|
|
47083
|
-
) : legendGroups;
|
|
47084
|
-
if (visibleGroups.length === 0) return;
|
|
47085
|
-
const legendContainer = mainSvg.append("g").attr("class", "tl-tag-legend-container");
|
|
47086
|
-
if (currentActiveGroup) {
|
|
47087
|
-
legendContainer.attr(
|
|
47088
|
-
"data-legend-active",
|
|
47089
|
-
currentActiveGroup.toLowerCase()
|
|
47090
|
-
);
|
|
47091
|
-
}
|
|
47092
|
-
const iconAddon = viewMode ? 0 : LG_ICON_W;
|
|
47093
|
-
const centralGroups = visibleGroups.map((lg) => ({
|
|
47094
|
-
name: lg.group.name,
|
|
47095
|
-
entries: lg.group.entries.map((e) => ({
|
|
47096
|
-
value: e.value,
|
|
47097
|
-
color: e.color
|
|
47098
|
-
}))
|
|
47099
|
-
}));
|
|
47100
|
-
const centralActive = viewMode ? effectiveColorKey : currentActiveGroup;
|
|
47101
|
-
const centralConfig = {
|
|
47102
|
-
groups: centralGroups,
|
|
47103
|
-
position: { placement: "top-center", titleRelation: "below-title" },
|
|
47104
|
-
mode: "fixed",
|
|
47105
|
-
capsulePillAddonWidth: iconAddon
|
|
47106
|
-
};
|
|
47107
|
-
const centralState = { activeGroup: centralActive };
|
|
47108
|
-
const centralCallbacks = viewMode ? {} : {
|
|
47109
|
-
onGroupToggle: (groupName) => {
|
|
47110
|
-
currentActiveGroup = currentActiveGroup === groupName.toLowerCase() ? null : groupName.toLowerCase();
|
|
47111
|
-
drawLegend2();
|
|
47112
|
-
recolorEvents2();
|
|
47113
|
-
onTagStateChange?.(currentActiveGroup, currentSwimlaneGroup);
|
|
47114
|
-
},
|
|
47115
|
-
onEntryHover: (groupName, entryValue) => {
|
|
47116
|
-
const tagKey = groupName.toLowerCase();
|
|
47117
|
-
if (entryValue) {
|
|
47118
|
-
const tagVal = entryValue.toLowerCase();
|
|
47119
|
-
fadeToTagValue(mainG, tagKey, tagVal);
|
|
47120
|
-
mainSvg.selectAll("[data-legend-entry]").each(function() {
|
|
47121
|
-
const el = d3Selection22.select(this);
|
|
47122
|
-
const ev = el.attr("data-legend-entry");
|
|
47123
|
-
const eg = el.attr("data-tag-group") ?? el.node()?.closest?.("[data-tag-group]")?.getAttribute("data-tag-group");
|
|
47124
|
-
el.attr(
|
|
47125
|
-
"opacity",
|
|
47126
|
-
eg === tagKey && ev === tagVal ? 1 : FADE_OPACITY3
|
|
47127
|
-
);
|
|
47128
|
-
});
|
|
47129
|
-
} else {
|
|
47130
|
-
fadeReset(mainG);
|
|
47131
|
-
mainSvg.selectAll("[data-legend-entry]").attr("opacity", 1);
|
|
47132
|
-
}
|
|
47133
|
-
},
|
|
47134
|
-
onGroupRendered: (groupName, groupEl, isActive) => {
|
|
47135
|
-
const groupKey = groupName.toLowerCase();
|
|
47136
|
-
groupEl.attr("data-tag-group", groupKey);
|
|
47137
|
-
if (isActive && !viewMode) {
|
|
47138
|
-
const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
|
|
47139
|
-
const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
47140
|
-
const pillXOff = LG_CAPSULE_PAD;
|
|
47141
|
-
const iconX = pillXOff + pillWidth3 + 5;
|
|
47142
|
-
const iconY = (LG_HEIGHT - 10) / 2;
|
|
47143
|
-
const iconEl = drawSwimlaneIcon4(
|
|
47144
|
-
groupEl,
|
|
47145
|
-
iconX,
|
|
47146
|
-
iconY,
|
|
47147
|
-
isSwimActive
|
|
47148
|
-
);
|
|
47149
|
-
iconEl.attr("data-swimlane-toggle", groupKey).on("click", (event) => {
|
|
47150
|
-
event.stopPropagation();
|
|
47151
|
-
currentSwimlaneGroup = currentSwimlaneGroup === groupKey ? null : groupKey;
|
|
47152
|
-
onTagStateChange?.(
|
|
47153
|
-
currentActiveGroup,
|
|
47154
|
-
currentSwimlaneGroup
|
|
47155
|
-
);
|
|
47156
|
-
relayout2();
|
|
47157
|
-
});
|
|
47158
|
-
}
|
|
47159
|
-
}
|
|
47160
|
-
};
|
|
47161
|
-
const legendInnerG = legendContainer.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
47162
|
-
renderLegendD3(
|
|
47163
|
-
legendInnerG,
|
|
47164
|
-
centralConfig,
|
|
47165
|
-
centralState,
|
|
47166
|
-
palette,
|
|
47167
|
-
isDark,
|
|
47168
|
-
centralCallbacks,
|
|
47169
|
-
width
|
|
47170
|
-
);
|
|
47171
|
-
}, recolorEvents2 = function() {
|
|
47172
|
-
const colorTG = currentActiveGroup ?? swimlaneTagGroup ?? null;
|
|
47173
|
-
mainG.selectAll(".tl-event").each(function() {
|
|
47174
|
-
const el = d3Selection22.select(this);
|
|
47175
|
-
const lineNum = el.attr("data-line-number");
|
|
47176
|
-
const ev = lineNum ? eventByLine.get(lineNum) : void 0;
|
|
47177
|
-
if (!ev) return;
|
|
47178
|
-
let color;
|
|
47179
|
-
if (colorTG) {
|
|
47180
|
-
const tagColor = resolveTagColor(
|
|
47181
|
-
ev.metadata,
|
|
47182
|
-
parsed.timelineTagGroups,
|
|
47183
|
-
colorTG
|
|
47184
|
-
);
|
|
47185
|
-
color = tagColor ?? (ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor);
|
|
47186
|
-
} else {
|
|
47187
|
-
color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
|
|
47188
|
-
}
|
|
47189
|
-
el.selectAll("rect").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
47190
|
-
el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
47191
|
-
});
|
|
47192
|
-
};
|
|
47193
|
-
var drawSwimlaneIcon3 = drawSwimlaneIcon4, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
|
|
47194
|
-
const legendY = title ? 50 : 10;
|
|
47195
|
-
const legendGroups = parsed.timelineTagGroups.map((g) => {
|
|
47196
|
-
const pillW = measureLegendText(g.name, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
47197
|
-
const iconSpace = viewMode ? 8 : LG_ICON_W + 4;
|
|
47198
|
-
let entryX = LG_CAPSULE_PAD + pillW + iconSpace;
|
|
47199
|
-
for (const entry of g.entries) {
|
|
47200
|
-
const textX = entryX + LG_DOT_R * 2 + LG_ENTRY_DOT_GAP;
|
|
47201
|
-
entryX = textX + measureLegendText(entry.value, LG_ENTRY_FONT_SIZE) + LG_ENTRY_TRAIL;
|
|
47202
|
-
}
|
|
47203
|
-
return {
|
|
47204
|
-
group: g,
|
|
47205
|
-
minifiedWidth: pillW,
|
|
47206
|
-
expandedWidth: entryX + LG_CAPSULE_PAD
|
|
47207
|
-
};
|
|
47208
|
-
});
|
|
47209
|
-
let currentActiveGroup = activeTagGroup ?? null;
|
|
47210
|
-
let currentSwimlaneGroup = swimlaneTagGroup ?? null;
|
|
47211
|
-
const eventByLine = /* @__PURE__ */ new Map();
|
|
47212
|
-
for (const ev of timelineEvents) {
|
|
47213
|
-
eventByLine.set(String(ev.lineNumber), ev);
|
|
47380
|
+
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);
|
|
47381
|
+
evG.append("text").attr("x", axisX + 16).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "11px").text(ev.label);
|
|
47214
47382
|
}
|
|
47215
|
-
|
|
47383
|
+
evG.append("text").attr("x", axisX - 14).attr(
|
|
47384
|
+
"y",
|
|
47385
|
+
ev.endDate ? yScale(parseTimelineDate(ev.date)) + Math.max(
|
|
47386
|
+
yScale(parseTimelineDate(ev.endDate)) - yScale(parseTimelineDate(ev.date)),
|
|
47387
|
+
4
|
|
47388
|
+
) / 2 : y
|
|
47389
|
+
).attr("dy", "0.35em").attr("text-anchor", "end").attr("fill", mutedColor).attr("font-size", "10px").text(ev.date + (ev.endDate ? `\u2192${ev.endDate}` : ""));
|
|
47216
47390
|
}
|
|
47217
47391
|
}
|
|
47218
47392
|
}
|
|
47393
|
+
function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims, activeTagGroup, swimlaneTagGroup, onTagStateChange, viewMode) {
|
|
47394
|
+
const setup = setupTimeline(
|
|
47395
|
+
container,
|
|
47396
|
+
parsed,
|
|
47397
|
+
palette,
|
|
47398
|
+
isDark,
|
|
47399
|
+
exportDims,
|
|
47400
|
+
activeTagGroup,
|
|
47401
|
+
swimlaneTagGroup
|
|
47402
|
+
);
|
|
47403
|
+
if (!setup) return;
|
|
47404
|
+
swimlaneTagGroup = setup.swimlaneTagGroup;
|
|
47405
|
+
const { isVertical, tagLanes } = setup;
|
|
47406
|
+
const hovers = makeTimelineHoverHelpers();
|
|
47407
|
+
if (isVertical) {
|
|
47408
|
+
renderTimelineVertical(
|
|
47409
|
+
container,
|
|
47410
|
+
parsed,
|
|
47411
|
+
palette,
|
|
47412
|
+
isDark,
|
|
47413
|
+
setup,
|
|
47414
|
+
hovers,
|
|
47415
|
+
onClickItem,
|
|
47416
|
+
exportDims,
|
|
47417
|
+
swimlaneTagGroup,
|
|
47418
|
+
activeTagGroup,
|
|
47419
|
+
onTagStateChange,
|
|
47420
|
+
viewMode
|
|
47421
|
+
);
|
|
47422
|
+
return;
|
|
47423
|
+
}
|
|
47424
|
+
const useGroupedHorizontal = tagLanes != null || parsed.timelineSort === "group" && parsed.timelineGroups.length > 0;
|
|
47425
|
+
if (useGroupedHorizontal) {
|
|
47426
|
+
renderTimelineHorizontalGrouped(
|
|
47427
|
+
container,
|
|
47428
|
+
parsed,
|
|
47429
|
+
palette,
|
|
47430
|
+
isDark,
|
|
47431
|
+
setup,
|
|
47432
|
+
hovers,
|
|
47433
|
+
onClickItem,
|
|
47434
|
+
exportDims,
|
|
47435
|
+
swimlaneTagGroup,
|
|
47436
|
+
activeTagGroup,
|
|
47437
|
+
onTagStateChange,
|
|
47438
|
+
viewMode
|
|
47439
|
+
);
|
|
47440
|
+
} else {
|
|
47441
|
+
renderTimelineHorizontalTimeSort(
|
|
47442
|
+
container,
|
|
47443
|
+
parsed,
|
|
47444
|
+
palette,
|
|
47445
|
+
isDark,
|
|
47446
|
+
setup,
|
|
47447
|
+
hovers,
|
|
47448
|
+
onClickItem,
|
|
47449
|
+
exportDims,
|
|
47450
|
+
swimlaneTagGroup,
|
|
47451
|
+
activeTagGroup,
|
|
47452
|
+
onTagStateChange,
|
|
47453
|
+
viewMode
|
|
47454
|
+
);
|
|
47455
|
+
}
|
|
47456
|
+
renderTimelineTagLegendOverlay(
|
|
47457
|
+
container,
|
|
47458
|
+
parsed,
|
|
47459
|
+
palette,
|
|
47460
|
+
isDark,
|
|
47461
|
+
setup,
|
|
47462
|
+
hovers,
|
|
47463
|
+
onClickItem,
|
|
47464
|
+
exportDims,
|
|
47465
|
+
swimlaneTagGroup,
|
|
47466
|
+
activeTagGroup,
|
|
47467
|
+
onTagStateChange,
|
|
47468
|
+
viewMode
|
|
47469
|
+
);
|
|
47470
|
+
}
|
|
47219
47471
|
function getRotateFn(mode) {
|
|
47220
47472
|
if (mode === "mixed") return () => Math.random() > 0.5 ? 0 : 90;
|
|
47221
47473
|
if (mode === "angled") return () => Math.round(Math.random() * 30 - 15);
|
|
@@ -47339,7 +47591,7 @@ function regionCentroid(circles, inside) {
|
|
|
47339
47591
|
}
|
|
47340
47592
|
return { x: sx / count, y: sy / count };
|
|
47341
47593
|
}
|
|
47342
|
-
function renderVenn(container, parsed, palette,
|
|
47594
|
+
function renderVenn(container, parsed, palette, _isDark, onClickItem, exportDims) {
|
|
47343
47595
|
const { vennSets, vennOverlaps } = parsed;
|
|
47344
47596
|
const title = parsed.noTitle ? null : parsed.title;
|
|
47345
47597
|
if (vennSets.length < 2 || vennSets.length > 3) return;
|
|
@@ -47573,7 +47825,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
47573
47825
|
};
|
|
47574
47826
|
const gcx = circles.reduce((s, c) => s + c.x, 0) / n;
|
|
47575
47827
|
const gcy = circles.reduce((s, c) => s + c.y, 0) / n;
|
|
47576
|
-
function exclusiveHSpan(
|
|
47828
|
+
function exclusiveHSpan(_px, py, ci) {
|
|
47577
47829
|
const dy = py - circles[ci].y;
|
|
47578
47830
|
const halfChord = Math.sqrt(
|
|
47579
47831
|
Math.max(0, circles[ci].r * circles[ci].r - dy * dy)
|
|
@@ -48486,9 +48738,9 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
48486
48738
|
blHiddenTagValues.set(k, new Set(v));
|
|
48487
48739
|
}
|
|
48488
48740
|
}
|
|
48489
|
-
const { layoutBoxesAndLines: layoutBoxesAndLines2 } = await Promise.resolve().then(() => (init_layout5(), layout_exports5));
|
|
48490
48741
|
const { renderBoxesAndLinesForExport: renderBoxesAndLinesForExport2 } = await Promise.resolve().then(() => (init_renderer6(), renderer_exports6));
|
|
48491
|
-
const
|
|
48742
|
+
const { layoutBoxesAndLines: layoutBoxesAndLines2 } = await Promise.resolve().then(() => (init_layout5(), layout_exports5));
|
|
48743
|
+
const blLayout = await layoutBoxesAndLines2(blParsed);
|
|
48492
48744
|
const PADDING3 = 20;
|
|
48493
48745
|
const titleOffset = blParsed.title ? 40 : 0;
|
|
48494
48746
|
const exportWidth = blLayout.width + PADDING3 * 2;
|
|
@@ -49595,7 +49847,7 @@ init_dgmo_router();
|
|
|
49595
49847
|
init_registry();
|
|
49596
49848
|
async function ensureDom() {
|
|
49597
49849
|
if (typeof document !== "undefined") return;
|
|
49598
|
-
const { JSDOM } = await
|
|
49850
|
+
const { JSDOM } = await loadJsdom();
|
|
49599
49851
|
const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>");
|
|
49600
49852
|
const win = dom.window;
|
|
49601
49853
|
Object.defineProperty(globalThis, "document", {
|
|
@@ -49619,6 +49871,14 @@ async function ensureDom() {
|
|
|
49619
49871
|
configurable: true
|
|
49620
49872
|
});
|
|
49621
49873
|
}
|
|
49874
|
+
async function loadJsdom() {
|
|
49875
|
+
const spec = ["js", "dom"].join("");
|
|
49876
|
+
return import(
|
|
49877
|
+
/* @vite-ignore */
|
|
49878
|
+
/* webpackIgnore: true */
|
|
49879
|
+
spec
|
|
49880
|
+
);
|
|
49881
|
+
}
|
|
49622
49882
|
async function render(content, options) {
|
|
49623
49883
|
const theme = options?.theme ?? "light";
|
|
49624
49884
|
const paletteName = options?.palette ?? "nord";
|
|
@@ -49800,6 +50060,7 @@ var DIRECTIVE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
49800
50060
|
"split",
|
|
49801
50061
|
"slo-p90-latency-ms",
|
|
49802
50062
|
"slo-availability",
|
|
50063
|
+
"slo-warning-margin",
|
|
49803
50064
|
"cache-hit",
|
|
49804
50065
|
"concurrency",
|
|
49805
50066
|
"duration-ms",
|
|
@@ -50423,7 +50684,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
|
|
|
50423
50684
|
|
|
50424
50685
|
// src/auto/index.ts
|
|
50425
50686
|
init_safe_href();
|
|
50426
|
-
var VERSION = "0.
|
|
50687
|
+
var VERSION = "0.15.1";
|
|
50427
50688
|
var DEFAULTS = {
|
|
50428
50689
|
theme: "auto",
|
|
50429
50690
|
palette: "nord",
|
|
@@ -50740,8 +51001,8 @@ function determineReplaceTarget(matched) {
|
|
|
50740
51001
|
}
|
|
50741
51002
|
async function processElement(el) {
|
|
50742
51003
|
if (!(el instanceof HTMLElement)) return {};
|
|
50743
|
-
if (el.dataset
|
|
50744
|
-
el.dataset
|
|
51004
|
+
if (el.dataset["dgmoProcessed"] === "true") return {};
|
|
51005
|
+
el.dataset["dgmoProcessed"] = "true";
|
|
50745
51006
|
const source = el.textContent || "";
|
|
50746
51007
|
const sourceBytes = new TextEncoder().encode(source).byteLength;
|
|
50747
51008
|
if (sourceBytes > SOURCE_BYTE_CAP) {
|
|
@@ -50758,7 +51019,7 @@ async function processElement(el) {
|
|
|
50758
51019
|
const resolvedTheme = cfg.theme === "transparent" ? "transparent" : resolveTheme(cfg.theme);
|
|
50759
51020
|
const renderTheme = resolvedTheme === "transparent" ? "transparent" : resolvedTheme;
|
|
50760
51021
|
const ariaLabel = deriveAriaLabel(source);
|
|
50761
|
-
const perElementShowSource = el.dataset
|
|
51022
|
+
const perElementShowSource = el.dataset["showSource"];
|
|
50762
51023
|
let showSource = cfg.showSource;
|
|
50763
51024
|
if (perElementShowSource === "true") showSource = true;
|
|
50764
51025
|
else if (perElementShowSource === "false") showSource = false;
|
|
@@ -50808,7 +51069,7 @@ async function processElement(el) {
|
|
|
50808
51069
|
const wrapper = document.createElement("div");
|
|
50809
51070
|
const themeClass = resolvedTheme === "dark" ? "dgmo-theme-dark" : resolvedTheme === "transparent" ? "dgmo-theme-transparent" : "dgmo-theme-light";
|
|
50810
51071
|
wrapper.className = `dgmo-rendered ${themeClass}`;
|
|
50811
|
-
wrapper.dataset
|
|
51072
|
+
wrapper.dataset["dgmoProcessed"] = "true";
|
|
50812
51073
|
const svgHolder = document.createElement("div");
|
|
50813
51074
|
svgHolder.innerHTML = result.svg;
|
|
50814
51075
|
const svgEl = svgHolder.querySelector("svg");
|
|
@@ -50877,15 +51138,16 @@ function initialize(opts = {}) {
|
|
|
50877
51138
|
}
|
|
50878
51139
|
}
|
|
50879
51140
|
const next = { ...activeConfig };
|
|
50880
|
-
if (isValidTheme(opts
|
|
50881
|
-
next.theme = opts
|
|
51141
|
+
if (isValidTheme(opts["theme"])) {
|
|
51142
|
+
next.theme = opts["theme"];
|
|
50882
51143
|
}
|
|
50883
|
-
if (typeof opts
|
|
50884
|
-
next.palette = opts
|
|
51144
|
+
if (typeof opts["palette"] === "string" && paletteExists(opts["palette"])) {
|
|
51145
|
+
next.palette = opts["palette"];
|
|
50885
51146
|
}
|
|
50886
|
-
if (typeof opts
|
|
50887
|
-
|
|
50888
|
-
|
|
51147
|
+
if (typeof opts["showSource"] === "boolean")
|
|
51148
|
+
next.showSource = opts["showSource"];
|
|
51149
|
+
if (typeof opts["showEditorLink"] === "boolean")
|
|
51150
|
+
next.showEditorLink = opts["showEditorLink"];
|
|
50889
51151
|
activeConfig = next;
|
|
50890
51152
|
}
|
|
50891
51153
|
async function run(opts = {}) {
|
|
@@ -50924,7 +51186,7 @@ function rerenderAllForTheme() {
|
|
|
50924
51186
|
placeholder.className = "dgmo";
|
|
50925
51187
|
placeholder.textContent = t.source;
|
|
50926
51188
|
if (t.perElementShowSource !== null) {
|
|
50927
|
-
placeholder.dataset
|
|
51189
|
+
placeholder.dataset["showSource"] = String(t.perElementShowSource);
|
|
50928
51190
|
}
|
|
50929
51191
|
t.wrapper.replaceWith(placeholder);
|
|
50930
51192
|
wrappers.delete(t);
|
|
@@ -50951,7 +51213,7 @@ function unhideAllSources() {
|
|
|
50951
51213
|
el.style.visibility = "visible";
|
|
50952
51214
|
});
|
|
50953
51215
|
if (document.documentElement && document.documentElement.dataset) {
|
|
50954
|
-
document.documentElement.dataset
|
|
51216
|
+
document.documentElement.dataset["dgmoAutoFailed"] = "1";
|
|
50955
51217
|
}
|
|
50956
51218
|
}
|
|
50957
51219
|
function bootstrap() {
|