@diagrammo/dgmo 0.8.17 → 0.8.19
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/dist/cli.cjs +103 -103
- package/dist/editor.cjs +1 -1
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.js +1 -1
- package/dist/editor.js.map +1 -1
- package/dist/highlight.cjs +1 -1
- package/dist/highlight.cjs.map +1 -1
- package/dist/highlight.js +1 -1
- package/dist/highlight.js.map +1 -1
- package/dist/index.cjs +1306 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +120 -15
- package/dist/index.d.ts +120 -15
- package/dist/index.js +1325 -151
- package/dist/index.js.map +1 -1
- package/docs/guide/how-dgmo-thinks.md +277 -0
- package/docs/guide/registry.json +1 -0
- package/gallery/fixtures/gantt-sprints.dgmo +20 -0
- package/package.json +1 -1
- package/src/colors.ts +1 -1
- package/src/editor/dgmo.grammar +1 -1
- package/src/editor/dgmo.grammar.js +1 -1
- package/src/gantt/calculator.ts +120 -7
- package/src/gantt/parser.ts +98 -3
- package/src/gantt/renderer.ts +410 -95
- package/src/gantt/types.ts +23 -2
- package/src/index.ts +10 -2
- package/src/sequence/collapse.ts +169 -0
- package/src/sequence/parser.ts +14 -2
- package/src/sequence/renderer.ts +186 -49
- package/src/sharing.ts +86 -49
- package/src/utils/duration.ts +16 -2
- package/src/utils/legend-constants.ts +11 -0
- package/src/utils/legend-d3.ts +171 -0
- package/src/utils/legend-layout.ts +148 -17
- package/src/utils/legend-types.ts +45 -0
package/dist/index.cjs
CHANGED
|
@@ -8,6 +8,9 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
|
8
8
|
var __esm = (fn, res) => function __init() {
|
|
9
9
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
10
|
};
|
|
11
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
12
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
13
|
+
};
|
|
11
14
|
var __export = (target, all) => {
|
|
12
15
|
for (var name in all)
|
|
13
16
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -2099,7 +2102,7 @@ function measureLegendText(text, fontSize) {
|
|
|
2099
2102
|
}
|
|
2100
2103
|
return w;
|
|
2101
2104
|
}
|
|
2102
|
-
var LEGEND_HEIGHT, LEGEND_PILL_PAD, LEGEND_PILL_FONT_SIZE, LEGEND_CAPSULE_PAD, LEGEND_DOT_R, LEGEND_ENTRY_FONT_SIZE, LEGEND_ENTRY_DOT_GAP, LEGEND_ENTRY_TRAIL, LEGEND_GROUP_GAP, LEGEND_EYE_SIZE, LEGEND_EYE_GAP, LEGEND_ICON_W, LEGEND_MAX_ENTRY_ROWS, CHAR_W, DEFAULT_W, EYE_OPEN_PATH, EYE_CLOSED_PATH;
|
|
2105
|
+
var LEGEND_HEIGHT, LEGEND_PILL_PAD, LEGEND_PILL_FONT_SIZE, LEGEND_CAPSULE_PAD, LEGEND_DOT_R, LEGEND_ENTRY_FONT_SIZE, LEGEND_ENTRY_DOT_GAP, LEGEND_ENTRY_TRAIL, LEGEND_GROUP_GAP, LEGEND_EYE_SIZE, LEGEND_EYE_GAP, LEGEND_ICON_W, LEGEND_MAX_ENTRY_ROWS, CHAR_W, DEFAULT_W, EYE_OPEN_PATH, EYE_CLOSED_PATH, CONTROLS_ICON_PATH, LEGEND_TOGGLE_DOT_R, LEGEND_TOGGLE_OFF_OPACITY, LEGEND_GEAR_PILL_W;
|
|
2103
2106
|
var init_legend_constants = __esm({
|
|
2104
2107
|
"src/utils/legend-constants.ts"() {
|
|
2105
2108
|
"use strict";
|
|
@@ -2206,6 +2209,10 @@ var init_legend_constants = __esm({
|
|
|
2206
2209
|
DEFAULT_W = 0.56;
|
|
2207
2210
|
EYE_OPEN_PATH = "M1 7s2.5-5 6-5 6 5 6 5-2.5 5-6 5-6-5-6-5z M7 9.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z";
|
|
2208
2211
|
EYE_CLOSED_PATH = "M2.5 2.5l9 9 M1.5 7s2.2-4 5.5-4c1.2 0 2.2.5 3 1.1 M12.5 7s-2.2 4-5.5 4c-1.2 0-2.2-.5-3-1.1";
|
|
2212
|
+
CONTROLS_ICON_PATH = "M5.6 1.7L8.4 1.7L7.9 3.6L9.5 4.5L10.9 3.1L12.3 5.6L10.4 6.1L10.4 7.9L12.3 8.4L10.9 10.9L9.5 9.5L7.9 10.4L8.4 12.3L5.6 12.3L6.1 10.4L4.5 9.5L3.1 10.9L1.7 8.4L3.6 7.9L3.6 6.1L1.7 5.6L3.1 3.1L4.5 4.5L6.1 3.6ZM5 7a2 2 0 1 0 4 0a2 2 0 1 0-4 0Z";
|
|
2213
|
+
LEGEND_TOGGLE_DOT_R = LEGEND_DOT_R;
|
|
2214
|
+
LEGEND_TOGGLE_OFF_OPACITY = 0.4;
|
|
2215
|
+
LEGEND_GEAR_PILL_W = 14 + LEGEND_PILL_PAD;
|
|
2209
2216
|
}
|
|
2210
2217
|
});
|
|
2211
2218
|
|
|
@@ -2251,13 +2258,13 @@ function capsuleWidth(name, entries, containerWidth, addonWidth = 0) {
|
|
|
2251
2258
|
visibleEntries: entries.length
|
|
2252
2259
|
};
|
|
2253
2260
|
}
|
|
2254
|
-
const rowWidth = maxCapsuleW - LEGEND_CAPSULE_PAD
|
|
2261
|
+
const rowWidth = maxCapsuleW - LEGEND_CAPSULE_PAD;
|
|
2255
2262
|
let row = 1;
|
|
2256
|
-
let rowX = pw + 4;
|
|
2263
|
+
let rowX = LEGEND_CAPSULE_PAD + pw + 4 + addonWidth;
|
|
2257
2264
|
let visible = 0;
|
|
2258
2265
|
for (let i = 0; i < entries.length; i++) {
|
|
2259
2266
|
const ew2 = entryWidth(entries[i].value);
|
|
2260
|
-
if (rowX + ew2 > rowWidth &&
|
|
2267
|
+
if (rowX + ew2 > rowWidth && i > 0) {
|
|
2261
2268
|
row++;
|
|
2262
2269
|
rowX = 0;
|
|
2263
2270
|
if (row > LEGEND_MAX_ENTRY_ROWS) {
|
|
@@ -2279,6 +2286,63 @@ function capsuleWidth(name, entries, containerWidth, addonWidth = 0) {
|
|
|
2279
2286
|
visibleEntries: entries.length
|
|
2280
2287
|
};
|
|
2281
2288
|
}
|
|
2289
|
+
function controlsGroupCapsuleWidth(toggles) {
|
|
2290
|
+
let w = LEGEND_CAPSULE_PAD * 2 + LEGEND_GEAR_PILL_W + 4;
|
|
2291
|
+
for (const t of toggles) {
|
|
2292
|
+
w += LEGEND_TOGGLE_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(t.label, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
2293
|
+
}
|
|
2294
|
+
return w;
|
|
2295
|
+
}
|
|
2296
|
+
function buildControlsGroupLayout(config, state) {
|
|
2297
|
+
const cg = config.controlsGroup;
|
|
2298
|
+
if (!cg || cg.toggles.length === 0) return void 0;
|
|
2299
|
+
const expanded = !!state.controlsExpanded;
|
|
2300
|
+
const pillH = LEGEND_HEIGHT - LEGEND_CAPSULE_PAD * 2;
|
|
2301
|
+
if (!expanded) {
|
|
2302
|
+
return {
|
|
2303
|
+
x: 0,
|
|
2304
|
+
y: 0,
|
|
2305
|
+
width: LEGEND_GEAR_PILL_W,
|
|
2306
|
+
height: LEGEND_HEIGHT,
|
|
2307
|
+
expanded: false,
|
|
2308
|
+
pill: { x: 0, y: 0, width: LEGEND_GEAR_PILL_W, height: LEGEND_HEIGHT },
|
|
2309
|
+
toggles: []
|
|
2310
|
+
};
|
|
2311
|
+
}
|
|
2312
|
+
const capsuleW = controlsGroupCapsuleWidth(cg.toggles);
|
|
2313
|
+
const toggleLayouts = [];
|
|
2314
|
+
let tx = LEGEND_CAPSULE_PAD + LEGEND_GEAR_PILL_W + 4;
|
|
2315
|
+
for (const toggle of cg.toggles) {
|
|
2316
|
+
const dotCx = tx + LEGEND_TOGGLE_DOT_R;
|
|
2317
|
+
const dotCy = LEGEND_HEIGHT / 2;
|
|
2318
|
+
const textX = tx + LEGEND_TOGGLE_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP;
|
|
2319
|
+
const textY = LEGEND_HEIGHT / 2;
|
|
2320
|
+
toggleLayouts.push({
|
|
2321
|
+
id: toggle.id,
|
|
2322
|
+
label: toggle.label,
|
|
2323
|
+
active: toggle.active,
|
|
2324
|
+
dotCx,
|
|
2325
|
+
dotCy,
|
|
2326
|
+
textX,
|
|
2327
|
+
textY
|
|
2328
|
+
});
|
|
2329
|
+
tx += LEGEND_TOGGLE_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(toggle.label, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
2330
|
+
}
|
|
2331
|
+
return {
|
|
2332
|
+
x: 0,
|
|
2333
|
+
y: 0,
|
|
2334
|
+
width: capsuleW,
|
|
2335
|
+
height: LEGEND_HEIGHT,
|
|
2336
|
+
expanded: true,
|
|
2337
|
+
pill: {
|
|
2338
|
+
x: LEGEND_CAPSULE_PAD,
|
|
2339
|
+
y: LEGEND_CAPSULE_PAD,
|
|
2340
|
+
width: LEGEND_GEAR_PILL_W - LEGEND_CAPSULE_PAD * 2,
|
|
2341
|
+
height: pillH
|
|
2342
|
+
},
|
|
2343
|
+
toggles: toggleLayouts
|
|
2344
|
+
};
|
|
2345
|
+
}
|
|
2282
2346
|
function computeLegendLayout(config, state, containerWidth) {
|
|
2283
2347
|
const { groups, controls: configControls, mode } = config;
|
|
2284
2348
|
const isExport = mode === "inline";
|
|
@@ -2293,8 +2357,9 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2293
2357
|
activeCapsule: void 0
|
|
2294
2358
|
};
|
|
2295
2359
|
}
|
|
2360
|
+
const controlsGroupLayout = isExport ? void 0 : buildControlsGroupLayout(config, state);
|
|
2296
2361
|
const visibleGroups = config.showEmptyGroups ? groups : groups.filter((g) => g.entries.length > 0);
|
|
2297
|
-
if (visibleGroups.length === 0 && (!configControls || configControls.length === 0)) {
|
|
2362
|
+
if (visibleGroups.length === 0 && (!configControls || configControls.length === 0) && !controlsGroupLayout) {
|
|
2298
2363
|
return {
|
|
2299
2364
|
height: 0,
|
|
2300
2365
|
width: 0,
|
|
@@ -2358,7 +2423,8 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2358
2423
|
if (totalControlsW > 0) totalControlsW -= CONTROL_GAP;
|
|
2359
2424
|
}
|
|
2360
2425
|
const controlsSpace = totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0;
|
|
2361
|
-
const
|
|
2426
|
+
const gearSpace = controlsGroupLayout ? controlsGroupLayout.width + LEGEND_GROUP_GAP : 0;
|
|
2427
|
+
const groupAvailW = containerWidth - controlsSpace - gearSpace;
|
|
2362
2428
|
const pills = [];
|
|
2363
2429
|
let activeCapsule;
|
|
2364
2430
|
for (const g of visibleGroups) {
|
|
@@ -2367,7 +2433,7 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2367
2433
|
if (isActive) {
|
|
2368
2434
|
activeCapsule = buildCapsuleLayout(
|
|
2369
2435
|
g,
|
|
2370
|
-
|
|
2436
|
+
groupAvailW,
|
|
2371
2437
|
config.capsulePillAddonWidth ?? 0
|
|
2372
2438
|
);
|
|
2373
2439
|
} else {
|
|
@@ -2390,7 +2456,8 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2390
2456
|
groupAvailW,
|
|
2391
2457
|
containerWidth,
|
|
2392
2458
|
totalControlsW,
|
|
2393
|
-
alignLeft
|
|
2459
|
+
alignLeft,
|
|
2460
|
+
controlsGroupLayout
|
|
2394
2461
|
);
|
|
2395
2462
|
const height = rows.length * LEGEND_HEIGHT;
|
|
2396
2463
|
const width = containerWidth;
|
|
@@ -2400,7 +2467,8 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2400
2467
|
rows,
|
|
2401
2468
|
activeCapsule,
|
|
2402
2469
|
controls: controlLayouts,
|
|
2403
|
-
pills
|
|
2470
|
+
pills,
|
|
2471
|
+
controlsGroup: controlsGroupLayout
|
|
2404
2472
|
};
|
|
2405
2473
|
}
|
|
2406
2474
|
function buildCapsuleLayout(group, containerWidth, addonWidth = 0) {
|
|
@@ -2423,7 +2491,7 @@ function buildCapsuleLayout(group, containerWidth, addonWidth = 0) {
|
|
|
2423
2491
|
let ex = LEGEND_CAPSULE_PAD + pw + 4 + addonWidth;
|
|
2424
2492
|
let ey = 0;
|
|
2425
2493
|
let rowX = ex;
|
|
2426
|
-
const maxRowW = containerWidth - LEGEND_CAPSULE_PAD
|
|
2494
|
+
const maxRowW = containerWidth - LEGEND_CAPSULE_PAD;
|
|
2427
2495
|
let currentRow = 0;
|
|
2428
2496
|
for (let i = 0; i < info.visibleEntries; i++) {
|
|
2429
2497
|
const entry = group.entries[i];
|
|
@@ -2464,19 +2532,27 @@ function buildCapsuleLayout(group, containerWidth, addonWidth = 0) {
|
|
|
2464
2532
|
addonX: addonWidth > 0 ? LEGEND_CAPSULE_PAD + pw + 4 : void 0
|
|
2465
2533
|
};
|
|
2466
2534
|
}
|
|
2467
|
-
function layoutRows(activeCapsule, pills, controls, groupAvailW, containerWidth, totalControlsW, alignLeft = false) {
|
|
2535
|
+
function layoutRows(activeCapsule, pills, controls, groupAvailW, containerWidth, totalControlsW, alignLeft = false, controlsGroup) {
|
|
2468
2536
|
const rows = [];
|
|
2469
2537
|
const groupItems = [];
|
|
2470
2538
|
if (activeCapsule) groupItems.push(activeCapsule);
|
|
2471
2539
|
groupItems.push(...pills);
|
|
2540
|
+
const gearW = controlsGroup ? controlsGroup.width + LEGEND_GROUP_GAP : 0;
|
|
2472
2541
|
let currentRowItems = [];
|
|
2473
2542
|
let currentRowW = 0;
|
|
2474
2543
|
let rowY = 0;
|
|
2475
2544
|
for (const item of groupItems) {
|
|
2476
2545
|
const itemW = item.width + LEGEND_GROUP_GAP;
|
|
2477
2546
|
if (currentRowW + item.width > groupAvailW && currentRowItems.length > 0) {
|
|
2478
|
-
if (!alignLeft)
|
|
2479
|
-
|
|
2547
|
+
if (!alignLeft) {
|
|
2548
|
+
const rowGearW = rows.length === 0 ? gearW : 0;
|
|
2549
|
+
centerRowItems(
|
|
2550
|
+
currentRowItems,
|
|
2551
|
+
containerWidth,
|
|
2552
|
+
totalControlsW,
|
|
2553
|
+
rowGearW
|
|
2554
|
+
);
|
|
2555
|
+
}
|
|
2480
2556
|
rows.push({ y: rowY, items: currentRowItems });
|
|
2481
2557
|
rowY += LEGEND_HEIGHT;
|
|
2482
2558
|
currentRowItems = [];
|
|
@@ -2504,19 +2580,32 @@ function layoutRows(activeCapsule, pills, controls, groupAvailW, containerWidth,
|
|
|
2504
2580
|
}
|
|
2505
2581
|
}
|
|
2506
2582
|
if (currentRowItems.length > 0) {
|
|
2507
|
-
centerRowItems(currentRowItems, containerWidth, totalControlsW);
|
|
2583
|
+
centerRowItems(currentRowItems, containerWidth, totalControlsW, gearW);
|
|
2508
2584
|
rows.push({ y: rowY, items: currentRowItems });
|
|
2509
2585
|
}
|
|
2586
|
+
if (controlsGroup) {
|
|
2587
|
+
const row0Items = rows[0]?.items ?? [];
|
|
2588
|
+
const groupItemsInRow0 = row0Items.filter(
|
|
2589
|
+
(it) => "groupName" in it
|
|
2590
|
+
);
|
|
2591
|
+
if (groupItemsInRow0.length > 0) {
|
|
2592
|
+
const last = groupItemsInRow0[groupItemsInRow0.length - 1];
|
|
2593
|
+
controlsGroup.x = last.x + last.width + LEGEND_GROUP_GAP;
|
|
2594
|
+
} else {
|
|
2595
|
+
controlsGroup.x = 0;
|
|
2596
|
+
}
|
|
2597
|
+
controlsGroup.y = 0;
|
|
2598
|
+
}
|
|
2510
2599
|
if (rows.length === 0) {
|
|
2511
2600
|
rows.push({ y: 0, items: [] });
|
|
2512
2601
|
}
|
|
2513
2602
|
return rows;
|
|
2514
2603
|
}
|
|
2515
|
-
function centerRowItems(items, containerWidth, totalControlsW) {
|
|
2604
|
+
function centerRowItems(items, containerWidth, totalControlsW, controlsGroupW = 0) {
|
|
2516
2605
|
const groupItems = items.filter((it) => "groupName" in it);
|
|
2517
2606
|
if (groupItems.length === 0) return;
|
|
2518
2607
|
const totalGroupW = groupItems.reduce((s, it) => s + it.width, 0) + (groupItems.length - 1) * LEGEND_GROUP_GAP;
|
|
2519
|
-
const availW = containerWidth - (totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0);
|
|
2608
|
+
const availW = containerWidth - (totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0) - controlsGroupW;
|
|
2520
2609
|
const offset = Math.max(0, (availW - totalGroupW) / 2);
|
|
2521
2610
|
let x = offset;
|
|
2522
2611
|
for (const item of groupItems) {
|
|
@@ -2574,6 +2663,17 @@ function renderLegendD3(container, config, state, palette, isDark, callbacks, co
|
|
|
2574
2663
|
for (const pill of currentLayout.pills) {
|
|
2575
2664
|
renderPill(legendG, pill, palette, groupBg, callbacks);
|
|
2576
2665
|
}
|
|
2666
|
+
if (currentLayout.controlsGroup) {
|
|
2667
|
+
renderControlsGroup(
|
|
2668
|
+
legendG,
|
|
2669
|
+
currentLayout.controlsGroup,
|
|
2670
|
+
palette,
|
|
2671
|
+
groupBg,
|
|
2672
|
+
pillBorder,
|
|
2673
|
+
callbacks,
|
|
2674
|
+
config
|
|
2675
|
+
);
|
|
2676
|
+
}
|
|
2577
2677
|
for (const ctrl of currentLayout.controls) {
|
|
2578
2678
|
renderControl(
|
|
2579
2679
|
legendG,
|
|
@@ -2688,6 +2788,57 @@ function renderControl(parent, ctrl, palette, _groupBg, pillBorder, _isDark, con
|
|
|
2688
2788
|
g.on("click", () => onClick());
|
|
2689
2789
|
}
|
|
2690
2790
|
}
|
|
2791
|
+
function renderControlsGroup(parent, layout, palette, groupBg, pillBorder, callbacks, config) {
|
|
2792
|
+
const g = parent.append("g").attr("transform", `translate(${layout.x},${layout.y})`).attr("data-legend-controls", layout.expanded ? "expanded" : "collapsed").attr("data-export-ignore", "true").style("cursor", "pointer");
|
|
2793
|
+
if (!layout.expanded) {
|
|
2794
|
+
g.append("rect").attr("width", layout.width).attr("height", layout.height).attr("rx", layout.height / 2).attr("fill", groupBg);
|
|
2795
|
+
const iconSize = 14;
|
|
2796
|
+
const iconX = (layout.width - iconSize) / 2;
|
|
2797
|
+
const iconY = (layout.height - iconSize) / 2;
|
|
2798
|
+
g.append("path").attr("d", CONTROLS_ICON_PATH).attr("transform", `translate(${iconX},${iconY})`).attr("fill", palette.textMuted).attr("fill-rule", "evenodd").attr("pointer-events", "none");
|
|
2799
|
+
if (callbacks?.onControlsExpand) {
|
|
2800
|
+
const cb = callbacks.onControlsExpand;
|
|
2801
|
+
g.on("click", () => cb());
|
|
2802
|
+
}
|
|
2803
|
+
} else {
|
|
2804
|
+
const pill = layout.pill;
|
|
2805
|
+
g.append("rect").attr("width", layout.width).attr("height", layout.height).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
2806
|
+
const pillG = g.append("g").attr("class", "controls-gear-pill").style("cursor", "pointer");
|
|
2807
|
+
pillG.append("rect").attr("x", pill.x).attr("y", pill.y).attr("width", pill.width).attr("height", pill.height).attr("rx", pill.height / 2).attr("fill", palette.bg);
|
|
2808
|
+
pillG.append("rect").attr("x", pill.x).attr("y", pill.y).attr("width", pill.width).attr("height", pill.height).attr("rx", pill.height / 2).attr("fill", "none").attr("stroke", pillBorder).attr("stroke-width", 0.75);
|
|
2809
|
+
const iconSize = 14;
|
|
2810
|
+
const iconX = pill.x + (pill.width - iconSize) / 2;
|
|
2811
|
+
const iconY = pill.y + (pill.height - iconSize) / 2;
|
|
2812
|
+
pillG.append("path").attr("d", CONTROLS_ICON_PATH).attr("transform", `translate(${iconX},${iconY})`).attr("fill", palette.text).attr("fill-rule", "evenodd").attr("pointer-events", "none");
|
|
2813
|
+
if (callbacks?.onControlsExpand) {
|
|
2814
|
+
const cb = callbacks.onControlsExpand;
|
|
2815
|
+
pillG.on("click", (event) => {
|
|
2816
|
+
event.stopPropagation();
|
|
2817
|
+
cb();
|
|
2818
|
+
});
|
|
2819
|
+
}
|
|
2820
|
+
const toggles = config?.controlsGroup?.toggles ?? [];
|
|
2821
|
+
for (const tl of layout.toggles) {
|
|
2822
|
+
const toggle = toggles.find((t) => t.id === tl.id);
|
|
2823
|
+
const entryG = g.append("g").attr("data-controls-toggle", tl.id).style("cursor", "pointer");
|
|
2824
|
+
if (tl.active) {
|
|
2825
|
+
entryG.append("circle").attr("cx", tl.dotCx).attr("cy", tl.dotCy).attr("r", LEGEND_TOGGLE_DOT_R).attr("fill", palette.primary ?? palette.text);
|
|
2826
|
+
} else {
|
|
2827
|
+
entryG.append("circle").attr("cx", tl.dotCx).attr("cy", tl.dotCy).attr("r", LEGEND_TOGGLE_DOT_R).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1);
|
|
2828
|
+
}
|
|
2829
|
+
entryG.append("text").attr("x", tl.textX).attr("y", tl.textY).attr("dominant-baseline", "central").attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).attr("opacity", tl.active ? 1 : LEGEND_TOGGLE_OFF_OPACITY).attr("font-family", FONT_FAMILY).text(tl.label);
|
|
2830
|
+
if (callbacks?.onControlsToggle && toggle) {
|
|
2831
|
+
const cb = callbacks.onControlsToggle;
|
|
2832
|
+
const id = tl.id;
|
|
2833
|
+
const newActive = !tl.active;
|
|
2834
|
+
entryG.on("click", (event) => {
|
|
2835
|
+
event.stopPropagation();
|
|
2836
|
+
cb(id, newActive);
|
|
2837
|
+
});
|
|
2838
|
+
}
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
}
|
|
2691
2842
|
var init_legend_d3 = __esm({
|
|
2692
2843
|
"src/utils/legend-d3.ts"() {
|
|
2693
2844
|
"use strict";
|
|
@@ -3241,7 +3392,13 @@ function parseSequenceDgmo(content) {
|
|
|
3241
3392
|
const groupName = groupMatch[1].trim();
|
|
3242
3393
|
const groupColor = groupMatch[2]?.trim();
|
|
3243
3394
|
let groupMeta;
|
|
3244
|
-
|
|
3395
|
+
let afterBracket = groupMatch[3]?.trim() || "";
|
|
3396
|
+
let isCollapsed = false;
|
|
3397
|
+
const collapseMatch = afterBracket.match(/^collapse\b/i);
|
|
3398
|
+
if (collapseMatch) {
|
|
3399
|
+
isCollapsed = true;
|
|
3400
|
+
afterBracket = afterBracket.slice(collapseMatch[0].length).trim();
|
|
3401
|
+
}
|
|
3245
3402
|
if (afterBracket.startsWith("|")) {
|
|
3246
3403
|
const segments = afterBracket.split("|");
|
|
3247
3404
|
const meta = parsePipeMetadata(
|
|
@@ -3262,7 +3419,8 @@ function parseSequenceDgmo(content) {
|
|
|
3262
3419
|
name: groupName,
|
|
3263
3420
|
participantIds: [],
|
|
3264
3421
|
lineNumber,
|
|
3265
|
-
...groupMeta ? { metadata: groupMeta } : {}
|
|
3422
|
+
...groupMeta ? { metadata: groupMeta } : {},
|
|
3423
|
+
...isCollapsed ? { collapsed: true } : {}
|
|
3266
3424
|
};
|
|
3267
3425
|
result.groups.push(activeGroup);
|
|
3268
3426
|
continue;
|
|
@@ -10359,7 +10517,7 @@ function addBusinessDays(startDate, count, workweek, holidaySet, direction = 1)
|
|
|
10359
10517
|
}
|
|
10360
10518
|
return current;
|
|
10361
10519
|
}
|
|
10362
|
-
function addGanttDuration(startDate, duration, holidays, holidaySet, direction = 1) {
|
|
10520
|
+
function addGanttDuration(startDate, duration, holidays, holidaySet, direction = 1, opts) {
|
|
10363
10521
|
const { amount, unit } = duration;
|
|
10364
10522
|
switch (unit) {
|
|
10365
10523
|
case "bd":
|
|
@@ -10421,10 +10579,22 @@ function addGanttDuration(startDate, duration, holidays, holidaySet, direction =
|
|
|
10421
10579
|
result.setTime(result.getTime() + amount * 6e4 * direction);
|
|
10422
10580
|
return result;
|
|
10423
10581
|
}
|
|
10582
|
+
case "s": {
|
|
10583
|
+
if (!opts?.sprintLength) {
|
|
10584
|
+
throw new Error(
|
|
10585
|
+
'Sprint duration unit "s" requires sprintLength configuration'
|
|
10586
|
+
);
|
|
10587
|
+
}
|
|
10588
|
+
const sl = opts.sprintLength;
|
|
10589
|
+
const totalDays = amount * sl.amount * (sl.unit === "w" ? 7 : 1);
|
|
10590
|
+
const result = new Date(startDate);
|
|
10591
|
+
result.setDate(result.getDate() + Math.round(totalDays) * direction);
|
|
10592
|
+
return result;
|
|
10593
|
+
}
|
|
10424
10594
|
}
|
|
10425
10595
|
}
|
|
10426
10596
|
function parseDuration(s) {
|
|
10427
|
-
const match = s.trim().match(/^(\d+(?:\.\d+)?)(min|bd|d|w|m|q|y|h)$/);
|
|
10597
|
+
const match = s.trim().match(/^(\d+(?:\.\d+)?)(min|bd|d|w|m|q|y|h|s)$/);
|
|
10428
10598
|
if (!match) return null;
|
|
10429
10599
|
return { amount: parseFloat(match[1]), unit: match[2] };
|
|
10430
10600
|
}
|
|
@@ -10511,7 +10681,11 @@ function parseGantt(content, palette) {
|
|
|
10511
10681
|
defaultSwimlaneGroup: null,
|
|
10512
10682
|
activeTag: null,
|
|
10513
10683
|
optionLineNumbers: {},
|
|
10514
|
-
holidaysLineNumber: null
|
|
10684
|
+
holidaysLineNumber: null,
|
|
10685
|
+
sprintLength: null,
|
|
10686
|
+
sprintNumber: null,
|
|
10687
|
+
sprintStart: null,
|
|
10688
|
+
sprintMode: null
|
|
10515
10689
|
},
|
|
10516
10690
|
diagnostics,
|
|
10517
10691
|
error: null
|
|
@@ -10927,6 +11101,55 @@ function parseGantt(content, palette) {
|
|
|
10927
11101
|
case "active-tag":
|
|
10928
11102
|
result.options.activeTag = value;
|
|
10929
11103
|
break;
|
|
11104
|
+
case "sprint-length": {
|
|
11105
|
+
const dur = parseDuration(value);
|
|
11106
|
+
if (!dur) {
|
|
11107
|
+
warn(
|
|
11108
|
+
lineNumber,
|
|
11109
|
+
`Invalid sprint-length value: "${value}". Expected a duration like "2w" or "10d".`
|
|
11110
|
+
);
|
|
11111
|
+
} else if (dur.unit !== "d" && dur.unit !== "w") {
|
|
11112
|
+
warn(
|
|
11113
|
+
lineNumber,
|
|
11114
|
+
`sprint-length only accepts "d" or "w" units, got "${dur.unit}".`
|
|
11115
|
+
);
|
|
11116
|
+
} else if (dur.amount <= 0) {
|
|
11117
|
+
warn(lineNumber, `sprint-length must be greater than 0.`);
|
|
11118
|
+
} else if (!Number.isInteger(dur.amount * (dur.unit === "w" ? 7 : 1))) {
|
|
11119
|
+
warn(
|
|
11120
|
+
lineNumber,
|
|
11121
|
+
`sprint-length must resolve to a whole number of days.`
|
|
11122
|
+
);
|
|
11123
|
+
} else {
|
|
11124
|
+
result.options.sprintLength = dur;
|
|
11125
|
+
}
|
|
11126
|
+
break;
|
|
11127
|
+
}
|
|
11128
|
+
case "sprint-number": {
|
|
11129
|
+
const n = Number(value);
|
|
11130
|
+
if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) {
|
|
11131
|
+
warn(
|
|
11132
|
+
lineNumber,
|
|
11133
|
+
`sprint-number must be a positive integer, got "${value}".`
|
|
11134
|
+
);
|
|
11135
|
+
} else {
|
|
11136
|
+
result.options.sprintNumber = n;
|
|
11137
|
+
}
|
|
11138
|
+
break;
|
|
11139
|
+
}
|
|
11140
|
+
case "sprint-start": {
|
|
11141
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
11142
|
+
warn(
|
|
11143
|
+
lineNumber,
|
|
11144
|
+
`sprint-start requires a full date (YYYY-MM-DD), got "${value}".`
|
|
11145
|
+
);
|
|
11146
|
+
} else if (Number.isNaN((/* @__PURE__ */ new Date(value + "T00:00:00")).getTime())) {
|
|
11147
|
+
warn(lineNumber, `sprint-start is not a valid date: "${value}".`);
|
|
11148
|
+
} else {
|
|
11149
|
+
result.options.sprintStart = value;
|
|
11150
|
+
}
|
|
11151
|
+
break;
|
|
11152
|
+
}
|
|
10930
11153
|
}
|
|
10931
11154
|
continue;
|
|
10932
11155
|
}
|
|
@@ -11107,6 +11330,21 @@ function parseGantt(content, palette) {
|
|
|
11107
11330
|
result.options.sort = "default";
|
|
11108
11331
|
}
|
|
11109
11332
|
validateTagGroupNames(result.tagGroups, warn);
|
|
11333
|
+
const hasSprintOption = result.options.sprintLength !== null || result.options.sprintNumber !== null || result.options.sprintStart !== null;
|
|
11334
|
+
const hasSprintUnit = hasSprintDurationUnit(result.nodes);
|
|
11335
|
+
if (hasSprintOption) {
|
|
11336
|
+
result.options.sprintMode = "explicit";
|
|
11337
|
+
} else if (hasSprintUnit) {
|
|
11338
|
+
result.options.sprintMode = "auto";
|
|
11339
|
+
}
|
|
11340
|
+
if (result.options.sprintMode) {
|
|
11341
|
+
if (!result.options.sprintLength) {
|
|
11342
|
+
result.options.sprintLength = { amount: 2, unit: "w" };
|
|
11343
|
+
}
|
|
11344
|
+
if (result.options.sprintNumber === null) {
|
|
11345
|
+
result.options.sprintNumber = 1;
|
|
11346
|
+
}
|
|
11347
|
+
}
|
|
11110
11348
|
return result;
|
|
11111
11349
|
function makeTask(labelRaw, duration, uncertain, ln, explicitStart) {
|
|
11112
11350
|
const segments = labelRaw.split("|");
|
|
@@ -11224,6 +11462,16 @@ function parseWorkweek(s) {
|
|
|
11224
11462
|
function isKnownOption(key) {
|
|
11225
11463
|
return KNOWN_OPTIONS5.has(key);
|
|
11226
11464
|
}
|
|
11465
|
+
function hasSprintDurationUnit(nodes) {
|
|
11466
|
+
for (const node of nodes) {
|
|
11467
|
+
if (node.kind === "task") {
|
|
11468
|
+
if (node.duration?.unit === "s") return true;
|
|
11469
|
+
} else if (node.kind === "group" || node.kind === "parallel") {
|
|
11470
|
+
if (hasSprintDurationUnit(node.children)) return true;
|
|
11471
|
+
}
|
|
11472
|
+
}
|
|
11473
|
+
return false;
|
|
11474
|
+
}
|
|
11227
11475
|
var DURATION_RE, EXPLICIT_DATE_RE, TIMELINE_DURATION_RE, GROUP_RE2, DEPENDENCY_RE, COMMENT_RE, ERA_RE, MARKER_RE, HOLIDAY_DATE_RE, HOLIDAY_RANGE_RE, WORKWEEK_RE, ERA_ENTRY_RE, MARKER_ENTRY_RE, WEEKDAY_MAP, KNOWN_OPTIONS5, KNOWN_BOOLEANS4;
|
|
11228
11476
|
var init_parser9 = __esm({
|
|
11229
11477
|
"src/gantt/parser.ts"() {
|
|
@@ -11233,9 +11481,9 @@ var init_parser9 = __esm({
|
|
|
11233
11481
|
init_parsing();
|
|
11234
11482
|
init_duration();
|
|
11235
11483
|
init_palettes();
|
|
11236
|
-
DURATION_RE = /^(\d+(?:\.\d+)?)(min|bd|d|w|m|q|y|h)(\?)?\s+(.+)$/;
|
|
11484
|
+
DURATION_RE = /^(\d+(?:\.\d+)?)(min|bd|d|w|m|q|y|h|s)(\?)?\s+(.+)$/;
|
|
11237
11485
|
EXPLICIT_DATE_RE = /^(\d{4}-\d{2}-\d{2}(?: \d{2}:\d{2})?)\s+(.+)$/;
|
|
11238
|
-
TIMELINE_DURATION_RE = /^(\d{4}-\d{2}-\d{2}(?: \d{2}:\d{2})?)\s*(?:->|\u2013>)\s*(\d+(?:\.\d+)?)(min|bd|d|w|m|q|y|h)(\?)?\s+(.+)$/;
|
|
11486
|
+
TIMELINE_DURATION_RE = /^(\d{4}-\d{2}-\d{2}(?: \d{2}:\d{2})?)\s*(?:->|\u2013>)\s*(\d+(?:\.\d+)?)(min|bd|d|w|m|q|y|h|s)(\?)?\s+(.+)$/;
|
|
11239
11487
|
GROUP_RE2 = /^\[(.+?)\]\s*(.*)$/;
|
|
11240
11488
|
DEPENDENCY_RE = /^(?:-(.+?))?->\s*(.+)$/;
|
|
11241
11489
|
COMMENT_RE = /^\/\//;
|
|
@@ -11270,7 +11518,10 @@ var init_parser9 = __esm({
|
|
|
11270
11518
|
"dependencies",
|
|
11271
11519
|
"chart",
|
|
11272
11520
|
"sort",
|
|
11273
|
-
"active-tag"
|
|
11521
|
+
"active-tag",
|
|
11522
|
+
"sprint-length",
|
|
11523
|
+
"sprint-number",
|
|
11524
|
+
"sprint-start"
|
|
11274
11525
|
]);
|
|
11275
11526
|
KNOWN_BOOLEANS4 = /* @__PURE__ */ new Set([
|
|
11276
11527
|
"critical-path",
|
|
@@ -22667,6 +22918,7 @@ function calculateSchedule(parsed) {
|
|
|
22667
22918
|
tagGroups: parsed.tagGroups,
|
|
22668
22919
|
eras: parsed.eras,
|
|
22669
22920
|
markers: parsed.markers,
|
|
22921
|
+
sprints: [],
|
|
22670
22922
|
options: parsed.options,
|
|
22671
22923
|
diagnostics,
|
|
22672
22924
|
error: parsed.error
|
|
@@ -22688,6 +22940,7 @@ function calculateSchedule(parsed) {
|
|
|
22688
22940
|
} else {
|
|
22689
22941
|
projectStart = new Date(2e3, 0, 1);
|
|
22690
22942
|
}
|
|
22943
|
+
const sprintOpts = parsed.options.sprintLength ? { sprintLength: parsed.options.sprintLength } : void 0;
|
|
22691
22944
|
const depOffsetMap = /* @__PURE__ */ new Map();
|
|
22692
22945
|
const allTasks = collectTasks(parsed.nodes);
|
|
22693
22946
|
if (allTasks.length === 0) {
|
|
@@ -22769,7 +23022,8 @@ function calculateSchedule(parsed) {
|
|
|
22769
23022
|
depOffset.duration,
|
|
22770
23023
|
parsed.holidays,
|
|
22771
23024
|
holidaySet,
|
|
22772
|
-
depOffset.direction
|
|
23025
|
+
depOffset.direction,
|
|
23026
|
+
sprintOpts
|
|
22773
23027
|
);
|
|
22774
23028
|
}
|
|
22775
23029
|
if (predEnd.getTime() > start.getTime()) {
|
|
@@ -22783,7 +23037,8 @@ function calculateSchedule(parsed) {
|
|
|
22783
23037
|
task.offset.duration,
|
|
22784
23038
|
parsed.holidays,
|
|
22785
23039
|
holidaySet,
|
|
22786
|
-
task.offset.direction
|
|
23040
|
+
task.offset.direction,
|
|
23041
|
+
sprintOpts
|
|
22787
23042
|
);
|
|
22788
23043
|
if (start.getTime() < projectStart.getTime()) {
|
|
22789
23044
|
warn(
|
|
@@ -22823,7 +23078,9 @@ function calculateSchedule(parsed) {
|
|
|
22823
23078
|
start,
|
|
22824
23079
|
task.duration,
|
|
22825
23080
|
parsed.holidays,
|
|
22826
|
-
holidaySet
|
|
23081
|
+
holidaySet,
|
|
23082
|
+
1,
|
|
23083
|
+
sprintOpts
|
|
22827
23084
|
);
|
|
22828
23085
|
}
|
|
22829
23086
|
} else {
|
|
@@ -22837,7 +23094,8 @@ function calculateSchedule(parsed) {
|
|
|
22837
23094
|
taskMap,
|
|
22838
23095
|
depOffsetMap,
|
|
22839
23096
|
parsed.holidays,
|
|
22840
|
-
holidaySet
|
|
23097
|
+
holidaySet,
|
|
23098
|
+
sprintOpts
|
|
22841
23099
|
) : /* @__PURE__ */ new Set();
|
|
22842
23100
|
const uncertainSet = /* @__PURE__ */ new Set();
|
|
22843
23101
|
for (const taskId of sortedIds) {
|
|
@@ -22877,6 +23135,20 @@ function calculateSchedule(parsed) {
|
|
|
22877
23135
|
result.startDate = minDate;
|
|
22878
23136
|
result.endDate = maxDate;
|
|
22879
23137
|
}
|
|
23138
|
+
if (parsed.options.sprintMode && parsed.options.sprintLength && result.tasks.length > 0) {
|
|
23139
|
+
result.sprints = generateSprintBands(
|
|
23140
|
+
parsed.options,
|
|
23141
|
+
result.startDate,
|
|
23142
|
+
result.endDate,
|
|
23143
|
+
projectStart
|
|
23144
|
+
);
|
|
23145
|
+
if (result.sprints.length > 0) {
|
|
23146
|
+
const lastSprintEnd = result.sprints[result.sprints.length - 1].endDate;
|
|
23147
|
+
if (lastSprintEnd.getTime() > result.endDate.getTime()) {
|
|
23148
|
+
result.endDate = lastSprintEnd;
|
|
23149
|
+
}
|
|
23150
|
+
}
|
|
23151
|
+
}
|
|
22880
23152
|
const topLevelGroups = parsed.nodes.filter((n) => n.kind === "group");
|
|
22881
23153
|
if (topLevelGroups.length >= 2) {
|
|
22882
23154
|
const names = topLevelGroups.map(
|
|
@@ -23077,7 +23349,7 @@ function breakCycle(cycle, taskMap, depOffsetMap) {
|
|
|
23077
23349
|
}
|
|
23078
23350
|
}
|
|
23079
23351
|
}
|
|
23080
|
-
function computeCriticalPath(sortedIds, taskMap, depOffsetMap, holidays, holidaySet) {
|
|
23352
|
+
function computeCriticalPath(sortedIds, taskMap, depOffsetMap, holidays, holidaySet, sprintOpts) {
|
|
23081
23353
|
if (sortedIds.length === 0) return /* @__PURE__ */ new Set();
|
|
23082
23354
|
const latestEnd = /* @__PURE__ */ new Map();
|
|
23083
23355
|
const latestStart = /* @__PURE__ */ new Map();
|
|
@@ -23115,7 +23387,8 @@ function computeCriticalPath(sortedIds, taskMap, depOffsetMap, holidays, holiday
|
|
|
23115
23387
|
succTask.offset.duration,
|
|
23116
23388
|
holidays,
|
|
23117
23389
|
holidaySet,
|
|
23118
|
-
reverseDir
|
|
23390
|
+
reverseDir,
|
|
23391
|
+
sprintOpts
|
|
23119
23392
|
);
|
|
23120
23393
|
succLS = adjusted.getTime();
|
|
23121
23394
|
}
|
|
@@ -23127,7 +23400,8 @@ function computeCriticalPath(sortedIds, taskMap, depOffsetMap, holidays, holiday
|
|
|
23127
23400
|
depOffset.duration,
|
|
23128
23401
|
holidays,
|
|
23129
23402
|
holidaySet,
|
|
23130
|
-
reverseDir
|
|
23403
|
+
reverseDir,
|
|
23404
|
+
sprintOpts
|
|
23131
23405
|
);
|
|
23132
23406
|
succLS = adjusted.getTime();
|
|
23133
23407
|
}
|
|
@@ -23202,6 +23476,51 @@ function buildResolvedGroups(nodes, taskMap, groups, depth) {
|
|
|
23202
23476
|
}
|
|
23203
23477
|
}
|
|
23204
23478
|
}
|
|
23479
|
+
function generateSprintBands(options, chartStart, chartEnd, projectStart) {
|
|
23480
|
+
const sprintLength = options.sprintLength;
|
|
23481
|
+
const sprintNumber = options.sprintNumber ?? 1;
|
|
23482
|
+
let anchorDate;
|
|
23483
|
+
if (options.sprintStart) {
|
|
23484
|
+
anchorDate = /* @__PURE__ */ new Date(options.sprintStart + "T00:00:00");
|
|
23485
|
+
} else if (options.start) {
|
|
23486
|
+
anchorDate = new Date(projectStart);
|
|
23487
|
+
} else {
|
|
23488
|
+
const now = /* @__PURE__ */ new Date();
|
|
23489
|
+
anchorDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
23490
|
+
}
|
|
23491
|
+
anchorDate.setHours(0, 0, 0, 0);
|
|
23492
|
+
const sprintDays = Math.round(
|
|
23493
|
+
sprintLength.amount * (sprintLength.unit === "w" ? 7 : 1)
|
|
23494
|
+
);
|
|
23495
|
+
if (sprintDays <= 0) return [];
|
|
23496
|
+
if (Number.isNaN(anchorDate.getTime())) return [];
|
|
23497
|
+
const chartStartTime = new Date(chartStart);
|
|
23498
|
+
chartStartTime.setHours(0, 0, 0, 0);
|
|
23499
|
+
const chartEndTime = new Date(chartEnd);
|
|
23500
|
+
chartEndTime.setHours(0, 0, 0, 0);
|
|
23501
|
+
const msPerDay = 864e5;
|
|
23502
|
+
const dayDiff = Math.floor(
|
|
23503
|
+
(chartStartTime.getTime() - anchorDate.getTime()) / msPerDay
|
|
23504
|
+
);
|
|
23505
|
+
const startSprintIndex = Math.floor(dayDiff / sprintDays);
|
|
23506
|
+
const sprints = [];
|
|
23507
|
+
const maxSprints = 1e3;
|
|
23508
|
+
for (let i = startSprintIndex; sprints.length < maxSprints; i++) {
|
|
23509
|
+
const sprintStartDate = new Date(anchorDate);
|
|
23510
|
+
sprintStartDate.setDate(sprintStartDate.getDate() + i * sprintDays);
|
|
23511
|
+
sprintStartDate.setHours(0, 0, 0, 0);
|
|
23512
|
+
const sprintEndDate = new Date(sprintStartDate);
|
|
23513
|
+
sprintEndDate.setDate(sprintEndDate.getDate() + sprintDays);
|
|
23514
|
+
sprintEndDate.setHours(0, 0, 0, 0);
|
|
23515
|
+
if (sprintStartDate.getTime() >= chartEndTime.getTime() + msPerDay) break;
|
|
23516
|
+
sprints.push({
|
|
23517
|
+
number: sprintNumber + i,
|
|
23518
|
+
startDate: sprintStartDate,
|
|
23519
|
+
endDate: sprintEndDate
|
|
23520
|
+
});
|
|
23521
|
+
}
|
|
23522
|
+
return sprints;
|
|
23523
|
+
}
|
|
23205
23524
|
function formatDate(d) {
|
|
23206
23525
|
const y = d.getFullYear();
|
|
23207
23526
|
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
@@ -23285,6 +23604,8 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23285
23604
|
options?.currentActiveGroup
|
|
23286
23605
|
);
|
|
23287
23606
|
let criticalPathActive = false;
|
|
23607
|
+
let dependenciesActive = !!resolved.options.dependencies;
|
|
23608
|
+
let controlsExpanded = false;
|
|
23288
23609
|
const tagRows = currentSwimlaneGroup ? buildTagLaneRowList(resolved, currentSwimlaneGroup, collapsedLanes) : null;
|
|
23289
23610
|
const rows = tagRows ?? buildRowList(resolved, collapsedGroups);
|
|
23290
23611
|
const isTagMode = tagRows !== null;
|
|
@@ -23301,28 +23622,31 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23301
23622
|
const maxLabelLen = Math.max(...allLabels.map((l) => l.length), 10);
|
|
23302
23623
|
const leftMargin = Math.max(MIN_LEFT_MARGIN, maxLabelLen * 7 + 30);
|
|
23303
23624
|
const totalRows = rows.length;
|
|
23625
|
+
const hasCriticalPath = resolved.options.criticalPath && resolved.tasks.some((t) => t.isCriticalPath);
|
|
23626
|
+
const hasDependencies = resolved.options.dependencies && resolved.tasks.some((t) => t.task.dependencies.length > 0);
|
|
23304
23627
|
const title = resolved.options.title;
|
|
23305
23628
|
const titleHeight = title ? 50 : 20;
|
|
23306
|
-
const tagLegendReserve = resolved.tagGroups.length > 0 ? LEGEND_HEIGHT + 8 : 0;
|
|
23629
|
+
const tagLegendReserve = resolved.tagGroups.length > 0 || hasCriticalPath || hasDependencies ? LEGEND_HEIGHT + 8 : 0;
|
|
23307
23630
|
const topDateLabelReserve = 22;
|
|
23308
23631
|
const hasOverheadLabels = resolved.markers.length > 0 || resolved.eras.length > 0;
|
|
23309
|
-
const markerLabelReserve = hasOverheadLabels ?
|
|
23632
|
+
const markerLabelReserve = hasOverheadLabels ? 28 : 0;
|
|
23633
|
+
const sprintLabelReserve = resolved.sprints.length > 0 ? 16 : 0;
|
|
23310
23634
|
const CONTENT_TOP_PAD = 16;
|
|
23311
|
-
const marginTop = titleHeight + tagLegendReserve + topDateLabelReserve + markerLabelReserve;
|
|
23635
|
+
const marginTop = titleHeight + tagLegendReserve + topDateLabelReserve + markerLabelReserve + sprintLabelReserve;
|
|
23312
23636
|
const contentH = isTagMode ? totalRows * (BAR_H + ROW_GAP) : totalRows * (BAR_H + ROW_GAP) + GROUP_GAP2 * resolved.groups.length;
|
|
23313
23637
|
const innerHeight = CONTENT_TOP_PAD + contentH;
|
|
23314
23638
|
const outerHeight = marginTop + innerHeight + BOTTOM_MARGIN;
|
|
23315
23639
|
const containerWidth = exportDims?.width ?? (container.clientWidth || 800);
|
|
23316
|
-
const
|
|
23640
|
+
const sprintRightPad = resolved.sprints.length > 0 ? 50 : 0;
|
|
23641
|
+
const innerWidth = containerWidth - leftMargin - RIGHT_MARGIN - sprintRightPad;
|
|
23317
23642
|
const svg = d3Selection10.select(container).append("svg").attr("viewBox", `0 0 ${containerWidth} ${outerHeight}`).attr("width", exportDims ? containerWidth : "100%").attr("preserveAspectRatio", "xMidYMin meet").attr("font-family", FONT_FAMILY).style("overflow", "visible");
|
|
23318
23643
|
const g = svg.append("g").attr("transform", `translate(${leftMargin}, ${marginTop})`);
|
|
23319
23644
|
if (title) {
|
|
23320
23645
|
svg.append("text").attr("x", containerWidth / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("fill", palette.text).text(title);
|
|
23321
23646
|
}
|
|
23322
|
-
const hasCriticalPath = resolved.options.criticalPath && resolved.tasks.some((t) => t.isCriticalPath);
|
|
23323
23647
|
function drawLegend() {
|
|
23324
23648
|
svg.selectAll(".gantt-tag-legend-container").remove();
|
|
23325
|
-
if (resolved.tagGroups.length > 0 || hasCriticalPath) {
|
|
23649
|
+
if (resolved.tagGroups.length > 0 || hasCriticalPath || hasDependencies) {
|
|
23326
23650
|
const legendY = titleHeight;
|
|
23327
23651
|
renderTagLegend(
|
|
23328
23652
|
svg,
|
|
@@ -23344,16 +23668,38 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23344
23668
|
recolorBars();
|
|
23345
23669
|
},
|
|
23346
23670
|
() => {
|
|
23347
|
-
|
|
23671
|
+
controlsExpanded = !controlsExpanded;
|
|
23348
23672
|
drawLegend();
|
|
23349
23673
|
},
|
|
23350
23674
|
currentSwimlaneGroup,
|
|
23351
23675
|
onSwimlaneChange,
|
|
23352
23676
|
viewMode,
|
|
23353
|
-
resolved.tasks
|
|
23677
|
+
resolved.tasks,
|
|
23678
|
+
controlsExpanded,
|
|
23679
|
+
hasDependencies,
|
|
23680
|
+
dependenciesActive,
|
|
23681
|
+
(toggleId, active) => {
|
|
23682
|
+
if (toggleId === "critical-path") {
|
|
23683
|
+
criticalPathActive = active;
|
|
23684
|
+
} else if (toggleId === "dependencies") {
|
|
23685
|
+
dependenciesActive = active;
|
|
23686
|
+
g.selectAll(
|
|
23687
|
+
".gantt-dep-arrow, .gantt-dep-arrowhead, .gantt-dep-label"
|
|
23688
|
+
).attr("display", active ? null : "none");
|
|
23689
|
+
}
|
|
23690
|
+
drawLegend();
|
|
23691
|
+
}
|
|
23354
23692
|
);
|
|
23355
23693
|
}
|
|
23356
23694
|
}
|
|
23695
|
+
function restoreHighlight() {
|
|
23696
|
+
if (criticalPathActive) {
|
|
23697
|
+
applyCriticalPathHighlight(svg, g);
|
|
23698
|
+
} else {
|
|
23699
|
+
svg.attr("data-critical-path-active", null);
|
|
23700
|
+
resetHighlight(g, svg);
|
|
23701
|
+
}
|
|
23702
|
+
}
|
|
23357
23703
|
function recolorBars() {
|
|
23358
23704
|
g.selectAll(".gantt-task").each(function() {
|
|
23359
23705
|
const el = d3Selection10.select(this);
|
|
@@ -23393,6 +23739,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23393
23739
|
onClickItem
|
|
23394
23740
|
);
|
|
23395
23741
|
renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette);
|
|
23742
|
+
renderSprintBands(g, svg, resolved, xScale, innerHeight, palette);
|
|
23396
23743
|
let todayDate = null;
|
|
23397
23744
|
let todayX = -1;
|
|
23398
23745
|
const todayColor = palette.accent || "#e74c3c";
|
|
@@ -23478,7 +23825,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23478
23825
|
);
|
|
23479
23826
|
}
|
|
23480
23827
|
}).on("mouseleave", () => {
|
|
23481
|
-
|
|
23828
|
+
restoreHighlight();
|
|
23482
23829
|
hideGanttDateIndicators(g);
|
|
23483
23830
|
});
|
|
23484
23831
|
labelG.append("text").attr("x", labelX).attr("y", marginTop + yOffset + BAR_H / 2).attr("dy", "0.35em").attr("text-anchor", "start").attr("font-size", "11px").attr("font-weight", "bold").attr("fill", laneColor).text(
|
|
@@ -23683,7 +24030,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23683
24030
|
);
|
|
23684
24031
|
g.append("text").attr("class", "gantt-milestone-hover-label").attr("x", mx - MILESTONE_SIZE - 4).attr("y", my).attr("dy", "0.35em").attr("text-anchor", "end").attr("font-size", "10px").attr("fill", barColor).attr("font-weight", "600").text(task.label);
|
|
23685
24032
|
}).on("mouseleave", () => {
|
|
23686
|
-
|
|
24033
|
+
restoreHighlight();
|
|
23687
24034
|
hideGanttDateIndicators(g);
|
|
23688
24035
|
g.selectAll(".gantt-milestone-hover-label").remove();
|
|
23689
24036
|
});
|
|
@@ -23712,11 +24059,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23712
24059
|
);
|
|
23713
24060
|
}).on("mouseleave", () => {
|
|
23714
24061
|
if (resolved.options.dependencies) {
|
|
23715
|
-
|
|
23716
|
-
applyCriticalPathHighlight(svg, g);
|
|
23717
|
-
} else {
|
|
23718
|
-
resetHighlight(g, svg);
|
|
23719
|
-
}
|
|
24062
|
+
restoreHighlight();
|
|
23720
24063
|
}
|
|
23721
24064
|
resetTaskLabels(svg);
|
|
23722
24065
|
hideGanttDateIndicators(g);
|
|
@@ -24031,6 +24374,7 @@ function arrowheadPoints(x, y, size, angle) {
|
|
|
24031
24374
|
return `${x},${y} ${x + size * Math.cos(a1)},${y + size * Math.sin(a1)} ${x + size * Math.cos(a2)},${y + size * Math.sin(a2)}`;
|
|
24032
24375
|
}
|
|
24033
24376
|
function applyCriticalPathHighlight(svg, chartG) {
|
|
24377
|
+
svg.attr("data-critical-path-active", "true");
|
|
24034
24378
|
chartG.selectAll(".gantt-task").each(function() {
|
|
24035
24379
|
const el = d3Selection10.select(this);
|
|
24036
24380
|
el.attr(
|
|
@@ -24083,8 +24427,31 @@ function drawSwimlaneIcon2(parent, x, y, isActive, palette) {
|
|
|
24083
24427
|
}
|
|
24084
24428
|
return iconG;
|
|
24085
24429
|
}
|
|
24086
|
-
function
|
|
24087
|
-
const
|
|
24430
|
+
function buildControlsToggles(hasCriticalPath, criticalPathActive, hasDependencies, dependenciesActive) {
|
|
24431
|
+
const toggles = [];
|
|
24432
|
+
if (hasCriticalPath) {
|
|
24433
|
+
toggles.push({
|
|
24434
|
+
id: "critical-path",
|
|
24435
|
+
type: "toggle",
|
|
24436
|
+
label: "Critical Path",
|
|
24437
|
+
active: criticalPathActive,
|
|
24438
|
+
onToggle: () => {
|
|
24439
|
+
}
|
|
24440
|
+
});
|
|
24441
|
+
}
|
|
24442
|
+
if (hasDependencies) {
|
|
24443
|
+
toggles.push({
|
|
24444
|
+
id: "dependencies",
|
|
24445
|
+
type: "toggle",
|
|
24446
|
+
label: "Dependencies",
|
|
24447
|
+
active: dependenciesActive,
|
|
24448
|
+
onToggle: () => {
|
|
24449
|
+
}
|
|
24450
|
+
});
|
|
24451
|
+
}
|
|
24452
|
+
return toggles;
|
|
24453
|
+
}
|
|
24454
|
+
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) {
|
|
24088
24455
|
let visibleGroups;
|
|
24089
24456
|
if (activeGroupName) {
|
|
24090
24457
|
const activeGroup = tagGroups.filter(
|
|
@@ -24145,16 +24512,17 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24145
24512
|
totalW += groupW;
|
|
24146
24513
|
}
|
|
24147
24514
|
totalW += Math.max(0, (visibleGroups.length - 1) * LEGEND_GROUP_GAP);
|
|
24148
|
-
const
|
|
24149
|
-
const
|
|
24150
|
-
if (hasCriticalPath) {
|
|
24515
|
+
const hasControls = hasCriticalPath || hasDependencies;
|
|
24516
|
+
const controlsToggleLabels = [];
|
|
24517
|
+
if (hasCriticalPath) controlsToggleLabels.push({ label: "Critical Path" });
|
|
24518
|
+
if (hasDependencies) controlsToggleLabels.push({ label: "Dependencies" });
|
|
24519
|
+
if (hasControls) {
|
|
24151
24520
|
if (visibleGroups.length > 0) totalW += LEGEND_GROUP_GAP;
|
|
24152
|
-
totalW +=
|
|
24521
|
+
totalW += controlsExpanded ? controlsGroupCapsuleWidth(controlsToggleLabels) : LEGEND_GEAR_PILL_W;
|
|
24153
24522
|
}
|
|
24154
24523
|
const containerWidth = chartLeftMargin + chartInnerWidth + RIGHT_MARGIN;
|
|
24155
24524
|
const legendX = (containerWidth - totalW) / 2;
|
|
24156
24525
|
const legendRow = svg.append("g").attr("class", "gantt-tag-legend-container").attr("transform", `translate(${legendX}, ${legendY})`);
|
|
24157
|
-
let cursorX = 0;
|
|
24158
24526
|
if (visibleGroups.length > 0) {
|
|
24159
24527
|
const showIcon = !legendViewMode && tagGroups.length > 0;
|
|
24160
24528
|
const iconReserve = showIcon ? LEGEND_ICON_W : 0;
|
|
@@ -24166,6 +24534,12 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24166
24534
|
entries: entries.map((e) => ({ value: e.value, color: e.color }))
|
|
24167
24535
|
};
|
|
24168
24536
|
});
|
|
24537
|
+
const controlsToggles = buildControlsToggles(
|
|
24538
|
+
hasCriticalPath,
|
|
24539
|
+
criticalPathActive,
|
|
24540
|
+
hasDependencies,
|
|
24541
|
+
dependenciesActive
|
|
24542
|
+
);
|
|
24169
24543
|
const legendConfig = {
|
|
24170
24544
|
groups: legendGroups,
|
|
24171
24545
|
position: {
|
|
@@ -24173,13 +24547,23 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24173
24547
|
titleRelation: "below-title"
|
|
24174
24548
|
},
|
|
24175
24549
|
mode: "fixed",
|
|
24176
|
-
capsulePillAddonWidth: iconReserve
|
|
24550
|
+
capsulePillAddonWidth: iconReserve,
|
|
24551
|
+
controlsGroup: controlsToggles.length > 0 ? { toggles: controlsToggles } : void 0
|
|
24177
24552
|
};
|
|
24178
|
-
const legendState = {
|
|
24179
|
-
|
|
24553
|
+
const legendState = {
|
|
24554
|
+
activeGroup: activeGroupName,
|
|
24555
|
+
controlsExpanded
|
|
24556
|
+
};
|
|
24557
|
+
let tagGroupsW = visibleGroups.reduce((s, _, i) => s + groupWidths[i], 0) + Math.max(0, (visibleGroups.length - 1) * LEGEND_GROUP_GAP);
|
|
24558
|
+
if (hasControls) {
|
|
24559
|
+
if (visibleGroups.length > 0) tagGroupsW += LEGEND_GROUP_GAP;
|
|
24560
|
+
tagGroupsW += controlsExpanded ? controlsGroupCapsuleWidth(controlsToggleLabels) : LEGEND_GEAR_PILL_W;
|
|
24561
|
+
}
|
|
24180
24562
|
const tagGroupG = legendRow.append("g");
|
|
24181
24563
|
const legendCallbacks = {
|
|
24182
24564
|
onGroupToggle: onToggle,
|
|
24565
|
+
onControlsExpand: onToggleControlsExpand,
|
|
24566
|
+
onControlsToggle,
|
|
24183
24567
|
onEntryHover: (groupName, entryValue) => {
|
|
24184
24568
|
const tagKey = groupName.toLowerCase();
|
|
24185
24569
|
if (entryValue) {
|
|
@@ -24256,31 +24640,38 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24256
24640
|
legendCallbacks,
|
|
24257
24641
|
tagGroupsW
|
|
24258
24642
|
);
|
|
24259
|
-
|
|
24260
|
-
|
|
24261
|
-
|
|
24643
|
+
} else if (hasControls) {
|
|
24644
|
+
const controlsToggles = buildControlsToggles(
|
|
24645
|
+
hasCriticalPath,
|
|
24646
|
+
criticalPathActive,
|
|
24647
|
+
hasDependencies,
|
|
24648
|
+
dependenciesActive
|
|
24649
|
+
);
|
|
24650
|
+
const legendConfig = {
|
|
24651
|
+
groups: [],
|
|
24652
|
+
position: {
|
|
24653
|
+
placement: "top-center",
|
|
24654
|
+
titleRelation: "below-title"
|
|
24655
|
+
},
|
|
24656
|
+
mode: "fixed",
|
|
24657
|
+
controlsGroup: { toggles: controlsToggles }
|
|
24658
|
+
};
|
|
24659
|
+
const tagGroupG = legendRow.append("g");
|
|
24660
|
+
renderLegendD3(
|
|
24661
|
+
tagGroupG,
|
|
24662
|
+
legendConfig,
|
|
24663
|
+
{ activeGroup: null, controlsExpanded },
|
|
24664
|
+
palette,
|
|
24665
|
+
isDark,
|
|
24666
|
+
{
|
|
24667
|
+
onControlsExpand: onToggleControlsExpand,
|
|
24668
|
+
onControlsToggle
|
|
24669
|
+
},
|
|
24670
|
+
totalW
|
|
24671
|
+
);
|
|
24262
24672
|
}
|
|
24263
|
-
if (
|
|
24264
|
-
|
|
24265
|
-
const cpG = legendRow.append("g").attr("transform", `translate(${cursorX}, 0)`).attr("class", "gantt-legend-critical-path").style("cursor", "pointer").on("click", () => {
|
|
24266
|
-
if (onToggleCriticalPath) onToggleCriticalPath();
|
|
24267
|
-
});
|
|
24268
|
-
if (cpLineNum) cpG.attr("data-line-number", String(cpLineNum));
|
|
24269
|
-
cpG.append("rect").attr("width", cpPillW).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", criticalPathActive ? palette.bg : groupBg);
|
|
24270
|
-
if (criticalPathActive) {
|
|
24271
|
-
cpG.append("rect").attr("width", cpPillW).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
|
|
24272
|
-
}
|
|
24273
|
-
cpG.append("text").attr("x", cpPillW / 2).attr("y", LEGEND_HEIGHT / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("text-anchor", "middle").attr("font-size", `${LEGEND_PILL_FONT_SIZE}px`).attr("font-weight", "500").attr("fill", criticalPathActive ? palette.text : palette.textMuted).text(cpLabel);
|
|
24274
|
-
if (criticalPathActive) {
|
|
24275
|
-
applyCriticalPathHighlight(svg, chartG);
|
|
24276
|
-
}
|
|
24277
|
-
cpG.on("mouseenter", () => {
|
|
24278
|
-
applyCriticalPathHighlight(svg, chartG);
|
|
24279
|
-
}).on("mouseleave", () => {
|
|
24280
|
-
if (!criticalPathActive) {
|
|
24281
|
-
resetHighlightAll(svg, chartG);
|
|
24282
|
-
}
|
|
24283
|
-
});
|
|
24673
|
+
if (criticalPathActive) {
|
|
24674
|
+
applyCriticalPathHighlight(svg, chartG);
|
|
24284
24675
|
}
|
|
24285
24676
|
}
|
|
24286
24677
|
function renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette) {
|
|
@@ -24296,7 +24687,7 @@ function renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette) {
|
|
|
24296
24687
|
const eraEndDate = parseDateStringToDate(era.endDate);
|
|
24297
24688
|
const eraG = g.append("g").attr("class", "gantt-era-group").attr("data-line-number", String(era.lineNumber));
|
|
24298
24689
|
const eraRect = eraG.append("rect").attr("class", "gantt-era").attr("x", sx).attr("y", 0).attr("width", ex - sx).attr("height", innerHeight).attr("fill", color).attr("opacity", baseEraOpacity);
|
|
24299
|
-
eraG.append("text").attr("class", "gantt-era-label").attr("x", (sx + ex) / 2).attr("y", -
|
|
24690
|
+
eraG.append("text").attr("class", "gantt-era-label").attr("x", (sx + ex) / 2).attr("y", -34).attr("text-anchor", "middle").attr("font-size", "10px").attr("fill", color).attr("opacity", 0.7).style("cursor", "pointer").text(era.label);
|
|
24300
24691
|
eraG.on("mouseenter", () => {
|
|
24301
24692
|
g.selectAll(".gantt-task").attr(
|
|
24302
24693
|
"opacity",
|
|
@@ -24342,8 +24733,8 @@ function renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette) {
|
|
|
24342
24733
|
const mx = xScale(parseDateToFractionalYear(marker.date));
|
|
24343
24734
|
const markerDate = parseDateStringToDate(marker.date);
|
|
24344
24735
|
const diamondSize = 5;
|
|
24345
|
-
const labelY = -
|
|
24346
|
-
const diamondY =
|
|
24736
|
+
const labelY = -34;
|
|
24737
|
+
const diamondY = -2;
|
|
24347
24738
|
const markerG = g.append("g").attr("class", "gantt-marker-group").attr("data-line-number", String(marker.lineNumber)).style("cursor", "pointer");
|
|
24348
24739
|
markerG.append("rect").attr("x", mx - 40).attr("y", labelY - 12).attr("width", 80).attr("height", innerHeight - labelY + 12).attr("fill", "transparent").attr("pointer-events", "all");
|
|
24349
24740
|
markerG.append("text").attr("class", "gantt-marker-label").attr("x", mx).attr("y", labelY).attr("text-anchor", "middle").attr("font-size", "11px").attr("font-weight", "600").attr("fill", color).text(marker.label);
|
|
@@ -24403,6 +24794,139 @@ function renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette) {
|
|
|
24403
24794
|
});
|
|
24404
24795
|
}
|
|
24405
24796
|
}
|
|
24797
|
+
function renderSprintBands(g, svg, resolved, xScale, innerHeight, palette) {
|
|
24798
|
+
if (resolved.sprints.length === 0) return;
|
|
24799
|
+
if (resolved.eras.length > 0) return;
|
|
24800
|
+
const bandColor = palette.textMuted || palette.text || "#888";
|
|
24801
|
+
const chartMinX = 0;
|
|
24802
|
+
for (let i = 0; i < resolved.sprints.length; i++) {
|
|
24803
|
+
const sprint = resolved.sprints[i];
|
|
24804
|
+
const rawSx = xScale(dateToFractionalYear(sprint.startDate));
|
|
24805
|
+
const rawEx = xScale(dateToFractionalYear(sprint.endDate));
|
|
24806
|
+
if (rawEx <= rawSx) continue;
|
|
24807
|
+
const sx = Math.max(rawSx, chartMinX);
|
|
24808
|
+
const ex = rawEx;
|
|
24809
|
+
const bandWidth = ex - sx;
|
|
24810
|
+
if (bandWidth <= 0) continue;
|
|
24811
|
+
const sprintG = g.append("g").attr("class", "gantt-sprint-group").style("cursor", "pointer");
|
|
24812
|
+
const sprintRect = sprintG.append("rect").attr("class", "gantt-sprint-band").attr("x", sx).attr("y", 0).attr("width", bandWidth).attr("height", innerHeight).attr("fill", bandColor).attr("opacity", sprint.number % 2 === 0 ? SPRINT_BAND_OPACITY : 0);
|
|
24813
|
+
if (sprint.number % 2 !== 0) {
|
|
24814
|
+
sprintG.append("rect").attr("x", sx).attr("y", 0).attr("width", bandWidth).attr("height", innerHeight).attr("fill", "transparent");
|
|
24815
|
+
}
|
|
24816
|
+
const sprintLabel = sprintG.append("text").attr("class", "gantt-sprint-label").attr("x", (sx + ex) / 2).attr("y", -22).attr("text-anchor", "middle").attr("font-size", "10px").attr("font-weight", "600").attr("fill", bandColor).attr("opacity", 0.4).text(String(sprint.number));
|
|
24817
|
+
if (i > 0 && rawSx >= chartMinX) {
|
|
24818
|
+
sprintG.append("line").attr("class", "gantt-sprint-boundary").attr("x1", sx).attr("y1", -6).attr("x2", sx).attr("y2", innerHeight).attr("stroke", bandColor).attr("stroke-width", 1).attr("stroke-dasharray", "3 3").attr("opacity", SPRINT_BOUNDARY_OPACITY);
|
|
24819
|
+
}
|
|
24820
|
+
const sprintStartMs = sprint.startDate.getTime();
|
|
24821
|
+
const sprintEndMs = sprint.endDate.getTime();
|
|
24822
|
+
const overlappingTaskIds = /* @__PURE__ */ new Set();
|
|
24823
|
+
for (const rt of resolved.tasks) {
|
|
24824
|
+
const taskStart = rt.startDate.getTime();
|
|
24825
|
+
const taskEnd = rt.endDate.getTime();
|
|
24826
|
+
if (taskStart < sprintEndMs && taskEnd > sprintStartMs) {
|
|
24827
|
+
overlappingTaskIds.add(rt.task.id);
|
|
24828
|
+
}
|
|
24829
|
+
if (taskStart === taskEnd && taskStart >= sprintStartMs && taskStart < sprintEndMs) {
|
|
24830
|
+
overlappingTaskIds.add(rt.task.id);
|
|
24831
|
+
}
|
|
24832
|
+
}
|
|
24833
|
+
const overlappingGroupNames = /* @__PURE__ */ new Set();
|
|
24834
|
+
for (const rg of resolved.groups) {
|
|
24835
|
+
const gStart = rg.startDate.getTime();
|
|
24836
|
+
const gEnd = rg.endDate.getTime();
|
|
24837
|
+
if (gStart < sprintEndMs && gEnd > sprintStartMs) {
|
|
24838
|
+
overlappingGroupNames.add(rg.name);
|
|
24839
|
+
}
|
|
24840
|
+
}
|
|
24841
|
+
const baseOpacity = sprint.number % 2 === 0 ? SPRINT_BAND_OPACITY : 0;
|
|
24842
|
+
sprintG.on("mouseenter", () => {
|
|
24843
|
+
g.selectAll(".gantt-task").each(function() {
|
|
24844
|
+
const el = d3Selection10.select(this);
|
|
24845
|
+
const id = el.attr("data-task-id");
|
|
24846
|
+
el.attr(
|
|
24847
|
+
"opacity",
|
|
24848
|
+
id && overlappingTaskIds.has(id) ? 1 : FADE_OPACITY
|
|
24849
|
+
);
|
|
24850
|
+
});
|
|
24851
|
+
g.selectAll(".gantt-milestone").each(function() {
|
|
24852
|
+
const el = d3Selection10.select(this);
|
|
24853
|
+
const id = el.attr("data-task-id");
|
|
24854
|
+
el.attr(
|
|
24855
|
+
"opacity",
|
|
24856
|
+
id && overlappingTaskIds.has(id) ? 1 : FADE_OPACITY
|
|
24857
|
+
);
|
|
24858
|
+
});
|
|
24859
|
+
svg.selectAll(".gantt-task-label").each(function() {
|
|
24860
|
+
const el = d3Selection10.select(this);
|
|
24861
|
+
const id = el.attr("data-task-id");
|
|
24862
|
+
el.attr(
|
|
24863
|
+
"opacity",
|
|
24864
|
+
id && overlappingTaskIds.has(id) ? 1 : FADE_OPACITY
|
|
24865
|
+
);
|
|
24866
|
+
});
|
|
24867
|
+
g.selectAll(
|
|
24868
|
+
".gantt-group-bar, .gantt-group-summary"
|
|
24869
|
+
).each(function() {
|
|
24870
|
+
const el = d3Selection10.select(this);
|
|
24871
|
+
const name = el.attr("data-group");
|
|
24872
|
+
el.attr(
|
|
24873
|
+
"opacity",
|
|
24874
|
+
name && overlappingGroupNames.has(name) ? 1 : FADE_OPACITY
|
|
24875
|
+
);
|
|
24876
|
+
});
|
|
24877
|
+
svg.selectAll(".gantt-group-label").each(function() {
|
|
24878
|
+
const el = d3Selection10.select(this);
|
|
24879
|
+
const name = el.attr("data-group");
|
|
24880
|
+
el.attr(
|
|
24881
|
+
"opacity",
|
|
24882
|
+
name && overlappingGroupNames.has(name) ? 1 : FADE_OPACITY
|
|
24883
|
+
);
|
|
24884
|
+
});
|
|
24885
|
+
svg.selectAll(".gantt-lane-header").attr("opacity", FADE_OPACITY);
|
|
24886
|
+
g.selectAll(
|
|
24887
|
+
".gantt-lane-band, .gantt-lane-accent, .gantt-lane-band-group"
|
|
24888
|
+
).attr("opacity", FADE_OPACITY);
|
|
24889
|
+
g.selectAll(
|
|
24890
|
+
".gantt-dep-arrow, .gantt-dep-arrowhead"
|
|
24891
|
+
).attr("opacity", FADE_OPACITY);
|
|
24892
|
+
g.selectAll(".gantt-marker-group").attr(
|
|
24893
|
+
"opacity",
|
|
24894
|
+
FADE_OPACITY
|
|
24895
|
+
);
|
|
24896
|
+
sprintRect.attr("opacity", SPRINT_HOVER_OPACITY);
|
|
24897
|
+
const startVisible = rawSx >= chartMinX;
|
|
24898
|
+
if (startVisible) {
|
|
24899
|
+
showGanttDateIndicators(
|
|
24900
|
+
g,
|
|
24901
|
+
xScale,
|
|
24902
|
+
sprint.startDate,
|
|
24903
|
+
sprint.endDate,
|
|
24904
|
+
innerHeight,
|
|
24905
|
+
bandColor
|
|
24906
|
+
);
|
|
24907
|
+
} else {
|
|
24908
|
+
showGanttDateIndicators(
|
|
24909
|
+
g,
|
|
24910
|
+
xScale,
|
|
24911
|
+
sprint.endDate,
|
|
24912
|
+
null,
|
|
24913
|
+
innerHeight,
|
|
24914
|
+
bandColor
|
|
24915
|
+
);
|
|
24916
|
+
}
|
|
24917
|
+
const accentColor = palette.accent || palette.text || bandColor;
|
|
24918
|
+
sprintLabel.text(`Sprint ${sprint.number}`).attr("font-size", "13px").attr("font-weight", "700").attr("fill", accentColor).attr("opacity", 1);
|
|
24919
|
+
}).on("mouseleave", () => {
|
|
24920
|
+
resetHighlight(g, svg);
|
|
24921
|
+
sprintRect.attr("opacity", baseOpacity);
|
|
24922
|
+
sprintLabel.text(String(sprint.number)).attr("font-size", "10px").attr("font-weight", "600").attr("fill", bandColor).attr("opacity", 0.4);
|
|
24923
|
+
hideGanttDateIndicators(g);
|
|
24924
|
+
});
|
|
24925
|
+
}
|
|
24926
|
+
const lastSprint = resolved.sprints[resolved.sprints.length - 1];
|
|
24927
|
+
const lastEx = xScale(dateToFractionalYear(lastSprint.endDate));
|
|
24928
|
+
g.append("line").attr("class", "gantt-sprint-boundary").attr("x1", lastEx).attr("y1", -6).attr("x2", lastEx).attr("y2", innerHeight).attr("stroke", bandColor).attr("stroke-width", 1).attr("stroke-dasharray", "3 3").attr("opacity", SPRINT_BOUNDARY_OPACITY);
|
|
24929
|
+
}
|
|
24406
24930
|
function parseDateStringToDate(s) {
|
|
24407
24931
|
const parts = s.split("-").map((p) => parseInt(p, 10));
|
|
24408
24932
|
const year = parts[0];
|
|
@@ -24615,6 +25139,10 @@ function resetTaskLabels(svg) {
|
|
|
24615
25139
|
svg.selectAll(".gantt-task-label").attr("opacity", 1);
|
|
24616
25140
|
}
|
|
24617
25141
|
function resetHighlight(g, svg) {
|
|
25142
|
+
if (svg.attr("data-critical-path-active") === "true") {
|
|
25143
|
+
applyCriticalPathHighlight(svg, g);
|
|
25144
|
+
return;
|
|
25145
|
+
}
|
|
24618
25146
|
g.selectAll(".gantt-task, .gantt-milestone").attr(
|
|
24619
25147
|
"opacity",
|
|
24620
25148
|
1
|
|
@@ -24875,7 +25403,7 @@ function renderTimeScaleHorizontal(g, scale, innerWidth, innerHeight, textColor)
|
|
|
24875
25403
|
g.append("text").attr("class", "gantt-scale-tick").attr("x", tick.pos).attr("y", innerHeight + tickLen + 12).attr("text-anchor", "middle").attr("font-size", "10px").attr("fill", textColor).attr("opacity", opacity).text(tick.label);
|
|
24876
25404
|
}
|
|
24877
25405
|
}
|
|
24878
|
-
var d3Scale, d3Selection10, BAR_H, ROW_GAP, GROUP_GAP2, MILESTONE_SIZE, MIN_LEFT_MARGIN, BOTTOM_MARGIN, RIGHT_MARGIN, CHAR_W2, LABEL_PAD, LABEL_GAP, BAND_ACCENT_W, BAND_RADIUS, bandClipCounter, JS_DAY_TO_WEEKDAY2, ERA_COLORS, FADE_OPACITY, MONTH_ABBR;
|
|
25406
|
+
var d3Scale, d3Selection10, BAR_H, ROW_GAP, GROUP_GAP2, MILESTONE_SIZE, MIN_LEFT_MARGIN, BOTTOM_MARGIN, RIGHT_MARGIN, CHAR_W2, LABEL_PAD, LABEL_GAP, BAND_ACCENT_W, BAND_RADIUS, bandClipCounter, JS_DAY_TO_WEEKDAY2, ERA_COLORS, SPRINT_BAND_OPACITY, SPRINT_HOVER_OPACITY, SPRINT_BOUNDARY_OPACITY, FADE_OPACITY, MONTH_ABBR;
|
|
24879
25407
|
var init_renderer9 = __esm({
|
|
24880
25408
|
"src/gantt/renderer.ts"() {
|
|
24881
25409
|
"use strict";
|
|
@@ -24888,6 +25416,7 @@ var init_renderer9 = __esm({
|
|
|
24888
25416
|
init_d3();
|
|
24889
25417
|
init_legend_constants();
|
|
24890
25418
|
init_legend_d3();
|
|
25419
|
+
init_legend_layout();
|
|
24891
25420
|
init_title_constants();
|
|
24892
25421
|
BAR_H = 22;
|
|
24893
25422
|
ROW_GAP = 6;
|
|
@@ -24912,6 +25441,9 @@ var init_renderer9 = __esm({
|
|
|
24912
25441
|
"sat"
|
|
24913
25442
|
];
|
|
24914
25443
|
ERA_COLORS = ["#5e81ac", "#a3be8c", "#ebcb8b", "#d08770", "#b48ead"];
|
|
25444
|
+
SPRINT_BAND_OPACITY = 0.05;
|
|
25445
|
+
SPRINT_HOVER_OPACITY = 0.12;
|
|
25446
|
+
SPRINT_BOUNDARY_OPACITY = 0.3;
|
|
24915
25447
|
FADE_OPACITY = 0.1;
|
|
24916
25448
|
MONTH_ABBR = [
|
|
24917
25449
|
"Jan",
|
|
@@ -25178,6 +25710,109 @@ var init_state_renderer = __esm({
|
|
|
25178
25710
|
}
|
|
25179
25711
|
});
|
|
25180
25712
|
|
|
25713
|
+
// src/sequence/collapse.ts
|
|
25714
|
+
function applyCollapseProjection(parsed, collapsedGroups) {
|
|
25715
|
+
if (collapsedGroups.size === 0) {
|
|
25716
|
+
return {
|
|
25717
|
+
participants: parsed.participants,
|
|
25718
|
+
messages: parsed.messages,
|
|
25719
|
+
elements: parsed.elements,
|
|
25720
|
+
groups: parsed.groups,
|
|
25721
|
+
collapsedGroupIds: /* @__PURE__ */ new Map()
|
|
25722
|
+
};
|
|
25723
|
+
}
|
|
25724
|
+
const memberToGroup = /* @__PURE__ */ new Map();
|
|
25725
|
+
const collapsedGroupNames = /* @__PURE__ */ new Set();
|
|
25726
|
+
for (const group of parsed.groups) {
|
|
25727
|
+
if (collapsedGroups.has(group.lineNumber)) {
|
|
25728
|
+
collapsedGroupNames.add(group.name);
|
|
25729
|
+
for (const memberId of group.participantIds) {
|
|
25730
|
+
memberToGroup.set(memberId, group.name);
|
|
25731
|
+
}
|
|
25732
|
+
}
|
|
25733
|
+
}
|
|
25734
|
+
const participants = [];
|
|
25735
|
+
const insertedGroups = /* @__PURE__ */ new Set();
|
|
25736
|
+
for (const p of parsed.participants) {
|
|
25737
|
+
const groupName = memberToGroup.get(p.id);
|
|
25738
|
+
if (groupName) {
|
|
25739
|
+
if (!insertedGroups.has(groupName)) {
|
|
25740
|
+
insertedGroups.add(groupName);
|
|
25741
|
+
const group = parsed.groups.find(
|
|
25742
|
+
(g) => g.name === groupName && collapsedGroups.has(g.lineNumber)
|
|
25743
|
+
);
|
|
25744
|
+
participants.push({
|
|
25745
|
+
id: groupName,
|
|
25746
|
+
label: groupName,
|
|
25747
|
+
type: "default",
|
|
25748
|
+
lineNumber: group.lineNumber
|
|
25749
|
+
});
|
|
25750
|
+
}
|
|
25751
|
+
} else if (collapsedGroupNames.has(p.id)) {
|
|
25752
|
+
} else {
|
|
25753
|
+
participants.push(p);
|
|
25754
|
+
}
|
|
25755
|
+
}
|
|
25756
|
+
const remap = (id) => memberToGroup.get(id) ?? id;
|
|
25757
|
+
const messages = parsed.messages.map((msg) => ({
|
|
25758
|
+
...msg,
|
|
25759
|
+
from: remap(msg.from),
|
|
25760
|
+
to: remap(msg.to)
|
|
25761
|
+
}));
|
|
25762
|
+
const elements = remapElements(parsed.elements, memberToGroup);
|
|
25763
|
+
const groups = parsed.groups.filter(
|
|
25764
|
+
(g) => !collapsedGroups.has(g.lineNumber)
|
|
25765
|
+
);
|
|
25766
|
+
return {
|
|
25767
|
+
participants,
|
|
25768
|
+
messages,
|
|
25769
|
+
elements,
|
|
25770
|
+
groups,
|
|
25771
|
+
collapsedGroupIds: memberToGroup
|
|
25772
|
+
};
|
|
25773
|
+
}
|
|
25774
|
+
function remapElements(elements, memberToGroup) {
|
|
25775
|
+
const remap = (id) => memberToGroup.get(id) ?? id;
|
|
25776
|
+
const result = [];
|
|
25777
|
+
for (const el of elements) {
|
|
25778
|
+
if (isSequenceSection(el)) {
|
|
25779
|
+
result.push(el);
|
|
25780
|
+
} else if (isSequenceNote(el)) {
|
|
25781
|
+
result.push({
|
|
25782
|
+
...el,
|
|
25783
|
+
participantId: remap(el.participantId)
|
|
25784
|
+
});
|
|
25785
|
+
} else if (isSequenceBlock(el)) {
|
|
25786
|
+
result.push({
|
|
25787
|
+
...el,
|
|
25788
|
+
children: remapElements(el.children, memberToGroup),
|
|
25789
|
+
elseChildren: remapElements(el.elseChildren, memberToGroup),
|
|
25790
|
+
...el.elseIfBranches ? {
|
|
25791
|
+
elseIfBranches: el.elseIfBranches.map((branch) => ({
|
|
25792
|
+
...branch,
|
|
25793
|
+
children: remapElements(branch.children, memberToGroup)
|
|
25794
|
+
}))
|
|
25795
|
+
} : {}
|
|
25796
|
+
});
|
|
25797
|
+
} else {
|
|
25798
|
+
const msg = el;
|
|
25799
|
+
const from = remap(msg.from);
|
|
25800
|
+
const to = remap(msg.to);
|
|
25801
|
+
if (from === to && from !== msg.from && !msg.label) {
|
|
25802
|
+
continue;
|
|
25803
|
+
}
|
|
25804
|
+
result.push({ ...msg, from, to });
|
|
25805
|
+
}
|
|
25806
|
+
}
|
|
25807
|
+
return result;
|
|
25808
|
+
}
|
|
25809
|
+
var init_collapse3 = __esm({
|
|
25810
|
+
"src/sequence/collapse.ts"() {
|
|
25811
|
+
"use strict";
|
|
25812
|
+
init_parser();
|
|
25813
|
+
}
|
|
25814
|
+
});
|
|
25815
|
+
|
|
25181
25816
|
// src/sequence/tag-resolution.ts
|
|
25182
25817
|
function propagateGroupTags(participantMeta, groups) {
|
|
25183
25818
|
for (const group of groups) {
|
|
@@ -25632,13 +26267,32 @@ function applyGroupOrdering(participants, groups, messages = []) {
|
|
|
25632
26267
|
}
|
|
25633
26268
|
function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateToLine, options) {
|
|
25634
26269
|
d3Selection12.select(container).selectAll("*").remove();
|
|
25635
|
-
const { title,
|
|
26270
|
+
const { title, options: parsedOptions } = parsed;
|
|
26271
|
+
const effectiveCollapsedGroups = /* @__PURE__ */ new Set();
|
|
26272
|
+
for (const group of parsed.groups) {
|
|
26273
|
+
if (group.collapsed) effectiveCollapsedGroups.add(group.lineNumber);
|
|
26274
|
+
}
|
|
26275
|
+
if (options?.collapsedGroups) {
|
|
26276
|
+
for (const ln of options.collapsedGroups) {
|
|
26277
|
+
if (effectiveCollapsedGroups.has(ln)) {
|
|
26278
|
+
effectiveCollapsedGroups.delete(ln);
|
|
26279
|
+
} else {
|
|
26280
|
+
effectiveCollapsedGroups.add(ln);
|
|
26281
|
+
}
|
|
26282
|
+
}
|
|
26283
|
+
}
|
|
26284
|
+
const collapsed = effectiveCollapsedGroups.size > 0 ? applyCollapseProjection(parsed, effectiveCollapsedGroups) : null;
|
|
26285
|
+
const messages = collapsed ? collapsed.messages : parsed.messages;
|
|
26286
|
+
const elements = collapsed ? collapsed.elements : parsed.elements;
|
|
26287
|
+
const groups = collapsed ? collapsed.groups : parsed.groups;
|
|
26288
|
+
const collapsedGroupIds = collapsed?.collapsedGroupIds ?? /* @__PURE__ */ new Map();
|
|
25636
26289
|
const collapsedSections = options?.collapsedSections;
|
|
25637
26290
|
const expandedNoteLines = options?.expandedNoteLines;
|
|
25638
26291
|
const collapseNotesDisabled = parsedOptions["collapse-notes"]?.toLowerCase() === "no";
|
|
25639
26292
|
const isNoteExpanded = (note) => expandedNoteLines === void 0 || collapseNotesDisabled || expandedNoteLines.has(note.lineNumber);
|
|
26293
|
+
const sourceParticipants = collapsed ? collapsed.participants : parsed.participants;
|
|
25640
26294
|
const participants = applyPositionOverrides(
|
|
25641
|
-
applyGroupOrdering(
|
|
26295
|
+
applyGroupOrdering(sourceParticipants, groups, messages)
|
|
25642
26296
|
);
|
|
25643
26297
|
if (participants.length === 0) return;
|
|
25644
26298
|
const activationsOff = parsedOptions.activations?.toLowerCase() === "off";
|
|
@@ -25809,13 +26463,16 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
25809
26463
|
const preSectionMsgIndices = [];
|
|
25810
26464
|
const sectionRegions = [];
|
|
25811
26465
|
{
|
|
26466
|
+
const msgLineToIndex = /* @__PURE__ */ new Map();
|
|
26467
|
+
messages.forEach((m, i) => msgLineToIndex.set(m.lineNumber, i));
|
|
26468
|
+
const findMsgIndex = (child) => msgLineToIndex.get(child.lineNumber) ?? -1;
|
|
25812
26469
|
const collectMsgIndicesFromBlock = (block) => {
|
|
25813
26470
|
const indices = [];
|
|
25814
26471
|
for (const child of block.children) {
|
|
25815
26472
|
if (isSequenceBlock(child)) {
|
|
25816
26473
|
indices.push(...collectMsgIndicesFromBlock(child));
|
|
25817
26474
|
} else if (!isSequenceSection(child) && !isSequenceNote(child)) {
|
|
25818
|
-
const idx =
|
|
26475
|
+
const idx = findMsgIndex(child);
|
|
25819
26476
|
if (idx >= 0) indices.push(idx);
|
|
25820
26477
|
}
|
|
25821
26478
|
}
|
|
@@ -25825,7 +26482,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
25825
26482
|
if (isSequenceBlock(child)) {
|
|
25826
26483
|
indices.push(...collectMsgIndicesFromBlock(child));
|
|
25827
26484
|
} else if (!isSequenceSection(child) && !isSequenceNote(child)) {
|
|
25828
|
-
const idx =
|
|
26485
|
+
const idx = findMsgIndex(child);
|
|
25829
26486
|
if (idx >= 0) indices.push(idx);
|
|
25830
26487
|
}
|
|
25831
26488
|
}
|
|
@@ -25835,7 +26492,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
25835
26492
|
if (isSequenceBlock(child)) {
|
|
25836
26493
|
indices.push(...collectMsgIndicesFromBlock(child));
|
|
25837
26494
|
} else if (!isSequenceSection(child) && !isSequenceNote(child)) {
|
|
25838
|
-
const idx =
|
|
26495
|
+
const idx = findMsgIndex(child);
|
|
25839
26496
|
if (idx >= 0) indices.push(idx);
|
|
25840
26497
|
}
|
|
25841
26498
|
}
|
|
@@ -25850,7 +26507,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
25850
26507
|
} else if (isSequenceBlock(el)) {
|
|
25851
26508
|
currentTarget.push(...collectMsgIndicesFromBlock(el));
|
|
25852
26509
|
} else {
|
|
25853
|
-
const idx =
|
|
26510
|
+
const idx = findMsgIndex(el);
|
|
25854
26511
|
if (idx >= 0) currentTarget.push(idx);
|
|
25855
26512
|
}
|
|
25856
26513
|
}
|
|
@@ -25912,7 +26569,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
25912
26569
|
const titleOffset = title ? TITLE_HEIGHT5 : 0;
|
|
25913
26570
|
const LEGEND_FIXED_GAP4 = 8;
|
|
25914
26571
|
const legendTopSpace = parsed.tagGroups.length > 0 ? LEGEND_HEIGHT + LEGEND_FIXED_GAP4 : 0;
|
|
25915
|
-
const groupOffset = groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;
|
|
26572
|
+
const groupOffset = parsed.groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;
|
|
25916
26573
|
const participantStartY = TOP_MARGIN + titleOffset + legendTopSpace + PARTICIPANT_Y_OFFSET + groupOffset;
|
|
25917
26574
|
const lifelineStartY0 = participantStartY + PARTICIPANT_BOX_HEIGHT;
|
|
25918
26575
|
const hasActors = participants.some((p) => p.type === "actor");
|
|
@@ -26082,6 +26739,17 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26082
26739
|
svgWidth
|
|
26083
26740
|
);
|
|
26084
26741
|
}
|
|
26742
|
+
const collapsedGroupNames = /* @__PURE__ */ new Set();
|
|
26743
|
+
const collapsedGroupMeta = /* @__PURE__ */ new Map();
|
|
26744
|
+
for (const group of parsed.groups) {
|
|
26745
|
+
if (effectiveCollapsedGroups.has(group.lineNumber)) {
|
|
26746
|
+
collapsedGroupNames.add(group.name);
|
|
26747
|
+
collapsedGroupMeta.set(group.name, {
|
|
26748
|
+
lineNumber: group.lineNumber,
|
|
26749
|
+
metadata: group.metadata
|
|
26750
|
+
});
|
|
26751
|
+
}
|
|
26752
|
+
}
|
|
26085
26753
|
for (const group of groups) {
|
|
26086
26754
|
if (group.participantIds.length === 0) continue;
|
|
26087
26755
|
const memberXs = group.participantIds.map((id) => participantX.get(id)).filter((x) => x !== void 0);
|
|
@@ -26098,8 +26766,10 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26098
26766
|
isDark ? 15 : 20
|
|
26099
26767
|
) : isDark ? palette.surface : palette.bg;
|
|
26100
26768
|
const strokeColor = groupTagColor || palette.textMuted;
|
|
26101
|
-
svg.append("
|
|
26102
|
-
|
|
26769
|
+
const groupG = svg.append("g").attr("class", "group-box-wrapper").attr("data-group-toggle", "").attr("data-group-line", String(group.lineNumber)).attr("cursor", "pointer");
|
|
26770
|
+
groupG.append("title").text("Click to collapse");
|
|
26771
|
+
groupG.append("rect").attr("x", minX).attr("y", boxY).attr("width", maxX - minX).attr("height", boxH).attr("rx", 6).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("class", "group-box");
|
|
26772
|
+
groupG.append("text").attr("x", minX + 8).attr("y", boxY + GROUP_LABEL_SIZE + 4).attr("fill", strokeColor).attr("font-size", GROUP_LABEL_SIZE).attr("font-weight", "bold").attr("opacity", 0.7).attr("class", "group-label").text(group.name);
|
|
26103
26773
|
}
|
|
26104
26774
|
const lifelineStartY = lifelineStartY0;
|
|
26105
26775
|
participants.forEach((participant, index) => {
|
|
@@ -26108,6 +26778,14 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26108
26778
|
const pTagValue = tagMap?.participants.get(participant.id);
|
|
26109
26779
|
const pTagColor = getTagColor(pTagValue);
|
|
26110
26780
|
const pTagAttr = tagKey && pTagValue ? { key: tagKey, value: pTagValue.toLowerCase() } : void 0;
|
|
26781
|
+
const isCollapsedGroup = collapsedGroupNames.has(participant.id);
|
|
26782
|
+
let effectiveTagColor = pTagColor;
|
|
26783
|
+
if (isCollapsedGroup && !effectiveTagColor) {
|
|
26784
|
+
const meta = collapsedGroupMeta.get(participant.id);
|
|
26785
|
+
if (meta?.metadata && tagKey) {
|
|
26786
|
+
effectiveTagColor = getTagColor(meta.metadata[tagKey]);
|
|
26787
|
+
}
|
|
26788
|
+
}
|
|
26111
26789
|
renderParticipant(
|
|
26112
26790
|
svg,
|
|
26113
26791
|
participant,
|
|
@@ -26115,10 +26793,35 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26115
26793
|
cy,
|
|
26116
26794
|
palette,
|
|
26117
26795
|
isDark,
|
|
26118
|
-
|
|
26796
|
+
effectiveTagColor,
|
|
26119
26797
|
pTagAttr
|
|
26120
26798
|
);
|
|
26121
|
-
|
|
26799
|
+
if (isCollapsedGroup) {
|
|
26800
|
+
const meta = collapsedGroupMeta.get(participant.id);
|
|
26801
|
+
const drillColor = effectiveTagColor || palette.textMuted;
|
|
26802
|
+
const drillBarH = 6;
|
|
26803
|
+
const boxW = PARTICIPANT_BOX_WIDTH;
|
|
26804
|
+
const fullH = PARTICIPANT_BOX_HEIGHT + GROUP_PADDING_TOP + GROUP_PADDING_BOTTOM;
|
|
26805
|
+
const clipId = `clip-drill-group-${participant.id.replace(/[^a-zA-Z0-9-]/g, "-")}`;
|
|
26806
|
+
const participantG = svg.select(
|
|
26807
|
+
`.participant[data-participant-id="${participant.id}"]`
|
|
26808
|
+
);
|
|
26809
|
+
participantG.attr("data-group-toggle", "").attr("data-group-line", String(meta.lineNumber)).attr("cursor", "pointer");
|
|
26810
|
+
participantG.append("title").text("Click to expand");
|
|
26811
|
+
const pFill = effectiveTagColor ? mix(
|
|
26812
|
+
effectiveTagColor,
|
|
26813
|
+
isDark ? palette.surface : palette.bg,
|
|
26814
|
+
isDark ? 30 : 40
|
|
26815
|
+
) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
|
|
26816
|
+
const pStroke = effectiveTagColor || palette.border;
|
|
26817
|
+
participantG.append("rect").attr("x", -boxW / 2).attr("y", -GROUP_PADDING_TOP).attr("width", boxW).attr("height", fullH).attr("rx", 6).attr("fill", pFill).attr("stroke", pStroke).attr("stroke-width", 1.5);
|
|
26818
|
+
participantG.append("text").attr("x", 0).attr("y", -GROUP_PADDING_TOP + fullH / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", palette.text).attr("font-size", 13).attr("font-weight", 500).text(participant.label);
|
|
26819
|
+
participantG.append("clipPath").attr("id", clipId).append("rect").attr("x", -boxW / 2).attr("y", -GROUP_PADDING_TOP).attr("width", boxW).attr("height", fullH).attr("rx", 6);
|
|
26820
|
+
participantG.append("rect").attr("class", "sequence-drill-bar").attr("x", -boxW / 2).attr("y", -GROUP_PADDING_TOP + fullH - drillBarH).attr("width", boxW).attr("height", drillBarH).attr("fill", drillColor).attr("clip-path", `url(#${clipId})`);
|
|
26821
|
+
}
|
|
26822
|
+
const llY = isCollapsedGroup ? lifelineStartY + GROUP_PADDING_BOTTOM : lifelineStartY;
|
|
26823
|
+
const llColor = isCollapsedGroup ? effectiveTagColor || palette.textMuted : pTagColor || palette.textMuted;
|
|
26824
|
+
const lifelineEl = svg.append("line").attr("x1", cx).attr("y1", llY).attr("x2", cx).attr("y2", lifelineStartY + lifelineLength).attr("stroke", llColor).attr("stroke-width", 1).attr("stroke-dasharray", "6 4").attr("class", "lifeline").attr("data-participant-id", participant.id);
|
|
26122
26825
|
if (tagKey && pTagValue) {
|
|
26123
26826
|
lifelineEl.attr(`data-tag-${tagKey}`, pTagValue.toLowerCase());
|
|
26124
26827
|
}
|
|
@@ -26346,23 +27049,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26346
27049
|
sectionG.append("rect").attr("x", bandX).attr("y", secY - BAND_HEIGHT / 2).attr("width", bandWidth).attr("height", BAND_HEIGHT).attr("fill", lineColor).attr("opacity", bandOpacity).attr("rx", 2).attr("class", "section-divider");
|
|
26347
27050
|
const msgCount = sectionMsgCounts.get(sec.lineNumber) ?? 0;
|
|
26348
27051
|
const labelText = isCollapsed ? `${sec.label} (${msgCount} ${msgCount === 1 ? "message" : "messages"})` : sec.label;
|
|
26349
|
-
const labelColor = isCollapsed ? "#ffffff" : lineColor;
|
|
26350
|
-
const chevronSpace = 14;
|
|
26351
27052
|
const labelX = (sectionLineX1 + sectionLineX2) / 2;
|
|
26352
|
-
|
|
26353
|
-
const chevronY = secY;
|
|
26354
|
-
if (isCollapsed) {
|
|
26355
|
-
sectionG.append("path").attr(
|
|
26356
|
-
"d",
|
|
26357
|
-
`M ${chevronX} ${chevronY - 4} L ${chevronX + 6} ${chevronY} L ${chevronX} ${chevronY + 4} Z`
|
|
26358
|
-
).attr("fill", labelColor).attr("class", "section-chevron");
|
|
26359
|
-
} else {
|
|
26360
|
-
sectionG.append("path").attr(
|
|
26361
|
-
"d",
|
|
26362
|
-
`M ${chevronX - 1} ${chevronY - 3} L ${chevronX + 7} ${chevronY - 3} L ${chevronX + 3} ${chevronY + 3} Z`
|
|
26363
|
-
).attr("fill", labelColor).attr("class", "section-chevron");
|
|
26364
|
-
}
|
|
26365
|
-
sectionG.append("text").attr("x", labelX + chevronSpace / 2).attr("y", secY + 4).attr("text-anchor", "middle").attr("fill", labelColor).attr("font-size", 11).attr("font-weight", "bold").attr("class", "section-label").text(labelText);
|
|
27053
|
+
sectionG.append("text").attr("x", labelX).attr("y", secY + 4).attr("text-anchor", "middle").attr("fill", lineColor).attr("font-size", 11).attr("font-weight", "bold").attr("class", "section-label").text(labelText);
|
|
26366
27054
|
}
|
|
26367
27055
|
const SELF_CALL_WIDTH = 30;
|
|
26368
27056
|
const SELF_CALL_HEIGHT = 25;
|
|
@@ -26644,6 +27332,7 @@ var init_renderer10 = __esm({
|
|
|
26644
27332
|
init_inline_markdown();
|
|
26645
27333
|
init_fonts();
|
|
26646
27334
|
init_parser();
|
|
27335
|
+
init_collapse3();
|
|
26647
27336
|
init_tag_resolution();
|
|
26648
27337
|
init_tag_groups();
|
|
26649
27338
|
init_legend_constants();
|
|
@@ -30967,6 +31656,463 @@ var init_d3 = __esm({
|
|
|
30967
31656
|
}
|
|
30968
31657
|
});
|
|
30969
31658
|
|
|
31659
|
+
// node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
|
|
31660
|
+
var require_lz_string = __commonJS({
|
|
31661
|
+
"node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports2, module2) {
|
|
31662
|
+
"use strict";
|
|
31663
|
+
var LZString = (function() {
|
|
31664
|
+
var f = String.fromCharCode;
|
|
31665
|
+
var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
31666
|
+
var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
|
|
31667
|
+
var baseReverseDic = {};
|
|
31668
|
+
function getBaseValue(alphabet, character) {
|
|
31669
|
+
if (!baseReverseDic[alphabet]) {
|
|
31670
|
+
baseReverseDic[alphabet] = {};
|
|
31671
|
+
for (var i = 0; i < alphabet.length; i++) {
|
|
31672
|
+
baseReverseDic[alphabet][alphabet.charAt(i)] = i;
|
|
31673
|
+
}
|
|
31674
|
+
}
|
|
31675
|
+
return baseReverseDic[alphabet][character];
|
|
31676
|
+
}
|
|
31677
|
+
var LZString2 = {
|
|
31678
|
+
compressToBase64: function(input) {
|
|
31679
|
+
if (input == null) return "";
|
|
31680
|
+
var res = LZString2._compress(input, 6, function(a) {
|
|
31681
|
+
return keyStrBase64.charAt(a);
|
|
31682
|
+
});
|
|
31683
|
+
switch (res.length % 4) {
|
|
31684
|
+
// To produce valid Base64
|
|
31685
|
+
default:
|
|
31686
|
+
// When could this happen ?
|
|
31687
|
+
case 0:
|
|
31688
|
+
return res;
|
|
31689
|
+
case 1:
|
|
31690
|
+
return res + "===";
|
|
31691
|
+
case 2:
|
|
31692
|
+
return res + "==";
|
|
31693
|
+
case 3:
|
|
31694
|
+
return res + "=";
|
|
31695
|
+
}
|
|
31696
|
+
},
|
|
31697
|
+
decompressFromBase64: function(input) {
|
|
31698
|
+
if (input == null) return "";
|
|
31699
|
+
if (input == "") return null;
|
|
31700
|
+
return LZString2._decompress(input.length, 32, function(index) {
|
|
31701
|
+
return getBaseValue(keyStrBase64, input.charAt(index));
|
|
31702
|
+
});
|
|
31703
|
+
},
|
|
31704
|
+
compressToUTF16: function(input) {
|
|
31705
|
+
if (input == null) return "";
|
|
31706
|
+
return LZString2._compress(input, 15, function(a) {
|
|
31707
|
+
return f(a + 32);
|
|
31708
|
+
}) + " ";
|
|
31709
|
+
},
|
|
31710
|
+
decompressFromUTF16: function(compressed) {
|
|
31711
|
+
if (compressed == null) return "";
|
|
31712
|
+
if (compressed == "") return null;
|
|
31713
|
+
return LZString2._decompress(compressed.length, 16384, function(index) {
|
|
31714
|
+
return compressed.charCodeAt(index) - 32;
|
|
31715
|
+
});
|
|
31716
|
+
},
|
|
31717
|
+
//compress into uint8array (UCS-2 big endian format)
|
|
31718
|
+
compressToUint8Array: function(uncompressed) {
|
|
31719
|
+
var compressed = LZString2.compress(uncompressed);
|
|
31720
|
+
var buf = new Uint8Array(compressed.length * 2);
|
|
31721
|
+
for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
|
|
31722
|
+
var current_value = compressed.charCodeAt(i);
|
|
31723
|
+
buf[i * 2] = current_value >>> 8;
|
|
31724
|
+
buf[i * 2 + 1] = current_value % 256;
|
|
31725
|
+
}
|
|
31726
|
+
return buf;
|
|
31727
|
+
},
|
|
31728
|
+
//decompress from uint8array (UCS-2 big endian format)
|
|
31729
|
+
decompressFromUint8Array: function(compressed) {
|
|
31730
|
+
if (compressed === null || compressed === void 0) {
|
|
31731
|
+
return LZString2.decompress(compressed);
|
|
31732
|
+
} else {
|
|
31733
|
+
var buf = new Array(compressed.length / 2);
|
|
31734
|
+
for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
|
|
31735
|
+
buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
|
|
31736
|
+
}
|
|
31737
|
+
var result = [];
|
|
31738
|
+
buf.forEach(function(c) {
|
|
31739
|
+
result.push(f(c));
|
|
31740
|
+
});
|
|
31741
|
+
return LZString2.decompress(result.join(""));
|
|
31742
|
+
}
|
|
31743
|
+
},
|
|
31744
|
+
//compress into a string that is already URI encoded
|
|
31745
|
+
compressToEncodedURIComponent: function(input) {
|
|
31746
|
+
if (input == null) return "";
|
|
31747
|
+
return LZString2._compress(input, 6, function(a) {
|
|
31748
|
+
return keyStrUriSafe.charAt(a);
|
|
31749
|
+
});
|
|
31750
|
+
},
|
|
31751
|
+
//decompress from an output of compressToEncodedURIComponent
|
|
31752
|
+
decompressFromEncodedURIComponent: function(input) {
|
|
31753
|
+
if (input == null) return "";
|
|
31754
|
+
if (input == "") return null;
|
|
31755
|
+
input = input.replace(/ /g, "+");
|
|
31756
|
+
return LZString2._decompress(input.length, 32, function(index) {
|
|
31757
|
+
return getBaseValue(keyStrUriSafe, input.charAt(index));
|
|
31758
|
+
});
|
|
31759
|
+
},
|
|
31760
|
+
compress: function(uncompressed) {
|
|
31761
|
+
return LZString2._compress(uncompressed, 16, function(a) {
|
|
31762
|
+
return f(a);
|
|
31763
|
+
});
|
|
31764
|
+
},
|
|
31765
|
+
_compress: function(uncompressed, bitsPerChar, getCharFromInt) {
|
|
31766
|
+
if (uncompressed == null) return "";
|
|
31767
|
+
var i, value, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
|
|
31768
|
+
for (ii = 0; ii < uncompressed.length; ii += 1) {
|
|
31769
|
+
context_c = uncompressed.charAt(ii);
|
|
31770
|
+
if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
|
|
31771
|
+
context_dictionary[context_c] = context_dictSize++;
|
|
31772
|
+
context_dictionaryToCreate[context_c] = true;
|
|
31773
|
+
}
|
|
31774
|
+
context_wc = context_w + context_c;
|
|
31775
|
+
if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
|
|
31776
|
+
context_w = context_wc;
|
|
31777
|
+
} else {
|
|
31778
|
+
if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
|
|
31779
|
+
if (context_w.charCodeAt(0) < 256) {
|
|
31780
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31781
|
+
context_data_val = context_data_val << 1;
|
|
31782
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31783
|
+
context_data_position = 0;
|
|
31784
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31785
|
+
context_data_val = 0;
|
|
31786
|
+
} else {
|
|
31787
|
+
context_data_position++;
|
|
31788
|
+
}
|
|
31789
|
+
}
|
|
31790
|
+
value = context_w.charCodeAt(0);
|
|
31791
|
+
for (i = 0; i < 8; i++) {
|
|
31792
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31793
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31794
|
+
context_data_position = 0;
|
|
31795
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31796
|
+
context_data_val = 0;
|
|
31797
|
+
} else {
|
|
31798
|
+
context_data_position++;
|
|
31799
|
+
}
|
|
31800
|
+
value = value >> 1;
|
|
31801
|
+
}
|
|
31802
|
+
} else {
|
|
31803
|
+
value = 1;
|
|
31804
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31805
|
+
context_data_val = context_data_val << 1 | value;
|
|
31806
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31807
|
+
context_data_position = 0;
|
|
31808
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31809
|
+
context_data_val = 0;
|
|
31810
|
+
} else {
|
|
31811
|
+
context_data_position++;
|
|
31812
|
+
}
|
|
31813
|
+
value = 0;
|
|
31814
|
+
}
|
|
31815
|
+
value = context_w.charCodeAt(0);
|
|
31816
|
+
for (i = 0; i < 16; i++) {
|
|
31817
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31818
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31819
|
+
context_data_position = 0;
|
|
31820
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31821
|
+
context_data_val = 0;
|
|
31822
|
+
} else {
|
|
31823
|
+
context_data_position++;
|
|
31824
|
+
}
|
|
31825
|
+
value = value >> 1;
|
|
31826
|
+
}
|
|
31827
|
+
}
|
|
31828
|
+
context_enlargeIn--;
|
|
31829
|
+
if (context_enlargeIn == 0) {
|
|
31830
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
31831
|
+
context_numBits++;
|
|
31832
|
+
}
|
|
31833
|
+
delete context_dictionaryToCreate[context_w];
|
|
31834
|
+
} else {
|
|
31835
|
+
value = context_dictionary[context_w];
|
|
31836
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31837
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31838
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31839
|
+
context_data_position = 0;
|
|
31840
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31841
|
+
context_data_val = 0;
|
|
31842
|
+
} else {
|
|
31843
|
+
context_data_position++;
|
|
31844
|
+
}
|
|
31845
|
+
value = value >> 1;
|
|
31846
|
+
}
|
|
31847
|
+
}
|
|
31848
|
+
context_enlargeIn--;
|
|
31849
|
+
if (context_enlargeIn == 0) {
|
|
31850
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
31851
|
+
context_numBits++;
|
|
31852
|
+
}
|
|
31853
|
+
context_dictionary[context_wc] = context_dictSize++;
|
|
31854
|
+
context_w = String(context_c);
|
|
31855
|
+
}
|
|
31856
|
+
}
|
|
31857
|
+
if (context_w !== "") {
|
|
31858
|
+
if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
|
|
31859
|
+
if (context_w.charCodeAt(0) < 256) {
|
|
31860
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31861
|
+
context_data_val = context_data_val << 1;
|
|
31862
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31863
|
+
context_data_position = 0;
|
|
31864
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31865
|
+
context_data_val = 0;
|
|
31866
|
+
} else {
|
|
31867
|
+
context_data_position++;
|
|
31868
|
+
}
|
|
31869
|
+
}
|
|
31870
|
+
value = context_w.charCodeAt(0);
|
|
31871
|
+
for (i = 0; i < 8; i++) {
|
|
31872
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31873
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31874
|
+
context_data_position = 0;
|
|
31875
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31876
|
+
context_data_val = 0;
|
|
31877
|
+
} else {
|
|
31878
|
+
context_data_position++;
|
|
31879
|
+
}
|
|
31880
|
+
value = value >> 1;
|
|
31881
|
+
}
|
|
31882
|
+
} else {
|
|
31883
|
+
value = 1;
|
|
31884
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31885
|
+
context_data_val = context_data_val << 1 | value;
|
|
31886
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31887
|
+
context_data_position = 0;
|
|
31888
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31889
|
+
context_data_val = 0;
|
|
31890
|
+
} else {
|
|
31891
|
+
context_data_position++;
|
|
31892
|
+
}
|
|
31893
|
+
value = 0;
|
|
31894
|
+
}
|
|
31895
|
+
value = context_w.charCodeAt(0);
|
|
31896
|
+
for (i = 0; i < 16; i++) {
|
|
31897
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31898
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31899
|
+
context_data_position = 0;
|
|
31900
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31901
|
+
context_data_val = 0;
|
|
31902
|
+
} else {
|
|
31903
|
+
context_data_position++;
|
|
31904
|
+
}
|
|
31905
|
+
value = value >> 1;
|
|
31906
|
+
}
|
|
31907
|
+
}
|
|
31908
|
+
context_enlargeIn--;
|
|
31909
|
+
if (context_enlargeIn == 0) {
|
|
31910
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
31911
|
+
context_numBits++;
|
|
31912
|
+
}
|
|
31913
|
+
delete context_dictionaryToCreate[context_w];
|
|
31914
|
+
} else {
|
|
31915
|
+
value = context_dictionary[context_w];
|
|
31916
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31917
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31918
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31919
|
+
context_data_position = 0;
|
|
31920
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31921
|
+
context_data_val = 0;
|
|
31922
|
+
} else {
|
|
31923
|
+
context_data_position++;
|
|
31924
|
+
}
|
|
31925
|
+
value = value >> 1;
|
|
31926
|
+
}
|
|
31927
|
+
}
|
|
31928
|
+
context_enlargeIn--;
|
|
31929
|
+
if (context_enlargeIn == 0) {
|
|
31930
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
31931
|
+
context_numBits++;
|
|
31932
|
+
}
|
|
31933
|
+
}
|
|
31934
|
+
value = 2;
|
|
31935
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31936
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31937
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31938
|
+
context_data_position = 0;
|
|
31939
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31940
|
+
context_data_val = 0;
|
|
31941
|
+
} else {
|
|
31942
|
+
context_data_position++;
|
|
31943
|
+
}
|
|
31944
|
+
value = value >> 1;
|
|
31945
|
+
}
|
|
31946
|
+
while (true) {
|
|
31947
|
+
context_data_val = context_data_val << 1;
|
|
31948
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31949
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31950
|
+
break;
|
|
31951
|
+
} else context_data_position++;
|
|
31952
|
+
}
|
|
31953
|
+
return context_data.join("");
|
|
31954
|
+
},
|
|
31955
|
+
decompress: function(compressed) {
|
|
31956
|
+
if (compressed == null) return "";
|
|
31957
|
+
if (compressed == "") return null;
|
|
31958
|
+
return LZString2._decompress(compressed.length, 32768, function(index) {
|
|
31959
|
+
return compressed.charCodeAt(index);
|
|
31960
|
+
});
|
|
31961
|
+
},
|
|
31962
|
+
_decompress: function(length, resetValue, getNextValue) {
|
|
31963
|
+
var dictionary = [], next, enlargeIn = 4, dictSize = 4, numBits = 3, entry = "", result = [], i, w, bits, resb, maxpower, power, c, data = { val: getNextValue(0), position: resetValue, index: 1 };
|
|
31964
|
+
for (i = 0; i < 3; i += 1) {
|
|
31965
|
+
dictionary[i] = i;
|
|
31966
|
+
}
|
|
31967
|
+
bits = 0;
|
|
31968
|
+
maxpower = Math.pow(2, 2);
|
|
31969
|
+
power = 1;
|
|
31970
|
+
while (power != maxpower) {
|
|
31971
|
+
resb = data.val & data.position;
|
|
31972
|
+
data.position >>= 1;
|
|
31973
|
+
if (data.position == 0) {
|
|
31974
|
+
data.position = resetValue;
|
|
31975
|
+
data.val = getNextValue(data.index++);
|
|
31976
|
+
}
|
|
31977
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
31978
|
+
power <<= 1;
|
|
31979
|
+
}
|
|
31980
|
+
switch (next = bits) {
|
|
31981
|
+
case 0:
|
|
31982
|
+
bits = 0;
|
|
31983
|
+
maxpower = Math.pow(2, 8);
|
|
31984
|
+
power = 1;
|
|
31985
|
+
while (power != maxpower) {
|
|
31986
|
+
resb = data.val & data.position;
|
|
31987
|
+
data.position >>= 1;
|
|
31988
|
+
if (data.position == 0) {
|
|
31989
|
+
data.position = resetValue;
|
|
31990
|
+
data.val = getNextValue(data.index++);
|
|
31991
|
+
}
|
|
31992
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
31993
|
+
power <<= 1;
|
|
31994
|
+
}
|
|
31995
|
+
c = f(bits);
|
|
31996
|
+
break;
|
|
31997
|
+
case 1:
|
|
31998
|
+
bits = 0;
|
|
31999
|
+
maxpower = Math.pow(2, 16);
|
|
32000
|
+
power = 1;
|
|
32001
|
+
while (power != maxpower) {
|
|
32002
|
+
resb = data.val & data.position;
|
|
32003
|
+
data.position >>= 1;
|
|
32004
|
+
if (data.position == 0) {
|
|
32005
|
+
data.position = resetValue;
|
|
32006
|
+
data.val = getNextValue(data.index++);
|
|
32007
|
+
}
|
|
32008
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
32009
|
+
power <<= 1;
|
|
32010
|
+
}
|
|
32011
|
+
c = f(bits);
|
|
32012
|
+
break;
|
|
32013
|
+
case 2:
|
|
32014
|
+
return "";
|
|
32015
|
+
}
|
|
32016
|
+
dictionary[3] = c;
|
|
32017
|
+
w = c;
|
|
32018
|
+
result.push(c);
|
|
32019
|
+
while (true) {
|
|
32020
|
+
if (data.index > length) {
|
|
32021
|
+
return "";
|
|
32022
|
+
}
|
|
32023
|
+
bits = 0;
|
|
32024
|
+
maxpower = Math.pow(2, numBits);
|
|
32025
|
+
power = 1;
|
|
32026
|
+
while (power != maxpower) {
|
|
32027
|
+
resb = data.val & data.position;
|
|
32028
|
+
data.position >>= 1;
|
|
32029
|
+
if (data.position == 0) {
|
|
32030
|
+
data.position = resetValue;
|
|
32031
|
+
data.val = getNextValue(data.index++);
|
|
32032
|
+
}
|
|
32033
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
32034
|
+
power <<= 1;
|
|
32035
|
+
}
|
|
32036
|
+
switch (c = bits) {
|
|
32037
|
+
case 0:
|
|
32038
|
+
bits = 0;
|
|
32039
|
+
maxpower = Math.pow(2, 8);
|
|
32040
|
+
power = 1;
|
|
32041
|
+
while (power != maxpower) {
|
|
32042
|
+
resb = data.val & data.position;
|
|
32043
|
+
data.position >>= 1;
|
|
32044
|
+
if (data.position == 0) {
|
|
32045
|
+
data.position = resetValue;
|
|
32046
|
+
data.val = getNextValue(data.index++);
|
|
32047
|
+
}
|
|
32048
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
32049
|
+
power <<= 1;
|
|
32050
|
+
}
|
|
32051
|
+
dictionary[dictSize++] = f(bits);
|
|
32052
|
+
c = dictSize - 1;
|
|
32053
|
+
enlargeIn--;
|
|
32054
|
+
break;
|
|
32055
|
+
case 1:
|
|
32056
|
+
bits = 0;
|
|
32057
|
+
maxpower = Math.pow(2, 16);
|
|
32058
|
+
power = 1;
|
|
32059
|
+
while (power != maxpower) {
|
|
32060
|
+
resb = data.val & data.position;
|
|
32061
|
+
data.position >>= 1;
|
|
32062
|
+
if (data.position == 0) {
|
|
32063
|
+
data.position = resetValue;
|
|
32064
|
+
data.val = getNextValue(data.index++);
|
|
32065
|
+
}
|
|
32066
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
32067
|
+
power <<= 1;
|
|
32068
|
+
}
|
|
32069
|
+
dictionary[dictSize++] = f(bits);
|
|
32070
|
+
c = dictSize - 1;
|
|
32071
|
+
enlargeIn--;
|
|
32072
|
+
break;
|
|
32073
|
+
case 2:
|
|
32074
|
+
return result.join("");
|
|
32075
|
+
}
|
|
32076
|
+
if (enlargeIn == 0) {
|
|
32077
|
+
enlargeIn = Math.pow(2, numBits);
|
|
32078
|
+
numBits++;
|
|
32079
|
+
}
|
|
32080
|
+
if (dictionary[c]) {
|
|
32081
|
+
entry = dictionary[c];
|
|
32082
|
+
} else {
|
|
32083
|
+
if (c === dictSize) {
|
|
32084
|
+
entry = w + w.charAt(0);
|
|
32085
|
+
} else {
|
|
32086
|
+
return null;
|
|
32087
|
+
}
|
|
32088
|
+
}
|
|
32089
|
+
result.push(entry);
|
|
32090
|
+
dictionary[dictSize++] = w + entry.charAt(0);
|
|
32091
|
+
enlargeIn--;
|
|
32092
|
+
w = entry;
|
|
32093
|
+
if (enlargeIn == 0) {
|
|
32094
|
+
enlargeIn = Math.pow(2, numBits);
|
|
32095
|
+
numBits++;
|
|
32096
|
+
}
|
|
32097
|
+
}
|
|
32098
|
+
}
|
|
32099
|
+
};
|
|
32100
|
+
return LZString2;
|
|
32101
|
+
})();
|
|
32102
|
+
if (typeof define === "function" && define.amd) {
|
|
32103
|
+
define(function() {
|
|
32104
|
+
return LZString;
|
|
32105
|
+
});
|
|
32106
|
+
} else if (typeof module2 !== "undefined" && module2 != null) {
|
|
32107
|
+
module2.exports = LZString;
|
|
32108
|
+
} else if (typeof angular !== "undefined" && angular != null) {
|
|
32109
|
+
angular.module("LZString", []).factory("LZString", function() {
|
|
32110
|
+
return LZString;
|
|
32111
|
+
});
|
|
32112
|
+
}
|
|
32113
|
+
}
|
|
32114
|
+
});
|
|
32115
|
+
|
|
30970
32116
|
// src/index.ts
|
|
30971
32117
|
var index_exports = {};
|
|
30972
32118
|
__export(index_exports, {
|
|
@@ -30981,6 +32127,7 @@ __export(index_exports, {
|
|
|
30981
32127
|
RECOGNIZED_COLOR_NAMES: () => RECOGNIZED_COLOR_NAMES,
|
|
30982
32128
|
RULE_COUNT: () => RULE_COUNT,
|
|
30983
32129
|
addDurationToDate: () => addDurationToDate,
|
|
32130
|
+
applyCollapseProjection: () => applyCollapseProjection,
|
|
30984
32131
|
applyGroupOrdering: () => applyGroupOrdering,
|
|
30985
32132
|
applyPositionOverrides: () => applyPositionOverrides,
|
|
30986
32133
|
boldPalette: () => boldPalette,
|
|
@@ -31010,8 +32157,10 @@ __export(index_exports, {
|
|
|
31010
32157
|
computeTimeTicks: () => computeTimeTicks,
|
|
31011
32158
|
contrastText: () => contrastText,
|
|
31012
32159
|
decodeDiagramUrl: () => decodeDiagramUrl,
|
|
32160
|
+
decodeViewState: () => decodeViewState,
|
|
31013
32161
|
draculaPalette: () => draculaPalette,
|
|
31014
32162
|
encodeDiagramUrl: () => encodeDiagramUrl,
|
|
32163
|
+
encodeViewState: () => encodeViewState,
|
|
31015
32164
|
extractDiagramSymbols: () => extractDiagramSymbols,
|
|
31016
32165
|
extractTagDeclarations: () => extractTagDeclarations,
|
|
31017
32166
|
formatDateLabel: () => formatDateLabel,
|
|
@@ -31921,13 +33070,32 @@ init_legend_d3();
|
|
|
31921
33070
|
init_legend_layout();
|
|
31922
33071
|
init_d3();
|
|
31923
33072
|
init_renderer10();
|
|
33073
|
+
init_collapse3();
|
|
31924
33074
|
init_colors();
|
|
31925
33075
|
init_palettes();
|
|
31926
33076
|
|
|
31927
33077
|
// src/sharing.ts
|
|
31928
|
-
var import_lz_string =
|
|
33078
|
+
var import_lz_string = __toESM(require_lz_string(), 1);
|
|
31929
33079
|
var DEFAULT_BASE_URL = "https://online.diagrammo.app";
|
|
31930
33080
|
var COMPRESSED_SIZE_LIMIT = 8192;
|
|
33081
|
+
function encodeViewState(state) {
|
|
33082
|
+
const keys = Object.keys(state);
|
|
33083
|
+
if (keys.length === 0) return "";
|
|
33084
|
+
return (0, import_lz_string.compressToEncodedURIComponent)(JSON.stringify(state));
|
|
33085
|
+
}
|
|
33086
|
+
function decodeViewState(encoded) {
|
|
33087
|
+
if (!encoded) return {};
|
|
33088
|
+
try {
|
|
33089
|
+
const json = (0, import_lz_string.decompressFromEncodedURIComponent)(encoded);
|
|
33090
|
+
if (!json) return {};
|
|
33091
|
+
const parsed = JSON.parse(json);
|
|
33092
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
33093
|
+
return {};
|
|
33094
|
+
return parsed;
|
|
33095
|
+
} catch {
|
|
33096
|
+
return {};
|
|
33097
|
+
}
|
|
33098
|
+
}
|
|
31931
33099
|
function encodeDiagramUrl(dsl, options) {
|
|
31932
33100
|
const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
|
|
31933
33101
|
const compressed = (0, import_lz_string.compressToEncodedURIComponent)(dsl);
|
|
@@ -31940,23 +33108,17 @@ function encodeDiagramUrl(dsl, options) {
|
|
|
31940
33108
|
};
|
|
31941
33109
|
}
|
|
31942
33110
|
let hash = `dgmo=${compressed}`;
|
|
31943
|
-
if (options?.viewState
|
|
31944
|
-
|
|
31945
|
-
|
|
31946
|
-
|
|
31947
|
-
|
|
31948
|
-
}
|
|
31949
|
-
if (options?.viewState?.swimlaneTagGroup) {
|
|
31950
|
-
hash += `&swim=${encodeURIComponent(options.viewState.swimlaneTagGroup)}`;
|
|
31951
|
-
}
|
|
31952
|
-
if (options?.viewState?.collapsedLanes?.length) {
|
|
31953
|
-
hash += `&cl=${encodeURIComponent(options.viewState.collapsedLanes.join(","))}`;
|
|
33111
|
+
if (options?.viewState) {
|
|
33112
|
+
const vsEncoded = encodeViewState(options.viewState);
|
|
33113
|
+
if (vsEncoded) {
|
|
33114
|
+
hash += `&vs=${vsEncoded}`;
|
|
33115
|
+
}
|
|
31954
33116
|
}
|
|
31955
|
-
if (options?.
|
|
31956
|
-
hash += `&pal=${encodeURIComponent(options.
|
|
33117
|
+
if (options?.palette && options.palette !== "nord") {
|
|
33118
|
+
hash += `&pal=${encodeURIComponent(options.palette)}`;
|
|
31957
33119
|
}
|
|
31958
|
-
if (options?.
|
|
31959
|
-
hash += `&th=${encodeURIComponent(options.
|
|
33120
|
+
if (options?.theme && options.theme !== "dark") {
|
|
33121
|
+
hash += `&th=${encodeURIComponent(options.theme)}`;
|
|
31960
33122
|
}
|
|
31961
33123
|
if (options?.filename) {
|
|
31962
33124
|
hash += `&fn=${encodeURIComponent(options.filename)}`;
|
|
@@ -31966,6 +33128,8 @@ function encodeDiagramUrl(dsl, options) {
|
|
|
31966
33128
|
function decodeDiagramUrl(hash) {
|
|
31967
33129
|
const empty = { dsl: "", viewState: {} };
|
|
31968
33130
|
let filename;
|
|
33131
|
+
let palette;
|
|
33132
|
+
let theme;
|
|
31969
33133
|
if (!hash) return empty;
|
|
31970
33134
|
let raw = hash;
|
|
31971
33135
|
if (raw.startsWith("#") || raw.startsWith("?")) {
|
|
@@ -31973,38 +33137,31 @@ function decodeDiagramUrl(hash) {
|
|
|
31973
33137
|
}
|
|
31974
33138
|
const parts = raw.split("&");
|
|
31975
33139
|
let payload = parts[0];
|
|
31976
|
-
|
|
33140
|
+
let viewState = {};
|
|
31977
33141
|
for (let i = 1; i < parts.length; i++) {
|
|
31978
33142
|
const eq = parts[i].indexOf("=");
|
|
31979
33143
|
if (eq === -1) continue;
|
|
31980
33144
|
const key = parts[i].slice(0, eq);
|
|
31981
|
-
const val =
|
|
31982
|
-
if (key === "
|
|
31983
|
-
viewState
|
|
31984
|
-
}
|
|
31985
|
-
if (key === "cg" && val) {
|
|
31986
|
-
viewState.collapsedGroups = val.split(",").filter(Boolean);
|
|
31987
|
-
}
|
|
31988
|
-
if (key === "swim" && val) {
|
|
31989
|
-
viewState.swimlaneTagGroup = val;
|
|
33145
|
+
const val = parts[i].slice(eq + 1);
|
|
33146
|
+
if (key === "vs" && val) {
|
|
33147
|
+
viewState = decodeViewState(val);
|
|
31990
33148
|
}
|
|
31991
|
-
if (key === "
|
|
31992
|
-
|
|
33149
|
+
if (key === "pal" && val) palette = decodeURIComponent(val);
|
|
33150
|
+
if (key === "th") {
|
|
33151
|
+
const decoded = decodeURIComponent(val);
|
|
33152
|
+
if (decoded === "light" || decoded === "dark") theme = decoded;
|
|
31993
33153
|
}
|
|
31994
|
-
if (key === "
|
|
31995
|
-
if (key === "th" && (val === "light" || val === "dark"))
|
|
31996
|
-
viewState.theme = val;
|
|
31997
|
-
if (key === "fn" && val) filename = val;
|
|
33154
|
+
if (key === "fn" && val) filename = decodeURIComponent(val);
|
|
31998
33155
|
}
|
|
31999
33156
|
if (payload.startsWith("dgmo=")) {
|
|
32000
33157
|
payload = payload.slice(5);
|
|
32001
33158
|
}
|
|
32002
|
-
if (!payload) return { dsl: "", viewState, filename };
|
|
33159
|
+
if (!payload) return { dsl: "", viewState, palette, theme, filename };
|
|
32003
33160
|
try {
|
|
32004
33161
|
const result = (0, import_lz_string.decompressFromEncodedURIComponent)(payload);
|
|
32005
|
-
return { dsl: result ?? "", viewState, filename };
|
|
33162
|
+
return { dsl: result ?? "", viewState, palette, theme, filename };
|
|
32006
33163
|
} catch {
|
|
32007
|
-
return { dsl: "", viewState, filename };
|
|
33164
|
+
return { dsl: "", viewState, palette, theme, filename };
|
|
32008
33165
|
}
|
|
32009
33166
|
}
|
|
32010
33167
|
|
|
@@ -32765,6 +33922,7 @@ init_branding();
|
|
|
32765
33922
|
RECOGNIZED_COLOR_NAMES,
|
|
32766
33923
|
RULE_COUNT,
|
|
32767
33924
|
addDurationToDate,
|
|
33925
|
+
applyCollapseProjection,
|
|
32768
33926
|
applyGroupOrdering,
|
|
32769
33927
|
applyPositionOverrides,
|
|
32770
33928
|
boldPalette,
|
|
@@ -32794,8 +33952,10 @@ init_branding();
|
|
|
32794
33952
|
computeTimeTicks,
|
|
32795
33953
|
contrastText,
|
|
32796
33954
|
decodeDiagramUrl,
|
|
33955
|
+
decodeViewState,
|
|
32797
33956
|
draculaPalette,
|
|
32798
33957
|
encodeDiagramUrl,
|
|
33958
|
+
encodeViewState,
|
|
32799
33959
|
extractDiagramSymbols,
|
|
32800
33960
|
extractTagDeclarations,
|
|
32801
33961
|
formatDateLabel,
|