@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.mjs
CHANGED
|
@@ -1759,6 +1759,7 @@ __export(palettes_exports, {
|
|
|
1759
1759
|
monokaiPalette: () => monokaiPalette,
|
|
1760
1760
|
nordPalette: () => nordPalette,
|
|
1761
1761
|
oneDarkPalette: () => oneDarkPalette,
|
|
1762
|
+
palettes: () => palettes,
|
|
1762
1763
|
registerPalette: () => registerPalette,
|
|
1763
1764
|
rosePinePalette: () => rosePinePalette,
|
|
1764
1765
|
shade: () => shade,
|
|
@@ -1767,6 +1768,7 @@ __export(palettes_exports, {
|
|
|
1767
1768
|
tint: () => tint,
|
|
1768
1769
|
tokyoNightPalette: () => tokyoNightPalette
|
|
1769
1770
|
});
|
|
1771
|
+
var palettes;
|
|
1770
1772
|
var init_palettes = __esm({
|
|
1771
1773
|
"src/palettes/index.ts"() {
|
|
1772
1774
|
"use strict";
|
|
@@ -1782,6 +1784,28 @@ var init_palettes = __esm({
|
|
|
1782
1784
|
init_tokyo_night();
|
|
1783
1785
|
init_dracula();
|
|
1784
1786
|
init_monokai();
|
|
1787
|
+
init_bold();
|
|
1788
|
+
init_catppuccin();
|
|
1789
|
+
init_dracula();
|
|
1790
|
+
init_gruvbox();
|
|
1791
|
+
init_monokai();
|
|
1792
|
+
init_nord();
|
|
1793
|
+
init_one_dark();
|
|
1794
|
+
init_rose_pine();
|
|
1795
|
+
init_solarized();
|
|
1796
|
+
init_tokyo_night();
|
|
1797
|
+
palettes = {
|
|
1798
|
+
nord: nordPalette,
|
|
1799
|
+
catppuccin: catppuccinPalette,
|
|
1800
|
+
solarized: solarizedPalette,
|
|
1801
|
+
gruvbox: gruvboxPalette,
|
|
1802
|
+
tokyoNight: tokyoNightPalette,
|
|
1803
|
+
oneDark: oneDarkPalette,
|
|
1804
|
+
rosePine: rosePinePalette,
|
|
1805
|
+
dracula: draculaPalette,
|
|
1806
|
+
monokai: monokaiPalette,
|
|
1807
|
+
bold: boldPalette
|
|
1808
|
+
};
|
|
1785
1809
|
}
|
|
1786
1810
|
});
|
|
1787
1811
|
|
|
@@ -2212,7 +2236,7 @@ function injectDefaultTagMetadata(entities, tagGroups, skip) {
|
|
|
2212
2236
|
}
|
|
2213
2237
|
}
|
|
2214
2238
|
}
|
|
2215
|
-
function resolveActiveTagGroup(
|
|
2239
|
+
function resolveActiveTagGroup(tagGroups, explicitActiveTag, programmaticOverride) {
|
|
2216
2240
|
if (programmaticOverride !== void 0) {
|
|
2217
2241
|
if (!programmaticOverride) return null;
|
|
2218
2242
|
if (programmaticOverride.toLowerCase() === "none") return null;
|
|
@@ -2222,6 +2246,7 @@ function resolveActiveTagGroup(_tagGroups, explicitActiveTag, programmaticOverri
|
|
|
2222
2246
|
if (explicitActiveTag.toLowerCase() === "none") return null;
|
|
2223
2247
|
return explicitActiveTag;
|
|
2224
2248
|
}
|
|
2249
|
+
if (tagGroups.length > 0) return tagGroups[0].name;
|
|
2225
2250
|
return null;
|
|
2226
2251
|
}
|
|
2227
2252
|
function matchTagBlockHeading(trimmed) {
|
|
@@ -5302,12 +5327,6 @@ function parseClassDiagram(content, palette) {
|
|
|
5302
5327
|
diagnostics: [],
|
|
5303
5328
|
error: null
|
|
5304
5329
|
};
|
|
5305
|
-
const _fail = (line12, message) => {
|
|
5306
|
-
const diag = makeDgmoError(line12, message);
|
|
5307
|
-
result.diagnostics.push(diag);
|
|
5308
|
-
result.error = formatDgmoError(diag);
|
|
5309
|
-
return result;
|
|
5310
|
-
};
|
|
5311
5330
|
const classMap = /* @__PURE__ */ new Map();
|
|
5312
5331
|
const nameAliasMap = /* @__PURE__ */ new Map();
|
|
5313
5332
|
function resolveAliasName(token) {
|
|
@@ -5702,12 +5721,6 @@ function parseERDiagram(content, palette) {
|
|
|
5702
5721
|
diagnostics: [],
|
|
5703
5722
|
error: null
|
|
5704
5723
|
};
|
|
5705
|
-
const _fail = (line12, message) => {
|
|
5706
|
-
const diag = makeDgmoError(line12, message);
|
|
5707
|
-
result.diagnostics.push(diag);
|
|
5708
|
-
result.error = formatDgmoError(diag);
|
|
5709
|
-
return result;
|
|
5710
|
-
};
|
|
5711
5724
|
const pushError = (line12, message) => {
|
|
5712
5725
|
const diag = makeDgmoError(line12, message);
|
|
5713
5726
|
result.diagnostics.push(diag);
|
|
@@ -7166,7 +7179,7 @@ function buildSankeyOption(parsed, textColor, colors, bg, titleConfig) {
|
|
|
7166
7179
|
]
|
|
7167
7180
|
};
|
|
7168
7181
|
}
|
|
7169
|
-
function buildChordOption(parsed, palette, isDark, textColor, colors,
|
|
7182
|
+
function buildChordOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
7170
7183
|
const nodeSet = /* @__PURE__ */ new Set();
|
|
7171
7184
|
if (parsed.links) {
|
|
7172
7185
|
for (const link of parsed.links) {
|
|
@@ -7280,7 +7293,7 @@ function evaluateExpression(expr, x) {
|
|
|
7280
7293
|
return NaN;
|
|
7281
7294
|
}
|
|
7282
7295
|
}
|
|
7283
|
-
function buildFunctionOption(parsed, palette,
|
|
7296
|
+
function buildFunctionOption(parsed, palette, _isDark, textColor, axisLineColor, gridOpacity, colors, titleConfig) {
|
|
7284
7297
|
const xRange = parsed.xRange ?? { min: -10, max: 10 };
|
|
7285
7298
|
const samples = 200;
|
|
7286
7299
|
const step = (xRange.max - xRange.min) / samples;
|
|
@@ -7953,7 +7966,7 @@ function buildHeatmapOption(parsed, palette, isDark, textColor, axisLineColor, t
|
|
|
7953
7966
|
]
|
|
7954
7967
|
};
|
|
7955
7968
|
}
|
|
7956
|
-
function buildFunnelOption(parsed, palette, isDark, textColor, colors,
|
|
7969
|
+
function buildFunnelOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
7957
7970
|
const sorted = [...parsed.data].sort((a, b) => b.value - a.value);
|
|
7958
7971
|
const data = sorted.map((d) => {
|
|
7959
7972
|
const stroke2 = d.color ?? colors[parsed.data.indexOf(d) % colors.length];
|
|
@@ -8236,7 +8249,7 @@ function wrapLabel(text, maxChars) {
|
|
|
8236
8249
|
if (current) lines.push(current);
|
|
8237
8250
|
return lines.join("\n");
|
|
8238
8251
|
}
|
|
8239
|
-
function buildBarOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors,
|
|
8252
|
+
function buildBarOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors, _bg, titleConfig, chartWidth) {
|
|
8240
8253
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
8241
8254
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
8242
8255
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -8563,7 +8576,7 @@ function pieLabelLayout(parsed) {
|
|
|
8563
8576
|
if (maxLen > 18) return { outerRadius: 55, fontSize: 13 };
|
|
8564
8577
|
return { outerRadius: 70, fontSize: 14 };
|
|
8565
8578
|
}
|
|
8566
|
-
function buildPieOption(parsed, palette, isDark, textColor, colors,
|
|
8579
|
+
function buildPieOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig, isDoughnut) {
|
|
8567
8580
|
const HIDE_AXES = { xAxis: { show: false }, yAxis: { show: false } };
|
|
8568
8581
|
const data = parsed.data.map((d, i) => {
|
|
8569
8582
|
const stroke2 = d.color ?? colors[i % colors.length];
|
|
@@ -8662,7 +8675,7 @@ function buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, title
|
|
|
8662
8675
|
]
|
|
8663
8676
|
};
|
|
8664
8677
|
}
|
|
8665
|
-
function buildPolarAreaOption(parsed, palette, isDark, textColor, colors,
|
|
8678
|
+
function buildPolarAreaOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
8666
8679
|
const data = parsed.data.map((d, i) => {
|
|
8667
8680
|
const stroke2 = d.color ?? colors[i % colors.length];
|
|
8668
8681
|
return {
|
|
@@ -8705,7 +8718,7 @@ function buildPolarAreaOption(parsed, palette, isDark, textColor, colors, bg, ti
|
|
|
8705
8718
|
]
|
|
8706
8719
|
};
|
|
8707
8720
|
}
|
|
8708
|
-
function buildBarStackedOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors,
|
|
8721
|
+
function buildBarStackedOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors, _bg, titleConfig, chartWidth) {
|
|
8709
8722
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
8710
8723
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
8711
8724
|
const seriesNames = parsed.seriesNames ?? [];
|
|
@@ -8845,8 +8858,8 @@ async function renderExtendedChartForExport(content, theme, palette) {
|
|
|
8845
8858
|
const titleHeight = option.title && option.title.text ? 40 : 0;
|
|
8846
8859
|
const legendY = 8 + titleHeight;
|
|
8847
8860
|
const grid = option.grid;
|
|
8848
|
-
const gridLeftPct = grid?.left ? parseFloat(String(grid
|
|
8849
|
-
const gridRightPct = grid?.right ? parseFloat(String(grid
|
|
8861
|
+
const gridLeftPct = grid?.["left"] ? parseFloat(String(grid["left"])) : void 0;
|
|
8862
|
+
const gridRightPct = grid?.["right"] ? parseFloat(String(grid["right"])) : void 0;
|
|
8850
8863
|
const { svg: legendSvgStr } = renderLegendSvg(legendGroups, {
|
|
8851
8864
|
palette: effectivePalette,
|
|
8852
8865
|
isDark,
|
|
@@ -9192,7 +9205,7 @@ function parseOrg(content, palette) {
|
|
|
9192
9205
|
}
|
|
9193
9206
|
return result;
|
|
9194
9207
|
}
|
|
9195
|
-
function parseNodeLabel(trimmed, _indent, lineNumber,
|
|
9208
|
+
function parseNodeLabel(trimmed, _indent, lineNumber, _palette, counter, metaAliasMap = /* @__PURE__ */ new Map(), warnFn, nameAliasMap) {
|
|
9196
9209
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
9197
9210
|
let label = segments[0];
|
|
9198
9211
|
const asMatch = label.match(/^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/);
|
|
@@ -9441,8 +9454,8 @@ function parseKanban(content, palette) {
|
|
|
9441
9454
|
columnMetadata,
|
|
9442
9455
|
parsePipeMetadata(pipeSegments, metaAliasMap)
|
|
9443
9456
|
);
|
|
9444
|
-
if (columnMetadata
|
|
9445
|
-
const wipVal = parseInt(columnMetadata
|
|
9457
|
+
if (columnMetadata["wip"]) {
|
|
9458
|
+
const wipVal = parseInt(columnMetadata["wip"], 10);
|
|
9446
9459
|
if (!isNaN(wipVal)) {
|
|
9447
9460
|
wipLimit = wipVal;
|
|
9448
9461
|
}
|
|
@@ -9821,7 +9834,7 @@ function parseC4(content, palette) {
|
|
|
9821
9834
|
);
|
|
9822
9835
|
const shape = inferC4Shape(
|
|
9823
9836
|
nodeName,
|
|
9824
|
-
metadata
|
|
9837
|
+
metadata["tech"] ?? metadata["technology"]
|
|
9825
9838
|
);
|
|
9826
9839
|
const dNode = {
|
|
9827
9840
|
name: nodeName,
|
|
@@ -9924,11 +9937,11 @@ function parseC4(content, palette) {
|
|
|
9924
9937
|
target = targetBody.substring(0, pipeIdx).trim();
|
|
9925
9938
|
const metaPart = targetBody.substring(pipeIdx + 1).trim();
|
|
9926
9939
|
const meta = parsePipeMetadata(["", metaPart], metaAliasMap);
|
|
9927
|
-
if (meta
|
|
9928
|
-
technology = meta
|
|
9940
|
+
if (meta["tech"]) {
|
|
9941
|
+
technology = meta["tech"];
|
|
9929
9942
|
}
|
|
9930
|
-
if (meta
|
|
9931
|
-
technology = meta
|
|
9943
|
+
if (meta["technology"]) {
|
|
9944
|
+
technology = meta["technology"];
|
|
9932
9945
|
}
|
|
9933
9946
|
}
|
|
9934
9947
|
const rel = {
|
|
@@ -10062,7 +10075,7 @@ function parseC4(content, palette) {
|
|
|
10062
10075
|
metaAliasMap,
|
|
10063
10076
|
() => pushError(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
10064
10077
|
);
|
|
10065
|
-
const shape = explicitShape ?? inferC4Shape(namePart, metadata
|
|
10078
|
+
const shape = explicitShape ?? inferC4Shape(namePart, metadata["tech"] ?? metadata["technology"]);
|
|
10066
10079
|
let isADescription;
|
|
10067
10080
|
if ("description" in metadata) {
|
|
10068
10081
|
const descVal = metadata["description"].trim();
|
|
@@ -10122,7 +10135,7 @@ function parseC4(content, palette) {
|
|
|
10122
10135
|
metaAliasMap,
|
|
10123
10136
|
() => pushError(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
10124
10137
|
);
|
|
10125
|
-
const shape = explicitShape ?? inferC4Shape(namePart, metadata
|
|
10138
|
+
const shape = explicitShape ?? inferC4Shape(namePart, metadata["tech"] ?? metadata["technology"]);
|
|
10126
10139
|
let prefixDescription;
|
|
10127
10140
|
if ("description" in metadata) {
|
|
10128
10141
|
const descVal = metadata["description"].trim();
|
|
@@ -10731,7 +10744,7 @@ function parseSitemap(content, palette) {
|
|
|
10731
10744
|
}
|
|
10732
10745
|
return result;
|
|
10733
10746
|
}
|
|
10734
|
-
function parseNodeLabel2(trimmed, lineNumber,
|
|
10747
|
+
function parseNodeLabel2(trimmed, lineNumber, _palette, counter, metaAliasMap = /* @__PURE__ */ new Map(), warnFn, _diagnostics, nameAliasMap) {
|
|
10735
10748
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
10736
10749
|
let label = segments[0];
|
|
10737
10750
|
const asMatch = label.match(/^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/);
|
|
@@ -10908,6 +10921,17 @@ function parseInfra(content) {
|
|
|
10908
10921
|
if (!m) return { label: trimmed };
|
|
10909
10922
|
return { label: m[1].trim(), alias: m[2] };
|
|
10910
10923
|
}
|
|
10924
|
+
const IS_A_SUFFIX = /^(.*?)\s+is\s+an?\s+[A-Za-z][\w-]*\s*$/i;
|
|
10925
|
+
function peelInfraDecorations(rawName, lineNumber) {
|
|
10926
|
+
const peeled = peelAlias2(rawName);
|
|
10927
|
+
const m = peeled.label.match(IS_A_SUFFIX);
|
|
10928
|
+
if (!m) return peeled;
|
|
10929
|
+
warn2(
|
|
10930
|
+
lineNumber,
|
|
10931
|
+
`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.`
|
|
10932
|
+
);
|
|
10933
|
+
return { label: m[1].trim(), alias: peeled.alias };
|
|
10934
|
+
}
|
|
10911
10935
|
function resolveTargetId(rawName) {
|
|
10912
10936
|
const aliasResolved = nameAliasMap.get(rawName.trim());
|
|
10913
10937
|
if (aliasResolved !== void 0) return aliasResolved;
|
|
@@ -11011,11 +11035,11 @@ function parseInfra(content) {
|
|
|
11011
11035
|
continue;
|
|
11012
11036
|
}
|
|
11013
11037
|
if (trimmed === "animate") {
|
|
11014
|
-
result.options
|
|
11038
|
+
result.options["animate"] = "on";
|
|
11015
11039
|
continue;
|
|
11016
11040
|
}
|
|
11017
11041
|
if (trimmed === "no-animate") {
|
|
11018
|
-
result.options
|
|
11042
|
+
result.options["animate"] = "off";
|
|
11019
11043
|
continue;
|
|
11020
11044
|
}
|
|
11021
11045
|
if (tryParseSharedOption(trimmed, result.options)) {
|
|
@@ -11062,7 +11086,7 @@ function parseInfra(content) {
|
|
|
11062
11086
|
finishCurrentNode();
|
|
11063
11087
|
finishCurrentTagGroup();
|
|
11064
11088
|
const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
|
|
11065
|
-
const peeled =
|
|
11089
|
+
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
11066
11090
|
const name = peeled.label;
|
|
11067
11091
|
const rest = compMatch[3] || "";
|
|
11068
11092
|
const { tags } = extractPipeMetadata(rest);
|
|
@@ -11133,7 +11157,7 @@ function parseInfra(content) {
|
|
|
11133
11157
|
if (compMatch) {
|
|
11134
11158
|
finishCurrentTagGroup();
|
|
11135
11159
|
const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
|
|
11136
|
-
const peeled =
|
|
11160
|
+
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
11137
11161
|
const name = peeled.label;
|
|
11138
11162
|
const rest = compMatch[3] || "";
|
|
11139
11163
|
const { tags: nodeTags } = extractPipeMetadata(rest);
|
|
@@ -11169,8 +11193,8 @@ function parseInfra(content) {
|
|
|
11169
11193
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11170
11194
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11171
11195
|
warnUnparsedPipeMeta(targetName, lineNumber, warn2);
|
|
11172
|
-
const split = pipeMeta.tags
|
|
11173
|
-
const fanoutRaw = pipeMeta.tags
|
|
11196
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11197
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11174
11198
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11175
11199
|
warn2(
|
|
11176
11200
|
lineNumber,
|
|
@@ -11201,8 +11225,8 @@ function parseInfra(content) {
|
|
|
11201
11225
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11202
11226
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11203
11227
|
warnUnparsedPipeMeta(targetName, lineNumber, warn2);
|
|
11204
|
-
const split = pipeMeta.tags
|
|
11205
|
-
const fanoutRaw = pipeMeta.tags
|
|
11228
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11229
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11206
11230
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11207
11231
|
warn2(
|
|
11208
11232
|
lineNumber,
|
|
@@ -11236,8 +11260,8 @@ function parseInfra(content) {
|
|
|
11236
11260
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11237
11261
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11238
11262
|
warnUnparsedPipeMeta(targetName, lineNumber, warn2);
|
|
11239
|
-
const split = pipeMeta.tags
|
|
11240
|
-
const fanoutRaw = pipeMeta.tags
|
|
11263
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11264
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11241
11265
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11242
11266
|
warn2(
|
|
11243
11267
|
lineNumber,
|
|
@@ -11268,8 +11292,8 @@ function parseInfra(content) {
|
|
|
11268
11292
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11269
11293
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11270
11294
|
warnUnparsedPipeMeta(targetName, lineNumber, warn2);
|
|
11271
|
-
const split = pipeMeta.tags
|
|
11272
|
-
const fanoutRaw = pipeMeta.tags
|
|
11295
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11296
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11273
11297
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11274
11298
|
warn2(
|
|
11275
11299
|
lineNumber,
|
|
@@ -11352,7 +11376,7 @@ function parseInfra(content) {
|
|
|
11352
11376
|
const compMatch = trimmed.match(COMPONENT_RE);
|
|
11353
11377
|
if (compMatch) {
|
|
11354
11378
|
const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
|
|
11355
|
-
const peeled =
|
|
11379
|
+
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
11356
11380
|
const name = peeled.label;
|
|
11357
11381
|
const rest = compMatch[3] || "";
|
|
11358
11382
|
const { tags: nodeTags } = extractPipeMetadata(rest);
|
|
@@ -11378,10 +11402,13 @@ function parseInfra(content) {
|
|
|
11378
11402
|
finishCurrentNode();
|
|
11379
11403
|
finishCurrentTagGroup();
|
|
11380
11404
|
currentGroup = null;
|
|
11381
|
-
const
|
|
11405
|
+
const rawName = (compMatch[1] ?? compMatch[2] ?? "").trim();
|
|
11406
|
+
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
11407
|
+
const name = peeled.label;
|
|
11382
11408
|
const rest = compMatch[3] || "";
|
|
11383
11409
|
const { tags } = extractPipeMetadata(rest);
|
|
11384
11410
|
const id = nodeId2(name);
|
|
11411
|
+
if (peeled.alias) nameAliasMap.set(peeled.alias, id);
|
|
11385
11412
|
currentNode = {
|
|
11386
11413
|
id,
|
|
11387
11414
|
label: name,
|
|
@@ -11431,6 +11458,14 @@ function parseInfra(content) {
|
|
|
11431
11458
|
validateTagGroupNames(result.tagGroups, warn2, setError);
|
|
11432
11459
|
return result;
|
|
11433
11460
|
}
|
|
11461
|
+
function stripNodeDecorations(name) {
|
|
11462
|
+
let s = name.trim();
|
|
11463
|
+
const aliasMatch = s.match(/^(.*?)\s+as\s+[A-Za-z][A-Za-z0-9_]{0,11}\s*$/);
|
|
11464
|
+
if (aliasMatch) s = aliasMatch[1].trim();
|
|
11465
|
+
const isAMatch = s.match(/^(.*?)\s+is\s+an?\s+[A-Za-z][\w-]*\s*$/i);
|
|
11466
|
+
if (isAMatch) s = isAMatch[1].trim();
|
|
11467
|
+
return s;
|
|
11468
|
+
}
|
|
11434
11469
|
function extractSymbols4(docText) {
|
|
11435
11470
|
const entities = [];
|
|
11436
11471
|
let inMetadata = true;
|
|
@@ -11464,7 +11499,7 @@ function extractSymbols4(docText) {
|
|
|
11464
11499
|
if (/^\[/.test(line12)) continue;
|
|
11465
11500
|
const m = COMPONENT_RE.exec(line12);
|
|
11466
11501
|
if (m) {
|
|
11467
|
-
const name = (m[1] ?? m[2] ?? "").trim();
|
|
11502
|
+
const name = stripNodeDecorations((m[1] ?? m[2] ?? "").trim());
|
|
11468
11503
|
if (name && !entities.includes(name)) entities.push(name);
|
|
11469
11504
|
}
|
|
11470
11505
|
} else {
|
|
@@ -11479,7 +11514,7 @@ function extractSymbols4(docText) {
|
|
|
11479
11514
|
continue;
|
|
11480
11515
|
const m = COMPONENT_RE.exec(line12);
|
|
11481
11516
|
if (m) {
|
|
11482
|
-
const name = (m[1] ?? m[2] ?? "").trim();
|
|
11517
|
+
const name = stripNodeDecorations((m[1] ?? m[2] ?? "").trim());
|
|
11483
11518
|
if (name && !entities.includes(name)) entities.push(name);
|
|
11484
11519
|
}
|
|
11485
11520
|
}
|
|
@@ -11965,15 +12000,15 @@ function parseGantt(content, palette) {
|
|
|
11965
12000
|
metaAliasMap,
|
|
11966
12001
|
() => warn2(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
11967
12002
|
);
|
|
11968
|
-
if (meta
|
|
11969
|
-
const key = meta
|
|
12003
|
+
if (meta["lag"] || meta["lead"]) {
|
|
12004
|
+
const key = meta["lag"] ? "lag" : "lead";
|
|
11970
12005
|
softError(
|
|
11971
12006
|
lineNumber,
|
|
11972
12007
|
`"${key}" is no longer supported \u2014 use "offset: ${meta[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
11973
12008
|
);
|
|
11974
12009
|
}
|
|
11975
|
-
if (meta
|
|
11976
|
-
const raw = meta
|
|
12010
|
+
if (meta["offset"]) {
|
|
12011
|
+
const raw = meta["offset"];
|
|
11977
12012
|
if (raw.trim().startsWith("+")) {
|
|
11978
12013
|
warn2(
|
|
11979
12014
|
lineNumber,
|
|
@@ -12360,15 +12395,15 @@ function parseGantt(content, palette) {
|
|
|
12360
12395
|
metaAliasMap,
|
|
12361
12396
|
() => warn2(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
12362
12397
|
);
|
|
12363
|
-
if (meta
|
|
12364
|
-
const key = meta
|
|
12398
|
+
if (meta["lag"] || meta["lead"]) {
|
|
12399
|
+
const key = meta["lag"] ? "lag" : "lead";
|
|
12365
12400
|
softError(
|
|
12366
12401
|
lineNumber,
|
|
12367
12402
|
`"${key}" is no longer supported \u2014 use "offset: ${meta[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
12368
12403
|
);
|
|
12369
12404
|
}
|
|
12370
|
-
if (meta
|
|
12371
|
-
const raw = meta
|
|
12405
|
+
if (meta["offset"]) {
|
|
12406
|
+
const raw = meta["offset"];
|
|
12372
12407
|
if (raw.trim().startsWith("+")) {
|
|
12373
12408
|
warn2(
|
|
12374
12409
|
lineNumber,
|
|
@@ -12439,9 +12474,9 @@ function parseGantt(content, palette) {
|
|
|
12439
12474
|
() => warn2(ln, MULTIPLE_PIPE_ERROR)
|
|
12440
12475
|
) : {};
|
|
12441
12476
|
let progress = null;
|
|
12442
|
-
if (metadata
|
|
12443
|
-
progress = parseFloat(metadata
|
|
12444
|
-
delete metadata
|
|
12477
|
+
if (metadata["progress"]) {
|
|
12478
|
+
progress = parseFloat(metadata["progress"]);
|
|
12479
|
+
delete metadata["progress"];
|
|
12445
12480
|
}
|
|
12446
12481
|
for (const part of segments.slice(1).join(",").split(",")) {
|
|
12447
12482
|
const seg = part.trim();
|
|
@@ -12450,16 +12485,16 @@ function parseGantt(content, palette) {
|
|
|
12450
12485
|
progress = parseInt(progressMatch[1], 10);
|
|
12451
12486
|
}
|
|
12452
12487
|
}
|
|
12453
|
-
if (metadata
|
|
12454
|
-
const key = metadata
|
|
12488
|
+
if (metadata["lag"] || metadata["lead"]) {
|
|
12489
|
+
const key = metadata["lag"] ? "lag" : "lead";
|
|
12455
12490
|
softError(
|
|
12456
12491
|
ln,
|
|
12457
12492
|
`"${key}" is no longer supported \u2014 use "offset: ${metadata[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
12458
12493
|
);
|
|
12459
12494
|
}
|
|
12460
12495
|
let taskOffset;
|
|
12461
|
-
if (metadata
|
|
12462
|
-
const raw = metadata
|
|
12496
|
+
if (metadata["offset"]) {
|
|
12497
|
+
const raw = metadata["offset"];
|
|
12463
12498
|
if (raw.trim().startsWith("+")) {
|
|
12464
12499
|
warn2(
|
|
12465
12500
|
ln,
|
|
@@ -12474,7 +12509,7 @@ function parseGantt(content, palette) {
|
|
|
12474
12509
|
);
|
|
12475
12510
|
}
|
|
12476
12511
|
}
|
|
12477
|
-
delete metadata
|
|
12512
|
+
delete metadata["offset"];
|
|
12478
12513
|
}
|
|
12479
12514
|
const groupPath = currentGroupPath();
|
|
12480
12515
|
const inheritedMeta = {};
|
|
@@ -12997,7 +13032,7 @@ function parsePert(content, parseOpts = {}) {
|
|
|
12997
13032
|
id,
|
|
12998
13033
|
name,
|
|
12999
13034
|
activityIds: [],
|
|
13000
|
-
collapsed: meta
|
|
13035
|
+
collapsed: meta["collapsed"] === "true",
|
|
13001
13036
|
lineNumber,
|
|
13002
13037
|
...Object.keys(tags).length > 0 && { tags }
|
|
13003
13038
|
});
|
|
@@ -13259,7 +13294,7 @@ function parsePert(content, parseOpts = {}) {
|
|
|
13259
13294
|
name: decl.name,
|
|
13260
13295
|
...decl.alias !== void 0 && { alias: decl.alias },
|
|
13261
13296
|
duration: estimate,
|
|
13262
|
-
...meta
|
|
13297
|
+
...meta["confidence"] && { confidence: meta["confidence"] },
|
|
13263
13298
|
...decl.groupHint !== void 0 && { groupId: decl.groupHint },
|
|
13264
13299
|
lineNumber: decl.lineNumber,
|
|
13265
13300
|
isMilestone,
|
|
@@ -14590,7 +14625,7 @@ function parseMindmap(content, palette) {
|
|
|
14590
14625
|
}
|
|
14591
14626
|
return result;
|
|
14592
14627
|
}
|
|
14593
|
-
function parseNodeLine2(trimmed, lineNumber,
|
|
14628
|
+
function parseNodeLine2(trimmed, lineNumber, _palette, counter, aliasMap, warnFn) {
|
|
14594
14629
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
14595
14630
|
const label = segments[0];
|
|
14596
14631
|
const metadata = parsePipeMetadata(
|
|
@@ -15034,7 +15069,7 @@ function parseWireframe(content) {
|
|
|
15034
15069
|
wrapper.isContainer = true;
|
|
15035
15070
|
wrapper.orientation = "horizontal";
|
|
15036
15071
|
wrapper.children = children;
|
|
15037
|
-
wrapper.metadata
|
|
15072
|
+
wrapper.metadata["_inlineRow"] = "true";
|
|
15038
15073
|
pushElement(wrapper);
|
|
15039
15074
|
}
|
|
15040
15075
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -15185,7 +15220,7 @@ function parseWireframe(content) {
|
|
|
15185
15220
|
wrapper.isContainer = true;
|
|
15186
15221
|
wrapper.orientation = "horizontal";
|
|
15187
15222
|
wrapper.children.push(labelEl, fieldEl);
|
|
15188
|
-
wrapper.metadata
|
|
15223
|
+
wrapper.metadata["_labelField"] = "true";
|
|
15189
15224
|
pushElement(wrapper);
|
|
15190
15225
|
}
|
|
15191
15226
|
} else {
|
|
@@ -17006,9 +17041,9 @@ function parseRaci(content, palette) {
|
|
|
17006
17041
|
let roleColor;
|
|
17007
17042
|
if (segments.length > 1) {
|
|
17008
17043
|
const meta = parsePipeMetadata(segments);
|
|
17009
|
-
if (meta
|
|
17044
|
+
if (meta["color"]) {
|
|
17010
17045
|
roleColor = resolveColorWithDiagnostic(
|
|
17011
|
-
meta
|
|
17046
|
+
meta["color"],
|
|
17012
17047
|
j + 1,
|
|
17013
17048
|
result.diagnostics,
|
|
17014
17049
|
palette
|
|
@@ -17075,9 +17110,9 @@ function parseRaci(content, palette) {
|
|
|
17075
17110
|
let phaseColor;
|
|
17076
17111
|
if (phaseMatch[2]) {
|
|
17077
17112
|
const meta = parsePipeMetadata(["", phaseMatch[2]]);
|
|
17078
|
-
if (meta
|
|
17113
|
+
if (meta["color"]) {
|
|
17079
17114
|
phaseColor = resolveColorWithDiagnostic(
|
|
17080
|
-
meta
|
|
17115
|
+
meta["color"],
|
|
17081
17116
|
lineNumber,
|
|
17082
17117
|
result.diagnostics,
|
|
17083
17118
|
palette
|
|
@@ -19087,7 +19122,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
19087
19122
|
displayNames.set(group.name.toLowerCase(), group.name);
|
|
19088
19123
|
}
|
|
19089
19124
|
const rootNodeIds = new Set(parsed.roots.map((r) => r.id));
|
|
19090
|
-
const colorOff = parsed.options?.color === "off";
|
|
19125
|
+
const colorOff = parsed.options?.["color"] === "off";
|
|
19091
19126
|
for (const c of layout.containers) {
|
|
19092
19127
|
const cG = contentG.append("g").attr("transform", `translate(${c.x}, ${c.y})`).attr("class", "org-container").attr("data-line-number", String(c.lineNumber));
|
|
19093
19128
|
if (activeTagGroup) {
|
|
@@ -22188,7 +22223,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
|
|
|
22188
22223
|
const seriesColors2 = getSeriesColors(palette);
|
|
22189
22224
|
const semanticRoles = useSemanticColors ? classifyEREntities(parsed.tables, parsed.relationships) : null;
|
|
22190
22225
|
const semanticActive = semanticRoles !== null && (semanticColorsActive ?? true);
|
|
22191
|
-
const useLabels = parsed.options
|
|
22226
|
+
const useLabels = parsed.options["notation"] === "labels";
|
|
22192
22227
|
for (const edge of layout.edges) {
|
|
22193
22228
|
if (edge.points.length < 2) continue;
|
|
22194
22229
|
const edgeG = contentG.append("g").attr("class", "er-edge-group").attr("data-line-number", String(edge.lineNumber));
|
|
@@ -22401,495 +22436,6 @@ var init_renderer5 = __esm({
|
|
|
22401
22436
|
}
|
|
22402
22437
|
});
|
|
22403
22438
|
|
|
22404
|
-
// src/boxes-and-lines/layout.ts
|
|
22405
|
-
var layout_exports5 = {};
|
|
22406
|
-
__export(layout_exports5, {
|
|
22407
|
-
layoutBoxesAndLines: () => layoutBoxesAndLines
|
|
22408
|
-
});
|
|
22409
|
-
import dagre4 from "@dagrejs/dagre";
|
|
22410
|
-
function clipToRectBorder2(cx, cy, w, h, tx, ty) {
|
|
22411
|
-
const dx = tx - cx;
|
|
22412
|
-
const dy = ty - cy;
|
|
22413
|
-
if (dx === 0 && dy === 0) return { x: cx, y: cy };
|
|
22414
|
-
const hw = w / 2;
|
|
22415
|
-
const hh = h / 2;
|
|
22416
|
-
const sx = dx !== 0 ? hw / Math.abs(dx) : Infinity;
|
|
22417
|
-
const sy = dy !== 0 ? hh / Math.abs(dy) : Infinity;
|
|
22418
|
-
const s = Math.min(sx, sy);
|
|
22419
|
-
return { x: cx + dx * s, y: cy + dy * s };
|
|
22420
|
-
}
|
|
22421
|
-
function splitCamelCase(word) {
|
|
22422
|
-
const parts = [];
|
|
22423
|
-
let start = 0;
|
|
22424
|
-
for (let i = 1; i < word.length; i++) {
|
|
22425
|
-
const prev = word[i - 1];
|
|
22426
|
-
const curr = word[i];
|
|
22427
|
-
const next = i + 1 < word.length ? word[i + 1] : "";
|
|
22428
|
-
const lowerToUpper = prev >= "a" && prev <= "z" && curr >= "A" && curr <= "Z";
|
|
22429
|
-
const upperRunEnd = prev >= "A" && prev <= "Z" && curr >= "A" && curr <= "Z" && next >= "a" && next <= "z";
|
|
22430
|
-
if (lowerToUpper || upperRunEnd) {
|
|
22431
|
-
parts.push(word.slice(start, i));
|
|
22432
|
-
start = i;
|
|
22433
|
-
}
|
|
22434
|
-
}
|
|
22435
|
-
parts.push(word.slice(start));
|
|
22436
|
-
return parts.length > 1 ? parts : [word];
|
|
22437
|
-
}
|
|
22438
|
-
function estimateLabelLines(label, nodeWidth2 = NODE_WIDTH) {
|
|
22439
|
-
const rawParts = label.split(/[\s-]+/);
|
|
22440
|
-
const words = [];
|
|
22441
|
-
for (const part of rawParts) {
|
|
22442
|
-
if (!part) continue;
|
|
22443
|
-
words.push(...splitCamelCase(part));
|
|
22444
|
-
}
|
|
22445
|
-
for (let fontSize = 13; fontSize >= 9; fontSize--) {
|
|
22446
|
-
const charWidth = fontSize * 0.6;
|
|
22447
|
-
const maxChars = Math.floor((nodeWidth2 - 24) / charWidth);
|
|
22448
|
-
if (maxChars < 2) continue;
|
|
22449
|
-
let lines = 1;
|
|
22450
|
-
let current = "";
|
|
22451
|
-
for (const word of words) {
|
|
22452
|
-
const test = current ? `${current} ${word}` : word;
|
|
22453
|
-
if (test.length <= maxChars) {
|
|
22454
|
-
current = test;
|
|
22455
|
-
} else {
|
|
22456
|
-
lines++;
|
|
22457
|
-
current = word;
|
|
22458
|
-
}
|
|
22459
|
-
}
|
|
22460
|
-
if (lines <= MAX_LABEL_LINES) return Math.min(lines, MAX_LABEL_LINES);
|
|
22461
|
-
}
|
|
22462
|
-
return MAX_LABEL_LINES;
|
|
22463
|
-
}
|
|
22464
|
-
function computeNodeSize(node) {
|
|
22465
|
-
if (!node.description || node.description.length === 0) {
|
|
22466
|
-
return { width: NODE_WIDTH, height: NODE_HEIGHT };
|
|
22467
|
-
}
|
|
22468
|
-
const w = DESC_NODE_WIDTH;
|
|
22469
|
-
const labelLines = estimateLabelLines(node.label, w);
|
|
22470
|
-
const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT + LABEL_PAD;
|
|
22471
|
-
const charsPerLine = Math.floor((w - 24) / (DESC_FONT_SIZE * 0.6));
|
|
22472
|
-
let totalRenderedLines = 0;
|
|
22473
|
-
for (const line12 of node.description) {
|
|
22474
|
-
if (line12.length <= charsPerLine) {
|
|
22475
|
-
totalRenderedLines += 1;
|
|
22476
|
-
} else {
|
|
22477
|
-
const words = line12.split(/\s+/);
|
|
22478
|
-
let current = "";
|
|
22479
|
-
let lineCount = 0;
|
|
22480
|
-
for (const word of words) {
|
|
22481
|
-
const fitted = word.length > charsPerLine ? word.slice(0, charsPerLine) : word;
|
|
22482
|
-
const test = current ? `${current} ${fitted}` : fitted;
|
|
22483
|
-
if (test.length <= charsPerLine) {
|
|
22484
|
-
current = test;
|
|
22485
|
-
} else {
|
|
22486
|
-
if (current) lineCount++;
|
|
22487
|
-
current = fitted;
|
|
22488
|
-
}
|
|
22489
|
-
}
|
|
22490
|
-
if (current) lineCount++;
|
|
22491
|
-
totalRenderedLines += lineCount;
|
|
22492
|
-
}
|
|
22493
|
-
}
|
|
22494
|
-
totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES);
|
|
22495
|
-
const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE * DESC_LINE_HEIGHT;
|
|
22496
|
-
const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING;
|
|
22497
|
-
return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
|
|
22498
|
-
}
|
|
22499
|
-
function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
|
|
22500
|
-
const hideDescriptions = layoutOptions?.hideDescriptions ?? false;
|
|
22501
|
-
const g = new dagre4.graphlib.Graph({ compound: true, multigraph: true });
|
|
22502
|
-
g.setGraph({
|
|
22503
|
-
rankdir: parsed.direction,
|
|
22504
|
-
nodesep: NODESEP,
|
|
22505
|
-
ranksep: RANKSEP,
|
|
22506
|
-
marginx: MARGIN3,
|
|
22507
|
-
marginy: MARGIN3
|
|
22508
|
-
});
|
|
22509
|
-
g.setDefaultEdgeLabel(() => ({}));
|
|
22510
|
-
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
22511
|
-
if (collapseInfo) {
|
|
22512
|
-
const missingGroups = /* @__PURE__ */ new Set();
|
|
22513
|
-
for (const og of collapseInfo.originalGroups) {
|
|
22514
|
-
if (!parsed.groups.some((g2) => g2.label === og.label)) {
|
|
22515
|
-
missingGroups.add(og.label);
|
|
22516
|
-
}
|
|
22517
|
-
}
|
|
22518
|
-
for (const label of missingGroups) {
|
|
22519
|
-
const og = collapseInfo.originalGroups.find((g2) => g2.label === label);
|
|
22520
|
-
const parentLabel = og?.parentGroup;
|
|
22521
|
-
if (!parentLabel || !missingGroups.has(parentLabel)) {
|
|
22522
|
-
collapsedGroupLabels.add(label);
|
|
22523
|
-
}
|
|
22524
|
-
}
|
|
22525
|
-
}
|
|
22526
|
-
for (const label of collapsedGroupLabels) {
|
|
22527
|
-
const gid = `__group_${label}`;
|
|
22528
|
-
g.setNode(gid, { label, width: NODE_WIDTH, height: NODE_HEIGHT });
|
|
22529
|
-
}
|
|
22530
|
-
for (const group of parsed.groups) {
|
|
22531
|
-
const gid = `__group_${group.label}`;
|
|
22532
|
-
g.setNode(gid, {
|
|
22533
|
-
label: group.label,
|
|
22534
|
-
paddingLeft: CONTAINER_PAD_X3,
|
|
22535
|
-
paddingRight: CONTAINER_PAD_X3,
|
|
22536
|
-
paddingTop: CONTAINER_PAD_TOP2,
|
|
22537
|
-
paddingBottom: CONTAINER_PAD_BOTTOM3
|
|
22538
|
-
});
|
|
22539
|
-
}
|
|
22540
|
-
const originalGroupByLabel = /* @__PURE__ */ new Map();
|
|
22541
|
-
if (collapseInfo) {
|
|
22542
|
-
for (const og of collapseInfo.originalGroups) {
|
|
22543
|
-
originalGroupByLabel.set(og.label, og);
|
|
22544
|
-
}
|
|
22545
|
-
}
|
|
22546
|
-
for (const label of collapsedGroupLabels) {
|
|
22547
|
-
const og = originalGroupByLabel.get(label);
|
|
22548
|
-
if (og?.parentGroup && !collapsedGroupLabels.has(og.parentGroup)) {
|
|
22549
|
-
const gid = `__group_${label}`;
|
|
22550
|
-
const parentGid = `__group_${og.parentGroup}`;
|
|
22551
|
-
if (g.hasNode(parentGid)) {
|
|
22552
|
-
g.setParent(gid, parentGid);
|
|
22553
|
-
}
|
|
22554
|
-
}
|
|
22555
|
-
}
|
|
22556
|
-
const nodeSizes = /* @__PURE__ */ new Map();
|
|
22557
|
-
let maxDescHeight = 0;
|
|
22558
|
-
for (const node of parsed.nodes) {
|
|
22559
|
-
const size = hideDescriptions ? { width: NODE_WIDTH, height: NODE_HEIGHT } : computeNodeSize(node);
|
|
22560
|
-
nodeSizes.set(node.label, size);
|
|
22561
|
-
if (!hideDescriptions && node.description && node.description.length > 0) {
|
|
22562
|
-
maxDescHeight = Math.max(maxDescHeight, size.height);
|
|
22563
|
-
}
|
|
22564
|
-
}
|
|
22565
|
-
if (maxDescHeight > 0) {
|
|
22566
|
-
for (const node of parsed.nodes) {
|
|
22567
|
-
if (node.description && node.description.length > 0) {
|
|
22568
|
-
const size = nodeSizes.get(node.label);
|
|
22569
|
-
nodeSizes.set(node.label, { width: size.width, height: maxDescHeight });
|
|
22570
|
-
}
|
|
22571
|
-
}
|
|
22572
|
-
}
|
|
22573
|
-
for (const node of parsed.nodes) {
|
|
22574
|
-
const size = nodeSizes.get(node.label);
|
|
22575
|
-
g.setNode(node.label, {
|
|
22576
|
-
label: node.label,
|
|
22577
|
-
width: size.width,
|
|
22578
|
-
height: size.height
|
|
22579
|
-
});
|
|
22580
|
-
}
|
|
22581
|
-
for (const group of parsed.groups) {
|
|
22582
|
-
if (group.parentGroup) {
|
|
22583
|
-
const childGid = `__group_${group.label}`;
|
|
22584
|
-
const parentGid = `__group_${group.parentGroup}`;
|
|
22585
|
-
if (g.hasNode(childGid) && g.hasNode(parentGid)) {
|
|
22586
|
-
g.setParent(childGid, parentGid);
|
|
22587
|
-
}
|
|
22588
|
-
}
|
|
22589
|
-
}
|
|
22590
|
-
const groupLabelSet = new Set(parsed.groups.map((gr) => gr.label));
|
|
22591
|
-
for (const group of parsed.groups) {
|
|
22592
|
-
const gid = `__group_${group.label}`;
|
|
22593
|
-
for (const child of group.children) {
|
|
22594
|
-
if (groupLabelSet.has(child)) continue;
|
|
22595
|
-
if (g.hasNode(child)) {
|
|
22596
|
-
g.setParent(child, gid);
|
|
22597
|
-
}
|
|
22598
|
-
}
|
|
22599
|
-
}
|
|
22600
|
-
const expandedGroupIds = /* @__PURE__ */ new Set();
|
|
22601
|
-
for (const group of parsed.groups) {
|
|
22602
|
-
expandedGroupIds.add(`__group_${group.label}`);
|
|
22603
|
-
}
|
|
22604
|
-
const groupFirstChild = /* @__PURE__ */ new Map();
|
|
22605
|
-
for (const group of parsed.groups) {
|
|
22606
|
-
const gid = `__group_${group.label}`;
|
|
22607
|
-
const firstChild = group.children.find(
|
|
22608
|
-
(c) => !groupLabelSet.has(c) && g.hasNode(c)
|
|
22609
|
-
);
|
|
22610
|
-
if (firstChild) {
|
|
22611
|
-
groupFirstChild.set(gid, firstChild);
|
|
22612
|
-
}
|
|
22613
|
-
}
|
|
22614
|
-
const deferredEdgeIndices = [];
|
|
22615
|
-
let proxyIdx = 0;
|
|
22616
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22617
|
-
const edge = parsed.edges[i];
|
|
22618
|
-
const src = edge.source;
|
|
22619
|
-
const tgt = edge.target;
|
|
22620
|
-
if (!g.hasNode(src) || !g.hasNode(tgt)) continue;
|
|
22621
|
-
if (expandedGroupIds.has(src) || expandedGroupIds.has(tgt)) {
|
|
22622
|
-
deferredEdgeIndices.push(i);
|
|
22623
|
-
const proxySrc = expandedGroupIds.has(src) ? groupFirstChild.get(src) : src;
|
|
22624
|
-
const proxyTgt = expandedGroupIds.has(tgt) ? groupFirstChild.get(tgt) : tgt;
|
|
22625
|
-
if (proxySrc && proxyTgt && proxySrc !== proxyTgt) {
|
|
22626
|
-
g.setEdge(
|
|
22627
|
-
proxySrc,
|
|
22628
|
-
proxyTgt,
|
|
22629
|
-
{ label: "", minlen: 1 },
|
|
22630
|
-
`proxy${proxyIdx++}`
|
|
22631
|
-
);
|
|
22632
|
-
}
|
|
22633
|
-
continue;
|
|
22634
|
-
}
|
|
22635
|
-
g.setEdge(src, tgt, { label: edge.label ?? "", minlen: 1 }, `e${i}`);
|
|
22636
|
-
}
|
|
22637
|
-
dagre4.layout(g);
|
|
22638
|
-
const layoutNodes = [];
|
|
22639
|
-
for (const node of parsed.nodes) {
|
|
22640
|
-
const dagreNode = g.node(node.label);
|
|
22641
|
-
if (!dagreNode) continue;
|
|
22642
|
-
layoutNodes.push({
|
|
22643
|
-
label: node.label,
|
|
22644
|
-
x: dagreNode.x,
|
|
22645
|
-
y: dagreNode.y,
|
|
22646
|
-
width: dagreNode.width,
|
|
22647
|
-
height: dagreNode.height
|
|
22648
|
-
});
|
|
22649
|
-
}
|
|
22650
|
-
const layoutGroups = [];
|
|
22651
|
-
for (const group of parsed.groups) {
|
|
22652
|
-
const gid = `__group_${group.label}`;
|
|
22653
|
-
const dagreNode = g.node(gid);
|
|
22654
|
-
if (!dagreNode) continue;
|
|
22655
|
-
layoutGroups.push({
|
|
22656
|
-
label: group.label,
|
|
22657
|
-
lineNumber: group.lineNumber,
|
|
22658
|
-
x: dagreNode.x,
|
|
22659
|
-
y: dagreNode.y,
|
|
22660
|
-
width: dagreNode.width,
|
|
22661
|
-
height: dagreNode.height,
|
|
22662
|
-
collapsed: false
|
|
22663
|
-
});
|
|
22664
|
-
}
|
|
22665
|
-
for (const label of collapsedGroupLabels) {
|
|
22666
|
-
const gid = `__group_${label}`;
|
|
22667
|
-
const dagreNode = g.node(gid);
|
|
22668
|
-
if (!dagreNode) continue;
|
|
22669
|
-
const og = collapseInfo?.originalGroups.find((g2) => g2.label === label);
|
|
22670
|
-
layoutGroups.push({
|
|
22671
|
-
label,
|
|
22672
|
-
lineNumber: og?.lineNumber ?? 0,
|
|
22673
|
-
x: dagreNode.x,
|
|
22674
|
-
y: dagreNode.y,
|
|
22675
|
-
width: dagreNode.width,
|
|
22676
|
-
height: dagreNode.height,
|
|
22677
|
-
collapsed: true,
|
|
22678
|
-
childCount: collapseInfo?.collapsedChildCounts.get(label) ?? 0
|
|
22679
|
-
});
|
|
22680
|
-
}
|
|
22681
|
-
const groupAlignShifts = /* @__PURE__ */ new Map();
|
|
22682
|
-
{
|
|
22683
|
-
const groupEdges = [];
|
|
22684
|
-
for (const edge of parsed.edges) {
|
|
22685
|
-
if (edge.source.startsWith("__group_") && edge.target.startsWith("__group_")) {
|
|
22686
|
-
groupEdges.push(edge);
|
|
22687
|
-
}
|
|
22688
|
-
}
|
|
22689
|
-
if (groupEdges.length > 0) {
|
|
22690
|
-
const groupParent = /* @__PURE__ */ new Map();
|
|
22691
|
-
const find = (x) => {
|
|
22692
|
-
while (groupParent.has(x) && groupParent.get(x) !== x) {
|
|
22693
|
-
groupParent.set(x, groupParent.get(groupParent.get(x)));
|
|
22694
|
-
x = groupParent.get(x);
|
|
22695
|
-
}
|
|
22696
|
-
return x;
|
|
22697
|
-
};
|
|
22698
|
-
const union = (a, b) => {
|
|
22699
|
-
const ra = find(a), rb = find(b);
|
|
22700
|
-
if (ra !== rb) groupParent.set(ra, rb);
|
|
22701
|
-
};
|
|
22702
|
-
for (const edge of groupEdges) {
|
|
22703
|
-
if (!groupParent.has(edge.source))
|
|
22704
|
-
groupParent.set(edge.source, edge.source);
|
|
22705
|
-
if (!groupParent.has(edge.target))
|
|
22706
|
-
groupParent.set(edge.target, edge.target);
|
|
22707
|
-
union(edge.source, edge.target);
|
|
22708
|
-
}
|
|
22709
|
-
const components = /* @__PURE__ */ new Map();
|
|
22710
|
-
for (const lg of layoutGroups) {
|
|
22711
|
-
const gid = `__group_${lg.label}`;
|
|
22712
|
-
if (!groupParent.has(gid)) continue;
|
|
22713
|
-
const root = find(gid);
|
|
22714
|
-
if (!components.has(root)) components.set(root, []);
|
|
22715
|
-
components.get(root).push(lg);
|
|
22716
|
-
}
|
|
22717
|
-
const axis = parsed.direction === "TB" ? "x" : "y";
|
|
22718
|
-
for (const groups of components.values()) {
|
|
22719
|
-
if (groups.length < 2) continue;
|
|
22720
|
-
const dim = axis === "x" ? "width" : "height";
|
|
22721
|
-
let widest = groups[0];
|
|
22722
|
-
for (const g2 of groups) {
|
|
22723
|
-
if (g2[dim] > widest[dim]) widest = g2;
|
|
22724
|
-
}
|
|
22725
|
-
const targetCenter = widest[axis];
|
|
22726
|
-
for (const grp of groups) {
|
|
22727
|
-
const dx = targetCenter - grp[axis];
|
|
22728
|
-
if (dx === 0) continue;
|
|
22729
|
-
grp[axis] += dx;
|
|
22730
|
-
groupAlignShifts.set(`__group_${grp.label}`, dx);
|
|
22731
|
-
const parsedGroup = parsed.groups.find(
|
|
22732
|
-
(pg) => pg.label === grp.label
|
|
22733
|
-
);
|
|
22734
|
-
if (parsedGroup) {
|
|
22735
|
-
for (const childLabel of parsedGroup.children) {
|
|
22736
|
-
const childNode = layoutNodes.find((n) => n.label === childLabel);
|
|
22737
|
-
if (childNode) childNode[axis] += dx;
|
|
22738
|
-
}
|
|
22739
|
-
}
|
|
22740
|
-
}
|
|
22741
|
-
}
|
|
22742
|
-
}
|
|
22743
|
-
}
|
|
22744
|
-
const edgeYOffsets = new Array(parsed.edges.length).fill(0);
|
|
22745
|
-
const edgeParallelCounts = new Array(parsed.edges.length).fill(1);
|
|
22746
|
-
const parallelGroups = /* @__PURE__ */ new Map();
|
|
22747
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22748
|
-
const edge = parsed.edges[i];
|
|
22749
|
-
const [a, b] = edge.source < edge.target ? [edge.source, edge.target] : [edge.target, edge.source];
|
|
22750
|
-
const key = `${a}\0${b}`;
|
|
22751
|
-
if (!parallelGroups.has(key)) parallelGroups.set(key, []);
|
|
22752
|
-
parallelGroups.get(key).push(i);
|
|
22753
|
-
}
|
|
22754
|
-
for (const group of parallelGroups.values()) {
|
|
22755
|
-
const capped = group.slice(0, MAX_PARALLEL_EDGES);
|
|
22756
|
-
for (const idx of group.slice(MAX_PARALLEL_EDGES)) {
|
|
22757
|
-
edgeParallelCounts[idx] = 0;
|
|
22758
|
-
}
|
|
22759
|
-
if (capped.length < 2) continue;
|
|
22760
|
-
const effectiveSpacing = PARALLEL_SPACING;
|
|
22761
|
-
for (let j = 0; j < capped.length; j++) {
|
|
22762
|
-
edgeYOffsets[capped[j]] = (j - (capped.length - 1) / 2) * effectiveSpacing;
|
|
22763
|
-
edgeParallelCounts[capped[j]] = capped.length;
|
|
22764
|
-
}
|
|
22765
|
-
}
|
|
22766
|
-
const deferredSet = new Set(deferredEdgeIndices);
|
|
22767
|
-
const layoutEdges = [];
|
|
22768
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22769
|
-
const edge = parsed.edges[i];
|
|
22770
|
-
if (edgeParallelCounts[i] === 0) continue;
|
|
22771
|
-
let points;
|
|
22772
|
-
if (deferredSet.has(i)) {
|
|
22773
|
-
const srcLayout = layoutGroups.find(
|
|
22774
|
-
(lg) => `__group_${lg.label}` === edge.source
|
|
22775
|
-
);
|
|
22776
|
-
const tgtLayout = layoutGroups.find(
|
|
22777
|
-
(lg) => `__group_${lg.label}` === edge.target
|
|
22778
|
-
);
|
|
22779
|
-
if (!srcLayout || !tgtLayout) {
|
|
22780
|
-
const srcNode = g.node(edge.source);
|
|
22781
|
-
const tgtNode = g.node(edge.target);
|
|
22782
|
-
if (!srcNode || !tgtNode) continue;
|
|
22783
|
-
const srcPt = clipToRectBorder2(
|
|
22784
|
-
srcNode.x,
|
|
22785
|
-
srcNode.y,
|
|
22786
|
-
srcNode.width,
|
|
22787
|
-
srcNode.height,
|
|
22788
|
-
tgtNode.x,
|
|
22789
|
-
tgtNode.y
|
|
22790
|
-
);
|
|
22791
|
-
const tgtPt = clipToRectBorder2(
|
|
22792
|
-
tgtNode.x,
|
|
22793
|
-
tgtNode.y,
|
|
22794
|
-
tgtNode.width,
|
|
22795
|
-
tgtNode.height,
|
|
22796
|
-
srcNode.x,
|
|
22797
|
-
srcNode.y
|
|
22798
|
-
);
|
|
22799
|
-
const midX = (srcPt.x + tgtPt.x) / 2;
|
|
22800
|
-
const midY = (srcPt.y + tgtPt.y) / 2;
|
|
22801
|
-
points = [srcPt, { x: midX, y: midY }, tgtPt];
|
|
22802
|
-
} else if (parsed.direction === "TB") {
|
|
22803
|
-
const cx = (srcLayout.x + tgtLayout.x) / 2;
|
|
22804
|
-
const srcPt = { x: cx, y: srcLayout.y + srcLayout.height / 2 };
|
|
22805
|
-
const tgtPt = { x: cx, y: tgtLayout.y - tgtLayout.height / 2 };
|
|
22806
|
-
const midY = (srcPt.y + tgtPt.y) / 2;
|
|
22807
|
-
points = [srcPt, { x: cx, y: midY }, tgtPt];
|
|
22808
|
-
} else {
|
|
22809
|
-
const cy = (srcLayout.y + tgtLayout.y) / 2;
|
|
22810
|
-
const srcPt = { x: srcLayout.x + srcLayout.width / 2, y: cy };
|
|
22811
|
-
const tgtPt = { x: tgtLayout.x - tgtLayout.width / 2, y: cy };
|
|
22812
|
-
const midX = (srcPt.x + tgtPt.x) / 2;
|
|
22813
|
-
points = [srcPt, { x: midX, y: cy }, tgtPt];
|
|
22814
|
-
}
|
|
22815
|
-
} else {
|
|
22816
|
-
const dagreEdge = g.edge(edge.source, edge.target, `e${i}`);
|
|
22817
|
-
points = dagreEdge?.points ?? [];
|
|
22818
|
-
const srcShift = groupAlignShifts.get(edge.source) ?? 0;
|
|
22819
|
-
const tgtShift = groupAlignShifts.get(edge.target) ?? 0;
|
|
22820
|
-
if (srcShift !== 0 || tgtShift !== 0) {
|
|
22821
|
-
const avgShift = (srcShift + tgtShift) / 2;
|
|
22822
|
-
const prop = parsed.direction === "TB" ? "x" : "y";
|
|
22823
|
-
points = points.map((p) => ({ ...p, [prop]: p[prop] + avgShift }));
|
|
22824
|
-
}
|
|
22825
|
-
}
|
|
22826
|
-
let labelX;
|
|
22827
|
-
let labelY;
|
|
22828
|
-
if (edge.label && points.length >= 2) {
|
|
22829
|
-
const mid = Math.floor(points.length / 2);
|
|
22830
|
-
labelX = points[mid].x;
|
|
22831
|
-
labelY = points[mid].y - 10;
|
|
22832
|
-
}
|
|
22833
|
-
layoutEdges.push({
|
|
22834
|
-
source: edge.source,
|
|
22835
|
-
target: edge.target,
|
|
22836
|
-
label: edge.label,
|
|
22837
|
-
bidirectional: edge.bidirectional,
|
|
22838
|
-
lineNumber: edge.lineNumber,
|
|
22839
|
-
points,
|
|
22840
|
-
labelX,
|
|
22841
|
-
labelY,
|
|
22842
|
-
yOffset: edgeYOffsets[i],
|
|
22843
|
-
parallelCount: edgeParallelCounts[i],
|
|
22844
|
-
metadata: edge.metadata,
|
|
22845
|
-
deferred: deferredSet.has(i) || void 0
|
|
22846
|
-
});
|
|
22847
|
-
}
|
|
22848
|
-
let maxX = 0;
|
|
22849
|
-
let maxY = 0;
|
|
22850
|
-
for (const node of layoutNodes) {
|
|
22851
|
-
maxX = Math.max(maxX, node.x + node.width / 2);
|
|
22852
|
-
maxY = Math.max(maxY, node.y + node.height / 2);
|
|
22853
|
-
}
|
|
22854
|
-
for (const group of layoutGroups) {
|
|
22855
|
-
maxX = Math.max(maxX, group.x + group.width / 2);
|
|
22856
|
-
maxY = Math.max(maxY, group.y + group.height / 2);
|
|
22857
|
-
}
|
|
22858
|
-
return {
|
|
22859
|
-
nodes: layoutNodes,
|
|
22860
|
-
edges: layoutEdges,
|
|
22861
|
-
groups: layoutGroups,
|
|
22862
|
-
width: maxX + MARGIN3,
|
|
22863
|
-
height: maxY + MARGIN3
|
|
22864
|
-
};
|
|
22865
|
-
}
|
|
22866
|
-
var NODESEP, RANKSEP, MARGIN3, CONTAINER_PAD_X3, CONTAINER_PAD_TOP2, CONTAINER_PAD_BOTTOM3, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE, DESC_LINE_HEIGHT, DESC_PADDING, SEPARATOR_GAP5, MAX_DESC_LINES, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, LABEL_PAD;
|
|
22867
|
-
var init_layout5 = __esm({
|
|
22868
|
-
"src/boxes-and-lines/layout.ts"() {
|
|
22869
|
-
"use strict";
|
|
22870
|
-
NODESEP = 60;
|
|
22871
|
-
RANKSEP = 100;
|
|
22872
|
-
MARGIN3 = 40;
|
|
22873
|
-
CONTAINER_PAD_X3 = 30;
|
|
22874
|
-
CONTAINER_PAD_TOP2 = 40;
|
|
22875
|
-
CONTAINER_PAD_BOTTOM3 = 24;
|
|
22876
|
-
MAX_PARALLEL_EDGES = 5;
|
|
22877
|
-
PARALLEL_SPACING = 22;
|
|
22878
|
-
PHI = 1.618;
|
|
22879
|
-
NODE_HEIGHT = 60;
|
|
22880
|
-
NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
|
|
22881
|
-
DESC_NODE_WIDTH = 140;
|
|
22882
|
-
DESC_FONT_SIZE = 10;
|
|
22883
|
-
DESC_LINE_HEIGHT = 1.4;
|
|
22884
|
-
DESC_PADDING = 8;
|
|
22885
|
-
SEPARATOR_GAP5 = 4;
|
|
22886
|
-
MAX_DESC_LINES = 6;
|
|
22887
|
-
MAX_LABEL_LINES = 3;
|
|
22888
|
-
LABEL_LINE_HEIGHT = 1.3;
|
|
22889
|
-
LABEL_PAD = 12;
|
|
22890
|
-
}
|
|
22891
|
-
});
|
|
22892
|
-
|
|
22893
22439
|
// src/utils/wrapped-desc.ts
|
|
22894
22440
|
function wrapDescriptionLines(lines, charsPerLine, lengthFn = (s) => s.length) {
|
|
22895
22441
|
const result = [];
|
|
@@ -22941,7 +22487,7 @@ __export(renderer_exports6, {
|
|
|
22941
22487
|
});
|
|
22942
22488
|
import * as d3Selection6 from "d3-selection";
|
|
22943
22489
|
import * as d3Shape4 from "d3-shape";
|
|
22944
|
-
function
|
|
22490
|
+
function splitCamelCase(word) {
|
|
22945
22491
|
const parts = [];
|
|
22946
22492
|
let start = 0;
|
|
22947
22493
|
for (let i = 1; i < word.length; i++) {
|
|
@@ -22964,7 +22510,7 @@ function fitLabelToHeader(label, nodeWidth2, maxLines) {
|
|
|
22964
22510
|
const words = [];
|
|
22965
22511
|
for (const part of rawParts) {
|
|
22966
22512
|
if (!part || /^\s+$/.test(part) || part === "-") continue;
|
|
22967
|
-
words.push(...
|
|
22513
|
+
words.push(...splitCamelCase(part));
|
|
22968
22514
|
}
|
|
22969
22515
|
for (let fontSize = NODE_FONT_SIZE; fontSize >= MIN_NODE_FONT_SIZE; fontSize--) {
|
|
22970
22516
|
const charWidth2 = fontSize * CHAR_WIDTH_RATIO2;
|
|
@@ -23340,12 +22886,12 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23340
22886
|
}
|
|
23341
22887
|
const sepY = -ln.height / 2 + headerH;
|
|
23342
22888
|
nodeG.append("line").attr("x1", -ln.width / 2).attr("y1", sepY).attr("x2", ln.width / 2).attr("y2", sepY).attr("stroke", colors.stroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
|
|
23343
|
-
const descStartY = sepY + 4 +
|
|
22889
|
+
const descStartY = sepY + 4 + DESC_FONT_SIZE;
|
|
23344
22890
|
const maxTextWidth = ln.width - NODE_TEXT_PADDING * 2;
|
|
23345
22891
|
const charsPerLine = Math.floor(
|
|
23346
|
-
maxTextWidth / (
|
|
22892
|
+
maxTextWidth / (DESC_FONT_SIZE * CHAR_WIDTH_RATIO2)
|
|
23347
22893
|
);
|
|
23348
|
-
const descLineH =
|
|
22894
|
+
const descLineH = DESC_FONT_SIZE * DESC_LINE_HEIGHT;
|
|
23349
22895
|
const displayLen = (text) => text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*(.+?)\*\*/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/`(.+?)`/g, "$1").replace(/https?:\/\/\S+/g, (u) => u.slice(0, 20)).length;
|
|
23350
22896
|
const normalizedLines = [];
|
|
23351
22897
|
for (const descLine of desc) {
|
|
@@ -23361,8 +22907,8 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23361
22907
|
charsPerLine,
|
|
23362
22908
|
displayLen
|
|
23363
22909
|
);
|
|
23364
|
-
const truncated = wrappedLinesShared.length >
|
|
23365
|
-
const visibleLines = truncated ? wrappedLinesShared.slice(0,
|
|
22910
|
+
const truncated = wrappedLinesShared.length > MAX_DESC_LINES;
|
|
22911
|
+
const visibleLines = truncated ? wrappedLinesShared.slice(0, MAX_DESC_LINES) : wrappedLinesShared;
|
|
23366
22912
|
const BULLET_GLYPH_X = -ln.width / 2 + 6;
|
|
23367
22913
|
const BULLET_BODY_X = BULLET_GLYPH_X + 10;
|
|
23368
22914
|
for (let li = 0; li < visibleLines.length; li++) {
|
|
@@ -23373,11 +22919,11 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23373
22919
|
}
|
|
23374
22920
|
const y2 = descStartY + li * descLineH;
|
|
23375
22921
|
if (line12.kind === "bullet-first") {
|
|
23376
|
-
nodeG.append("text").attr("x", BULLET_GLYPH_X).attr("y", y2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("font-size",
|
|
22922
|
+
nodeG.append("text").attr("x", BULLET_GLYPH_X).attr("y", y2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("font-size", DESC_FONT_SIZE).attr("fill", palette.textMuted).text("\u2022");
|
|
23377
22923
|
}
|
|
23378
22924
|
const isBullet = line12.kind === "bullet-first" || line12.kind === "bullet-cont";
|
|
23379
|
-
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",
|
|
23380
|
-
renderInlineText(textEl, lineText, palette,
|
|
22925
|
+
const textEl = nodeG.append("text").attr("x", isBullet ? BULLET_BODY_X : 0).attr("y", y2).attr("text-anchor", isBullet ? "start" : "middle").attr("dominant-baseline", "central").attr("font-size", DESC_FONT_SIZE).attr("fill", palette.textMuted);
|
|
22926
|
+
renderInlineText(textEl, lineText, palette, DESC_FONT_SIZE);
|
|
23381
22927
|
}
|
|
23382
22928
|
if (truncated) {
|
|
23383
22929
|
const fullText = desc.join(" ");
|
|
@@ -23455,7 +23001,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
|
|
|
23455
23001
|
hiddenTagValues: options?.hiddenTagValues
|
|
23456
23002
|
});
|
|
23457
23003
|
}
|
|
23458
|
-
var DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2,
|
|
23004
|
+
var DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, CHAR_WIDTH_RATIO2, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, lineGeneratorLR, lineGeneratorTB;
|
|
23459
23005
|
var init_renderer6 = __esm({
|
|
23460
23006
|
"src/boxes-and-lines/renderer.ts"() {
|
|
23461
23007
|
"use strict";
|
|
@@ -23477,9 +23023,9 @@ var init_renderer6 = __esm({
|
|
|
23477
23023
|
COLLAPSE_BAR_HEIGHT3 = 4;
|
|
23478
23024
|
ARROWHEAD_W2 = 5;
|
|
23479
23025
|
ARROWHEAD_H2 = 4;
|
|
23480
|
-
|
|
23481
|
-
|
|
23482
|
-
|
|
23026
|
+
DESC_FONT_SIZE = 10;
|
|
23027
|
+
DESC_LINE_HEIGHT = 1.4;
|
|
23028
|
+
MAX_DESC_LINES = 6;
|
|
23483
23029
|
CHAR_WIDTH_RATIO2 = 0.6;
|
|
23484
23030
|
NODE_TEXT_PADDING = 12;
|
|
23485
23031
|
GROUP_RX = 8;
|
|
@@ -23490,6 +23036,523 @@ var init_renderer6 = __esm({
|
|
|
23490
23036
|
}
|
|
23491
23037
|
});
|
|
23492
23038
|
|
|
23039
|
+
// src/boxes-and-lines/layout.ts
|
|
23040
|
+
var layout_exports5 = {};
|
|
23041
|
+
__export(layout_exports5, {
|
|
23042
|
+
layoutBoxesAndLines: () => layoutBoxesAndLines
|
|
23043
|
+
});
|
|
23044
|
+
import ELK from "elkjs/lib/elk.bundled.js";
|
|
23045
|
+
function splitCamelCase2(word) {
|
|
23046
|
+
const parts = [];
|
|
23047
|
+
let start = 0;
|
|
23048
|
+
for (let i = 1; i < word.length; i++) {
|
|
23049
|
+
const prev = word[i - 1];
|
|
23050
|
+
const curr = word[i];
|
|
23051
|
+
const next = i + 1 < word.length ? word[i + 1] : "";
|
|
23052
|
+
const lowerToUpper = prev >= "a" && prev <= "z" && curr >= "A" && curr <= "Z";
|
|
23053
|
+
const upperRunEnd = prev >= "A" && prev <= "Z" && curr >= "A" && curr <= "Z" && next >= "a" && next <= "z";
|
|
23054
|
+
if (lowerToUpper || upperRunEnd) {
|
|
23055
|
+
parts.push(word.slice(start, i));
|
|
23056
|
+
start = i;
|
|
23057
|
+
}
|
|
23058
|
+
}
|
|
23059
|
+
parts.push(word.slice(start));
|
|
23060
|
+
return parts.length > 1 ? parts : [word];
|
|
23061
|
+
}
|
|
23062
|
+
function estimateLabelLines(label, nodeWidth2 = NODE_WIDTH) {
|
|
23063
|
+
const rawParts = label.split(/[\s-]+/);
|
|
23064
|
+
const words = [];
|
|
23065
|
+
for (const part of rawParts) {
|
|
23066
|
+
if (!part) continue;
|
|
23067
|
+
words.push(...splitCamelCase2(part));
|
|
23068
|
+
}
|
|
23069
|
+
for (let fontSize = 13; fontSize >= 9; fontSize--) {
|
|
23070
|
+
const charWidth = fontSize * 0.6;
|
|
23071
|
+
const maxChars = Math.floor((nodeWidth2 - 24) / charWidth);
|
|
23072
|
+
if (maxChars < 2) continue;
|
|
23073
|
+
let lines = 1;
|
|
23074
|
+
let current = "";
|
|
23075
|
+
for (const word of words) {
|
|
23076
|
+
const test = current ? `${current} ${word}` : word;
|
|
23077
|
+
if (test.length <= maxChars) {
|
|
23078
|
+
current = test;
|
|
23079
|
+
} else {
|
|
23080
|
+
lines++;
|
|
23081
|
+
current = word;
|
|
23082
|
+
}
|
|
23083
|
+
}
|
|
23084
|
+
if (lines <= MAX_LABEL_LINES) return Math.min(lines, MAX_LABEL_LINES);
|
|
23085
|
+
}
|
|
23086
|
+
return MAX_LABEL_LINES;
|
|
23087
|
+
}
|
|
23088
|
+
function computeNodeSize(node) {
|
|
23089
|
+
if (!node.description || node.description.length === 0) {
|
|
23090
|
+
return { width: NODE_WIDTH, height: NODE_HEIGHT };
|
|
23091
|
+
}
|
|
23092
|
+
const w = DESC_NODE_WIDTH;
|
|
23093
|
+
const labelLines = estimateLabelLines(node.label, w);
|
|
23094
|
+
const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT + LABEL_PAD;
|
|
23095
|
+
const charsPerLine = Math.floor((w - 24) / (DESC_FONT_SIZE2 * 0.6));
|
|
23096
|
+
let totalRenderedLines = 0;
|
|
23097
|
+
for (const line12 of node.description) {
|
|
23098
|
+
if (line12.length <= charsPerLine) {
|
|
23099
|
+
totalRenderedLines += 1;
|
|
23100
|
+
} else {
|
|
23101
|
+
const words = line12.split(/\s+/);
|
|
23102
|
+
let current = "";
|
|
23103
|
+
let lineCount = 0;
|
|
23104
|
+
for (const word of words) {
|
|
23105
|
+
const fitted = word.length > charsPerLine ? word.slice(0, charsPerLine) : word;
|
|
23106
|
+
const test = current ? `${current} ${fitted}` : fitted;
|
|
23107
|
+
if (test.length <= charsPerLine) {
|
|
23108
|
+
current = test;
|
|
23109
|
+
} else {
|
|
23110
|
+
if (current) lineCount++;
|
|
23111
|
+
current = fitted;
|
|
23112
|
+
}
|
|
23113
|
+
}
|
|
23114
|
+
if (current) lineCount++;
|
|
23115
|
+
totalRenderedLines += lineCount;
|
|
23116
|
+
}
|
|
23117
|
+
}
|
|
23118
|
+
totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES2);
|
|
23119
|
+
const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE2 * DESC_LINE_HEIGHT2;
|
|
23120
|
+
const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING;
|
|
23121
|
+
return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
|
|
23122
|
+
}
|
|
23123
|
+
function getElk() {
|
|
23124
|
+
if (!elkInstance) elkInstance = new ELK();
|
|
23125
|
+
return elkInstance;
|
|
23126
|
+
}
|
|
23127
|
+
function baseOptions() {
|
|
23128
|
+
return {
|
|
23129
|
+
"elk.algorithm": "layered",
|
|
23130
|
+
// INCLUDE_CHILDREN lets ELK route edges across container boundaries.
|
|
23131
|
+
"elk.hierarchyHandling": "INCLUDE_CHILDREN",
|
|
23132
|
+
"elk.edgeRouting": "ORTHOGONAL",
|
|
23133
|
+
"elk.layered.unnecessaryBendpoints": "true",
|
|
23134
|
+
// Let edges leave from top/bottom of nodes (not just the flow-direction
|
|
23135
|
+
// sides) when it reduces crossings.
|
|
23136
|
+
"elk.layered.allowNonFlowPortsToSwitchSides": "true"
|
|
23137
|
+
};
|
|
23138
|
+
}
|
|
23139
|
+
function bkBaseline() {
|
|
23140
|
+
return {
|
|
23141
|
+
...baseOptions(),
|
|
23142
|
+
"elk.layered.nodePlacement.strategy": "BRANDES_KOEPF",
|
|
23143
|
+
"elk.layered.nodePlacement.bk.fixedAlignment": "BALANCED",
|
|
23144
|
+
"elk.layered.nodePlacement.bk.edgeStraightening": "IMPROVE_STRAIGHTNESS",
|
|
23145
|
+
"elk.layered.compaction.connectedComponents": "true",
|
|
23146
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": "90",
|
|
23147
|
+
"elk.spacing.nodeNode": "55",
|
|
23148
|
+
"elk.spacing.edgeNode": "55",
|
|
23149
|
+
"elk.spacing.edgeEdge": "18"
|
|
23150
|
+
};
|
|
23151
|
+
}
|
|
23152
|
+
function getVariants() {
|
|
23153
|
+
const bk = bkBaseline();
|
|
23154
|
+
return [
|
|
23155
|
+
{
|
|
23156
|
+
name: "bk-baseline",
|
|
23157
|
+
options: {
|
|
23158
|
+
...bk,
|
|
23159
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "ONE_SIDED"
|
|
23160
|
+
}
|
|
23161
|
+
},
|
|
23162
|
+
{
|
|
23163
|
+
name: "bk-aggressive",
|
|
23164
|
+
options: {
|
|
23165
|
+
...bk,
|
|
23166
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23167
|
+
"elk.layered.thoroughness": "50"
|
|
23168
|
+
}
|
|
23169
|
+
},
|
|
23170
|
+
{
|
|
23171
|
+
name: "bk-wide",
|
|
23172
|
+
options: {
|
|
23173
|
+
...bk,
|
|
23174
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23175
|
+
"elk.layered.thoroughness": "50",
|
|
23176
|
+
"elk.spacing.nodeNode": "70",
|
|
23177
|
+
"elk.spacing.edgeNode": "75",
|
|
23178
|
+
"elk.spacing.edgeEdge": "22",
|
|
23179
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": "120"
|
|
23180
|
+
}
|
|
23181
|
+
},
|
|
23182
|
+
{
|
|
23183
|
+
name: "longest-path",
|
|
23184
|
+
options: {
|
|
23185
|
+
...bk,
|
|
23186
|
+
"elk.layered.layering.strategy": "LONGEST_PATH",
|
|
23187
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23188
|
+
"elk.layered.thoroughness": "50"
|
|
23189
|
+
}
|
|
23190
|
+
},
|
|
23191
|
+
{
|
|
23192
|
+
name: "bounded-width",
|
|
23193
|
+
options: {
|
|
23194
|
+
...bk,
|
|
23195
|
+
"elk.layered.layering.strategy": "COFFMAN_GRAHAM",
|
|
23196
|
+
"elk.layered.layering.coffmanGraham.layerBound": "3",
|
|
23197
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23198
|
+
"elk.layered.thoroughness": "50"
|
|
23199
|
+
}
|
|
23200
|
+
}
|
|
23201
|
+
];
|
|
23202
|
+
}
|
|
23203
|
+
function countCrossings(edges) {
|
|
23204
|
+
let count = 0;
|
|
23205
|
+
for (let i = 0; i < edges.length; i++) {
|
|
23206
|
+
const a = edges[i].points;
|
|
23207
|
+
if (a.length < 2) continue;
|
|
23208
|
+
for (let j = i + 1; j < edges.length; j++) {
|
|
23209
|
+
const b = edges[j].points;
|
|
23210
|
+
if (b.length < 2) continue;
|
|
23211
|
+
if (edges[i].source === edges[j].source) continue;
|
|
23212
|
+
if (edges[i].source === edges[j].target) continue;
|
|
23213
|
+
if (edges[i].target === edges[j].source) continue;
|
|
23214
|
+
if (edges[i].target === edges[j].target) continue;
|
|
23215
|
+
for (let ai = 0; ai < a.length - 1; ai++) {
|
|
23216
|
+
for (let bi = 0; bi < b.length - 1; bi++) {
|
|
23217
|
+
if (segmentsCross(a[ai], a[ai + 1], b[bi], b[bi + 1])) count++;
|
|
23218
|
+
}
|
|
23219
|
+
}
|
|
23220
|
+
}
|
|
23221
|
+
}
|
|
23222
|
+
return count;
|
|
23223
|
+
}
|
|
23224
|
+
function segmentsCross(p1, p2, p3, p4) {
|
|
23225
|
+
const d1x = p2.x - p1.x;
|
|
23226
|
+
const d1y = p2.y - p1.y;
|
|
23227
|
+
const d2x = p4.x - p3.x;
|
|
23228
|
+
const d2y = p4.y - p3.y;
|
|
23229
|
+
const denom = d1x * d2y - d1y * d2x;
|
|
23230
|
+
if (Math.abs(denom) < 1e-9) return false;
|
|
23231
|
+
const t = ((p3.x - p1.x) * d2y - (p3.y - p1.y) * d2x) / denom;
|
|
23232
|
+
const s = ((p3.x - p1.x) * d1y - (p3.y - p1.y) * d1x) / denom;
|
|
23233
|
+
const EPS = 1e-3;
|
|
23234
|
+
return t > EPS && t < 1 - EPS && s > EPS && s < 1 - EPS;
|
|
23235
|
+
}
|
|
23236
|
+
function countTotalBends(edges) {
|
|
23237
|
+
let bends = 0;
|
|
23238
|
+
for (const e of edges) bends += Math.max(0, e.points.length - 2);
|
|
23239
|
+
return bends;
|
|
23240
|
+
}
|
|
23241
|
+
function scoreLayout(layout) {
|
|
23242
|
+
return {
|
|
23243
|
+
crossings: countCrossings(layout.edges),
|
|
23244
|
+
bends: countTotalBends(layout.edges),
|
|
23245
|
+
area: layout.width * layout.height
|
|
23246
|
+
};
|
|
23247
|
+
}
|
|
23248
|
+
function cmpScore(a, b) {
|
|
23249
|
+
const aBucket = a.crossings <= CROSSINGS_FORGIVENESS ? 0 : a.crossings;
|
|
23250
|
+
const bBucket = b.crossings <= CROSSINGS_FORGIVENESS ? 0 : b.crossings;
|
|
23251
|
+
if (aBucket !== bBucket) return aBucket - bBucket;
|
|
23252
|
+
if (a.area !== b.area) return a.area - b.area;
|
|
23253
|
+
return a.bends - b.bends;
|
|
23254
|
+
}
|
|
23255
|
+
async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
|
|
23256
|
+
const hideDescriptions = layoutOptions?.hideDescriptions ?? false;
|
|
23257
|
+
const direction = parsed.direction === "TB" ? "DOWN" : "RIGHT";
|
|
23258
|
+
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
23259
|
+
if (collapseInfo) {
|
|
23260
|
+
const missingGroups = /* @__PURE__ */ new Set();
|
|
23261
|
+
for (const og of collapseInfo.originalGroups) {
|
|
23262
|
+
if (!parsed.groups.some((g) => g.label === og.label)) {
|
|
23263
|
+
missingGroups.add(og.label);
|
|
23264
|
+
}
|
|
23265
|
+
}
|
|
23266
|
+
for (const label of missingGroups) {
|
|
23267
|
+
const og = collapseInfo.originalGroups.find((g) => g.label === label);
|
|
23268
|
+
const parentLabel = og?.parentGroup;
|
|
23269
|
+
if (!parentLabel || !missingGroups.has(parentLabel)) {
|
|
23270
|
+
collapsedGroupLabels.add(label);
|
|
23271
|
+
}
|
|
23272
|
+
}
|
|
23273
|
+
}
|
|
23274
|
+
const nodeSizes = /* @__PURE__ */ new Map();
|
|
23275
|
+
let maxDescHeight = 0;
|
|
23276
|
+
for (const node of parsed.nodes) {
|
|
23277
|
+
const size = hideDescriptions ? { width: NODE_WIDTH, height: NODE_HEIGHT } : computeNodeSize(node);
|
|
23278
|
+
nodeSizes.set(node.label, size);
|
|
23279
|
+
if (!hideDescriptions && node.description && node.description.length > 0) {
|
|
23280
|
+
maxDescHeight = Math.max(maxDescHeight, size.height);
|
|
23281
|
+
}
|
|
23282
|
+
}
|
|
23283
|
+
if (maxDescHeight > 0) {
|
|
23284
|
+
for (const node of parsed.nodes) {
|
|
23285
|
+
if (node.description && node.description.length > 0) {
|
|
23286
|
+
const size = nodeSizes.get(node.label);
|
|
23287
|
+
nodeSizes.set(node.label, { width: size.width, height: maxDescHeight });
|
|
23288
|
+
}
|
|
23289
|
+
}
|
|
23290
|
+
}
|
|
23291
|
+
const expandedGroupSet = new Set(parsed.groups.map((g) => g.label));
|
|
23292
|
+
const gid = (label) => `__group_${label}`;
|
|
23293
|
+
function buildGraph() {
|
|
23294
|
+
const nodeById = /* @__PURE__ */ new Map();
|
|
23295
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
23296
|
+
for (const node of parsed.nodes) {
|
|
23297
|
+
const size = nodeSizes.get(node.label);
|
|
23298
|
+
nodeById.set(node.label, {
|
|
23299
|
+
id: node.label,
|
|
23300
|
+
width: size.width,
|
|
23301
|
+
height: size.height,
|
|
23302
|
+
labels: [{ text: node.label }]
|
|
23303
|
+
});
|
|
23304
|
+
}
|
|
23305
|
+
for (const group of parsed.groups) {
|
|
23306
|
+
nodeById.set(gid(group.label), {
|
|
23307
|
+
id: gid(group.label),
|
|
23308
|
+
labels: [{ text: group.label }],
|
|
23309
|
+
layoutOptions: {
|
|
23310
|
+
"elk.padding": `[top=${CONTAINER_PAD_TOP2},left=${CONTAINER_PAD_X3},bottom=${CONTAINER_PAD_BOTTOM3},right=${CONTAINER_PAD_X3}]`,
|
|
23311
|
+
// Suggest square-ish containers — has limited effect with
|
|
23312
|
+
// INCLUDE_CHILDREN but doesn't hurt.
|
|
23313
|
+
"elk.aspectRatio": "1.4"
|
|
23314
|
+
},
|
|
23315
|
+
children: [],
|
|
23316
|
+
edges: []
|
|
23317
|
+
});
|
|
23318
|
+
}
|
|
23319
|
+
for (const label of collapsedGroupLabels) {
|
|
23320
|
+
nodeById.set(gid(label), {
|
|
23321
|
+
id: gid(label),
|
|
23322
|
+
width: NODE_WIDTH,
|
|
23323
|
+
height: NODE_HEIGHT,
|
|
23324
|
+
labels: [{ text: label }]
|
|
23325
|
+
});
|
|
23326
|
+
}
|
|
23327
|
+
for (const group of parsed.groups) {
|
|
23328
|
+
if (group.parentGroup && nodeById.has(gid(group.parentGroup))) {
|
|
23329
|
+
parentOf.set(gid(group.label), gid(group.parentGroup));
|
|
23330
|
+
}
|
|
23331
|
+
}
|
|
23332
|
+
if (collapseInfo) {
|
|
23333
|
+
for (const label of collapsedGroupLabels) {
|
|
23334
|
+
const og = collapseInfo.originalGroups.find((g) => g.label === label);
|
|
23335
|
+
if (og?.parentGroup && !collapsedGroupLabels.has(og.parentGroup) && nodeById.has(gid(og.parentGroup))) {
|
|
23336
|
+
parentOf.set(gid(label), gid(og.parentGroup));
|
|
23337
|
+
}
|
|
23338
|
+
}
|
|
23339
|
+
}
|
|
23340
|
+
for (const group of parsed.groups) {
|
|
23341
|
+
for (const child of group.children) {
|
|
23342
|
+
if (expandedGroupSet.has(child)) continue;
|
|
23343
|
+
if (nodeById.has(child)) {
|
|
23344
|
+
parentOf.set(child, gid(group.label));
|
|
23345
|
+
}
|
|
23346
|
+
}
|
|
23347
|
+
}
|
|
23348
|
+
const roots = [];
|
|
23349
|
+
for (const [id, node] of nodeById) {
|
|
23350
|
+
const parentId = parentOf.get(id);
|
|
23351
|
+
if (parentId) {
|
|
23352
|
+
const parent = nodeById.get(parentId);
|
|
23353
|
+
parent.children = parent.children ?? [];
|
|
23354
|
+
parent.children.push(node);
|
|
23355
|
+
} else {
|
|
23356
|
+
roots.push(node);
|
|
23357
|
+
}
|
|
23358
|
+
}
|
|
23359
|
+
const rootEdges = [];
|
|
23360
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23361
|
+
const edge = parsed.edges[i];
|
|
23362
|
+
if (!nodeById.has(edge.source) || !nodeById.has(edge.target)) continue;
|
|
23363
|
+
rootEdges.push({
|
|
23364
|
+
id: `e${i}`,
|
|
23365
|
+
sources: [edge.source],
|
|
23366
|
+
targets: [edge.target]
|
|
23367
|
+
});
|
|
23368
|
+
}
|
|
23369
|
+
return { roots, rootEdges };
|
|
23370
|
+
}
|
|
23371
|
+
async function runVariant(variant) {
|
|
23372
|
+
const { roots, rootEdges } = buildGraph();
|
|
23373
|
+
const elkRoot = {
|
|
23374
|
+
id: "root",
|
|
23375
|
+
layoutOptions: {
|
|
23376
|
+
...variant.options,
|
|
23377
|
+
"elk.direction": direction,
|
|
23378
|
+
"elk.padding": `[top=${MARGIN3},left=${MARGIN3},bottom=${MARGIN3},right=${MARGIN3}]`
|
|
23379
|
+
},
|
|
23380
|
+
children: roots,
|
|
23381
|
+
edges: rootEdges
|
|
23382
|
+
};
|
|
23383
|
+
const result = await getElk().layout(elkRoot);
|
|
23384
|
+
return extractLayout(result);
|
|
23385
|
+
}
|
|
23386
|
+
function extractLayout(result) {
|
|
23387
|
+
const layoutNodes = [];
|
|
23388
|
+
const layoutGroups = [];
|
|
23389
|
+
const allEdges = [];
|
|
23390
|
+
const containerAbs = /* @__PURE__ */ new Map();
|
|
23391
|
+
function walk(n, offsetX, offsetY, isRoot) {
|
|
23392
|
+
const nx = (n.x ?? 0) + offsetX;
|
|
23393
|
+
const ny = (n.y ?? 0) + offsetY;
|
|
23394
|
+
const nw = n.width ?? 0;
|
|
23395
|
+
const nh = n.height ?? 0;
|
|
23396
|
+
if (isRoot) {
|
|
23397
|
+
containerAbs.set("root", { x: nx, y: ny });
|
|
23398
|
+
} else {
|
|
23399
|
+
const isGroup = n.id.startsWith("__group_");
|
|
23400
|
+
if (isGroup) {
|
|
23401
|
+
const label = n.id.slice("__group_".length);
|
|
23402
|
+
const collapsed = collapsedGroupLabels.has(label);
|
|
23403
|
+
const og = collapseInfo?.originalGroups.find(
|
|
23404
|
+
(g) => g.label === label
|
|
23405
|
+
);
|
|
23406
|
+
const pg = parsed.groups.find((g) => g.label === label);
|
|
23407
|
+
layoutGroups.push({
|
|
23408
|
+
label,
|
|
23409
|
+
lineNumber: pg?.lineNumber ?? og?.lineNumber ?? 0,
|
|
23410
|
+
x: nx + nw / 2,
|
|
23411
|
+
y: ny + nh / 2,
|
|
23412
|
+
width: nw,
|
|
23413
|
+
height: nh,
|
|
23414
|
+
collapsed,
|
|
23415
|
+
childCount: collapsed ? collapseInfo?.collapsedChildCounts.get(label) ?? 0 : void 0
|
|
23416
|
+
});
|
|
23417
|
+
if (!collapsed) containerAbs.set(n.id, { x: nx, y: ny });
|
|
23418
|
+
} else {
|
|
23419
|
+
layoutNodes.push({
|
|
23420
|
+
label: n.id,
|
|
23421
|
+
x: nx + nw / 2,
|
|
23422
|
+
y: ny + nh / 2,
|
|
23423
|
+
width: nw,
|
|
23424
|
+
height: nh
|
|
23425
|
+
});
|
|
23426
|
+
}
|
|
23427
|
+
}
|
|
23428
|
+
if (n.edges) for (const e of n.edges) allEdges.push(e);
|
|
23429
|
+
if (n.children) for (const c of n.children) walk(c, nx, ny, false);
|
|
23430
|
+
}
|
|
23431
|
+
walk(result, 0, 0, true);
|
|
23432
|
+
const edgeYOffsets = new Array(parsed.edges.length).fill(0);
|
|
23433
|
+
const edgeParallelCounts = new Array(parsed.edges.length).fill(1);
|
|
23434
|
+
const parallelGroups = /* @__PURE__ */ new Map();
|
|
23435
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23436
|
+
const edge = parsed.edges[i];
|
|
23437
|
+
const [a, b] = edge.source < edge.target ? [edge.source, edge.target] : [edge.target, edge.source];
|
|
23438
|
+
const key = `${a}\0${b}`;
|
|
23439
|
+
if (!parallelGroups.has(key)) parallelGroups.set(key, []);
|
|
23440
|
+
parallelGroups.get(key).push(i);
|
|
23441
|
+
}
|
|
23442
|
+
for (const group of parallelGroups.values()) {
|
|
23443
|
+
const capped = group.slice(0, MAX_PARALLEL_EDGES);
|
|
23444
|
+
for (const idx of group.slice(MAX_PARALLEL_EDGES)) {
|
|
23445
|
+
edgeParallelCounts[idx] = 0;
|
|
23446
|
+
}
|
|
23447
|
+
if (capped.length < 2) continue;
|
|
23448
|
+
for (let j = 0; j < capped.length; j++) {
|
|
23449
|
+
edgeYOffsets[capped[j]] = (j - (capped.length - 1) / 2) * PARALLEL_SPACING;
|
|
23450
|
+
edgeParallelCounts[capped[j]] = capped.length;
|
|
23451
|
+
}
|
|
23452
|
+
}
|
|
23453
|
+
const edgeById = /* @__PURE__ */ new Map();
|
|
23454
|
+
for (const e of allEdges) edgeById.set(e.id, e);
|
|
23455
|
+
const layoutEdges = [];
|
|
23456
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23457
|
+
const edge = parsed.edges[i];
|
|
23458
|
+
if (edgeParallelCounts[i] === 0) continue;
|
|
23459
|
+
const elkEdge = edgeById.get(`e${i}`);
|
|
23460
|
+
if (!elkEdge || !elkEdge.sections || elkEdge.sections.length === 0)
|
|
23461
|
+
continue;
|
|
23462
|
+
const container = elkEdge.container ?? "root";
|
|
23463
|
+
const off = containerAbs.get(container) ?? { x: 0, y: 0 };
|
|
23464
|
+
const s = elkEdge.sections[0];
|
|
23465
|
+
const points = [
|
|
23466
|
+
{ x: s.startPoint.x + off.x, y: s.startPoint.y + off.y },
|
|
23467
|
+
...(s.bendPoints ?? []).map((p) => ({
|
|
23468
|
+
x: p.x + off.x,
|
|
23469
|
+
y: p.y + off.y
|
|
23470
|
+
})),
|
|
23471
|
+
{ x: s.endPoint.x + off.x, y: s.endPoint.y + off.y }
|
|
23472
|
+
];
|
|
23473
|
+
let labelX;
|
|
23474
|
+
let labelY;
|
|
23475
|
+
if (edge.label && points.length >= 2) {
|
|
23476
|
+
const mid = Math.floor(points.length / 2);
|
|
23477
|
+
labelX = points[mid].x;
|
|
23478
|
+
labelY = points[mid].y - 10;
|
|
23479
|
+
}
|
|
23480
|
+
layoutEdges.push({
|
|
23481
|
+
source: edge.source,
|
|
23482
|
+
target: edge.target,
|
|
23483
|
+
label: edge.label,
|
|
23484
|
+
bidirectional: edge.bidirectional,
|
|
23485
|
+
lineNumber: edge.lineNumber,
|
|
23486
|
+
points,
|
|
23487
|
+
labelX,
|
|
23488
|
+
labelY,
|
|
23489
|
+
yOffset: edgeYOffsets[i],
|
|
23490
|
+
parallelCount: edgeParallelCounts[i],
|
|
23491
|
+
metadata: edge.metadata,
|
|
23492
|
+
deferred: true
|
|
23493
|
+
});
|
|
23494
|
+
}
|
|
23495
|
+
let maxX = 0;
|
|
23496
|
+
let maxY = 0;
|
|
23497
|
+
for (const node of layoutNodes) {
|
|
23498
|
+
maxX = Math.max(maxX, node.x + node.width / 2);
|
|
23499
|
+
maxY = Math.max(maxY, node.y + node.height / 2);
|
|
23500
|
+
}
|
|
23501
|
+
for (const group of layoutGroups) {
|
|
23502
|
+
maxX = Math.max(maxX, group.x + group.width / 2);
|
|
23503
|
+
maxY = Math.max(maxY, group.y + group.height / 2);
|
|
23504
|
+
}
|
|
23505
|
+
return {
|
|
23506
|
+
nodes: layoutNodes,
|
|
23507
|
+
edges: layoutEdges,
|
|
23508
|
+
groups: layoutGroups,
|
|
23509
|
+
width: maxX + MARGIN3,
|
|
23510
|
+
height: maxY + MARGIN3
|
|
23511
|
+
};
|
|
23512
|
+
}
|
|
23513
|
+
const N = parsed.nodes.length + parsed.groups.length;
|
|
23514
|
+
const E = parsed.edges.length;
|
|
23515
|
+
const trivial = N < 8 && E < 10;
|
|
23516
|
+
const variants = trivial ? [getVariants()[1]] : getVariants();
|
|
23517
|
+
const results = await Promise.all(variants.map((v) => runVariant(v)));
|
|
23518
|
+
let best = results[0];
|
|
23519
|
+
let bestScore = scoreLayout(best);
|
|
23520
|
+
for (let i = 1; i < results.length; i++) {
|
|
23521
|
+
const s = scoreLayout(results[i]);
|
|
23522
|
+
if (cmpScore(s, bestScore) < 0) {
|
|
23523
|
+
best = results[i];
|
|
23524
|
+
bestScore = s;
|
|
23525
|
+
}
|
|
23526
|
+
}
|
|
23527
|
+
return best;
|
|
23528
|
+
}
|
|
23529
|
+
var MARGIN3, CONTAINER_PAD_X3, CONTAINER_PAD_TOP2, CONTAINER_PAD_BOTTOM3, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE2, DESC_LINE_HEIGHT2, DESC_PADDING, SEPARATOR_GAP5, MAX_DESC_LINES2, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, LABEL_PAD, elkInstance, CROSSINGS_FORGIVENESS;
|
|
23530
|
+
var init_layout5 = __esm({
|
|
23531
|
+
"src/boxes-and-lines/layout.ts"() {
|
|
23532
|
+
"use strict";
|
|
23533
|
+
MARGIN3 = 40;
|
|
23534
|
+
CONTAINER_PAD_X3 = 30;
|
|
23535
|
+
CONTAINER_PAD_TOP2 = 40;
|
|
23536
|
+
CONTAINER_PAD_BOTTOM3 = 24;
|
|
23537
|
+
MAX_PARALLEL_EDGES = 5;
|
|
23538
|
+
PARALLEL_SPACING = 22;
|
|
23539
|
+
PHI = 1.618;
|
|
23540
|
+
NODE_HEIGHT = 60;
|
|
23541
|
+
NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
|
|
23542
|
+
DESC_NODE_WIDTH = 140;
|
|
23543
|
+
DESC_FONT_SIZE2 = 10;
|
|
23544
|
+
DESC_LINE_HEIGHT2 = 1.4;
|
|
23545
|
+
DESC_PADDING = 8;
|
|
23546
|
+
SEPARATOR_GAP5 = 4;
|
|
23547
|
+
MAX_DESC_LINES2 = 6;
|
|
23548
|
+
MAX_LABEL_LINES = 3;
|
|
23549
|
+
LABEL_LINE_HEIGHT = 1.3;
|
|
23550
|
+
LABEL_PAD = 12;
|
|
23551
|
+
elkInstance = null;
|
|
23552
|
+
CROSSINGS_FORGIVENESS = 1;
|
|
23553
|
+
}
|
|
23554
|
+
});
|
|
23555
|
+
|
|
23493
23556
|
// src/mindmap/text-wrap.ts
|
|
23494
23557
|
function tokenize(text) {
|
|
23495
23558
|
const tokens = [];
|
|
@@ -23628,7 +23691,7 @@ var layout_exports6 = {};
|
|
|
23628
23691
|
__export(layout_exports6, {
|
|
23629
23692
|
layoutMindmap: () => layoutMindmap
|
|
23630
23693
|
});
|
|
23631
|
-
function layoutMindmap(parsed,
|
|
23694
|
+
function layoutMindmap(parsed, _palette, options) {
|
|
23632
23695
|
const roots = parsed.roots;
|
|
23633
23696
|
if (roots.length === 0) {
|
|
23634
23697
|
return { nodes: [], edges: [], width: 0, height: 0 };
|
|
@@ -24524,7 +24587,7 @@ function layoutElement(el, x, y, width) {
|
|
|
24524
24587
|
node.height = getElementHeight(el);
|
|
24525
24588
|
return node;
|
|
24526
24589
|
}
|
|
24527
|
-
const isInlineRow = el.metadata
|
|
24590
|
+
const isInlineRow = el.metadata["_inlineRow"] === "true" || el.metadata["_labelField"] === "true";
|
|
24528
24591
|
const padTop = isInlineRow ? 0 : GROUP_PADDING_TOP;
|
|
24529
24592
|
const padBottom = isInlineRow ? 0 : GROUP_PADDING_BOTTOM;
|
|
24530
24593
|
const padX = isInlineRow ? 0 : GROUP_PADDING_X;
|
|
@@ -24573,7 +24636,7 @@ function allocateEqualWidths(children, totalWidth) {
|
|
|
24573
24636
|
}
|
|
24574
24637
|
function getElementHeight(el) {
|
|
24575
24638
|
if (el.type === "heading") {
|
|
24576
|
-
return el.headingLevel === 2 ? ELEMENT_HEIGHTS
|
|
24639
|
+
return el.headingLevel === 2 ? ELEMENT_HEIGHTS["subheading"] ?? 36 : ELEMENT_HEIGHTS["heading"] ?? 48;
|
|
24577
24640
|
}
|
|
24578
24641
|
if (el.type === "textInput" && el.fieldVariant === "textarea") {
|
|
24579
24642
|
return 80;
|
|
@@ -24587,16 +24650,16 @@ function getElementHeight(el) {
|
|
|
24587
24650
|
if (el.type === "image") {
|
|
24588
24651
|
if (el.imageHint === "round") return 80;
|
|
24589
24652
|
if (el.imageHint === "wide") return 80;
|
|
24590
|
-
return ELEMENT_HEIGHTS
|
|
24653
|
+
return ELEMENT_HEIGHTS["image"] ?? 120;
|
|
24591
24654
|
}
|
|
24592
|
-
if (el.metadata
|
|
24655
|
+
if (el.metadata["_labelField"] === "true") {
|
|
24593
24656
|
return 36;
|
|
24594
24657
|
}
|
|
24595
24658
|
return ELEMENT_HEIGHTS[el.type] ?? 24;
|
|
24596
24659
|
}
|
|
24597
24660
|
function getSpacingAfter(el) {
|
|
24598
24661
|
if (el.type === "heading" && el.headingLevel === 2) {
|
|
24599
|
-
return SPACING_AFTER
|
|
24662
|
+
return SPACING_AFTER["subheading"] ?? 12;
|
|
24600
24663
|
}
|
|
24601
24664
|
return SPACING_AFTER[el.type] ?? 8;
|
|
24602
24665
|
}
|
|
@@ -24604,7 +24667,7 @@ function computeFieldAlignX(children) {
|
|
|
24604
24667
|
let maxLabelWidth = 0;
|
|
24605
24668
|
let labelFieldCount = 0;
|
|
24606
24669
|
for (const child of children) {
|
|
24607
|
-
if (child.metadata
|
|
24670
|
+
if (child.metadata["_labelField"] === "true" && child.children.length >= 2) {
|
|
24608
24671
|
const labelEl = child.children[0];
|
|
24609
24672
|
const labelWidth = labelEl.label.length * CHAR_WIDTH5;
|
|
24610
24673
|
maxLabelWidth = Math.max(maxLabelWidth, labelWidth);
|
|
@@ -24816,7 +24879,7 @@ function renderNode(parent, node, ctx, depth) {
|
|
|
24816
24879
|
function renderGroup(g, node, ctx, depth) {
|
|
24817
24880
|
const { palette, isTransparent } = ctx;
|
|
24818
24881
|
const el = node.element;
|
|
24819
|
-
if (el.metadata
|
|
24882
|
+
if (el.metadata["_inlineRow"] === "true" || el.metadata["_labelField"] === "true") {
|
|
24820
24883
|
for (const child of node.children) {
|
|
24821
24884
|
renderNode(g, child, ctx, depth);
|
|
24822
24885
|
}
|
|
@@ -24944,7 +25007,7 @@ function renderDivider(g, node, ctx) {
|
|
|
24944
25007
|
function renderText(g, node, ctx) {
|
|
24945
25008
|
const { palette } = ctx;
|
|
24946
25009
|
const el = node.element;
|
|
24947
|
-
if (el.metadata
|
|
25010
|
+
if (el.metadata["_labelField"] === "true" && el.children.length >= 2) {
|
|
24948
25011
|
for (const child of node.children) {
|
|
24949
25012
|
renderNode(g, child, ctx, 0);
|
|
24950
25013
|
}
|
|
@@ -25238,7 +25301,7 @@ __export(layout_exports8, {
|
|
|
25238
25301
|
layoutC4Deployment: () => layoutC4Deployment,
|
|
25239
25302
|
rollUpContextRelationships: () => rollUpContextRelationships
|
|
25240
25303
|
});
|
|
25241
|
-
import
|
|
25304
|
+
import dagre4 from "@dagrejs/dagre";
|
|
25242
25305
|
function computeEdgePenalty(edgeList, nodePositions, degrees, nodeGeometry) {
|
|
25243
25306
|
let penalty = 0;
|
|
25244
25307
|
for (const edge of edgeList) {
|
|
@@ -25679,7 +25742,7 @@ function layoutC4Context(parsed, activeTagGroup) {
|
|
|
25679
25742
|
}
|
|
25680
25743
|
const contextRels = rollUpContextRelationships(parsed);
|
|
25681
25744
|
const spacing = computeAdaptiveSpacing(contextRels);
|
|
25682
|
-
const g = new
|
|
25745
|
+
const g = new dagre4.graphlib.Graph();
|
|
25683
25746
|
g.setGraph({
|
|
25684
25747
|
rankdir: "TB",
|
|
25685
25748
|
nodesep: spacing.nodesep,
|
|
@@ -25700,7 +25763,7 @@ function layoutC4Context(parsed, activeTagGroup) {
|
|
|
25700
25763
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
25701
25764
|
}
|
|
25702
25765
|
}
|
|
25703
|
-
|
|
25766
|
+
dagre4.layout(g);
|
|
25704
25767
|
reduceCrossings(
|
|
25705
25768
|
g,
|
|
25706
25769
|
validRels.map((r) => ({ source: r.sourceName, target: r.targetName }))
|
|
@@ -25872,7 +25935,7 @@ function layoutC4Containers(parsed, systemName, activeTagGroup) {
|
|
|
25872
25935
|
}
|
|
25873
25936
|
}
|
|
25874
25937
|
const hasGroups = elementToGroup.size > 0;
|
|
25875
|
-
const g = hasGroups ? new
|
|
25938
|
+
const g = hasGroups ? new dagre4.graphlib.Graph({ compound: true }) : new dagre4.graphlib.Graph();
|
|
25876
25939
|
g.setDefaultEdgeLabel(() => ({}));
|
|
25877
25940
|
if (hasGroups) {
|
|
25878
25941
|
const seenGroups = /* @__PURE__ */ new Set();
|
|
@@ -25950,7 +26013,7 @@ function layoutC4Containers(parsed, systemName, activeTagGroup) {
|
|
|
25950
26013
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
25951
26014
|
}
|
|
25952
26015
|
}
|
|
25953
|
-
|
|
26016
|
+
dagre4.layout(g);
|
|
25954
26017
|
const nodeGroupMap = hasGroups ? new Map([...elementToGroup.entries()].map(([k, v]) => [k, v.name])) : void 0;
|
|
25955
26018
|
reduceCrossings(
|
|
25956
26019
|
g,
|
|
@@ -26276,7 +26339,7 @@ function layoutC4Components(parsed, systemName, containerName, activeTagGroup) {
|
|
|
26276
26339
|
}
|
|
26277
26340
|
}
|
|
26278
26341
|
const hasGroups = elementToGroup.size > 0;
|
|
26279
|
-
const g = hasGroups ? new
|
|
26342
|
+
const g = hasGroups ? new dagre4.graphlib.Graph({ compound: true }) : new dagre4.graphlib.Graph();
|
|
26280
26343
|
g.setDefaultEdgeLabel(() => ({}));
|
|
26281
26344
|
if (hasGroups) {
|
|
26282
26345
|
const seenGroups = /* @__PURE__ */ new Set();
|
|
@@ -26360,7 +26423,7 @@ function layoutC4Components(parsed, systemName, containerName, activeTagGroup) {
|
|
|
26360
26423
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
26361
26424
|
}
|
|
26362
26425
|
}
|
|
26363
|
-
|
|
26426
|
+
dagre4.layout(g);
|
|
26364
26427
|
const nodeGroupMap = hasGroups ? new Map([...elementToGroup.entries()].map(([k, v]) => [k, v.name])) : void 0;
|
|
26365
26428
|
reduceCrossings(
|
|
26366
26429
|
g,
|
|
@@ -26649,7 +26712,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
26649
26712
|
for (const r of refEntries) {
|
|
26650
26713
|
nameToElement.set(r.element.name, r.element);
|
|
26651
26714
|
}
|
|
26652
|
-
const g = new
|
|
26715
|
+
const g = new dagre4.graphlib.Graph({ compound: true });
|
|
26653
26716
|
g.setDefaultEdgeLabel(() => ({}));
|
|
26654
26717
|
for (const [infraId] of infraIds) {
|
|
26655
26718
|
g.setNode(infraId, {});
|
|
@@ -26693,7 +26756,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
26693
26756
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
26694
26757
|
}
|
|
26695
26758
|
}
|
|
26696
|
-
|
|
26759
|
+
dagre4.layout(g);
|
|
26697
26760
|
const nodeInfraMap = /* @__PURE__ */ new Map();
|
|
26698
26761
|
for (const r of refEntries) nodeInfraMap.set(r.element.name, r.infraId);
|
|
26699
26762
|
reduceCrossings(
|
|
@@ -27925,7 +27988,7 @@ var layout_exports9 = {};
|
|
|
27925
27988
|
__export(layout_exports9, {
|
|
27926
27989
|
layoutGraph: () => layoutGraph
|
|
27927
27990
|
});
|
|
27928
|
-
import
|
|
27991
|
+
import dagre5 from "@dagrejs/dagre";
|
|
27929
27992
|
function computeNodeWidth(label, shape) {
|
|
27930
27993
|
if (shape === "pseudostate") return 24;
|
|
27931
27994
|
const base = Math.max(120, label.length * 9 + 40);
|
|
@@ -27958,7 +28021,7 @@ function layoutGraph(graph, options) {
|
|
|
27958
28021
|
if (allNodes.length === 0) {
|
|
27959
28022
|
return { nodes: [], edges: [], groups: [], width: 0, height: 0 };
|
|
27960
28023
|
}
|
|
27961
|
-
const g = new
|
|
28024
|
+
const g = new dagre5.graphlib.Graph({ compound: true });
|
|
27962
28025
|
g.setGraph({
|
|
27963
28026
|
rankdir: graph.direction,
|
|
27964
28027
|
nodesep: 50,
|
|
@@ -27994,7 +28057,7 @@ function layoutGraph(graph, options) {
|
|
|
27994
28057
|
label: edge.label ?? ""
|
|
27995
28058
|
});
|
|
27996
28059
|
}
|
|
27997
|
-
|
|
28060
|
+
dagre5.layout(g);
|
|
27998
28061
|
const collapsedGroupIds = collapsedChildCounts ? new Set(collapsedChildCounts.keys()) : /* @__PURE__ */ new Set();
|
|
27999
28062
|
const layoutNodes = allNodes.map((node) => {
|
|
28000
28063
|
const pos = g.node(node.id);
|
|
@@ -28428,7 +28491,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
28428
28491
|
endTerminalIds.add(node.id);
|
|
28429
28492
|
}
|
|
28430
28493
|
}
|
|
28431
|
-
const colorOff = graph.options?.color === "off";
|
|
28494
|
+
const colorOff = graph.options?.["color"] === "off";
|
|
28432
28495
|
const solid = graph.options?.["solid-fill"] === "on";
|
|
28433
28496
|
for (const node of layout.nodes) {
|
|
28434
28497
|
const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", "fc-node").attr("data-line-number", String(node.lineNumber)).attr("data-node-id", node.id);
|
|
@@ -29357,7 +29420,7 @@ __export(layout_exports10, {
|
|
|
29357
29420
|
layoutInfra: () => layoutInfra,
|
|
29358
29421
|
separateGroups: () => separateGroups
|
|
29359
29422
|
});
|
|
29360
|
-
import
|
|
29423
|
+
import dagre6 from "@dagrejs/dagre";
|
|
29361
29424
|
function countDisplayProps(node, expanded, options) {
|
|
29362
29425
|
if (!expanded) return 0;
|
|
29363
29426
|
let count = node.properties.filter((p) => DISPLAY_KEYS.has(p.key)).length;
|
|
@@ -29660,7 +29723,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
29660
29723
|
};
|
|
29661
29724
|
}
|
|
29662
29725
|
const isLR = computed.direction !== "TB";
|
|
29663
|
-
const g = new
|
|
29726
|
+
const g = new dagre6.graphlib.Graph();
|
|
29664
29727
|
g.setGraph({
|
|
29665
29728
|
rankdir: computed.direction === "TB" ? "TB" : "LR",
|
|
29666
29729
|
nodesep: isLR ? 70 : 60,
|
|
@@ -29711,7 +29774,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
29711
29774
|
g.setEdge(edge.sourceId, edge.targetId, { label: edge.label });
|
|
29712
29775
|
}
|
|
29713
29776
|
}
|
|
29714
|
-
|
|
29777
|
+
dagre6.layout(g);
|
|
29715
29778
|
const layoutNodes = computed.nodes.map((node) => {
|
|
29716
29779
|
const pos = g.node(node.id);
|
|
29717
29780
|
return {
|
|
@@ -30620,7 +30683,7 @@ function renderGroups(svg, groups, palette, _isDark) {
|
|
|
30620
30683
|
}
|
|
30621
30684
|
}
|
|
30622
30685
|
}
|
|
30623
|
-
function renderEdgePaths(svg, edges, nodes, groups, palette,
|
|
30686
|
+
function renderEdgePaths(svg, edges, nodes, groups, palette, _isDark, animate, direction, speedMultiplier = 1) {
|
|
30624
30687
|
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
30625
30688
|
const maxRps = Math.max(...edges.map((e) => e.computedRps), 1);
|
|
30626
30689
|
const { srcPts, tgtPts } = computePortPts(edges, nodeMap, direction);
|
|
@@ -30661,7 +30724,7 @@ function renderEdgePaths(svg, edges, nodes, groups, palette, isDark, animate, di
|
|
|
30661
30724
|
}
|
|
30662
30725
|
}
|
|
30663
30726
|
}
|
|
30664
|
-
function renderEdgeLabels(svg, edges, nodes, groups, palette,
|
|
30727
|
+
function renderEdgeLabels(svg, edges, nodes, groups, palette, _isDark, animate, direction) {
|
|
30665
30728
|
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
30666
30729
|
const { srcPts, tgtPts } = computePortPts(edges, nodeMap, direction);
|
|
30667
30730
|
for (const edge of edges) {
|
|
@@ -31400,7 +31463,7 @@ function sampleBetaPert(o, m, p, rng) {
|
|
|
31400
31463
|
const beta = 1 + 4 * (p - m) / range;
|
|
31401
31464
|
return o + sampleBeta(alpha, beta, rng) * range;
|
|
31402
31465
|
}
|
|
31403
|
-
function simulate(resolved, expanded,
|
|
31466
|
+
function simulate(resolved, expanded, _predecessors, _successors, topo, terminals, poisoned, opts) {
|
|
31404
31467
|
const rng = mulberry32(opts.seed);
|
|
31405
31468
|
const expById = /* @__PURE__ */ new Map();
|
|
31406
31469
|
for (const e of expanded) expById.set(e.id, e);
|
|
@@ -32413,7 +32476,7 @@ __export(layout_exports11, {
|
|
|
32413
32476
|
layoutPert: () => layoutPert,
|
|
32414
32477
|
relayoutPert: () => relayoutPert
|
|
32415
32478
|
});
|
|
32416
|
-
import
|
|
32479
|
+
import dagre7 from "@dagrejs/dagre";
|
|
32417
32480
|
function computeNodeSizing(resolved) {
|
|
32418
32481
|
const unit = resolved.options.timeUnit;
|
|
32419
32482
|
const sprintMode = resolved.options.sprintMode;
|
|
@@ -32521,7 +32584,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32521
32584
|
}
|
|
32522
32585
|
}
|
|
32523
32586
|
const dagreId = (id) => memberToGroup.get(id) ?? id;
|
|
32524
|
-
const g = new
|
|
32587
|
+
const g = new dagre7.graphlib.Graph();
|
|
32525
32588
|
g.setGraph({
|
|
32526
32589
|
rankdir: resolved.options.direction,
|
|
32527
32590
|
nodesep: 50,
|
|
@@ -32560,7 +32623,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32560
32623
|
seenEdges.add(k);
|
|
32561
32624
|
g.setEdge(src, tgt, {});
|
|
32562
32625
|
}
|
|
32563
|
-
|
|
32626
|
+
dagre7.layout(g);
|
|
32564
32627
|
const swimApplied = applySwimLanes(
|
|
32565
32628
|
g,
|
|
32566
32629
|
resolved,
|
|
@@ -32680,7 +32743,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32680
32743
|
height: totalH + DIAGRAM_PADDING10
|
|
32681
32744
|
};
|
|
32682
32745
|
}
|
|
32683
|
-
function applySwimLanes(g, resolved,
|
|
32746
|
+
function applySwimLanes(g, resolved, _memberToGroup, collapsedGroupIds) {
|
|
32684
32747
|
const expanded = resolved.groups.filter(
|
|
32685
32748
|
(rg) => !collapsedGroupIds.has(rg.group.id)
|
|
32686
32749
|
);
|
|
@@ -32906,7 +32969,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32906
32969
|
buckets.get(key).push(id);
|
|
32907
32970
|
}
|
|
32908
32971
|
const edges = g.edges().map((e) => ({ v: e.v, w: e.w }));
|
|
32909
|
-
const
|
|
32972
|
+
const countCrossings2 = () => {
|
|
32910
32973
|
let total = 0;
|
|
32911
32974
|
for (let i = 0; i < edges.length; i++) {
|
|
32912
32975
|
const a = edges[i];
|
|
@@ -32919,13 +32982,13 @@ function reduceCrossings2(g, direction) {
|
|
|
32919
32982
|
const b1 = g.node(b.v);
|
|
32920
32983
|
const b2 = g.node(b.w);
|
|
32921
32984
|
if (!b1 || !b2) continue;
|
|
32922
|
-
if (
|
|
32985
|
+
if (segmentsCross2(a1, a2, b1, b2)) total++;
|
|
32923
32986
|
}
|
|
32924
32987
|
}
|
|
32925
32988
|
return total;
|
|
32926
32989
|
};
|
|
32927
32990
|
const MAX_ITER = 8;
|
|
32928
|
-
let baseline =
|
|
32991
|
+
let baseline = countCrossings2();
|
|
32929
32992
|
if (baseline === 0) return;
|
|
32930
32993
|
for (let iter = 0; iter < MAX_ITER; iter++) {
|
|
32931
32994
|
let improved = false;
|
|
@@ -32943,7 +33006,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32943
33006
|
const bv = bn[slotAxis];
|
|
32944
33007
|
an[slotAxis] = bv;
|
|
32945
33008
|
bn[slotAxis] = av;
|
|
32946
|
-
const after =
|
|
33009
|
+
const after = countCrossings2();
|
|
32947
33010
|
if (after < baseline) {
|
|
32948
33011
|
baseline = after;
|
|
32949
33012
|
improved = true;
|
|
@@ -32964,7 +33027,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32964
33027
|
data.points = smoothEdge(src, tgt, direction);
|
|
32965
33028
|
}
|
|
32966
33029
|
}
|
|
32967
|
-
function
|
|
33030
|
+
function segmentsCross2(a1, a2, b1, b2) {
|
|
32968
33031
|
const ccw = (p, q, r) => (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
|
|
32969
33032
|
const d1 = ccw(b1, b2, a1);
|
|
32970
33033
|
const d2 = ccw(b1, b2, a2);
|
|
@@ -34972,12 +35035,6 @@ function calculateSchedule(parsed) {
|
|
|
34972
35035
|
const warn2 = (line12, message) => {
|
|
34973
35036
|
diagnostics.push(makeDgmoError(line12, message, "warning"));
|
|
34974
35037
|
};
|
|
34975
|
-
const _fail = (line12, message) => {
|
|
34976
|
-
const diag = makeDgmoError(line12, message);
|
|
34977
|
-
diagnostics.push(diag);
|
|
34978
|
-
result.error = formatDgmoError(diag);
|
|
34979
|
-
return result;
|
|
34980
|
-
};
|
|
34981
35038
|
const holidaySet = buildHolidaySet(parsed.holidays);
|
|
34982
35039
|
let projectStart;
|
|
34983
35040
|
if (parsed.options.start) {
|
|
@@ -35002,7 +35059,6 @@ function calculateSchedule(parsed) {
|
|
|
35002
35059
|
}
|
|
35003
35060
|
buildImplicitDeps(parsed.nodes, taskMap);
|
|
35004
35061
|
for (const task of allTasks2) {
|
|
35005
|
-
const _node = taskMap.get(task.id);
|
|
35006
35062
|
for (const dep of task.dependencies) {
|
|
35007
35063
|
const resolved = resolveTaskName(dep.targetName, allTasks2);
|
|
35008
35064
|
if (isResolverError(resolved)) {
|
|
@@ -36543,7 +36599,7 @@ function buildControlsToggles(hasCriticalPath, criticalPathActive, hasDependenci
|
|
|
36543
36599
|
}
|
|
36544
36600
|
return toggles;
|
|
36545
36601
|
}
|
|
36546
|
-
function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive,
|
|
36602
|
+
function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive, _optionLineNumbers, onToggle, onToggleControlsExpand, currentSwimlaneGroup, onSwimlaneChange, legendViewMode, resolvedTasks, controlsExpanded = false, hasDependencies = false, dependenciesActive = false, onControlsToggle) {
|
|
36547
36603
|
let visibleGroups;
|
|
36548
36604
|
if (activeGroupName) {
|
|
36549
36605
|
const activeGroup = tagGroups.filter(
|
|
@@ -37506,7 +37562,7 @@ function resolveTaskColor(rt, activeTagGroup, resolved, seriesColors2, palette)
|
|
|
37506
37562
|
}
|
|
37507
37563
|
return palette.accent || seriesColors2[0] || "#4a90d9";
|
|
37508
37564
|
}
|
|
37509
|
-
function renderTimeScaleHorizontal(g, scale,
|
|
37565
|
+
function renderTimeScaleHorizontal(g, scale, _innerWidth, innerHeight, textColor) {
|
|
37510
37566
|
const [domainMin, domainMax] = scale.domain();
|
|
37511
37567
|
const ticks = computeTimeTicks(domainMin, domainMax, scale);
|
|
37512
37568
|
if (ticks.length < 2) return;
|
|
@@ -37753,7 +37809,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
|
|
|
37753
37809
|
for (const group of layout.groups) {
|
|
37754
37810
|
if (group.collapsed) collapsedGroupIds.add(group.id);
|
|
37755
37811
|
}
|
|
37756
|
-
const colorOff = graph.options?.color === "off";
|
|
37812
|
+
const colorOff = graph.options?.["color"] === "off";
|
|
37757
37813
|
const solid = graph.options?.["solid-fill"] === "on";
|
|
37758
37814
|
for (const node of layout.nodes) {
|
|
37759
37815
|
const isCollapsedGroup = collapsedGroupIds.has(node.id);
|
|
@@ -38152,7 +38208,7 @@ function renderQuadrantFocus(container, parsed, quadrantPosition, palette, isDar
|
|
|
38152
38208
|
}
|
|
38153
38209
|
}
|
|
38154
38210
|
}
|
|
38155
|
-
function renderQuarterCircle(svg, parsed, quadrant, qColor, palette, isDark, width, height, mutedColor,
|
|
38211
|
+
function renderQuarterCircle(svg, parsed, quadrant, qColor, palette, isDark, width, height, mutedColor, _tooltip, rootContainer, onClickItem) {
|
|
38156
38212
|
const padding = 8;
|
|
38157
38213
|
const size = Math.min(width - padding, height - padding);
|
|
38158
38214
|
const maxRadius = size * 0.95;
|
|
@@ -39022,7 +39078,7 @@ function estimateListingHeight(parsed) {
|
|
|
39022
39078
|
);
|
|
39023
39079
|
return LISTING_LINE_HEIGHT * (maxBlipsInQuadrant + 1) + LISTING_LINE_HEIGHT + LISTING_TOP_MARGIN;
|
|
39024
39080
|
}
|
|
39025
|
-
function createBlipPopover(container,
|
|
39081
|
+
function createBlipPopover(container, _palette, isDark) {
|
|
39026
39082
|
container.style.position = "relative";
|
|
39027
39083
|
const existing = container.querySelector(
|
|
39028
39084
|
"[data-blip-popover]"
|
|
@@ -40889,7 +40945,7 @@ function computeEdgeLabelPosition(midAngle, radius, cx, cy, lineCount, maxCharLe
|
|
|
40889
40945
|
labelAngle: best.labelAngle
|
|
40890
40946
|
};
|
|
40891
40947
|
}
|
|
40892
|
-
function fitToCanvas(nodes, edges, parsed,
|
|
40948
|
+
function fitToCanvas(nodes, edges, parsed, _cx, _cy, radius, width, height, _isClockwise) {
|
|
40893
40949
|
const PADDING3 = 30;
|
|
40894
40950
|
let contentMinX = Infinity, contentMaxX = -Infinity;
|
|
40895
40951
|
let contentMinY = Infinity, contentMaxY = -Infinity;
|
|
@@ -42399,7 +42455,7 @@ function renderPhaseBar(svg, phase, x, y, width, palette, collapsed, autoColor,
|
|
|
42399
42455
|
});
|
|
42400
42456
|
}
|
|
42401
42457
|
}
|
|
42402
|
-
function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette, surfaceBg, solid, taskDiagnostics,
|
|
42458
|
+
function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette, surfaceBg, solid, taskDiagnostics, _hasAnyDiagnostic, rowContent, onClickLine, _onMarkerDragStart) {
|
|
42403
42459
|
const rowG = svg.append("g").attr("class", "raci-task-row").attr("data-task-id", task.id).attr("data-line-number", String(task.lineNumber));
|
|
42404
42460
|
const labelX = x + 8;
|
|
42405
42461
|
const labelMaxW = labelW - 16;
|
|
@@ -43205,7 +43261,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
43205
43261
|
const messages = collapsed ? collapsed.messages : parsed.messages;
|
|
43206
43262
|
const elements = collapsed ? collapsed.elements : parsed.elements;
|
|
43207
43263
|
const groups = collapsed ? collapsed.groups : parsed.groups;
|
|
43208
|
-
const collapsedGroupIds = collapsed?.collapsedGroupIds ?? /* @__PURE__ */ new Map();
|
|
43209
43264
|
const collapsedSections = options?.collapsedSections;
|
|
43210
43265
|
const sourceParticipants = collapsed ? collapsed.participants : parsed.participants;
|
|
43211
43266
|
const participants = applyPositionOverrides(
|
|
@@ -43233,7 +43288,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
43233
43288
|
return Math.min(NOTE_MAX_W, laneMax);
|
|
43234
43289
|
};
|
|
43235
43290
|
const charsForWidth = (maxW) => Math.floor((maxW - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W);
|
|
43236
|
-
const activationsOff = parsedOptions
|
|
43291
|
+
const activationsOff = parsedOptions["activations"]?.toLowerCase() === "off";
|
|
43237
43292
|
const activeTagGroup = resolveActiveTagGroup(
|
|
43238
43293
|
parsed.tagGroups,
|
|
43239
43294
|
parsedOptions["active-tag"],
|
|
@@ -46189,7 +46244,7 @@ function renderTimelineGroupLegend(g, groups, groupColorMap, textColor, palette,
|
|
|
46189
46244
|
legendX += pillW + GAP;
|
|
46190
46245
|
}
|
|
46191
46246
|
}
|
|
46192
|
-
function
|
|
46247
|
+
function setupTimeline(container, parsed, palette, isDark, exportDims, activeTagGroup, swimlaneTagGroup) {
|
|
46193
46248
|
d3Selection22.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
46194
46249
|
const solid = parsed.solidFill === true;
|
|
46195
46250
|
const {
|
|
@@ -46198,19 +46253,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46198
46253
|
timelineEras,
|
|
46199
46254
|
timelineMarkers,
|
|
46200
46255
|
timelineSort,
|
|
46201
|
-
timelineScale,
|
|
46202
|
-
timelineSwimlanes,
|
|
46203
46256
|
orientation
|
|
46204
46257
|
} = parsed;
|
|
46205
|
-
|
|
46206
|
-
|
|
46207
|
-
if (
|
|
46208
|
-
|
|
46258
|
+
if (timelineEvents.length === 0) return null;
|
|
46259
|
+
let resolvedSwimlaneTG = swimlaneTagGroup ?? null;
|
|
46260
|
+
if (resolvedSwimlaneTG == null && timelineSort === "tag" && parsed.timelineDefaultSwimlaneTG) {
|
|
46261
|
+
resolvedSwimlaneTG = parsed.timelineDefaultSwimlaneTG;
|
|
46209
46262
|
}
|
|
46210
46263
|
const tooltip = createTooltip2(container, palette, isDark);
|
|
46211
46264
|
const width = exportDims?.width ?? container.clientWidth;
|
|
46212
46265
|
const height = exportDims?.height ?? container.clientHeight;
|
|
46213
|
-
if (width <= 0 || height <= 0) return;
|
|
46266
|
+
if (width <= 0 || height <= 0) return null;
|
|
46214
46267
|
const isVertical = orientation === "vertical";
|
|
46215
46268
|
const textColor = palette.text;
|
|
46216
46269
|
const mutedColor = palette.border;
|
|
@@ -46222,8 +46275,8 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46222
46275
|
groupColorMap.set(grp.name, grp.color ?? colors[i % colors.length]);
|
|
46223
46276
|
});
|
|
46224
46277
|
let tagLanes = null;
|
|
46225
|
-
if (
|
|
46226
|
-
const tagKey =
|
|
46278
|
+
if (resolvedSwimlaneTG) {
|
|
46279
|
+
const tagKey = resolvedSwimlaneTG.toLowerCase();
|
|
46227
46280
|
const tagGroup = parsed.timelineTagGroups.find(
|
|
46228
46281
|
(g) => g.name.toLowerCase() === tagKey
|
|
46229
46282
|
);
|
|
@@ -46254,7 +46307,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46254
46307
|
}
|
|
46255
46308
|
}
|
|
46256
46309
|
}
|
|
46257
|
-
const effectiveColorTG = activeTagGroup ??
|
|
46310
|
+
const effectiveColorTG = activeTagGroup ?? resolvedSwimlaneTG ?? null;
|
|
46258
46311
|
function eventColor(ev) {
|
|
46259
46312
|
if (effectiveColorTG) {
|
|
46260
46313
|
const tagColor = resolveTagColor(
|
|
@@ -46310,6 +46363,30 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46310
46363
|
}
|
|
46311
46364
|
}
|
|
46312
46365
|
const datePadding = (maxDate - minDate) * 0.05 || 0.5;
|
|
46366
|
+
const tagLegendReserve = parsed.timelineTagGroups.length > 0 ? 36 : 0;
|
|
46367
|
+
return {
|
|
46368
|
+
width,
|
|
46369
|
+
height,
|
|
46370
|
+
isVertical,
|
|
46371
|
+
tooltip,
|
|
46372
|
+
solid,
|
|
46373
|
+
textColor,
|
|
46374
|
+
mutedColor,
|
|
46375
|
+
bgColor,
|
|
46376
|
+
bg,
|
|
46377
|
+
swimlaneTagGroup: resolvedSwimlaneTG,
|
|
46378
|
+
groupColorMap,
|
|
46379
|
+
tagLanes,
|
|
46380
|
+
eventColor,
|
|
46381
|
+
minDate,
|
|
46382
|
+
maxDate,
|
|
46383
|
+
datePadding,
|
|
46384
|
+
earliestStartDateStr,
|
|
46385
|
+
latestEndDateStr,
|
|
46386
|
+
tagLegendReserve
|
|
46387
|
+
};
|
|
46388
|
+
}
|
|
46389
|
+
function makeTimelineHoverHelpers() {
|
|
46313
46390
|
const FADE_OPACITY3 = 0.1;
|
|
46314
46391
|
function fadeToGroup(g, groupName) {
|
|
46315
46392
|
g.selectAll(".tl-event").each(function() {
|
|
@@ -46409,337 +46486,683 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46409
46486
|
evG.attr(`data-tag-${key}`, value.toLowerCase());
|
|
46410
46487
|
}
|
|
46411
46488
|
}
|
|
46412
|
-
|
|
46413
|
-
|
|
46414
|
-
|
|
46415
|
-
|
|
46416
|
-
|
|
46417
|
-
|
|
46418
|
-
|
|
46419
|
-
|
|
46420
|
-
|
|
46421
|
-
|
|
46422
|
-
|
|
46423
|
-
|
|
46424
|
-
|
|
46425
|
-
|
|
46426
|
-
|
|
46427
|
-
|
|
46428
|
-
|
|
46429
|
-
|
|
46430
|
-
|
|
46431
|
-
|
|
46432
|
-
|
|
46433
|
-
|
|
46434
|
-
|
|
46489
|
+
return {
|
|
46490
|
+
FADE_OPACITY: FADE_OPACITY3,
|
|
46491
|
+
fadeToGroup,
|
|
46492
|
+
fadeToEra,
|
|
46493
|
+
fadeToMarker,
|
|
46494
|
+
fadeReset,
|
|
46495
|
+
fadeToTagValue,
|
|
46496
|
+
setTagAttrs
|
|
46497
|
+
};
|
|
46498
|
+
}
|
|
46499
|
+
function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, swimlaneTagGroup, activeTagGroup, onTagStateChange, viewMode) {
|
|
46500
|
+
if (parsed.timelineTagGroups.length === 0) return;
|
|
46501
|
+
const { width, textColor, groupColorMap, solid } = setup;
|
|
46502
|
+
const { FADE_OPACITY: FADE_OPACITY3, fadeReset, fadeToTagValue } = hovers;
|
|
46503
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46504
|
+
const { timelineEvents } = parsed;
|
|
46505
|
+
const LG_HEIGHT = LEGEND_HEIGHT;
|
|
46506
|
+
const LG_PILL_PAD = LEGEND_PILL_PAD;
|
|
46507
|
+
const LG_PILL_FONT_SIZE = LEGEND_PILL_FONT_SIZE;
|
|
46508
|
+
const LG_CAPSULE_PAD = LEGEND_CAPSULE_PAD;
|
|
46509
|
+
const LG_DOT_R = LEGEND_DOT_R;
|
|
46510
|
+
const LG_ENTRY_FONT_SIZE = LEGEND_ENTRY_FONT_SIZE;
|
|
46511
|
+
const LG_ENTRY_DOT_GAP = LEGEND_ENTRY_DOT_GAP;
|
|
46512
|
+
const LG_ENTRY_TRAIL = LEGEND_ENTRY_TRAIL;
|
|
46513
|
+
const LG_ICON_W = 20;
|
|
46514
|
+
const mainSvg = d3Selection22.select(container).select("svg");
|
|
46515
|
+
const mainG = mainSvg.select("g");
|
|
46516
|
+
if (!mainSvg.empty() && !mainG.empty()) {
|
|
46517
|
+
let drawSwimlaneIcon4 = function(parent, x, y, isSwimActive) {
|
|
46518
|
+
const iconG = parent.append("g").attr("class", "tl-swimlane-icon").attr("transform", `translate(${x}, ${y})`).style("cursor", "pointer");
|
|
46519
|
+
const barColor = isSwimActive ? palette.primary : palette.textMuted;
|
|
46520
|
+
const barOpacity = isSwimActive ? 1 : 0.35;
|
|
46521
|
+
const bars = [
|
|
46522
|
+
{ y: 0, w: 8 },
|
|
46523
|
+
{ y: 4, w: 12 },
|
|
46524
|
+
{ y: 8, w: 6 }
|
|
46525
|
+
];
|
|
46526
|
+
for (const bar of bars) {
|
|
46527
|
+
iconG.append("rect").attr("x", 0).attr("y", bar.y).attr("width", bar.w).attr("height", 2).attr("rx", 1).attr("fill", barColor).attr("opacity", barOpacity);
|
|
46435
46528
|
}
|
|
46436
|
-
|
|
46437
|
-
|
|
46438
|
-
|
|
46439
|
-
|
|
46440
|
-
|
|
46441
|
-
|
|
46442
|
-
|
|
46443
|
-
|
|
46444
|
-
|
|
46445
|
-
|
|
46446
|
-
|
|
46447
|
-
|
|
46448
|
-
|
|
46449
|
-
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);
|
|
46450
|
-
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46451
|
-
renderChartTitle(
|
|
46452
|
-
svg,
|
|
46453
|
-
title,
|
|
46454
|
-
parsed.titleLineNumber,
|
|
46455
|
-
width,
|
|
46456
|
-
textColor,
|
|
46457
|
-
onClickItem
|
|
46458
|
-
);
|
|
46459
|
-
renderEras(
|
|
46460
|
-
g,
|
|
46461
|
-
timelineEras,
|
|
46462
|
-
yScale,
|
|
46463
|
-
true,
|
|
46464
|
-
innerWidth,
|
|
46465
|
-
innerHeight,
|
|
46466
|
-
(s, e) => fadeToEra(g, s, e),
|
|
46467
|
-
() => fadeReset(g),
|
|
46468
|
-
timelineScale,
|
|
46469
|
-
tooltip,
|
|
46470
|
-
palette
|
|
46471
|
-
);
|
|
46472
|
-
renderMarkers(
|
|
46473
|
-
g,
|
|
46474
|
-
timelineMarkers,
|
|
46475
|
-
yScale,
|
|
46476
|
-
true,
|
|
46477
|
-
innerWidth,
|
|
46478
|
-
innerHeight,
|
|
46479
|
-
(d) => fadeToMarker(g, d),
|
|
46480
|
-
() => fadeReset(g),
|
|
46481
|
-
timelineScale,
|
|
46482
|
-
tooltip,
|
|
46483
|
-
palette
|
|
46529
|
+
return iconG;
|
|
46530
|
+
}, relayout2 = function() {
|
|
46531
|
+
renderTimeline(
|
|
46532
|
+
container,
|
|
46533
|
+
parsed,
|
|
46534
|
+
palette,
|
|
46535
|
+
isDark,
|
|
46536
|
+
onClickItem,
|
|
46537
|
+
exportDims,
|
|
46538
|
+
currentActiveGroup,
|
|
46539
|
+
currentSwimlaneGroup,
|
|
46540
|
+
onTagStateChange,
|
|
46541
|
+
viewMode
|
|
46484
46542
|
);
|
|
46485
|
-
|
|
46486
|
-
|
|
46487
|
-
|
|
46488
|
-
|
|
46489
|
-
|
|
46490
|
-
|
|
46491
|
-
|
|
46492
|
-
|
|
46493
|
-
|
|
46494
|
-
|
|
46495
|
-
|
|
46496
|
-
|
|
46543
|
+
}, drawLegend2 = function() {
|
|
46544
|
+
mainSvg.selectAll(".tl-tag-legend-group").remove();
|
|
46545
|
+
mainSvg.selectAll(".tl-tag-legend-container").remove();
|
|
46546
|
+
const effectiveColorKey = (currentActiveGroup ?? currentSwimlaneGroup)?.toLowerCase() ?? null;
|
|
46547
|
+
const visibleGroups = viewMode ? legendGroups.filter(
|
|
46548
|
+
(lg) => effectiveColorKey != null && lg.group.name.toLowerCase() === effectiveColorKey
|
|
46549
|
+
) : legendGroups;
|
|
46550
|
+
if (visibleGroups.length === 0) return;
|
|
46551
|
+
const legendContainer = mainSvg.append("g").attr("class", "tl-tag-legend-container");
|
|
46552
|
+
if (currentActiveGroup) {
|
|
46553
|
+
legendContainer.attr(
|
|
46554
|
+
"data-legend-active",
|
|
46555
|
+
currentActiveGroup.toLowerCase()
|
|
46497
46556
|
);
|
|
46498
46557
|
}
|
|
46499
|
-
|
|
46500
|
-
|
|
46501
|
-
|
|
46502
|
-
|
|
46503
|
-
|
|
46504
|
-
|
|
46505
|
-
|
|
46506
|
-
|
|
46507
|
-
|
|
46508
|
-
|
|
46509
|
-
|
|
46510
|
-
|
|
46511
|
-
|
|
46512
|
-
|
|
46513
|
-
|
|
46514
|
-
|
|
46515
|
-
|
|
46516
|
-
|
|
46517
|
-
|
|
46518
|
-
|
|
46519
|
-
|
|
46520
|
-
|
|
46521
|
-
|
|
46522
|
-
|
|
46523
|
-
|
|
46524
|
-
|
|
46525
|
-
|
|
46526
|
-
|
|
46527
|
-
|
|
46528
|
-
|
|
46529
|
-
|
|
46530
|
-
|
|
46531
|
-
|
|
46532
|
-
|
|
46533
|
-
|
|
46534
|
-
|
|
46535
|
-
|
|
46536
|
-
let stroke2 = evColor;
|
|
46537
|
-
if (ev.uncertain) {
|
|
46538
|
-
const gradientId = `uncertain-vg-${ev.lineNumber}`;
|
|
46539
|
-
const strokeGradientId = `uncertain-vg-s-${ev.lineNumber}`;
|
|
46540
|
-
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46541
|
-
const defsEl = d3Selection22.select(defs);
|
|
46542
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46543
|
-
{ offset: "0%", opacity: 1 },
|
|
46544
|
-
{ offset: "80%", opacity: 1 },
|
|
46545
|
-
{ offset: "100%", opacity: 0 }
|
|
46546
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
46547
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46548
|
-
{ offset: "0%", opacity: 1 },
|
|
46549
|
-
{ offset: "80%", opacity: 1 },
|
|
46550
|
-
{ offset: "100%", opacity: 0 }
|
|
46551
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", evColor).attr("stop-opacity", (d) => d.opacity);
|
|
46552
|
-
fill2 = `url(#${gradientId})`;
|
|
46553
|
-
stroke2 = `url(#${strokeGradientId})`;
|
|
46554
|
-
}
|
|
46555
|
-
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);
|
|
46556
|
-
evG.append("text").attr("x", laneCenter + 14).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
|
|
46558
|
+
const iconAddon = viewMode ? 0 : LG_ICON_W;
|
|
46559
|
+
const centralGroups = visibleGroups.map((lg) => ({
|
|
46560
|
+
name: lg.group.name,
|
|
46561
|
+
entries: lg.group.entries.map((e) => ({
|
|
46562
|
+
value: e.value,
|
|
46563
|
+
color: e.color
|
|
46564
|
+
}))
|
|
46565
|
+
}));
|
|
46566
|
+
const centralActive = viewMode ? effectiveColorKey : currentActiveGroup;
|
|
46567
|
+
const centralConfig = {
|
|
46568
|
+
groups: centralGroups,
|
|
46569
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
46570
|
+
mode: "fixed",
|
|
46571
|
+
capsulePillAddonWidth: iconAddon
|
|
46572
|
+
};
|
|
46573
|
+
const centralState = { activeGroup: centralActive };
|
|
46574
|
+
const centralCallbacks = viewMode ? {} : {
|
|
46575
|
+
onGroupToggle: (groupName) => {
|
|
46576
|
+
currentActiveGroup = currentActiveGroup === groupName.toLowerCase() ? null : groupName.toLowerCase();
|
|
46577
|
+
drawLegend2();
|
|
46578
|
+
recolorEvents2();
|
|
46579
|
+
onTagStateChange?.(currentActiveGroup, currentSwimlaneGroup);
|
|
46580
|
+
},
|
|
46581
|
+
onEntryHover: (groupName, entryValue) => {
|
|
46582
|
+
const tagKey = groupName.toLowerCase();
|
|
46583
|
+
if (entryValue) {
|
|
46584
|
+
const tagVal = entryValue.toLowerCase();
|
|
46585
|
+
fadeToTagValue(mainG, tagKey, tagVal);
|
|
46586
|
+
mainSvg.selectAll("[data-legend-entry]").each(function() {
|
|
46587
|
+
const el = d3Selection22.select(this);
|
|
46588
|
+
const ev = el.attr("data-legend-entry");
|
|
46589
|
+
const eg = el.attr("data-tag-group") ?? el.node()?.closest?.("[data-tag-group]")?.getAttribute("data-tag-group");
|
|
46590
|
+
el.attr(
|
|
46591
|
+
"opacity",
|
|
46592
|
+
eg === tagKey && ev === tagVal ? 1 : FADE_OPACITY3
|
|
46593
|
+
);
|
|
46594
|
+
});
|
|
46557
46595
|
} else {
|
|
46558
|
-
|
|
46559
|
-
|
|
46596
|
+
fadeReset(mainG);
|
|
46597
|
+
mainSvg.selectAll("[data-legend-entry]").attr("opacity", 1);
|
|
46598
|
+
}
|
|
46599
|
+
},
|
|
46600
|
+
onGroupRendered: (groupName, groupEl, isActive) => {
|
|
46601
|
+
const groupKey = groupName.toLowerCase();
|
|
46602
|
+
groupEl.attr("data-tag-group", groupKey);
|
|
46603
|
+
if (isActive && !viewMode) {
|
|
46604
|
+
const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
|
|
46605
|
+
const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
46606
|
+
const pillXOff = LG_CAPSULE_PAD;
|
|
46607
|
+
const iconX = pillXOff + pillWidth3 + 5;
|
|
46608
|
+
const iconY = (LG_HEIGHT - 10) / 2;
|
|
46609
|
+
const iconEl = drawSwimlaneIcon4(
|
|
46610
|
+
groupEl,
|
|
46611
|
+
iconX,
|
|
46612
|
+
iconY,
|
|
46613
|
+
isSwimActive
|
|
46614
|
+
);
|
|
46615
|
+
iconEl.attr("data-swimlane-toggle", groupKey).on("click", (event) => {
|
|
46616
|
+
event.stopPropagation();
|
|
46617
|
+
currentSwimlaneGroup = currentSwimlaneGroup === groupKey ? null : groupKey;
|
|
46618
|
+
onTagStateChange?.(
|
|
46619
|
+
currentActiveGroup,
|
|
46620
|
+
currentSwimlaneGroup
|
|
46621
|
+
);
|
|
46622
|
+
relayout2();
|
|
46623
|
+
});
|
|
46560
46624
|
}
|
|
46561
46625
|
}
|
|
46562
|
-
});
|
|
46563
|
-
} else {
|
|
46564
|
-
const scaleMargin = timelineScale ? 40 : 0;
|
|
46565
|
-
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46566
|
-
const margin = {
|
|
46567
|
-
top: 104 + markerMargin + tagLegendReserve,
|
|
46568
|
-
right: 200,
|
|
46569
|
-
bottom: 40,
|
|
46570
|
-
left: 60 + scaleMargin
|
|
46571
46626
|
};
|
|
46572
|
-
const
|
|
46573
|
-
|
|
46574
|
-
|
|
46575
|
-
|
|
46576
|
-
|
|
46577
|
-
|
|
46578
|
-
|
|
46579
|
-
|
|
46580
|
-
|
|
46581
|
-
title,
|
|
46582
|
-
parsed.titleLineNumber,
|
|
46583
|
-
width,
|
|
46584
|
-
textColor,
|
|
46585
|
-
onClickItem
|
|
46586
|
-
);
|
|
46587
|
-
renderEras(
|
|
46588
|
-
g,
|
|
46589
|
-
timelineEras,
|
|
46590
|
-
yScale,
|
|
46591
|
-
true,
|
|
46592
|
-
innerWidth,
|
|
46593
|
-
innerHeight,
|
|
46594
|
-
(s, e) => fadeToEra(g, s, e),
|
|
46595
|
-
() => fadeReset(g),
|
|
46596
|
-
timelineScale,
|
|
46597
|
-
tooltip,
|
|
46598
|
-
palette
|
|
46599
|
-
);
|
|
46600
|
-
renderMarkers(
|
|
46601
|
-
g,
|
|
46602
|
-
timelineMarkers,
|
|
46603
|
-
yScale,
|
|
46604
|
-
true,
|
|
46605
|
-
innerWidth,
|
|
46606
|
-
innerHeight,
|
|
46607
|
-
(d) => fadeToMarker(g, d),
|
|
46608
|
-
() => fadeReset(g),
|
|
46609
|
-
timelineScale,
|
|
46610
|
-
tooltip,
|
|
46611
|
-
palette
|
|
46627
|
+
const legendInnerG = legendContainer.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
46628
|
+
renderLegendD3(
|
|
46629
|
+
legendInnerG,
|
|
46630
|
+
centralConfig,
|
|
46631
|
+
centralState,
|
|
46632
|
+
palette,
|
|
46633
|
+
isDark,
|
|
46634
|
+
centralCallbacks,
|
|
46635
|
+
width
|
|
46612
46636
|
);
|
|
46637
|
+
}, recolorEvents2 = function() {
|
|
46638
|
+
const colorTG = currentActiveGroup ?? swimlaneTagGroup ?? null;
|
|
46639
|
+
mainG.selectAll(".tl-event").each(function() {
|
|
46640
|
+
const el = d3Selection22.select(this);
|
|
46641
|
+
const lineNum = el.attr("data-line-number");
|
|
46642
|
+
const ev = lineNum ? eventByLine.get(lineNum) : void 0;
|
|
46643
|
+
if (!ev) return;
|
|
46644
|
+
let color;
|
|
46645
|
+
if (colorTG) {
|
|
46646
|
+
const tagColor = resolveTagColor(
|
|
46647
|
+
ev.metadata,
|
|
46648
|
+
parsed.timelineTagGroups,
|
|
46649
|
+
colorTG
|
|
46650
|
+
);
|
|
46651
|
+
color = tagColor ?? (ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor);
|
|
46652
|
+
} else {
|
|
46653
|
+
color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
|
|
46654
|
+
}
|
|
46655
|
+
el.selectAll("rect").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
46656
|
+
el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
46657
|
+
});
|
|
46658
|
+
};
|
|
46659
|
+
var drawSwimlaneIcon3 = drawSwimlaneIcon4, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
|
|
46660
|
+
const legendY = title ? 50 : 10;
|
|
46661
|
+
const legendGroups = parsed.timelineTagGroups.map((g) => {
|
|
46662
|
+
const pillW = measureLegendText(g.name, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
46663
|
+
const iconSpace = viewMode ? 8 : LG_ICON_W + 4;
|
|
46664
|
+
let entryX = LG_CAPSULE_PAD + pillW + iconSpace;
|
|
46665
|
+
for (const entry of g.entries) {
|
|
46666
|
+
const textX = entryX + LG_DOT_R * 2 + LG_ENTRY_DOT_GAP;
|
|
46667
|
+
entryX = textX + measureLegendText(entry.value, LG_ENTRY_FONT_SIZE) + LG_ENTRY_TRAIL;
|
|
46668
|
+
}
|
|
46669
|
+
return {
|
|
46670
|
+
group: g,
|
|
46671
|
+
minifiedWidth: pillW,
|
|
46672
|
+
expandedWidth: entryX + LG_CAPSULE_PAD
|
|
46673
|
+
};
|
|
46674
|
+
});
|
|
46675
|
+
let currentActiveGroup = activeTagGroup ?? null;
|
|
46676
|
+
let currentSwimlaneGroup = swimlaneTagGroup ?? null;
|
|
46677
|
+
const eventByLine = /* @__PURE__ */ new Map();
|
|
46678
|
+
for (const ev of timelineEvents) {
|
|
46679
|
+
eventByLine.set(String(ev.lineNumber), ev);
|
|
46680
|
+
}
|
|
46681
|
+
drawLegend2();
|
|
46682
|
+
}
|
|
46683
|
+
}
|
|
46684
|
+
function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
46685
|
+
const {
|
|
46686
|
+
width,
|
|
46687
|
+
height,
|
|
46688
|
+
tooltip,
|
|
46689
|
+
solid,
|
|
46690
|
+
textColor,
|
|
46691
|
+
bgColor,
|
|
46692
|
+
bg,
|
|
46693
|
+
groupColorMap,
|
|
46694
|
+
eventColor,
|
|
46695
|
+
minDate,
|
|
46696
|
+
maxDate,
|
|
46697
|
+
datePadding,
|
|
46698
|
+
earliestStartDateStr,
|
|
46699
|
+
latestEndDateStr,
|
|
46700
|
+
tagLegendReserve
|
|
46701
|
+
} = setup;
|
|
46702
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
46703
|
+
const {
|
|
46704
|
+
timelineEvents,
|
|
46705
|
+
timelineGroups,
|
|
46706
|
+
timelineEras,
|
|
46707
|
+
timelineMarkers,
|
|
46708
|
+
timelineScale
|
|
46709
|
+
} = parsed;
|
|
46710
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46711
|
+
const BAR_H2 = 22;
|
|
46712
|
+
const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
|
|
46713
|
+
const scaleMargin = timelineScale ? 24 : 0;
|
|
46714
|
+
const ERA_ROW_H = 22;
|
|
46715
|
+
const MARKER_ROW_H = 22;
|
|
46716
|
+
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46717
|
+
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46718
|
+
const topScaleH = timelineScale ? 40 : 0;
|
|
46719
|
+
const margin = {
|
|
46720
|
+
top: 104 + topScaleH + eraReserve + markerReserve + tagLegendReserve,
|
|
46721
|
+
right: 40,
|
|
46722
|
+
bottom: 40 + scaleMargin,
|
|
46723
|
+
left: 60
|
|
46724
|
+
};
|
|
46725
|
+
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46726
|
+
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46727
|
+
const innerWidth = width - margin.left - margin.right;
|
|
46728
|
+
const innerHeight = height - margin.top - margin.bottom;
|
|
46729
|
+
const rowH = Math.min(28, innerHeight / sorted.length);
|
|
46730
|
+
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
46731
|
+
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
46732
|
+
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46733
|
+
renderChartTitle(
|
|
46734
|
+
svg,
|
|
46735
|
+
title,
|
|
46736
|
+
parsed.titleLineNumber,
|
|
46737
|
+
width,
|
|
46738
|
+
textColor,
|
|
46739
|
+
onClickItem
|
|
46740
|
+
);
|
|
46741
|
+
renderEras(
|
|
46742
|
+
g,
|
|
46743
|
+
timelineEras,
|
|
46744
|
+
xScale,
|
|
46745
|
+
false,
|
|
46746
|
+
innerWidth,
|
|
46747
|
+
innerHeight,
|
|
46748
|
+
(s, e) => fadeToEra(g, s, e),
|
|
46749
|
+
() => fadeReset(g),
|
|
46750
|
+
timelineScale,
|
|
46751
|
+
tooltip,
|
|
46752
|
+
palette,
|
|
46753
|
+
eraReserve ? eraLabelY : void 0
|
|
46754
|
+
);
|
|
46755
|
+
renderMarkers(
|
|
46756
|
+
g,
|
|
46757
|
+
timelineMarkers,
|
|
46758
|
+
xScale,
|
|
46759
|
+
false,
|
|
46760
|
+
innerWidth,
|
|
46761
|
+
innerHeight,
|
|
46762
|
+
(d) => fadeToMarker(g, d),
|
|
46763
|
+
() => fadeReset(g),
|
|
46764
|
+
timelineScale,
|
|
46765
|
+
tooltip,
|
|
46766
|
+
palette,
|
|
46767
|
+
markerReserve ? markerLabelY : void 0
|
|
46768
|
+
);
|
|
46769
|
+
if (timelineScale) {
|
|
46770
|
+
renderTimeScale(
|
|
46771
|
+
g,
|
|
46772
|
+
xScale,
|
|
46773
|
+
false,
|
|
46774
|
+
innerWidth,
|
|
46775
|
+
innerHeight,
|
|
46776
|
+
textColor,
|
|
46777
|
+
minDate,
|
|
46778
|
+
maxDate,
|
|
46779
|
+
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46780
|
+
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46781
|
+
);
|
|
46782
|
+
}
|
|
46783
|
+
if (timelineGroups.length > 0) {
|
|
46784
|
+
const legendY = timelineScale ? -75 : -55;
|
|
46785
|
+
renderTimelineGroupLegend(
|
|
46786
|
+
g,
|
|
46787
|
+
timelineGroups,
|
|
46788
|
+
groupColorMap,
|
|
46789
|
+
textColor,
|
|
46790
|
+
palette,
|
|
46791
|
+
isDark,
|
|
46792
|
+
legendY,
|
|
46793
|
+
(name) => fadeToGroup(g, name),
|
|
46794
|
+
() => fadeReset(g)
|
|
46795
|
+
);
|
|
46796
|
+
}
|
|
46797
|
+
sorted.forEach((ev, i) => {
|
|
46798
|
+
const y = i * rowH + rowH / 2;
|
|
46799
|
+
const x = xScale(parseTimelineDate(ev.date));
|
|
46800
|
+
const color = eventColor(ev);
|
|
46801
|
+
const evG = g.append("g").attr("class", "tl-event").attr("data-group", ev.group || "").attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
46802
|
+
"data-end-date",
|
|
46803
|
+
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
46804
|
+
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
46805
|
+
if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);
|
|
46613
46806
|
if (timelineScale) {
|
|
46614
|
-
|
|
46807
|
+
showEventDatesOnScale(
|
|
46615
46808
|
g,
|
|
46616
|
-
|
|
46617
|
-
|
|
46618
|
-
|
|
46809
|
+
xScale,
|
|
46810
|
+
ev.date,
|
|
46811
|
+
ev.endDate,
|
|
46619
46812
|
innerHeight,
|
|
46620
|
-
|
|
46621
|
-
minDate,
|
|
46622
|
-
maxDate,
|
|
46623
|
-
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46624
|
-
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46813
|
+
color
|
|
46625
46814
|
);
|
|
46815
|
+
} else {
|
|
46816
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46626
46817
|
}
|
|
46627
|
-
|
|
46628
|
-
|
|
46629
|
-
|
|
46630
|
-
|
|
46631
|
-
|
|
46632
|
-
|
|
46633
|
-
palette,
|
|
46634
|
-
isDark,
|
|
46635
|
-
-55,
|
|
46636
|
-
(name) => fadeToGroup(g, name),
|
|
46637
|
-
() => fadeReset(g)
|
|
46638
|
-
);
|
|
46818
|
+
}).on("mouseleave", function() {
|
|
46819
|
+
fadeReset(g);
|
|
46820
|
+
if (timelineScale) {
|
|
46821
|
+
hideEventDatesOnScale(g);
|
|
46822
|
+
} else {
|
|
46823
|
+
hideTooltip(tooltip);
|
|
46639
46824
|
}
|
|
46640
|
-
|
|
46641
|
-
|
|
46642
|
-
|
|
46643
|
-
|
|
46644
|
-
|
|
46645
|
-
|
|
46646
|
-
|
|
46647
|
-
|
|
46648
|
-
|
|
46825
|
+
}).on("mousemove", function(event) {
|
|
46826
|
+
if (!timelineScale) {
|
|
46827
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46828
|
+
}
|
|
46829
|
+
}).on("click", () => {
|
|
46830
|
+
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
46831
|
+
});
|
|
46832
|
+
setTagAttrs(evG, ev);
|
|
46833
|
+
if (ev.endDate) {
|
|
46834
|
+
const x2 = xScale(parseTimelineDate(ev.endDate));
|
|
46835
|
+
const rectW = Math.max(x2 - x, 4);
|
|
46836
|
+
const estLabelWidth = ev.label.length * 7 + 16;
|
|
46837
|
+
const labelFitsInside = rectW >= estLabelWidth;
|
|
46838
|
+
let fill2 = shapeFill(palette, color, isDark, { solid });
|
|
46839
|
+
let stroke2 = color;
|
|
46840
|
+
if (ev.uncertain) {
|
|
46841
|
+
const gradientId = `uncertain-ts-${ev.lineNumber}`;
|
|
46842
|
+
const strokeGradientId = `uncertain-ts-s-${ev.lineNumber}`;
|
|
46843
|
+
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46844
|
+
const defsEl = d3Selection22.select(defs);
|
|
46845
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
46846
|
+
{ offset: "0%", opacity: 1 },
|
|
46847
|
+
{ offset: "80%", opacity: 1 },
|
|
46848
|
+
{ offset: "100%", opacity: 0 }
|
|
46849
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
46850
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
46851
|
+
{ offset: "0%", opacity: 1 },
|
|
46852
|
+
{ offset: "80%", opacity: 1 },
|
|
46853
|
+
{ offset: "100%", opacity: 0 }
|
|
46854
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", color).attr("stop-opacity", (d) => d.opacity);
|
|
46855
|
+
fill2 = `url(#${gradientId})`;
|
|
46856
|
+
stroke2 = `url(#${strokeGradientId})`;
|
|
46857
|
+
}
|
|
46858
|
+
evG.append("rect").attr("x", x).attr("y", y - BAR_H2 / 2).attr("width", rectW).attr("height", BAR_H2).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
46859
|
+
if (labelFitsInside) {
|
|
46860
|
+
evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46861
|
+
} else {
|
|
46862
|
+
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
46863
|
+
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
46864
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46865
|
+
evG.append("text").attr("x", flipLeft ? x - 6 : x + rectW + 6).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46866
|
+
}
|
|
46867
|
+
} else {
|
|
46868
|
+
const estLabelWidth = ev.label.length * 7;
|
|
46869
|
+
const wouldFlipLeft = x > innerWidth * 0.6;
|
|
46870
|
+
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
46871
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46872
|
+
evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color).attr("stroke-width", 2);
|
|
46873
|
+
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
46874
|
+
}
|
|
46875
|
+
});
|
|
46876
|
+
}
|
|
46877
|
+
function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
46878
|
+
const {
|
|
46879
|
+
width,
|
|
46880
|
+
height,
|
|
46881
|
+
tooltip,
|
|
46882
|
+
solid,
|
|
46883
|
+
textColor,
|
|
46884
|
+
bgColor,
|
|
46885
|
+
bg,
|
|
46886
|
+
groupColorMap,
|
|
46887
|
+
tagLanes,
|
|
46888
|
+
eventColor,
|
|
46889
|
+
minDate,
|
|
46890
|
+
maxDate,
|
|
46891
|
+
datePadding,
|
|
46892
|
+
earliestStartDateStr,
|
|
46893
|
+
latestEndDateStr,
|
|
46894
|
+
tagLegendReserve
|
|
46895
|
+
} = setup;
|
|
46896
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
46897
|
+
const {
|
|
46898
|
+
timelineEvents,
|
|
46899
|
+
timelineGroups,
|
|
46900
|
+
timelineEras,
|
|
46901
|
+
timelineMarkers,
|
|
46902
|
+
timelineScale,
|
|
46903
|
+
timelineSwimlanes
|
|
46904
|
+
} = parsed;
|
|
46905
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46906
|
+
const BAR_H2 = 22;
|
|
46907
|
+
const GROUP_GAP3 = 12;
|
|
46908
|
+
let lanes;
|
|
46909
|
+
if (tagLanes) {
|
|
46910
|
+
lanes = tagLanes;
|
|
46911
|
+
} else {
|
|
46912
|
+
const groupNames = timelineGroups.map((gr) => gr.name);
|
|
46913
|
+
const ungroupedEvents = timelineEvents.filter(
|
|
46914
|
+
(ev) => ev.group === null || !groupNames.includes(ev.group)
|
|
46915
|
+
);
|
|
46916
|
+
const laneNames = ungroupedEvents.length > 0 ? [...groupNames, "(Other)"] : groupNames;
|
|
46917
|
+
lanes = laneNames.map((name) => ({
|
|
46918
|
+
name,
|
|
46919
|
+
events: timelineEvents.filter(
|
|
46920
|
+
(ev) => name === "(Other)" ? ev.group === null || !groupNames.includes(ev.group) : ev.group === name
|
|
46921
|
+
)
|
|
46922
|
+
}));
|
|
46923
|
+
}
|
|
46924
|
+
const totalEventRows = lanes.reduce((s, l) => s + l.events.length, 0);
|
|
46925
|
+
const scaleMargin = timelineScale ? 24 : 0;
|
|
46926
|
+
const ERA_ROW_H = 22;
|
|
46927
|
+
const MARKER_ROW_H = 22;
|
|
46928
|
+
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46929
|
+
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46930
|
+
const topScaleH = timelineScale ? 40 : 0;
|
|
46931
|
+
const maxGroupNameLen = Math.max(...lanes.map((l) => l.name.length));
|
|
46932
|
+
const dynamicLeftMargin = Math.max(120, maxGroupNameLen * 7 + 30);
|
|
46933
|
+
const baseTopMargin = title ? 50 : 20;
|
|
46934
|
+
const margin = {
|
|
46935
|
+
top: baseTopMargin + topScaleH + eraReserve + markerReserve + tagLegendReserve,
|
|
46936
|
+
right: 40,
|
|
46937
|
+
bottom: 40 + scaleMargin,
|
|
46938
|
+
left: dynamicLeftMargin
|
|
46939
|
+
};
|
|
46940
|
+
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46941
|
+
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46942
|
+
const innerWidth = width - margin.left - margin.right;
|
|
46943
|
+
const innerHeight = height - margin.top - margin.bottom;
|
|
46944
|
+
const totalGaps = (lanes.length - 1) * GROUP_GAP3;
|
|
46945
|
+
const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);
|
|
46946
|
+
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
46947
|
+
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
46948
|
+
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46949
|
+
renderChartTitle(
|
|
46950
|
+
svg,
|
|
46951
|
+
title,
|
|
46952
|
+
parsed.titleLineNumber,
|
|
46953
|
+
width,
|
|
46954
|
+
textColor,
|
|
46955
|
+
onClickItem
|
|
46956
|
+
);
|
|
46957
|
+
renderEras(
|
|
46958
|
+
g,
|
|
46959
|
+
timelineEras,
|
|
46960
|
+
xScale,
|
|
46961
|
+
false,
|
|
46962
|
+
innerWidth,
|
|
46963
|
+
innerHeight,
|
|
46964
|
+
(s, e) => fadeToEra(g, s, e),
|
|
46965
|
+
() => fadeReset(g),
|
|
46966
|
+
timelineScale,
|
|
46967
|
+
tooltip,
|
|
46968
|
+
palette,
|
|
46969
|
+
eraReserve ? eraLabelY : void 0
|
|
46970
|
+
);
|
|
46971
|
+
renderMarkers(
|
|
46972
|
+
g,
|
|
46973
|
+
timelineMarkers,
|
|
46974
|
+
xScale,
|
|
46975
|
+
false,
|
|
46976
|
+
innerWidth,
|
|
46977
|
+
innerHeight,
|
|
46978
|
+
(d) => fadeToMarker(g, d),
|
|
46979
|
+
() => fadeReset(g),
|
|
46980
|
+
timelineScale,
|
|
46981
|
+
tooltip,
|
|
46982
|
+
palette,
|
|
46983
|
+
markerReserve ? markerLabelY : void 0
|
|
46984
|
+
);
|
|
46985
|
+
if (timelineScale) {
|
|
46986
|
+
renderTimeScale(
|
|
46987
|
+
g,
|
|
46988
|
+
xScale,
|
|
46989
|
+
false,
|
|
46990
|
+
innerWidth,
|
|
46991
|
+
innerHeight,
|
|
46992
|
+
textColor,
|
|
46993
|
+
minDate,
|
|
46994
|
+
maxDate,
|
|
46995
|
+
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46996
|
+
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46997
|
+
);
|
|
46998
|
+
}
|
|
46999
|
+
let curY = 0;
|
|
47000
|
+
if (timelineSwimlanes || tagLanes) {
|
|
47001
|
+
let swimY = 0;
|
|
47002
|
+
lanes.forEach((lane, idx) => {
|
|
47003
|
+
const laneSpan = lane.events.length * rowH;
|
|
47004
|
+
const fillColor = idx % 2 === 0 ? textColor : "transparent";
|
|
47005
|
+
g.append("rect").attr("class", "tl-swimlane").attr("data-group", lane.name).attr("x", -margin.left).attr("y", swimY).attr("width", innerWidth + margin.left).attr("height", laneSpan + (idx < lanes.length - 1 ? GROUP_GAP3 : 0)).attr("fill", fillColor).attr("opacity", 0.06);
|
|
47006
|
+
swimY += laneSpan + GROUP_GAP3;
|
|
47007
|
+
});
|
|
47008
|
+
}
|
|
47009
|
+
for (const lane of lanes) {
|
|
47010
|
+
const laneColor = groupColorMap.get(lane.name) ?? textColor;
|
|
47011
|
+
const laneSpan = lane.events.length * rowH;
|
|
47012
|
+
const group = timelineGroups.find((grp) => grp.name === lane.name);
|
|
47013
|
+
const headerG = g.append("g").attr("class", "tl-lane-header").attr("data-group", lane.name).style("cursor", "pointer").on("mouseenter", () => fadeToGroup(g, lane.name)).on("mouseleave", () => fadeReset(g)).on("click", () => {
|
|
47014
|
+
if (onClickItem && group?.lineNumber) onClickItem(group.lineNumber);
|
|
47015
|
+
});
|
|
47016
|
+
headerG.append("text").attr("x", -margin.left + 10).attr("y", curY + laneSpan / 2).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", laneColor).attr("font-size", "12px").attr("font-weight", "600").text(lane.name);
|
|
47017
|
+
lane.events.forEach((ev, i) => {
|
|
47018
|
+
const y = curY + i * rowH + rowH / 2;
|
|
47019
|
+
const x = xScale(parseTimelineDate(ev.date));
|
|
47020
|
+
const evG = g.append("g").attr("class", "tl-event").attr("data-group", lane.name).attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
47021
|
+
"data-end-date",
|
|
47022
|
+
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
47023
|
+
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
47024
|
+
fadeToGroup(g, lane.name);
|
|
47025
|
+
if (timelineScale) {
|
|
47026
|
+
showEventDatesOnScale(
|
|
47027
|
+
g,
|
|
47028
|
+
xScale,
|
|
47029
|
+
ev.date,
|
|
47030
|
+
ev.endDate,
|
|
47031
|
+
innerHeight,
|
|
47032
|
+
laneColor
|
|
47033
|
+
);
|
|
47034
|
+
} else {
|
|
46649
47035
|
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46650
|
-
}
|
|
46651
|
-
|
|
47036
|
+
}
|
|
47037
|
+
}).on("mouseleave", function() {
|
|
47038
|
+
fadeReset(g);
|
|
47039
|
+
if (timelineScale) {
|
|
47040
|
+
hideEventDatesOnScale(g);
|
|
47041
|
+
} else {
|
|
46652
47042
|
hideTooltip(tooltip);
|
|
46653
|
-
}
|
|
47043
|
+
}
|
|
47044
|
+
}).on("mousemove", function(event) {
|
|
47045
|
+
if (!timelineScale) {
|
|
46654
47046
|
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46655
|
-
}
|
|
46656
|
-
|
|
46657
|
-
|
|
46658
|
-
|
|
46659
|
-
|
|
46660
|
-
|
|
46661
|
-
|
|
46662
|
-
|
|
46663
|
-
|
|
46664
|
-
|
|
46665
|
-
|
|
46666
|
-
|
|
46667
|
-
|
|
46668
|
-
|
|
46669
|
-
|
|
46670
|
-
|
|
46671
|
-
|
|
46672
|
-
|
|
46673
|
-
|
|
46674
|
-
|
|
46675
|
-
|
|
46676
|
-
|
|
46677
|
-
|
|
46678
|
-
|
|
46679
|
-
|
|
46680
|
-
|
|
46681
|
-
|
|
46682
|
-
|
|
46683
|
-
|
|
47047
|
+
}
|
|
47048
|
+
}).on("click", () => {
|
|
47049
|
+
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
47050
|
+
});
|
|
47051
|
+
setTagAttrs(evG, ev);
|
|
47052
|
+
const evColor = eventColor(ev);
|
|
47053
|
+
if (ev.endDate) {
|
|
47054
|
+
const x2 = xScale(parseTimelineDate(ev.endDate));
|
|
47055
|
+
const rectW = Math.max(x2 - x, 4);
|
|
47056
|
+
const estLabelWidth = ev.label.length * 7 + 16;
|
|
47057
|
+
const labelFitsInside = rectW >= estLabelWidth;
|
|
47058
|
+
let fill2 = shapeFill(palette, evColor, isDark, { solid });
|
|
47059
|
+
let stroke2 = evColor;
|
|
47060
|
+
if (ev.uncertain) {
|
|
47061
|
+
const gradientId = `uncertain-${ev.lineNumber}`;
|
|
47062
|
+
const strokeGradientId = `uncertain-s-${ev.lineNumber}`;
|
|
47063
|
+
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
47064
|
+
const defsEl = d3Selection22.select(defs);
|
|
47065
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
47066
|
+
{ offset: "0%", opacity: 1 },
|
|
47067
|
+
{ offset: "80%", opacity: 1 },
|
|
47068
|
+
{ offset: "100%", opacity: 0 }
|
|
47069
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(evColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47070
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
47071
|
+
{ offset: "0%", opacity: 1 },
|
|
47072
|
+
{ offset: "80%", opacity: 1 },
|
|
47073
|
+
{ offset: "100%", opacity: 0 }
|
|
47074
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", evColor).attr("stop-opacity", (d) => d.opacity);
|
|
47075
|
+
fill2 = `url(#${gradientId})`;
|
|
47076
|
+
stroke2 = `url(#${strokeGradientId})`;
|
|
47077
|
+
}
|
|
47078
|
+
evG.append("rect").attr("x", x).attr("y", y - BAR_H2 / 2).attr("width", rectW).attr("height", BAR_H2).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
47079
|
+
if (labelFitsInside) {
|
|
47080
|
+
evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46684
47081
|
} else {
|
|
46685
|
-
|
|
46686
|
-
|
|
47082
|
+
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
47083
|
+
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
47084
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47085
|
+
evG.append("text").attr("x", flipLeft ? x - 6 : x + rectW + 6).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46687
47086
|
}
|
|
46688
|
-
|
|
46689
|
-
|
|
46690
|
-
|
|
46691
|
-
|
|
46692
|
-
|
|
46693
|
-
|
|
46694
|
-
).attr("dy", "0.35em").attr("text-anchor", "end").attr("fill",
|
|
47087
|
+
} else {
|
|
47088
|
+
const estLabelWidth = ev.label.length * 7;
|
|
47089
|
+
const wouldFlipLeft = x > innerWidth * 0.6;
|
|
47090
|
+
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
47091
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47092
|
+
evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", shapeFill(palette, evColor, isDark, { solid })).attr("stroke", evColor).attr("stroke-width", 2);
|
|
47093
|
+
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
46695
47094
|
}
|
|
46696
|
-
}
|
|
46697
|
-
|
|
47095
|
+
});
|
|
47096
|
+
curY += laneSpan + GROUP_GAP3;
|
|
46698
47097
|
}
|
|
46699
|
-
|
|
46700
|
-
|
|
46701
|
-
const
|
|
46702
|
-
|
|
46703
|
-
|
|
47098
|
+
}
|
|
47099
|
+
function renderTimelineVertical(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
47100
|
+
const {
|
|
47101
|
+
width,
|
|
47102
|
+
height,
|
|
47103
|
+
tooltip,
|
|
47104
|
+
solid,
|
|
47105
|
+
textColor,
|
|
47106
|
+
mutedColor,
|
|
47107
|
+
bgColor,
|
|
47108
|
+
bg,
|
|
47109
|
+
groupColorMap,
|
|
47110
|
+
tagLanes,
|
|
47111
|
+
eventColor,
|
|
47112
|
+
minDate,
|
|
47113
|
+
maxDate,
|
|
47114
|
+
datePadding,
|
|
47115
|
+
earliestStartDateStr,
|
|
47116
|
+
latestEndDateStr,
|
|
47117
|
+
tagLegendReserve
|
|
47118
|
+
} = setup;
|
|
47119
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
47120
|
+
const {
|
|
47121
|
+
timelineEvents,
|
|
47122
|
+
timelineGroups,
|
|
47123
|
+
timelineEras,
|
|
47124
|
+
timelineMarkers,
|
|
47125
|
+
timelineSort,
|
|
47126
|
+
timelineScale,
|
|
47127
|
+
timelineSwimlanes
|
|
47128
|
+
} = parsed;
|
|
47129
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
47130
|
+
const useGroupedVertical = tagLanes != null || timelineSort === "group" && timelineGroups.length > 0;
|
|
47131
|
+
if (useGroupedVertical) {
|
|
47132
|
+
let laneNames;
|
|
47133
|
+
let laneEventsByName;
|
|
46704
47134
|
if (tagLanes) {
|
|
46705
|
-
|
|
47135
|
+
laneNames = tagLanes.map((l) => l.name);
|
|
47136
|
+
laneEventsByName = new Map(tagLanes.map((l) => [l.name, l.events]));
|
|
46706
47137
|
} else {
|
|
46707
47138
|
const groupNames = timelineGroups.map((gr) => gr.name);
|
|
46708
47139
|
const ungroupedEvents = timelineEvents.filter(
|
|
46709
47140
|
(ev) => ev.group === null || !groupNames.includes(ev.group)
|
|
46710
47141
|
);
|
|
46711
|
-
|
|
46712
|
-
|
|
46713
|
-
name
|
|
46714
|
-
|
|
46715
|
-
|
|
46716
|
-
|
|
46717
|
-
|
|
47142
|
+
laneNames = ungroupedEvents.length > 0 ? [...groupNames, "(Other)"] : groupNames;
|
|
47143
|
+
laneEventsByName = new Map(
|
|
47144
|
+
laneNames.map((name) => [
|
|
47145
|
+
name,
|
|
47146
|
+
timelineEvents.filter(
|
|
47147
|
+
(ev) => name === "(Other)" ? ev.group === null || !groupNames.includes(ev.group) : ev.group === name
|
|
47148
|
+
)
|
|
47149
|
+
])
|
|
47150
|
+
);
|
|
46718
47151
|
}
|
|
46719
|
-
const
|
|
46720
|
-
const scaleMargin = timelineScale ?
|
|
46721
|
-
const
|
|
46722
|
-
const MARKER_ROW_H = 22;
|
|
46723
|
-
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46724
|
-
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46725
|
-
const topScaleH = timelineScale ? 40 : 0;
|
|
46726
|
-
const maxGroupNameLen = Math.max(...lanes.map((l) => l.name.length));
|
|
46727
|
-
const dynamicLeftMargin = Math.max(120, maxGroupNameLen * 7 + 30);
|
|
46728
|
-
const baseTopMargin = title ? 50 : 20;
|
|
47152
|
+
const laneCount = laneNames.length;
|
|
47153
|
+
const scaleMargin = timelineScale ? 40 : 0;
|
|
47154
|
+
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46729
47155
|
const margin = {
|
|
46730
|
-
top:
|
|
46731
|
-
right: 40,
|
|
46732
|
-
bottom: 40
|
|
46733
|
-
left:
|
|
47156
|
+
top: 104 + markerMargin + tagLegendReserve,
|
|
47157
|
+
right: 40 + scaleMargin,
|
|
47158
|
+
bottom: 40,
|
|
47159
|
+
left: 60 + scaleMargin
|
|
46734
47160
|
};
|
|
46735
|
-
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46736
|
-
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46737
47161
|
const innerWidth = width - margin.left - margin.right;
|
|
46738
47162
|
const innerHeight = height - margin.top - margin.bottom;
|
|
46739
|
-
const
|
|
46740
|
-
const
|
|
46741
|
-
const
|
|
46742
|
-
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
47163
|
+
const laneWidth = innerWidth / laneCount;
|
|
47164
|
+
const yScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
|
|
47165
|
+
const svg = d3Selection22.select(container).append("svg").attr("viewBox", `0 0 ${width} ${height}`).attr("width", exportDims ? width : "100%").attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
46743
47166
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46744
47167
|
renderChartTitle(
|
|
46745
47168
|
svg,
|
|
@@ -46752,36 +47175,34 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46752
47175
|
renderEras(
|
|
46753
47176
|
g,
|
|
46754
47177
|
timelineEras,
|
|
46755
|
-
|
|
46756
|
-
|
|
47178
|
+
yScale,
|
|
47179
|
+
true,
|
|
46757
47180
|
innerWidth,
|
|
46758
47181
|
innerHeight,
|
|
46759
47182
|
(s, e) => fadeToEra(g, s, e),
|
|
46760
47183
|
() => fadeReset(g),
|
|
46761
47184
|
timelineScale,
|
|
46762
47185
|
tooltip,
|
|
46763
|
-
palette
|
|
46764
|
-
eraReserve ? eraLabelY : void 0
|
|
47186
|
+
palette
|
|
46765
47187
|
);
|
|
46766
47188
|
renderMarkers(
|
|
46767
47189
|
g,
|
|
46768
47190
|
timelineMarkers,
|
|
46769
|
-
|
|
46770
|
-
|
|
47191
|
+
yScale,
|
|
47192
|
+
true,
|
|
46771
47193
|
innerWidth,
|
|
46772
47194
|
innerHeight,
|
|
46773
47195
|
(d) => fadeToMarker(g, d),
|
|
46774
47196
|
() => fadeReset(g),
|
|
46775
47197
|
timelineScale,
|
|
46776
47198
|
tooltip,
|
|
46777
|
-
palette
|
|
46778
|
-
markerReserve ? markerLabelY : void 0
|
|
47199
|
+
palette
|
|
46779
47200
|
);
|
|
46780
47201
|
if (timelineScale) {
|
|
46781
47202
|
renderTimeScale(
|
|
46782
47203
|
g,
|
|
46783
|
-
|
|
46784
|
-
|
|
47204
|
+
yScale,
|
|
47205
|
+
true,
|
|
46785
47206
|
innerWidth,
|
|
46786
47207
|
innerHeight,
|
|
46787
47208
|
textColor,
|
|
@@ -46791,78 +47212,55 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46791
47212
|
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46792
47213
|
);
|
|
46793
47214
|
}
|
|
46794
|
-
let curY = 0;
|
|
46795
47215
|
if (timelineSwimlanes || tagLanes) {
|
|
46796
|
-
|
|
46797
|
-
|
|
46798
|
-
const
|
|
46799
|
-
|
|
46800
|
-
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);
|
|
46801
|
-
swimY += laneSpan + GROUP_GAP3;
|
|
47216
|
+
laneNames.forEach((laneName, laneIdx) => {
|
|
47217
|
+
const laneX = laneIdx * laneWidth;
|
|
47218
|
+
const fillColor = laneIdx % 2 === 0 ? textColor : "transparent";
|
|
47219
|
+
g.append("rect").attr("class", "tl-swimlane").attr("data-group", laneName).attr("x", laneX).attr("y", 0).attr("width", laneWidth).attr("height", innerHeight).attr("fill", fillColor).attr("opacity", 0.06);
|
|
46802
47220
|
});
|
|
46803
47221
|
}
|
|
46804
|
-
|
|
46805
|
-
const
|
|
46806
|
-
const
|
|
46807
|
-
const
|
|
46808
|
-
const headerG = g.append("g").attr("class", "tl-lane-header").attr("data-group",
|
|
46809
|
-
|
|
46810
|
-
|
|
46811
|
-
|
|
46812
|
-
|
|
46813
|
-
const y =
|
|
46814
|
-
const
|
|
46815
|
-
const evG = g.append("g").attr("class", "tl-event").attr("data-group", lane.name).attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
47222
|
+
laneNames.forEach((laneName, laneIdx) => {
|
|
47223
|
+
const laneX = laneIdx * laneWidth;
|
|
47224
|
+
const laneColor = groupColorMap.get(laneName) ?? textColor;
|
|
47225
|
+
const laneCenter = laneX + laneWidth / 2;
|
|
47226
|
+
const headerG = g.append("g").attr("class", "tl-lane-header").attr("data-group", laneName).style("cursor", "pointer").on("mouseenter", () => fadeToGroup(g, laneName)).on("mouseleave", () => fadeReset(g));
|
|
47227
|
+
headerG.append("text").attr("x", laneCenter).attr("y", -15).attr("text-anchor", "middle").attr("fill", laneColor).attr("font-size", "12px").attr("font-weight", "600").text(laneName);
|
|
47228
|
+
g.append("line").attr("x1", laneCenter).attr("y1", 0).attr("x2", laneCenter).attr("y2", innerHeight).attr("stroke", mutedColor).attr("stroke-width", 1).attr("stroke-dasharray", "4,4");
|
|
47229
|
+
const laneEvents = laneEventsByName.get(laneName) ?? [];
|
|
47230
|
+
for (const ev of laneEvents) {
|
|
47231
|
+
const y = yScale(parseTimelineDate(ev.date));
|
|
47232
|
+
const evG = g.append("g").attr("class", "tl-event").attr("data-group", laneName).attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
46816
47233
|
"data-end-date",
|
|
46817
47234
|
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
46818
47235
|
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
46819
|
-
fadeToGroup(g,
|
|
46820
|
-
|
|
46821
|
-
showEventDatesOnScale(
|
|
46822
|
-
g,
|
|
46823
|
-
xScale,
|
|
46824
|
-
ev.date,
|
|
46825
|
-
ev.endDate,
|
|
46826
|
-
innerHeight,
|
|
46827
|
-
laneColor
|
|
46828
|
-
);
|
|
46829
|
-
} else {
|
|
46830
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46831
|
-
}
|
|
47236
|
+
fadeToGroup(g, laneName);
|
|
47237
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46832
47238
|
}).on("mouseleave", function() {
|
|
46833
47239
|
fadeReset(g);
|
|
46834
|
-
|
|
46835
|
-
hideEventDatesOnScale(g);
|
|
46836
|
-
} else {
|
|
46837
|
-
hideTooltip(tooltip);
|
|
46838
|
-
}
|
|
47240
|
+
hideTooltip(tooltip);
|
|
46839
47241
|
}).on("mousemove", function(event) {
|
|
46840
|
-
|
|
46841
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46842
|
-
}
|
|
47242
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46843
47243
|
}).on("click", () => {
|
|
46844
47244
|
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
46845
47245
|
});
|
|
46846
47246
|
setTagAttrs(evG, ev);
|
|
46847
47247
|
const evColor = eventColor(ev);
|
|
46848
47248
|
if (ev.endDate) {
|
|
46849
|
-
const
|
|
46850
|
-
const
|
|
46851
|
-
const estLabelWidth = ev.label.length * 7 + 16;
|
|
46852
|
-
const labelFitsInside = rectW >= estLabelWidth;
|
|
47249
|
+
const y2 = yScale(parseTimelineDate(ev.endDate));
|
|
47250
|
+
const rectH = Math.max(y2 - y, 4);
|
|
46853
47251
|
let fill2 = shapeFill(palette, evColor, isDark, { solid });
|
|
46854
47252
|
let stroke2 = evColor;
|
|
46855
47253
|
if (ev.uncertain) {
|
|
46856
|
-
const gradientId = `uncertain-${ev.lineNumber}`;
|
|
46857
|
-
const strokeGradientId = `uncertain-s-${ev.lineNumber}`;
|
|
47254
|
+
const gradientId = `uncertain-vg-${ev.lineNumber}`;
|
|
47255
|
+
const strokeGradientId = `uncertain-vg-s-${ev.lineNumber}`;
|
|
46858
47256
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46859
47257
|
const defsEl = d3Selection22.select(defs);
|
|
46860
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47258
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46861
47259
|
{ offset: "0%", opacity: 1 },
|
|
46862
47260
|
{ offset: "80%", opacity: 1 },
|
|
46863
47261
|
{ offset: "100%", opacity: 0 }
|
|
46864
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(
|
|
46865
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47262
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47263
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46866
47264
|
{ offset: "0%", opacity: 1 },
|
|
46867
47265
|
{ offset: "80%", opacity: 1 },
|
|
46868
47266
|
{ offset: "100%", opacity: 0 }
|
|
@@ -46870,47 +47268,29 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46870
47268
|
fill2 = `url(#${gradientId})`;
|
|
46871
47269
|
stroke2 = `url(#${strokeGradientId})`;
|
|
46872
47270
|
}
|
|
46873
|
-
evG.append("rect").attr("x",
|
|
46874
|
-
|
|
46875
|
-
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);
|
|
46876
|
-
} else {
|
|
46877
|
-
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
46878
|
-
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
46879
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46880
|
-
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);
|
|
46881
|
-
}
|
|
47271
|
+
evG.append("rect").attr("x", laneCenter - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
47272
|
+
evG.append("text").attr("x", laneCenter + 14).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
|
|
46882
47273
|
} else {
|
|
46883
|
-
|
|
46884
|
-
|
|
46885
|
-
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
46886
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46887
|
-
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);
|
|
46888
|
-
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
47274
|
+
evG.append("circle").attr("cx", laneCenter).attr("cy", y).attr("r", 4).attr("fill", shapeFill(palette, evColor, isDark, { solid })).attr("stroke", evColor).attr("stroke-width", 2);
|
|
47275
|
+
evG.append("text").attr("x", laneCenter + 10).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
|
|
46889
47276
|
}
|
|
46890
|
-
}
|
|
46891
|
-
|
|
46892
|
-
}
|
|
47277
|
+
}
|
|
47278
|
+
});
|
|
46893
47279
|
} else {
|
|
46894
|
-
const
|
|
46895
|
-
const
|
|
46896
|
-
const ERA_ROW_H = 22;
|
|
46897
|
-
const MARKER_ROW_H = 22;
|
|
46898
|
-
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46899
|
-
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46900
|
-
const topScaleH = timelineScale ? 40 : 0;
|
|
47280
|
+
const scaleMargin = timelineScale ? 40 : 0;
|
|
47281
|
+
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46901
47282
|
const margin = {
|
|
46902
|
-
top: 104 +
|
|
46903
|
-
right:
|
|
46904
|
-
bottom: 40
|
|
46905
|
-
left: 60
|
|
47283
|
+
top: 104 + markerMargin + tagLegendReserve,
|
|
47284
|
+
right: 200,
|
|
47285
|
+
bottom: 40,
|
|
47286
|
+
left: 60 + scaleMargin
|
|
46906
47287
|
};
|
|
46907
|
-
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46908
|
-
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46909
47288
|
const innerWidth = width - margin.left - margin.right;
|
|
46910
47289
|
const innerHeight = height - margin.top - margin.bottom;
|
|
46911
|
-
const
|
|
46912
|
-
const
|
|
46913
|
-
const
|
|
47290
|
+
const axisX = 20;
|
|
47291
|
+
const yScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
|
|
47292
|
+
const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
|
|
47293
|
+
const svg = d3Selection22.select(container).append("svg").attr("viewBox", `0 0 ${width} ${height}`).attr("width", exportDims ? width : "100%").attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
46914
47294
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46915
47295
|
renderChartTitle(
|
|
46916
47296
|
svg,
|
|
@@ -46923,36 +47303,34 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46923
47303
|
renderEras(
|
|
46924
47304
|
g,
|
|
46925
47305
|
timelineEras,
|
|
46926
|
-
|
|
46927
|
-
|
|
47306
|
+
yScale,
|
|
47307
|
+
true,
|
|
46928
47308
|
innerWidth,
|
|
46929
47309
|
innerHeight,
|
|
46930
47310
|
(s, e) => fadeToEra(g, s, e),
|
|
46931
47311
|
() => fadeReset(g),
|
|
46932
47312
|
timelineScale,
|
|
46933
47313
|
tooltip,
|
|
46934
|
-
palette
|
|
46935
|
-
eraReserve ? eraLabelY : void 0
|
|
47314
|
+
palette
|
|
46936
47315
|
);
|
|
46937
47316
|
renderMarkers(
|
|
46938
47317
|
g,
|
|
46939
47318
|
timelineMarkers,
|
|
46940
|
-
|
|
46941
|
-
|
|
47319
|
+
yScale,
|
|
47320
|
+
true,
|
|
46942
47321
|
innerWidth,
|
|
46943
47322
|
innerHeight,
|
|
46944
47323
|
(d) => fadeToMarker(g, d),
|
|
46945
47324
|
() => fadeReset(g),
|
|
46946
47325
|
timelineScale,
|
|
46947
47326
|
tooltip,
|
|
46948
|
-
palette
|
|
46949
|
-
markerReserve ? markerLabelY : void 0
|
|
47327
|
+
palette
|
|
46950
47328
|
);
|
|
46951
47329
|
if (timelineScale) {
|
|
46952
47330
|
renderTimeScale(
|
|
46953
47331
|
g,
|
|
46954
|
-
|
|
46955
|
-
|
|
47332
|
+
yScale,
|
|
47333
|
+
true,
|
|
46956
47334
|
innerWidth,
|
|
46957
47335
|
innerHeight,
|
|
46958
47336
|
textColor,
|
|
@@ -46963,7 +47341,6 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46963
47341
|
);
|
|
46964
47342
|
}
|
|
46965
47343
|
if (timelineGroups.length > 0) {
|
|
46966
|
-
const legendY = timelineScale ? -75 : -55;
|
|
46967
47344
|
renderTimelineGroupLegend(
|
|
46968
47345
|
g,
|
|
46969
47346
|
timelineGroups,
|
|
@@ -46971,65 +47348,46 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46971
47348
|
textColor,
|
|
46972
47349
|
palette,
|
|
46973
47350
|
isDark,
|
|
46974
|
-
|
|
47351
|
+
-55,
|
|
46975
47352
|
(name) => fadeToGroup(g, name),
|
|
46976
47353
|
() => fadeReset(g)
|
|
46977
47354
|
);
|
|
46978
47355
|
}
|
|
46979
|
-
|
|
46980
|
-
|
|
46981
|
-
const
|
|
47356
|
+
g.append("line").attr("x1", axisX).attr("y1", 0).attr("x2", axisX).attr("y2", innerHeight).attr("stroke", mutedColor).attr("stroke-width", 1).attr("stroke-dasharray", "4,4");
|
|
47357
|
+
for (const ev of sorted) {
|
|
47358
|
+
const y = yScale(parseTimelineDate(ev.date));
|
|
46982
47359
|
const color = eventColor(ev);
|
|
46983
47360
|
const evG = g.append("g").attr("class", "tl-event").attr("data-group", ev.group || "").attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
46984
47361
|
"data-end-date",
|
|
46985
47362
|
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
46986
47363
|
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
46987
47364
|
if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);
|
|
46988
|
-
|
|
46989
|
-
showEventDatesOnScale(
|
|
46990
|
-
g,
|
|
46991
|
-
xScale,
|
|
46992
|
-
ev.date,
|
|
46993
|
-
ev.endDate,
|
|
46994
|
-
innerHeight,
|
|
46995
|
-
color
|
|
46996
|
-
);
|
|
46997
|
-
} else {
|
|
46998
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46999
|
-
}
|
|
47365
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47000
47366
|
}).on("mouseleave", function() {
|
|
47001
47367
|
fadeReset(g);
|
|
47002
|
-
|
|
47003
|
-
hideEventDatesOnScale(g);
|
|
47004
|
-
} else {
|
|
47005
|
-
hideTooltip(tooltip);
|
|
47006
|
-
}
|
|
47368
|
+
hideTooltip(tooltip);
|
|
47007
47369
|
}).on("mousemove", function(event) {
|
|
47008
|
-
|
|
47009
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47010
|
-
}
|
|
47370
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47011
47371
|
}).on("click", () => {
|
|
47012
47372
|
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
47013
47373
|
});
|
|
47014
47374
|
setTagAttrs(evG, ev);
|
|
47015
47375
|
if (ev.endDate) {
|
|
47016
|
-
const
|
|
47017
|
-
const
|
|
47018
|
-
const estLabelWidth = ev.label.length * 7 + 16;
|
|
47019
|
-
const labelFitsInside = rectW >= estLabelWidth;
|
|
47376
|
+
const y2 = yScale(parseTimelineDate(ev.endDate));
|
|
47377
|
+
const rectH = Math.max(y2 - y, 4);
|
|
47020
47378
|
let fill2 = shapeFill(palette, color, isDark, { solid });
|
|
47021
47379
|
let stroke2 = color;
|
|
47022
47380
|
if (ev.uncertain) {
|
|
47023
|
-
const gradientId = `uncertain-
|
|
47024
|
-
const strokeGradientId = `uncertain-
|
|
47381
|
+
const gradientId = `uncertain-v-${ev.lineNumber}`;
|
|
47382
|
+
const strokeGradientId = `uncertain-v-s-${ev.lineNumber}`;
|
|
47025
47383
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
47026
47384
|
const defsEl = d3Selection22.select(defs);
|
|
47027
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47385
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
47028
47386
|
{ offset: "0%", opacity: 1 },
|
|
47029
47387
|
{ offset: "80%", opacity: 1 },
|
|
47030
47388
|
{ offset: "100%", opacity: 0 }
|
|
47031
47389
|
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47032
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47390
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
47033
47391
|
{ offset: "0%", opacity: 1 },
|
|
47034
47392
|
{ offset: "80%", opacity: 1 },
|
|
47035
47393
|
{ offset: "100%", opacity: 0 }
|
|
@@ -47037,206 +47395,100 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
47037
47395
|
fill2 = `url(#${gradientId})`;
|
|
47038
47396
|
stroke2 = `url(#${strokeGradientId})`;
|
|
47039
47397
|
}
|
|
47040
|
-
evG.append("rect").attr("x",
|
|
47041
|
-
|
|
47042
|
-
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);
|
|
47043
|
-
} else {
|
|
47044
|
-
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
47045
|
-
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
47046
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47047
|
-
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);
|
|
47048
|
-
}
|
|
47398
|
+
evG.append("rect").attr("x", axisX - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
47399
|
+
evG.append("text").attr("x", axisX + 16).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "11px").text(ev.label);
|
|
47049
47400
|
} else {
|
|
47050
|
-
|
|
47051
|
-
|
|
47052
|
-
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
47053
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47054
|
-
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);
|
|
47055
|
-
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);
|
|
47056
|
-
}
|
|
47057
|
-
});
|
|
47058
|
-
}
|
|
47059
|
-
if (parsed.timelineTagGroups.length > 0) {
|
|
47060
|
-
const LG_HEIGHT = LEGEND_HEIGHT;
|
|
47061
|
-
const LG_PILL_PAD = LEGEND_PILL_PAD;
|
|
47062
|
-
const LG_PILL_FONT_SIZE = LEGEND_PILL_FONT_SIZE;
|
|
47063
|
-
const LG_CAPSULE_PAD = LEGEND_CAPSULE_PAD;
|
|
47064
|
-
const LG_DOT_R = LEGEND_DOT_R;
|
|
47065
|
-
const LG_ENTRY_FONT_SIZE = LEGEND_ENTRY_FONT_SIZE;
|
|
47066
|
-
const LG_ENTRY_DOT_GAP = LEGEND_ENTRY_DOT_GAP;
|
|
47067
|
-
const LG_ENTRY_TRAIL = LEGEND_ENTRY_TRAIL;
|
|
47068
|
-
const LG_ICON_W = 20;
|
|
47069
|
-
const mainSvg = d3Selection22.select(container).select("svg");
|
|
47070
|
-
const mainG = mainSvg.select("g");
|
|
47071
|
-
if (!mainSvg.empty() && !mainG.empty()) {
|
|
47072
|
-
let drawSwimlaneIcon4 = function(parent, x, y, isSwimActive) {
|
|
47073
|
-
const iconG = parent.append("g").attr("class", "tl-swimlane-icon").attr("transform", `translate(${x}, ${y})`).style("cursor", "pointer");
|
|
47074
|
-
const barColor = isSwimActive ? palette.primary : palette.textMuted;
|
|
47075
|
-
const barOpacity = isSwimActive ? 1 : 0.35;
|
|
47076
|
-
const bars = [
|
|
47077
|
-
{ y: 0, w: 8 },
|
|
47078
|
-
{ y: 4, w: 12 },
|
|
47079
|
-
{ y: 8, w: 6 }
|
|
47080
|
-
];
|
|
47081
|
-
for (const bar of bars) {
|
|
47082
|
-
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);
|
|
47083
|
-
}
|
|
47084
|
-
return iconG;
|
|
47085
|
-
}, relayout2 = function() {
|
|
47086
|
-
renderTimeline(
|
|
47087
|
-
container,
|
|
47088
|
-
parsed,
|
|
47089
|
-
palette,
|
|
47090
|
-
isDark,
|
|
47091
|
-
onClickItem,
|
|
47092
|
-
exportDims,
|
|
47093
|
-
currentActiveGroup,
|
|
47094
|
-
currentSwimlaneGroup,
|
|
47095
|
-
onTagStateChange,
|
|
47096
|
-
viewMode
|
|
47097
|
-
);
|
|
47098
|
-
}, drawLegend2 = function() {
|
|
47099
|
-
mainSvg.selectAll(".tl-tag-legend-group").remove();
|
|
47100
|
-
mainSvg.selectAll(".tl-tag-legend-container").remove();
|
|
47101
|
-
const effectiveColorKey = (currentActiveGroup ?? currentSwimlaneGroup)?.toLowerCase() ?? null;
|
|
47102
|
-
const visibleGroups = viewMode ? legendGroups.filter(
|
|
47103
|
-
(lg) => effectiveColorKey != null && lg.group.name.toLowerCase() === effectiveColorKey
|
|
47104
|
-
) : legendGroups;
|
|
47105
|
-
if (visibleGroups.length === 0) return;
|
|
47106
|
-
const legendContainer = mainSvg.append("g").attr("class", "tl-tag-legend-container");
|
|
47107
|
-
if (currentActiveGroup) {
|
|
47108
|
-
legendContainer.attr(
|
|
47109
|
-
"data-legend-active",
|
|
47110
|
-
currentActiveGroup.toLowerCase()
|
|
47111
|
-
);
|
|
47112
|
-
}
|
|
47113
|
-
const iconAddon = viewMode ? 0 : LG_ICON_W;
|
|
47114
|
-
const centralGroups = visibleGroups.map((lg) => ({
|
|
47115
|
-
name: lg.group.name,
|
|
47116
|
-
entries: lg.group.entries.map((e) => ({
|
|
47117
|
-
value: e.value,
|
|
47118
|
-
color: e.color
|
|
47119
|
-
}))
|
|
47120
|
-
}));
|
|
47121
|
-
const centralActive = viewMode ? effectiveColorKey : currentActiveGroup;
|
|
47122
|
-
const centralConfig = {
|
|
47123
|
-
groups: centralGroups,
|
|
47124
|
-
position: { placement: "top-center", titleRelation: "below-title" },
|
|
47125
|
-
mode: "fixed",
|
|
47126
|
-
capsulePillAddonWidth: iconAddon
|
|
47127
|
-
};
|
|
47128
|
-
const centralState = { activeGroup: centralActive };
|
|
47129
|
-
const centralCallbacks = viewMode ? {} : {
|
|
47130
|
-
onGroupToggle: (groupName) => {
|
|
47131
|
-
currentActiveGroup = currentActiveGroup === groupName.toLowerCase() ? null : groupName.toLowerCase();
|
|
47132
|
-
drawLegend2();
|
|
47133
|
-
recolorEvents2();
|
|
47134
|
-
onTagStateChange?.(currentActiveGroup, currentSwimlaneGroup);
|
|
47135
|
-
},
|
|
47136
|
-
onEntryHover: (groupName, entryValue) => {
|
|
47137
|
-
const tagKey = groupName.toLowerCase();
|
|
47138
|
-
if (entryValue) {
|
|
47139
|
-
const tagVal = entryValue.toLowerCase();
|
|
47140
|
-
fadeToTagValue(mainG, tagKey, tagVal);
|
|
47141
|
-
mainSvg.selectAll("[data-legend-entry]").each(function() {
|
|
47142
|
-
const el = d3Selection22.select(this);
|
|
47143
|
-
const ev = el.attr("data-legend-entry");
|
|
47144
|
-
const eg = el.attr("data-tag-group") ?? el.node()?.closest?.("[data-tag-group]")?.getAttribute("data-tag-group");
|
|
47145
|
-
el.attr(
|
|
47146
|
-
"opacity",
|
|
47147
|
-
eg === tagKey && ev === tagVal ? 1 : FADE_OPACITY3
|
|
47148
|
-
);
|
|
47149
|
-
});
|
|
47150
|
-
} else {
|
|
47151
|
-
fadeReset(mainG);
|
|
47152
|
-
mainSvg.selectAll("[data-legend-entry]").attr("opacity", 1);
|
|
47153
|
-
}
|
|
47154
|
-
},
|
|
47155
|
-
onGroupRendered: (groupName, groupEl, isActive) => {
|
|
47156
|
-
const groupKey = groupName.toLowerCase();
|
|
47157
|
-
groupEl.attr("data-tag-group", groupKey);
|
|
47158
|
-
if (isActive && !viewMode) {
|
|
47159
|
-
const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
|
|
47160
|
-
const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
47161
|
-
const pillXOff = LG_CAPSULE_PAD;
|
|
47162
|
-
const iconX = pillXOff + pillWidth3 + 5;
|
|
47163
|
-
const iconY = (LG_HEIGHT - 10) / 2;
|
|
47164
|
-
const iconEl = drawSwimlaneIcon4(
|
|
47165
|
-
groupEl,
|
|
47166
|
-
iconX,
|
|
47167
|
-
iconY,
|
|
47168
|
-
isSwimActive
|
|
47169
|
-
);
|
|
47170
|
-
iconEl.attr("data-swimlane-toggle", groupKey).on("click", (event) => {
|
|
47171
|
-
event.stopPropagation();
|
|
47172
|
-
currentSwimlaneGroup = currentSwimlaneGroup === groupKey ? null : groupKey;
|
|
47173
|
-
onTagStateChange?.(
|
|
47174
|
-
currentActiveGroup,
|
|
47175
|
-
currentSwimlaneGroup
|
|
47176
|
-
);
|
|
47177
|
-
relayout2();
|
|
47178
|
-
});
|
|
47179
|
-
}
|
|
47180
|
-
}
|
|
47181
|
-
};
|
|
47182
|
-
const legendInnerG = legendContainer.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
47183
|
-
renderLegendD3(
|
|
47184
|
-
legendInnerG,
|
|
47185
|
-
centralConfig,
|
|
47186
|
-
centralState,
|
|
47187
|
-
palette,
|
|
47188
|
-
isDark,
|
|
47189
|
-
centralCallbacks,
|
|
47190
|
-
width
|
|
47191
|
-
);
|
|
47192
|
-
}, recolorEvents2 = function() {
|
|
47193
|
-
const colorTG = currentActiveGroup ?? swimlaneTagGroup ?? null;
|
|
47194
|
-
mainG.selectAll(".tl-event").each(function() {
|
|
47195
|
-
const el = d3Selection22.select(this);
|
|
47196
|
-
const lineNum = el.attr("data-line-number");
|
|
47197
|
-
const ev = lineNum ? eventByLine.get(lineNum) : void 0;
|
|
47198
|
-
if (!ev) return;
|
|
47199
|
-
let color;
|
|
47200
|
-
if (colorTG) {
|
|
47201
|
-
const tagColor = resolveTagColor(
|
|
47202
|
-
ev.metadata,
|
|
47203
|
-
parsed.timelineTagGroups,
|
|
47204
|
-
colorTG
|
|
47205
|
-
);
|
|
47206
|
-
color = tagColor ?? (ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor);
|
|
47207
|
-
} else {
|
|
47208
|
-
color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
|
|
47209
|
-
}
|
|
47210
|
-
el.selectAll("rect").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
47211
|
-
el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
47212
|
-
});
|
|
47213
|
-
};
|
|
47214
|
-
var drawSwimlaneIcon3 = drawSwimlaneIcon4, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
|
|
47215
|
-
const legendY = title ? 50 : 10;
|
|
47216
|
-
const legendGroups = parsed.timelineTagGroups.map((g) => {
|
|
47217
|
-
const pillW = measureLegendText(g.name, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
47218
|
-
const iconSpace = viewMode ? 8 : LG_ICON_W + 4;
|
|
47219
|
-
let entryX = LG_CAPSULE_PAD + pillW + iconSpace;
|
|
47220
|
-
for (const entry of g.entries) {
|
|
47221
|
-
const textX = entryX + LG_DOT_R * 2 + LG_ENTRY_DOT_GAP;
|
|
47222
|
-
entryX = textX + measureLegendText(entry.value, LG_ENTRY_FONT_SIZE) + LG_ENTRY_TRAIL;
|
|
47223
|
-
}
|
|
47224
|
-
return {
|
|
47225
|
-
group: g,
|
|
47226
|
-
minifiedWidth: pillW,
|
|
47227
|
-
expandedWidth: entryX + LG_CAPSULE_PAD
|
|
47228
|
-
};
|
|
47229
|
-
});
|
|
47230
|
-
let currentActiveGroup = activeTagGroup ?? null;
|
|
47231
|
-
let currentSwimlaneGroup = swimlaneTagGroup ?? null;
|
|
47232
|
-
const eventByLine = /* @__PURE__ */ new Map();
|
|
47233
|
-
for (const ev of timelineEvents) {
|
|
47234
|
-
eventByLine.set(String(ev.lineNumber), ev);
|
|
47401
|
+
evG.append("circle").attr("cx", axisX).attr("cy", y).attr("r", 4).attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color).attr("stroke-width", 2);
|
|
47402
|
+
evG.append("text").attr("x", axisX + 16).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "11px").text(ev.label);
|
|
47235
47403
|
}
|
|
47236
|
-
|
|
47404
|
+
evG.append("text").attr("x", axisX - 14).attr(
|
|
47405
|
+
"y",
|
|
47406
|
+
ev.endDate ? yScale(parseTimelineDate(ev.date)) + Math.max(
|
|
47407
|
+
yScale(parseTimelineDate(ev.endDate)) - yScale(parseTimelineDate(ev.date)),
|
|
47408
|
+
4
|
|
47409
|
+
) / 2 : y
|
|
47410
|
+
).attr("dy", "0.35em").attr("text-anchor", "end").attr("fill", mutedColor).attr("font-size", "10px").text(ev.date + (ev.endDate ? `\u2192${ev.endDate}` : ""));
|
|
47237
47411
|
}
|
|
47238
47412
|
}
|
|
47239
47413
|
}
|
|
47414
|
+
function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims, activeTagGroup, swimlaneTagGroup, onTagStateChange, viewMode) {
|
|
47415
|
+
const setup = setupTimeline(
|
|
47416
|
+
container,
|
|
47417
|
+
parsed,
|
|
47418
|
+
palette,
|
|
47419
|
+
isDark,
|
|
47420
|
+
exportDims,
|
|
47421
|
+
activeTagGroup,
|
|
47422
|
+
swimlaneTagGroup
|
|
47423
|
+
);
|
|
47424
|
+
if (!setup) return;
|
|
47425
|
+
swimlaneTagGroup = setup.swimlaneTagGroup;
|
|
47426
|
+
const { isVertical, tagLanes } = setup;
|
|
47427
|
+
const hovers = makeTimelineHoverHelpers();
|
|
47428
|
+
if (isVertical) {
|
|
47429
|
+
renderTimelineVertical(
|
|
47430
|
+
container,
|
|
47431
|
+
parsed,
|
|
47432
|
+
palette,
|
|
47433
|
+
isDark,
|
|
47434
|
+
setup,
|
|
47435
|
+
hovers,
|
|
47436
|
+
onClickItem,
|
|
47437
|
+
exportDims,
|
|
47438
|
+
swimlaneTagGroup,
|
|
47439
|
+
activeTagGroup,
|
|
47440
|
+
onTagStateChange,
|
|
47441
|
+
viewMode
|
|
47442
|
+
);
|
|
47443
|
+
return;
|
|
47444
|
+
}
|
|
47445
|
+
const useGroupedHorizontal = tagLanes != null || parsed.timelineSort === "group" && parsed.timelineGroups.length > 0;
|
|
47446
|
+
if (useGroupedHorizontal) {
|
|
47447
|
+
renderTimelineHorizontalGrouped(
|
|
47448
|
+
container,
|
|
47449
|
+
parsed,
|
|
47450
|
+
palette,
|
|
47451
|
+
isDark,
|
|
47452
|
+
setup,
|
|
47453
|
+
hovers,
|
|
47454
|
+
onClickItem,
|
|
47455
|
+
exportDims,
|
|
47456
|
+
swimlaneTagGroup,
|
|
47457
|
+
activeTagGroup,
|
|
47458
|
+
onTagStateChange,
|
|
47459
|
+
viewMode
|
|
47460
|
+
);
|
|
47461
|
+
} else {
|
|
47462
|
+
renderTimelineHorizontalTimeSort(
|
|
47463
|
+
container,
|
|
47464
|
+
parsed,
|
|
47465
|
+
palette,
|
|
47466
|
+
isDark,
|
|
47467
|
+
setup,
|
|
47468
|
+
hovers,
|
|
47469
|
+
onClickItem,
|
|
47470
|
+
exportDims,
|
|
47471
|
+
swimlaneTagGroup,
|
|
47472
|
+
activeTagGroup,
|
|
47473
|
+
onTagStateChange,
|
|
47474
|
+
viewMode
|
|
47475
|
+
);
|
|
47476
|
+
}
|
|
47477
|
+
renderTimelineTagLegendOverlay(
|
|
47478
|
+
container,
|
|
47479
|
+
parsed,
|
|
47480
|
+
palette,
|
|
47481
|
+
isDark,
|
|
47482
|
+
setup,
|
|
47483
|
+
hovers,
|
|
47484
|
+
onClickItem,
|
|
47485
|
+
exportDims,
|
|
47486
|
+
swimlaneTagGroup,
|
|
47487
|
+
activeTagGroup,
|
|
47488
|
+
onTagStateChange,
|
|
47489
|
+
viewMode
|
|
47490
|
+
);
|
|
47491
|
+
}
|
|
47240
47492
|
function getRotateFn(mode) {
|
|
47241
47493
|
if (mode === "mixed") return () => Math.random() > 0.5 ? 0 : 90;
|
|
47242
47494
|
if (mode === "angled") return () => Math.round(Math.random() * 30 - 15);
|
|
@@ -47360,7 +47612,7 @@ function regionCentroid(circles, inside) {
|
|
|
47360
47612
|
}
|
|
47361
47613
|
return { x: sx / count, y: sy / count };
|
|
47362
47614
|
}
|
|
47363
|
-
function renderVenn(container, parsed, palette,
|
|
47615
|
+
function renderVenn(container, parsed, palette, _isDark, onClickItem, exportDims) {
|
|
47364
47616
|
const { vennSets, vennOverlaps } = parsed;
|
|
47365
47617
|
const title = parsed.noTitle ? null : parsed.title;
|
|
47366
47618
|
if (vennSets.length < 2 || vennSets.length > 3) return;
|
|
@@ -47594,7 +47846,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
47594
47846
|
};
|
|
47595
47847
|
const gcx = circles.reduce((s, c) => s + c.x, 0) / n;
|
|
47596
47848
|
const gcy = circles.reduce((s, c) => s + c.y, 0) / n;
|
|
47597
|
-
function exclusiveHSpan(
|
|
47849
|
+
function exclusiveHSpan(_px, py, ci) {
|
|
47598
47850
|
const dy = py - circles[ci].y;
|
|
47599
47851
|
const halfChord = Math.sqrt(
|
|
47600
47852
|
Math.max(0, circles[ci].r * circles[ci].r - dy * dy)
|
|
@@ -48507,9 +48759,9 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
48507
48759
|
blHiddenTagValues.set(k, new Set(v));
|
|
48508
48760
|
}
|
|
48509
48761
|
}
|
|
48510
|
-
const { layoutBoxesAndLines: layoutBoxesAndLines2 } = await Promise.resolve().then(() => (init_layout5(), layout_exports5));
|
|
48511
48762
|
const { renderBoxesAndLinesForExport: renderBoxesAndLinesForExport2 } = await Promise.resolve().then(() => (init_renderer6(), renderer_exports6));
|
|
48512
|
-
const
|
|
48763
|
+
const { layoutBoxesAndLines: layoutBoxesAndLines2 } = await Promise.resolve().then(() => (init_layout5(), layout_exports5));
|
|
48764
|
+
const blLayout = await layoutBoxesAndLines2(blParsed);
|
|
48513
48765
|
const PADDING3 = 20;
|
|
48514
48766
|
const titleOffset = blParsed.title ? 40 : 0;
|
|
48515
48767
|
const exportWidth = blLayout.width + PADDING3 * 2;
|
|
@@ -49597,7 +49849,7 @@ init_dgmo_router();
|
|
|
49597
49849
|
init_registry();
|
|
49598
49850
|
async function ensureDom() {
|
|
49599
49851
|
if (typeof document !== "undefined") return;
|
|
49600
|
-
const { JSDOM } = await
|
|
49852
|
+
const { JSDOM } = await loadJsdom();
|
|
49601
49853
|
const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>");
|
|
49602
49854
|
const win = dom.window;
|
|
49603
49855
|
Object.defineProperty(globalThis, "document", {
|
|
@@ -49621,6 +49873,14 @@ async function ensureDom() {
|
|
|
49621
49873
|
configurable: true
|
|
49622
49874
|
});
|
|
49623
49875
|
}
|
|
49876
|
+
async function loadJsdom() {
|
|
49877
|
+
const spec = ["js", "dom"].join("");
|
|
49878
|
+
return import(
|
|
49879
|
+
/* @vite-ignore */
|
|
49880
|
+
/* webpackIgnore: true */
|
|
49881
|
+
spec
|
|
49882
|
+
);
|
|
49883
|
+
}
|
|
49624
49884
|
async function render(content, options) {
|
|
49625
49885
|
const theme = options?.theme ?? "light";
|
|
49626
49886
|
const paletteName = options?.palette ?? "nord";
|
|
@@ -49802,6 +50062,7 @@ var DIRECTIVE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
49802
50062
|
"split",
|
|
49803
50063
|
"slo-p90-latency-ms",
|
|
49804
50064
|
"slo-availability",
|
|
50065
|
+
"slo-warning-margin",
|
|
49805
50066
|
"cache-hit",
|
|
49806
50067
|
"concurrency",
|
|
49807
50068
|
"duration-ms",
|
|
@@ -50425,7 +50686,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
|
|
|
50425
50686
|
|
|
50426
50687
|
// src/auto/index.ts
|
|
50427
50688
|
init_safe_href();
|
|
50428
|
-
var VERSION = "0.
|
|
50689
|
+
var VERSION = "0.15.1";
|
|
50429
50690
|
var DEFAULTS = {
|
|
50430
50691
|
theme: "auto",
|
|
50431
50692
|
palette: "nord",
|
|
@@ -50742,8 +51003,8 @@ function determineReplaceTarget(matched) {
|
|
|
50742
51003
|
}
|
|
50743
51004
|
async function processElement(el) {
|
|
50744
51005
|
if (!(el instanceof HTMLElement)) return {};
|
|
50745
|
-
if (el.dataset
|
|
50746
|
-
el.dataset
|
|
51006
|
+
if (el.dataset["dgmoProcessed"] === "true") return {};
|
|
51007
|
+
el.dataset["dgmoProcessed"] = "true";
|
|
50747
51008
|
const source = el.textContent || "";
|
|
50748
51009
|
const sourceBytes = new TextEncoder().encode(source).byteLength;
|
|
50749
51010
|
if (sourceBytes > SOURCE_BYTE_CAP) {
|
|
@@ -50760,7 +51021,7 @@ async function processElement(el) {
|
|
|
50760
51021
|
const resolvedTheme = cfg.theme === "transparent" ? "transparent" : resolveTheme(cfg.theme);
|
|
50761
51022
|
const renderTheme = resolvedTheme === "transparent" ? "transparent" : resolvedTheme;
|
|
50762
51023
|
const ariaLabel = deriveAriaLabel(source);
|
|
50763
|
-
const perElementShowSource = el.dataset
|
|
51024
|
+
const perElementShowSource = el.dataset["showSource"];
|
|
50764
51025
|
let showSource = cfg.showSource;
|
|
50765
51026
|
if (perElementShowSource === "true") showSource = true;
|
|
50766
51027
|
else if (perElementShowSource === "false") showSource = false;
|
|
@@ -50810,7 +51071,7 @@ async function processElement(el) {
|
|
|
50810
51071
|
const wrapper = document.createElement("div");
|
|
50811
51072
|
const themeClass = resolvedTheme === "dark" ? "dgmo-theme-dark" : resolvedTheme === "transparent" ? "dgmo-theme-transparent" : "dgmo-theme-light";
|
|
50812
51073
|
wrapper.className = `dgmo-rendered ${themeClass}`;
|
|
50813
|
-
wrapper.dataset
|
|
51074
|
+
wrapper.dataset["dgmoProcessed"] = "true";
|
|
50814
51075
|
const svgHolder = document.createElement("div");
|
|
50815
51076
|
svgHolder.innerHTML = result.svg;
|
|
50816
51077
|
const svgEl = svgHolder.querySelector("svg");
|
|
@@ -50879,15 +51140,16 @@ function initialize(opts = {}) {
|
|
|
50879
51140
|
}
|
|
50880
51141
|
}
|
|
50881
51142
|
const next = { ...activeConfig };
|
|
50882
|
-
if (isValidTheme(opts
|
|
50883
|
-
next.theme = opts
|
|
51143
|
+
if (isValidTheme(opts["theme"])) {
|
|
51144
|
+
next.theme = opts["theme"];
|
|
50884
51145
|
}
|
|
50885
|
-
if (typeof opts
|
|
50886
|
-
next.palette = opts
|
|
51146
|
+
if (typeof opts["palette"] === "string" && paletteExists(opts["palette"])) {
|
|
51147
|
+
next.palette = opts["palette"];
|
|
50887
51148
|
}
|
|
50888
|
-
if (typeof opts
|
|
50889
|
-
|
|
50890
|
-
|
|
51149
|
+
if (typeof opts["showSource"] === "boolean")
|
|
51150
|
+
next.showSource = opts["showSource"];
|
|
51151
|
+
if (typeof opts["showEditorLink"] === "boolean")
|
|
51152
|
+
next.showEditorLink = opts["showEditorLink"];
|
|
50891
51153
|
activeConfig = next;
|
|
50892
51154
|
}
|
|
50893
51155
|
async function run(opts = {}) {
|
|
@@ -50926,7 +51188,7 @@ function rerenderAllForTheme() {
|
|
|
50926
51188
|
placeholder.className = "dgmo";
|
|
50927
51189
|
placeholder.textContent = t.source;
|
|
50928
51190
|
if (t.perElementShowSource !== null) {
|
|
50929
|
-
placeholder.dataset
|
|
51191
|
+
placeholder.dataset["showSource"] = String(t.perElementShowSource);
|
|
50930
51192
|
}
|
|
50931
51193
|
t.wrapper.replaceWith(placeholder);
|
|
50932
51194
|
wrappers.delete(t);
|
|
@@ -50953,7 +51215,7 @@ function unhideAllSources() {
|
|
|
50953
51215
|
el.style.visibility = "visible";
|
|
50954
51216
|
});
|
|
50955
51217
|
if (document.documentElement && document.documentElement.dataset) {
|
|
50956
|
-
document.documentElement.dataset
|
|
51218
|
+
document.documentElement.dataset["dgmoAutoFailed"] = "1";
|
|
50957
51219
|
}
|
|
50958
51220
|
}
|
|
50959
51221
|
function bootstrap() {
|