@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.js
CHANGED
|
@@ -1,12 +1,35 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
2
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
3
7
|
var __esm = (fn, res) => function __init() {
|
|
4
8
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
9
|
};
|
|
10
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
11
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
12
|
+
};
|
|
6
13
|
var __export = (target, all) => {
|
|
7
14
|
for (var name in all)
|
|
8
15
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
16
|
};
|
|
17
|
+
var __copyProps = (to, from, except, desc) => {
|
|
18
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
19
|
+
for (let key of __getOwnPropNames(from))
|
|
20
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
21
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
22
|
+
}
|
|
23
|
+
return to;
|
|
24
|
+
};
|
|
25
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
26
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
27
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
28
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
29
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
30
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
31
|
+
mod
|
|
32
|
+
));
|
|
10
33
|
|
|
11
34
|
// src/diagnostics.ts
|
|
12
35
|
function makeDgmoError(line10, message, severity = "error") {
|
|
@@ -2077,7 +2100,7 @@ function measureLegendText(text, fontSize) {
|
|
|
2077
2100
|
}
|
|
2078
2101
|
return w;
|
|
2079
2102
|
}
|
|
2080
|
-
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;
|
|
2103
|
+
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;
|
|
2081
2104
|
var init_legend_constants = __esm({
|
|
2082
2105
|
"src/utils/legend-constants.ts"() {
|
|
2083
2106
|
"use strict";
|
|
@@ -2184,6 +2207,10 @@ var init_legend_constants = __esm({
|
|
|
2184
2207
|
DEFAULT_W = 0.56;
|
|
2185
2208
|
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";
|
|
2186
2209
|
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";
|
|
2210
|
+
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";
|
|
2211
|
+
LEGEND_TOGGLE_DOT_R = LEGEND_DOT_R;
|
|
2212
|
+
LEGEND_TOGGLE_OFF_OPACITY = 0.4;
|
|
2213
|
+
LEGEND_GEAR_PILL_W = 14 + LEGEND_PILL_PAD;
|
|
2187
2214
|
}
|
|
2188
2215
|
});
|
|
2189
2216
|
|
|
@@ -2229,13 +2256,13 @@ function capsuleWidth(name, entries, containerWidth, addonWidth = 0) {
|
|
|
2229
2256
|
visibleEntries: entries.length
|
|
2230
2257
|
};
|
|
2231
2258
|
}
|
|
2232
|
-
const rowWidth = maxCapsuleW - LEGEND_CAPSULE_PAD
|
|
2259
|
+
const rowWidth = maxCapsuleW - LEGEND_CAPSULE_PAD;
|
|
2233
2260
|
let row = 1;
|
|
2234
|
-
let rowX = pw + 4;
|
|
2261
|
+
let rowX = LEGEND_CAPSULE_PAD + pw + 4 + addonWidth;
|
|
2235
2262
|
let visible = 0;
|
|
2236
2263
|
for (let i = 0; i < entries.length; i++) {
|
|
2237
2264
|
const ew2 = entryWidth(entries[i].value);
|
|
2238
|
-
if (rowX + ew2 > rowWidth &&
|
|
2265
|
+
if (rowX + ew2 > rowWidth && i > 0) {
|
|
2239
2266
|
row++;
|
|
2240
2267
|
rowX = 0;
|
|
2241
2268
|
if (row > LEGEND_MAX_ENTRY_ROWS) {
|
|
@@ -2257,6 +2284,63 @@ function capsuleWidth(name, entries, containerWidth, addonWidth = 0) {
|
|
|
2257
2284
|
visibleEntries: entries.length
|
|
2258
2285
|
};
|
|
2259
2286
|
}
|
|
2287
|
+
function controlsGroupCapsuleWidth(toggles) {
|
|
2288
|
+
let w = LEGEND_CAPSULE_PAD * 2 + LEGEND_GEAR_PILL_W + 4;
|
|
2289
|
+
for (const t of toggles) {
|
|
2290
|
+
w += LEGEND_TOGGLE_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(t.label, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
2291
|
+
}
|
|
2292
|
+
return w;
|
|
2293
|
+
}
|
|
2294
|
+
function buildControlsGroupLayout(config, state) {
|
|
2295
|
+
const cg = config.controlsGroup;
|
|
2296
|
+
if (!cg || cg.toggles.length === 0) return void 0;
|
|
2297
|
+
const expanded = !!state.controlsExpanded;
|
|
2298
|
+
const pillH = LEGEND_HEIGHT - LEGEND_CAPSULE_PAD * 2;
|
|
2299
|
+
if (!expanded) {
|
|
2300
|
+
return {
|
|
2301
|
+
x: 0,
|
|
2302
|
+
y: 0,
|
|
2303
|
+
width: LEGEND_GEAR_PILL_W,
|
|
2304
|
+
height: LEGEND_HEIGHT,
|
|
2305
|
+
expanded: false,
|
|
2306
|
+
pill: { x: 0, y: 0, width: LEGEND_GEAR_PILL_W, height: LEGEND_HEIGHT },
|
|
2307
|
+
toggles: []
|
|
2308
|
+
};
|
|
2309
|
+
}
|
|
2310
|
+
const capsuleW = controlsGroupCapsuleWidth(cg.toggles);
|
|
2311
|
+
const toggleLayouts = [];
|
|
2312
|
+
let tx = LEGEND_CAPSULE_PAD + LEGEND_GEAR_PILL_W + 4;
|
|
2313
|
+
for (const toggle of cg.toggles) {
|
|
2314
|
+
const dotCx = tx + LEGEND_TOGGLE_DOT_R;
|
|
2315
|
+
const dotCy = LEGEND_HEIGHT / 2;
|
|
2316
|
+
const textX = tx + LEGEND_TOGGLE_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP;
|
|
2317
|
+
const textY = LEGEND_HEIGHT / 2;
|
|
2318
|
+
toggleLayouts.push({
|
|
2319
|
+
id: toggle.id,
|
|
2320
|
+
label: toggle.label,
|
|
2321
|
+
active: toggle.active,
|
|
2322
|
+
dotCx,
|
|
2323
|
+
dotCy,
|
|
2324
|
+
textX,
|
|
2325
|
+
textY
|
|
2326
|
+
});
|
|
2327
|
+
tx += LEGEND_TOGGLE_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(toggle.label, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
2328
|
+
}
|
|
2329
|
+
return {
|
|
2330
|
+
x: 0,
|
|
2331
|
+
y: 0,
|
|
2332
|
+
width: capsuleW,
|
|
2333
|
+
height: LEGEND_HEIGHT,
|
|
2334
|
+
expanded: true,
|
|
2335
|
+
pill: {
|
|
2336
|
+
x: LEGEND_CAPSULE_PAD,
|
|
2337
|
+
y: LEGEND_CAPSULE_PAD,
|
|
2338
|
+
width: LEGEND_GEAR_PILL_W - LEGEND_CAPSULE_PAD * 2,
|
|
2339
|
+
height: pillH
|
|
2340
|
+
},
|
|
2341
|
+
toggles: toggleLayouts
|
|
2342
|
+
};
|
|
2343
|
+
}
|
|
2260
2344
|
function computeLegendLayout(config, state, containerWidth) {
|
|
2261
2345
|
const { groups, controls: configControls, mode } = config;
|
|
2262
2346
|
const isExport = mode === "inline";
|
|
@@ -2271,8 +2355,9 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2271
2355
|
activeCapsule: void 0
|
|
2272
2356
|
};
|
|
2273
2357
|
}
|
|
2358
|
+
const controlsGroupLayout = isExport ? void 0 : buildControlsGroupLayout(config, state);
|
|
2274
2359
|
const visibleGroups = config.showEmptyGroups ? groups : groups.filter((g) => g.entries.length > 0);
|
|
2275
|
-
if (visibleGroups.length === 0 && (!configControls || configControls.length === 0)) {
|
|
2360
|
+
if (visibleGroups.length === 0 && (!configControls || configControls.length === 0) && !controlsGroupLayout) {
|
|
2276
2361
|
return {
|
|
2277
2362
|
height: 0,
|
|
2278
2363
|
width: 0,
|
|
@@ -2336,7 +2421,8 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2336
2421
|
if (totalControlsW > 0) totalControlsW -= CONTROL_GAP;
|
|
2337
2422
|
}
|
|
2338
2423
|
const controlsSpace = totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0;
|
|
2339
|
-
const
|
|
2424
|
+
const gearSpace = controlsGroupLayout ? controlsGroupLayout.width + LEGEND_GROUP_GAP : 0;
|
|
2425
|
+
const groupAvailW = containerWidth - controlsSpace - gearSpace;
|
|
2340
2426
|
const pills = [];
|
|
2341
2427
|
let activeCapsule;
|
|
2342
2428
|
for (const g of visibleGroups) {
|
|
@@ -2345,7 +2431,7 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2345
2431
|
if (isActive) {
|
|
2346
2432
|
activeCapsule = buildCapsuleLayout(
|
|
2347
2433
|
g,
|
|
2348
|
-
|
|
2434
|
+
groupAvailW,
|
|
2349
2435
|
config.capsulePillAddonWidth ?? 0
|
|
2350
2436
|
);
|
|
2351
2437
|
} else {
|
|
@@ -2368,7 +2454,8 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2368
2454
|
groupAvailW,
|
|
2369
2455
|
containerWidth,
|
|
2370
2456
|
totalControlsW,
|
|
2371
|
-
alignLeft
|
|
2457
|
+
alignLeft,
|
|
2458
|
+
controlsGroupLayout
|
|
2372
2459
|
);
|
|
2373
2460
|
const height = rows.length * LEGEND_HEIGHT;
|
|
2374
2461
|
const width = containerWidth;
|
|
@@ -2378,7 +2465,8 @@ function computeLegendLayout(config, state, containerWidth) {
|
|
|
2378
2465
|
rows,
|
|
2379
2466
|
activeCapsule,
|
|
2380
2467
|
controls: controlLayouts,
|
|
2381
|
-
pills
|
|
2468
|
+
pills,
|
|
2469
|
+
controlsGroup: controlsGroupLayout
|
|
2382
2470
|
};
|
|
2383
2471
|
}
|
|
2384
2472
|
function buildCapsuleLayout(group, containerWidth, addonWidth = 0) {
|
|
@@ -2401,7 +2489,7 @@ function buildCapsuleLayout(group, containerWidth, addonWidth = 0) {
|
|
|
2401
2489
|
let ex = LEGEND_CAPSULE_PAD + pw + 4 + addonWidth;
|
|
2402
2490
|
let ey = 0;
|
|
2403
2491
|
let rowX = ex;
|
|
2404
|
-
const maxRowW = containerWidth - LEGEND_CAPSULE_PAD
|
|
2492
|
+
const maxRowW = containerWidth - LEGEND_CAPSULE_PAD;
|
|
2405
2493
|
let currentRow = 0;
|
|
2406
2494
|
for (let i = 0; i < info.visibleEntries; i++) {
|
|
2407
2495
|
const entry = group.entries[i];
|
|
@@ -2442,19 +2530,27 @@ function buildCapsuleLayout(group, containerWidth, addonWidth = 0) {
|
|
|
2442
2530
|
addonX: addonWidth > 0 ? LEGEND_CAPSULE_PAD + pw + 4 : void 0
|
|
2443
2531
|
};
|
|
2444
2532
|
}
|
|
2445
|
-
function layoutRows(activeCapsule, pills, controls, groupAvailW, containerWidth, totalControlsW, alignLeft = false) {
|
|
2533
|
+
function layoutRows(activeCapsule, pills, controls, groupAvailW, containerWidth, totalControlsW, alignLeft = false, controlsGroup) {
|
|
2446
2534
|
const rows = [];
|
|
2447
2535
|
const groupItems = [];
|
|
2448
2536
|
if (activeCapsule) groupItems.push(activeCapsule);
|
|
2449
2537
|
groupItems.push(...pills);
|
|
2538
|
+
const gearW = controlsGroup ? controlsGroup.width + LEGEND_GROUP_GAP : 0;
|
|
2450
2539
|
let currentRowItems = [];
|
|
2451
2540
|
let currentRowW = 0;
|
|
2452
2541
|
let rowY = 0;
|
|
2453
2542
|
for (const item of groupItems) {
|
|
2454
2543
|
const itemW = item.width + LEGEND_GROUP_GAP;
|
|
2455
2544
|
if (currentRowW + item.width > groupAvailW && currentRowItems.length > 0) {
|
|
2456
|
-
if (!alignLeft)
|
|
2457
|
-
|
|
2545
|
+
if (!alignLeft) {
|
|
2546
|
+
const rowGearW = rows.length === 0 ? gearW : 0;
|
|
2547
|
+
centerRowItems(
|
|
2548
|
+
currentRowItems,
|
|
2549
|
+
containerWidth,
|
|
2550
|
+
totalControlsW,
|
|
2551
|
+
rowGearW
|
|
2552
|
+
);
|
|
2553
|
+
}
|
|
2458
2554
|
rows.push({ y: rowY, items: currentRowItems });
|
|
2459
2555
|
rowY += LEGEND_HEIGHT;
|
|
2460
2556
|
currentRowItems = [];
|
|
@@ -2482,19 +2578,32 @@ function layoutRows(activeCapsule, pills, controls, groupAvailW, containerWidth,
|
|
|
2482
2578
|
}
|
|
2483
2579
|
}
|
|
2484
2580
|
if (currentRowItems.length > 0) {
|
|
2485
|
-
centerRowItems(currentRowItems, containerWidth, totalControlsW);
|
|
2581
|
+
centerRowItems(currentRowItems, containerWidth, totalControlsW, gearW);
|
|
2486
2582
|
rows.push({ y: rowY, items: currentRowItems });
|
|
2487
2583
|
}
|
|
2584
|
+
if (controlsGroup) {
|
|
2585
|
+
const row0Items = rows[0]?.items ?? [];
|
|
2586
|
+
const groupItemsInRow0 = row0Items.filter(
|
|
2587
|
+
(it) => "groupName" in it
|
|
2588
|
+
);
|
|
2589
|
+
if (groupItemsInRow0.length > 0) {
|
|
2590
|
+
const last = groupItemsInRow0[groupItemsInRow0.length - 1];
|
|
2591
|
+
controlsGroup.x = last.x + last.width + LEGEND_GROUP_GAP;
|
|
2592
|
+
} else {
|
|
2593
|
+
controlsGroup.x = 0;
|
|
2594
|
+
}
|
|
2595
|
+
controlsGroup.y = 0;
|
|
2596
|
+
}
|
|
2488
2597
|
if (rows.length === 0) {
|
|
2489
2598
|
rows.push({ y: 0, items: [] });
|
|
2490
2599
|
}
|
|
2491
2600
|
return rows;
|
|
2492
2601
|
}
|
|
2493
|
-
function centerRowItems(items, containerWidth, totalControlsW) {
|
|
2602
|
+
function centerRowItems(items, containerWidth, totalControlsW, controlsGroupW = 0) {
|
|
2494
2603
|
const groupItems = items.filter((it) => "groupName" in it);
|
|
2495
2604
|
if (groupItems.length === 0) return;
|
|
2496
2605
|
const totalGroupW = groupItems.reduce((s, it) => s + it.width, 0) + (groupItems.length - 1) * LEGEND_GROUP_GAP;
|
|
2497
|
-
const availW = containerWidth - (totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0);
|
|
2606
|
+
const availW = containerWidth - (totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0) - controlsGroupW;
|
|
2498
2607
|
const offset = Math.max(0, (availW - totalGroupW) / 2);
|
|
2499
2608
|
let x = offset;
|
|
2500
2609
|
for (const item of groupItems) {
|
|
@@ -2552,6 +2661,17 @@ function renderLegendD3(container, config, state, palette, isDark, callbacks, co
|
|
|
2552
2661
|
for (const pill of currentLayout.pills) {
|
|
2553
2662
|
renderPill(legendG, pill, palette, groupBg, callbacks);
|
|
2554
2663
|
}
|
|
2664
|
+
if (currentLayout.controlsGroup) {
|
|
2665
|
+
renderControlsGroup(
|
|
2666
|
+
legendG,
|
|
2667
|
+
currentLayout.controlsGroup,
|
|
2668
|
+
palette,
|
|
2669
|
+
groupBg,
|
|
2670
|
+
pillBorder,
|
|
2671
|
+
callbacks,
|
|
2672
|
+
config
|
|
2673
|
+
);
|
|
2674
|
+
}
|
|
2555
2675
|
for (const ctrl of currentLayout.controls) {
|
|
2556
2676
|
renderControl(
|
|
2557
2677
|
legendG,
|
|
@@ -2666,6 +2786,57 @@ function renderControl(parent, ctrl, palette, _groupBg, pillBorder, _isDark, con
|
|
|
2666
2786
|
g.on("click", () => onClick());
|
|
2667
2787
|
}
|
|
2668
2788
|
}
|
|
2789
|
+
function renderControlsGroup(parent, layout, palette, groupBg, pillBorder, callbacks, config) {
|
|
2790
|
+
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");
|
|
2791
|
+
if (!layout.expanded) {
|
|
2792
|
+
g.append("rect").attr("width", layout.width).attr("height", layout.height).attr("rx", layout.height / 2).attr("fill", groupBg);
|
|
2793
|
+
const iconSize = 14;
|
|
2794
|
+
const iconX = (layout.width - iconSize) / 2;
|
|
2795
|
+
const iconY = (layout.height - iconSize) / 2;
|
|
2796
|
+
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");
|
|
2797
|
+
if (callbacks?.onControlsExpand) {
|
|
2798
|
+
const cb = callbacks.onControlsExpand;
|
|
2799
|
+
g.on("click", () => cb());
|
|
2800
|
+
}
|
|
2801
|
+
} else {
|
|
2802
|
+
const pill = layout.pill;
|
|
2803
|
+
g.append("rect").attr("width", layout.width).attr("height", layout.height).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
2804
|
+
const pillG = g.append("g").attr("class", "controls-gear-pill").style("cursor", "pointer");
|
|
2805
|
+
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);
|
|
2806
|
+
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);
|
|
2807
|
+
const iconSize = 14;
|
|
2808
|
+
const iconX = pill.x + (pill.width - iconSize) / 2;
|
|
2809
|
+
const iconY = pill.y + (pill.height - iconSize) / 2;
|
|
2810
|
+
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");
|
|
2811
|
+
if (callbacks?.onControlsExpand) {
|
|
2812
|
+
const cb = callbacks.onControlsExpand;
|
|
2813
|
+
pillG.on("click", (event) => {
|
|
2814
|
+
event.stopPropagation();
|
|
2815
|
+
cb();
|
|
2816
|
+
});
|
|
2817
|
+
}
|
|
2818
|
+
const toggles = config?.controlsGroup?.toggles ?? [];
|
|
2819
|
+
for (const tl of layout.toggles) {
|
|
2820
|
+
const toggle = toggles.find((t) => t.id === tl.id);
|
|
2821
|
+
const entryG = g.append("g").attr("data-controls-toggle", tl.id).style("cursor", "pointer");
|
|
2822
|
+
if (tl.active) {
|
|
2823
|
+
entryG.append("circle").attr("cx", tl.dotCx).attr("cy", tl.dotCy).attr("r", LEGEND_TOGGLE_DOT_R).attr("fill", palette.primary ?? palette.text);
|
|
2824
|
+
} else {
|
|
2825
|
+
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);
|
|
2826
|
+
}
|
|
2827
|
+
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);
|
|
2828
|
+
if (callbacks?.onControlsToggle && toggle) {
|
|
2829
|
+
const cb = callbacks.onControlsToggle;
|
|
2830
|
+
const id = tl.id;
|
|
2831
|
+
const newActive = !tl.active;
|
|
2832
|
+
entryG.on("click", (event) => {
|
|
2833
|
+
event.stopPropagation();
|
|
2834
|
+
cb(id, newActive);
|
|
2835
|
+
});
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
}
|
|
2669
2840
|
var init_legend_d3 = __esm({
|
|
2670
2841
|
"src/utils/legend-d3.ts"() {
|
|
2671
2842
|
"use strict";
|
|
@@ -3219,7 +3390,13 @@ function parseSequenceDgmo(content) {
|
|
|
3219
3390
|
const groupName = groupMatch[1].trim();
|
|
3220
3391
|
const groupColor = groupMatch[2]?.trim();
|
|
3221
3392
|
let groupMeta;
|
|
3222
|
-
|
|
3393
|
+
let afterBracket = groupMatch[3]?.trim() || "";
|
|
3394
|
+
let isCollapsed = false;
|
|
3395
|
+
const collapseMatch = afterBracket.match(/^collapse\b/i);
|
|
3396
|
+
if (collapseMatch) {
|
|
3397
|
+
isCollapsed = true;
|
|
3398
|
+
afterBracket = afterBracket.slice(collapseMatch[0].length).trim();
|
|
3399
|
+
}
|
|
3223
3400
|
if (afterBracket.startsWith("|")) {
|
|
3224
3401
|
const segments = afterBracket.split("|");
|
|
3225
3402
|
const meta = parsePipeMetadata(
|
|
@@ -3240,7 +3417,8 @@ function parseSequenceDgmo(content) {
|
|
|
3240
3417
|
name: groupName,
|
|
3241
3418
|
participantIds: [],
|
|
3242
3419
|
lineNumber,
|
|
3243
|
-
...groupMeta ? { metadata: groupMeta } : {}
|
|
3420
|
+
...groupMeta ? { metadata: groupMeta } : {},
|
|
3421
|
+
...isCollapsed ? { collapsed: true } : {}
|
|
3244
3422
|
};
|
|
3245
3423
|
result.groups.push(activeGroup);
|
|
3246
3424
|
continue;
|
|
@@ -10337,7 +10515,7 @@ function addBusinessDays(startDate, count, workweek, holidaySet, direction = 1)
|
|
|
10337
10515
|
}
|
|
10338
10516
|
return current;
|
|
10339
10517
|
}
|
|
10340
|
-
function addGanttDuration(startDate, duration, holidays, holidaySet, direction = 1) {
|
|
10518
|
+
function addGanttDuration(startDate, duration, holidays, holidaySet, direction = 1, opts) {
|
|
10341
10519
|
const { amount, unit } = duration;
|
|
10342
10520
|
switch (unit) {
|
|
10343
10521
|
case "bd":
|
|
@@ -10399,10 +10577,22 @@ function addGanttDuration(startDate, duration, holidays, holidaySet, direction =
|
|
|
10399
10577
|
result.setTime(result.getTime() + amount * 6e4 * direction);
|
|
10400
10578
|
return result;
|
|
10401
10579
|
}
|
|
10580
|
+
case "s": {
|
|
10581
|
+
if (!opts?.sprintLength) {
|
|
10582
|
+
throw new Error(
|
|
10583
|
+
'Sprint duration unit "s" requires sprintLength configuration'
|
|
10584
|
+
);
|
|
10585
|
+
}
|
|
10586
|
+
const sl = opts.sprintLength;
|
|
10587
|
+
const totalDays = amount * sl.amount * (sl.unit === "w" ? 7 : 1);
|
|
10588
|
+
const result = new Date(startDate);
|
|
10589
|
+
result.setDate(result.getDate() + Math.round(totalDays) * direction);
|
|
10590
|
+
return result;
|
|
10591
|
+
}
|
|
10402
10592
|
}
|
|
10403
10593
|
}
|
|
10404
10594
|
function parseDuration(s) {
|
|
10405
|
-
const match = s.trim().match(/^(\d+(?:\.\d+)?)(min|bd|d|w|m|q|y|h)$/);
|
|
10595
|
+
const match = s.trim().match(/^(\d+(?:\.\d+)?)(min|bd|d|w|m|q|y|h|s)$/);
|
|
10406
10596
|
if (!match) return null;
|
|
10407
10597
|
return { amount: parseFloat(match[1]), unit: match[2] };
|
|
10408
10598
|
}
|
|
@@ -10489,7 +10679,11 @@ function parseGantt(content, palette) {
|
|
|
10489
10679
|
defaultSwimlaneGroup: null,
|
|
10490
10680
|
activeTag: null,
|
|
10491
10681
|
optionLineNumbers: {},
|
|
10492
|
-
holidaysLineNumber: null
|
|
10682
|
+
holidaysLineNumber: null,
|
|
10683
|
+
sprintLength: null,
|
|
10684
|
+
sprintNumber: null,
|
|
10685
|
+
sprintStart: null,
|
|
10686
|
+
sprintMode: null
|
|
10493
10687
|
},
|
|
10494
10688
|
diagnostics,
|
|
10495
10689
|
error: null
|
|
@@ -10905,6 +11099,55 @@ function parseGantt(content, palette) {
|
|
|
10905
11099
|
case "active-tag":
|
|
10906
11100
|
result.options.activeTag = value;
|
|
10907
11101
|
break;
|
|
11102
|
+
case "sprint-length": {
|
|
11103
|
+
const dur = parseDuration(value);
|
|
11104
|
+
if (!dur) {
|
|
11105
|
+
warn(
|
|
11106
|
+
lineNumber,
|
|
11107
|
+
`Invalid sprint-length value: "${value}". Expected a duration like "2w" or "10d".`
|
|
11108
|
+
);
|
|
11109
|
+
} else if (dur.unit !== "d" && dur.unit !== "w") {
|
|
11110
|
+
warn(
|
|
11111
|
+
lineNumber,
|
|
11112
|
+
`sprint-length only accepts "d" or "w" units, got "${dur.unit}".`
|
|
11113
|
+
);
|
|
11114
|
+
} else if (dur.amount <= 0) {
|
|
11115
|
+
warn(lineNumber, `sprint-length must be greater than 0.`);
|
|
11116
|
+
} else if (!Number.isInteger(dur.amount * (dur.unit === "w" ? 7 : 1))) {
|
|
11117
|
+
warn(
|
|
11118
|
+
lineNumber,
|
|
11119
|
+
`sprint-length must resolve to a whole number of days.`
|
|
11120
|
+
);
|
|
11121
|
+
} else {
|
|
11122
|
+
result.options.sprintLength = dur;
|
|
11123
|
+
}
|
|
11124
|
+
break;
|
|
11125
|
+
}
|
|
11126
|
+
case "sprint-number": {
|
|
11127
|
+
const n = Number(value);
|
|
11128
|
+
if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) {
|
|
11129
|
+
warn(
|
|
11130
|
+
lineNumber,
|
|
11131
|
+
`sprint-number must be a positive integer, got "${value}".`
|
|
11132
|
+
);
|
|
11133
|
+
} else {
|
|
11134
|
+
result.options.sprintNumber = n;
|
|
11135
|
+
}
|
|
11136
|
+
break;
|
|
11137
|
+
}
|
|
11138
|
+
case "sprint-start": {
|
|
11139
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
11140
|
+
warn(
|
|
11141
|
+
lineNumber,
|
|
11142
|
+
`sprint-start requires a full date (YYYY-MM-DD), got "${value}".`
|
|
11143
|
+
);
|
|
11144
|
+
} else if (Number.isNaN((/* @__PURE__ */ new Date(value + "T00:00:00")).getTime())) {
|
|
11145
|
+
warn(lineNumber, `sprint-start is not a valid date: "${value}".`);
|
|
11146
|
+
} else {
|
|
11147
|
+
result.options.sprintStart = value;
|
|
11148
|
+
}
|
|
11149
|
+
break;
|
|
11150
|
+
}
|
|
10908
11151
|
}
|
|
10909
11152
|
continue;
|
|
10910
11153
|
}
|
|
@@ -11085,6 +11328,21 @@ function parseGantt(content, palette) {
|
|
|
11085
11328
|
result.options.sort = "default";
|
|
11086
11329
|
}
|
|
11087
11330
|
validateTagGroupNames(result.tagGroups, warn);
|
|
11331
|
+
const hasSprintOption = result.options.sprintLength !== null || result.options.sprintNumber !== null || result.options.sprintStart !== null;
|
|
11332
|
+
const hasSprintUnit = hasSprintDurationUnit(result.nodes);
|
|
11333
|
+
if (hasSprintOption) {
|
|
11334
|
+
result.options.sprintMode = "explicit";
|
|
11335
|
+
} else if (hasSprintUnit) {
|
|
11336
|
+
result.options.sprintMode = "auto";
|
|
11337
|
+
}
|
|
11338
|
+
if (result.options.sprintMode) {
|
|
11339
|
+
if (!result.options.sprintLength) {
|
|
11340
|
+
result.options.sprintLength = { amount: 2, unit: "w" };
|
|
11341
|
+
}
|
|
11342
|
+
if (result.options.sprintNumber === null) {
|
|
11343
|
+
result.options.sprintNumber = 1;
|
|
11344
|
+
}
|
|
11345
|
+
}
|
|
11088
11346
|
return result;
|
|
11089
11347
|
function makeTask(labelRaw, duration, uncertain, ln, explicitStart) {
|
|
11090
11348
|
const segments = labelRaw.split("|");
|
|
@@ -11202,6 +11460,16 @@ function parseWorkweek(s) {
|
|
|
11202
11460
|
function isKnownOption(key) {
|
|
11203
11461
|
return KNOWN_OPTIONS5.has(key);
|
|
11204
11462
|
}
|
|
11463
|
+
function hasSprintDurationUnit(nodes) {
|
|
11464
|
+
for (const node of nodes) {
|
|
11465
|
+
if (node.kind === "task") {
|
|
11466
|
+
if (node.duration?.unit === "s") return true;
|
|
11467
|
+
} else if (node.kind === "group" || node.kind === "parallel") {
|
|
11468
|
+
if (hasSprintDurationUnit(node.children)) return true;
|
|
11469
|
+
}
|
|
11470
|
+
}
|
|
11471
|
+
return false;
|
|
11472
|
+
}
|
|
11205
11473
|
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;
|
|
11206
11474
|
var init_parser9 = __esm({
|
|
11207
11475
|
"src/gantt/parser.ts"() {
|
|
@@ -11211,9 +11479,9 @@ var init_parser9 = __esm({
|
|
|
11211
11479
|
init_parsing();
|
|
11212
11480
|
init_duration();
|
|
11213
11481
|
init_palettes();
|
|
11214
|
-
DURATION_RE = /^(\d+(?:\.\d+)?)(min|bd|d|w|m|q|y|h)(\?)?\s+(.+)$/;
|
|
11482
|
+
DURATION_RE = /^(\d+(?:\.\d+)?)(min|bd|d|w|m|q|y|h|s)(\?)?\s+(.+)$/;
|
|
11215
11483
|
EXPLICIT_DATE_RE = /^(\d{4}-\d{2}-\d{2}(?: \d{2}:\d{2})?)\s+(.+)$/;
|
|
11216
|
-
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+(.+)$/;
|
|
11484
|
+
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+(.+)$/;
|
|
11217
11485
|
GROUP_RE2 = /^\[(.+?)\]\s*(.*)$/;
|
|
11218
11486
|
DEPENDENCY_RE = /^(?:-(.+?))?->\s*(.+)$/;
|
|
11219
11487
|
COMMENT_RE = /^\/\//;
|
|
@@ -11248,7 +11516,10 @@ var init_parser9 = __esm({
|
|
|
11248
11516
|
"dependencies",
|
|
11249
11517
|
"chart",
|
|
11250
11518
|
"sort",
|
|
11251
|
-
"active-tag"
|
|
11519
|
+
"active-tag",
|
|
11520
|
+
"sprint-length",
|
|
11521
|
+
"sprint-number",
|
|
11522
|
+
"sprint-start"
|
|
11252
11523
|
]);
|
|
11253
11524
|
KNOWN_BOOLEANS4 = /* @__PURE__ */ new Set([
|
|
11254
11525
|
"critical-path",
|
|
@@ -22645,6 +22916,7 @@ function calculateSchedule(parsed) {
|
|
|
22645
22916
|
tagGroups: parsed.tagGroups,
|
|
22646
22917
|
eras: parsed.eras,
|
|
22647
22918
|
markers: parsed.markers,
|
|
22919
|
+
sprints: [],
|
|
22648
22920
|
options: parsed.options,
|
|
22649
22921
|
diagnostics,
|
|
22650
22922
|
error: parsed.error
|
|
@@ -22666,6 +22938,7 @@ function calculateSchedule(parsed) {
|
|
|
22666
22938
|
} else {
|
|
22667
22939
|
projectStart = new Date(2e3, 0, 1);
|
|
22668
22940
|
}
|
|
22941
|
+
const sprintOpts = parsed.options.sprintLength ? { sprintLength: parsed.options.sprintLength } : void 0;
|
|
22669
22942
|
const depOffsetMap = /* @__PURE__ */ new Map();
|
|
22670
22943
|
const allTasks = collectTasks(parsed.nodes);
|
|
22671
22944
|
if (allTasks.length === 0) {
|
|
@@ -22747,7 +23020,8 @@ function calculateSchedule(parsed) {
|
|
|
22747
23020
|
depOffset.duration,
|
|
22748
23021
|
parsed.holidays,
|
|
22749
23022
|
holidaySet,
|
|
22750
|
-
depOffset.direction
|
|
23023
|
+
depOffset.direction,
|
|
23024
|
+
sprintOpts
|
|
22751
23025
|
);
|
|
22752
23026
|
}
|
|
22753
23027
|
if (predEnd.getTime() > start.getTime()) {
|
|
@@ -22761,7 +23035,8 @@ function calculateSchedule(parsed) {
|
|
|
22761
23035
|
task.offset.duration,
|
|
22762
23036
|
parsed.holidays,
|
|
22763
23037
|
holidaySet,
|
|
22764
|
-
task.offset.direction
|
|
23038
|
+
task.offset.direction,
|
|
23039
|
+
sprintOpts
|
|
22765
23040
|
);
|
|
22766
23041
|
if (start.getTime() < projectStart.getTime()) {
|
|
22767
23042
|
warn(
|
|
@@ -22801,7 +23076,9 @@ function calculateSchedule(parsed) {
|
|
|
22801
23076
|
start,
|
|
22802
23077
|
task.duration,
|
|
22803
23078
|
parsed.holidays,
|
|
22804
|
-
holidaySet
|
|
23079
|
+
holidaySet,
|
|
23080
|
+
1,
|
|
23081
|
+
sprintOpts
|
|
22805
23082
|
);
|
|
22806
23083
|
}
|
|
22807
23084
|
} else {
|
|
@@ -22815,7 +23092,8 @@ function calculateSchedule(parsed) {
|
|
|
22815
23092
|
taskMap,
|
|
22816
23093
|
depOffsetMap,
|
|
22817
23094
|
parsed.holidays,
|
|
22818
|
-
holidaySet
|
|
23095
|
+
holidaySet,
|
|
23096
|
+
sprintOpts
|
|
22819
23097
|
) : /* @__PURE__ */ new Set();
|
|
22820
23098
|
const uncertainSet = /* @__PURE__ */ new Set();
|
|
22821
23099
|
for (const taskId of sortedIds) {
|
|
@@ -22855,6 +23133,20 @@ function calculateSchedule(parsed) {
|
|
|
22855
23133
|
result.startDate = minDate;
|
|
22856
23134
|
result.endDate = maxDate;
|
|
22857
23135
|
}
|
|
23136
|
+
if (parsed.options.sprintMode && parsed.options.sprintLength && result.tasks.length > 0) {
|
|
23137
|
+
result.sprints = generateSprintBands(
|
|
23138
|
+
parsed.options,
|
|
23139
|
+
result.startDate,
|
|
23140
|
+
result.endDate,
|
|
23141
|
+
projectStart
|
|
23142
|
+
);
|
|
23143
|
+
if (result.sprints.length > 0) {
|
|
23144
|
+
const lastSprintEnd = result.sprints[result.sprints.length - 1].endDate;
|
|
23145
|
+
if (lastSprintEnd.getTime() > result.endDate.getTime()) {
|
|
23146
|
+
result.endDate = lastSprintEnd;
|
|
23147
|
+
}
|
|
23148
|
+
}
|
|
23149
|
+
}
|
|
22858
23150
|
const topLevelGroups = parsed.nodes.filter((n) => n.kind === "group");
|
|
22859
23151
|
if (topLevelGroups.length >= 2) {
|
|
22860
23152
|
const names = topLevelGroups.map(
|
|
@@ -23055,7 +23347,7 @@ function breakCycle(cycle, taskMap, depOffsetMap) {
|
|
|
23055
23347
|
}
|
|
23056
23348
|
}
|
|
23057
23349
|
}
|
|
23058
|
-
function computeCriticalPath(sortedIds, taskMap, depOffsetMap, holidays, holidaySet) {
|
|
23350
|
+
function computeCriticalPath(sortedIds, taskMap, depOffsetMap, holidays, holidaySet, sprintOpts) {
|
|
23059
23351
|
if (sortedIds.length === 0) return /* @__PURE__ */ new Set();
|
|
23060
23352
|
const latestEnd = /* @__PURE__ */ new Map();
|
|
23061
23353
|
const latestStart = /* @__PURE__ */ new Map();
|
|
@@ -23093,7 +23385,8 @@ function computeCriticalPath(sortedIds, taskMap, depOffsetMap, holidays, holiday
|
|
|
23093
23385
|
succTask.offset.duration,
|
|
23094
23386
|
holidays,
|
|
23095
23387
|
holidaySet,
|
|
23096
|
-
reverseDir
|
|
23388
|
+
reverseDir,
|
|
23389
|
+
sprintOpts
|
|
23097
23390
|
);
|
|
23098
23391
|
succLS = adjusted.getTime();
|
|
23099
23392
|
}
|
|
@@ -23105,7 +23398,8 @@ function computeCriticalPath(sortedIds, taskMap, depOffsetMap, holidays, holiday
|
|
|
23105
23398
|
depOffset.duration,
|
|
23106
23399
|
holidays,
|
|
23107
23400
|
holidaySet,
|
|
23108
|
-
reverseDir
|
|
23401
|
+
reverseDir,
|
|
23402
|
+
sprintOpts
|
|
23109
23403
|
);
|
|
23110
23404
|
succLS = adjusted.getTime();
|
|
23111
23405
|
}
|
|
@@ -23180,6 +23474,51 @@ function buildResolvedGroups(nodes, taskMap, groups, depth) {
|
|
|
23180
23474
|
}
|
|
23181
23475
|
}
|
|
23182
23476
|
}
|
|
23477
|
+
function generateSprintBands(options, chartStart, chartEnd, projectStart) {
|
|
23478
|
+
const sprintLength = options.sprintLength;
|
|
23479
|
+
const sprintNumber = options.sprintNumber ?? 1;
|
|
23480
|
+
let anchorDate;
|
|
23481
|
+
if (options.sprintStart) {
|
|
23482
|
+
anchorDate = /* @__PURE__ */ new Date(options.sprintStart + "T00:00:00");
|
|
23483
|
+
} else if (options.start) {
|
|
23484
|
+
anchorDate = new Date(projectStart);
|
|
23485
|
+
} else {
|
|
23486
|
+
const now = /* @__PURE__ */ new Date();
|
|
23487
|
+
anchorDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
23488
|
+
}
|
|
23489
|
+
anchorDate.setHours(0, 0, 0, 0);
|
|
23490
|
+
const sprintDays = Math.round(
|
|
23491
|
+
sprintLength.amount * (sprintLength.unit === "w" ? 7 : 1)
|
|
23492
|
+
);
|
|
23493
|
+
if (sprintDays <= 0) return [];
|
|
23494
|
+
if (Number.isNaN(anchorDate.getTime())) return [];
|
|
23495
|
+
const chartStartTime = new Date(chartStart);
|
|
23496
|
+
chartStartTime.setHours(0, 0, 0, 0);
|
|
23497
|
+
const chartEndTime = new Date(chartEnd);
|
|
23498
|
+
chartEndTime.setHours(0, 0, 0, 0);
|
|
23499
|
+
const msPerDay = 864e5;
|
|
23500
|
+
const dayDiff = Math.floor(
|
|
23501
|
+
(chartStartTime.getTime() - anchorDate.getTime()) / msPerDay
|
|
23502
|
+
);
|
|
23503
|
+
const startSprintIndex = Math.floor(dayDiff / sprintDays);
|
|
23504
|
+
const sprints = [];
|
|
23505
|
+
const maxSprints = 1e3;
|
|
23506
|
+
for (let i = startSprintIndex; sprints.length < maxSprints; i++) {
|
|
23507
|
+
const sprintStartDate = new Date(anchorDate);
|
|
23508
|
+
sprintStartDate.setDate(sprintStartDate.getDate() + i * sprintDays);
|
|
23509
|
+
sprintStartDate.setHours(0, 0, 0, 0);
|
|
23510
|
+
const sprintEndDate = new Date(sprintStartDate);
|
|
23511
|
+
sprintEndDate.setDate(sprintEndDate.getDate() + sprintDays);
|
|
23512
|
+
sprintEndDate.setHours(0, 0, 0, 0);
|
|
23513
|
+
if (sprintStartDate.getTime() >= chartEndTime.getTime() + msPerDay) break;
|
|
23514
|
+
sprints.push({
|
|
23515
|
+
number: sprintNumber + i,
|
|
23516
|
+
startDate: sprintStartDate,
|
|
23517
|
+
endDate: sprintEndDate
|
|
23518
|
+
});
|
|
23519
|
+
}
|
|
23520
|
+
return sprints;
|
|
23521
|
+
}
|
|
23183
23522
|
function formatDate(d) {
|
|
23184
23523
|
const y = d.getFullYear();
|
|
23185
23524
|
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
@@ -23265,6 +23604,8 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23265
23604
|
options?.currentActiveGroup
|
|
23266
23605
|
);
|
|
23267
23606
|
let criticalPathActive = false;
|
|
23607
|
+
let dependenciesActive = !!resolved.options.dependencies;
|
|
23608
|
+
let controlsExpanded = false;
|
|
23268
23609
|
const tagRows = currentSwimlaneGroup ? buildTagLaneRowList(resolved, currentSwimlaneGroup, collapsedLanes) : null;
|
|
23269
23610
|
const rows = tagRows ?? buildRowList(resolved, collapsedGroups);
|
|
23270
23611
|
const isTagMode = tagRows !== null;
|
|
@@ -23281,28 +23622,31 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23281
23622
|
const maxLabelLen = Math.max(...allLabels.map((l) => l.length), 10);
|
|
23282
23623
|
const leftMargin = Math.max(MIN_LEFT_MARGIN, maxLabelLen * 7 + 30);
|
|
23283
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);
|
|
23284
23627
|
const title = resolved.options.title;
|
|
23285
23628
|
const titleHeight = title ? 50 : 20;
|
|
23286
|
-
const tagLegendReserve = resolved.tagGroups.length > 0 ? LEGEND_HEIGHT + 8 : 0;
|
|
23629
|
+
const tagLegendReserve = resolved.tagGroups.length > 0 || hasCriticalPath || hasDependencies ? LEGEND_HEIGHT + 8 : 0;
|
|
23287
23630
|
const topDateLabelReserve = 22;
|
|
23288
23631
|
const hasOverheadLabels = resolved.markers.length > 0 || resolved.eras.length > 0;
|
|
23289
|
-
const markerLabelReserve = hasOverheadLabels ?
|
|
23632
|
+
const markerLabelReserve = hasOverheadLabels ? 28 : 0;
|
|
23633
|
+
const sprintLabelReserve = resolved.sprints.length > 0 ? 16 : 0;
|
|
23290
23634
|
const CONTENT_TOP_PAD = 16;
|
|
23291
|
-
const marginTop = titleHeight + tagLegendReserve + topDateLabelReserve + markerLabelReserve;
|
|
23635
|
+
const marginTop = titleHeight + tagLegendReserve + topDateLabelReserve + markerLabelReserve + sprintLabelReserve;
|
|
23292
23636
|
const contentH = isTagMode ? totalRows * (BAR_H + ROW_GAP) : totalRows * (BAR_H + ROW_GAP) + GROUP_GAP2 * resolved.groups.length;
|
|
23293
23637
|
const innerHeight = CONTENT_TOP_PAD + contentH;
|
|
23294
23638
|
const outerHeight = marginTop + innerHeight + BOTTOM_MARGIN;
|
|
23295
23639
|
const containerWidth = exportDims?.width ?? (container.clientWidth || 800);
|
|
23296
|
-
const
|
|
23640
|
+
const sprintRightPad = resolved.sprints.length > 0 ? 50 : 0;
|
|
23641
|
+
const innerWidth = containerWidth - leftMargin - RIGHT_MARGIN - sprintRightPad;
|
|
23297
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");
|
|
23298
23643
|
const g = svg.append("g").attr("transform", `translate(${leftMargin}, ${marginTop})`);
|
|
23299
23644
|
if (title) {
|
|
23300
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);
|
|
23301
23646
|
}
|
|
23302
|
-
const hasCriticalPath = resolved.options.criticalPath && resolved.tasks.some((t) => t.isCriticalPath);
|
|
23303
23647
|
function drawLegend() {
|
|
23304
23648
|
svg.selectAll(".gantt-tag-legend-container").remove();
|
|
23305
|
-
if (resolved.tagGroups.length > 0 || hasCriticalPath) {
|
|
23649
|
+
if (resolved.tagGroups.length > 0 || hasCriticalPath || hasDependencies) {
|
|
23306
23650
|
const legendY = titleHeight;
|
|
23307
23651
|
renderTagLegend(
|
|
23308
23652
|
svg,
|
|
@@ -23324,16 +23668,38 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23324
23668
|
recolorBars();
|
|
23325
23669
|
},
|
|
23326
23670
|
() => {
|
|
23327
|
-
|
|
23671
|
+
controlsExpanded = !controlsExpanded;
|
|
23328
23672
|
drawLegend();
|
|
23329
23673
|
},
|
|
23330
23674
|
currentSwimlaneGroup,
|
|
23331
23675
|
onSwimlaneChange,
|
|
23332
23676
|
viewMode,
|
|
23333
|
-
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
|
+
}
|
|
23334
23692
|
);
|
|
23335
23693
|
}
|
|
23336
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
|
+
}
|
|
23337
23703
|
function recolorBars() {
|
|
23338
23704
|
g.selectAll(".gantt-task").each(function() {
|
|
23339
23705
|
const el = d3Selection10.select(this);
|
|
@@ -23373,6 +23739,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23373
23739
|
onClickItem
|
|
23374
23740
|
);
|
|
23375
23741
|
renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette);
|
|
23742
|
+
renderSprintBands(g, svg, resolved, xScale, innerHeight, palette);
|
|
23376
23743
|
let todayDate = null;
|
|
23377
23744
|
let todayX = -1;
|
|
23378
23745
|
const todayColor = palette.accent || "#e74c3c";
|
|
@@ -23458,7 +23825,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23458
23825
|
);
|
|
23459
23826
|
}
|
|
23460
23827
|
}).on("mouseleave", () => {
|
|
23461
|
-
|
|
23828
|
+
restoreHighlight();
|
|
23462
23829
|
hideGanttDateIndicators(g);
|
|
23463
23830
|
});
|
|
23464
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(
|
|
@@ -23663,7 +24030,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23663
24030
|
);
|
|
23664
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);
|
|
23665
24032
|
}).on("mouseleave", () => {
|
|
23666
|
-
|
|
24033
|
+
restoreHighlight();
|
|
23667
24034
|
hideGanttDateIndicators(g);
|
|
23668
24035
|
g.selectAll(".gantt-milestone-hover-label").remove();
|
|
23669
24036
|
});
|
|
@@ -23692,11 +24059,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
|
|
|
23692
24059
|
);
|
|
23693
24060
|
}).on("mouseleave", () => {
|
|
23694
24061
|
if (resolved.options.dependencies) {
|
|
23695
|
-
|
|
23696
|
-
applyCriticalPathHighlight(svg, g);
|
|
23697
|
-
} else {
|
|
23698
|
-
resetHighlight(g, svg);
|
|
23699
|
-
}
|
|
24062
|
+
restoreHighlight();
|
|
23700
24063
|
}
|
|
23701
24064
|
resetTaskLabels(svg);
|
|
23702
24065
|
hideGanttDateIndicators(g);
|
|
@@ -24011,6 +24374,7 @@ function arrowheadPoints(x, y, size, angle) {
|
|
|
24011
24374
|
return `${x},${y} ${x + size * Math.cos(a1)},${y + size * Math.sin(a1)} ${x + size * Math.cos(a2)},${y + size * Math.sin(a2)}`;
|
|
24012
24375
|
}
|
|
24013
24376
|
function applyCriticalPathHighlight(svg, chartG) {
|
|
24377
|
+
svg.attr("data-critical-path-active", "true");
|
|
24014
24378
|
chartG.selectAll(".gantt-task").each(function() {
|
|
24015
24379
|
const el = d3Selection10.select(this);
|
|
24016
24380
|
el.attr(
|
|
@@ -24063,8 +24427,31 @@ function drawSwimlaneIcon2(parent, x, y, isActive, palette) {
|
|
|
24063
24427
|
}
|
|
24064
24428
|
return iconG;
|
|
24065
24429
|
}
|
|
24066
|
-
function
|
|
24067
|
-
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) {
|
|
24068
24455
|
let visibleGroups;
|
|
24069
24456
|
if (activeGroupName) {
|
|
24070
24457
|
const activeGroup = tagGroups.filter(
|
|
@@ -24125,16 +24512,17 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24125
24512
|
totalW += groupW;
|
|
24126
24513
|
}
|
|
24127
24514
|
totalW += Math.max(0, (visibleGroups.length - 1) * LEGEND_GROUP_GAP);
|
|
24128
|
-
const
|
|
24129
|
-
const
|
|
24130
|
-
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) {
|
|
24131
24520
|
if (visibleGroups.length > 0) totalW += LEGEND_GROUP_GAP;
|
|
24132
|
-
totalW +=
|
|
24521
|
+
totalW += controlsExpanded ? controlsGroupCapsuleWidth(controlsToggleLabels) : LEGEND_GEAR_PILL_W;
|
|
24133
24522
|
}
|
|
24134
24523
|
const containerWidth = chartLeftMargin + chartInnerWidth + RIGHT_MARGIN;
|
|
24135
24524
|
const legendX = (containerWidth - totalW) / 2;
|
|
24136
24525
|
const legendRow = svg.append("g").attr("class", "gantt-tag-legend-container").attr("transform", `translate(${legendX}, ${legendY})`);
|
|
24137
|
-
let cursorX = 0;
|
|
24138
24526
|
if (visibleGroups.length > 0) {
|
|
24139
24527
|
const showIcon = !legendViewMode && tagGroups.length > 0;
|
|
24140
24528
|
const iconReserve = showIcon ? LEGEND_ICON_W : 0;
|
|
@@ -24146,6 +24534,12 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24146
24534
|
entries: entries.map((e) => ({ value: e.value, color: e.color }))
|
|
24147
24535
|
};
|
|
24148
24536
|
});
|
|
24537
|
+
const controlsToggles = buildControlsToggles(
|
|
24538
|
+
hasCriticalPath,
|
|
24539
|
+
criticalPathActive,
|
|
24540
|
+
hasDependencies,
|
|
24541
|
+
dependenciesActive
|
|
24542
|
+
);
|
|
24149
24543
|
const legendConfig = {
|
|
24150
24544
|
groups: legendGroups,
|
|
24151
24545
|
position: {
|
|
@@ -24153,13 +24547,23 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24153
24547
|
titleRelation: "below-title"
|
|
24154
24548
|
},
|
|
24155
24549
|
mode: "fixed",
|
|
24156
|
-
capsulePillAddonWidth: iconReserve
|
|
24550
|
+
capsulePillAddonWidth: iconReserve,
|
|
24551
|
+
controlsGroup: controlsToggles.length > 0 ? { toggles: controlsToggles } : void 0
|
|
24552
|
+
};
|
|
24553
|
+
const legendState = {
|
|
24554
|
+
activeGroup: activeGroupName,
|
|
24555
|
+
controlsExpanded
|
|
24157
24556
|
};
|
|
24158
|
-
|
|
24159
|
-
|
|
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
|
+
}
|
|
24160
24562
|
const tagGroupG = legendRow.append("g");
|
|
24161
24563
|
const legendCallbacks = {
|
|
24162
24564
|
onGroupToggle: onToggle,
|
|
24565
|
+
onControlsExpand: onToggleControlsExpand,
|
|
24566
|
+
onControlsToggle,
|
|
24163
24567
|
onEntryHover: (groupName, entryValue) => {
|
|
24164
24568
|
const tagKey = groupName.toLowerCase();
|
|
24165
24569
|
if (entryValue) {
|
|
@@ -24236,31 +24640,38 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
24236
24640
|
legendCallbacks,
|
|
24237
24641
|
tagGroupsW
|
|
24238
24642
|
);
|
|
24239
|
-
|
|
24240
|
-
|
|
24241
|
-
|
|
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
|
+
);
|
|
24242
24672
|
}
|
|
24243
|
-
if (
|
|
24244
|
-
|
|
24245
|
-
const cpG = legendRow.append("g").attr("transform", `translate(${cursorX}, 0)`).attr("class", "gantt-legend-critical-path").style("cursor", "pointer").on("click", () => {
|
|
24246
|
-
if (onToggleCriticalPath) onToggleCriticalPath();
|
|
24247
|
-
});
|
|
24248
|
-
if (cpLineNum) cpG.attr("data-line-number", String(cpLineNum));
|
|
24249
|
-
cpG.append("rect").attr("width", cpPillW).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", criticalPathActive ? palette.bg : groupBg);
|
|
24250
|
-
if (criticalPathActive) {
|
|
24251
|
-
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);
|
|
24252
|
-
}
|
|
24253
|
-
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);
|
|
24254
|
-
if (criticalPathActive) {
|
|
24255
|
-
applyCriticalPathHighlight(svg, chartG);
|
|
24256
|
-
}
|
|
24257
|
-
cpG.on("mouseenter", () => {
|
|
24258
|
-
applyCriticalPathHighlight(svg, chartG);
|
|
24259
|
-
}).on("mouseleave", () => {
|
|
24260
|
-
if (!criticalPathActive) {
|
|
24261
|
-
resetHighlightAll(svg, chartG);
|
|
24262
|
-
}
|
|
24263
|
-
});
|
|
24673
|
+
if (criticalPathActive) {
|
|
24674
|
+
applyCriticalPathHighlight(svg, chartG);
|
|
24264
24675
|
}
|
|
24265
24676
|
}
|
|
24266
24677
|
function renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette) {
|
|
@@ -24276,7 +24687,7 @@ function renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette) {
|
|
|
24276
24687
|
const eraEndDate = parseDateStringToDate(era.endDate);
|
|
24277
24688
|
const eraG = g.append("g").attr("class", "gantt-era-group").attr("data-line-number", String(era.lineNumber));
|
|
24278
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);
|
|
24279
|
-
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);
|
|
24280
24691
|
eraG.on("mouseenter", () => {
|
|
24281
24692
|
g.selectAll(".gantt-task").attr(
|
|
24282
24693
|
"opacity",
|
|
@@ -24322,8 +24733,8 @@ function renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette) {
|
|
|
24322
24733
|
const mx = xScale(parseDateToFractionalYear(marker.date));
|
|
24323
24734
|
const markerDate = parseDateStringToDate(marker.date);
|
|
24324
24735
|
const diamondSize = 5;
|
|
24325
|
-
const labelY = -
|
|
24326
|
-
const diamondY =
|
|
24736
|
+
const labelY = -34;
|
|
24737
|
+
const diamondY = -2;
|
|
24327
24738
|
const markerG = g.append("g").attr("class", "gantt-marker-group").attr("data-line-number", String(marker.lineNumber)).style("cursor", "pointer");
|
|
24328
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");
|
|
24329
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);
|
|
@@ -24383,6 +24794,139 @@ function renderErasAndMarkers(g, svg, resolved, xScale, innerHeight, palette) {
|
|
|
24383
24794
|
});
|
|
24384
24795
|
}
|
|
24385
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
|
+
}
|
|
24386
24930
|
function parseDateStringToDate(s) {
|
|
24387
24931
|
const parts = s.split("-").map((p) => parseInt(p, 10));
|
|
24388
24932
|
const year = parts[0];
|
|
@@ -24595,6 +25139,10 @@ function resetTaskLabels(svg) {
|
|
|
24595
25139
|
svg.selectAll(".gantt-task-label").attr("opacity", 1);
|
|
24596
25140
|
}
|
|
24597
25141
|
function resetHighlight(g, svg) {
|
|
25142
|
+
if (svg.attr("data-critical-path-active") === "true") {
|
|
25143
|
+
applyCriticalPathHighlight(svg, g);
|
|
25144
|
+
return;
|
|
25145
|
+
}
|
|
24598
25146
|
g.selectAll(".gantt-task, .gantt-milestone").attr(
|
|
24599
25147
|
"opacity",
|
|
24600
25148
|
1
|
|
@@ -24855,7 +25403,7 @@ function renderTimeScaleHorizontal(g, scale, innerWidth, innerHeight, textColor)
|
|
|
24855
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);
|
|
24856
25404
|
}
|
|
24857
25405
|
}
|
|
24858
|
-
var 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 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;
|
|
24859
25407
|
var init_renderer9 = __esm({
|
|
24860
25408
|
"src/gantt/renderer.ts"() {
|
|
24861
25409
|
"use strict";
|
|
@@ -24866,6 +25414,7 @@ var init_renderer9 = __esm({
|
|
|
24866
25414
|
init_d3();
|
|
24867
25415
|
init_legend_constants();
|
|
24868
25416
|
init_legend_d3();
|
|
25417
|
+
init_legend_layout();
|
|
24869
25418
|
init_title_constants();
|
|
24870
25419
|
BAR_H = 22;
|
|
24871
25420
|
ROW_GAP = 6;
|
|
@@ -24890,6 +25439,9 @@ var init_renderer9 = __esm({
|
|
|
24890
25439
|
"sat"
|
|
24891
25440
|
];
|
|
24892
25441
|
ERA_COLORS = ["#5e81ac", "#a3be8c", "#ebcb8b", "#d08770", "#b48ead"];
|
|
25442
|
+
SPRINT_BAND_OPACITY = 0.05;
|
|
25443
|
+
SPRINT_HOVER_OPACITY = 0.12;
|
|
25444
|
+
SPRINT_BOUNDARY_OPACITY = 0.3;
|
|
24893
25445
|
FADE_OPACITY = 0.1;
|
|
24894
25446
|
MONTH_ABBR = [
|
|
24895
25447
|
"Jan",
|
|
@@ -25156,6 +25708,109 @@ var init_state_renderer = __esm({
|
|
|
25156
25708
|
}
|
|
25157
25709
|
});
|
|
25158
25710
|
|
|
25711
|
+
// src/sequence/collapse.ts
|
|
25712
|
+
function applyCollapseProjection(parsed, collapsedGroups) {
|
|
25713
|
+
if (collapsedGroups.size === 0) {
|
|
25714
|
+
return {
|
|
25715
|
+
participants: parsed.participants,
|
|
25716
|
+
messages: parsed.messages,
|
|
25717
|
+
elements: parsed.elements,
|
|
25718
|
+
groups: parsed.groups,
|
|
25719
|
+
collapsedGroupIds: /* @__PURE__ */ new Map()
|
|
25720
|
+
};
|
|
25721
|
+
}
|
|
25722
|
+
const memberToGroup = /* @__PURE__ */ new Map();
|
|
25723
|
+
const collapsedGroupNames = /* @__PURE__ */ new Set();
|
|
25724
|
+
for (const group of parsed.groups) {
|
|
25725
|
+
if (collapsedGroups.has(group.lineNumber)) {
|
|
25726
|
+
collapsedGroupNames.add(group.name);
|
|
25727
|
+
for (const memberId of group.participantIds) {
|
|
25728
|
+
memberToGroup.set(memberId, group.name);
|
|
25729
|
+
}
|
|
25730
|
+
}
|
|
25731
|
+
}
|
|
25732
|
+
const participants = [];
|
|
25733
|
+
const insertedGroups = /* @__PURE__ */ new Set();
|
|
25734
|
+
for (const p of parsed.participants) {
|
|
25735
|
+
const groupName = memberToGroup.get(p.id);
|
|
25736
|
+
if (groupName) {
|
|
25737
|
+
if (!insertedGroups.has(groupName)) {
|
|
25738
|
+
insertedGroups.add(groupName);
|
|
25739
|
+
const group = parsed.groups.find(
|
|
25740
|
+
(g) => g.name === groupName && collapsedGroups.has(g.lineNumber)
|
|
25741
|
+
);
|
|
25742
|
+
participants.push({
|
|
25743
|
+
id: groupName,
|
|
25744
|
+
label: groupName,
|
|
25745
|
+
type: "default",
|
|
25746
|
+
lineNumber: group.lineNumber
|
|
25747
|
+
});
|
|
25748
|
+
}
|
|
25749
|
+
} else if (collapsedGroupNames.has(p.id)) {
|
|
25750
|
+
} else {
|
|
25751
|
+
participants.push(p);
|
|
25752
|
+
}
|
|
25753
|
+
}
|
|
25754
|
+
const remap = (id) => memberToGroup.get(id) ?? id;
|
|
25755
|
+
const messages = parsed.messages.map((msg) => ({
|
|
25756
|
+
...msg,
|
|
25757
|
+
from: remap(msg.from),
|
|
25758
|
+
to: remap(msg.to)
|
|
25759
|
+
}));
|
|
25760
|
+
const elements = remapElements(parsed.elements, memberToGroup);
|
|
25761
|
+
const groups = parsed.groups.filter(
|
|
25762
|
+
(g) => !collapsedGroups.has(g.lineNumber)
|
|
25763
|
+
);
|
|
25764
|
+
return {
|
|
25765
|
+
participants,
|
|
25766
|
+
messages,
|
|
25767
|
+
elements,
|
|
25768
|
+
groups,
|
|
25769
|
+
collapsedGroupIds: memberToGroup
|
|
25770
|
+
};
|
|
25771
|
+
}
|
|
25772
|
+
function remapElements(elements, memberToGroup) {
|
|
25773
|
+
const remap = (id) => memberToGroup.get(id) ?? id;
|
|
25774
|
+
const result = [];
|
|
25775
|
+
for (const el of elements) {
|
|
25776
|
+
if (isSequenceSection(el)) {
|
|
25777
|
+
result.push(el);
|
|
25778
|
+
} else if (isSequenceNote(el)) {
|
|
25779
|
+
result.push({
|
|
25780
|
+
...el,
|
|
25781
|
+
participantId: remap(el.participantId)
|
|
25782
|
+
});
|
|
25783
|
+
} else if (isSequenceBlock(el)) {
|
|
25784
|
+
result.push({
|
|
25785
|
+
...el,
|
|
25786
|
+
children: remapElements(el.children, memberToGroup),
|
|
25787
|
+
elseChildren: remapElements(el.elseChildren, memberToGroup),
|
|
25788
|
+
...el.elseIfBranches ? {
|
|
25789
|
+
elseIfBranches: el.elseIfBranches.map((branch) => ({
|
|
25790
|
+
...branch,
|
|
25791
|
+
children: remapElements(branch.children, memberToGroup)
|
|
25792
|
+
}))
|
|
25793
|
+
} : {}
|
|
25794
|
+
});
|
|
25795
|
+
} else {
|
|
25796
|
+
const msg = el;
|
|
25797
|
+
const from = remap(msg.from);
|
|
25798
|
+
const to = remap(msg.to);
|
|
25799
|
+
if (from === to && from !== msg.from && !msg.label) {
|
|
25800
|
+
continue;
|
|
25801
|
+
}
|
|
25802
|
+
result.push({ ...msg, from, to });
|
|
25803
|
+
}
|
|
25804
|
+
}
|
|
25805
|
+
return result;
|
|
25806
|
+
}
|
|
25807
|
+
var init_collapse3 = __esm({
|
|
25808
|
+
"src/sequence/collapse.ts"() {
|
|
25809
|
+
"use strict";
|
|
25810
|
+
init_parser();
|
|
25811
|
+
}
|
|
25812
|
+
});
|
|
25813
|
+
|
|
25159
25814
|
// src/sequence/tag-resolution.ts
|
|
25160
25815
|
function propagateGroupTags(participantMeta, groups) {
|
|
25161
25816
|
for (const group of groups) {
|
|
@@ -25611,13 +26266,32 @@ function applyGroupOrdering(participants, groups, messages = []) {
|
|
|
25611
26266
|
}
|
|
25612
26267
|
function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateToLine, options) {
|
|
25613
26268
|
d3Selection12.select(container).selectAll("*").remove();
|
|
25614
|
-
const { title,
|
|
26269
|
+
const { title, options: parsedOptions } = parsed;
|
|
26270
|
+
const effectiveCollapsedGroups = /* @__PURE__ */ new Set();
|
|
26271
|
+
for (const group of parsed.groups) {
|
|
26272
|
+
if (group.collapsed) effectiveCollapsedGroups.add(group.lineNumber);
|
|
26273
|
+
}
|
|
26274
|
+
if (options?.collapsedGroups) {
|
|
26275
|
+
for (const ln of options.collapsedGroups) {
|
|
26276
|
+
if (effectiveCollapsedGroups.has(ln)) {
|
|
26277
|
+
effectiveCollapsedGroups.delete(ln);
|
|
26278
|
+
} else {
|
|
26279
|
+
effectiveCollapsedGroups.add(ln);
|
|
26280
|
+
}
|
|
26281
|
+
}
|
|
26282
|
+
}
|
|
26283
|
+
const collapsed = effectiveCollapsedGroups.size > 0 ? applyCollapseProjection(parsed, effectiveCollapsedGroups) : null;
|
|
26284
|
+
const messages = collapsed ? collapsed.messages : parsed.messages;
|
|
26285
|
+
const elements = collapsed ? collapsed.elements : parsed.elements;
|
|
26286
|
+
const groups = collapsed ? collapsed.groups : parsed.groups;
|
|
26287
|
+
const collapsedGroupIds = collapsed?.collapsedGroupIds ?? /* @__PURE__ */ new Map();
|
|
25615
26288
|
const collapsedSections = options?.collapsedSections;
|
|
25616
26289
|
const expandedNoteLines = options?.expandedNoteLines;
|
|
25617
26290
|
const collapseNotesDisabled = parsedOptions["collapse-notes"]?.toLowerCase() === "no";
|
|
25618
26291
|
const isNoteExpanded = (note) => expandedNoteLines === void 0 || collapseNotesDisabled || expandedNoteLines.has(note.lineNumber);
|
|
26292
|
+
const sourceParticipants = collapsed ? collapsed.participants : parsed.participants;
|
|
25619
26293
|
const participants = applyPositionOverrides(
|
|
25620
|
-
applyGroupOrdering(
|
|
26294
|
+
applyGroupOrdering(sourceParticipants, groups, messages)
|
|
25621
26295
|
);
|
|
25622
26296
|
if (participants.length === 0) return;
|
|
25623
26297
|
const activationsOff = parsedOptions.activations?.toLowerCase() === "off";
|
|
@@ -25788,13 +26462,16 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
25788
26462
|
const preSectionMsgIndices = [];
|
|
25789
26463
|
const sectionRegions = [];
|
|
25790
26464
|
{
|
|
26465
|
+
const msgLineToIndex = /* @__PURE__ */ new Map();
|
|
26466
|
+
messages.forEach((m, i) => msgLineToIndex.set(m.lineNumber, i));
|
|
26467
|
+
const findMsgIndex = (child) => msgLineToIndex.get(child.lineNumber) ?? -1;
|
|
25791
26468
|
const collectMsgIndicesFromBlock = (block) => {
|
|
25792
26469
|
const indices = [];
|
|
25793
26470
|
for (const child of block.children) {
|
|
25794
26471
|
if (isSequenceBlock(child)) {
|
|
25795
26472
|
indices.push(...collectMsgIndicesFromBlock(child));
|
|
25796
26473
|
} else if (!isSequenceSection(child) && !isSequenceNote(child)) {
|
|
25797
|
-
const idx =
|
|
26474
|
+
const idx = findMsgIndex(child);
|
|
25798
26475
|
if (idx >= 0) indices.push(idx);
|
|
25799
26476
|
}
|
|
25800
26477
|
}
|
|
@@ -25804,7 +26481,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
25804
26481
|
if (isSequenceBlock(child)) {
|
|
25805
26482
|
indices.push(...collectMsgIndicesFromBlock(child));
|
|
25806
26483
|
} else if (!isSequenceSection(child) && !isSequenceNote(child)) {
|
|
25807
|
-
const idx =
|
|
26484
|
+
const idx = findMsgIndex(child);
|
|
25808
26485
|
if (idx >= 0) indices.push(idx);
|
|
25809
26486
|
}
|
|
25810
26487
|
}
|
|
@@ -25814,7 +26491,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
25814
26491
|
if (isSequenceBlock(child)) {
|
|
25815
26492
|
indices.push(...collectMsgIndicesFromBlock(child));
|
|
25816
26493
|
} else if (!isSequenceSection(child) && !isSequenceNote(child)) {
|
|
25817
|
-
const idx =
|
|
26494
|
+
const idx = findMsgIndex(child);
|
|
25818
26495
|
if (idx >= 0) indices.push(idx);
|
|
25819
26496
|
}
|
|
25820
26497
|
}
|
|
@@ -25829,7 +26506,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
25829
26506
|
} else if (isSequenceBlock(el)) {
|
|
25830
26507
|
currentTarget.push(...collectMsgIndicesFromBlock(el));
|
|
25831
26508
|
} else {
|
|
25832
|
-
const idx =
|
|
26509
|
+
const idx = findMsgIndex(el);
|
|
25833
26510
|
if (idx >= 0) currentTarget.push(idx);
|
|
25834
26511
|
}
|
|
25835
26512
|
}
|
|
@@ -25891,7 +26568,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
25891
26568
|
const titleOffset = title ? TITLE_HEIGHT5 : 0;
|
|
25892
26569
|
const LEGEND_FIXED_GAP4 = 8;
|
|
25893
26570
|
const legendTopSpace = parsed.tagGroups.length > 0 ? LEGEND_HEIGHT + LEGEND_FIXED_GAP4 : 0;
|
|
25894
|
-
const groupOffset = groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;
|
|
26571
|
+
const groupOffset = parsed.groups.length > 0 ? GROUP_PADDING_TOP + GROUP_LABEL_SIZE : 0;
|
|
25895
26572
|
const participantStartY = TOP_MARGIN + titleOffset + legendTopSpace + PARTICIPANT_Y_OFFSET + groupOffset;
|
|
25896
26573
|
const lifelineStartY0 = participantStartY + PARTICIPANT_BOX_HEIGHT;
|
|
25897
26574
|
const hasActors = participants.some((p) => p.type === "actor");
|
|
@@ -26061,6 +26738,17 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26061
26738
|
svgWidth
|
|
26062
26739
|
);
|
|
26063
26740
|
}
|
|
26741
|
+
const collapsedGroupNames = /* @__PURE__ */ new Set();
|
|
26742
|
+
const collapsedGroupMeta = /* @__PURE__ */ new Map();
|
|
26743
|
+
for (const group of parsed.groups) {
|
|
26744
|
+
if (effectiveCollapsedGroups.has(group.lineNumber)) {
|
|
26745
|
+
collapsedGroupNames.add(group.name);
|
|
26746
|
+
collapsedGroupMeta.set(group.name, {
|
|
26747
|
+
lineNumber: group.lineNumber,
|
|
26748
|
+
metadata: group.metadata
|
|
26749
|
+
});
|
|
26750
|
+
}
|
|
26751
|
+
}
|
|
26064
26752
|
for (const group of groups) {
|
|
26065
26753
|
if (group.participantIds.length === 0) continue;
|
|
26066
26754
|
const memberXs = group.participantIds.map((id) => participantX.get(id)).filter((x) => x !== void 0);
|
|
@@ -26077,8 +26765,10 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26077
26765
|
isDark ? 15 : 20
|
|
26078
26766
|
) : isDark ? palette.surface : palette.bg;
|
|
26079
26767
|
const strokeColor = groupTagColor || palette.textMuted;
|
|
26080
|
-
svg.append("
|
|
26081
|
-
|
|
26768
|
+
const groupG = svg.append("g").attr("class", "group-box-wrapper").attr("data-group-toggle", "").attr("data-group-line", String(group.lineNumber)).attr("cursor", "pointer");
|
|
26769
|
+
groupG.append("title").text("Click to collapse");
|
|
26770
|
+
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");
|
|
26771
|
+
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);
|
|
26082
26772
|
}
|
|
26083
26773
|
const lifelineStartY = lifelineStartY0;
|
|
26084
26774
|
participants.forEach((participant, index) => {
|
|
@@ -26087,6 +26777,14 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26087
26777
|
const pTagValue = tagMap?.participants.get(participant.id);
|
|
26088
26778
|
const pTagColor = getTagColor(pTagValue);
|
|
26089
26779
|
const pTagAttr = tagKey && pTagValue ? { key: tagKey, value: pTagValue.toLowerCase() } : void 0;
|
|
26780
|
+
const isCollapsedGroup = collapsedGroupNames.has(participant.id);
|
|
26781
|
+
let effectiveTagColor = pTagColor;
|
|
26782
|
+
if (isCollapsedGroup && !effectiveTagColor) {
|
|
26783
|
+
const meta = collapsedGroupMeta.get(participant.id);
|
|
26784
|
+
if (meta?.metadata && tagKey) {
|
|
26785
|
+
effectiveTagColor = getTagColor(meta.metadata[tagKey]);
|
|
26786
|
+
}
|
|
26787
|
+
}
|
|
26090
26788
|
renderParticipant(
|
|
26091
26789
|
svg,
|
|
26092
26790
|
participant,
|
|
@@ -26094,10 +26792,35 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26094
26792
|
cy,
|
|
26095
26793
|
palette,
|
|
26096
26794
|
isDark,
|
|
26097
|
-
|
|
26795
|
+
effectiveTagColor,
|
|
26098
26796
|
pTagAttr
|
|
26099
26797
|
);
|
|
26100
|
-
|
|
26798
|
+
if (isCollapsedGroup) {
|
|
26799
|
+
const meta = collapsedGroupMeta.get(participant.id);
|
|
26800
|
+
const drillColor = effectiveTagColor || palette.textMuted;
|
|
26801
|
+
const drillBarH = 6;
|
|
26802
|
+
const boxW = PARTICIPANT_BOX_WIDTH;
|
|
26803
|
+
const fullH = PARTICIPANT_BOX_HEIGHT + GROUP_PADDING_TOP + GROUP_PADDING_BOTTOM;
|
|
26804
|
+
const clipId = `clip-drill-group-${participant.id.replace(/[^a-zA-Z0-9-]/g, "-")}`;
|
|
26805
|
+
const participantG = svg.select(
|
|
26806
|
+
`.participant[data-participant-id="${participant.id}"]`
|
|
26807
|
+
);
|
|
26808
|
+
participantG.attr("data-group-toggle", "").attr("data-group-line", String(meta.lineNumber)).attr("cursor", "pointer");
|
|
26809
|
+
participantG.append("title").text("Click to expand");
|
|
26810
|
+
const pFill = effectiveTagColor ? mix(
|
|
26811
|
+
effectiveTagColor,
|
|
26812
|
+
isDark ? palette.surface : palette.bg,
|
|
26813
|
+
isDark ? 30 : 40
|
|
26814
|
+
) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
|
|
26815
|
+
const pStroke = effectiveTagColor || palette.border;
|
|
26816
|
+
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);
|
|
26817
|
+
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);
|
|
26818
|
+
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);
|
|
26819
|
+
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})`);
|
|
26820
|
+
}
|
|
26821
|
+
const llY = isCollapsedGroup ? lifelineStartY + GROUP_PADDING_BOTTOM : lifelineStartY;
|
|
26822
|
+
const llColor = isCollapsedGroup ? effectiveTagColor || palette.textMuted : pTagColor || palette.textMuted;
|
|
26823
|
+
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);
|
|
26101
26824
|
if (tagKey && pTagValue) {
|
|
26102
26825
|
lifelineEl.attr(`data-tag-${tagKey}`, pTagValue.toLowerCase());
|
|
26103
26826
|
}
|
|
@@ -26325,23 +27048,8 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
26325
27048
|
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");
|
|
26326
27049
|
const msgCount = sectionMsgCounts.get(sec.lineNumber) ?? 0;
|
|
26327
27050
|
const labelText = isCollapsed ? `${sec.label} (${msgCount} ${msgCount === 1 ? "message" : "messages"})` : sec.label;
|
|
26328
|
-
const labelColor = isCollapsed ? "#ffffff" : lineColor;
|
|
26329
|
-
const chevronSpace = 14;
|
|
26330
27051
|
const labelX = (sectionLineX1 + sectionLineX2) / 2;
|
|
26331
|
-
|
|
26332
|
-
const chevronY = secY;
|
|
26333
|
-
if (isCollapsed) {
|
|
26334
|
-
sectionG.append("path").attr(
|
|
26335
|
-
"d",
|
|
26336
|
-
`M ${chevronX} ${chevronY - 4} L ${chevronX + 6} ${chevronY} L ${chevronX} ${chevronY + 4} Z`
|
|
26337
|
-
).attr("fill", labelColor).attr("class", "section-chevron");
|
|
26338
|
-
} else {
|
|
26339
|
-
sectionG.append("path").attr(
|
|
26340
|
-
"d",
|
|
26341
|
-
`M ${chevronX - 1} ${chevronY - 3} L ${chevronX + 7} ${chevronY - 3} L ${chevronX + 3} ${chevronY + 3} Z`
|
|
26342
|
-
).attr("fill", labelColor).attr("class", "section-chevron");
|
|
26343
|
-
}
|
|
26344
|
-
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);
|
|
27052
|
+
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);
|
|
26345
27053
|
}
|
|
26346
27054
|
const SELF_CALL_WIDTH = 30;
|
|
26347
27055
|
const SELF_CALL_HEIGHT = 25;
|
|
@@ -26622,6 +27330,7 @@ var init_renderer10 = __esm({
|
|
|
26622
27330
|
init_inline_markdown();
|
|
26623
27331
|
init_fonts();
|
|
26624
27332
|
init_parser();
|
|
27333
|
+
init_collapse3();
|
|
26625
27334
|
init_tag_resolution();
|
|
26626
27335
|
init_tag_groups();
|
|
26627
27336
|
init_legend_constants();
|
|
@@ -30945,6 +31654,463 @@ var init_d3 = __esm({
|
|
|
30945
31654
|
}
|
|
30946
31655
|
});
|
|
30947
31656
|
|
|
31657
|
+
// node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js
|
|
31658
|
+
var require_lz_string = __commonJS({
|
|
31659
|
+
"node_modules/.pnpm/lz-string@1.5.0/node_modules/lz-string/libs/lz-string.js"(exports, module) {
|
|
31660
|
+
"use strict";
|
|
31661
|
+
var LZString = (function() {
|
|
31662
|
+
var f = String.fromCharCode;
|
|
31663
|
+
var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
31664
|
+
var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
|
|
31665
|
+
var baseReverseDic = {};
|
|
31666
|
+
function getBaseValue(alphabet, character) {
|
|
31667
|
+
if (!baseReverseDic[alphabet]) {
|
|
31668
|
+
baseReverseDic[alphabet] = {};
|
|
31669
|
+
for (var i = 0; i < alphabet.length; i++) {
|
|
31670
|
+
baseReverseDic[alphabet][alphabet.charAt(i)] = i;
|
|
31671
|
+
}
|
|
31672
|
+
}
|
|
31673
|
+
return baseReverseDic[alphabet][character];
|
|
31674
|
+
}
|
|
31675
|
+
var LZString2 = {
|
|
31676
|
+
compressToBase64: function(input) {
|
|
31677
|
+
if (input == null) return "";
|
|
31678
|
+
var res = LZString2._compress(input, 6, function(a) {
|
|
31679
|
+
return keyStrBase64.charAt(a);
|
|
31680
|
+
});
|
|
31681
|
+
switch (res.length % 4) {
|
|
31682
|
+
// To produce valid Base64
|
|
31683
|
+
default:
|
|
31684
|
+
// When could this happen ?
|
|
31685
|
+
case 0:
|
|
31686
|
+
return res;
|
|
31687
|
+
case 1:
|
|
31688
|
+
return res + "===";
|
|
31689
|
+
case 2:
|
|
31690
|
+
return res + "==";
|
|
31691
|
+
case 3:
|
|
31692
|
+
return res + "=";
|
|
31693
|
+
}
|
|
31694
|
+
},
|
|
31695
|
+
decompressFromBase64: function(input) {
|
|
31696
|
+
if (input == null) return "";
|
|
31697
|
+
if (input == "") return null;
|
|
31698
|
+
return LZString2._decompress(input.length, 32, function(index) {
|
|
31699
|
+
return getBaseValue(keyStrBase64, input.charAt(index));
|
|
31700
|
+
});
|
|
31701
|
+
},
|
|
31702
|
+
compressToUTF16: function(input) {
|
|
31703
|
+
if (input == null) return "";
|
|
31704
|
+
return LZString2._compress(input, 15, function(a) {
|
|
31705
|
+
return f(a + 32);
|
|
31706
|
+
}) + " ";
|
|
31707
|
+
},
|
|
31708
|
+
decompressFromUTF16: function(compressed) {
|
|
31709
|
+
if (compressed == null) return "";
|
|
31710
|
+
if (compressed == "") return null;
|
|
31711
|
+
return LZString2._decompress(compressed.length, 16384, function(index) {
|
|
31712
|
+
return compressed.charCodeAt(index) - 32;
|
|
31713
|
+
});
|
|
31714
|
+
},
|
|
31715
|
+
//compress into uint8array (UCS-2 big endian format)
|
|
31716
|
+
compressToUint8Array: function(uncompressed) {
|
|
31717
|
+
var compressed = LZString2.compress(uncompressed);
|
|
31718
|
+
var buf = new Uint8Array(compressed.length * 2);
|
|
31719
|
+
for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
|
|
31720
|
+
var current_value = compressed.charCodeAt(i);
|
|
31721
|
+
buf[i * 2] = current_value >>> 8;
|
|
31722
|
+
buf[i * 2 + 1] = current_value % 256;
|
|
31723
|
+
}
|
|
31724
|
+
return buf;
|
|
31725
|
+
},
|
|
31726
|
+
//decompress from uint8array (UCS-2 big endian format)
|
|
31727
|
+
decompressFromUint8Array: function(compressed) {
|
|
31728
|
+
if (compressed === null || compressed === void 0) {
|
|
31729
|
+
return LZString2.decompress(compressed);
|
|
31730
|
+
} else {
|
|
31731
|
+
var buf = new Array(compressed.length / 2);
|
|
31732
|
+
for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
|
|
31733
|
+
buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
|
|
31734
|
+
}
|
|
31735
|
+
var result = [];
|
|
31736
|
+
buf.forEach(function(c) {
|
|
31737
|
+
result.push(f(c));
|
|
31738
|
+
});
|
|
31739
|
+
return LZString2.decompress(result.join(""));
|
|
31740
|
+
}
|
|
31741
|
+
},
|
|
31742
|
+
//compress into a string that is already URI encoded
|
|
31743
|
+
compressToEncodedURIComponent: function(input) {
|
|
31744
|
+
if (input == null) return "";
|
|
31745
|
+
return LZString2._compress(input, 6, function(a) {
|
|
31746
|
+
return keyStrUriSafe.charAt(a);
|
|
31747
|
+
});
|
|
31748
|
+
},
|
|
31749
|
+
//decompress from an output of compressToEncodedURIComponent
|
|
31750
|
+
decompressFromEncodedURIComponent: function(input) {
|
|
31751
|
+
if (input == null) return "";
|
|
31752
|
+
if (input == "") return null;
|
|
31753
|
+
input = input.replace(/ /g, "+");
|
|
31754
|
+
return LZString2._decompress(input.length, 32, function(index) {
|
|
31755
|
+
return getBaseValue(keyStrUriSafe, input.charAt(index));
|
|
31756
|
+
});
|
|
31757
|
+
},
|
|
31758
|
+
compress: function(uncompressed) {
|
|
31759
|
+
return LZString2._compress(uncompressed, 16, function(a) {
|
|
31760
|
+
return f(a);
|
|
31761
|
+
});
|
|
31762
|
+
},
|
|
31763
|
+
_compress: function(uncompressed, bitsPerChar, getCharFromInt) {
|
|
31764
|
+
if (uncompressed == null) return "";
|
|
31765
|
+
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;
|
|
31766
|
+
for (ii = 0; ii < uncompressed.length; ii += 1) {
|
|
31767
|
+
context_c = uncompressed.charAt(ii);
|
|
31768
|
+
if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
|
|
31769
|
+
context_dictionary[context_c] = context_dictSize++;
|
|
31770
|
+
context_dictionaryToCreate[context_c] = true;
|
|
31771
|
+
}
|
|
31772
|
+
context_wc = context_w + context_c;
|
|
31773
|
+
if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
|
|
31774
|
+
context_w = context_wc;
|
|
31775
|
+
} else {
|
|
31776
|
+
if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
|
|
31777
|
+
if (context_w.charCodeAt(0) < 256) {
|
|
31778
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31779
|
+
context_data_val = context_data_val << 1;
|
|
31780
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31781
|
+
context_data_position = 0;
|
|
31782
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31783
|
+
context_data_val = 0;
|
|
31784
|
+
} else {
|
|
31785
|
+
context_data_position++;
|
|
31786
|
+
}
|
|
31787
|
+
}
|
|
31788
|
+
value = context_w.charCodeAt(0);
|
|
31789
|
+
for (i = 0; i < 8; i++) {
|
|
31790
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31791
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31792
|
+
context_data_position = 0;
|
|
31793
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31794
|
+
context_data_val = 0;
|
|
31795
|
+
} else {
|
|
31796
|
+
context_data_position++;
|
|
31797
|
+
}
|
|
31798
|
+
value = value >> 1;
|
|
31799
|
+
}
|
|
31800
|
+
} else {
|
|
31801
|
+
value = 1;
|
|
31802
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31803
|
+
context_data_val = context_data_val << 1 | value;
|
|
31804
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31805
|
+
context_data_position = 0;
|
|
31806
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31807
|
+
context_data_val = 0;
|
|
31808
|
+
} else {
|
|
31809
|
+
context_data_position++;
|
|
31810
|
+
}
|
|
31811
|
+
value = 0;
|
|
31812
|
+
}
|
|
31813
|
+
value = context_w.charCodeAt(0);
|
|
31814
|
+
for (i = 0; i < 16; i++) {
|
|
31815
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31816
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31817
|
+
context_data_position = 0;
|
|
31818
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31819
|
+
context_data_val = 0;
|
|
31820
|
+
} else {
|
|
31821
|
+
context_data_position++;
|
|
31822
|
+
}
|
|
31823
|
+
value = value >> 1;
|
|
31824
|
+
}
|
|
31825
|
+
}
|
|
31826
|
+
context_enlargeIn--;
|
|
31827
|
+
if (context_enlargeIn == 0) {
|
|
31828
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
31829
|
+
context_numBits++;
|
|
31830
|
+
}
|
|
31831
|
+
delete context_dictionaryToCreate[context_w];
|
|
31832
|
+
} else {
|
|
31833
|
+
value = context_dictionary[context_w];
|
|
31834
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31835
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31836
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31837
|
+
context_data_position = 0;
|
|
31838
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31839
|
+
context_data_val = 0;
|
|
31840
|
+
} else {
|
|
31841
|
+
context_data_position++;
|
|
31842
|
+
}
|
|
31843
|
+
value = value >> 1;
|
|
31844
|
+
}
|
|
31845
|
+
}
|
|
31846
|
+
context_enlargeIn--;
|
|
31847
|
+
if (context_enlargeIn == 0) {
|
|
31848
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
31849
|
+
context_numBits++;
|
|
31850
|
+
}
|
|
31851
|
+
context_dictionary[context_wc] = context_dictSize++;
|
|
31852
|
+
context_w = String(context_c);
|
|
31853
|
+
}
|
|
31854
|
+
}
|
|
31855
|
+
if (context_w !== "") {
|
|
31856
|
+
if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
|
|
31857
|
+
if (context_w.charCodeAt(0) < 256) {
|
|
31858
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31859
|
+
context_data_val = context_data_val << 1;
|
|
31860
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31861
|
+
context_data_position = 0;
|
|
31862
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31863
|
+
context_data_val = 0;
|
|
31864
|
+
} else {
|
|
31865
|
+
context_data_position++;
|
|
31866
|
+
}
|
|
31867
|
+
}
|
|
31868
|
+
value = context_w.charCodeAt(0);
|
|
31869
|
+
for (i = 0; i < 8; i++) {
|
|
31870
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31871
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31872
|
+
context_data_position = 0;
|
|
31873
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31874
|
+
context_data_val = 0;
|
|
31875
|
+
} else {
|
|
31876
|
+
context_data_position++;
|
|
31877
|
+
}
|
|
31878
|
+
value = value >> 1;
|
|
31879
|
+
}
|
|
31880
|
+
} else {
|
|
31881
|
+
value = 1;
|
|
31882
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31883
|
+
context_data_val = context_data_val << 1 | value;
|
|
31884
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31885
|
+
context_data_position = 0;
|
|
31886
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31887
|
+
context_data_val = 0;
|
|
31888
|
+
} else {
|
|
31889
|
+
context_data_position++;
|
|
31890
|
+
}
|
|
31891
|
+
value = 0;
|
|
31892
|
+
}
|
|
31893
|
+
value = context_w.charCodeAt(0);
|
|
31894
|
+
for (i = 0; i < 16; i++) {
|
|
31895
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31896
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31897
|
+
context_data_position = 0;
|
|
31898
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31899
|
+
context_data_val = 0;
|
|
31900
|
+
} else {
|
|
31901
|
+
context_data_position++;
|
|
31902
|
+
}
|
|
31903
|
+
value = value >> 1;
|
|
31904
|
+
}
|
|
31905
|
+
}
|
|
31906
|
+
context_enlargeIn--;
|
|
31907
|
+
if (context_enlargeIn == 0) {
|
|
31908
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
31909
|
+
context_numBits++;
|
|
31910
|
+
}
|
|
31911
|
+
delete context_dictionaryToCreate[context_w];
|
|
31912
|
+
} else {
|
|
31913
|
+
value = context_dictionary[context_w];
|
|
31914
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31915
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31916
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31917
|
+
context_data_position = 0;
|
|
31918
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31919
|
+
context_data_val = 0;
|
|
31920
|
+
} else {
|
|
31921
|
+
context_data_position++;
|
|
31922
|
+
}
|
|
31923
|
+
value = value >> 1;
|
|
31924
|
+
}
|
|
31925
|
+
}
|
|
31926
|
+
context_enlargeIn--;
|
|
31927
|
+
if (context_enlargeIn == 0) {
|
|
31928
|
+
context_enlargeIn = Math.pow(2, context_numBits);
|
|
31929
|
+
context_numBits++;
|
|
31930
|
+
}
|
|
31931
|
+
}
|
|
31932
|
+
value = 2;
|
|
31933
|
+
for (i = 0; i < context_numBits; i++) {
|
|
31934
|
+
context_data_val = context_data_val << 1 | value & 1;
|
|
31935
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31936
|
+
context_data_position = 0;
|
|
31937
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31938
|
+
context_data_val = 0;
|
|
31939
|
+
} else {
|
|
31940
|
+
context_data_position++;
|
|
31941
|
+
}
|
|
31942
|
+
value = value >> 1;
|
|
31943
|
+
}
|
|
31944
|
+
while (true) {
|
|
31945
|
+
context_data_val = context_data_val << 1;
|
|
31946
|
+
if (context_data_position == bitsPerChar - 1) {
|
|
31947
|
+
context_data.push(getCharFromInt(context_data_val));
|
|
31948
|
+
break;
|
|
31949
|
+
} else context_data_position++;
|
|
31950
|
+
}
|
|
31951
|
+
return context_data.join("");
|
|
31952
|
+
},
|
|
31953
|
+
decompress: function(compressed) {
|
|
31954
|
+
if (compressed == null) return "";
|
|
31955
|
+
if (compressed == "") return null;
|
|
31956
|
+
return LZString2._decompress(compressed.length, 32768, function(index) {
|
|
31957
|
+
return compressed.charCodeAt(index);
|
|
31958
|
+
});
|
|
31959
|
+
},
|
|
31960
|
+
_decompress: function(length, resetValue, getNextValue) {
|
|
31961
|
+
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 };
|
|
31962
|
+
for (i = 0; i < 3; i += 1) {
|
|
31963
|
+
dictionary[i] = i;
|
|
31964
|
+
}
|
|
31965
|
+
bits = 0;
|
|
31966
|
+
maxpower = Math.pow(2, 2);
|
|
31967
|
+
power = 1;
|
|
31968
|
+
while (power != maxpower) {
|
|
31969
|
+
resb = data.val & data.position;
|
|
31970
|
+
data.position >>= 1;
|
|
31971
|
+
if (data.position == 0) {
|
|
31972
|
+
data.position = resetValue;
|
|
31973
|
+
data.val = getNextValue(data.index++);
|
|
31974
|
+
}
|
|
31975
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
31976
|
+
power <<= 1;
|
|
31977
|
+
}
|
|
31978
|
+
switch (next = bits) {
|
|
31979
|
+
case 0:
|
|
31980
|
+
bits = 0;
|
|
31981
|
+
maxpower = Math.pow(2, 8);
|
|
31982
|
+
power = 1;
|
|
31983
|
+
while (power != maxpower) {
|
|
31984
|
+
resb = data.val & data.position;
|
|
31985
|
+
data.position >>= 1;
|
|
31986
|
+
if (data.position == 0) {
|
|
31987
|
+
data.position = resetValue;
|
|
31988
|
+
data.val = getNextValue(data.index++);
|
|
31989
|
+
}
|
|
31990
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
31991
|
+
power <<= 1;
|
|
31992
|
+
}
|
|
31993
|
+
c = f(bits);
|
|
31994
|
+
break;
|
|
31995
|
+
case 1:
|
|
31996
|
+
bits = 0;
|
|
31997
|
+
maxpower = Math.pow(2, 16);
|
|
31998
|
+
power = 1;
|
|
31999
|
+
while (power != maxpower) {
|
|
32000
|
+
resb = data.val & data.position;
|
|
32001
|
+
data.position >>= 1;
|
|
32002
|
+
if (data.position == 0) {
|
|
32003
|
+
data.position = resetValue;
|
|
32004
|
+
data.val = getNextValue(data.index++);
|
|
32005
|
+
}
|
|
32006
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
32007
|
+
power <<= 1;
|
|
32008
|
+
}
|
|
32009
|
+
c = f(bits);
|
|
32010
|
+
break;
|
|
32011
|
+
case 2:
|
|
32012
|
+
return "";
|
|
32013
|
+
}
|
|
32014
|
+
dictionary[3] = c;
|
|
32015
|
+
w = c;
|
|
32016
|
+
result.push(c);
|
|
32017
|
+
while (true) {
|
|
32018
|
+
if (data.index > length) {
|
|
32019
|
+
return "";
|
|
32020
|
+
}
|
|
32021
|
+
bits = 0;
|
|
32022
|
+
maxpower = Math.pow(2, numBits);
|
|
32023
|
+
power = 1;
|
|
32024
|
+
while (power != maxpower) {
|
|
32025
|
+
resb = data.val & data.position;
|
|
32026
|
+
data.position >>= 1;
|
|
32027
|
+
if (data.position == 0) {
|
|
32028
|
+
data.position = resetValue;
|
|
32029
|
+
data.val = getNextValue(data.index++);
|
|
32030
|
+
}
|
|
32031
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
32032
|
+
power <<= 1;
|
|
32033
|
+
}
|
|
32034
|
+
switch (c = bits) {
|
|
32035
|
+
case 0:
|
|
32036
|
+
bits = 0;
|
|
32037
|
+
maxpower = Math.pow(2, 8);
|
|
32038
|
+
power = 1;
|
|
32039
|
+
while (power != maxpower) {
|
|
32040
|
+
resb = data.val & data.position;
|
|
32041
|
+
data.position >>= 1;
|
|
32042
|
+
if (data.position == 0) {
|
|
32043
|
+
data.position = resetValue;
|
|
32044
|
+
data.val = getNextValue(data.index++);
|
|
32045
|
+
}
|
|
32046
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
32047
|
+
power <<= 1;
|
|
32048
|
+
}
|
|
32049
|
+
dictionary[dictSize++] = f(bits);
|
|
32050
|
+
c = dictSize - 1;
|
|
32051
|
+
enlargeIn--;
|
|
32052
|
+
break;
|
|
32053
|
+
case 1:
|
|
32054
|
+
bits = 0;
|
|
32055
|
+
maxpower = Math.pow(2, 16);
|
|
32056
|
+
power = 1;
|
|
32057
|
+
while (power != maxpower) {
|
|
32058
|
+
resb = data.val & data.position;
|
|
32059
|
+
data.position >>= 1;
|
|
32060
|
+
if (data.position == 0) {
|
|
32061
|
+
data.position = resetValue;
|
|
32062
|
+
data.val = getNextValue(data.index++);
|
|
32063
|
+
}
|
|
32064
|
+
bits |= (resb > 0 ? 1 : 0) * power;
|
|
32065
|
+
power <<= 1;
|
|
32066
|
+
}
|
|
32067
|
+
dictionary[dictSize++] = f(bits);
|
|
32068
|
+
c = dictSize - 1;
|
|
32069
|
+
enlargeIn--;
|
|
32070
|
+
break;
|
|
32071
|
+
case 2:
|
|
32072
|
+
return result.join("");
|
|
32073
|
+
}
|
|
32074
|
+
if (enlargeIn == 0) {
|
|
32075
|
+
enlargeIn = Math.pow(2, numBits);
|
|
32076
|
+
numBits++;
|
|
32077
|
+
}
|
|
32078
|
+
if (dictionary[c]) {
|
|
32079
|
+
entry = dictionary[c];
|
|
32080
|
+
} else {
|
|
32081
|
+
if (c === dictSize) {
|
|
32082
|
+
entry = w + w.charAt(0);
|
|
32083
|
+
} else {
|
|
32084
|
+
return null;
|
|
32085
|
+
}
|
|
32086
|
+
}
|
|
32087
|
+
result.push(entry);
|
|
32088
|
+
dictionary[dictSize++] = w + entry.charAt(0);
|
|
32089
|
+
enlargeIn--;
|
|
32090
|
+
w = entry;
|
|
32091
|
+
if (enlargeIn == 0) {
|
|
32092
|
+
enlargeIn = Math.pow(2, numBits);
|
|
32093
|
+
numBits++;
|
|
32094
|
+
}
|
|
32095
|
+
}
|
|
32096
|
+
}
|
|
32097
|
+
};
|
|
32098
|
+
return LZString2;
|
|
32099
|
+
})();
|
|
32100
|
+
if (typeof define === "function" && define.amd) {
|
|
32101
|
+
define(function() {
|
|
32102
|
+
return LZString;
|
|
32103
|
+
});
|
|
32104
|
+
} else if (typeof module !== "undefined" && module != null) {
|
|
32105
|
+
module.exports = LZString;
|
|
32106
|
+
} else if (typeof angular !== "undefined" && angular != null) {
|
|
32107
|
+
angular.module("LZString", []).factory("LZString", function() {
|
|
32108
|
+
return LZString;
|
|
32109
|
+
});
|
|
32110
|
+
}
|
|
32111
|
+
}
|
|
32112
|
+
});
|
|
32113
|
+
|
|
30948
32114
|
// src/index.ts
|
|
30949
32115
|
init_diagnostics();
|
|
30950
32116
|
|
|
@@ -31727,19 +32893,35 @@ init_legend_d3();
|
|
|
31727
32893
|
init_legend_layout();
|
|
31728
32894
|
init_d3();
|
|
31729
32895
|
init_renderer10();
|
|
32896
|
+
init_collapse3();
|
|
31730
32897
|
init_colors();
|
|
31731
32898
|
init_palettes();
|
|
31732
32899
|
|
|
31733
32900
|
// src/sharing.ts
|
|
31734
|
-
|
|
31735
|
-
compressToEncodedURIComponent,
|
|
31736
|
-
decompressFromEncodedURIComponent
|
|
31737
|
-
} from "lz-string";
|
|
32901
|
+
var import_lz_string = __toESM(require_lz_string(), 1);
|
|
31738
32902
|
var DEFAULT_BASE_URL = "https://online.diagrammo.app";
|
|
31739
32903
|
var COMPRESSED_SIZE_LIMIT = 8192;
|
|
32904
|
+
function encodeViewState(state) {
|
|
32905
|
+
const keys = Object.keys(state);
|
|
32906
|
+
if (keys.length === 0) return "";
|
|
32907
|
+
return (0, import_lz_string.compressToEncodedURIComponent)(JSON.stringify(state));
|
|
32908
|
+
}
|
|
32909
|
+
function decodeViewState(encoded) {
|
|
32910
|
+
if (!encoded) return {};
|
|
32911
|
+
try {
|
|
32912
|
+
const json = (0, import_lz_string.decompressFromEncodedURIComponent)(encoded);
|
|
32913
|
+
if (!json) return {};
|
|
32914
|
+
const parsed = JSON.parse(json);
|
|
32915
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
32916
|
+
return {};
|
|
32917
|
+
return parsed;
|
|
32918
|
+
} catch {
|
|
32919
|
+
return {};
|
|
32920
|
+
}
|
|
32921
|
+
}
|
|
31740
32922
|
function encodeDiagramUrl(dsl, options) {
|
|
31741
32923
|
const baseUrl = options?.baseUrl ?? DEFAULT_BASE_URL;
|
|
31742
|
-
const compressed = compressToEncodedURIComponent(dsl);
|
|
32924
|
+
const compressed = (0, import_lz_string.compressToEncodedURIComponent)(dsl);
|
|
31743
32925
|
const byteSize = new TextEncoder().encode(compressed).byteLength;
|
|
31744
32926
|
if (byteSize > COMPRESSED_SIZE_LIMIT) {
|
|
31745
32927
|
return {
|
|
@@ -31749,23 +32931,17 @@ function encodeDiagramUrl(dsl, options) {
|
|
|
31749
32931
|
};
|
|
31750
32932
|
}
|
|
31751
32933
|
let hash = `dgmo=${compressed}`;
|
|
31752
|
-
if (options?.viewState
|
|
31753
|
-
|
|
31754
|
-
|
|
31755
|
-
|
|
31756
|
-
|
|
31757
|
-
}
|
|
31758
|
-
if (options?.viewState?.swimlaneTagGroup) {
|
|
31759
|
-
hash += `&swim=${encodeURIComponent(options.viewState.swimlaneTagGroup)}`;
|
|
31760
|
-
}
|
|
31761
|
-
if (options?.viewState?.collapsedLanes?.length) {
|
|
31762
|
-
hash += `&cl=${encodeURIComponent(options.viewState.collapsedLanes.join(","))}`;
|
|
32934
|
+
if (options?.viewState) {
|
|
32935
|
+
const vsEncoded = encodeViewState(options.viewState);
|
|
32936
|
+
if (vsEncoded) {
|
|
32937
|
+
hash += `&vs=${vsEncoded}`;
|
|
32938
|
+
}
|
|
31763
32939
|
}
|
|
31764
|
-
if (options?.
|
|
31765
|
-
hash += `&pal=${encodeURIComponent(options.
|
|
32940
|
+
if (options?.palette && options.palette !== "nord") {
|
|
32941
|
+
hash += `&pal=${encodeURIComponent(options.palette)}`;
|
|
31766
32942
|
}
|
|
31767
|
-
if (options?.
|
|
31768
|
-
hash += `&th=${encodeURIComponent(options.
|
|
32943
|
+
if (options?.theme && options.theme !== "dark") {
|
|
32944
|
+
hash += `&th=${encodeURIComponent(options.theme)}`;
|
|
31769
32945
|
}
|
|
31770
32946
|
if (options?.filename) {
|
|
31771
32947
|
hash += `&fn=${encodeURIComponent(options.filename)}`;
|
|
@@ -31775,6 +32951,8 @@ function encodeDiagramUrl(dsl, options) {
|
|
|
31775
32951
|
function decodeDiagramUrl(hash) {
|
|
31776
32952
|
const empty = { dsl: "", viewState: {} };
|
|
31777
32953
|
let filename;
|
|
32954
|
+
let palette;
|
|
32955
|
+
let theme;
|
|
31778
32956
|
if (!hash) return empty;
|
|
31779
32957
|
let raw = hash;
|
|
31780
32958
|
if (raw.startsWith("#") || raw.startsWith("?")) {
|
|
@@ -31782,38 +32960,31 @@ function decodeDiagramUrl(hash) {
|
|
|
31782
32960
|
}
|
|
31783
32961
|
const parts = raw.split("&");
|
|
31784
32962
|
let payload = parts[0];
|
|
31785
|
-
|
|
32963
|
+
let viewState = {};
|
|
31786
32964
|
for (let i = 1; i < parts.length; i++) {
|
|
31787
32965
|
const eq = parts[i].indexOf("=");
|
|
31788
32966
|
if (eq === -1) continue;
|
|
31789
32967
|
const key = parts[i].slice(0, eq);
|
|
31790
|
-
const val =
|
|
31791
|
-
if (key === "
|
|
31792
|
-
viewState
|
|
31793
|
-
}
|
|
31794
|
-
if (key === "cg" && val) {
|
|
31795
|
-
viewState.collapsedGroups = val.split(",").filter(Boolean);
|
|
31796
|
-
}
|
|
31797
|
-
if (key === "swim" && val) {
|
|
31798
|
-
viewState.swimlaneTagGroup = val;
|
|
32968
|
+
const val = parts[i].slice(eq + 1);
|
|
32969
|
+
if (key === "vs" && val) {
|
|
32970
|
+
viewState = decodeViewState(val);
|
|
31799
32971
|
}
|
|
31800
|
-
if (key === "
|
|
31801
|
-
|
|
32972
|
+
if (key === "pal" && val) palette = decodeURIComponent(val);
|
|
32973
|
+
if (key === "th") {
|
|
32974
|
+
const decoded = decodeURIComponent(val);
|
|
32975
|
+
if (decoded === "light" || decoded === "dark") theme = decoded;
|
|
31802
32976
|
}
|
|
31803
|
-
if (key === "
|
|
31804
|
-
if (key === "th" && (val === "light" || val === "dark"))
|
|
31805
|
-
viewState.theme = val;
|
|
31806
|
-
if (key === "fn" && val) filename = val;
|
|
32977
|
+
if (key === "fn" && val) filename = decodeURIComponent(val);
|
|
31807
32978
|
}
|
|
31808
32979
|
if (payload.startsWith("dgmo=")) {
|
|
31809
32980
|
payload = payload.slice(5);
|
|
31810
32981
|
}
|
|
31811
|
-
if (!payload) return { dsl: "", viewState, filename };
|
|
32982
|
+
if (!payload) return { dsl: "", viewState, palette, theme, filename };
|
|
31812
32983
|
try {
|
|
31813
|
-
const result = decompressFromEncodedURIComponent(payload);
|
|
31814
|
-
return { dsl: result ?? "", viewState, filename };
|
|
32984
|
+
const result = (0, import_lz_string.decompressFromEncodedURIComponent)(payload);
|
|
32985
|
+
return { dsl: result ?? "", viewState, palette, theme, filename };
|
|
31815
32986
|
} catch {
|
|
31816
|
-
return { dsl: "", viewState, filename };
|
|
32987
|
+
return { dsl: "", viewState, palette, theme, filename };
|
|
31817
32988
|
}
|
|
31818
32989
|
}
|
|
31819
32990
|
|
|
@@ -32573,6 +33744,7 @@ export {
|
|
|
32573
33744
|
RECOGNIZED_COLOR_NAMES,
|
|
32574
33745
|
RULE_COUNT,
|
|
32575
33746
|
addDurationToDate,
|
|
33747
|
+
applyCollapseProjection,
|
|
32576
33748
|
applyGroupOrdering,
|
|
32577
33749
|
applyPositionOverrides,
|
|
32578
33750
|
boldPalette,
|
|
@@ -32602,8 +33774,10 @@ export {
|
|
|
32602
33774
|
computeTimeTicks,
|
|
32603
33775
|
contrastText,
|
|
32604
33776
|
decodeDiagramUrl,
|
|
33777
|
+
decodeViewState,
|
|
32605
33778
|
draculaPalette,
|
|
32606
33779
|
encodeDiagramUrl,
|
|
33780
|
+
encodeViewState,
|
|
32607
33781
|
extractDiagramSymbols,
|
|
32608
33782
|
extractTagDeclarations,
|
|
32609
33783
|
formatDateLabel,
|