@diagrammo/dgmo 0.15.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/dist/advanced.cjs +53069 -0
- package/dist/advanced.d.cts +4691 -0
- package/dist/advanced.d.ts +4691 -0
- package/dist/advanced.js +52823 -0
- package/dist/auto.cjs +1495 -1288
- package/dist/auto.js +132 -109
- package/dist/auto.mjs +1491 -1284
- package/dist/cli.cjs +173 -150
- package/dist/index.cjs +1486 -1276
- package/dist/index.d.cts +45 -1
- package/dist/index.d.ts +45 -1
- package/dist/index.js +1481 -1272
- package/dist/internal.cjs +1497 -1289
- package/dist/internal.d.cts +80 -79
- package/dist/internal.d.ts +80 -79
- package/dist/internal.js +1492 -1285
- package/dist/pert.cjs +325 -0
- package/dist/pert.d.cts +542 -0
- package/dist/pert.d.ts +542 -0
- package/dist/pert.js +294 -0
- package/package.json +28 -3
- package/src/advanced.ts +731 -0
- package/src/auto/index.ts +14 -13
- package/src/boxes-and-lines/layout.ts +481 -445
- package/src/c4/parser.ts +7 -7
- package/src/chart-types.ts +0 -5
- package/src/class/parser.ts +1 -9
- package/src/cli.ts +9 -7
- package/src/completion-types.ts +28 -0
- package/src/completion.ts +15 -18
- package/src/cycle/layout.ts +2 -2
- package/src/d3.ts +1455 -1122
- package/src/echarts.ts +11 -11
- package/src/er/parser.ts +1 -9
- package/src/er/renderer.ts +1 -1
- package/src/gantt/calculator.ts +1 -11
- package/src/gantt/parser.ts +16 -16
- package/src/gantt/renderer.ts +2 -2
- package/src/graph/flowchart-parser.ts +1 -1
- package/src/graph/flowchart-renderer.ts +1 -1
- package/src/graph/state-renderer.ts +1 -1
- package/src/index.ts +17 -1
- package/src/infra/parser.ts +19 -19
- package/src/infra/renderer.ts +2 -2
- package/src/internal.ts +9 -721
- package/src/kanban/parser.ts +2 -2
- package/src/mindmap/layout.ts +1 -1
- package/src/mindmap/parser.ts +1 -1
- package/src/org/parser.ts +1 -1
- package/src/org/renderer.ts +1 -1
- package/src/pert/layout.ts +1 -1
- package/src/pert/monte-carlo.ts +2 -2
- package/src/pert/parser.ts +3 -3
- package/src/raci/parser.ts +4 -4
- package/src/raci/renderer.ts +1 -1
- package/src/sequence/renderer.ts +1 -4
- package/src/sitemap/parser.ts +1 -1
- package/src/tech-radar/interactive.ts +1 -1
- package/src/tech-radar/renderer.ts +1 -1
- package/src/utils/tag-groups.ts +11 -12
- package/src/wireframe/layout.ts +11 -7
- package/src/wireframe/parser.ts +2 -2
- package/src/wireframe/renderer.ts +5 -2
package/dist/index.cjs
CHANGED
|
@@ -2238,7 +2238,7 @@ function injectDefaultTagMetadata(entities, tagGroups, skip) {
|
|
|
2238
2238
|
}
|
|
2239
2239
|
}
|
|
2240
2240
|
}
|
|
2241
|
-
function resolveActiveTagGroup(
|
|
2241
|
+
function resolveActiveTagGroup(tagGroups, explicitActiveTag, programmaticOverride) {
|
|
2242
2242
|
if (programmaticOverride !== void 0) {
|
|
2243
2243
|
if (!programmaticOverride) return null;
|
|
2244
2244
|
if (programmaticOverride.toLowerCase() === "none") return null;
|
|
@@ -2248,6 +2248,7 @@ function resolveActiveTagGroup(_tagGroups, explicitActiveTag, programmaticOverri
|
|
|
2248
2248
|
if (explicitActiveTag.toLowerCase() === "none") return null;
|
|
2249
2249
|
return explicitActiveTag;
|
|
2250
2250
|
}
|
|
2251
|
+
if (tagGroups.length > 0) return tagGroups[0].name;
|
|
2251
2252
|
return null;
|
|
2252
2253
|
}
|
|
2253
2254
|
function matchTagBlockHeading(trimmed) {
|
|
@@ -5328,12 +5329,6 @@ function parseClassDiagram(content, palette) {
|
|
|
5328
5329
|
diagnostics: [],
|
|
5329
5330
|
error: null
|
|
5330
5331
|
};
|
|
5331
|
-
const _fail = (line12, message) => {
|
|
5332
|
-
const diag = makeDgmoError(line12, message);
|
|
5333
|
-
result.diagnostics.push(diag);
|
|
5334
|
-
result.error = formatDgmoError(diag);
|
|
5335
|
-
return result;
|
|
5336
|
-
};
|
|
5337
5332
|
const classMap = /* @__PURE__ */ new Map();
|
|
5338
5333
|
const nameAliasMap = /* @__PURE__ */ new Map();
|
|
5339
5334
|
function resolveAliasName(token) {
|
|
@@ -5728,12 +5723,6 @@ function parseERDiagram(content, palette) {
|
|
|
5728
5723
|
diagnostics: [],
|
|
5729
5724
|
error: null
|
|
5730
5725
|
};
|
|
5731
|
-
const _fail = (line12, message) => {
|
|
5732
|
-
const diag = makeDgmoError(line12, message);
|
|
5733
|
-
result.diagnostics.push(diag);
|
|
5734
|
-
result.error = formatDgmoError(diag);
|
|
5735
|
-
return result;
|
|
5736
|
-
};
|
|
5737
5726
|
const pushError = (line12, message) => {
|
|
5738
5727
|
const diag = makeDgmoError(line12, message);
|
|
5739
5728
|
result.diagnostics.push(diag);
|
|
@@ -7170,7 +7159,7 @@ function buildSankeyOption(parsed, textColor, colors, bg, titleConfig) {
|
|
|
7170
7159
|
]
|
|
7171
7160
|
};
|
|
7172
7161
|
}
|
|
7173
|
-
function buildChordOption(parsed, palette, isDark, textColor, colors,
|
|
7162
|
+
function buildChordOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
7174
7163
|
const nodeSet = /* @__PURE__ */ new Set();
|
|
7175
7164
|
if (parsed.links) {
|
|
7176
7165
|
for (const link of parsed.links) {
|
|
@@ -7284,7 +7273,7 @@ function evaluateExpression(expr, x) {
|
|
|
7284
7273
|
return NaN;
|
|
7285
7274
|
}
|
|
7286
7275
|
}
|
|
7287
|
-
function buildFunctionOption(parsed, palette,
|
|
7276
|
+
function buildFunctionOption(parsed, palette, _isDark, textColor, axisLineColor, gridOpacity, colors, titleConfig) {
|
|
7288
7277
|
const xRange = parsed.xRange ?? { min: -10, max: 10 };
|
|
7289
7278
|
const samples = 200;
|
|
7290
7279
|
const step = (xRange.max - xRange.min) / samples;
|
|
@@ -7957,7 +7946,7 @@ function buildHeatmapOption(parsed, palette, isDark, textColor, axisLineColor, t
|
|
|
7957
7946
|
]
|
|
7958
7947
|
};
|
|
7959
7948
|
}
|
|
7960
|
-
function buildFunnelOption(parsed, palette, isDark, textColor, colors,
|
|
7949
|
+
function buildFunnelOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
7961
7950
|
const sorted = [...parsed.data].sort((a, b) => b.value - a.value);
|
|
7962
7951
|
const data = sorted.map((d) => {
|
|
7963
7952
|
const stroke2 = d.color ?? colors[parsed.data.indexOf(d) % colors.length];
|
|
@@ -8240,7 +8229,7 @@ function wrapLabel(text, maxChars) {
|
|
|
8240
8229
|
if (current) lines.push(current);
|
|
8241
8230
|
return lines.join("\n");
|
|
8242
8231
|
}
|
|
8243
|
-
function buildBarOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors,
|
|
8232
|
+
function buildBarOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors, _bg, titleConfig, chartWidth) {
|
|
8244
8233
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
8245
8234
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
8246
8235
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -8567,7 +8556,7 @@ function pieLabelLayout(parsed) {
|
|
|
8567
8556
|
if (maxLen > 18) return { outerRadius: 55, fontSize: 13 };
|
|
8568
8557
|
return { outerRadius: 70, fontSize: 14 };
|
|
8569
8558
|
}
|
|
8570
|
-
function buildPieOption(parsed, palette, isDark, textColor, colors,
|
|
8559
|
+
function buildPieOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig, isDoughnut) {
|
|
8571
8560
|
const HIDE_AXES = { xAxis: { show: false }, yAxis: { show: false } };
|
|
8572
8561
|
const data = parsed.data.map((d, i) => {
|
|
8573
8562
|
const stroke2 = d.color ?? colors[i % colors.length];
|
|
@@ -8666,7 +8655,7 @@ function buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, title
|
|
|
8666
8655
|
]
|
|
8667
8656
|
};
|
|
8668
8657
|
}
|
|
8669
|
-
function buildPolarAreaOption(parsed, palette, isDark, textColor, colors,
|
|
8658
|
+
function buildPolarAreaOption(parsed, palette, isDark, textColor, colors, _bg, titleConfig) {
|
|
8670
8659
|
const data = parsed.data.map((d, i) => {
|
|
8671
8660
|
const stroke2 = d.color ?? colors[i % colors.length];
|
|
8672
8661
|
return {
|
|
@@ -8709,7 +8698,7 @@ function buildPolarAreaOption(parsed, palette, isDark, textColor, colors, bg, ti
|
|
|
8709
8698
|
]
|
|
8710
8699
|
};
|
|
8711
8700
|
}
|
|
8712
|
-
function buildBarStackedOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors,
|
|
8701
|
+
function buildBarStackedOption(parsed, palette, isDark, textColor, axisLineColor, splitLineColor, gridOpacity, colors, _bg, titleConfig, chartWidth) {
|
|
8713
8702
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
8714
8703
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
8715
8704
|
const seriesNames = parsed.seriesNames ?? [];
|
|
@@ -8849,8 +8838,8 @@ async function renderExtendedChartForExport(content, theme, palette) {
|
|
|
8849
8838
|
const titleHeight = option.title && option.title.text ? 40 : 0;
|
|
8850
8839
|
const legendY = 8 + titleHeight;
|
|
8851
8840
|
const grid = option.grid;
|
|
8852
|
-
const gridLeftPct = grid?.left ? parseFloat(String(grid
|
|
8853
|
-
const gridRightPct = grid?.right ? parseFloat(String(grid
|
|
8841
|
+
const gridLeftPct = grid?.["left"] ? parseFloat(String(grid["left"])) : void 0;
|
|
8842
|
+
const gridRightPct = grid?.["right"] ? parseFloat(String(grid["right"])) : void 0;
|
|
8854
8843
|
const { svg: legendSvgStr } = renderLegendSvg(legendGroups, {
|
|
8855
8844
|
palette: effectivePalette,
|
|
8856
8845
|
isDark,
|
|
@@ -9200,7 +9189,7 @@ function parseOrg(content, palette) {
|
|
|
9200
9189
|
}
|
|
9201
9190
|
return result;
|
|
9202
9191
|
}
|
|
9203
|
-
function parseNodeLabel(trimmed, _indent, lineNumber,
|
|
9192
|
+
function parseNodeLabel(trimmed, _indent, lineNumber, _palette, counter, metaAliasMap = /* @__PURE__ */ new Map(), warnFn, nameAliasMap) {
|
|
9204
9193
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
9205
9194
|
let label = segments[0];
|
|
9206
9195
|
const asMatch = label.match(/^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/);
|
|
@@ -9449,8 +9438,8 @@ function parseKanban(content, palette) {
|
|
|
9449
9438
|
columnMetadata,
|
|
9450
9439
|
parsePipeMetadata(pipeSegments, metaAliasMap)
|
|
9451
9440
|
);
|
|
9452
|
-
if (columnMetadata
|
|
9453
|
-
const wipVal = parseInt(columnMetadata
|
|
9441
|
+
if (columnMetadata["wip"]) {
|
|
9442
|
+
const wipVal = parseInt(columnMetadata["wip"], 10);
|
|
9454
9443
|
if (!isNaN(wipVal)) {
|
|
9455
9444
|
wipLimit = wipVal;
|
|
9456
9445
|
}
|
|
@@ -9829,7 +9818,7 @@ function parseC4(content, palette) {
|
|
|
9829
9818
|
);
|
|
9830
9819
|
const shape = inferC4Shape(
|
|
9831
9820
|
nodeName,
|
|
9832
|
-
metadata
|
|
9821
|
+
metadata["tech"] ?? metadata["technology"]
|
|
9833
9822
|
);
|
|
9834
9823
|
const dNode = {
|
|
9835
9824
|
name: nodeName,
|
|
@@ -9932,11 +9921,11 @@ function parseC4(content, palette) {
|
|
|
9932
9921
|
target = targetBody.substring(0, pipeIdx).trim();
|
|
9933
9922
|
const metaPart = targetBody.substring(pipeIdx + 1).trim();
|
|
9934
9923
|
const meta = parsePipeMetadata(["", metaPart], metaAliasMap);
|
|
9935
|
-
if (meta
|
|
9936
|
-
technology = meta
|
|
9924
|
+
if (meta["tech"]) {
|
|
9925
|
+
technology = meta["tech"];
|
|
9937
9926
|
}
|
|
9938
|
-
if (meta
|
|
9939
|
-
technology = meta
|
|
9927
|
+
if (meta["technology"]) {
|
|
9928
|
+
technology = meta["technology"];
|
|
9940
9929
|
}
|
|
9941
9930
|
}
|
|
9942
9931
|
const rel = {
|
|
@@ -10070,7 +10059,7 @@ function parseC4(content, palette) {
|
|
|
10070
10059
|
metaAliasMap,
|
|
10071
10060
|
() => pushError(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
10072
10061
|
);
|
|
10073
|
-
const shape = explicitShape ?? inferC4Shape(namePart, metadata
|
|
10062
|
+
const shape = explicitShape ?? inferC4Shape(namePart, metadata["tech"] ?? metadata["technology"]);
|
|
10074
10063
|
let isADescription;
|
|
10075
10064
|
if ("description" in metadata) {
|
|
10076
10065
|
const descVal = metadata["description"].trim();
|
|
@@ -10130,7 +10119,7 @@ function parseC4(content, palette) {
|
|
|
10130
10119
|
metaAliasMap,
|
|
10131
10120
|
() => pushError(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
10132
10121
|
);
|
|
10133
|
-
const shape = explicitShape ?? inferC4Shape(namePart, metadata
|
|
10122
|
+
const shape = explicitShape ?? inferC4Shape(namePart, metadata["tech"] ?? metadata["technology"]);
|
|
10134
10123
|
let prefixDescription;
|
|
10135
10124
|
if ("description" in metadata) {
|
|
10136
10125
|
const descVal = metadata["description"].trim();
|
|
@@ -10739,7 +10728,7 @@ function parseSitemap(content, palette) {
|
|
|
10739
10728
|
}
|
|
10740
10729
|
return result;
|
|
10741
10730
|
}
|
|
10742
|
-
function parseNodeLabel2(trimmed, lineNumber,
|
|
10731
|
+
function parseNodeLabel2(trimmed, lineNumber, _palette, counter, metaAliasMap = /* @__PURE__ */ new Map(), warnFn, _diagnostics, nameAliasMap) {
|
|
10743
10732
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
10744
10733
|
let label = segments[0];
|
|
10745
10734
|
const asMatch = label.match(/^(.*?)\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*$/);
|
|
@@ -11030,11 +11019,11 @@ function parseInfra(content) {
|
|
|
11030
11019
|
continue;
|
|
11031
11020
|
}
|
|
11032
11021
|
if (trimmed === "animate") {
|
|
11033
|
-
result.options
|
|
11022
|
+
result.options["animate"] = "on";
|
|
11034
11023
|
continue;
|
|
11035
11024
|
}
|
|
11036
11025
|
if (trimmed === "no-animate") {
|
|
11037
|
-
result.options
|
|
11026
|
+
result.options["animate"] = "off";
|
|
11038
11027
|
continue;
|
|
11039
11028
|
}
|
|
11040
11029
|
if (tryParseSharedOption(trimmed, result.options)) {
|
|
@@ -11188,8 +11177,8 @@ function parseInfra(content) {
|
|
|
11188
11177
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11189
11178
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11190
11179
|
warnUnparsedPipeMeta(targetName, lineNumber, warn);
|
|
11191
|
-
const split = pipeMeta.tags
|
|
11192
|
-
const fanoutRaw = pipeMeta.tags
|
|
11180
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11181
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11193
11182
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11194
11183
|
warn(
|
|
11195
11184
|
lineNumber,
|
|
@@ -11220,8 +11209,8 @@ function parseInfra(content) {
|
|
|
11220
11209
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11221
11210
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11222
11211
|
warnUnparsedPipeMeta(targetName, lineNumber, warn);
|
|
11223
|
-
const split = pipeMeta.tags
|
|
11224
|
-
const fanoutRaw = pipeMeta.tags
|
|
11212
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11213
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11225
11214
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11226
11215
|
warn(
|
|
11227
11216
|
lineNumber,
|
|
@@ -11255,8 +11244,8 @@ function parseInfra(content) {
|
|
|
11255
11244
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11256
11245
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11257
11246
|
warnUnparsedPipeMeta(targetName, lineNumber, warn);
|
|
11258
|
-
const split = pipeMeta.tags
|
|
11259
|
-
const fanoutRaw = pipeMeta.tags
|
|
11247
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11248
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11260
11249
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11261
11250
|
warn(
|
|
11262
11251
|
lineNumber,
|
|
@@ -11287,8 +11276,8 @@ function parseInfra(content) {
|
|
|
11287
11276
|
const pipeMeta = extractPipeMetadata(targetRaw);
|
|
11288
11277
|
const targetName = pipeMeta.clean || targetRaw;
|
|
11289
11278
|
warnUnparsedPipeMeta(targetName, lineNumber, warn);
|
|
11290
|
-
const split = pipeMeta.tags
|
|
11291
|
-
const fanoutRaw = pipeMeta.tags
|
|
11279
|
+
const split = pipeMeta.tags["split"] ? parseFloat(pipeMeta.tags["split"]) : null;
|
|
11280
|
+
const fanoutRaw = pipeMeta.tags["fanout"] ? parseInt(pipeMeta.tags["fanout"], 10) : null;
|
|
11292
11281
|
if (fanoutRaw !== null && fanoutRaw < 1) {
|
|
11293
11282
|
warn(
|
|
11294
11283
|
lineNumber,
|
|
@@ -11995,15 +11984,15 @@ function parseGantt(content, palette) {
|
|
|
11995
11984
|
metaAliasMap,
|
|
11996
11985
|
() => warn(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
11997
11986
|
);
|
|
11998
|
-
if (meta
|
|
11999
|
-
const key = meta
|
|
11987
|
+
if (meta["lag"] || meta["lead"]) {
|
|
11988
|
+
const key = meta["lag"] ? "lag" : "lead";
|
|
12000
11989
|
softError(
|
|
12001
11990
|
lineNumber,
|
|
12002
11991
|
`"${key}" is no longer supported \u2014 use "offset: ${meta[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
12003
11992
|
);
|
|
12004
11993
|
}
|
|
12005
|
-
if (meta
|
|
12006
|
-
const raw = meta
|
|
11994
|
+
if (meta["offset"]) {
|
|
11995
|
+
const raw = meta["offset"];
|
|
12007
11996
|
if (raw.trim().startsWith("+")) {
|
|
12008
11997
|
warn(
|
|
12009
11998
|
lineNumber,
|
|
@@ -12390,15 +12379,15 @@ function parseGantt(content, palette) {
|
|
|
12390
12379
|
metaAliasMap,
|
|
12391
12380
|
() => warn(lineNumber, MULTIPLE_PIPE_ERROR)
|
|
12392
12381
|
);
|
|
12393
|
-
if (meta
|
|
12394
|
-
const key = meta
|
|
12382
|
+
if (meta["lag"] || meta["lead"]) {
|
|
12383
|
+
const key = meta["lag"] ? "lag" : "lead";
|
|
12395
12384
|
softError(
|
|
12396
12385
|
lineNumber,
|
|
12397
12386
|
`"${key}" is no longer supported \u2014 use "offset: ${meta[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
12398
12387
|
);
|
|
12399
12388
|
}
|
|
12400
|
-
if (meta
|
|
12401
|
-
const raw = meta
|
|
12389
|
+
if (meta["offset"]) {
|
|
12390
|
+
const raw = meta["offset"];
|
|
12402
12391
|
if (raw.trim().startsWith("+")) {
|
|
12403
12392
|
warn(
|
|
12404
12393
|
lineNumber,
|
|
@@ -12469,9 +12458,9 @@ function parseGantt(content, palette) {
|
|
|
12469
12458
|
() => warn(ln, MULTIPLE_PIPE_ERROR)
|
|
12470
12459
|
) : {};
|
|
12471
12460
|
let progress = null;
|
|
12472
|
-
if (metadata
|
|
12473
|
-
progress = parseFloat(metadata
|
|
12474
|
-
delete metadata
|
|
12461
|
+
if (metadata["progress"]) {
|
|
12462
|
+
progress = parseFloat(metadata["progress"]);
|
|
12463
|
+
delete metadata["progress"];
|
|
12475
12464
|
}
|
|
12476
12465
|
for (const part of segments.slice(1).join(",").split(",")) {
|
|
12477
12466
|
const seg = part.trim();
|
|
@@ -12480,16 +12469,16 @@ function parseGantt(content, palette) {
|
|
|
12480
12469
|
progress = parseInt(progressMatch[1], 10);
|
|
12481
12470
|
}
|
|
12482
12471
|
}
|
|
12483
|
-
if (metadata
|
|
12484
|
-
const key = metadata
|
|
12472
|
+
if (metadata["lag"] || metadata["lead"]) {
|
|
12473
|
+
const key = metadata["lag"] ? "lag" : "lead";
|
|
12485
12474
|
softError(
|
|
12486
12475
|
ln,
|
|
12487
12476
|
`"${key}" is no longer supported \u2014 use "offset: ${metadata[key]}" instead.${key === "lead" ? ' Negate the value for lead behavior: "offset: -...".' : ""}`
|
|
12488
12477
|
);
|
|
12489
12478
|
}
|
|
12490
12479
|
let taskOffset;
|
|
12491
|
-
if (metadata
|
|
12492
|
-
const raw = metadata
|
|
12480
|
+
if (metadata["offset"]) {
|
|
12481
|
+
const raw = metadata["offset"];
|
|
12493
12482
|
if (raw.trim().startsWith("+")) {
|
|
12494
12483
|
warn(
|
|
12495
12484
|
ln,
|
|
@@ -12504,7 +12493,7 @@ function parseGantt(content, palette) {
|
|
|
12504
12493
|
);
|
|
12505
12494
|
}
|
|
12506
12495
|
}
|
|
12507
|
-
delete metadata
|
|
12496
|
+
delete metadata["offset"];
|
|
12508
12497
|
}
|
|
12509
12498
|
const groupPath = currentGroupPath();
|
|
12510
12499
|
const inheritedMeta = {};
|
|
@@ -13027,7 +13016,7 @@ function parsePert(content, parseOpts = {}) {
|
|
|
13027
13016
|
id,
|
|
13028
13017
|
name,
|
|
13029
13018
|
activityIds: [],
|
|
13030
|
-
collapsed: meta
|
|
13019
|
+
collapsed: meta["collapsed"] === "true",
|
|
13031
13020
|
lineNumber,
|
|
13032
13021
|
...Object.keys(tags).length > 0 && { tags }
|
|
13033
13022
|
});
|
|
@@ -13289,7 +13278,7 @@ function parsePert(content, parseOpts = {}) {
|
|
|
13289
13278
|
name: decl.name,
|
|
13290
13279
|
...decl.alias !== void 0 && { alias: decl.alias },
|
|
13291
13280
|
duration: estimate,
|
|
13292
|
-
...meta
|
|
13281
|
+
...meta["confidence"] && { confidence: meta["confidence"] },
|
|
13293
13282
|
...decl.groupHint !== void 0 && { groupId: decl.groupHint },
|
|
13294
13283
|
lineNumber: decl.lineNumber,
|
|
13295
13284
|
isMilestone,
|
|
@@ -14620,7 +14609,7 @@ function parseMindmap(content, palette) {
|
|
|
14620
14609
|
}
|
|
14621
14610
|
return result;
|
|
14622
14611
|
}
|
|
14623
|
-
function parseNodeLine2(trimmed, lineNumber,
|
|
14612
|
+
function parseNodeLine2(trimmed, lineNumber, _palette, counter, aliasMap, warnFn) {
|
|
14624
14613
|
const segments = trimmed.split("|").map((s) => s.trim());
|
|
14625
14614
|
const label = segments[0];
|
|
14626
14615
|
const metadata = parsePipeMetadata(
|
|
@@ -15064,7 +15053,7 @@ function parseWireframe(content) {
|
|
|
15064
15053
|
wrapper.isContainer = true;
|
|
15065
15054
|
wrapper.orientation = "horizontal";
|
|
15066
15055
|
wrapper.children = children;
|
|
15067
|
-
wrapper.metadata
|
|
15056
|
+
wrapper.metadata["_inlineRow"] = "true";
|
|
15068
15057
|
pushElement(wrapper);
|
|
15069
15058
|
}
|
|
15070
15059
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -15215,7 +15204,7 @@ function parseWireframe(content) {
|
|
|
15215
15204
|
wrapper.isContainer = true;
|
|
15216
15205
|
wrapper.orientation = "horizontal";
|
|
15217
15206
|
wrapper.children.push(labelEl, fieldEl);
|
|
15218
|
-
wrapper.metadata
|
|
15207
|
+
wrapper.metadata["_labelField"] = "true";
|
|
15219
15208
|
pushElement(wrapper);
|
|
15220
15209
|
}
|
|
15221
15210
|
} else {
|
|
@@ -17036,9 +17025,9 @@ function parseRaci(content, palette) {
|
|
|
17036
17025
|
let roleColor;
|
|
17037
17026
|
if (segments.length > 1) {
|
|
17038
17027
|
const meta = parsePipeMetadata(segments);
|
|
17039
|
-
if (meta
|
|
17028
|
+
if (meta["color"]) {
|
|
17040
17029
|
roleColor = resolveColorWithDiagnostic(
|
|
17041
|
-
meta
|
|
17030
|
+
meta["color"],
|
|
17042
17031
|
j + 1,
|
|
17043
17032
|
result.diagnostics,
|
|
17044
17033
|
palette
|
|
@@ -17105,9 +17094,9 @@ function parseRaci(content, palette) {
|
|
|
17105
17094
|
let phaseColor;
|
|
17106
17095
|
if (phaseMatch[2]) {
|
|
17107
17096
|
const meta = parsePipeMetadata(["", phaseMatch[2]]);
|
|
17108
|
-
if (meta
|
|
17097
|
+
if (meta["color"]) {
|
|
17109
17098
|
phaseColor = resolveColorWithDiagnostic(
|
|
17110
|
-
meta
|
|
17099
|
+
meta["color"],
|
|
17111
17100
|
lineNumber,
|
|
17112
17101
|
result.diagnostics,
|
|
17113
17102
|
palette
|
|
@@ -19116,7 +19105,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
19116
19105
|
displayNames.set(group.name.toLowerCase(), group.name);
|
|
19117
19106
|
}
|
|
19118
19107
|
const rootNodeIds = new Set(parsed.roots.map((r) => r.id));
|
|
19119
|
-
const colorOff = parsed.options?.color === "off";
|
|
19108
|
+
const colorOff = parsed.options?.["color"] === "off";
|
|
19120
19109
|
for (const c of layout.containers) {
|
|
19121
19110
|
const cG = contentG.append("g").attr("transform", `translate(${c.x}, ${c.y})`).attr("class", "org-container").attr("data-line-number", String(c.lineNumber));
|
|
19122
19111
|
if (activeTagGroup) {
|
|
@@ -22216,7 +22205,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
|
|
|
22216
22205
|
const seriesColors2 = getSeriesColors(palette);
|
|
22217
22206
|
const semanticRoles = useSemanticColors ? classifyEREntities(parsed.tables, parsed.relationships) : null;
|
|
22218
22207
|
const semanticActive = semanticRoles !== null && (semanticColorsActive ?? true);
|
|
22219
|
-
const useLabels = parsed.options
|
|
22208
|
+
const useLabels = parsed.options["notation"] === "labels";
|
|
22220
22209
|
for (const edge of layout.edges) {
|
|
22221
22210
|
if (edge.points.length < 2) continue;
|
|
22222
22211
|
const edgeG = contentG.append("g").attr("class", "er-edge-group").attr("data-line-number", String(edge.lineNumber));
|
|
@@ -22431,495 +22420,6 @@ var init_renderer5 = __esm({
|
|
|
22431
22420
|
}
|
|
22432
22421
|
});
|
|
22433
22422
|
|
|
22434
|
-
// src/boxes-and-lines/layout.ts
|
|
22435
|
-
var layout_exports5 = {};
|
|
22436
|
-
__export(layout_exports5, {
|
|
22437
|
-
layoutBoxesAndLines: () => layoutBoxesAndLines
|
|
22438
|
-
});
|
|
22439
|
-
function clipToRectBorder2(cx, cy, w, h, tx, ty) {
|
|
22440
|
-
const dx = tx - cx;
|
|
22441
|
-
const dy = ty - cy;
|
|
22442
|
-
if (dx === 0 && dy === 0) return { x: cx, y: cy };
|
|
22443
|
-
const hw = w / 2;
|
|
22444
|
-
const hh = h / 2;
|
|
22445
|
-
const sx = dx !== 0 ? hw / Math.abs(dx) : Infinity;
|
|
22446
|
-
const sy = dy !== 0 ? hh / Math.abs(dy) : Infinity;
|
|
22447
|
-
const s = Math.min(sx, sy);
|
|
22448
|
-
return { x: cx + dx * s, y: cy + dy * s };
|
|
22449
|
-
}
|
|
22450
|
-
function splitCamelCase(word) {
|
|
22451
|
-
const parts = [];
|
|
22452
|
-
let start = 0;
|
|
22453
|
-
for (let i = 1; i < word.length; i++) {
|
|
22454
|
-
const prev = word[i - 1];
|
|
22455
|
-
const curr = word[i];
|
|
22456
|
-
const next = i + 1 < word.length ? word[i + 1] : "";
|
|
22457
|
-
const lowerToUpper = prev >= "a" && prev <= "z" && curr >= "A" && curr <= "Z";
|
|
22458
|
-
const upperRunEnd = prev >= "A" && prev <= "Z" && curr >= "A" && curr <= "Z" && next >= "a" && next <= "z";
|
|
22459
|
-
if (lowerToUpper || upperRunEnd) {
|
|
22460
|
-
parts.push(word.slice(start, i));
|
|
22461
|
-
start = i;
|
|
22462
|
-
}
|
|
22463
|
-
}
|
|
22464
|
-
parts.push(word.slice(start));
|
|
22465
|
-
return parts.length > 1 ? parts : [word];
|
|
22466
|
-
}
|
|
22467
|
-
function estimateLabelLines(label, nodeWidth2 = NODE_WIDTH) {
|
|
22468
|
-
const rawParts = label.split(/[\s-]+/);
|
|
22469
|
-
const words = [];
|
|
22470
|
-
for (const part of rawParts) {
|
|
22471
|
-
if (!part) continue;
|
|
22472
|
-
words.push(...splitCamelCase(part));
|
|
22473
|
-
}
|
|
22474
|
-
for (let fontSize = 13; fontSize >= 9; fontSize--) {
|
|
22475
|
-
const charWidth = fontSize * 0.6;
|
|
22476
|
-
const maxChars = Math.floor((nodeWidth2 - 24) / charWidth);
|
|
22477
|
-
if (maxChars < 2) continue;
|
|
22478
|
-
let lines = 1;
|
|
22479
|
-
let current = "";
|
|
22480
|
-
for (const word of words) {
|
|
22481
|
-
const test = current ? `${current} ${word}` : word;
|
|
22482
|
-
if (test.length <= maxChars) {
|
|
22483
|
-
current = test;
|
|
22484
|
-
} else {
|
|
22485
|
-
lines++;
|
|
22486
|
-
current = word;
|
|
22487
|
-
}
|
|
22488
|
-
}
|
|
22489
|
-
if (lines <= MAX_LABEL_LINES) return Math.min(lines, MAX_LABEL_LINES);
|
|
22490
|
-
}
|
|
22491
|
-
return MAX_LABEL_LINES;
|
|
22492
|
-
}
|
|
22493
|
-
function computeNodeSize(node) {
|
|
22494
|
-
if (!node.description || node.description.length === 0) {
|
|
22495
|
-
return { width: NODE_WIDTH, height: NODE_HEIGHT };
|
|
22496
|
-
}
|
|
22497
|
-
const w = DESC_NODE_WIDTH;
|
|
22498
|
-
const labelLines = estimateLabelLines(node.label, w);
|
|
22499
|
-
const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT + LABEL_PAD;
|
|
22500
|
-
const charsPerLine = Math.floor((w - 24) / (DESC_FONT_SIZE * 0.6));
|
|
22501
|
-
let totalRenderedLines = 0;
|
|
22502
|
-
for (const line12 of node.description) {
|
|
22503
|
-
if (line12.length <= charsPerLine) {
|
|
22504
|
-
totalRenderedLines += 1;
|
|
22505
|
-
} else {
|
|
22506
|
-
const words = line12.split(/\s+/);
|
|
22507
|
-
let current = "";
|
|
22508
|
-
let lineCount = 0;
|
|
22509
|
-
for (const word of words) {
|
|
22510
|
-
const fitted = word.length > charsPerLine ? word.slice(0, charsPerLine) : word;
|
|
22511
|
-
const test = current ? `${current} ${fitted}` : fitted;
|
|
22512
|
-
if (test.length <= charsPerLine) {
|
|
22513
|
-
current = test;
|
|
22514
|
-
} else {
|
|
22515
|
-
if (current) lineCount++;
|
|
22516
|
-
current = fitted;
|
|
22517
|
-
}
|
|
22518
|
-
}
|
|
22519
|
-
if (current) lineCount++;
|
|
22520
|
-
totalRenderedLines += lineCount;
|
|
22521
|
-
}
|
|
22522
|
-
}
|
|
22523
|
-
totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES);
|
|
22524
|
-
const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE * DESC_LINE_HEIGHT;
|
|
22525
|
-
const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING;
|
|
22526
|
-
return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
|
|
22527
|
-
}
|
|
22528
|
-
function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
|
|
22529
|
-
const hideDescriptions = layoutOptions?.hideDescriptions ?? false;
|
|
22530
|
-
const g = new import_dagre4.default.graphlib.Graph({ compound: true, multigraph: true });
|
|
22531
|
-
g.setGraph({
|
|
22532
|
-
rankdir: parsed.direction,
|
|
22533
|
-
nodesep: NODESEP,
|
|
22534
|
-
ranksep: RANKSEP,
|
|
22535
|
-
marginx: MARGIN3,
|
|
22536
|
-
marginy: MARGIN3
|
|
22537
|
-
});
|
|
22538
|
-
g.setDefaultEdgeLabel(() => ({}));
|
|
22539
|
-
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
22540
|
-
if (collapseInfo) {
|
|
22541
|
-
const missingGroups = /* @__PURE__ */ new Set();
|
|
22542
|
-
for (const og of collapseInfo.originalGroups) {
|
|
22543
|
-
if (!parsed.groups.some((g2) => g2.label === og.label)) {
|
|
22544
|
-
missingGroups.add(og.label);
|
|
22545
|
-
}
|
|
22546
|
-
}
|
|
22547
|
-
for (const label of missingGroups) {
|
|
22548
|
-
const og = collapseInfo.originalGroups.find((g2) => g2.label === label);
|
|
22549
|
-
const parentLabel = og?.parentGroup;
|
|
22550
|
-
if (!parentLabel || !missingGroups.has(parentLabel)) {
|
|
22551
|
-
collapsedGroupLabels.add(label);
|
|
22552
|
-
}
|
|
22553
|
-
}
|
|
22554
|
-
}
|
|
22555
|
-
for (const label of collapsedGroupLabels) {
|
|
22556
|
-
const gid = `__group_${label}`;
|
|
22557
|
-
g.setNode(gid, { label, width: NODE_WIDTH, height: NODE_HEIGHT });
|
|
22558
|
-
}
|
|
22559
|
-
for (const group of parsed.groups) {
|
|
22560
|
-
const gid = `__group_${group.label}`;
|
|
22561
|
-
g.setNode(gid, {
|
|
22562
|
-
label: group.label,
|
|
22563
|
-
paddingLeft: CONTAINER_PAD_X3,
|
|
22564
|
-
paddingRight: CONTAINER_PAD_X3,
|
|
22565
|
-
paddingTop: CONTAINER_PAD_TOP2,
|
|
22566
|
-
paddingBottom: CONTAINER_PAD_BOTTOM3
|
|
22567
|
-
});
|
|
22568
|
-
}
|
|
22569
|
-
const originalGroupByLabel = /* @__PURE__ */ new Map();
|
|
22570
|
-
if (collapseInfo) {
|
|
22571
|
-
for (const og of collapseInfo.originalGroups) {
|
|
22572
|
-
originalGroupByLabel.set(og.label, og);
|
|
22573
|
-
}
|
|
22574
|
-
}
|
|
22575
|
-
for (const label of collapsedGroupLabels) {
|
|
22576
|
-
const og = originalGroupByLabel.get(label);
|
|
22577
|
-
if (og?.parentGroup && !collapsedGroupLabels.has(og.parentGroup)) {
|
|
22578
|
-
const gid = `__group_${label}`;
|
|
22579
|
-
const parentGid = `__group_${og.parentGroup}`;
|
|
22580
|
-
if (g.hasNode(parentGid)) {
|
|
22581
|
-
g.setParent(gid, parentGid);
|
|
22582
|
-
}
|
|
22583
|
-
}
|
|
22584
|
-
}
|
|
22585
|
-
const nodeSizes = /* @__PURE__ */ new Map();
|
|
22586
|
-
let maxDescHeight = 0;
|
|
22587
|
-
for (const node of parsed.nodes) {
|
|
22588
|
-
const size = hideDescriptions ? { width: NODE_WIDTH, height: NODE_HEIGHT } : computeNodeSize(node);
|
|
22589
|
-
nodeSizes.set(node.label, size);
|
|
22590
|
-
if (!hideDescriptions && node.description && node.description.length > 0) {
|
|
22591
|
-
maxDescHeight = Math.max(maxDescHeight, size.height);
|
|
22592
|
-
}
|
|
22593
|
-
}
|
|
22594
|
-
if (maxDescHeight > 0) {
|
|
22595
|
-
for (const node of parsed.nodes) {
|
|
22596
|
-
if (node.description && node.description.length > 0) {
|
|
22597
|
-
const size = nodeSizes.get(node.label);
|
|
22598
|
-
nodeSizes.set(node.label, { width: size.width, height: maxDescHeight });
|
|
22599
|
-
}
|
|
22600
|
-
}
|
|
22601
|
-
}
|
|
22602
|
-
for (const node of parsed.nodes) {
|
|
22603
|
-
const size = nodeSizes.get(node.label);
|
|
22604
|
-
g.setNode(node.label, {
|
|
22605
|
-
label: node.label,
|
|
22606
|
-
width: size.width,
|
|
22607
|
-
height: size.height
|
|
22608
|
-
});
|
|
22609
|
-
}
|
|
22610
|
-
for (const group of parsed.groups) {
|
|
22611
|
-
if (group.parentGroup) {
|
|
22612
|
-
const childGid = `__group_${group.label}`;
|
|
22613
|
-
const parentGid = `__group_${group.parentGroup}`;
|
|
22614
|
-
if (g.hasNode(childGid) && g.hasNode(parentGid)) {
|
|
22615
|
-
g.setParent(childGid, parentGid);
|
|
22616
|
-
}
|
|
22617
|
-
}
|
|
22618
|
-
}
|
|
22619
|
-
const groupLabelSet = new Set(parsed.groups.map((gr) => gr.label));
|
|
22620
|
-
for (const group of parsed.groups) {
|
|
22621
|
-
const gid = `__group_${group.label}`;
|
|
22622
|
-
for (const child of group.children) {
|
|
22623
|
-
if (groupLabelSet.has(child)) continue;
|
|
22624
|
-
if (g.hasNode(child)) {
|
|
22625
|
-
g.setParent(child, gid);
|
|
22626
|
-
}
|
|
22627
|
-
}
|
|
22628
|
-
}
|
|
22629
|
-
const expandedGroupIds = /* @__PURE__ */ new Set();
|
|
22630
|
-
for (const group of parsed.groups) {
|
|
22631
|
-
expandedGroupIds.add(`__group_${group.label}`);
|
|
22632
|
-
}
|
|
22633
|
-
const groupFirstChild = /* @__PURE__ */ new Map();
|
|
22634
|
-
for (const group of parsed.groups) {
|
|
22635
|
-
const gid = `__group_${group.label}`;
|
|
22636
|
-
const firstChild = group.children.find(
|
|
22637
|
-
(c) => !groupLabelSet.has(c) && g.hasNode(c)
|
|
22638
|
-
);
|
|
22639
|
-
if (firstChild) {
|
|
22640
|
-
groupFirstChild.set(gid, firstChild);
|
|
22641
|
-
}
|
|
22642
|
-
}
|
|
22643
|
-
const deferredEdgeIndices = [];
|
|
22644
|
-
let proxyIdx = 0;
|
|
22645
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22646
|
-
const edge = parsed.edges[i];
|
|
22647
|
-
const src = edge.source;
|
|
22648
|
-
const tgt = edge.target;
|
|
22649
|
-
if (!g.hasNode(src) || !g.hasNode(tgt)) continue;
|
|
22650
|
-
if (expandedGroupIds.has(src) || expandedGroupIds.has(tgt)) {
|
|
22651
|
-
deferredEdgeIndices.push(i);
|
|
22652
|
-
const proxySrc = expandedGroupIds.has(src) ? groupFirstChild.get(src) : src;
|
|
22653
|
-
const proxyTgt = expandedGroupIds.has(tgt) ? groupFirstChild.get(tgt) : tgt;
|
|
22654
|
-
if (proxySrc && proxyTgt && proxySrc !== proxyTgt) {
|
|
22655
|
-
g.setEdge(
|
|
22656
|
-
proxySrc,
|
|
22657
|
-
proxyTgt,
|
|
22658
|
-
{ label: "", minlen: 1 },
|
|
22659
|
-
`proxy${proxyIdx++}`
|
|
22660
|
-
);
|
|
22661
|
-
}
|
|
22662
|
-
continue;
|
|
22663
|
-
}
|
|
22664
|
-
g.setEdge(src, tgt, { label: edge.label ?? "", minlen: 1 }, `e${i}`);
|
|
22665
|
-
}
|
|
22666
|
-
import_dagre4.default.layout(g);
|
|
22667
|
-
const layoutNodes = [];
|
|
22668
|
-
for (const node of parsed.nodes) {
|
|
22669
|
-
const dagreNode = g.node(node.label);
|
|
22670
|
-
if (!dagreNode) continue;
|
|
22671
|
-
layoutNodes.push({
|
|
22672
|
-
label: node.label,
|
|
22673
|
-
x: dagreNode.x,
|
|
22674
|
-
y: dagreNode.y,
|
|
22675
|
-
width: dagreNode.width,
|
|
22676
|
-
height: dagreNode.height
|
|
22677
|
-
});
|
|
22678
|
-
}
|
|
22679
|
-
const layoutGroups = [];
|
|
22680
|
-
for (const group of parsed.groups) {
|
|
22681
|
-
const gid = `__group_${group.label}`;
|
|
22682
|
-
const dagreNode = g.node(gid);
|
|
22683
|
-
if (!dagreNode) continue;
|
|
22684
|
-
layoutGroups.push({
|
|
22685
|
-
label: group.label,
|
|
22686
|
-
lineNumber: group.lineNumber,
|
|
22687
|
-
x: dagreNode.x,
|
|
22688
|
-
y: dagreNode.y,
|
|
22689
|
-
width: dagreNode.width,
|
|
22690
|
-
height: dagreNode.height,
|
|
22691
|
-
collapsed: false
|
|
22692
|
-
});
|
|
22693
|
-
}
|
|
22694
|
-
for (const label of collapsedGroupLabels) {
|
|
22695
|
-
const gid = `__group_${label}`;
|
|
22696
|
-
const dagreNode = g.node(gid);
|
|
22697
|
-
if (!dagreNode) continue;
|
|
22698
|
-
const og = collapseInfo?.originalGroups.find((g2) => g2.label === label);
|
|
22699
|
-
layoutGroups.push({
|
|
22700
|
-
label,
|
|
22701
|
-
lineNumber: og?.lineNumber ?? 0,
|
|
22702
|
-
x: dagreNode.x,
|
|
22703
|
-
y: dagreNode.y,
|
|
22704
|
-
width: dagreNode.width,
|
|
22705
|
-
height: dagreNode.height,
|
|
22706
|
-
collapsed: true,
|
|
22707
|
-
childCount: collapseInfo?.collapsedChildCounts.get(label) ?? 0
|
|
22708
|
-
});
|
|
22709
|
-
}
|
|
22710
|
-
const groupAlignShifts = /* @__PURE__ */ new Map();
|
|
22711
|
-
{
|
|
22712
|
-
const groupEdges = [];
|
|
22713
|
-
for (const edge of parsed.edges) {
|
|
22714
|
-
if (edge.source.startsWith("__group_") && edge.target.startsWith("__group_")) {
|
|
22715
|
-
groupEdges.push(edge);
|
|
22716
|
-
}
|
|
22717
|
-
}
|
|
22718
|
-
if (groupEdges.length > 0) {
|
|
22719
|
-
const groupParent = /* @__PURE__ */ new Map();
|
|
22720
|
-
const find = (x) => {
|
|
22721
|
-
while (groupParent.has(x) && groupParent.get(x) !== x) {
|
|
22722
|
-
groupParent.set(x, groupParent.get(groupParent.get(x)));
|
|
22723
|
-
x = groupParent.get(x);
|
|
22724
|
-
}
|
|
22725
|
-
return x;
|
|
22726
|
-
};
|
|
22727
|
-
const union = (a, b) => {
|
|
22728
|
-
const ra = find(a), rb = find(b);
|
|
22729
|
-
if (ra !== rb) groupParent.set(ra, rb);
|
|
22730
|
-
};
|
|
22731
|
-
for (const edge of groupEdges) {
|
|
22732
|
-
if (!groupParent.has(edge.source))
|
|
22733
|
-
groupParent.set(edge.source, edge.source);
|
|
22734
|
-
if (!groupParent.has(edge.target))
|
|
22735
|
-
groupParent.set(edge.target, edge.target);
|
|
22736
|
-
union(edge.source, edge.target);
|
|
22737
|
-
}
|
|
22738
|
-
const components = /* @__PURE__ */ new Map();
|
|
22739
|
-
for (const lg of layoutGroups) {
|
|
22740
|
-
const gid = `__group_${lg.label}`;
|
|
22741
|
-
if (!groupParent.has(gid)) continue;
|
|
22742
|
-
const root = find(gid);
|
|
22743
|
-
if (!components.has(root)) components.set(root, []);
|
|
22744
|
-
components.get(root).push(lg);
|
|
22745
|
-
}
|
|
22746
|
-
const axis = parsed.direction === "TB" ? "x" : "y";
|
|
22747
|
-
for (const groups of components.values()) {
|
|
22748
|
-
if (groups.length < 2) continue;
|
|
22749
|
-
const dim = axis === "x" ? "width" : "height";
|
|
22750
|
-
let widest = groups[0];
|
|
22751
|
-
for (const g2 of groups) {
|
|
22752
|
-
if (g2[dim] > widest[dim]) widest = g2;
|
|
22753
|
-
}
|
|
22754
|
-
const targetCenter = widest[axis];
|
|
22755
|
-
for (const grp of groups) {
|
|
22756
|
-
const dx = targetCenter - grp[axis];
|
|
22757
|
-
if (dx === 0) continue;
|
|
22758
|
-
grp[axis] += dx;
|
|
22759
|
-
groupAlignShifts.set(`__group_${grp.label}`, dx);
|
|
22760
|
-
const parsedGroup = parsed.groups.find(
|
|
22761
|
-
(pg) => pg.label === grp.label
|
|
22762
|
-
);
|
|
22763
|
-
if (parsedGroup) {
|
|
22764
|
-
for (const childLabel of parsedGroup.children) {
|
|
22765
|
-
const childNode = layoutNodes.find((n) => n.label === childLabel);
|
|
22766
|
-
if (childNode) childNode[axis] += dx;
|
|
22767
|
-
}
|
|
22768
|
-
}
|
|
22769
|
-
}
|
|
22770
|
-
}
|
|
22771
|
-
}
|
|
22772
|
-
}
|
|
22773
|
-
const edgeYOffsets = new Array(parsed.edges.length).fill(0);
|
|
22774
|
-
const edgeParallelCounts = new Array(parsed.edges.length).fill(1);
|
|
22775
|
-
const parallelGroups = /* @__PURE__ */ new Map();
|
|
22776
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22777
|
-
const edge = parsed.edges[i];
|
|
22778
|
-
const [a, b] = edge.source < edge.target ? [edge.source, edge.target] : [edge.target, edge.source];
|
|
22779
|
-
const key = `${a}\0${b}`;
|
|
22780
|
-
if (!parallelGroups.has(key)) parallelGroups.set(key, []);
|
|
22781
|
-
parallelGroups.get(key).push(i);
|
|
22782
|
-
}
|
|
22783
|
-
for (const group of parallelGroups.values()) {
|
|
22784
|
-
const capped = group.slice(0, MAX_PARALLEL_EDGES);
|
|
22785
|
-
for (const idx of group.slice(MAX_PARALLEL_EDGES)) {
|
|
22786
|
-
edgeParallelCounts[idx] = 0;
|
|
22787
|
-
}
|
|
22788
|
-
if (capped.length < 2) continue;
|
|
22789
|
-
const effectiveSpacing = PARALLEL_SPACING;
|
|
22790
|
-
for (let j = 0; j < capped.length; j++) {
|
|
22791
|
-
edgeYOffsets[capped[j]] = (j - (capped.length - 1) / 2) * effectiveSpacing;
|
|
22792
|
-
edgeParallelCounts[capped[j]] = capped.length;
|
|
22793
|
-
}
|
|
22794
|
-
}
|
|
22795
|
-
const deferredSet = new Set(deferredEdgeIndices);
|
|
22796
|
-
const layoutEdges = [];
|
|
22797
|
-
for (let i = 0; i < parsed.edges.length; i++) {
|
|
22798
|
-
const edge = parsed.edges[i];
|
|
22799
|
-
if (edgeParallelCounts[i] === 0) continue;
|
|
22800
|
-
let points;
|
|
22801
|
-
if (deferredSet.has(i)) {
|
|
22802
|
-
const srcLayout = layoutGroups.find(
|
|
22803
|
-
(lg) => `__group_${lg.label}` === edge.source
|
|
22804
|
-
);
|
|
22805
|
-
const tgtLayout = layoutGroups.find(
|
|
22806
|
-
(lg) => `__group_${lg.label}` === edge.target
|
|
22807
|
-
);
|
|
22808
|
-
if (!srcLayout || !tgtLayout) {
|
|
22809
|
-
const srcNode = g.node(edge.source);
|
|
22810
|
-
const tgtNode = g.node(edge.target);
|
|
22811
|
-
if (!srcNode || !tgtNode) continue;
|
|
22812
|
-
const srcPt = clipToRectBorder2(
|
|
22813
|
-
srcNode.x,
|
|
22814
|
-
srcNode.y,
|
|
22815
|
-
srcNode.width,
|
|
22816
|
-
srcNode.height,
|
|
22817
|
-
tgtNode.x,
|
|
22818
|
-
tgtNode.y
|
|
22819
|
-
);
|
|
22820
|
-
const tgtPt = clipToRectBorder2(
|
|
22821
|
-
tgtNode.x,
|
|
22822
|
-
tgtNode.y,
|
|
22823
|
-
tgtNode.width,
|
|
22824
|
-
tgtNode.height,
|
|
22825
|
-
srcNode.x,
|
|
22826
|
-
srcNode.y
|
|
22827
|
-
);
|
|
22828
|
-
const midX = (srcPt.x + tgtPt.x) / 2;
|
|
22829
|
-
const midY = (srcPt.y + tgtPt.y) / 2;
|
|
22830
|
-
points = [srcPt, { x: midX, y: midY }, tgtPt];
|
|
22831
|
-
} else if (parsed.direction === "TB") {
|
|
22832
|
-
const cx = (srcLayout.x + tgtLayout.x) / 2;
|
|
22833
|
-
const srcPt = { x: cx, y: srcLayout.y + srcLayout.height / 2 };
|
|
22834
|
-
const tgtPt = { x: cx, y: tgtLayout.y - tgtLayout.height / 2 };
|
|
22835
|
-
const midY = (srcPt.y + tgtPt.y) / 2;
|
|
22836
|
-
points = [srcPt, { x: cx, y: midY }, tgtPt];
|
|
22837
|
-
} else {
|
|
22838
|
-
const cy = (srcLayout.y + tgtLayout.y) / 2;
|
|
22839
|
-
const srcPt = { x: srcLayout.x + srcLayout.width / 2, y: cy };
|
|
22840
|
-
const tgtPt = { x: tgtLayout.x - tgtLayout.width / 2, y: cy };
|
|
22841
|
-
const midX = (srcPt.x + tgtPt.x) / 2;
|
|
22842
|
-
points = [srcPt, { x: midX, y: cy }, tgtPt];
|
|
22843
|
-
}
|
|
22844
|
-
} else {
|
|
22845
|
-
const dagreEdge = g.edge(edge.source, edge.target, `e${i}`);
|
|
22846
|
-
points = dagreEdge?.points ?? [];
|
|
22847
|
-
const srcShift = groupAlignShifts.get(edge.source) ?? 0;
|
|
22848
|
-
const tgtShift = groupAlignShifts.get(edge.target) ?? 0;
|
|
22849
|
-
if (srcShift !== 0 || tgtShift !== 0) {
|
|
22850
|
-
const avgShift = (srcShift + tgtShift) / 2;
|
|
22851
|
-
const prop = parsed.direction === "TB" ? "x" : "y";
|
|
22852
|
-
points = points.map((p) => ({ ...p, [prop]: p[prop] + avgShift }));
|
|
22853
|
-
}
|
|
22854
|
-
}
|
|
22855
|
-
let labelX;
|
|
22856
|
-
let labelY;
|
|
22857
|
-
if (edge.label && points.length >= 2) {
|
|
22858
|
-
const mid = Math.floor(points.length / 2);
|
|
22859
|
-
labelX = points[mid].x;
|
|
22860
|
-
labelY = points[mid].y - 10;
|
|
22861
|
-
}
|
|
22862
|
-
layoutEdges.push({
|
|
22863
|
-
source: edge.source,
|
|
22864
|
-
target: edge.target,
|
|
22865
|
-
label: edge.label,
|
|
22866
|
-
bidirectional: edge.bidirectional,
|
|
22867
|
-
lineNumber: edge.lineNumber,
|
|
22868
|
-
points,
|
|
22869
|
-
labelX,
|
|
22870
|
-
labelY,
|
|
22871
|
-
yOffset: edgeYOffsets[i],
|
|
22872
|
-
parallelCount: edgeParallelCounts[i],
|
|
22873
|
-
metadata: edge.metadata,
|
|
22874
|
-
deferred: deferredSet.has(i) || void 0
|
|
22875
|
-
});
|
|
22876
|
-
}
|
|
22877
|
-
let maxX = 0;
|
|
22878
|
-
let maxY = 0;
|
|
22879
|
-
for (const node of layoutNodes) {
|
|
22880
|
-
maxX = Math.max(maxX, node.x + node.width / 2);
|
|
22881
|
-
maxY = Math.max(maxY, node.y + node.height / 2);
|
|
22882
|
-
}
|
|
22883
|
-
for (const group of layoutGroups) {
|
|
22884
|
-
maxX = Math.max(maxX, group.x + group.width / 2);
|
|
22885
|
-
maxY = Math.max(maxY, group.y + group.height / 2);
|
|
22886
|
-
}
|
|
22887
|
-
return {
|
|
22888
|
-
nodes: layoutNodes,
|
|
22889
|
-
edges: layoutEdges,
|
|
22890
|
-
groups: layoutGroups,
|
|
22891
|
-
width: maxX + MARGIN3,
|
|
22892
|
-
height: maxY + MARGIN3
|
|
22893
|
-
};
|
|
22894
|
-
}
|
|
22895
|
-
var import_dagre4, NODESEP, RANKSEP, MARGIN3, CONTAINER_PAD_X3, CONTAINER_PAD_TOP2, CONTAINER_PAD_BOTTOM3, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE, DESC_LINE_HEIGHT, DESC_PADDING, SEPARATOR_GAP5, MAX_DESC_LINES, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, LABEL_PAD;
|
|
22896
|
-
var init_layout5 = __esm({
|
|
22897
|
-
"src/boxes-and-lines/layout.ts"() {
|
|
22898
|
-
"use strict";
|
|
22899
|
-
import_dagre4 = __toESM(require("@dagrejs/dagre"), 1);
|
|
22900
|
-
NODESEP = 60;
|
|
22901
|
-
RANKSEP = 100;
|
|
22902
|
-
MARGIN3 = 40;
|
|
22903
|
-
CONTAINER_PAD_X3 = 30;
|
|
22904
|
-
CONTAINER_PAD_TOP2 = 40;
|
|
22905
|
-
CONTAINER_PAD_BOTTOM3 = 24;
|
|
22906
|
-
MAX_PARALLEL_EDGES = 5;
|
|
22907
|
-
PARALLEL_SPACING = 22;
|
|
22908
|
-
PHI = 1.618;
|
|
22909
|
-
NODE_HEIGHT = 60;
|
|
22910
|
-
NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
|
|
22911
|
-
DESC_NODE_WIDTH = 140;
|
|
22912
|
-
DESC_FONT_SIZE = 10;
|
|
22913
|
-
DESC_LINE_HEIGHT = 1.4;
|
|
22914
|
-
DESC_PADDING = 8;
|
|
22915
|
-
SEPARATOR_GAP5 = 4;
|
|
22916
|
-
MAX_DESC_LINES = 6;
|
|
22917
|
-
MAX_LABEL_LINES = 3;
|
|
22918
|
-
LABEL_LINE_HEIGHT = 1.3;
|
|
22919
|
-
LABEL_PAD = 12;
|
|
22920
|
-
}
|
|
22921
|
-
});
|
|
22922
|
-
|
|
22923
22423
|
// src/utils/wrapped-desc.ts
|
|
22924
22424
|
function wrapDescriptionLines(lines, charsPerLine, lengthFn = (s) => s.length) {
|
|
22925
22425
|
const result = [];
|
|
@@ -22969,7 +22469,7 @@ __export(renderer_exports6, {
|
|
|
22969
22469
|
renderBoxesAndLines: () => renderBoxesAndLines,
|
|
22970
22470
|
renderBoxesAndLinesForExport: () => renderBoxesAndLinesForExport
|
|
22971
22471
|
});
|
|
22972
|
-
function
|
|
22472
|
+
function splitCamelCase(word) {
|
|
22973
22473
|
const parts = [];
|
|
22974
22474
|
let start = 0;
|
|
22975
22475
|
for (let i = 1; i < word.length; i++) {
|
|
@@ -22992,7 +22492,7 @@ function fitLabelToHeader(label, nodeWidth2, maxLines) {
|
|
|
22992
22492
|
const words = [];
|
|
22993
22493
|
for (const part of rawParts) {
|
|
22994
22494
|
if (!part || /^\s+$/.test(part) || part === "-") continue;
|
|
22995
|
-
words.push(...
|
|
22495
|
+
words.push(...splitCamelCase(part));
|
|
22996
22496
|
}
|
|
22997
22497
|
for (let fontSize = NODE_FONT_SIZE; fontSize >= MIN_NODE_FONT_SIZE; fontSize--) {
|
|
22998
22498
|
const charWidth2 = fontSize * CHAR_WIDTH_RATIO2;
|
|
@@ -23368,12 +22868,12 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23368
22868
|
}
|
|
23369
22869
|
const sepY = -ln.height / 2 + headerH;
|
|
23370
22870
|
nodeG.append("line").attr("x1", -ln.width / 2).attr("y1", sepY).attr("x2", ln.width / 2).attr("y2", sepY).attr("stroke", colors.stroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
|
|
23371
|
-
const descStartY = sepY + 4 +
|
|
22871
|
+
const descStartY = sepY + 4 + DESC_FONT_SIZE;
|
|
23372
22872
|
const maxTextWidth = ln.width - NODE_TEXT_PADDING * 2;
|
|
23373
22873
|
const charsPerLine = Math.floor(
|
|
23374
|
-
maxTextWidth / (
|
|
22874
|
+
maxTextWidth / (DESC_FONT_SIZE * CHAR_WIDTH_RATIO2)
|
|
23375
22875
|
);
|
|
23376
|
-
const descLineH =
|
|
22876
|
+
const descLineH = DESC_FONT_SIZE * DESC_LINE_HEIGHT;
|
|
23377
22877
|
const displayLen = (text) => text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*(.+?)\*\*/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/`(.+?)`/g, "$1").replace(/https?:\/\/\S+/g, (u) => u.slice(0, 20)).length;
|
|
23378
22878
|
const normalizedLines = [];
|
|
23379
22879
|
for (const descLine of desc) {
|
|
@@ -23389,8 +22889,8 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23389
22889
|
charsPerLine,
|
|
23390
22890
|
displayLen
|
|
23391
22891
|
);
|
|
23392
|
-
const truncated = wrappedLinesShared.length >
|
|
23393
|
-
const visibleLines = truncated ? wrappedLinesShared.slice(0,
|
|
22892
|
+
const truncated = wrappedLinesShared.length > MAX_DESC_LINES;
|
|
22893
|
+
const visibleLines = truncated ? wrappedLinesShared.slice(0, MAX_DESC_LINES) : wrappedLinesShared;
|
|
23394
22894
|
const BULLET_GLYPH_X = -ln.width / 2 + 6;
|
|
23395
22895
|
const BULLET_BODY_X = BULLET_GLYPH_X + 10;
|
|
23396
22896
|
for (let li = 0; li < visibleLines.length; li++) {
|
|
@@ -23401,11 +22901,11 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
23401
22901
|
}
|
|
23402
22902
|
const y2 = descStartY + li * descLineH;
|
|
23403
22903
|
if (line12.kind === "bullet-first") {
|
|
23404
|
-
nodeG.append("text").attr("x", BULLET_GLYPH_X).attr("y", y2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("font-size",
|
|
22904
|
+
nodeG.append("text").attr("x", BULLET_GLYPH_X).attr("y", y2).attr("text-anchor", "start").attr("dominant-baseline", "central").attr("font-size", DESC_FONT_SIZE).attr("fill", palette.textMuted).text("\u2022");
|
|
23405
22905
|
}
|
|
23406
22906
|
const isBullet = line12.kind === "bullet-first" || line12.kind === "bullet-cont";
|
|
23407
|
-
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",
|
|
23408
|
-
renderInlineText(textEl, lineText, palette,
|
|
22907
|
+
const textEl = nodeG.append("text").attr("x", isBullet ? BULLET_BODY_X : 0).attr("y", y2).attr("text-anchor", isBullet ? "start" : "middle").attr("dominant-baseline", "central").attr("font-size", DESC_FONT_SIZE).attr("fill", palette.textMuted);
|
|
22908
|
+
renderInlineText(textEl, lineText, palette, DESC_FONT_SIZE);
|
|
23409
22909
|
}
|
|
23410
22910
|
if (truncated) {
|
|
23411
22911
|
const fullText = desc.join(" ");
|
|
@@ -23483,7 +22983,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
|
|
|
23483
22983
|
hiddenTagValues: options?.hiddenTagValues
|
|
23484
22984
|
});
|
|
23485
22985
|
}
|
|
23486
|
-
var d3Selection6, d3Shape4, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2,
|
|
22986
|
+
var d3Selection6, d3Shape4, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, CHAR_WIDTH_RATIO2, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, lineGeneratorLR, lineGeneratorTB;
|
|
23487
22987
|
var init_renderer6 = __esm({
|
|
23488
22988
|
"src/boxes-and-lines/renderer.ts"() {
|
|
23489
22989
|
"use strict";
|
|
@@ -23507,9 +23007,9 @@ var init_renderer6 = __esm({
|
|
|
23507
23007
|
COLLAPSE_BAR_HEIGHT3 = 4;
|
|
23508
23008
|
ARROWHEAD_W2 = 5;
|
|
23509
23009
|
ARROWHEAD_H2 = 4;
|
|
23510
|
-
|
|
23511
|
-
|
|
23512
|
-
|
|
23010
|
+
DESC_FONT_SIZE = 10;
|
|
23011
|
+
DESC_LINE_HEIGHT = 1.4;
|
|
23012
|
+
MAX_DESC_LINES = 6;
|
|
23513
23013
|
CHAR_WIDTH_RATIO2 = 0.6;
|
|
23514
23014
|
NODE_TEXT_PADDING = 12;
|
|
23515
23015
|
GROUP_RX = 8;
|
|
@@ -23520,6 +23020,523 @@ var init_renderer6 = __esm({
|
|
|
23520
23020
|
}
|
|
23521
23021
|
});
|
|
23522
23022
|
|
|
23023
|
+
// src/boxes-and-lines/layout.ts
|
|
23024
|
+
var layout_exports5 = {};
|
|
23025
|
+
__export(layout_exports5, {
|
|
23026
|
+
layoutBoxesAndLines: () => layoutBoxesAndLines
|
|
23027
|
+
});
|
|
23028
|
+
function splitCamelCase2(word) {
|
|
23029
|
+
const parts = [];
|
|
23030
|
+
let start = 0;
|
|
23031
|
+
for (let i = 1; i < word.length; i++) {
|
|
23032
|
+
const prev = word[i - 1];
|
|
23033
|
+
const curr = word[i];
|
|
23034
|
+
const next = i + 1 < word.length ? word[i + 1] : "";
|
|
23035
|
+
const lowerToUpper = prev >= "a" && prev <= "z" && curr >= "A" && curr <= "Z";
|
|
23036
|
+
const upperRunEnd = prev >= "A" && prev <= "Z" && curr >= "A" && curr <= "Z" && next >= "a" && next <= "z";
|
|
23037
|
+
if (lowerToUpper || upperRunEnd) {
|
|
23038
|
+
parts.push(word.slice(start, i));
|
|
23039
|
+
start = i;
|
|
23040
|
+
}
|
|
23041
|
+
}
|
|
23042
|
+
parts.push(word.slice(start));
|
|
23043
|
+
return parts.length > 1 ? parts : [word];
|
|
23044
|
+
}
|
|
23045
|
+
function estimateLabelLines(label, nodeWidth2 = NODE_WIDTH) {
|
|
23046
|
+
const rawParts = label.split(/[\s-]+/);
|
|
23047
|
+
const words = [];
|
|
23048
|
+
for (const part of rawParts) {
|
|
23049
|
+
if (!part) continue;
|
|
23050
|
+
words.push(...splitCamelCase2(part));
|
|
23051
|
+
}
|
|
23052
|
+
for (let fontSize = 13; fontSize >= 9; fontSize--) {
|
|
23053
|
+
const charWidth = fontSize * 0.6;
|
|
23054
|
+
const maxChars = Math.floor((nodeWidth2 - 24) / charWidth);
|
|
23055
|
+
if (maxChars < 2) continue;
|
|
23056
|
+
let lines = 1;
|
|
23057
|
+
let current = "";
|
|
23058
|
+
for (const word of words) {
|
|
23059
|
+
const test = current ? `${current} ${word}` : word;
|
|
23060
|
+
if (test.length <= maxChars) {
|
|
23061
|
+
current = test;
|
|
23062
|
+
} else {
|
|
23063
|
+
lines++;
|
|
23064
|
+
current = word;
|
|
23065
|
+
}
|
|
23066
|
+
}
|
|
23067
|
+
if (lines <= MAX_LABEL_LINES) return Math.min(lines, MAX_LABEL_LINES);
|
|
23068
|
+
}
|
|
23069
|
+
return MAX_LABEL_LINES;
|
|
23070
|
+
}
|
|
23071
|
+
function computeNodeSize(node) {
|
|
23072
|
+
if (!node.description || node.description.length === 0) {
|
|
23073
|
+
return { width: NODE_WIDTH, height: NODE_HEIGHT };
|
|
23074
|
+
}
|
|
23075
|
+
const w = DESC_NODE_WIDTH;
|
|
23076
|
+
const labelLines = estimateLabelLines(node.label, w);
|
|
23077
|
+
const labelHeight = labelLines * 13 * LABEL_LINE_HEIGHT + LABEL_PAD;
|
|
23078
|
+
const charsPerLine = Math.floor((w - 24) / (DESC_FONT_SIZE2 * 0.6));
|
|
23079
|
+
let totalRenderedLines = 0;
|
|
23080
|
+
for (const line12 of node.description) {
|
|
23081
|
+
if (line12.length <= charsPerLine) {
|
|
23082
|
+
totalRenderedLines += 1;
|
|
23083
|
+
} else {
|
|
23084
|
+
const words = line12.split(/\s+/);
|
|
23085
|
+
let current = "";
|
|
23086
|
+
let lineCount = 0;
|
|
23087
|
+
for (const word of words) {
|
|
23088
|
+
const fitted = word.length > charsPerLine ? word.slice(0, charsPerLine) : word;
|
|
23089
|
+
const test = current ? `${current} ${fitted}` : fitted;
|
|
23090
|
+
if (test.length <= charsPerLine) {
|
|
23091
|
+
current = test;
|
|
23092
|
+
} else {
|
|
23093
|
+
if (current) lineCount++;
|
|
23094
|
+
current = fitted;
|
|
23095
|
+
}
|
|
23096
|
+
}
|
|
23097
|
+
if (current) lineCount++;
|
|
23098
|
+
totalRenderedLines += lineCount;
|
|
23099
|
+
}
|
|
23100
|
+
}
|
|
23101
|
+
totalRenderedLines = Math.min(totalRenderedLines, MAX_DESC_LINES2);
|
|
23102
|
+
const descriptionHeight = totalRenderedLines * DESC_FONT_SIZE2 * DESC_LINE_HEIGHT2;
|
|
23103
|
+
const totalHeight = labelHeight + SEPARATOR_GAP5 + DESC_PADDING + descriptionHeight + DESC_PADDING;
|
|
23104
|
+
return { width: w, height: Math.max(NODE_HEIGHT, totalHeight) };
|
|
23105
|
+
}
|
|
23106
|
+
function getElk() {
|
|
23107
|
+
if (!elkInstance) elkInstance = new import_elk_bundled.default();
|
|
23108
|
+
return elkInstance;
|
|
23109
|
+
}
|
|
23110
|
+
function baseOptions() {
|
|
23111
|
+
return {
|
|
23112
|
+
"elk.algorithm": "layered",
|
|
23113
|
+
// INCLUDE_CHILDREN lets ELK route edges across container boundaries.
|
|
23114
|
+
"elk.hierarchyHandling": "INCLUDE_CHILDREN",
|
|
23115
|
+
"elk.edgeRouting": "ORTHOGONAL",
|
|
23116
|
+
"elk.layered.unnecessaryBendpoints": "true",
|
|
23117
|
+
// Let edges leave from top/bottom of nodes (not just the flow-direction
|
|
23118
|
+
// sides) when it reduces crossings.
|
|
23119
|
+
"elk.layered.allowNonFlowPortsToSwitchSides": "true"
|
|
23120
|
+
};
|
|
23121
|
+
}
|
|
23122
|
+
function bkBaseline() {
|
|
23123
|
+
return {
|
|
23124
|
+
...baseOptions(),
|
|
23125
|
+
"elk.layered.nodePlacement.strategy": "BRANDES_KOEPF",
|
|
23126
|
+
"elk.layered.nodePlacement.bk.fixedAlignment": "BALANCED",
|
|
23127
|
+
"elk.layered.nodePlacement.bk.edgeStraightening": "IMPROVE_STRAIGHTNESS",
|
|
23128
|
+
"elk.layered.compaction.connectedComponents": "true",
|
|
23129
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": "90",
|
|
23130
|
+
"elk.spacing.nodeNode": "55",
|
|
23131
|
+
"elk.spacing.edgeNode": "55",
|
|
23132
|
+
"elk.spacing.edgeEdge": "18"
|
|
23133
|
+
};
|
|
23134
|
+
}
|
|
23135
|
+
function getVariants() {
|
|
23136
|
+
const bk = bkBaseline();
|
|
23137
|
+
return [
|
|
23138
|
+
{
|
|
23139
|
+
name: "bk-baseline",
|
|
23140
|
+
options: {
|
|
23141
|
+
...bk,
|
|
23142
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "ONE_SIDED"
|
|
23143
|
+
}
|
|
23144
|
+
},
|
|
23145
|
+
{
|
|
23146
|
+
name: "bk-aggressive",
|
|
23147
|
+
options: {
|
|
23148
|
+
...bk,
|
|
23149
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23150
|
+
"elk.layered.thoroughness": "50"
|
|
23151
|
+
}
|
|
23152
|
+
},
|
|
23153
|
+
{
|
|
23154
|
+
name: "bk-wide",
|
|
23155
|
+
options: {
|
|
23156
|
+
...bk,
|
|
23157
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23158
|
+
"elk.layered.thoroughness": "50",
|
|
23159
|
+
"elk.spacing.nodeNode": "70",
|
|
23160
|
+
"elk.spacing.edgeNode": "75",
|
|
23161
|
+
"elk.spacing.edgeEdge": "22",
|
|
23162
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": "120"
|
|
23163
|
+
}
|
|
23164
|
+
},
|
|
23165
|
+
{
|
|
23166
|
+
name: "longest-path",
|
|
23167
|
+
options: {
|
|
23168
|
+
...bk,
|
|
23169
|
+
"elk.layered.layering.strategy": "LONGEST_PATH",
|
|
23170
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23171
|
+
"elk.layered.thoroughness": "50"
|
|
23172
|
+
}
|
|
23173
|
+
},
|
|
23174
|
+
{
|
|
23175
|
+
name: "bounded-width",
|
|
23176
|
+
options: {
|
|
23177
|
+
...bk,
|
|
23178
|
+
"elk.layered.layering.strategy": "COFFMAN_GRAHAM",
|
|
23179
|
+
"elk.layered.layering.coffmanGraham.layerBound": "3",
|
|
23180
|
+
"elk.layered.crossingMinimization.greedySwitch.type": "TWO_SIDED",
|
|
23181
|
+
"elk.layered.thoroughness": "50"
|
|
23182
|
+
}
|
|
23183
|
+
}
|
|
23184
|
+
];
|
|
23185
|
+
}
|
|
23186
|
+
function countCrossings(edges) {
|
|
23187
|
+
let count = 0;
|
|
23188
|
+
for (let i = 0; i < edges.length; i++) {
|
|
23189
|
+
const a = edges[i].points;
|
|
23190
|
+
if (a.length < 2) continue;
|
|
23191
|
+
for (let j = i + 1; j < edges.length; j++) {
|
|
23192
|
+
const b = edges[j].points;
|
|
23193
|
+
if (b.length < 2) continue;
|
|
23194
|
+
if (edges[i].source === edges[j].source) continue;
|
|
23195
|
+
if (edges[i].source === edges[j].target) continue;
|
|
23196
|
+
if (edges[i].target === edges[j].source) continue;
|
|
23197
|
+
if (edges[i].target === edges[j].target) continue;
|
|
23198
|
+
for (let ai = 0; ai < a.length - 1; ai++) {
|
|
23199
|
+
for (let bi = 0; bi < b.length - 1; bi++) {
|
|
23200
|
+
if (segmentsCross(a[ai], a[ai + 1], b[bi], b[bi + 1])) count++;
|
|
23201
|
+
}
|
|
23202
|
+
}
|
|
23203
|
+
}
|
|
23204
|
+
}
|
|
23205
|
+
return count;
|
|
23206
|
+
}
|
|
23207
|
+
function segmentsCross(p1, p2, p3, p4) {
|
|
23208
|
+
const d1x = p2.x - p1.x;
|
|
23209
|
+
const d1y = p2.y - p1.y;
|
|
23210
|
+
const d2x = p4.x - p3.x;
|
|
23211
|
+
const d2y = p4.y - p3.y;
|
|
23212
|
+
const denom = d1x * d2y - d1y * d2x;
|
|
23213
|
+
if (Math.abs(denom) < 1e-9) return false;
|
|
23214
|
+
const t = ((p3.x - p1.x) * d2y - (p3.y - p1.y) * d2x) / denom;
|
|
23215
|
+
const s = ((p3.x - p1.x) * d1y - (p3.y - p1.y) * d1x) / denom;
|
|
23216
|
+
const EPS = 1e-3;
|
|
23217
|
+
return t > EPS && t < 1 - EPS && s > EPS && s < 1 - EPS;
|
|
23218
|
+
}
|
|
23219
|
+
function countTotalBends(edges) {
|
|
23220
|
+
let bends = 0;
|
|
23221
|
+
for (const e of edges) bends += Math.max(0, e.points.length - 2);
|
|
23222
|
+
return bends;
|
|
23223
|
+
}
|
|
23224
|
+
function scoreLayout(layout) {
|
|
23225
|
+
return {
|
|
23226
|
+
crossings: countCrossings(layout.edges),
|
|
23227
|
+
bends: countTotalBends(layout.edges),
|
|
23228
|
+
area: layout.width * layout.height
|
|
23229
|
+
};
|
|
23230
|
+
}
|
|
23231
|
+
function cmpScore(a, b) {
|
|
23232
|
+
const aBucket = a.crossings <= CROSSINGS_FORGIVENESS ? 0 : a.crossings;
|
|
23233
|
+
const bBucket = b.crossings <= CROSSINGS_FORGIVENESS ? 0 : b.crossings;
|
|
23234
|
+
if (aBucket !== bBucket) return aBucket - bBucket;
|
|
23235
|
+
if (a.area !== b.area) return a.area - b.area;
|
|
23236
|
+
return a.bends - b.bends;
|
|
23237
|
+
}
|
|
23238
|
+
async function layoutBoxesAndLines(parsed, collapseInfo, layoutOptions) {
|
|
23239
|
+
const hideDescriptions = layoutOptions?.hideDescriptions ?? false;
|
|
23240
|
+
const direction = parsed.direction === "TB" ? "DOWN" : "RIGHT";
|
|
23241
|
+
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
23242
|
+
if (collapseInfo) {
|
|
23243
|
+
const missingGroups = /* @__PURE__ */ new Set();
|
|
23244
|
+
for (const og of collapseInfo.originalGroups) {
|
|
23245
|
+
if (!parsed.groups.some((g) => g.label === og.label)) {
|
|
23246
|
+
missingGroups.add(og.label);
|
|
23247
|
+
}
|
|
23248
|
+
}
|
|
23249
|
+
for (const label of missingGroups) {
|
|
23250
|
+
const og = collapseInfo.originalGroups.find((g) => g.label === label);
|
|
23251
|
+
const parentLabel = og?.parentGroup;
|
|
23252
|
+
if (!parentLabel || !missingGroups.has(parentLabel)) {
|
|
23253
|
+
collapsedGroupLabels.add(label);
|
|
23254
|
+
}
|
|
23255
|
+
}
|
|
23256
|
+
}
|
|
23257
|
+
const nodeSizes = /* @__PURE__ */ new Map();
|
|
23258
|
+
let maxDescHeight = 0;
|
|
23259
|
+
for (const node of parsed.nodes) {
|
|
23260
|
+
const size = hideDescriptions ? { width: NODE_WIDTH, height: NODE_HEIGHT } : computeNodeSize(node);
|
|
23261
|
+
nodeSizes.set(node.label, size);
|
|
23262
|
+
if (!hideDescriptions && node.description && node.description.length > 0) {
|
|
23263
|
+
maxDescHeight = Math.max(maxDescHeight, size.height);
|
|
23264
|
+
}
|
|
23265
|
+
}
|
|
23266
|
+
if (maxDescHeight > 0) {
|
|
23267
|
+
for (const node of parsed.nodes) {
|
|
23268
|
+
if (node.description && node.description.length > 0) {
|
|
23269
|
+
const size = nodeSizes.get(node.label);
|
|
23270
|
+
nodeSizes.set(node.label, { width: size.width, height: maxDescHeight });
|
|
23271
|
+
}
|
|
23272
|
+
}
|
|
23273
|
+
}
|
|
23274
|
+
const expandedGroupSet = new Set(parsed.groups.map((g) => g.label));
|
|
23275
|
+
const gid = (label) => `__group_${label}`;
|
|
23276
|
+
function buildGraph() {
|
|
23277
|
+
const nodeById = /* @__PURE__ */ new Map();
|
|
23278
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
23279
|
+
for (const node of parsed.nodes) {
|
|
23280
|
+
const size = nodeSizes.get(node.label);
|
|
23281
|
+
nodeById.set(node.label, {
|
|
23282
|
+
id: node.label,
|
|
23283
|
+
width: size.width,
|
|
23284
|
+
height: size.height,
|
|
23285
|
+
labels: [{ text: node.label }]
|
|
23286
|
+
});
|
|
23287
|
+
}
|
|
23288
|
+
for (const group of parsed.groups) {
|
|
23289
|
+
nodeById.set(gid(group.label), {
|
|
23290
|
+
id: gid(group.label),
|
|
23291
|
+
labels: [{ text: group.label }],
|
|
23292
|
+
layoutOptions: {
|
|
23293
|
+
"elk.padding": `[top=${CONTAINER_PAD_TOP2},left=${CONTAINER_PAD_X3},bottom=${CONTAINER_PAD_BOTTOM3},right=${CONTAINER_PAD_X3}]`,
|
|
23294
|
+
// Suggest square-ish containers — has limited effect with
|
|
23295
|
+
// INCLUDE_CHILDREN but doesn't hurt.
|
|
23296
|
+
"elk.aspectRatio": "1.4"
|
|
23297
|
+
},
|
|
23298
|
+
children: [],
|
|
23299
|
+
edges: []
|
|
23300
|
+
});
|
|
23301
|
+
}
|
|
23302
|
+
for (const label of collapsedGroupLabels) {
|
|
23303
|
+
nodeById.set(gid(label), {
|
|
23304
|
+
id: gid(label),
|
|
23305
|
+
width: NODE_WIDTH,
|
|
23306
|
+
height: NODE_HEIGHT,
|
|
23307
|
+
labels: [{ text: label }]
|
|
23308
|
+
});
|
|
23309
|
+
}
|
|
23310
|
+
for (const group of parsed.groups) {
|
|
23311
|
+
if (group.parentGroup && nodeById.has(gid(group.parentGroup))) {
|
|
23312
|
+
parentOf.set(gid(group.label), gid(group.parentGroup));
|
|
23313
|
+
}
|
|
23314
|
+
}
|
|
23315
|
+
if (collapseInfo) {
|
|
23316
|
+
for (const label of collapsedGroupLabels) {
|
|
23317
|
+
const og = collapseInfo.originalGroups.find((g) => g.label === label);
|
|
23318
|
+
if (og?.parentGroup && !collapsedGroupLabels.has(og.parentGroup) && nodeById.has(gid(og.parentGroup))) {
|
|
23319
|
+
parentOf.set(gid(label), gid(og.parentGroup));
|
|
23320
|
+
}
|
|
23321
|
+
}
|
|
23322
|
+
}
|
|
23323
|
+
for (const group of parsed.groups) {
|
|
23324
|
+
for (const child of group.children) {
|
|
23325
|
+
if (expandedGroupSet.has(child)) continue;
|
|
23326
|
+
if (nodeById.has(child)) {
|
|
23327
|
+
parentOf.set(child, gid(group.label));
|
|
23328
|
+
}
|
|
23329
|
+
}
|
|
23330
|
+
}
|
|
23331
|
+
const roots = [];
|
|
23332
|
+
for (const [id, node] of nodeById) {
|
|
23333
|
+
const parentId = parentOf.get(id);
|
|
23334
|
+
if (parentId) {
|
|
23335
|
+
const parent = nodeById.get(parentId);
|
|
23336
|
+
parent.children = parent.children ?? [];
|
|
23337
|
+
parent.children.push(node);
|
|
23338
|
+
} else {
|
|
23339
|
+
roots.push(node);
|
|
23340
|
+
}
|
|
23341
|
+
}
|
|
23342
|
+
const rootEdges = [];
|
|
23343
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23344
|
+
const edge = parsed.edges[i];
|
|
23345
|
+
if (!nodeById.has(edge.source) || !nodeById.has(edge.target)) continue;
|
|
23346
|
+
rootEdges.push({
|
|
23347
|
+
id: `e${i}`,
|
|
23348
|
+
sources: [edge.source],
|
|
23349
|
+
targets: [edge.target]
|
|
23350
|
+
});
|
|
23351
|
+
}
|
|
23352
|
+
return { roots, rootEdges };
|
|
23353
|
+
}
|
|
23354
|
+
async function runVariant(variant) {
|
|
23355
|
+
const { roots, rootEdges } = buildGraph();
|
|
23356
|
+
const elkRoot = {
|
|
23357
|
+
id: "root",
|
|
23358
|
+
layoutOptions: {
|
|
23359
|
+
...variant.options,
|
|
23360
|
+
"elk.direction": direction,
|
|
23361
|
+
"elk.padding": `[top=${MARGIN3},left=${MARGIN3},bottom=${MARGIN3},right=${MARGIN3}]`
|
|
23362
|
+
},
|
|
23363
|
+
children: roots,
|
|
23364
|
+
edges: rootEdges
|
|
23365
|
+
};
|
|
23366
|
+
const result = await getElk().layout(elkRoot);
|
|
23367
|
+
return extractLayout(result);
|
|
23368
|
+
}
|
|
23369
|
+
function extractLayout(result) {
|
|
23370
|
+
const layoutNodes = [];
|
|
23371
|
+
const layoutGroups = [];
|
|
23372
|
+
const allEdges = [];
|
|
23373
|
+
const containerAbs = /* @__PURE__ */ new Map();
|
|
23374
|
+
function walk(n, offsetX, offsetY, isRoot) {
|
|
23375
|
+
const nx = (n.x ?? 0) + offsetX;
|
|
23376
|
+
const ny = (n.y ?? 0) + offsetY;
|
|
23377
|
+
const nw = n.width ?? 0;
|
|
23378
|
+
const nh = n.height ?? 0;
|
|
23379
|
+
if (isRoot) {
|
|
23380
|
+
containerAbs.set("root", { x: nx, y: ny });
|
|
23381
|
+
} else {
|
|
23382
|
+
const isGroup = n.id.startsWith("__group_");
|
|
23383
|
+
if (isGroup) {
|
|
23384
|
+
const label = n.id.slice("__group_".length);
|
|
23385
|
+
const collapsed = collapsedGroupLabels.has(label);
|
|
23386
|
+
const og = collapseInfo?.originalGroups.find(
|
|
23387
|
+
(g) => g.label === label
|
|
23388
|
+
);
|
|
23389
|
+
const pg = parsed.groups.find((g) => g.label === label);
|
|
23390
|
+
layoutGroups.push({
|
|
23391
|
+
label,
|
|
23392
|
+
lineNumber: pg?.lineNumber ?? og?.lineNumber ?? 0,
|
|
23393
|
+
x: nx + nw / 2,
|
|
23394
|
+
y: ny + nh / 2,
|
|
23395
|
+
width: nw,
|
|
23396
|
+
height: nh,
|
|
23397
|
+
collapsed,
|
|
23398
|
+
childCount: collapsed ? collapseInfo?.collapsedChildCounts.get(label) ?? 0 : void 0
|
|
23399
|
+
});
|
|
23400
|
+
if (!collapsed) containerAbs.set(n.id, { x: nx, y: ny });
|
|
23401
|
+
} else {
|
|
23402
|
+
layoutNodes.push({
|
|
23403
|
+
label: n.id,
|
|
23404
|
+
x: nx + nw / 2,
|
|
23405
|
+
y: ny + nh / 2,
|
|
23406
|
+
width: nw,
|
|
23407
|
+
height: nh
|
|
23408
|
+
});
|
|
23409
|
+
}
|
|
23410
|
+
}
|
|
23411
|
+
if (n.edges) for (const e of n.edges) allEdges.push(e);
|
|
23412
|
+
if (n.children) for (const c of n.children) walk(c, nx, ny, false);
|
|
23413
|
+
}
|
|
23414
|
+
walk(result, 0, 0, true);
|
|
23415
|
+
const edgeYOffsets = new Array(parsed.edges.length).fill(0);
|
|
23416
|
+
const edgeParallelCounts = new Array(parsed.edges.length).fill(1);
|
|
23417
|
+
const parallelGroups = /* @__PURE__ */ new Map();
|
|
23418
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23419
|
+
const edge = parsed.edges[i];
|
|
23420
|
+
const [a, b] = edge.source < edge.target ? [edge.source, edge.target] : [edge.target, edge.source];
|
|
23421
|
+
const key = `${a}\0${b}`;
|
|
23422
|
+
if (!parallelGroups.has(key)) parallelGroups.set(key, []);
|
|
23423
|
+
parallelGroups.get(key).push(i);
|
|
23424
|
+
}
|
|
23425
|
+
for (const group of parallelGroups.values()) {
|
|
23426
|
+
const capped = group.slice(0, MAX_PARALLEL_EDGES);
|
|
23427
|
+
for (const idx of group.slice(MAX_PARALLEL_EDGES)) {
|
|
23428
|
+
edgeParallelCounts[idx] = 0;
|
|
23429
|
+
}
|
|
23430
|
+
if (capped.length < 2) continue;
|
|
23431
|
+
for (let j = 0; j < capped.length; j++) {
|
|
23432
|
+
edgeYOffsets[capped[j]] = (j - (capped.length - 1) / 2) * PARALLEL_SPACING;
|
|
23433
|
+
edgeParallelCounts[capped[j]] = capped.length;
|
|
23434
|
+
}
|
|
23435
|
+
}
|
|
23436
|
+
const edgeById = /* @__PURE__ */ new Map();
|
|
23437
|
+
for (const e of allEdges) edgeById.set(e.id, e);
|
|
23438
|
+
const layoutEdges = [];
|
|
23439
|
+
for (let i = 0; i < parsed.edges.length; i++) {
|
|
23440
|
+
const edge = parsed.edges[i];
|
|
23441
|
+
if (edgeParallelCounts[i] === 0) continue;
|
|
23442
|
+
const elkEdge = edgeById.get(`e${i}`);
|
|
23443
|
+
if (!elkEdge || !elkEdge.sections || elkEdge.sections.length === 0)
|
|
23444
|
+
continue;
|
|
23445
|
+
const container = elkEdge.container ?? "root";
|
|
23446
|
+
const off = containerAbs.get(container) ?? { x: 0, y: 0 };
|
|
23447
|
+
const s = elkEdge.sections[0];
|
|
23448
|
+
const points = [
|
|
23449
|
+
{ x: s.startPoint.x + off.x, y: s.startPoint.y + off.y },
|
|
23450
|
+
...(s.bendPoints ?? []).map((p) => ({
|
|
23451
|
+
x: p.x + off.x,
|
|
23452
|
+
y: p.y + off.y
|
|
23453
|
+
})),
|
|
23454
|
+
{ x: s.endPoint.x + off.x, y: s.endPoint.y + off.y }
|
|
23455
|
+
];
|
|
23456
|
+
let labelX;
|
|
23457
|
+
let labelY;
|
|
23458
|
+
if (edge.label && points.length >= 2) {
|
|
23459
|
+
const mid = Math.floor(points.length / 2);
|
|
23460
|
+
labelX = points[mid].x;
|
|
23461
|
+
labelY = points[mid].y - 10;
|
|
23462
|
+
}
|
|
23463
|
+
layoutEdges.push({
|
|
23464
|
+
source: edge.source,
|
|
23465
|
+
target: edge.target,
|
|
23466
|
+
label: edge.label,
|
|
23467
|
+
bidirectional: edge.bidirectional,
|
|
23468
|
+
lineNumber: edge.lineNumber,
|
|
23469
|
+
points,
|
|
23470
|
+
labelX,
|
|
23471
|
+
labelY,
|
|
23472
|
+
yOffset: edgeYOffsets[i],
|
|
23473
|
+
parallelCount: edgeParallelCounts[i],
|
|
23474
|
+
metadata: edge.metadata,
|
|
23475
|
+
deferred: true
|
|
23476
|
+
});
|
|
23477
|
+
}
|
|
23478
|
+
let maxX = 0;
|
|
23479
|
+
let maxY = 0;
|
|
23480
|
+
for (const node of layoutNodes) {
|
|
23481
|
+
maxX = Math.max(maxX, node.x + node.width / 2);
|
|
23482
|
+
maxY = Math.max(maxY, node.y + node.height / 2);
|
|
23483
|
+
}
|
|
23484
|
+
for (const group of layoutGroups) {
|
|
23485
|
+
maxX = Math.max(maxX, group.x + group.width / 2);
|
|
23486
|
+
maxY = Math.max(maxY, group.y + group.height / 2);
|
|
23487
|
+
}
|
|
23488
|
+
return {
|
|
23489
|
+
nodes: layoutNodes,
|
|
23490
|
+
edges: layoutEdges,
|
|
23491
|
+
groups: layoutGroups,
|
|
23492
|
+
width: maxX + MARGIN3,
|
|
23493
|
+
height: maxY + MARGIN3
|
|
23494
|
+
};
|
|
23495
|
+
}
|
|
23496
|
+
const N = parsed.nodes.length + parsed.groups.length;
|
|
23497
|
+
const E = parsed.edges.length;
|
|
23498
|
+
const trivial = N < 8 && E < 10;
|
|
23499
|
+
const variants = trivial ? [getVariants()[1]] : getVariants();
|
|
23500
|
+
const results = await Promise.all(variants.map((v) => runVariant(v)));
|
|
23501
|
+
let best = results[0];
|
|
23502
|
+
let bestScore = scoreLayout(best);
|
|
23503
|
+
for (let i = 1; i < results.length; i++) {
|
|
23504
|
+
const s = scoreLayout(results[i]);
|
|
23505
|
+
if (cmpScore(s, bestScore) < 0) {
|
|
23506
|
+
best = results[i];
|
|
23507
|
+
bestScore = s;
|
|
23508
|
+
}
|
|
23509
|
+
}
|
|
23510
|
+
return best;
|
|
23511
|
+
}
|
|
23512
|
+
var import_elk_bundled, MARGIN3, CONTAINER_PAD_X3, CONTAINER_PAD_TOP2, CONTAINER_PAD_BOTTOM3, MAX_PARALLEL_EDGES, PARALLEL_SPACING, PHI, NODE_HEIGHT, NODE_WIDTH, DESC_NODE_WIDTH, DESC_FONT_SIZE2, DESC_LINE_HEIGHT2, DESC_PADDING, SEPARATOR_GAP5, MAX_DESC_LINES2, MAX_LABEL_LINES, LABEL_LINE_HEIGHT, LABEL_PAD, elkInstance, CROSSINGS_FORGIVENESS;
|
|
23513
|
+
var init_layout5 = __esm({
|
|
23514
|
+
"src/boxes-and-lines/layout.ts"() {
|
|
23515
|
+
"use strict";
|
|
23516
|
+
import_elk_bundled = __toESM(require("elkjs/lib/elk.bundled.js"), 1);
|
|
23517
|
+
MARGIN3 = 40;
|
|
23518
|
+
CONTAINER_PAD_X3 = 30;
|
|
23519
|
+
CONTAINER_PAD_TOP2 = 40;
|
|
23520
|
+
CONTAINER_PAD_BOTTOM3 = 24;
|
|
23521
|
+
MAX_PARALLEL_EDGES = 5;
|
|
23522
|
+
PARALLEL_SPACING = 22;
|
|
23523
|
+
PHI = 1.618;
|
|
23524
|
+
NODE_HEIGHT = 60;
|
|
23525
|
+
NODE_WIDTH = Math.round(NODE_HEIGHT * PHI);
|
|
23526
|
+
DESC_NODE_WIDTH = 140;
|
|
23527
|
+
DESC_FONT_SIZE2 = 10;
|
|
23528
|
+
DESC_LINE_HEIGHT2 = 1.4;
|
|
23529
|
+
DESC_PADDING = 8;
|
|
23530
|
+
SEPARATOR_GAP5 = 4;
|
|
23531
|
+
MAX_DESC_LINES2 = 6;
|
|
23532
|
+
MAX_LABEL_LINES = 3;
|
|
23533
|
+
LABEL_LINE_HEIGHT = 1.3;
|
|
23534
|
+
LABEL_PAD = 12;
|
|
23535
|
+
elkInstance = null;
|
|
23536
|
+
CROSSINGS_FORGIVENESS = 1;
|
|
23537
|
+
}
|
|
23538
|
+
});
|
|
23539
|
+
|
|
23523
23540
|
// src/mindmap/text-wrap.ts
|
|
23524
23541
|
function tokenize(text) {
|
|
23525
23542
|
const tokens = [];
|
|
@@ -23658,7 +23675,7 @@ var layout_exports6 = {};
|
|
|
23658
23675
|
__export(layout_exports6, {
|
|
23659
23676
|
layoutMindmap: () => layoutMindmap
|
|
23660
23677
|
});
|
|
23661
|
-
function layoutMindmap(parsed,
|
|
23678
|
+
function layoutMindmap(parsed, _palette, options) {
|
|
23662
23679
|
const roots = parsed.roots;
|
|
23663
23680
|
if (roots.length === 0) {
|
|
23664
23681
|
return { nodes: [], edges: [], width: 0, height: 0 };
|
|
@@ -24554,7 +24571,7 @@ function layoutElement(el, x, y, width) {
|
|
|
24554
24571
|
node.height = getElementHeight(el);
|
|
24555
24572
|
return node;
|
|
24556
24573
|
}
|
|
24557
|
-
const isInlineRow = el.metadata
|
|
24574
|
+
const isInlineRow = el.metadata["_inlineRow"] === "true" || el.metadata["_labelField"] === "true";
|
|
24558
24575
|
const padTop = isInlineRow ? 0 : GROUP_PADDING_TOP;
|
|
24559
24576
|
const padBottom = isInlineRow ? 0 : GROUP_PADDING_BOTTOM;
|
|
24560
24577
|
const padX = isInlineRow ? 0 : GROUP_PADDING_X;
|
|
@@ -24603,7 +24620,7 @@ function allocateEqualWidths(children, totalWidth) {
|
|
|
24603
24620
|
}
|
|
24604
24621
|
function getElementHeight(el) {
|
|
24605
24622
|
if (el.type === "heading") {
|
|
24606
|
-
return el.headingLevel === 2 ? ELEMENT_HEIGHTS
|
|
24623
|
+
return el.headingLevel === 2 ? ELEMENT_HEIGHTS["subheading"] ?? 36 : ELEMENT_HEIGHTS["heading"] ?? 48;
|
|
24607
24624
|
}
|
|
24608
24625
|
if (el.type === "textInput" && el.fieldVariant === "textarea") {
|
|
24609
24626
|
return 80;
|
|
@@ -24617,16 +24634,16 @@ function getElementHeight(el) {
|
|
|
24617
24634
|
if (el.type === "image") {
|
|
24618
24635
|
if (el.imageHint === "round") return 80;
|
|
24619
24636
|
if (el.imageHint === "wide") return 80;
|
|
24620
|
-
return ELEMENT_HEIGHTS
|
|
24637
|
+
return ELEMENT_HEIGHTS["image"] ?? 120;
|
|
24621
24638
|
}
|
|
24622
|
-
if (el.metadata
|
|
24639
|
+
if (el.metadata["_labelField"] === "true") {
|
|
24623
24640
|
return 36;
|
|
24624
24641
|
}
|
|
24625
24642
|
return ELEMENT_HEIGHTS[el.type] ?? 24;
|
|
24626
24643
|
}
|
|
24627
24644
|
function getSpacingAfter(el) {
|
|
24628
24645
|
if (el.type === "heading" && el.headingLevel === 2) {
|
|
24629
|
-
return SPACING_AFTER
|
|
24646
|
+
return SPACING_AFTER["subheading"] ?? 12;
|
|
24630
24647
|
}
|
|
24631
24648
|
return SPACING_AFTER[el.type] ?? 8;
|
|
24632
24649
|
}
|
|
@@ -24634,7 +24651,7 @@ function computeFieldAlignX(children) {
|
|
|
24634
24651
|
let maxLabelWidth = 0;
|
|
24635
24652
|
let labelFieldCount = 0;
|
|
24636
24653
|
for (const child of children) {
|
|
24637
|
-
if (child.metadata
|
|
24654
|
+
if (child.metadata["_labelField"] === "true" && child.children.length >= 2) {
|
|
24638
24655
|
const labelEl = child.children[0];
|
|
24639
24656
|
const labelWidth = labelEl.label.length * CHAR_WIDTH5;
|
|
24640
24657
|
maxLabelWidth = Math.max(maxLabelWidth, labelWidth);
|
|
@@ -24845,7 +24862,7 @@ function renderNode(parent, node, ctx, depth) {
|
|
|
24845
24862
|
function renderGroup(g, node, ctx, depth) {
|
|
24846
24863
|
const { palette, isTransparent } = ctx;
|
|
24847
24864
|
const el = node.element;
|
|
24848
|
-
if (el.metadata
|
|
24865
|
+
if (el.metadata["_inlineRow"] === "true" || el.metadata["_labelField"] === "true") {
|
|
24849
24866
|
for (const child of node.children) {
|
|
24850
24867
|
renderNode(g, child, ctx, depth);
|
|
24851
24868
|
}
|
|
@@ -24973,7 +24990,7 @@ function renderDivider(g, node, ctx) {
|
|
|
24973
24990
|
function renderText(g, node, ctx) {
|
|
24974
24991
|
const { palette } = ctx;
|
|
24975
24992
|
const el = node.element;
|
|
24976
|
-
if (el.metadata
|
|
24993
|
+
if (el.metadata["_labelField"] === "true" && el.children.length >= 2) {
|
|
24977
24994
|
for (const child of node.children) {
|
|
24978
24995
|
renderNode(g, child, ctx, 0);
|
|
24979
24996
|
}
|
|
@@ -25708,7 +25725,7 @@ function layoutC4Context(parsed, activeTagGroup) {
|
|
|
25708
25725
|
}
|
|
25709
25726
|
const contextRels = rollUpContextRelationships(parsed);
|
|
25710
25727
|
const spacing = computeAdaptiveSpacing(contextRels);
|
|
25711
|
-
const g = new
|
|
25728
|
+
const g = new import_dagre4.default.graphlib.Graph();
|
|
25712
25729
|
g.setGraph({
|
|
25713
25730
|
rankdir: "TB",
|
|
25714
25731
|
nodesep: spacing.nodesep,
|
|
@@ -25729,7 +25746,7 @@ function layoutC4Context(parsed, activeTagGroup) {
|
|
|
25729
25746
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
25730
25747
|
}
|
|
25731
25748
|
}
|
|
25732
|
-
|
|
25749
|
+
import_dagre4.default.layout(g);
|
|
25733
25750
|
reduceCrossings(
|
|
25734
25751
|
g,
|
|
25735
25752
|
validRels.map((r) => ({ source: r.sourceName, target: r.targetName }))
|
|
@@ -25901,7 +25918,7 @@ function layoutC4Containers(parsed, systemName, activeTagGroup) {
|
|
|
25901
25918
|
}
|
|
25902
25919
|
}
|
|
25903
25920
|
const hasGroups = elementToGroup.size > 0;
|
|
25904
|
-
const g = hasGroups ? new
|
|
25921
|
+
const g = hasGroups ? new import_dagre4.default.graphlib.Graph({ compound: true }) : new import_dagre4.default.graphlib.Graph();
|
|
25905
25922
|
g.setDefaultEdgeLabel(() => ({}));
|
|
25906
25923
|
if (hasGroups) {
|
|
25907
25924
|
const seenGroups = /* @__PURE__ */ new Set();
|
|
@@ -25979,7 +25996,7 @@ function layoutC4Containers(parsed, systemName, activeTagGroup) {
|
|
|
25979
25996
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
25980
25997
|
}
|
|
25981
25998
|
}
|
|
25982
|
-
|
|
25999
|
+
import_dagre4.default.layout(g);
|
|
25983
26000
|
const nodeGroupMap = hasGroups ? new Map([...elementToGroup.entries()].map(([k, v]) => [k, v.name])) : void 0;
|
|
25984
26001
|
reduceCrossings(
|
|
25985
26002
|
g,
|
|
@@ -26305,7 +26322,7 @@ function layoutC4Components(parsed, systemName, containerName, activeTagGroup) {
|
|
|
26305
26322
|
}
|
|
26306
26323
|
}
|
|
26307
26324
|
const hasGroups = elementToGroup.size > 0;
|
|
26308
|
-
const g = hasGroups ? new
|
|
26325
|
+
const g = hasGroups ? new import_dagre4.default.graphlib.Graph({ compound: true }) : new import_dagre4.default.graphlib.Graph();
|
|
26309
26326
|
g.setDefaultEdgeLabel(() => ({}));
|
|
26310
26327
|
if (hasGroups) {
|
|
26311
26328
|
const seenGroups = /* @__PURE__ */ new Set();
|
|
@@ -26389,7 +26406,7 @@ function layoutC4Components(parsed, systemName, containerName, activeTagGroup) {
|
|
|
26389
26406
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
26390
26407
|
}
|
|
26391
26408
|
}
|
|
26392
|
-
|
|
26409
|
+
import_dagre4.default.layout(g);
|
|
26393
26410
|
const nodeGroupMap = hasGroups ? new Map([...elementToGroup.entries()].map(([k, v]) => [k, v.name])) : void 0;
|
|
26394
26411
|
reduceCrossings(
|
|
26395
26412
|
g,
|
|
@@ -26678,7 +26695,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
26678
26695
|
for (const r of refEntries) {
|
|
26679
26696
|
nameToElement.set(r.element.name, r.element);
|
|
26680
26697
|
}
|
|
26681
|
-
const g = new
|
|
26698
|
+
const g = new import_dagre4.default.graphlib.Graph({ compound: true });
|
|
26682
26699
|
g.setDefaultEdgeLabel(() => ({}));
|
|
26683
26700
|
for (const [infraId] of infraIds) {
|
|
26684
26701
|
g.setNode(infraId, {});
|
|
@@ -26722,7 +26739,7 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
26722
26739
|
g.setEdge(rel.sourceName, rel.targetName, { label: rel.label ?? "" });
|
|
26723
26740
|
}
|
|
26724
26741
|
}
|
|
26725
|
-
|
|
26742
|
+
import_dagre4.default.layout(g);
|
|
26726
26743
|
const nodeInfraMap = /* @__PURE__ */ new Map();
|
|
26727
26744
|
for (const r of refEntries) nodeInfraMap.set(r.element.name, r.infraId);
|
|
26728
26745
|
reduceCrossings(
|
|
@@ -26900,11 +26917,11 @@ function layoutC4Deployment(parsed, activeTagGroup) {
|
|
|
26900
26917
|
height: totalHeight
|
|
26901
26918
|
};
|
|
26902
26919
|
}
|
|
26903
|
-
var
|
|
26920
|
+
var import_dagre4, gNode, gEdge, CHAR_WIDTH6, MIN_NODE_WIDTH, MAX_NODE_WIDTH, TYPE_LABEL_HEIGHT, DIVIDER_GAP, NAME_HEIGHT, DESC_LINE_HEIGHT5, DESC_CHAR_WIDTH, CARD_V_PAD3, CARD_H_PAD3, META_LINE_HEIGHT5, META_CHAR_WIDTH, MARGIN5, BOUNDARY_PAD, GROUP_BOUNDARY_PAD, LEGEND_HEIGHT4, LEGEND_PILL_PAD4, LEGEND_DOT_R4, LEGEND_ENTRY_DOT_GAP4, LEGEND_ENTRY_TRAIL4, LEGEND_CAPSULE_PAD4, EDGE_NODE_COLLISION_WEIGHT, META_EXCLUDE_KEYS;
|
|
26904
26921
|
var init_layout8 = __esm({
|
|
26905
26922
|
"src/c4/layout.ts"() {
|
|
26906
26923
|
"use strict";
|
|
26907
|
-
|
|
26924
|
+
import_dagre4 = __toESM(require("@dagrejs/dagre"), 1);
|
|
26908
26925
|
init_legend_constants();
|
|
26909
26926
|
gNode = (g, name) => g.node(name);
|
|
26910
26927
|
gEdge = (g, v, w) => g.edge(v, w);
|
|
@@ -27987,7 +28004,7 @@ function layoutGraph(graph, options) {
|
|
|
27987
28004
|
if (allNodes.length === 0) {
|
|
27988
28005
|
return { nodes: [], edges: [], groups: [], width: 0, height: 0 };
|
|
27989
28006
|
}
|
|
27990
|
-
const g = new
|
|
28007
|
+
const g = new import_dagre5.default.graphlib.Graph({ compound: true });
|
|
27991
28008
|
g.setGraph({
|
|
27992
28009
|
rankdir: graph.direction,
|
|
27993
28010
|
nodesep: 50,
|
|
@@ -28023,7 +28040,7 @@ function layoutGraph(graph, options) {
|
|
|
28023
28040
|
label: edge.label ?? ""
|
|
28024
28041
|
});
|
|
28025
28042
|
}
|
|
28026
|
-
|
|
28043
|
+
import_dagre5.default.layout(g);
|
|
28027
28044
|
const collapsedGroupIds = collapsedChildCounts ? new Set(collapsedChildCounts.keys()) : /* @__PURE__ */ new Set();
|
|
28028
28045
|
const layoutNodes = allNodes.map((node) => {
|
|
28029
28046
|
const pos = g.node(node.id);
|
|
@@ -28140,11 +28157,11 @@ function layoutGraph(graph, options) {
|
|
|
28140
28157
|
height: totalHeight
|
|
28141
28158
|
};
|
|
28142
28159
|
}
|
|
28143
|
-
var
|
|
28160
|
+
var import_dagre5, GROUP_PADDING;
|
|
28144
28161
|
var init_layout9 = __esm({
|
|
28145
28162
|
"src/graph/layout.ts"() {
|
|
28146
28163
|
"use strict";
|
|
28147
|
-
|
|
28164
|
+
import_dagre5 = __toESM(require("@dagrejs/dagre"), 1);
|
|
28148
28165
|
GROUP_PADDING = 20;
|
|
28149
28166
|
}
|
|
28150
28167
|
});
|
|
@@ -28456,7 +28473,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
|
|
|
28456
28473
|
endTerminalIds.add(node.id);
|
|
28457
28474
|
}
|
|
28458
28475
|
}
|
|
28459
|
-
const colorOff = graph.options?.color === "off";
|
|
28476
|
+
const colorOff = graph.options?.["color"] === "off";
|
|
28460
28477
|
const solid = graph.options?.["solid-fill"] === "on";
|
|
28461
28478
|
for (const node of layout.nodes) {
|
|
28462
28479
|
const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", "fc-node").attr("data-line-number", String(node.lineNumber)).attr("data-node-id", node.id);
|
|
@@ -29689,7 +29706,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
29689
29706
|
};
|
|
29690
29707
|
}
|
|
29691
29708
|
const isLR = computed.direction !== "TB";
|
|
29692
|
-
const g = new
|
|
29709
|
+
const g = new import_dagre6.default.graphlib.Graph();
|
|
29693
29710
|
g.setGraph({
|
|
29694
29711
|
rankdir: computed.direction === "TB" ? "TB" : "LR",
|
|
29695
29712
|
nodesep: isLR ? 70 : 60,
|
|
@@ -29740,7 +29757,7 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
29740
29757
|
g.setEdge(edge.sourceId, edge.targetId, { label: edge.label });
|
|
29741
29758
|
}
|
|
29742
29759
|
}
|
|
29743
|
-
|
|
29760
|
+
import_dagre6.default.layout(g);
|
|
29744
29761
|
const layoutNodes = computed.nodes.map((node) => {
|
|
29745
29762
|
const pos = g.node(node.id);
|
|
29746
29763
|
return {
|
|
@@ -29902,11 +29919,11 @@ function layoutInfra(computed, expandedNodeIds, collapsedNodes) {
|
|
|
29902
29919
|
height: totalHeight
|
|
29903
29920
|
};
|
|
29904
29921
|
}
|
|
29905
|
-
var
|
|
29922
|
+
var import_dagre6, MIN_NODE_WIDTH2, NODE_HEADER_HEIGHT, META_LINE_HEIGHT7, NODE_SEPARATOR_GAP, NODE_PAD_BOTTOM, ROLE_DOT_ROW, COLLAPSE_BAR_HEIGHT5, CHAR_WIDTH7, META_CHAR_WIDTH3, PADDING_X3, GROUP_PADDING2, GROUP_HEADER_HEIGHT, EDGE_MARGIN, DISPLAY_KEYS, DISPLAY_NAMES, GROUP_GAP;
|
|
29906
29923
|
var init_layout10 = __esm({
|
|
29907
29924
|
"src/infra/layout.ts"() {
|
|
29908
29925
|
"use strict";
|
|
29909
|
-
|
|
29926
|
+
import_dagre6 = __toESM(require("@dagrejs/dagre"), 1);
|
|
29910
29927
|
MIN_NODE_WIDTH2 = 140;
|
|
29911
29928
|
NODE_HEADER_HEIGHT = 28;
|
|
29912
29929
|
META_LINE_HEIGHT7 = 14;
|
|
@@ -30648,7 +30665,7 @@ function renderGroups(svg, groups, palette, _isDark) {
|
|
|
30648
30665
|
}
|
|
30649
30666
|
}
|
|
30650
30667
|
}
|
|
30651
|
-
function renderEdgePaths(svg, edges, nodes, groups, palette,
|
|
30668
|
+
function renderEdgePaths(svg, edges, nodes, groups, palette, _isDark, animate, direction, speedMultiplier = 1) {
|
|
30652
30669
|
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
30653
30670
|
const maxRps = Math.max(...edges.map((e) => e.computedRps), 1);
|
|
30654
30671
|
const { srcPts, tgtPts } = computePortPts(edges, nodeMap, direction);
|
|
@@ -30689,7 +30706,7 @@ function renderEdgePaths(svg, edges, nodes, groups, palette, isDark, animate, di
|
|
|
30689
30706
|
}
|
|
30690
30707
|
}
|
|
30691
30708
|
}
|
|
30692
|
-
function renderEdgeLabels(svg, edges, nodes, groups, palette,
|
|
30709
|
+
function renderEdgeLabels(svg, edges, nodes, groups, palette, _isDark, animate, direction) {
|
|
30693
30710
|
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
30694
30711
|
const { srcPts, tgtPts } = computePortPts(edges, nodeMap, direction);
|
|
30695
30712
|
for (const edge of edges) {
|
|
@@ -31430,7 +31447,7 @@ function sampleBetaPert(o, m, p, rng) {
|
|
|
31430
31447
|
const beta = 1 + 4 * (p - m) / range;
|
|
31431
31448
|
return o + sampleBeta(alpha, beta, rng) * range;
|
|
31432
31449
|
}
|
|
31433
|
-
function simulate(resolved, expanded,
|
|
31450
|
+
function simulate(resolved, expanded, _predecessors, _successors, topo, terminals, poisoned, opts) {
|
|
31434
31451
|
const rng = mulberry32(opts.seed);
|
|
31435
31452
|
const expById = /* @__PURE__ */ new Map();
|
|
31436
31453
|
for (const e of expanded) expById.set(e.id, e);
|
|
@@ -32550,7 +32567,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32550
32567
|
}
|
|
32551
32568
|
}
|
|
32552
32569
|
const dagreId = (id) => memberToGroup.get(id) ?? id;
|
|
32553
|
-
const g = new
|
|
32570
|
+
const g = new import_dagre7.default.graphlib.Graph();
|
|
32554
32571
|
g.setGraph({
|
|
32555
32572
|
rankdir: resolved.options.direction,
|
|
32556
32573
|
nodesep: 50,
|
|
@@ -32589,7 +32606,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32589
32606
|
seenEdges.add(k);
|
|
32590
32607
|
g.setEdge(src, tgt, {});
|
|
32591
32608
|
}
|
|
32592
|
-
|
|
32609
|
+
import_dagre7.default.layout(g);
|
|
32593
32610
|
const swimApplied = applySwimLanes(
|
|
32594
32611
|
g,
|
|
32595
32612
|
resolved,
|
|
@@ -32709,7 +32726,7 @@ function relayoutPert(resolved, overrides, collapsedGroupIds = /* @__PURE__ */ n
|
|
|
32709
32726
|
height: totalH + DIAGRAM_PADDING10
|
|
32710
32727
|
};
|
|
32711
32728
|
}
|
|
32712
|
-
function applySwimLanes(g, resolved,
|
|
32729
|
+
function applySwimLanes(g, resolved, _memberToGroup, collapsedGroupIds) {
|
|
32713
32730
|
const expanded = resolved.groups.filter(
|
|
32714
32731
|
(rg) => !collapsedGroupIds.has(rg.group.id)
|
|
32715
32732
|
);
|
|
@@ -32935,7 +32952,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32935
32952
|
buckets.get(key).push(id);
|
|
32936
32953
|
}
|
|
32937
32954
|
const edges = g.edges().map((e) => ({ v: e.v, w: e.w }));
|
|
32938
|
-
const
|
|
32955
|
+
const countCrossings2 = () => {
|
|
32939
32956
|
let total = 0;
|
|
32940
32957
|
for (let i = 0; i < edges.length; i++) {
|
|
32941
32958
|
const a = edges[i];
|
|
@@ -32948,13 +32965,13 @@ function reduceCrossings2(g, direction) {
|
|
|
32948
32965
|
const b1 = g.node(b.v);
|
|
32949
32966
|
const b2 = g.node(b.w);
|
|
32950
32967
|
if (!b1 || !b2) continue;
|
|
32951
|
-
if (
|
|
32968
|
+
if (segmentsCross2(a1, a2, b1, b2)) total++;
|
|
32952
32969
|
}
|
|
32953
32970
|
}
|
|
32954
32971
|
return total;
|
|
32955
32972
|
};
|
|
32956
32973
|
const MAX_ITER = 8;
|
|
32957
|
-
let baseline =
|
|
32974
|
+
let baseline = countCrossings2();
|
|
32958
32975
|
if (baseline === 0) return;
|
|
32959
32976
|
for (let iter = 0; iter < MAX_ITER; iter++) {
|
|
32960
32977
|
let improved = false;
|
|
@@ -32972,7 +32989,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32972
32989
|
const bv = bn[slotAxis];
|
|
32973
32990
|
an[slotAxis] = bv;
|
|
32974
32991
|
bn[slotAxis] = av;
|
|
32975
|
-
const after =
|
|
32992
|
+
const after = countCrossings2();
|
|
32976
32993
|
if (after < baseline) {
|
|
32977
32994
|
baseline = after;
|
|
32978
32995
|
improved = true;
|
|
@@ -32993,7 +33010,7 @@ function reduceCrossings2(g, direction) {
|
|
|
32993
33010
|
data.points = smoothEdge(src, tgt, direction);
|
|
32994
33011
|
}
|
|
32995
33012
|
}
|
|
32996
|
-
function
|
|
33013
|
+
function segmentsCross2(a1, a2, b1, b2) {
|
|
32997
33014
|
const ccw = (p, q, r) => (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
|
|
32998
33015
|
const d1 = ccw(b1, b2, a1);
|
|
32999
33016
|
const d2 = ccw(b1, b2, a2);
|
|
@@ -33001,11 +33018,11 @@ function segmentsCross(a1, a2, b1, b2) {
|
|
|
33001
33018
|
const d4 = ccw(a1, a2, b2);
|
|
33002
33019
|
return (d1 > 0 && d2 < 0 || d1 < 0 && d2 > 0) && (d32 > 0 && d4 < 0 || d32 < 0 && d4 > 0);
|
|
33003
33020
|
}
|
|
33004
|
-
var
|
|
33021
|
+
var import_dagre7, DEFAULT_NODE_HEIGHT, MILESTONE_NODE_HEIGHT, COLLAPSED_GROUP_HEIGHT, DIAGRAM_PADDING10, GROUP_PADDING3, GROUP_TOP_PADDING, SWIMLANE_SLOT_SEP, SWIMLANE_GAP, NODE_CELL_FONT_SIZE, NODE_NAME_FONT_SIZE, CELL_CHAR_WIDTH_RATIO, CELL_PAD_X, NAME_PAD_X, NAME_PIN_WIDTH, MIN_CELL_WIDTH, MIN_NODE_WIDTH3, MAX_NODE_WIDTH2, MIN_MILESTONE_WIDTH, MAX_MILESTONE_WIDTH;
|
|
33005
33022
|
var init_layout11 = __esm({
|
|
33006
33023
|
"src/pert/layout.ts"() {
|
|
33007
33024
|
"use strict";
|
|
33008
|
-
|
|
33025
|
+
import_dagre7 = __toESM(require("@dagrejs/dagre"), 1);
|
|
33009
33026
|
init_internal();
|
|
33010
33027
|
DEFAULT_NODE_HEIGHT = 90;
|
|
33011
33028
|
MILESTONE_NODE_HEIGHT = DEFAULT_NODE_HEIGHT;
|
|
@@ -35002,12 +35019,6 @@ function calculateSchedule(parsed) {
|
|
|
35002
35019
|
const warn = (line12, message) => {
|
|
35003
35020
|
diagnostics.push(makeDgmoError(line12, message, "warning"));
|
|
35004
35021
|
};
|
|
35005
|
-
const _fail = (line12, message) => {
|
|
35006
|
-
const diag = makeDgmoError(line12, message);
|
|
35007
|
-
diagnostics.push(diag);
|
|
35008
|
-
result.error = formatDgmoError(diag);
|
|
35009
|
-
return result;
|
|
35010
|
-
};
|
|
35011
35022
|
const holidaySet = buildHolidaySet(parsed.holidays);
|
|
35012
35023
|
let projectStart;
|
|
35013
35024
|
if (parsed.options.start) {
|
|
@@ -35032,7 +35043,6 @@ function calculateSchedule(parsed) {
|
|
|
35032
35043
|
}
|
|
35033
35044
|
buildImplicitDeps(parsed.nodes, taskMap);
|
|
35034
35045
|
for (const task of allTasks2) {
|
|
35035
|
-
const _node = taskMap.get(task.id);
|
|
35036
35046
|
for (const dep of task.dependencies) {
|
|
35037
35047
|
const resolved = resolveTaskName(dep.targetName, allTasks2);
|
|
35038
35048
|
if (isResolverError(resolved)) {
|
|
@@ -36571,7 +36581,7 @@ function buildControlsToggles(hasCriticalPath, criticalPathActive, hasDependenci
|
|
|
36571
36581
|
}
|
|
36572
36582
|
return toggles;
|
|
36573
36583
|
}
|
|
36574
|
-
function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive,
|
|
36584
|
+
function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargin, chartInnerWidth, legendY, palette, isDark, hasCriticalPath, criticalPathActive, _optionLineNumbers, onToggle, onToggleControlsExpand, currentSwimlaneGroup, onSwimlaneChange, legendViewMode, resolvedTasks, controlsExpanded = false, hasDependencies = false, dependenciesActive = false, onControlsToggle) {
|
|
36575
36585
|
let visibleGroups;
|
|
36576
36586
|
if (activeGroupName) {
|
|
36577
36587
|
const activeGroup = tagGroups.filter(
|
|
@@ -37534,7 +37544,7 @@ function resolveTaskColor(rt, activeTagGroup, resolved, seriesColors2, palette)
|
|
|
37534
37544
|
}
|
|
37535
37545
|
return palette.accent || seriesColors2[0] || "#4a90d9";
|
|
37536
37546
|
}
|
|
37537
|
-
function renderTimeScaleHorizontal(g, scale,
|
|
37547
|
+
function renderTimeScaleHorizontal(g, scale, _innerWidth, innerHeight, textColor) {
|
|
37538
37548
|
const [domainMin, domainMax] = scale.domain();
|
|
37539
37549
|
const ticks = computeTimeTicks(domainMin, domainMax, scale);
|
|
37540
37550
|
if (ticks.length < 2) return;
|
|
@@ -37781,7 +37791,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
|
|
|
37781
37791
|
for (const group of layout.groups) {
|
|
37782
37792
|
if (group.collapsed) collapsedGroupIds.add(group.id);
|
|
37783
37793
|
}
|
|
37784
|
-
const colorOff = graph.options?.color === "off";
|
|
37794
|
+
const colorOff = graph.options?.["color"] === "off";
|
|
37785
37795
|
const solid = graph.options?.["solid-fill"] === "on";
|
|
37786
37796
|
for (const node of layout.nodes) {
|
|
37787
37797
|
const isCollapsedGroup = collapsedGroupIds.has(node.id);
|
|
@@ -38181,7 +38191,7 @@ function renderQuadrantFocus(container, parsed, quadrantPosition, palette, isDar
|
|
|
38181
38191
|
}
|
|
38182
38192
|
}
|
|
38183
38193
|
}
|
|
38184
|
-
function renderQuarterCircle(svg, parsed, quadrant, qColor, palette, isDark, width, height, mutedColor,
|
|
38194
|
+
function renderQuarterCircle(svg, parsed, quadrant, qColor, palette, isDark, width, height, mutedColor, _tooltip, rootContainer, onClickItem) {
|
|
38185
38195
|
const padding = 8;
|
|
38186
38196
|
const size = Math.min(width - padding, height - padding);
|
|
38187
38197
|
const maxRadius = size * 0.95;
|
|
@@ -39051,7 +39061,7 @@ function estimateListingHeight(parsed) {
|
|
|
39051
39061
|
);
|
|
39052
39062
|
return LISTING_LINE_HEIGHT * (maxBlipsInQuadrant + 1) + LISTING_LINE_HEIGHT + LISTING_TOP_MARGIN;
|
|
39053
39063
|
}
|
|
39054
|
-
function createBlipPopover(container,
|
|
39064
|
+
function createBlipPopover(container, _palette, isDark) {
|
|
39055
39065
|
container.style.position = "relative";
|
|
39056
39066
|
const existing = container.querySelector(
|
|
39057
39067
|
"[data-blip-popover]"
|
|
@@ -40919,7 +40929,7 @@ function computeEdgeLabelPosition(midAngle, radius, cx, cy, lineCount, maxCharLe
|
|
|
40919
40929
|
labelAngle: best.labelAngle
|
|
40920
40930
|
};
|
|
40921
40931
|
}
|
|
40922
|
-
function fitToCanvas(nodes, edges, parsed,
|
|
40932
|
+
function fitToCanvas(nodes, edges, parsed, _cx, _cy, radius, width, height, _isClockwise) {
|
|
40923
40933
|
const PADDING3 = 30;
|
|
40924
40934
|
let contentMinX = Infinity, contentMaxX = -Infinity;
|
|
40925
40935
|
let contentMinY = Infinity, contentMaxY = -Infinity;
|
|
@@ -42428,7 +42438,7 @@ function renderPhaseBar(svg, phase, x, y, width, palette, collapsed, autoColor,
|
|
|
42428
42438
|
});
|
|
42429
42439
|
}
|
|
42430
42440
|
}
|
|
42431
|
-
function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette, surfaceBg, solid, taskDiagnostics,
|
|
42441
|
+
function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette, surfaceBg, solid, taskDiagnostics, _hasAnyDiagnostic, rowContent, onClickLine, _onMarkerDragStart) {
|
|
42432
42442
|
const rowG = svg.append("g").attr("class", "raci-task-row").attr("data-task-id", task.id).attr("data-line-number", String(task.lineNumber));
|
|
42433
42443
|
const labelX = x + 8;
|
|
42434
42444
|
const labelMaxW = labelW - 16;
|
|
@@ -43234,7 +43244,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
43234
43244
|
const messages = collapsed ? collapsed.messages : parsed.messages;
|
|
43235
43245
|
const elements = collapsed ? collapsed.elements : parsed.elements;
|
|
43236
43246
|
const groups = collapsed ? collapsed.groups : parsed.groups;
|
|
43237
|
-
const collapsedGroupIds = collapsed?.collapsedGroupIds ?? /* @__PURE__ */ new Map();
|
|
43238
43247
|
const collapsedSections = options?.collapsedSections;
|
|
43239
43248
|
const sourceParticipants = collapsed ? collapsed.participants : parsed.participants;
|
|
43240
43249
|
const participants = applyPositionOverrides(
|
|
@@ -43262,7 +43271,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
43262
43271
|
return Math.min(NOTE_MAX_W, laneMax);
|
|
43263
43272
|
};
|
|
43264
43273
|
const charsForWidth = (maxW) => Math.floor((maxW - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W);
|
|
43265
|
-
const activationsOff = parsedOptions
|
|
43274
|
+
const activationsOff = parsedOptions["activations"]?.toLowerCase() === "off";
|
|
43266
43275
|
const activeTagGroup = resolveActiveTagGroup(
|
|
43267
43276
|
parsed.tagGroups,
|
|
43268
43277
|
parsedOptions["active-tag"],
|
|
@@ -46214,7 +46223,7 @@ function renderTimelineGroupLegend(g, groups, groupColorMap, textColor, palette,
|
|
|
46214
46223
|
legendX += pillW + GAP;
|
|
46215
46224
|
}
|
|
46216
46225
|
}
|
|
46217
|
-
function
|
|
46226
|
+
function setupTimeline(container, parsed, palette, isDark, exportDims, activeTagGroup, swimlaneTagGroup) {
|
|
46218
46227
|
d3Selection22.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
46219
46228
|
const solid = parsed.solidFill === true;
|
|
46220
46229
|
const {
|
|
@@ -46223,19 +46232,17 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46223
46232
|
timelineEras,
|
|
46224
46233
|
timelineMarkers,
|
|
46225
46234
|
timelineSort,
|
|
46226
|
-
timelineScale,
|
|
46227
|
-
timelineSwimlanes,
|
|
46228
46235
|
orientation
|
|
46229
46236
|
} = parsed;
|
|
46230
|
-
|
|
46231
|
-
|
|
46232
|
-
if (
|
|
46233
|
-
|
|
46237
|
+
if (timelineEvents.length === 0) return null;
|
|
46238
|
+
let resolvedSwimlaneTG = swimlaneTagGroup ?? null;
|
|
46239
|
+
if (resolvedSwimlaneTG == null && timelineSort === "tag" && parsed.timelineDefaultSwimlaneTG) {
|
|
46240
|
+
resolvedSwimlaneTG = parsed.timelineDefaultSwimlaneTG;
|
|
46234
46241
|
}
|
|
46235
46242
|
const tooltip = createTooltip2(container, palette, isDark);
|
|
46236
46243
|
const width = exportDims?.width ?? container.clientWidth;
|
|
46237
46244
|
const height = exportDims?.height ?? container.clientHeight;
|
|
46238
|
-
if (width <= 0 || height <= 0) return;
|
|
46245
|
+
if (width <= 0 || height <= 0) return null;
|
|
46239
46246
|
const isVertical = orientation === "vertical";
|
|
46240
46247
|
const textColor = palette.text;
|
|
46241
46248
|
const mutedColor = palette.border;
|
|
@@ -46247,8 +46254,8 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46247
46254
|
groupColorMap.set(grp.name, grp.color ?? colors[i % colors.length]);
|
|
46248
46255
|
});
|
|
46249
46256
|
let tagLanes = null;
|
|
46250
|
-
if (
|
|
46251
|
-
const tagKey =
|
|
46257
|
+
if (resolvedSwimlaneTG) {
|
|
46258
|
+
const tagKey = resolvedSwimlaneTG.toLowerCase();
|
|
46252
46259
|
const tagGroup = parsed.timelineTagGroups.find(
|
|
46253
46260
|
(g) => g.name.toLowerCase() === tagKey
|
|
46254
46261
|
);
|
|
@@ -46279,7 +46286,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46279
46286
|
}
|
|
46280
46287
|
}
|
|
46281
46288
|
}
|
|
46282
|
-
const effectiveColorTG = activeTagGroup ??
|
|
46289
|
+
const effectiveColorTG = activeTagGroup ?? resolvedSwimlaneTG ?? null;
|
|
46283
46290
|
function eventColor(ev) {
|
|
46284
46291
|
if (effectiveColorTG) {
|
|
46285
46292
|
const tagColor = resolveTagColor(
|
|
@@ -46335,6 +46342,30 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46335
46342
|
}
|
|
46336
46343
|
}
|
|
46337
46344
|
const datePadding = (maxDate - minDate) * 0.05 || 0.5;
|
|
46345
|
+
const tagLegendReserve = parsed.timelineTagGroups.length > 0 ? 36 : 0;
|
|
46346
|
+
return {
|
|
46347
|
+
width,
|
|
46348
|
+
height,
|
|
46349
|
+
isVertical,
|
|
46350
|
+
tooltip,
|
|
46351
|
+
solid,
|
|
46352
|
+
textColor,
|
|
46353
|
+
mutedColor,
|
|
46354
|
+
bgColor,
|
|
46355
|
+
bg,
|
|
46356
|
+
swimlaneTagGroup: resolvedSwimlaneTG,
|
|
46357
|
+
groupColorMap,
|
|
46358
|
+
tagLanes,
|
|
46359
|
+
eventColor,
|
|
46360
|
+
minDate,
|
|
46361
|
+
maxDate,
|
|
46362
|
+
datePadding,
|
|
46363
|
+
earliestStartDateStr,
|
|
46364
|
+
latestEndDateStr,
|
|
46365
|
+
tagLegendReserve
|
|
46366
|
+
};
|
|
46367
|
+
}
|
|
46368
|
+
function makeTimelineHoverHelpers() {
|
|
46338
46369
|
const FADE_OPACITY3 = 0.1;
|
|
46339
46370
|
function fadeToGroup(g, groupName) {
|
|
46340
46371
|
g.selectAll(".tl-event").each(function() {
|
|
@@ -46434,337 +46465,683 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46434
46465
|
evG.attr(`data-tag-${key}`, value.toLowerCase());
|
|
46435
46466
|
}
|
|
46436
46467
|
}
|
|
46437
|
-
|
|
46438
|
-
|
|
46439
|
-
|
|
46440
|
-
|
|
46441
|
-
|
|
46442
|
-
|
|
46443
|
-
|
|
46444
|
-
|
|
46445
|
-
|
|
46446
|
-
|
|
46447
|
-
|
|
46448
|
-
|
|
46449
|
-
|
|
46450
|
-
|
|
46451
|
-
|
|
46452
|
-
|
|
46453
|
-
|
|
46454
|
-
|
|
46455
|
-
|
|
46456
|
-
|
|
46457
|
-
|
|
46458
|
-
|
|
46459
|
-
|
|
46468
|
+
return {
|
|
46469
|
+
FADE_OPACITY: FADE_OPACITY3,
|
|
46470
|
+
fadeToGroup,
|
|
46471
|
+
fadeToEra,
|
|
46472
|
+
fadeToMarker,
|
|
46473
|
+
fadeReset,
|
|
46474
|
+
fadeToTagValue,
|
|
46475
|
+
setTagAttrs
|
|
46476
|
+
};
|
|
46477
|
+
}
|
|
46478
|
+
function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, swimlaneTagGroup, activeTagGroup, onTagStateChange, viewMode) {
|
|
46479
|
+
if (parsed.timelineTagGroups.length === 0) return;
|
|
46480
|
+
const { width, textColor, groupColorMap, solid } = setup;
|
|
46481
|
+
const { FADE_OPACITY: FADE_OPACITY3, fadeReset, fadeToTagValue } = hovers;
|
|
46482
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46483
|
+
const { timelineEvents } = parsed;
|
|
46484
|
+
const LG_HEIGHT = LEGEND_HEIGHT;
|
|
46485
|
+
const LG_PILL_PAD = LEGEND_PILL_PAD;
|
|
46486
|
+
const LG_PILL_FONT_SIZE = LEGEND_PILL_FONT_SIZE;
|
|
46487
|
+
const LG_CAPSULE_PAD = LEGEND_CAPSULE_PAD;
|
|
46488
|
+
const LG_DOT_R = LEGEND_DOT_R;
|
|
46489
|
+
const LG_ENTRY_FONT_SIZE = LEGEND_ENTRY_FONT_SIZE;
|
|
46490
|
+
const LG_ENTRY_DOT_GAP = LEGEND_ENTRY_DOT_GAP;
|
|
46491
|
+
const LG_ENTRY_TRAIL = LEGEND_ENTRY_TRAIL;
|
|
46492
|
+
const LG_ICON_W = 20;
|
|
46493
|
+
const mainSvg = d3Selection22.select(container).select("svg");
|
|
46494
|
+
const mainG = mainSvg.select("g");
|
|
46495
|
+
if (!mainSvg.empty() && !mainG.empty()) {
|
|
46496
|
+
let drawSwimlaneIcon4 = function(parent, x, y, isSwimActive) {
|
|
46497
|
+
const iconG = parent.append("g").attr("class", "tl-swimlane-icon").attr("transform", `translate(${x}, ${y})`).style("cursor", "pointer");
|
|
46498
|
+
const barColor = isSwimActive ? palette.primary : palette.textMuted;
|
|
46499
|
+
const barOpacity = isSwimActive ? 1 : 0.35;
|
|
46500
|
+
const bars = [
|
|
46501
|
+
{ y: 0, w: 8 },
|
|
46502
|
+
{ y: 4, w: 12 },
|
|
46503
|
+
{ y: 8, w: 6 }
|
|
46504
|
+
];
|
|
46505
|
+
for (const bar of bars) {
|
|
46506
|
+
iconG.append("rect").attr("x", 0).attr("y", bar.y).attr("width", bar.w).attr("height", 2).attr("rx", 1).attr("fill", barColor).attr("opacity", barOpacity);
|
|
46460
46507
|
}
|
|
46461
|
-
|
|
46462
|
-
|
|
46463
|
-
|
|
46464
|
-
|
|
46465
|
-
|
|
46466
|
-
|
|
46467
|
-
|
|
46468
|
-
|
|
46469
|
-
|
|
46470
|
-
|
|
46471
|
-
|
|
46472
|
-
|
|
46473
|
-
|
|
46474
|
-
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);
|
|
46475
|
-
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46476
|
-
renderChartTitle(
|
|
46477
|
-
svg,
|
|
46478
|
-
title,
|
|
46479
|
-
parsed.titleLineNumber,
|
|
46480
|
-
width,
|
|
46481
|
-
textColor,
|
|
46482
|
-
onClickItem
|
|
46483
|
-
);
|
|
46484
|
-
renderEras(
|
|
46485
|
-
g,
|
|
46486
|
-
timelineEras,
|
|
46487
|
-
yScale,
|
|
46488
|
-
true,
|
|
46489
|
-
innerWidth,
|
|
46490
|
-
innerHeight,
|
|
46491
|
-
(s, e) => fadeToEra(g, s, e),
|
|
46492
|
-
() => fadeReset(g),
|
|
46493
|
-
timelineScale,
|
|
46494
|
-
tooltip,
|
|
46495
|
-
palette
|
|
46496
|
-
);
|
|
46497
|
-
renderMarkers(
|
|
46498
|
-
g,
|
|
46499
|
-
timelineMarkers,
|
|
46500
|
-
yScale,
|
|
46501
|
-
true,
|
|
46502
|
-
innerWidth,
|
|
46503
|
-
innerHeight,
|
|
46504
|
-
(d) => fadeToMarker(g, d),
|
|
46505
|
-
() => fadeReset(g),
|
|
46506
|
-
timelineScale,
|
|
46507
|
-
tooltip,
|
|
46508
|
-
palette
|
|
46508
|
+
return iconG;
|
|
46509
|
+
}, relayout2 = function() {
|
|
46510
|
+
renderTimeline(
|
|
46511
|
+
container,
|
|
46512
|
+
parsed,
|
|
46513
|
+
palette,
|
|
46514
|
+
isDark,
|
|
46515
|
+
onClickItem,
|
|
46516
|
+
exportDims,
|
|
46517
|
+
currentActiveGroup,
|
|
46518
|
+
currentSwimlaneGroup,
|
|
46519
|
+
onTagStateChange,
|
|
46520
|
+
viewMode
|
|
46509
46521
|
);
|
|
46510
|
-
|
|
46511
|
-
|
|
46512
|
-
|
|
46513
|
-
|
|
46514
|
-
|
|
46515
|
-
|
|
46516
|
-
|
|
46517
|
-
|
|
46518
|
-
|
|
46519
|
-
|
|
46520
|
-
|
|
46521
|
-
|
|
46522
|
+
}, drawLegend2 = function() {
|
|
46523
|
+
mainSvg.selectAll(".tl-tag-legend-group").remove();
|
|
46524
|
+
mainSvg.selectAll(".tl-tag-legend-container").remove();
|
|
46525
|
+
const effectiveColorKey = (currentActiveGroup ?? currentSwimlaneGroup)?.toLowerCase() ?? null;
|
|
46526
|
+
const visibleGroups = viewMode ? legendGroups.filter(
|
|
46527
|
+
(lg) => effectiveColorKey != null && lg.group.name.toLowerCase() === effectiveColorKey
|
|
46528
|
+
) : legendGroups;
|
|
46529
|
+
if (visibleGroups.length === 0) return;
|
|
46530
|
+
const legendContainer = mainSvg.append("g").attr("class", "tl-tag-legend-container");
|
|
46531
|
+
if (currentActiveGroup) {
|
|
46532
|
+
legendContainer.attr(
|
|
46533
|
+
"data-legend-active",
|
|
46534
|
+
currentActiveGroup.toLowerCase()
|
|
46522
46535
|
);
|
|
46523
46536
|
}
|
|
46524
|
-
|
|
46525
|
-
|
|
46526
|
-
|
|
46527
|
-
|
|
46528
|
-
|
|
46529
|
-
|
|
46530
|
-
|
|
46531
|
-
|
|
46532
|
-
|
|
46533
|
-
|
|
46534
|
-
|
|
46535
|
-
|
|
46536
|
-
|
|
46537
|
-
|
|
46538
|
-
|
|
46539
|
-
|
|
46540
|
-
|
|
46541
|
-
|
|
46542
|
-
|
|
46543
|
-
|
|
46544
|
-
|
|
46545
|
-
|
|
46546
|
-
|
|
46547
|
-
|
|
46548
|
-
|
|
46549
|
-
|
|
46550
|
-
|
|
46551
|
-
|
|
46552
|
-
|
|
46553
|
-
|
|
46554
|
-
|
|
46555
|
-
|
|
46556
|
-
|
|
46557
|
-
|
|
46558
|
-
|
|
46559
|
-
|
|
46560
|
-
|
|
46561
|
-
let stroke2 = evColor;
|
|
46562
|
-
if (ev.uncertain) {
|
|
46563
|
-
const gradientId = `uncertain-vg-${ev.lineNumber}`;
|
|
46564
|
-
const strokeGradientId = `uncertain-vg-s-${ev.lineNumber}`;
|
|
46565
|
-
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46566
|
-
const defsEl = d3Selection22.select(defs);
|
|
46567
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46568
|
-
{ offset: "0%", opacity: 1 },
|
|
46569
|
-
{ offset: "80%", opacity: 1 },
|
|
46570
|
-
{ offset: "100%", opacity: 0 }
|
|
46571
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
46572
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46573
|
-
{ offset: "0%", opacity: 1 },
|
|
46574
|
-
{ offset: "80%", opacity: 1 },
|
|
46575
|
-
{ offset: "100%", opacity: 0 }
|
|
46576
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", evColor).attr("stop-opacity", (d) => d.opacity);
|
|
46577
|
-
fill2 = `url(#${gradientId})`;
|
|
46578
|
-
stroke2 = `url(#${strokeGradientId})`;
|
|
46579
|
-
}
|
|
46580
|
-
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);
|
|
46581
|
-
evG.append("text").attr("x", laneCenter + 14).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
|
|
46537
|
+
const iconAddon = viewMode ? 0 : LG_ICON_W;
|
|
46538
|
+
const centralGroups = visibleGroups.map((lg) => ({
|
|
46539
|
+
name: lg.group.name,
|
|
46540
|
+
entries: lg.group.entries.map((e) => ({
|
|
46541
|
+
value: e.value,
|
|
46542
|
+
color: e.color
|
|
46543
|
+
}))
|
|
46544
|
+
}));
|
|
46545
|
+
const centralActive = viewMode ? effectiveColorKey : currentActiveGroup;
|
|
46546
|
+
const centralConfig = {
|
|
46547
|
+
groups: centralGroups,
|
|
46548
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
46549
|
+
mode: "fixed",
|
|
46550
|
+
capsulePillAddonWidth: iconAddon
|
|
46551
|
+
};
|
|
46552
|
+
const centralState = { activeGroup: centralActive };
|
|
46553
|
+
const centralCallbacks = viewMode ? {} : {
|
|
46554
|
+
onGroupToggle: (groupName) => {
|
|
46555
|
+
currentActiveGroup = currentActiveGroup === groupName.toLowerCase() ? null : groupName.toLowerCase();
|
|
46556
|
+
drawLegend2();
|
|
46557
|
+
recolorEvents2();
|
|
46558
|
+
onTagStateChange?.(currentActiveGroup, currentSwimlaneGroup);
|
|
46559
|
+
},
|
|
46560
|
+
onEntryHover: (groupName, entryValue) => {
|
|
46561
|
+
const tagKey = groupName.toLowerCase();
|
|
46562
|
+
if (entryValue) {
|
|
46563
|
+
const tagVal = entryValue.toLowerCase();
|
|
46564
|
+
fadeToTagValue(mainG, tagKey, tagVal);
|
|
46565
|
+
mainSvg.selectAll("[data-legend-entry]").each(function() {
|
|
46566
|
+
const el = d3Selection22.select(this);
|
|
46567
|
+
const ev = el.attr("data-legend-entry");
|
|
46568
|
+
const eg = el.attr("data-tag-group") ?? el.node()?.closest?.("[data-tag-group]")?.getAttribute("data-tag-group");
|
|
46569
|
+
el.attr(
|
|
46570
|
+
"opacity",
|
|
46571
|
+
eg === tagKey && ev === tagVal ? 1 : FADE_OPACITY3
|
|
46572
|
+
);
|
|
46573
|
+
});
|
|
46582
46574
|
} else {
|
|
46583
|
-
|
|
46584
|
-
|
|
46575
|
+
fadeReset(mainG);
|
|
46576
|
+
mainSvg.selectAll("[data-legend-entry]").attr("opacity", 1);
|
|
46577
|
+
}
|
|
46578
|
+
},
|
|
46579
|
+
onGroupRendered: (groupName, groupEl, isActive) => {
|
|
46580
|
+
const groupKey = groupName.toLowerCase();
|
|
46581
|
+
groupEl.attr("data-tag-group", groupKey);
|
|
46582
|
+
if (isActive && !viewMode) {
|
|
46583
|
+
const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
|
|
46584
|
+
const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
46585
|
+
const pillXOff = LG_CAPSULE_PAD;
|
|
46586
|
+
const iconX = pillXOff + pillWidth3 + 5;
|
|
46587
|
+
const iconY = (LG_HEIGHT - 10) / 2;
|
|
46588
|
+
const iconEl = drawSwimlaneIcon4(
|
|
46589
|
+
groupEl,
|
|
46590
|
+
iconX,
|
|
46591
|
+
iconY,
|
|
46592
|
+
isSwimActive
|
|
46593
|
+
);
|
|
46594
|
+
iconEl.attr("data-swimlane-toggle", groupKey).on("click", (event) => {
|
|
46595
|
+
event.stopPropagation();
|
|
46596
|
+
currentSwimlaneGroup = currentSwimlaneGroup === groupKey ? null : groupKey;
|
|
46597
|
+
onTagStateChange?.(
|
|
46598
|
+
currentActiveGroup,
|
|
46599
|
+
currentSwimlaneGroup
|
|
46600
|
+
);
|
|
46601
|
+
relayout2();
|
|
46602
|
+
});
|
|
46585
46603
|
}
|
|
46586
46604
|
}
|
|
46587
|
-
});
|
|
46588
|
-
} else {
|
|
46589
|
-
const scaleMargin = timelineScale ? 40 : 0;
|
|
46590
|
-
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46591
|
-
const margin = {
|
|
46592
|
-
top: 104 + markerMargin + tagLegendReserve,
|
|
46593
|
-
right: 200,
|
|
46594
|
-
bottom: 40,
|
|
46595
|
-
left: 60 + scaleMargin
|
|
46596
46605
|
};
|
|
46597
|
-
const
|
|
46598
|
-
|
|
46599
|
-
|
|
46600
|
-
|
|
46601
|
-
|
|
46602
|
-
|
|
46603
|
-
|
|
46604
|
-
|
|
46605
|
-
|
|
46606
|
-
title,
|
|
46607
|
-
parsed.titleLineNumber,
|
|
46608
|
-
width,
|
|
46609
|
-
textColor,
|
|
46610
|
-
onClickItem
|
|
46611
|
-
);
|
|
46612
|
-
renderEras(
|
|
46613
|
-
g,
|
|
46614
|
-
timelineEras,
|
|
46615
|
-
yScale,
|
|
46616
|
-
true,
|
|
46617
|
-
innerWidth,
|
|
46618
|
-
innerHeight,
|
|
46619
|
-
(s, e) => fadeToEra(g, s, e),
|
|
46620
|
-
() => fadeReset(g),
|
|
46621
|
-
timelineScale,
|
|
46622
|
-
tooltip,
|
|
46623
|
-
palette
|
|
46624
|
-
);
|
|
46625
|
-
renderMarkers(
|
|
46626
|
-
g,
|
|
46627
|
-
timelineMarkers,
|
|
46628
|
-
yScale,
|
|
46629
|
-
true,
|
|
46630
|
-
innerWidth,
|
|
46631
|
-
innerHeight,
|
|
46632
|
-
(d) => fadeToMarker(g, d),
|
|
46633
|
-
() => fadeReset(g),
|
|
46634
|
-
timelineScale,
|
|
46635
|
-
tooltip,
|
|
46636
|
-
palette
|
|
46606
|
+
const legendInnerG = legendContainer.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
46607
|
+
renderLegendD3(
|
|
46608
|
+
legendInnerG,
|
|
46609
|
+
centralConfig,
|
|
46610
|
+
centralState,
|
|
46611
|
+
palette,
|
|
46612
|
+
isDark,
|
|
46613
|
+
centralCallbacks,
|
|
46614
|
+
width
|
|
46637
46615
|
);
|
|
46616
|
+
}, recolorEvents2 = function() {
|
|
46617
|
+
const colorTG = currentActiveGroup ?? swimlaneTagGroup ?? null;
|
|
46618
|
+
mainG.selectAll(".tl-event").each(function() {
|
|
46619
|
+
const el = d3Selection22.select(this);
|
|
46620
|
+
const lineNum = el.attr("data-line-number");
|
|
46621
|
+
const ev = lineNum ? eventByLine.get(lineNum) : void 0;
|
|
46622
|
+
if (!ev) return;
|
|
46623
|
+
let color;
|
|
46624
|
+
if (colorTG) {
|
|
46625
|
+
const tagColor = resolveTagColor(
|
|
46626
|
+
ev.metadata,
|
|
46627
|
+
parsed.timelineTagGroups,
|
|
46628
|
+
colorTG
|
|
46629
|
+
);
|
|
46630
|
+
color = tagColor ?? (ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor);
|
|
46631
|
+
} else {
|
|
46632
|
+
color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
|
|
46633
|
+
}
|
|
46634
|
+
el.selectAll("rect").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
46635
|
+
el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
46636
|
+
});
|
|
46637
|
+
};
|
|
46638
|
+
var drawSwimlaneIcon3 = drawSwimlaneIcon4, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
|
|
46639
|
+
const legendY = title ? 50 : 10;
|
|
46640
|
+
const legendGroups = parsed.timelineTagGroups.map((g) => {
|
|
46641
|
+
const pillW = measureLegendText(g.name, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
46642
|
+
const iconSpace = viewMode ? 8 : LG_ICON_W + 4;
|
|
46643
|
+
let entryX = LG_CAPSULE_PAD + pillW + iconSpace;
|
|
46644
|
+
for (const entry of g.entries) {
|
|
46645
|
+
const textX = entryX + LG_DOT_R * 2 + LG_ENTRY_DOT_GAP;
|
|
46646
|
+
entryX = textX + measureLegendText(entry.value, LG_ENTRY_FONT_SIZE) + LG_ENTRY_TRAIL;
|
|
46647
|
+
}
|
|
46648
|
+
return {
|
|
46649
|
+
group: g,
|
|
46650
|
+
minifiedWidth: pillW,
|
|
46651
|
+
expandedWidth: entryX + LG_CAPSULE_PAD
|
|
46652
|
+
};
|
|
46653
|
+
});
|
|
46654
|
+
let currentActiveGroup = activeTagGroup ?? null;
|
|
46655
|
+
let currentSwimlaneGroup = swimlaneTagGroup ?? null;
|
|
46656
|
+
const eventByLine = /* @__PURE__ */ new Map();
|
|
46657
|
+
for (const ev of timelineEvents) {
|
|
46658
|
+
eventByLine.set(String(ev.lineNumber), ev);
|
|
46659
|
+
}
|
|
46660
|
+
drawLegend2();
|
|
46661
|
+
}
|
|
46662
|
+
}
|
|
46663
|
+
function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
46664
|
+
const {
|
|
46665
|
+
width,
|
|
46666
|
+
height,
|
|
46667
|
+
tooltip,
|
|
46668
|
+
solid,
|
|
46669
|
+
textColor,
|
|
46670
|
+
bgColor,
|
|
46671
|
+
bg,
|
|
46672
|
+
groupColorMap,
|
|
46673
|
+
eventColor,
|
|
46674
|
+
minDate,
|
|
46675
|
+
maxDate,
|
|
46676
|
+
datePadding,
|
|
46677
|
+
earliestStartDateStr,
|
|
46678
|
+
latestEndDateStr,
|
|
46679
|
+
tagLegendReserve
|
|
46680
|
+
} = setup;
|
|
46681
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
46682
|
+
const {
|
|
46683
|
+
timelineEvents,
|
|
46684
|
+
timelineGroups,
|
|
46685
|
+
timelineEras,
|
|
46686
|
+
timelineMarkers,
|
|
46687
|
+
timelineScale
|
|
46688
|
+
} = parsed;
|
|
46689
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46690
|
+
const BAR_H2 = 22;
|
|
46691
|
+
const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
|
|
46692
|
+
const scaleMargin = timelineScale ? 24 : 0;
|
|
46693
|
+
const ERA_ROW_H = 22;
|
|
46694
|
+
const MARKER_ROW_H = 22;
|
|
46695
|
+
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46696
|
+
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46697
|
+
const topScaleH = timelineScale ? 40 : 0;
|
|
46698
|
+
const margin = {
|
|
46699
|
+
top: 104 + topScaleH + eraReserve + markerReserve + tagLegendReserve,
|
|
46700
|
+
right: 40,
|
|
46701
|
+
bottom: 40 + scaleMargin,
|
|
46702
|
+
left: 60
|
|
46703
|
+
};
|
|
46704
|
+
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46705
|
+
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46706
|
+
const innerWidth = width - margin.left - margin.right;
|
|
46707
|
+
const innerHeight = height - margin.top - margin.bottom;
|
|
46708
|
+
const rowH = Math.min(28, innerHeight / sorted.length);
|
|
46709
|
+
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
46710
|
+
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
46711
|
+
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46712
|
+
renderChartTitle(
|
|
46713
|
+
svg,
|
|
46714
|
+
title,
|
|
46715
|
+
parsed.titleLineNumber,
|
|
46716
|
+
width,
|
|
46717
|
+
textColor,
|
|
46718
|
+
onClickItem
|
|
46719
|
+
);
|
|
46720
|
+
renderEras(
|
|
46721
|
+
g,
|
|
46722
|
+
timelineEras,
|
|
46723
|
+
xScale,
|
|
46724
|
+
false,
|
|
46725
|
+
innerWidth,
|
|
46726
|
+
innerHeight,
|
|
46727
|
+
(s, e) => fadeToEra(g, s, e),
|
|
46728
|
+
() => fadeReset(g),
|
|
46729
|
+
timelineScale,
|
|
46730
|
+
tooltip,
|
|
46731
|
+
palette,
|
|
46732
|
+
eraReserve ? eraLabelY : void 0
|
|
46733
|
+
);
|
|
46734
|
+
renderMarkers(
|
|
46735
|
+
g,
|
|
46736
|
+
timelineMarkers,
|
|
46737
|
+
xScale,
|
|
46738
|
+
false,
|
|
46739
|
+
innerWidth,
|
|
46740
|
+
innerHeight,
|
|
46741
|
+
(d) => fadeToMarker(g, d),
|
|
46742
|
+
() => fadeReset(g),
|
|
46743
|
+
timelineScale,
|
|
46744
|
+
tooltip,
|
|
46745
|
+
palette,
|
|
46746
|
+
markerReserve ? markerLabelY : void 0
|
|
46747
|
+
);
|
|
46748
|
+
if (timelineScale) {
|
|
46749
|
+
renderTimeScale(
|
|
46750
|
+
g,
|
|
46751
|
+
xScale,
|
|
46752
|
+
false,
|
|
46753
|
+
innerWidth,
|
|
46754
|
+
innerHeight,
|
|
46755
|
+
textColor,
|
|
46756
|
+
minDate,
|
|
46757
|
+
maxDate,
|
|
46758
|
+
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46759
|
+
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46760
|
+
);
|
|
46761
|
+
}
|
|
46762
|
+
if (timelineGroups.length > 0) {
|
|
46763
|
+
const legendY = timelineScale ? -75 : -55;
|
|
46764
|
+
renderTimelineGroupLegend(
|
|
46765
|
+
g,
|
|
46766
|
+
timelineGroups,
|
|
46767
|
+
groupColorMap,
|
|
46768
|
+
textColor,
|
|
46769
|
+
palette,
|
|
46770
|
+
isDark,
|
|
46771
|
+
legendY,
|
|
46772
|
+
(name) => fadeToGroup(g, name),
|
|
46773
|
+
() => fadeReset(g)
|
|
46774
|
+
);
|
|
46775
|
+
}
|
|
46776
|
+
sorted.forEach((ev, i) => {
|
|
46777
|
+
const y = i * rowH + rowH / 2;
|
|
46778
|
+
const x = xScale(parseTimelineDate(ev.date));
|
|
46779
|
+
const color = eventColor(ev);
|
|
46780
|
+
const evG = g.append("g").attr("class", "tl-event").attr("data-group", ev.group || "").attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
46781
|
+
"data-end-date",
|
|
46782
|
+
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
46783
|
+
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
46784
|
+
if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);
|
|
46638
46785
|
if (timelineScale) {
|
|
46639
|
-
|
|
46786
|
+
showEventDatesOnScale(
|
|
46640
46787
|
g,
|
|
46641
|
-
|
|
46642
|
-
|
|
46643
|
-
|
|
46788
|
+
xScale,
|
|
46789
|
+
ev.date,
|
|
46790
|
+
ev.endDate,
|
|
46644
46791
|
innerHeight,
|
|
46645
|
-
|
|
46646
|
-
minDate,
|
|
46647
|
-
maxDate,
|
|
46648
|
-
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46649
|
-
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46792
|
+
color
|
|
46650
46793
|
);
|
|
46794
|
+
} else {
|
|
46795
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46651
46796
|
}
|
|
46652
|
-
|
|
46653
|
-
|
|
46654
|
-
|
|
46655
|
-
|
|
46656
|
-
|
|
46657
|
-
|
|
46658
|
-
palette,
|
|
46659
|
-
isDark,
|
|
46660
|
-
-55,
|
|
46661
|
-
(name) => fadeToGroup(g, name),
|
|
46662
|
-
() => fadeReset(g)
|
|
46663
|
-
);
|
|
46797
|
+
}).on("mouseleave", function() {
|
|
46798
|
+
fadeReset(g);
|
|
46799
|
+
if (timelineScale) {
|
|
46800
|
+
hideEventDatesOnScale(g);
|
|
46801
|
+
} else {
|
|
46802
|
+
hideTooltip(tooltip);
|
|
46664
46803
|
}
|
|
46665
|
-
|
|
46666
|
-
|
|
46667
|
-
|
|
46668
|
-
|
|
46669
|
-
|
|
46670
|
-
|
|
46671
|
-
|
|
46672
|
-
|
|
46673
|
-
|
|
46804
|
+
}).on("mousemove", function(event) {
|
|
46805
|
+
if (!timelineScale) {
|
|
46806
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46807
|
+
}
|
|
46808
|
+
}).on("click", () => {
|
|
46809
|
+
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
46810
|
+
});
|
|
46811
|
+
setTagAttrs(evG, ev);
|
|
46812
|
+
if (ev.endDate) {
|
|
46813
|
+
const x2 = xScale(parseTimelineDate(ev.endDate));
|
|
46814
|
+
const rectW = Math.max(x2 - x, 4);
|
|
46815
|
+
const estLabelWidth = ev.label.length * 7 + 16;
|
|
46816
|
+
const labelFitsInside = rectW >= estLabelWidth;
|
|
46817
|
+
let fill2 = shapeFill(palette, color, isDark, { solid });
|
|
46818
|
+
let stroke2 = color;
|
|
46819
|
+
if (ev.uncertain) {
|
|
46820
|
+
const gradientId = `uncertain-ts-${ev.lineNumber}`;
|
|
46821
|
+
const strokeGradientId = `uncertain-ts-s-${ev.lineNumber}`;
|
|
46822
|
+
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46823
|
+
const defsEl = d3Selection22.select(defs);
|
|
46824
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
46825
|
+
{ offset: "0%", opacity: 1 },
|
|
46826
|
+
{ offset: "80%", opacity: 1 },
|
|
46827
|
+
{ offset: "100%", opacity: 0 }
|
|
46828
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
46829
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
46830
|
+
{ offset: "0%", opacity: 1 },
|
|
46831
|
+
{ offset: "80%", opacity: 1 },
|
|
46832
|
+
{ offset: "100%", opacity: 0 }
|
|
46833
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", color).attr("stop-opacity", (d) => d.opacity);
|
|
46834
|
+
fill2 = `url(#${gradientId})`;
|
|
46835
|
+
stroke2 = `url(#${strokeGradientId})`;
|
|
46836
|
+
}
|
|
46837
|
+
evG.append("rect").attr("x", x).attr("y", y - BAR_H2 / 2).attr("width", rectW).attr("height", BAR_H2).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
46838
|
+
if (labelFitsInside) {
|
|
46839
|
+
evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46840
|
+
} else {
|
|
46841
|
+
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
46842
|
+
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
46843
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46844
|
+
evG.append("text").attr("x", flipLeft ? x - 6 : x + rectW + 6).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46845
|
+
}
|
|
46846
|
+
} else {
|
|
46847
|
+
const estLabelWidth = ev.label.length * 7;
|
|
46848
|
+
const wouldFlipLeft = x > innerWidth * 0.6;
|
|
46849
|
+
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
46850
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46851
|
+
evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color).attr("stroke-width", 2);
|
|
46852
|
+
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
46853
|
+
}
|
|
46854
|
+
});
|
|
46855
|
+
}
|
|
46856
|
+
function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
46857
|
+
const {
|
|
46858
|
+
width,
|
|
46859
|
+
height,
|
|
46860
|
+
tooltip,
|
|
46861
|
+
solid,
|
|
46862
|
+
textColor,
|
|
46863
|
+
bgColor,
|
|
46864
|
+
bg,
|
|
46865
|
+
groupColorMap,
|
|
46866
|
+
tagLanes,
|
|
46867
|
+
eventColor,
|
|
46868
|
+
minDate,
|
|
46869
|
+
maxDate,
|
|
46870
|
+
datePadding,
|
|
46871
|
+
earliestStartDateStr,
|
|
46872
|
+
latestEndDateStr,
|
|
46873
|
+
tagLegendReserve
|
|
46874
|
+
} = setup;
|
|
46875
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
46876
|
+
const {
|
|
46877
|
+
timelineEvents,
|
|
46878
|
+
timelineGroups,
|
|
46879
|
+
timelineEras,
|
|
46880
|
+
timelineMarkers,
|
|
46881
|
+
timelineScale,
|
|
46882
|
+
timelineSwimlanes
|
|
46883
|
+
} = parsed;
|
|
46884
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
46885
|
+
const BAR_H2 = 22;
|
|
46886
|
+
const GROUP_GAP3 = 12;
|
|
46887
|
+
let lanes;
|
|
46888
|
+
if (tagLanes) {
|
|
46889
|
+
lanes = tagLanes;
|
|
46890
|
+
} else {
|
|
46891
|
+
const groupNames = timelineGroups.map((gr) => gr.name);
|
|
46892
|
+
const ungroupedEvents = timelineEvents.filter(
|
|
46893
|
+
(ev) => ev.group === null || !groupNames.includes(ev.group)
|
|
46894
|
+
);
|
|
46895
|
+
const laneNames = ungroupedEvents.length > 0 ? [...groupNames, "(Other)"] : groupNames;
|
|
46896
|
+
lanes = laneNames.map((name) => ({
|
|
46897
|
+
name,
|
|
46898
|
+
events: timelineEvents.filter(
|
|
46899
|
+
(ev) => name === "(Other)" ? ev.group === null || !groupNames.includes(ev.group) : ev.group === name
|
|
46900
|
+
)
|
|
46901
|
+
}));
|
|
46902
|
+
}
|
|
46903
|
+
const totalEventRows = lanes.reduce((s, l) => s + l.events.length, 0);
|
|
46904
|
+
const scaleMargin = timelineScale ? 24 : 0;
|
|
46905
|
+
const ERA_ROW_H = 22;
|
|
46906
|
+
const MARKER_ROW_H = 22;
|
|
46907
|
+
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46908
|
+
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46909
|
+
const topScaleH = timelineScale ? 40 : 0;
|
|
46910
|
+
const maxGroupNameLen = Math.max(...lanes.map((l) => l.name.length));
|
|
46911
|
+
const dynamicLeftMargin = Math.max(120, maxGroupNameLen * 7 + 30);
|
|
46912
|
+
const baseTopMargin = title ? 50 : 20;
|
|
46913
|
+
const margin = {
|
|
46914
|
+
top: baseTopMargin + topScaleH + eraReserve + markerReserve + tagLegendReserve,
|
|
46915
|
+
right: 40,
|
|
46916
|
+
bottom: 40 + scaleMargin,
|
|
46917
|
+
left: dynamicLeftMargin
|
|
46918
|
+
};
|
|
46919
|
+
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46920
|
+
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46921
|
+
const innerWidth = width - margin.left - margin.right;
|
|
46922
|
+
const innerHeight = height - margin.top - margin.bottom;
|
|
46923
|
+
const totalGaps = (lanes.length - 1) * GROUP_GAP3;
|
|
46924
|
+
const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);
|
|
46925
|
+
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
46926
|
+
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
46927
|
+
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46928
|
+
renderChartTitle(
|
|
46929
|
+
svg,
|
|
46930
|
+
title,
|
|
46931
|
+
parsed.titleLineNumber,
|
|
46932
|
+
width,
|
|
46933
|
+
textColor,
|
|
46934
|
+
onClickItem
|
|
46935
|
+
);
|
|
46936
|
+
renderEras(
|
|
46937
|
+
g,
|
|
46938
|
+
timelineEras,
|
|
46939
|
+
xScale,
|
|
46940
|
+
false,
|
|
46941
|
+
innerWidth,
|
|
46942
|
+
innerHeight,
|
|
46943
|
+
(s, e) => fadeToEra(g, s, e),
|
|
46944
|
+
() => fadeReset(g),
|
|
46945
|
+
timelineScale,
|
|
46946
|
+
tooltip,
|
|
46947
|
+
palette,
|
|
46948
|
+
eraReserve ? eraLabelY : void 0
|
|
46949
|
+
);
|
|
46950
|
+
renderMarkers(
|
|
46951
|
+
g,
|
|
46952
|
+
timelineMarkers,
|
|
46953
|
+
xScale,
|
|
46954
|
+
false,
|
|
46955
|
+
innerWidth,
|
|
46956
|
+
innerHeight,
|
|
46957
|
+
(d) => fadeToMarker(g, d),
|
|
46958
|
+
() => fadeReset(g),
|
|
46959
|
+
timelineScale,
|
|
46960
|
+
tooltip,
|
|
46961
|
+
palette,
|
|
46962
|
+
markerReserve ? markerLabelY : void 0
|
|
46963
|
+
);
|
|
46964
|
+
if (timelineScale) {
|
|
46965
|
+
renderTimeScale(
|
|
46966
|
+
g,
|
|
46967
|
+
xScale,
|
|
46968
|
+
false,
|
|
46969
|
+
innerWidth,
|
|
46970
|
+
innerHeight,
|
|
46971
|
+
textColor,
|
|
46972
|
+
minDate,
|
|
46973
|
+
maxDate,
|
|
46974
|
+
formatBoundaryLabel(earliestStartDateStr, latestEndDateStr),
|
|
46975
|
+
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46976
|
+
);
|
|
46977
|
+
}
|
|
46978
|
+
let curY = 0;
|
|
46979
|
+
if (timelineSwimlanes || tagLanes) {
|
|
46980
|
+
let swimY = 0;
|
|
46981
|
+
lanes.forEach((lane, idx) => {
|
|
46982
|
+
const laneSpan = lane.events.length * rowH;
|
|
46983
|
+
const fillColor = idx % 2 === 0 ? textColor : "transparent";
|
|
46984
|
+
g.append("rect").attr("class", "tl-swimlane").attr("data-group", lane.name).attr("x", -margin.left).attr("y", swimY).attr("width", innerWidth + margin.left).attr("height", laneSpan + (idx < lanes.length - 1 ? GROUP_GAP3 : 0)).attr("fill", fillColor).attr("opacity", 0.06);
|
|
46985
|
+
swimY += laneSpan + GROUP_GAP3;
|
|
46986
|
+
});
|
|
46987
|
+
}
|
|
46988
|
+
for (const lane of lanes) {
|
|
46989
|
+
const laneColor = groupColorMap.get(lane.name) ?? textColor;
|
|
46990
|
+
const laneSpan = lane.events.length * rowH;
|
|
46991
|
+
const group = timelineGroups.find((grp) => grp.name === lane.name);
|
|
46992
|
+
const headerG = g.append("g").attr("class", "tl-lane-header").attr("data-group", lane.name).style("cursor", "pointer").on("mouseenter", () => fadeToGroup(g, lane.name)).on("mouseleave", () => fadeReset(g)).on("click", () => {
|
|
46993
|
+
if (onClickItem && group?.lineNumber) onClickItem(group.lineNumber);
|
|
46994
|
+
});
|
|
46995
|
+
headerG.append("text").attr("x", -margin.left + 10).attr("y", curY + laneSpan / 2).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", laneColor).attr("font-size", "12px").attr("font-weight", "600").text(lane.name);
|
|
46996
|
+
lane.events.forEach((ev, i) => {
|
|
46997
|
+
const y = curY + i * rowH + rowH / 2;
|
|
46998
|
+
const x = xScale(parseTimelineDate(ev.date));
|
|
46999
|
+
const evG = g.append("g").attr("class", "tl-event").attr("data-group", lane.name).attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
47000
|
+
"data-end-date",
|
|
47001
|
+
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
47002
|
+
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
47003
|
+
fadeToGroup(g, lane.name);
|
|
47004
|
+
if (timelineScale) {
|
|
47005
|
+
showEventDatesOnScale(
|
|
47006
|
+
g,
|
|
47007
|
+
xScale,
|
|
47008
|
+
ev.date,
|
|
47009
|
+
ev.endDate,
|
|
47010
|
+
innerHeight,
|
|
47011
|
+
laneColor
|
|
47012
|
+
);
|
|
47013
|
+
} else {
|
|
46674
47014
|
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46675
|
-
}
|
|
46676
|
-
|
|
47015
|
+
}
|
|
47016
|
+
}).on("mouseleave", function() {
|
|
47017
|
+
fadeReset(g);
|
|
47018
|
+
if (timelineScale) {
|
|
47019
|
+
hideEventDatesOnScale(g);
|
|
47020
|
+
} else {
|
|
46677
47021
|
hideTooltip(tooltip);
|
|
46678
|
-
}
|
|
47022
|
+
}
|
|
47023
|
+
}).on("mousemove", function(event) {
|
|
47024
|
+
if (!timelineScale) {
|
|
46679
47025
|
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46680
|
-
}
|
|
46681
|
-
|
|
46682
|
-
|
|
46683
|
-
|
|
46684
|
-
|
|
46685
|
-
|
|
46686
|
-
|
|
46687
|
-
|
|
46688
|
-
|
|
46689
|
-
|
|
46690
|
-
|
|
46691
|
-
|
|
46692
|
-
|
|
46693
|
-
|
|
46694
|
-
|
|
46695
|
-
|
|
46696
|
-
|
|
46697
|
-
|
|
46698
|
-
|
|
46699
|
-
|
|
46700
|
-
|
|
46701
|
-
|
|
46702
|
-
|
|
46703
|
-
|
|
46704
|
-
|
|
46705
|
-
|
|
46706
|
-
|
|
46707
|
-
|
|
46708
|
-
|
|
47026
|
+
}
|
|
47027
|
+
}).on("click", () => {
|
|
47028
|
+
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
47029
|
+
});
|
|
47030
|
+
setTagAttrs(evG, ev);
|
|
47031
|
+
const evColor = eventColor(ev);
|
|
47032
|
+
if (ev.endDate) {
|
|
47033
|
+
const x2 = xScale(parseTimelineDate(ev.endDate));
|
|
47034
|
+
const rectW = Math.max(x2 - x, 4);
|
|
47035
|
+
const estLabelWidth = ev.label.length * 7 + 16;
|
|
47036
|
+
const labelFitsInside = rectW >= estLabelWidth;
|
|
47037
|
+
let fill2 = shapeFill(palette, evColor, isDark, { solid });
|
|
47038
|
+
let stroke2 = evColor;
|
|
47039
|
+
if (ev.uncertain) {
|
|
47040
|
+
const gradientId = `uncertain-${ev.lineNumber}`;
|
|
47041
|
+
const strokeGradientId = `uncertain-s-${ev.lineNumber}`;
|
|
47042
|
+
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
47043
|
+
const defsEl = d3Selection22.select(defs);
|
|
47044
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
47045
|
+
{ offset: "0%", opacity: 1 },
|
|
47046
|
+
{ offset: "80%", opacity: 1 },
|
|
47047
|
+
{ offset: "100%", opacity: 0 }
|
|
47048
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(evColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47049
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
47050
|
+
{ offset: "0%", opacity: 1 },
|
|
47051
|
+
{ offset: "80%", opacity: 1 },
|
|
47052
|
+
{ offset: "100%", opacity: 0 }
|
|
47053
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", evColor).attr("stop-opacity", (d) => d.opacity);
|
|
47054
|
+
fill2 = `url(#${gradientId})`;
|
|
47055
|
+
stroke2 = `url(#${strokeGradientId})`;
|
|
47056
|
+
}
|
|
47057
|
+
evG.append("rect").attr("x", x).attr("y", y - BAR_H2 / 2).attr("width", rectW).attr("height", BAR_H2).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
47058
|
+
if (labelFitsInside) {
|
|
47059
|
+
evG.append("text").attr("x", x + 8).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46709
47060
|
} else {
|
|
46710
|
-
|
|
46711
|
-
|
|
47061
|
+
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
47062
|
+
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
47063
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47064
|
+
evG.append("text").attr("x", flipLeft ? x - 6 : x + rectW + 6).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "13px").text(ev.label);
|
|
46712
47065
|
}
|
|
46713
|
-
|
|
46714
|
-
|
|
46715
|
-
|
|
46716
|
-
|
|
46717
|
-
|
|
46718
|
-
|
|
46719
|
-
).attr("dy", "0.35em").attr("text-anchor", "end").attr("fill",
|
|
47066
|
+
} else {
|
|
47067
|
+
const estLabelWidth = ev.label.length * 7;
|
|
47068
|
+
const wouldFlipLeft = x > innerWidth * 0.6;
|
|
47069
|
+
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
47070
|
+
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47071
|
+
evG.append("circle").attr("cx", x).attr("cy", y).attr("r", 5).attr("fill", shapeFill(palette, evColor, isDark, { solid })).attr("stroke", evColor).attr("stroke-width", 2);
|
|
47072
|
+
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
46720
47073
|
}
|
|
46721
|
-
}
|
|
46722
|
-
|
|
47074
|
+
});
|
|
47075
|
+
curY += laneSpan + GROUP_GAP3;
|
|
46723
47076
|
}
|
|
46724
|
-
|
|
46725
|
-
|
|
46726
|
-
const
|
|
46727
|
-
|
|
46728
|
-
|
|
47077
|
+
}
|
|
47078
|
+
function renderTimelineVertical(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
47079
|
+
const {
|
|
47080
|
+
width,
|
|
47081
|
+
height,
|
|
47082
|
+
tooltip,
|
|
47083
|
+
solid,
|
|
47084
|
+
textColor,
|
|
47085
|
+
mutedColor,
|
|
47086
|
+
bgColor,
|
|
47087
|
+
bg,
|
|
47088
|
+
groupColorMap,
|
|
47089
|
+
tagLanes,
|
|
47090
|
+
eventColor,
|
|
47091
|
+
minDate,
|
|
47092
|
+
maxDate,
|
|
47093
|
+
datePadding,
|
|
47094
|
+
earliestStartDateStr,
|
|
47095
|
+
latestEndDateStr,
|
|
47096
|
+
tagLegendReserve
|
|
47097
|
+
} = setup;
|
|
47098
|
+
const { fadeToGroup, fadeToEra, fadeToMarker, fadeReset, setTagAttrs } = hovers;
|
|
47099
|
+
const {
|
|
47100
|
+
timelineEvents,
|
|
47101
|
+
timelineGroups,
|
|
47102
|
+
timelineEras,
|
|
47103
|
+
timelineMarkers,
|
|
47104
|
+
timelineSort,
|
|
47105
|
+
timelineScale,
|
|
47106
|
+
timelineSwimlanes
|
|
47107
|
+
} = parsed;
|
|
47108
|
+
const title = parsed.noTitle ? null : parsed.title;
|
|
47109
|
+
const useGroupedVertical = tagLanes != null || timelineSort === "group" && timelineGroups.length > 0;
|
|
47110
|
+
if (useGroupedVertical) {
|
|
47111
|
+
let laneNames;
|
|
47112
|
+
let laneEventsByName;
|
|
46729
47113
|
if (tagLanes) {
|
|
46730
|
-
|
|
47114
|
+
laneNames = tagLanes.map((l) => l.name);
|
|
47115
|
+
laneEventsByName = new Map(tagLanes.map((l) => [l.name, l.events]));
|
|
46731
47116
|
} else {
|
|
46732
47117
|
const groupNames = timelineGroups.map((gr) => gr.name);
|
|
46733
47118
|
const ungroupedEvents = timelineEvents.filter(
|
|
46734
47119
|
(ev) => ev.group === null || !groupNames.includes(ev.group)
|
|
46735
47120
|
);
|
|
46736
|
-
|
|
46737
|
-
|
|
46738
|
-
name
|
|
46739
|
-
|
|
46740
|
-
|
|
46741
|
-
|
|
46742
|
-
|
|
47121
|
+
laneNames = ungroupedEvents.length > 0 ? [...groupNames, "(Other)"] : groupNames;
|
|
47122
|
+
laneEventsByName = new Map(
|
|
47123
|
+
laneNames.map((name) => [
|
|
47124
|
+
name,
|
|
47125
|
+
timelineEvents.filter(
|
|
47126
|
+
(ev) => name === "(Other)" ? ev.group === null || !groupNames.includes(ev.group) : ev.group === name
|
|
47127
|
+
)
|
|
47128
|
+
])
|
|
47129
|
+
);
|
|
46743
47130
|
}
|
|
46744
|
-
const
|
|
46745
|
-
const scaleMargin = timelineScale ?
|
|
46746
|
-
const
|
|
46747
|
-
const MARKER_ROW_H = 22;
|
|
46748
|
-
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46749
|
-
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46750
|
-
const topScaleH = timelineScale ? 40 : 0;
|
|
46751
|
-
const maxGroupNameLen = Math.max(...lanes.map((l) => l.name.length));
|
|
46752
|
-
const dynamicLeftMargin = Math.max(120, maxGroupNameLen * 7 + 30);
|
|
46753
|
-
const baseTopMargin = title ? 50 : 20;
|
|
47131
|
+
const laneCount = laneNames.length;
|
|
47132
|
+
const scaleMargin = timelineScale ? 40 : 0;
|
|
47133
|
+
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46754
47134
|
const margin = {
|
|
46755
|
-
top:
|
|
46756
|
-
right: 40,
|
|
46757
|
-
bottom: 40
|
|
46758
|
-
left:
|
|
47135
|
+
top: 104 + markerMargin + tagLegendReserve,
|
|
47136
|
+
right: 40 + scaleMargin,
|
|
47137
|
+
bottom: 40,
|
|
47138
|
+
left: 60 + scaleMargin
|
|
46759
47139
|
};
|
|
46760
|
-
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46761
|
-
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46762
47140
|
const innerWidth = width - margin.left - margin.right;
|
|
46763
47141
|
const innerHeight = height - margin.top - margin.bottom;
|
|
46764
|
-
const
|
|
46765
|
-
const
|
|
46766
|
-
const
|
|
46767
|
-
const svg = d3Selection22.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
47142
|
+
const laneWidth = innerWidth / laneCount;
|
|
47143
|
+
const yScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
|
|
47144
|
+
const svg = d3Selection22.select(container).append("svg").attr("viewBox", `0 0 ${width} ${height}`).attr("width", exportDims ? width : "100%").attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
46768
47145
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46769
47146
|
renderChartTitle(
|
|
46770
47147
|
svg,
|
|
@@ -46777,36 +47154,34 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46777
47154
|
renderEras(
|
|
46778
47155
|
g,
|
|
46779
47156
|
timelineEras,
|
|
46780
|
-
|
|
46781
|
-
|
|
47157
|
+
yScale,
|
|
47158
|
+
true,
|
|
46782
47159
|
innerWidth,
|
|
46783
47160
|
innerHeight,
|
|
46784
47161
|
(s, e) => fadeToEra(g, s, e),
|
|
46785
47162
|
() => fadeReset(g),
|
|
46786
47163
|
timelineScale,
|
|
46787
47164
|
tooltip,
|
|
46788
|
-
palette
|
|
46789
|
-
eraReserve ? eraLabelY : void 0
|
|
47165
|
+
palette
|
|
46790
47166
|
);
|
|
46791
47167
|
renderMarkers(
|
|
46792
47168
|
g,
|
|
46793
47169
|
timelineMarkers,
|
|
46794
|
-
|
|
46795
|
-
|
|
47170
|
+
yScale,
|
|
47171
|
+
true,
|
|
46796
47172
|
innerWidth,
|
|
46797
47173
|
innerHeight,
|
|
46798
47174
|
(d) => fadeToMarker(g, d),
|
|
46799
47175
|
() => fadeReset(g),
|
|
46800
47176
|
timelineScale,
|
|
46801
47177
|
tooltip,
|
|
46802
|
-
palette
|
|
46803
|
-
markerReserve ? markerLabelY : void 0
|
|
47178
|
+
palette
|
|
46804
47179
|
);
|
|
46805
47180
|
if (timelineScale) {
|
|
46806
47181
|
renderTimeScale(
|
|
46807
47182
|
g,
|
|
46808
|
-
|
|
46809
|
-
|
|
47183
|
+
yScale,
|
|
47184
|
+
true,
|
|
46810
47185
|
innerWidth,
|
|
46811
47186
|
innerHeight,
|
|
46812
47187
|
textColor,
|
|
@@ -46816,78 +47191,55 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46816
47191
|
formatBoundaryLabel(latestEndDateStr, earliestStartDateStr)
|
|
46817
47192
|
);
|
|
46818
47193
|
}
|
|
46819
|
-
let curY = 0;
|
|
46820
47194
|
if (timelineSwimlanes || tagLanes) {
|
|
46821
|
-
|
|
46822
|
-
|
|
46823
|
-
const
|
|
46824
|
-
|
|
46825
|
-
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);
|
|
46826
|
-
swimY += laneSpan + GROUP_GAP3;
|
|
47195
|
+
laneNames.forEach((laneName, laneIdx) => {
|
|
47196
|
+
const laneX = laneIdx * laneWidth;
|
|
47197
|
+
const fillColor = laneIdx % 2 === 0 ? textColor : "transparent";
|
|
47198
|
+
g.append("rect").attr("class", "tl-swimlane").attr("data-group", laneName).attr("x", laneX).attr("y", 0).attr("width", laneWidth).attr("height", innerHeight).attr("fill", fillColor).attr("opacity", 0.06);
|
|
46827
47199
|
});
|
|
46828
47200
|
}
|
|
46829
|
-
|
|
46830
|
-
const
|
|
46831
|
-
const
|
|
46832
|
-
const
|
|
46833
|
-
const headerG = g.append("g").attr("class", "tl-lane-header").attr("data-group",
|
|
46834
|
-
|
|
46835
|
-
|
|
46836
|
-
|
|
46837
|
-
|
|
46838
|
-
const y =
|
|
46839
|
-
const
|
|
46840
|
-
const evG = g.append("g").attr("class", "tl-event").attr("data-group", lane.name).attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
47201
|
+
laneNames.forEach((laneName, laneIdx) => {
|
|
47202
|
+
const laneX = laneIdx * laneWidth;
|
|
47203
|
+
const laneColor = groupColorMap.get(laneName) ?? textColor;
|
|
47204
|
+
const laneCenter = laneX + laneWidth / 2;
|
|
47205
|
+
const headerG = g.append("g").attr("class", "tl-lane-header").attr("data-group", laneName).style("cursor", "pointer").on("mouseenter", () => fadeToGroup(g, laneName)).on("mouseleave", () => fadeReset(g));
|
|
47206
|
+
headerG.append("text").attr("x", laneCenter).attr("y", -15).attr("text-anchor", "middle").attr("fill", laneColor).attr("font-size", "12px").attr("font-weight", "600").text(laneName);
|
|
47207
|
+
g.append("line").attr("x1", laneCenter).attr("y1", 0).attr("x2", laneCenter).attr("y2", innerHeight).attr("stroke", mutedColor).attr("stroke-width", 1).attr("stroke-dasharray", "4,4");
|
|
47208
|
+
const laneEvents = laneEventsByName.get(laneName) ?? [];
|
|
47209
|
+
for (const ev of laneEvents) {
|
|
47210
|
+
const y = yScale(parseTimelineDate(ev.date));
|
|
47211
|
+
const evG = g.append("g").attr("class", "tl-event").attr("data-group", laneName).attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
46841
47212
|
"data-end-date",
|
|
46842
47213
|
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
46843
47214
|
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
46844
|
-
fadeToGroup(g,
|
|
46845
|
-
|
|
46846
|
-
showEventDatesOnScale(
|
|
46847
|
-
g,
|
|
46848
|
-
xScale,
|
|
46849
|
-
ev.date,
|
|
46850
|
-
ev.endDate,
|
|
46851
|
-
innerHeight,
|
|
46852
|
-
laneColor
|
|
46853
|
-
);
|
|
46854
|
-
} else {
|
|
46855
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46856
|
-
}
|
|
47215
|
+
fadeToGroup(g, laneName);
|
|
47216
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46857
47217
|
}).on("mouseleave", function() {
|
|
46858
47218
|
fadeReset(g);
|
|
46859
|
-
|
|
46860
|
-
hideEventDatesOnScale(g);
|
|
46861
|
-
} else {
|
|
46862
|
-
hideTooltip(tooltip);
|
|
46863
|
-
}
|
|
47219
|
+
hideTooltip(tooltip);
|
|
46864
47220
|
}).on("mousemove", function(event) {
|
|
46865
|
-
|
|
46866
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46867
|
-
}
|
|
47221
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
46868
47222
|
}).on("click", () => {
|
|
46869
47223
|
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
46870
47224
|
});
|
|
46871
47225
|
setTagAttrs(evG, ev);
|
|
46872
47226
|
const evColor = eventColor(ev);
|
|
46873
47227
|
if (ev.endDate) {
|
|
46874
|
-
const
|
|
46875
|
-
const
|
|
46876
|
-
const estLabelWidth = ev.label.length * 7 + 16;
|
|
46877
|
-
const labelFitsInside = rectW >= estLabelWidth;
|
|
47228
|
+
const y2 = yScale(parseTimelineDate(ev.endDate));
|
|
47229
|
+
const rectH = Math.max(y2 - y, 4);
|
|
46878
47230
|
let fill2 = shapeFill(palette, evColor, isDark, { solid });
|
|
46879
47231
|
let stroke2 = evColor;
|
|
46880
47232
|
if (ev.uncertain) {
|
|
46881
|
-
const gradientId = `uncertain-${ev.lineNumber}`;
|
|
46882
|
-
const strokeGradientId = `uncertain-s-${ev.lineNumber}`;
|
|
47233
|
+
const gradientId = `uncertain-vg-${ev.lineNumber}`;
|
|
47234
|
+
const strokeGradientId = `uncertain-vg-s-${ev.lineNumber}`;
|
|
46883
47235
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
46884
47236
|
const defsEl = d3Selection22.select(defs);
|
|
46885
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47237
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46886
47238
|
{ offset: "0%", opacity: 1 },
|
|
46887
47239
|
{ offset: "80%", opacity: 1 },
|
|
46888
47240
|
{ offset: "100%", opacity: 0 }
|
|
46889
|
-
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(
|
|
46890
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47241
|
+
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47242
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
46891
47243
|
{ offset: "0%", opacity: 1 },
|
|
46892
47244
|
{ offset: "80%", opacity: 1 },
|
|
46893
47245
|
{ offset: "100%", opacity: 0 }
|
|
@@ -46895,47 +47247,29 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46895
47247
|
fill2 = `url(#${gradientId})`;
|
|
46896
47248
|
stroke2 = `url(#${strokeGradientId})`;
|
|
46897
47249
|
}
|
|
46898
|
-
evG.append("rect").attr("x",
|
|
46899
|
-
|
|
46900
|
-
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);
|
|
46901
|
-
} else {
|
|
46902
|
-
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
46903
|
-
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
46904
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46905
|
-
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);
|
|
46906
|
-
}
|
|
47250
|
+
evG.append("rect").attr("x", laneCenter - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
47251
|
+
evG.append("text").attr("x", laneCenter + 14).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
|
|
46907
47252
|
} else {
|
|
46908
|
-
|
|
46909
|
-
|
|
46910
|
-
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
46911
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
46912
|
-
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);
|
|
46913
|
-
evG.append("text").attr("x", flipLeft ? x - 10 : x + 10).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", "12px").text(ev.label);
|
|
47253
|
+
evG.append("circle").attr("cx", laneCenter).attr("cy", y).attr("r", 4).attr("fill", shapeFill(palette, evColor, isDark, { solid })).attr("stroke", evColor).attr("stroke-width", 2);
|
|
47254
|
+
evG.append("text").attr("x", laneCenter + 10).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "10px").text(ev.label);
|
|
46914
47255
|
}
|
|
46915
|
-
}
|
|
46916
|
-
|
|
46917
|
-
}
|
|
47256
|
+
}
|
|
47257
|
+
});
|
|
46918
47258
|
} else {
|
|
46919
|
-
const
|
|
46920
|
-
const
|
|
46921
|
-
const ERA_ROW_H = 22;
|
|
46922
|
-
const MARKER_ROW_H = 22;
|
|
46923
|
-
const eraReserve = timelineEras.length > 0 ? ERA_ROW_H : 0;
|
|
46924
|
-
const markerReserve = timelineMarkers.length > 0 ? MARKER_ROW_H : 0;
|
|
46925
|
-
const topScaleH = timelineScale ? 40 : 0;
|
|
47259
|
+
const scaleMargin = timelineScale ? 40 : 0;
|
|
47260
|
+
const markerMargin = timelineMarkers.length > 0 ? 30 : 0;
|
|
46926
47261
|
const margin = {
|
|
46927
|
-
top: 104 +
|
|
46928
|
-
right:
|
|
46929
|
-
bottom: 40
|
|
46930
|
-
left: 60
|
|
47262
|
+
top: 104 + markerMargin + tagLegendReserve,
|
|
47263
|
+
right: 200,
|
|
47264
|
+
bottom: 40,
|
|
47265
|
+
left: 60 + scaleMargin
|
|
46931
47266
|
};
|
|
46932
|
-
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
46933
|
-
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
46934
47267
|
const innerWidth = width - margin.left - margin.right;
|
|
46935
47268
|
const innerHeight = height - margin.top - margin.bottom;
|
|
46936
|
-
const
|
|
46937
|
-
const
|
|
46938
|
-
const
|
|
47269
|
+
const axisX = 20;
|
|
47270
|
+
const yScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
|
|
47271
|
+
const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
|
|
47272
|
+
const svg = d3Selection22.select(container).append("svg").attr("viewBox", `0 0 ${width} ${height}`).attr("width", exportDims ? width : "100%").attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
46939
47273
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
46940
47274
|
renderChartTitle(
|
|
46941
47275
|
svg,
|
|
@@ -46948,36 +47282,34 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46948
47282
|
renderEras(
|
|
46949
47283
|
g,
|
|
46950
47284
|
timelineEras,
|
|
46951
|
-
|
|
46952
|
-
|
|
47285
|
+
yScale,
|
|
47286
|
+
true,
|
|
46953
47287
|
innerWidth,
|
|
46954
47288
|
innerHeight,
|
|
46955
47289
|
(s, e) => fadeToEra(g, s, e),
|
|
46956
47290
|
() => fadeReset(g),
|
|
46957
47291
|
timelineScale,
|
|
46958
47292
|
tooltip,
|
|
46959
|
-
palette
|
|
46960
|
-
eraReserve ? eraLabelY : void 0
|
|
47293
|
+
palette
|
|
46961
47294
|
);
|
|
46962
47295
|
renderMarkers(
|
|
46963
47296
|
g,
|
|
46964
47297
|
timelineMarkers,
|
|
46965
|
-
|
|
46966
|
-
|
|
47298
|
+
yScale,
|
|
47299
|
+
true,
|
|
46967
47300
|
innerWidth,
|
|
46968
47301
|
innerHeight,
|
|
46969
47302
|
(d) => fadeToMarker(g, d),
|
|
46970
47303
|
() => fadeReset(g),
|
|
46971
47304
|
timelineScale,
|
|
46972
47305
|
tooltip,
|
|
46973
|
-
palette
|
|
46974
|
-
markerReserve ? markerLabelY : void 0
|
|
47306
|
+
palette
|
|
46975
47307
|
);
|
|
46976
47308
|
if (timelineScale) {
|
|
46977
47309
|
renderTimeScale(
|
|
46978
47310
|
g,
|
|
46979
|
-
|
|
46980
|
-
|
|
47311
|
+
yScale,
|
|
47312
|
+
true,
|
|
46981
47313
|
innerWidth,
|
|
46982
47314
|
innerHeight,
|
|
46983
47315
|
textColor,
|
|
@@ -46988,7 +47320,6 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46988
47320
|
);
|
|
46989
47321
|
}
|
|
46990
47322
|
if (timelineGroups.length > 0) {
|
|
46991
|
-
const legendY = timelineScale ? -75 : -55;
|
|
46992
47323
|
renderTimelineGroupLegend(
|
|
46993
47324
|
g,
|
|
46994
47325
|
timelineGroups,
|
|
@@ -46996,65 +47327,46 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
46996
47327
|
textColor,
|
|
46997
47328
|
palette,
|
|
46998
47329
|
isDark,
|
|
46999
|
-
|
|
47330
|
+
-55,
|
|
47000
47331
|
(name) => fadeToGroup(g, name),
|
|
47001
47332
|
() => fadeReset(g)
|
|
47002
47333
|
);
|
|
47003
47334
|
}
|
|
47004
|
-
|
|
47005
|
-
|
|
47006
|
-
const
|
|
47335
|
+
g.append("line").attr("x1", axisX).attr("y1", 0).attr("x2", axisX).attr("y2", innerHeight).attr("stroke", mutedColor).attr("stroke-width", 1).attr("stroke-dasharray", "4,4");
|
|
47336
|
+
for (const ev of sorted) {
|
|
47337
|
+
const y = yScale(parseTimelineDate(ev.date));
|
|
47007
47338
|
const color = eventColor(ev);
|
|
47008
47339
|
const evG = g.append("g").attr("class", "tl-event").attr("data-group", ev.group || "").attr("data-line-number", String(ev.lineNumber)).attr("data-date", String(parseTimelineDate(ev.date))).attr(
|
|
47009
47340
|
"data-end-date",
|
|
47010
47341
|
ev.endDate ? String(parseTimelineDate(ev.endDate)) : null
|
|
47011
47342
|
).style("cursor", "pointer").on("mouseenter", function(event) {
|
|
47012
47343
|
if (ev.group && timelineGroups.length > 0) fadeToGroup(g, ev.group);
|
|
47013
|
-
|
|
47014
|
-
showEventDatesOnScale(
|
|
47015
|
-
g,
|
|
47016
|
-
xScale,
|
|
47017
|
-
ev.date,
|
|
47018
|
-
ev.endDate,
|
|
47019
|
-
innerHeight,
|
|
47020
|
-
color
|
|
47021
|
-
);
|
|
47022
|
-
} else {
|
|
47023
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47024
|
-
}
|
|
47344
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47025
47345
|
}).on("mouseleave", function() {
|
|
47026
47346
|
fadeReset(g);
|
|
47027
|
-
|
|
47028
|
-
hideEventDatesOnScale(g);
|
|
47029
|
-
} else {
|
|
47030
|
-
hideTooltip(tooltip);
|
|
47031
|
-
}
|
|
47347
|
+
hideTooltip(tooltip);
|
|
47032
47348
|
}).on("mousemove", function(event) {
|
|
47033
|
-
|
|
47034
|
-
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47035
|
-
}
|
|
47349
|
+
showTooltip(tooltip, buildEventTooltipHtml(ev), event);
|
|
47036
47350
|
}).on("click", () => {
|
|
47037
47351
|
if (onClickItem && ev.lineNumber) onClickItem(ev.lineNumber);
|
|
47038
47352
|
});
|
|
47039
47353
|
setTagAttrs(evG, ev);
|
|
47040
47354
|
if (ev.endDate) {
|
|
47041
|
-
const
|
|
47042
|
-
const
|
|
47043
|
-
const estLabelWidth = ev.label.length * 7 + 16;
|
|
47044
|
-
const labelFitsInside = rectW >= estLabelWidth;
|
|
47355
|
+
const y2 = yScale(parseTimelineDate(ev.endDate));
|
|
47356
|
+
const rectH = Math.max(y2 - y, 4);
|
|
47045
47357
|
let fill2 = shapeFill(palette, color, isDark, { solid });
|
|
47046
47358
|
let stroke2 = color;
|
|
47047
47359
|
if (ev.uncertain) {
|
|
47048
|
-
const gradientId = `uncertain-
|
|
47049
|
-
const strokeGradientId = `uncertain-
|
|
47360
|
+
const gradientId = `uncertain-v-${ev.lineNumber}`;
|
|
47361
|
+
const strokeGradientId = `uncertain-v-s-${ev.lineNumber}`;
|
|
47050
47362
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
47051
47363
|
const defsEl = d3Selection22.select(defs);
|
|
47052
|
-
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47364
|
+
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
47053
47365
|
{ offset: "0%", opacity: 1 },
|
|
47054
47366
|
{ offset: "80%", opacity: 1 },
|
|
47055
47367
|
{ offset: "100%", opacity: 0 }
|
|
47056
47368
|
]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
|
|
47057
|
-
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "
|
|
47369
|
+
defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
47058
47370
|
{ offset: "0%", opacity: 1 },
|
|
47059
47371
|
{ offset: "80%", opacity: 1 },
|
|
47060
47372
|
{ offset: "100%", opacity: 0 }
|
|
@@ -47062,206 +47374,100 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
47062
47374
|
fill2 = `url(#${gradientId})`;
|
|
47063
47375
|
stroke2 = `url(#${strokeGradientId})`;
|
|
47064
47376
|
}
|
|
47065
|
-
evG.append("rect").attr("x",
|
|
47066
|
-
|
|
47067
|
-
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);
|
|
47068
|
-
} else {
|
|
47069
|
-
const wouldFlipLeft = x + rectW > innerWidth * 0.6;
|
|
47070
|
-
const labelFitsLeft = x - 6 - estLabelWidth > 0;
|
|
47071
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47072
|
-
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);
|
|
47073
|
-
}
|
|
47377
|
+
evG.append("rect").attr("x", axisX - 6).attr("y", y).attr("width", 12).attr("height", rectH).attr("rx", 4).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 2);
|
|
47378
|
+
evG.append("text").attr("x", axisX + 16).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "11px").text(ev.label);
|
|
47074
47379
|
} else {
|
|
47075
|
-
|
|
47076
|
-
|
|
47077
|
-
const labelFitsLeft = x - 10 - estLabelWidth > 0;
|
|
47078
|
-
const flipLeft = wouldFlipLeft && labelFitsLeft;
|
|
47079
|
-
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);
|
|
47080
|
-
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);
|
|
47081
|
-
}
|
|
47082
|
-
});
|
|
47083
|
-
}
|
|
47084
|
-
if (parsed.timelineTagGroups.length > 0) {
|
|
47085
|
-
const LG_HEIGHT = LEGEND_HEIGHT;
|
|
47086
|
-
const LG_PILL_PAD = LEGEND_PILL_PAD;
|
|
47087
|
-
const LG_PILL_FONT_SIZE = LEGEND_PILL_FONT_SIZE;
|
|
47088
|
-
const LG_CAPSULE_PAD = LEGEND_CAPSULE_PAD;
|
|
47089
|
-
const LG_DOT_R = LEGEND_DOT_R;
|
|
47090
|
-
const LG_ENTRY_FONT_SIZE = LEGEND_ENTRY_FONT_SIZE;
|
|
47091
|
-
const LG_ENTRY_DOT_GAP = LEGEND_ENTRY_DOT_GAP;
|
|
47092
|
-
const LG_ENTRY_TRAIL = LEGEND_ENTRY_TRAIL;
|
|
47093
|
-
const LG_ICON_W = 20;
|
|
47094
|
-
const mainSvg = d3Selection22.select(container).select("svg");
|
|
47095
|
-
const mainG = mainSvg.select("g");
|
|
47096
|
-
if (!mainSvg.empty() && !mainG.empty()) {
|
|
47097
|
-
let drawSwimlaneIcon4 = function(parent, x, y, isSwimActive) {
|
|
47098
|
-
const iconG = parent.append("g").attr("class", "tl-swimlane-icon").attr("transform", `translate(${x}, ${y})`).style("cursor", "pointer");
|
|
47099
|
-
const barColor = isSwimActive ? palette.primary : palette.textMuted;
|
|
47100
|
-
const barOpacity = isSwimActive ? 1 : 0.35;
|
|
47101
|
-
const bars = [
|
|
47102
|
-
{ y: 0, w: 8 },
|
|
47103
|
-
{ y: 4, w: 12 },
|
|
47104
|
-
{ y: 8, w: 6 }
|
|
47105
|
-
];
|
|
47106
|
-
for (const bar of bars) {
|
|
47107
|
-
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);
|
|
47108
|
-
}
|
|
47109
|
-
return iconG;
|
|
47110
|
-
}, relayout2 = function() {
|
|
47111
|
-
renderTimeline(
|
|
47112
|
-
container,
|
|
47113
|
-
parsed,
|
|
47114
|
-
palette,
|
|
47115
|
-
isDark,
|
|
47116
|
-
onClickItem,
|
|
47117
|
-
exportDims,
|
|
47118
|
-
currentActiveGroup,
|
|
47119
|
-
currentSwimlaneGroup,
|
|
47120
|
-
onTagStateChange,
|
|
47121
|
-
viewMode
|
|
47122
|
-
);
|
|
47123
|
-
}, drawLegend2 = function() {
|
|
47124
|
-
mainSvg.selectAll(".tl-tag-legend-group").remove();
|
|
47125
|
-
mainSvg.selectAll(".tl-tag-legend-container").remove();
|
|
47126
|
-
const effectiveColorKey = (currentActiveGroup ?? currentSwimlaneGroup)?.toLowerCase() ?? null;
|
|
47127
|
-
const visibleGroups = viewMode ? legendGroups.filter(
|
|
47128
|
-
(lg) => effectiveColorKey != null && lg.group.name.toLowerCase() === effectiveColorKey
|
|
47129
|
-
) : legendGroups;
|
|
47130
|
-
if (visibleGroups.length === 0) return;
|
|
47131
|
-
const legendContainer = mainSvg.append("g").attr("class", "tl-tag-legend-container");
|
|
47132
|
-
if (currentActiveGroup) {
|
|
47133
|
-
legendContainer.attr(
|
|
47134
|
-
"data-legend-active",
|
|
47135
|
-
currentActiveGroup.toLowerCase()
|
|
47136
|
-
);
|
|
47137
|
-
}
|
|
47138
|
-
const iconAddon = viewMode ? 0 : LG_ICON_W;
|
|
47139
|
-
const centralGroups = visibleGroups.map((lg) => ({
|
|
47140
|
-
name: lg.group.name,
|
|
47141
|
-
entries: lg.group.entries.map((e) => ({
|
|
47142
|
-
value: e.value,
|
|
47143
|
-
color: e.color
|
|
47144
|
-
}))
|
|
47145
|
-
}));
|
|
47146
|
-
const centralActive = viewMode ? effectiveColorKey : currentActiveGroup;
|
|
47147
|
-
const centralConfig = {
|
|
47148
|
-
groups: centralGroups,
|
|
47149
|
-
position: { placement: "top-center", titleRelation: "below-title" },
|
|
47150
|
-
mode: "fixed",
|
|
47151
|
-
capsulePillAddonWidth: iconAddon
|
|
47152
|
-
};
|
|
47153
|
-
const centralState = { activeGroup: centralActive };
|
|
47154
|
-
const centralCallbacks = viewMode ? {} : {
|
|
47155
|
-
onGroupToggle: (groupName) => {
|
|
47156
|
-
currentActiveGroup = currentActiveGroup === groupName.toLowerCase() ? null : groupName.toLowerCase();
|
|
47157
|
-
drawLegend2();
|
|
47158
|
-
recolorEvents2();
|
|
47159
|
-
onTagStateChange?.(currentActiveGroup, currentSwimlaneGroup);
|
|
47160
|
-
},
|
|
47161
|
-
onEntryHover: (groupName, entryValue) => {
|
|
47162
|
-
const tagKey = groupName.toLowerCase();
|
|
47163
|
-
if (entryValue) {
|
|
47164
|
-
const tagVal = entryValue.toLowerCase();
|
|
47165
|
-
fadeToTagValue(mainG, tagKey, tagVal);
|
|
47166
|
-
mainSvg.selectAll("[data-legend-entry]").each(function() {
|
|
47167
|
-
const el = d3Selection22.select(this);
|
|
47168
|
-
const ev = el.attr("data-legend-entry");
|
|
47169
|
-
const eg = el.attr("data-tag-group") ?? el.node()?.closest?.("[data-tag-group]")?.getAttribute("data-tag-group");
|
|
47170
|
-
el.attr(
|
|
47171
|
-
"opacity",
|
|
47172
|
-
eg === tagKey && ev === tagVal ? 1 : FADE_OPACITY3
|
|
47173
|
-
);
|
|
47174
|
-
});
|
|
47175
|
-
} else {
|
|
47176
|
-
fadeReset(mainG);
|
|
47177
|
-
mainSvg.selectAll("[data-legend-entry]").attr("opacity", 1);
|
|
47178
|
-
}
|
|
47179
|
-
},
|
|
47180
|
-
onGroupRendered: (groupName, groupEl, isActive) => {
|
|
47181
|
-
const groupKey = groupName.toLowerCase();
|
|
47182
|
-
groupEl.attr("data-tag-group", groupKey);
|
|
47183
|
-
if (isActive && !viewMode) {
|
|
47184
|
-
const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
|
|
47185
|
-
const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
47186
|
-
const pillXOff = LG_CAPSULE_PAD;
|
|
47187
|
-
const iconX = pillXOff + pillWidth3 + 5;
|
|
47188
|
-
const iconY = (LG_HEIGHT - 10) / 2;
|
|
47189
|
-
const iconEl = drawSwimlaneIcon4(
|
|
47190
|
-
groupEl,
|
|
47191
|
-
iconX,
|
|
47192
|
-
iconY,
|
|
47193
|
-
isSwimActive
|
|
47194
|
-
);
|
|
47195
|
-
iconEl.attr("data-swimlane-toggle", groupKey).on("click", (event) => {
|
|
47196
|
-
event.stopPropagation();
|
|
47197
|
-
currentSwimlaneGroup = currentSwimlaneGroup === groupKey ? null : groupKey;
|
|
47198
|
-
onTagStateChange?.(
|
|
47199
|
-
currentActiveGroup,
|
|
47200
|
-
currentSwimlaneGroup
|
|
47201
|
-
);
|
|
47202
|
-
relayout2();
|
|
47203
|
-
});
|
|
47204
|
-
}
|
|
47205
|
-
}
|
|
47206
|
-
};
|
|
47207
|
-
const legendInnerG = legendContainer.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
47208
|
-
renderLegendD3(
|
|
47209
|
-
legendInnerG,
|
|
47210
|
-
centralConfig,
|
|
47211
|
-
centralState,
|
|
47212
|
-
palette,
|
|
47213
|
-
isDark,
|
|
47214
|
-
centralCallbacks,
|
|
47215
|
-
width
|
|
47216
|
-
);
|
|
47217
|
-
}, recolorEvents2 = function() {
|
|
47218
|
-
const colorTG = currentActiveGroup ?? swimlaneTagGroup ?? null;
|
|
47219
|
-
mainG.selectAll(".tl-event").each(function() {
|
|
47220
|
-
const el = d3Selection22.select(this);
|
|
47221
|
-
const lineNum = el.attr("data-line-number");
|
|
47222
|
-
const ev = lineNum ? eventByLine.get(lineNum) : void 0;
|
|
47223
|
-
if (!ev) return;
|
|
47224
|
-
let color;
|
|
47225
|
-
if (colorTG) {
|
|
47226
|
-
const tagColor = resolveTagColor(
|
|
47227
|
-
ev.metadata,
|
|
47228
|
-
parsed.timelineTagGroups,
|
|
47229
|
-
colorTG
|
|
47230
|
-
);
|
|
47231
|
-
color = tagColor ?? (ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor);
|
|
47232
|
-
} else {
|
|
47233
|
-
color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
|
|
47234
|
-
}
|
|
47235
|
-
el.selectAll("rect").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
47236
|
-
el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
|
|
47237
|
-
});
|
|
47238
|
-
};
|
|
47239
|
-
var drawSwimlaneIcon3 = drawSwimlaneIcon4, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
|
|
47240
|
-
const legendY = title ? 50 : 10;
|
|
47241
|
-
const legendGroups = parsed.timelineTagGroups.map((g) => {
|
|
47242
|
-
const pillW = measureLegendText(g.name, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
47243
|
-
const iconSpace = viewMode ? 8 : LG_ICON_W + 4;
|
|
47244
|
-
let entryX = LG_CAPSULE_PAD + pillW + iconSpace;
|
|
47245
|
-
for (const entry of g.entries) {
|
|
47246
|
-
const textX = entryX + LG_DOT_R * 2 + LG_ENTRY_DOT_GAP;
|
|
47247
|
-
entryX = textX + measureLegendText(entry.value, LG_ENTRY_FONT_SIZE) + LG_ENTRY_TRAIL;
|
|
47248
|
-
}
|
|
47249
|
-
return {
|
|
47250
|
-
group: g,
|
|
47251
|
-
minifiedWidth: pillW,
|
|
47252
|
-
expandedWidth: entryX + LG_CAPSULE_PAD
|
|
47253
|
-
};
|
|
47254
|
-
});
|
|
47255
|
-
let currentActiveGroup = activeTagGroup ?? null;
|
|
47256
|
-
let currentSwimlaneGroup = swimlaneTagGroup ?? null;
|
|
47257
|
-
const eventByLine = /* @__PURE__ */ new Map();
|
|
47258
|
-
for (const ev of timelineEvents) {
|
|
47259
|
-
eventByLine.set(String(ev.lineNumber), ev);
|
|
47380
|
+
evG.append("circle").attr("cx", axisX).attr("cy", y).attr("r", 4).attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color).attr("stroke-width", 2);
|
|
47381
|
+
evG.append("text").attr("x", axisX + 16).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", "11px").text(ev.label);
|
|
47260
47382
|
}
|
|
47261
|
-
|
|
47383
|
+
evG.append("text").attr("x", axisX - 14).attr(
|
|
47384
|
+
"y",
|
|
47385
|
+
ev.endDate ? yScale(parseTimelineDate(ev.date)) + Math.max(
|
|
47386
|
+
yScale(parseTimelineDate(ev.endDate)) - yScale(parseTimelineDate(ev.date)),
|
|
47387
|
+
4
|
|
47388
|
+
) / 2 : y
|
|
47389
|
+
).attr("dy", "0.35em").attr("text-anchor", "end").attr("fill", mutedColor).attr("font-size", "10px").text(ev.date + (ev.endDate ? `\u2192${ev.endDate}` : ""));
|
|
47262
47390
|
}
|
|
47263
47391
|
}
|
|
47264
47392
|
}
|
|
47393
|
+
function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims, activeTagGroup, swimlaneTagGroup, onTagStateChange, viewMode) {
|
|
47394
|
+
const setup = setupTimeline(
|
|
47395
|
+
container,
|
|
47396
|
+
parsed,
|
|
47397
|
+
palette,
|
|
47398
|
+
isDark,
|
|
47399
|
+
exportDims,
|
|
47400
|
+
activeTagGroup,
|
|
47401
|
+
swimlaneTagGroup
|
|
47402
|
+
);
|
|
47403
|
+
if (!setup) return;
|
|
47404
|
+
swimlaneTagGroup = setup.swimlaneTagGroup;
|
|
47405
|
+
const { isVertical, tagLanes } = setup;
|
|
47406
|
+
const hovers = makeTimelineHoverHelpers();
|
|
47407
|
+
if (isVertical) {
|
|
47408
|
+
renderTimelineVertical(
|
|
47409
|
+
container,
|
|
47410
|
+
parsed,
|
|
47411
|
+
palette,
|
|
47412
|
+
isDark,
|
|
47413
|
+
setup,
|
|
47414
|
+
hovers,
|
|
47415
|
+
onClickItem,
|
|
47416
|
+
exportDims,
|
|
47417
|
+
swimlaneTagGroup,
|
|
47418
|
+
activeTagGroup,
|
|
47419
|
+
onTagStateChange,
|
|
47420
|
+
viewMode
|
|
47421
|
+
);
|
|
47422
|
+
return;
|
|
47423
|
+
}
|
|
47424
|
+
const useGroupedHorizontal = tagLanes != null || parsed.timelineSort === "group" && parsed.timelineGroups.length > 0;
|
|
47425
|
+
if (useGroupedHorizontal) {
|
|
47426
|
+
renderTimelineHorizontalGrouped(
|
|
47427
|
+
container,
|
|
47428
|
+
parsed,
|
|
47429
|
+
palette,
|
|
47430
|
+
isDark,
|
|
47431
|
+
setup,
|
|
47432
|
+
hovers,
|
|
47433
|
+
onClickItem,
|
|
47434
|
+
exportDims,
|
|
47435
|
+
swimlaneTagGroup,
|
|
47436
|
+
activeTagGroup,
|
|
47437
|
+
onTagStateChange,
|
|
47438
|
+
viewMode
|
|
47439
|
+
);
|
|
47440
|
+
} else {
|
|
47441
|
+
renderTimelineHorizontalTimeSort(
|
|
47442
|
+
container,
|
|
47443
|
+
parsed,
|
|
47444
|
+
palette,
|
|
47445
|
+
isDark,
|
|
47446
|
+
setup,
|
|
47447
|
+
hovers,
|
|
47448
|
+
onClickItem,
|
|
47449
|
+
exportDims,
|
|
47450
|
+
swimlaneTagGroup,
|
|
47451
|
+
activeTagGroup,
|
|
47452
|
+
onTagStateChange,
|
|
47453
|
+
viewMode
|
|
47454
|
+
);
|
|
47455
|
+
}
|
|
47456
|
+
renderTimelineTagLegendOverlay(
|
|
47457
|
+
container,
|
|
47458
|
+
parsed,
|
|
47459
|
+
palette,
|
|
47460
|
+
isDark,
|
|
47461
|
+
setup,
|
|
47462
|
+
hovers,
|
|
47463
|
+
onClickItem,
|
|
47464
|
+
exportDims,
|
|
47465
|
+
swimlaneTagGroup,
|
|
47466
|
+
activeTagGroup,
|
|
47467
|
+
onTagStateChange,
|
|
47468
|
+
viewMode
|
|
47469
|
+
);
|
|
47470
|
+
}
|
|
47265
47471
|
function getRotateFn(mode) {
|
|
47266
47472
|
if (mode === "mixed") return () => Math.random() > 0.5 ? 0 : 90;
|
|
47267
47473
|
if (mode === "angled") return () => Math.round(Math.random() * 30 - 15);
|
|
@@ -47385,7 +47591,7 @@ function regionCentroid(circles, inside) {
|
|
|
47385
47591
|
}
|
|
47386
47592
|
return { x: sx / count, y: sy / count };
|
|
47387
47593
|
}
|
|
47388
|
-
function renderVenn(container, parsed, palette,
|
|
47594
|
+
function renderVenn(container, parsed, palette, _isDark, onClickItem, exportDims) {
|
|
47389
47595
|
const { vennSets, vennOverlaps } = parsed;
|
|
47390
47596
|
const title = parsed.noTitle ? null : parsed.title;
|
|
47391
47597
|
if (vennSets.length < 2 || vennSets.length > 3) return;
|
|
@@ -47619,7 +47825,7 @@ function renderVenn(container, parsed, palette, isDark, onClickItem, exportDims)
|
|
|
47619
47825
|
};
|
|
47620
47826
|
const gcx = circles.reduce((s, c) => s + c.x, 0) / n;
|
|
47621
47827
|
const gcy = circles.reduce((s, c) => s + c.y, 0) / n;
|
|
47622
|
-
function exclusiveHSpan(
|
|
47828
|
+
function exclusiveHSpan(_px, py, ci) {
|
|
47623
47829
|
const dy = py - circles[ci].y;
|
|
47624
47830
|
const halfChord = Math.sqrt(
|
|
47625
47831
|
Math.max(0, circles[ci].r * circles[ci].r - dy * dy)
|
|
@@ -48532,9 +48738,9 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
48532
48738
|
blHiddenTagValues.set(k, new Set(v));
|
|
48533
48739
|
}
|
|
48534
48740
|
}
|
|
48535
|
-
const { layoutBoxesAndLines: layoutBoxesAndLines2 } = await Promise.resolve().then(() => (init_layout5(), layout_exports5));
|
|
48536
48741
|
const { renderBoxesAndLinesForExport: renderBoxesAndLinesForExport2 } = await Promise.resolve().then(() => (init_renderer6(), renderer_exports6));
|
|
48537
|
-
const
|
|
48742
|
+
const { layoutBoxesAndLines: layoutBoxesAndLines2 } = await Promise.resolve().then(() => (init_layout5(), layout_exports5));
|
|
48743
|
+
const blLayout = await layoutBoxesAndLines2(blParsed);
|
|
48538
48744
|
const PADDING3 = 20;
|
|
48539
48745
|
const titleOffset = blParsed.title ? 40 : 0;
|
|
48540
48746
|
const exportWidth = blLayout.width + PADDING3 * 2;
|
|
@@ -49626,6 +49832,7 @@ __export(index_exports, {
|
|
|
49626
49832
|
decodeDiagramUrl: () => decodeDiagramUrl2,
|
|
49627
49833
|
encodeDiagramUrl: () => encodeDiagramUrl2,
|
|
49628
49834
|
formatDgmoError: () => formatDgmoError,
|
|
49835
|
+
getPalette: () => getPalette,
|
|
49629
49836
|
palettes: () => palettes,
|
|
49630
49837
|
render: () => render2,
|
|
49631
49838
|
themes: () => themes,
|
|
@@ -49810,7 +50017,8 @@ async function render2(text, options) {
|
|
|
49810
50017
|
const onError = options?.onError ?? "svg";
|
|
49811
50018
|
const result = await render(text, {
|
|
49812
50019
|
theme: options?.theme,
|
|
49813
|
-
palette: palette.id
|
|
50020
|
+
palette: palette.id,
|
|
50021
|
+
viewState: options?.viewState
|
|
49814
50022
|
});
|
|
49815
50023
|
const errors = result.diagnostics.filter((d) => d.severity === "error");
|
|
49816
50024
|
if (errors.length === 0) {
|
|
@@ -49850,7 +50058,8 @@ function encodeDiagramUrl2(text, options) {
|
|
|
49850
50058
|
baseUrl: options?.baseUrl,
|
|
49851
50059
|
palette: options?.palette?.id,
|
|
49852
50060
|
theme: internalTheme,
|
|
49853
|
-
filename: options?.filename
|
|
50061
|
+
filename: options?.filename,
|
|
50062
|
+
viewState: options?.viewState
|
|
49854
50063
|
});
|
|
49855
50064
|
return "error" in result && result.error ? null : result.url ?? null;
|
|
49856
50065
|
}
|
|
@@ -49869,6 +50078,7 @@ function decodeDiagramUrl2(url) {
|
|
|
49869
50078
|
decodeDiagramUrl,
|
|
49870
50079
|
encodeDiagramUrl,
|
|
49871
50080
|
formatDgmoError,
|
|
50081
|
+
getPalette,
|
|
49872
50082
|
palettes,
|
|
49873
50083
|
render,
|
|
49874
50084
|
themes,
|