@diagrammo/dgmo 0.8.22 → 0.8.25
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/.claude/commands/dgmo.md +60 -72
- package/dist/cli.cjs +123 -116
- package/dist/editor.cjs +3 -2
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.js +3 -2
- package/dist/editor.js.map +1 -1
- package/dist/highlight.cjs +3 -2
- package/dist/highlight.cjs.map +1 -1
- package/dist/highlight.js +3 -2
- package/dist/highlight.js.map +1 -1
- package/dist/index.cjs +1649 -442
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +196 -23
- package/dist/index.d.ts +196 -23
- package/dist/index.js +1631 -440
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +677 -0
- package/dist/internal.cjs.map +1 -0
- package/dist/internal.d.cts +267 -0
- package/dist/internal.d.ts +267 -0
- package/dist/internal.js +633 -0
- package/dist/internal.js.map +1 -0
- package/docs/guide/chart-area.md +17 -17
- package/docs/guide/chart-bar-stacked.md +12 -12
- package/docs/guide/chart-cycle.md +156 -0
- package/docs/guide/chart-doughnut.md +10 -10
- package/docs/guide/chart-funnel.md +9 -9
- package/docs/guide/chart-heatmap.md +10 -10
- package/docs/guide/chart-journey-map.md +179 -0
- package/docs/guide/chart-kanban.md +2 -0
- package/docs/guide/chart-line.md +19 -19
- package/docs/guide/chart-multi-line.md +16 -16
- package/docs/guide/chart-pie.md +11 -11
- package/docs/guide/chart-polar-area.md +10 -10
- package/docs/guide/chart-pyramid.md +111 -0
- package/docs/guide/chart-radar.md +9 -9
- package/docs/guide/chart-scatter.md +24 -27
- package/docs/guide/index.md +3 -3
- package/docs/guide/registry.json +5 -0
- package/docs/language-reference.md +108 -26
- package/fonts/Inter-Bold.ttf +0 -0
- package/fonts/Inter-Regular.ttf +0 -0
- package/fonts/LICENSE-Inter.txt +92 -0
- package/gallery/fixtures/bar-stacked.dgmo +12 -6
- package/gallery/fixtures/heatmap.dgmo +12 -6
- package/gallery/fixtures/multi-line.dgmo +11 -7
- package/gallery/fixtures/pyramid/dikw.dgmo +17 -0
- package/gallery/fixtures/pyramid/inverted-funnel.dgmo +16 -0
- package/gallery/fixtures/pyramid/minimal.dgmo +5 -0
- package/gallery/fixtures/quadrant.dgmo +8 -8
- package/gallery/fixtures/scatter.dgmo +12 -12
- package/package.json +14 -2
- package/src/boxes-and-lines/parser.ts +13 -2
- package/src/boxes-and-lines/renderer.ts +22 -13
- package/src/chart-type-scoring.ts +162 -0
- package/src/chart-types.ts +437 -0
- package/src/cli.ts +152 -101
- package/src/completion.ts +9 -48
- package/src/cycle/layout.ts +19 -28
- package/src/cycle/renderer.ts +59 -32
- package/src/cycle/types.ts +21 -0
- package/src/d3.ts +30 -3
- package/src/dgmo-router.ts +98 -73
- package/src/echarts.ts +1 -1
- package/src/editor/keywords.ts +3 -2
- package/src/fonts.ts +3 -2
- package/src/gantt/parser.ts +5 -1
- package/src/index.ts +37 -3
- package/src/infra/parser.ts +3 -3
- package/src/internal.ts +20 -0
- package/src/journey-map/layout.ts +7 -3
- package/src/journey-map/parser.ts +5 -1
- package/src/journey-map/renderer.ts +112 -47
- package/src/kanban/parser.ts +5 -1
- package/src/org/collapse.ts +82 -4
- package/src/org/parser.ts +1 -1
- package/src/org/renderer.ts +221 -4
- package/src/pyramid/parser.ts +172 -0
- package/src/pyramid/renderer.ts +684 -0
- package/src/pyramid/types.ts +28 -0
- package/src/render.ts +2 -8
- package/src/sequence/parser.ts +64 -22
- package/src/sequence/participant-inference.ts +0 -1
- package/src/sequence/renderer.ts +97 -265
- package/src/sharing.ts +0 -1
- package/src/sitemap/parser.ts +1 -1
- package/src/tech-radar/interactive.ts +54 -0
- package/src/utils/parsing.ts +1 -0
- package/src/utils/tag-groups.ts +35 -5
- package/src/wireframe/parser.ts +3 -1
package/dist/index.js
CHANGED
|
@@ -1957,7 +1957,8 @@ var init_parsing = __esm({
|
|
|
1957
1957
|
"wireframe",
|
|
1958
1958
|
"tech-radar",
|
|
1959
1959
|
"cycle",
|
|
1960
|
-
"journey-map"
|
|
1960
|
+
"journey-map",
|
|
1961
|
+
"pyramid"
|
|
1961
1962
|
]);
|
|
1962
1963
|
COLOR_SUFFIX_RE = /\(([^)]+)\)\s*$/;
|
|
1963
1964
|
OPTION_NOCOLON_RE = /^([a-z][a-z0-9-]*)\s+(.+)$/i;
|
|
@@ -2083,7 +2084,8 @@ function validateTagValues(entities, tagGroups, pushWarning, suggestFn) {
|
|
|
2083
2084
|
}
|
|
2084
2085
|
}
|
|
2085
2086
|
}
|
|
2086
|
-
function validateTagGroupNames(tagGroups, pushWarning) {
|
|
2087
|
+
function validateTagGroupNames(tagGroups, pushWarning, pushError) {
|
|
2088
|
+
const report = pushError ?? pushWarning;
|
|
2087
2089
|
for (const group of tagGroups) {
|
|
2088
2090
|
if (group.name.toLowerCase() === "none") {
|
|
2089
2091
|
pushWarning(
|
|
@@ -2091,6 +2093,18 @@ function validateTagGroupNames(tagGroups, pushWarning) {
|
|
|
2091
2093
|
`'none' is a reserved keyword and cannot be used as a tag group name`
|
|
2092
2094
|
);
|
|
2093
2095
|
}
|
|
2096
|
+
if (!VALID_TAG_IDENT_RE.test(group.name)) {
|
|
2097
|
+
report(
|
|
2098
|
+
group.lineNumber,
|
|
2099
|
+
`Tag group name "${group.name}" contains invalid characters \u2014 use a single identifier (letters, digits, underscore, hyphen)`
|
|
2100
|
+
);
|
|
2101
|
+
}
|
|
2102
|
+
if (group.alias != null && !VALID_TAG_IDENT_RE.test(group.alias)) {
|
|
2103
|
+
report(
|
|
2104
|
+
group.lineNumber,
|
|
2105
|
+
`Tag group alias "${group.alias}" contains invalid characters \u2014 use a single identifier (letters, digits, underscore, hyphen)`
|
|
2106
|
+
);
|
|
2107
|
+
}
|
|
2094
2108
|
}
|
|
2095
2109
|
}
|
|
2096
2110
|
function injectDefaultTagMetadata(entities, tagGroups, skip) {
|
|
@@ -2129,12 +2143,13 @@ function resolveActiveTagGroup(tagGroups, explicitActiveTag, programmaticOverrid
|
|
|
2129
2143
|
function matchTagBlockHeading(trimmed) {
|
|
2130
2144
|
return parseTagDeclaration(trimmed);
|
|
2131
2145
|
}
|
|
2132
|
-
var TAG_BLOCK_NOCOLON_RE;
|
|
2146
|
+
var TAG_BLOCK_NOCOLON_RE, VALID_TAG_IDENT_RE;
|
|
2133
2147
|
var init_tag_groups = __esm({
|
|
2134
2148
|
"src/utils/tag-groups.ts"() {
|
|
2135
2149
|
"use strict";
|
|
2136
2150
|
init_parsing();
|
|
2137
2151
|
TAG_BLOCK_NOCOLON_RE = /^tag\s+/i;
|
|
2152
|
+
VALID_TAG_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_-]*$/;
|
|
2138
2153
|
}
|
|
2139
2154
|
});
|
|
2140
2155
|
|
|
@@ -3070,7 +3085,6 @@ var init_participant_inference = __esm({
|
|
|
3070
3085
|
{ pattern: /^Admin$/i, type: "actor" },
|
|
3071
3086
|
{ pattern: /^User$/i, type: "actor" },
|
|
3072
3087
|
{ pattern: /^Customer$/i, type: "actor" },
|
|
3073
|
-
{ pattern: /^Client$/i, type: "actor" },
|
|
3074
3088
|
{ pattern: /^Agent$/i, type: "actor" },
|
|
3075
3089
|
{ pattern: /^Person$/i, type: "actor" },
|
|
3076
3090
|
{ pattern: /^Buyer$/i, type: "actor" },
|
|
@@ -3199,7 +3213,7 @@ function isSequenceSection(el) {
|
|
|
3199
3213
|
function isSequenceNote(el) {
|
|
3200
3214
|
return "kind" in el && el.kind === "note";
|
|
3201
3215
|
}
|
|
3202
|
-
function parseNoteLine(trimmed, participants, lastMsgFrom) {
|
|
3216
|
+
function parseNoteLine(trimmed, participants, participantIds, sortedParticipantsCache, lastMsgFrom) {
|
|
3203
3217
|
const lower = trimmed.toLowerCase();
|
|
3204
3218
|
if (!lower.startsWith("note")) return null;
|
|
3205
3219
|
if (trimmed.length > 4 && trimmed[4] !== " ") return null;
|
|
@@ -3211,7 +3225,7 @@ function parseNoteLine(trimmed, participants, lastMsgFrom) {
|
|
|
3211
3225
|
if (!lastMsgFrom) return { kind: "skip" };
|
|
3212
3226
|
participantId = lastMsgFrom;
|
|
3213
3227
|
}
|
|
3214
|
-
if (
|
|
3228
|
+
if (participantIds.has(participantId)) {
|
|
3215
3229
|
return { kind: "multi-head", position, participantId };
|
|
3216
3230
|
}
|
|
3217
3231
|
}
|
|
@@ -3230,11 +3244,15 @@ function parseNoteLine(trimmed, participants, lastMsgFrom) {
|
|
|
3230
3244
|
}
|
|
3231
3245
|
if (!afterPos) {
|
|
3232
3246
|
if (!lastMsgFrom) return { kind: "skip" };
|
|
3233
|
-
if (!
|
|
3234
|
-
return { kind: "skip" };
|
|
3247
|
+
if (!participantIds.has(lastMsgFrom)) return { kind: "skip" };
|
|
3235
3248
|
return { kind: "multi-head", position, participantId: lastMsgFrom };
|
|
3236
3249
|
}
|
|
3237
|
-
const resolved = resolveParticipantAndText(
|
|
3250
|
+
const resolved = resolveParticipantAndText(
|
|
3251
|
+
afterPos,
|
|
3252
|
+
participants,
|
|
3253
|
+
participantIds,
|
|
3254
|
+
sortedParticipantsCache
|
|
3255
|
+
);
|
|
3238
3256
|
if (resolved) {
|
|
3239
3257
|
if (resolved.text) {
|
|
3240
3258
|
return {
|
|
@@ -3253,8 +3271,7 @@ function parseNoteLine(trimmed, participants, lastMsgFrom) {
|
|
|
3253
3271
|
}
|
|
3254
3272
|
if (hadOf) return { kind: "skip" };
|
|
3255
3273
|
if (!lastMsgFrom) return { kind: "skip" };
|
|
3256
|
-
if (!
|
|
3257
|
-
return { kind: "skip" };
|
|
3274
|
+
if (!participantIds.has(lastMsgFrom)) return { kind: "skip" };
|
|
3258
3275
|
return {
|
|
3259
3276
|
kind: "single",
|
|
3260
3277
|
position,
|
|
@@ -3263,8 +3280,7 @@ function parseNoteLine(trimmed, participants, lastMsgFrom) {
|
|
|
3263
3280
|
};
|
|
3264
3281
|
}
|
|
3265
3282
|
if (!lastMsgFrom) return { kind: "skip" };
|
|
3266
|
-
if (!
|
|
3267
|
-
return { kind: "skip" };
|
|
3283
|
+
if (!participantIds.has(lastMsgFrom)) return { kind: "skip" };
|
|
3268
3284
|
return {
|
|
3269
3285
|
kind: "single",
|
|
3270
3286
|
position: "right",
|
|
@@ -3274,20 +3290,20 @@ function parseNoteLine(trimmed, participants, lastMsgFrom) {
|
|
|
3274
3290
|
}
|
|
3275
3291
|
return null;
|
|
3276
3292
|
}
|
|
3277
|
-
function resolveParticipantAndText(input, participants) {
|
|
3293
|
+
function resolveParticipantAndText(input, participants, participantIds, sortedParticipantsCache) {
|
|
3278
3294
|
if (input.startsWith('"') || input.startsWith("'")) {
|
|
3279
3295
|
const quote = input[0];
|
|
3280
3296
|
const endQuote = input.indexOf(quote, 1);
|
|
3281
3297
|
if (endQuote > 0) {
|
|
3282
3298
|
const name = input.substring(1, endQuote);
|
|
3283
|
-
if (
|
|
3299
|
+
if (participantIds.has(name)) {
|
|
3284
3300
|
const text = input.substring(endQuote + 1).trim();
|
|
3285
3301
|
return { participantId: name, text };
|
|
3286
3302
|
}
|
|
3287
3303
|
}
|
|
3288
3304
|
return null;
|
|
3289
3305
|
}
|
|
3290
|
-
const sorted =
|
|
3306
|
+
const sorted = sortedParticipantsCache;
|
|
3291
3307
|
for (const p of sorted) {
|
|
3292
3308
|
if (input.startsWith(p.id)) {
|
|
3293
3309
|
const remaining = input.substring(p.id.length);
|
|
@@ -3348,6 +3364,18 @@ function parseSequenceDgmo(content) {
|
|
|
3348
3364
|
break;
|
|
3349
3365
|
}
|
|
3350
3366
|
let activeGroup = null;
|
|
3367
|
+
const participantIds = /* @__PURE__ */ new Set();
|
|
3368
|
+
let sortedParticipantsCache = [];
|
|
3369
|
+
let sortedCacheDirty = true;
|
|
3370
|
+
const getSortedParticipants = () => {
|
|
3371
|
+
if (sortedCacheDirty) {
|
|
3372
|
+
sortedParticipantsCache = [...result.participants].sort(
|
|
3373
|
+
(a, b) => b.id.length - a.id.length
|
|
3374
|
+
);
|
|
3375
|
+
sortedCacheDirty = false;
|
|
3376
|
+
}
|
|
3377
|
+
return sortedParticipantsCache;
|
|
3378
|
+
};
|
|
3351
3379
|
const participantGroupMap = /* @__PURE__ */ new Map();
|
|
3352
3380
|
let currentTagGroup = null;
|
|
3353
3381
|
const aliasMap = /* @__PURE__ */ new Map();
|
|
@@ -3593,7 +3621,9 @@ function parseSequenceDgmo(content) {
|
|
|
3593
3621
|
const posMatch = remainder.match(/\bposition\s+(-?\d+)/i);
|
|
3594
3622
|
const alias = akaMatch ? akaMatch[1].trim() : null;
|
|
3595
3623
|
const position = posMatch ? parseInt(posMatch[1], 10) : void 0;
|
|
3596
|
-
if (!
|
|
3624
|
+
if (!participantIds.has(id)) {
|
|
3625
|
+
participantIds.add(id);
|
|
3626
|
+
sortedCacheDirty = true;
|
|
3597
3627
|
result.participants.push({
|
|
3598
3628
|
id,
|
|
3599
3629
|
label: alias || id,
|
|
@@ -3623,7 +3653,9 @@ function parseSequenceDgmo(content) {
|
|
|
3623
3653
|
contentStarted = true;
|
|
3624
3654
|
const id = posOnlyMatch[1];
|
|
3625
3655
|
const position = parseInt(posOnlyMatch[2], 10);
|
|
3626
|
-
if (!
|
|
3656
|
+
if (!participantIds.has(id)) {
|
|
3657
|
+
participantIds.add(id);
|
|
3658
|
+
sortedCacheDirty = true;
|
|
3627
3659
|
result.participants.push({
|
|
3628
3660
|
id,
|
|
3629
3661
|
label: id,
|
|
@@ -3657,7 +3689,9 @@ function parseSequenceDgmo(content) {
|
|
|
3657
3689
|
`'${id}(${color})' syntax is no longer supported \u2014 use 'tag:' groups for coloring`
|
|
3658
3690
|
);
|
|
3659
3691
|
contentStarted = true;
|
|
3660
|
-
if (!
|
|
3692
|
+
if (!participantIds.has(id)) {
|
|
3693
|
+
participantIds.add(id);
|
|
3694
|
+
sortedCacheDirty = true;
|
|
3661
3695
|
result.participants.push({
|
|
3662
3696
|
id,
|
|
3663
3697
|
label: id,
|
|
@@ -3686,7 +3720,8 @@ function parseSequenceDgmo(content) {
|
|
|
3686
3720
|
if (/^\S+$/.test(bareCore) && !ARROW_PATTERN.test(bareCore) && (inGroup || !contentStarted || bareMeta)) {
|
|
3687
3721
|
contentStarted = true;
|
|
3688
3722
|
const id = bareCore;
|
|
3689
|
-
if (!
|
|
3723
|
+
if (!participantIds.has(id)) {
|
|
3724
|
+
participantIds.add(id);
|
|
3690
3725
|
result.participants.push({
|
|
3691
3726
|
id,
|
|
3692
3727
|
label: id,
|
|
@@ -3748,7 +3783,9 @@ function parseSequenceDgmo(content) {
|
|
|
3748
3783
|
};
|
|
3749
3784
|
result.messages.push(msg);
|
|
3750
3785
|
currentContainer().push(msg);
|
|
3751
|
-
if (!
|
|
3786
|
+
if (!participantIds.has(from)) {
|
|
3787
|
+
participantIds.add(from);
|
|
3788
|
+
sortedCacheDirty = true;
|
|
3752
3789
|
result.participants.push({
|
|
3753
3790
|
id: from,
|
|
3754
3791
|
label: from,
|
|
@@ -3756,7 +3793,9 @@ function parseSequenceDgmo(content) {
|
|
|
3756
3793
|
lineNumber
|
|
3757
3794
|
});
|
|
3758
3795
|
}
|
|
3759
|
-
if (!
|
|
3796
|
+
if (!participantIds.has(to)) {
|
|
3797
|
+
participantIds.add(to);
|
|
3798
|
+
sortedCacheDirty = true;
|
|
3760
3799
|
result.participants.push({
|
|
3761
3800
|
id: to,
|
|
3762
3801
|
label: to,
|
|
@@ -3823,7 +3862,9 @@ function parseSequenceDgmo(content) {
|
|
|
3823
3862
|
};
|
|
3824
3863
|
result.messages.push(msg);
|
|
3825
3864
|
currentContainer().push(msg);
|
|
3826
|
-
if (!
|
|
3865
|
+
if (!participantIds.has(from)) {
|
|
3866
|
+
participantIds.add(from);
|
|
3867
|
+
sortedCacheDirty = true;
|
|
3827
3868
|
result.participants.push({
|
|
3828
3869
|
id: from,
|
|
3829
3870
|
label: from,
|
|
@@ -3831,7 +3872,9 @@ function parseSequenceDgmo(content) {
|
|
|
3831
3872
|
lineNumber
|
|
3832
3873
|
});
|
|
3833
3874
|
}
|
|
3834
|
-
if (!
|
|
3875
|
+
if (!participantIds.has(to)) {
|
|
3876
|
+
participantIds.add(to);
|
|
3877
|
+
sortedCacheDirty = true;
|
|
3835
3878
|
result.participants.push({
|
|
3836
3879
|
id: to,
|
|
3837
3880
|
label: to,
|
|
@@ -3933,6 +3976,8 @@ function parseSequenceDgmo(content) {
|
|
|
3933
3976
|
const noteParsed = parseNoteLine(
|
|
3934
3977
|
trimmed,
|
|
3935
3978
|
result.participants,
|
|
3979
|
+
participantIds,
|
|
3980
|
+
getSortedParticipants(),
|
|
3936
3981
|
lastMsgFrom
|
|
3937
3982
|
);
|
|
3938
3983
|
if (noteParsed) {
|
|
@@ -4037,7 +4082,7 @@ function parseSequenceDgmo(content) {
|
|
|
4037
4082
|
entities.push({ metadata: g.metadata, lineNumber: g.lineNumber });
|
|
4038
4083
|
}
|
|
4039
4084
|
validateTagValues(entities, result.tagGroups, pushWarning, suggest);
|
|
4040
|
-
validateTagGroupNames(result.tagGroups, pushWarning);
|
|
4085
|
+
validateTagGroupNames(result.tagGroups, pushWarning, pushError);
|
|
4041
4086
|
}
|
|
4042
4087
|
return result;
|
|
4043
4088
|
}
|
|
@@ -4060,7 +4105,7 @@ var init_parser = __esm({
|
|
|
4060
4105
|
init_parsing();
|
|
4061
4106
|
init_tag_groups();
|
|
4062
4107
|
KNOWN_SEQ_OPTIONS = /* @__PURE__ */ new Set(["active-tag"]);
|
|
4063
|
-
KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set(["activations"
|
|
4108
|
+
KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set(["activations"]);
|
|
4064
4109
|
VALID_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
|
|
4065
4110
|
"service",
|
|
4066
4111
|
"database",
|
|
@@ -7321,7 +7366,7 @@ function buildFunnelOption(parsed, textColor, colors, bg, titleConfig) {
|
|
|
7321
7366
|
bottom: 20,
|
|
7322
7367
|
width: "60%",
|
|
7323
7368
|
sort: "descending",
|
|
7324
|
-
gap:
|
|
7369
|
+
gap: 0,
|
|
7325
7370
|
minSize: "8%"
|
|
7326
7371
|
};
|
|
7327
7372
|
return {
|
|
@@ -8436,7 +8481,7 @@ function parseOrg(content, palette) {
|
|
|
8436
8481
|
};
|
|
8437
8482
|
collectAll(result.roots);
|
|
8438
8483
|
validateTagValues(allNodes, result.tagGroups, pushWarning, suggest);
|
|
8439
|
-
validateTagGroupNames(result.tagGroups, pushWarning);
|
|
8484
|
+
validateTagGroupNames(result.tagGroups, pushWarning, pushError);
|
|
8440
8485
|
}
|
|
8441
8486
|
if (result.roots.length === 0 && result.tagGroups.length === 0 && !result.error) {
|
|
8442
8487
|
const diag = makeDgmoError(1, "No nodes found in org chart");
|
|
@@ -8769,7 +8814,11 @@ function parseKanban(content, palette) {
|
|
|
8769
8814
|
if (result.columns.length === 0 && !result.error) {
|
|
8770
8815
|
return fail(1, "No columns found. Use [Column Name] to define columns");
|
|
8771
8816
|
}
|
|
8772
|
-
validateTagGroupNames(result.tagGroups, warn)
|
|
8817
|
+
validateTagGroupNames(result.tagGroups, warn, (line11, msg) => {
|
|
8818
|
+
const diag = makeDgmoError(line11, msg);
|
|
8819
|
+
result.diagnostics.push(diag);
|
|
8820
|
+
if (!result.error) result.error = formatDgmoError(diag);
|
|
8821
|
+
});
|
|
8773
8822
|
return result;
|
|
8774
8823
|
}
|
|
8775
8824
|
function parseCardLine(trimmed, lineNumber, counter, aliasMap, _palette, _diagnostics) {
|
|
@@ -9895,7 +9944,7 @@ function parseSitemap(content, palette) {
|
|
|
9895
9944
|
};
|
|
9896
9945
|
collectAll(result.roots);
|
|
9897
9946
|
validateTagValues(allNodes, result.tagGroups, pushWarning, suggest);
|
|
9898
|
-
validateTagGroupNames(result.tagGroups, pushWarning);
|
|
9947
|
+
validateTagGroupNames(result.tagGroups, pushWarning, pushError);
|
|
9899
9948
|
}
|
|
9900
9949
|
if (result.roots.length === 0 && result.tagGroups.length === 0 && !result.error) {
|
|
9901
9950
|
const diag = makeDgmoError(1, "No pages found in sitemap");
|
|
@@ -10029,8 +10078,8 @@ function extractPipeMetadata(rest) {
|
|
|
10029
10078
|
const tags = {};
|
|
10030
10079
|
let clean = rest;
|
|
10031
10080
|
let match;
|
|
10032
|
-
|
|
10033
|
-
while ((match =
|
|
10081
|
+
PIPE_META_RE.lastIndex = 0;
|
|
10082
|
+
while ((match = PIPE_META_RE.exec(rest)) !== null) {
|
|
10034
10083
|
tags[match[1].trim()] = match[2].trim();
|
|
10035
10084
|
clean = clean.replace(match[0], "");
|
|
10036
10085
|
}
|
|
@@ -10532,7 +10581,7 @@ function parseInfra(content) {
|
|
|
10532
10581
|
}
|
|
10533
10582
|
}
|
|
10534
10583
|
}
|
|
10535
|
-
validateTagGroupNames(result.tagGroups, warn);
|
|
10584
|
+
validateTagGroupNames(result.tagGroups, warn, setError);
|
|
10536
10585
|
return result;
|
|
10537
10586
|
}
|
|
10538
10587
|
function extractSymbols4(docText) {
|
|
@@ -11473,7 +11522,11 @@ function parseGantt(content, palette) {
|
|
|
11473
11522
|
warn(0, "sort tag has no effect \u2014 no tag groups defined.");
|
|
11474
11523
|
result.options.sort = "default";
|
|
11475
11524
|
}
|
|
11476
|
-
validateTagGroupNames(result.tagGroups, warn)
|
|
11525
|
+
validateTagGroupNames(result.tagGroups, warn, (line11, msg) => {
|
|
11526
|
+
const diag = makeDgmoError(line11, msg);
|
|
11527
|
+
diagnostics.push(diag);
|
|
11528
|
+
if (!result.error) result.error = formatDgmoError(diag);
|
|
11529
|
+
});
|
|
11477
11530
|
const hasSprintOption = result.options.sprintLength !== null || result.options.sprintNumber !== null || result.options.sprintStart !== null;
|
|
11478
11531
|
const hasSprintUnit = hasSprintDurationUnit(result.nodes);
|
|
11479
11532
|
if (hasSprintOption) {
|
|
@@ -11737,6 +11790,7 @@ function parseBoxesAndLines(content) {
|
|
|
11737
11790
|
const groupLabels = /* @__PURE__ */ new Set();
|
|
11738
11791
|
let lastNodeLabel = null;
|
|
11739
11792
|
let lastSourceIsGroup = false;
|
|
11793
|
+
let lastNodeIndent = 0;
|
|
11740
11794
|
let descState = null;
|
|
11741
11795
|
function flushDescription() {
|
|
11742
11796
|
if (descState && descState.lines.length > 0) {
|
|
@@ -12034,7 +12088,8 @@ function parseBoxesAndLines(content) {
|
|
|
12034
12088
|
if (trimmed.startsWith("->") || /^-[^>].*->/.test(trimmed)) {
|
|
12035
12089
|
const gs2 = currentGroupState();
|
|
12036
12090
|
const inGroup = gs2 && indent > gs2.indent;
|
|
12037
|
-
|
|
12091
|
+
const indentedUnderNode = lastNodeLabel && !lastSourceIsGroup && indent > lastNodeIndent;
|
|
12092
|
+
if (inGroup && !indentedUnderNode) {
|
|
12038
12093
|
const sourcePrefix = `[${gs2.group.label}]`;
|
|
12039
12094
|
edgeText = `${sourcePrefix} ${trimmed}`;
|
|
12040
12095
|
} else if (lastNodeLabel) {
|
|
@@ -12074,6 +12129,7 @@ function parseBoxesAndLines(content) {
|
|
|
12074
12129
|
}
|
|
12075
12130
|
lastNodeLabel = node.label;
|
|
12076
12131
|
lastSourceIsGroup = false;
|
|
12132
|
+
lastNodeIndent = indent;
|
|
12077
12133
|
const gs = currentGroupState();
|
|
12078
12134
|
const isGroupChild = gs && indent > gs.indent;
|
|
12079
12135
|
if (nodeLabels.has(node.label)) {
|
|
@@ -12142,7 +12198,11 @@ function parseBoxesAndLines(content) {
|
|
|
12142
12198
|
if (result.tagGroups.length > 0) {
|
|
12143
12199
|
injectDefaultTagMetadata(result.nodes, result.tagGroups);
|
|
12144
12200
|
validateTagValues(result.nodes, result.tagGroups, pushWarning, suggest);
|
|
12145
|
-
validateTagGroupNames(result.tagGroups, pushWarning)
|
|
12201
|
+
validateTagGroupNames(result.tagGroups, pushWarning, (line11, msg) => {
|
|
12202
|
+
const diag = makeDgmoError(line11, msg);
|
|
12203
|
+
result.diagnostics.push(diag);
|
|
12204
|
+
if (!result.error) result.error = diag.message;
|
|
12205
|
+
});
|
|
12146
12206
|
}
|
|
12147
12207
|
return result;
|
|
12148
12208
|
}
|
|
@@ -13118,7 +13178,9 @@ function parseWireframe(content) {
|
|
|
13118
13178
|
}
|
|
13119
13179
|
}
|
|
13120
13180
|
}
|
|
13121
|
-
validateTagGroupNames(tagGroups, pushWarning)
|
|
13181
|
+
validateTagGroupNames(tagGroups, pushWarning, (line11, msg) => {
|
|
13182
|
+
diagnostics.push(makeDgmoError(line11, msg));
|
|
13183
|
+
});
|
|
13122
13184
|
const error = diagnostics.find((d) => d.severity === "error") ? formatDgmoError(diagnostics.find((d) => d.severity === "error")) : null;
|
|
13123
13185
|
return {
|
|
13124
13186
|
title,
|
|
@@ -14046,7 +14108,11 @@ function parseJourneyMap(content, palette) {
|
|
|
14046
14108
|
if (result.phases.length === 0 && result.steps.length === 0 && !result.error) {
|
|
14047
14109
|
return fail(1, "No phases or steps found");
|
|
14048
14110
|
}
|
|
14049
|
-
validateTagGroupNames(result.tagGroups, warn)
|
|
14111
|
+
validateTagGroupNames(result.tagGroups, warn, (line11, msg) => {
|
|
14112
|
+
const diag = makeDgmoError(line11, msg);
|
|
14113
|
+
result.diagnostics.push(diag);
|
|
14114
|
+
if (!result.error) result.error = formatDgmoError(diag);
|
|
14115
|
+
});
|
|
14050
14116
|
return result;
|
|
14051
14117
|
}
|
|
14052
14118
|
function parseStepLine(trimmed, lineNumber, counter, aliasMap, warn) {
|
|
@@ -14158,12 +14224,543 @@ var init_parser15 = __esm({
|
|
|
14158
14224
|
}
|
|
14159
14225
|
});
|
|
14160
14226
|
|
|
14227
|
+
// src/pyramid/parser.ts
|
|
14228
|
+
var parser_exports16 = {};
|
|
14229
|
+
__export(parser_exports16, {
|
|
14230
|
+
parsePyramid: () => parsePyramid
|
|
14231
|
+
});
|
|
14232
|
+
function parsePyramid(content) {
|
|
14233
|
+
const result = {
|
|
14234
|
+
type: "pyramid",
|
|
14235
|
+
title: "",
|
|
14236
|
+
titleLineNumber: 0,
|
|
14237
|
+
layers: [],
|
|
14238
|
+
inverted: false,
|
|
14239
|
+
options: {},
|
|
14240
|
+
diagnostics: [],
|
|
14241
|
+
error: null
|
|
14242
|
+
};
|
|
14243
|
+
const lines = content.split("\n");
|
|
14244
|
+
let headerParsed = false;
|
|
14245
|
+
let currentLayer = null;
|
|
14246
|
+
const fail = (line11, message) => {
|
|
14247
|
+
const diag = makeDgmoError(line11, message);
|
|
14248
|
+
result.diagnostics.push(diag);
|
|
14249
|
+
result.error = formatDgmoError(diag);
|
|
14250
|
+
return result;
|
|
14251
|
+
};
|
|
14252
|
+
const warn = (line11, message, severity = "warning") => {
|
|
14253
|
+
result.diagnostics.push(makeDgmoError(line11, message, severity));
|
|
14254
|
+
};
|
|
14255
|
+
const flushLayer = () => {
|
|
14256
|
+
if (currentLayer) {
|
|
14257
|
+
result.layers.push(currentLayer);
|
|
14258
|
+
currentLayer = null;
|
|
14259
|
+
}
|
|
14260
|
+
};
|
|
14261
|
+
for (let i = 0; i < lines.length; i++) {
|
|
14262
|
+
const lineNum = i + 1;
|
|
14263
|
+
const raw = lines[i];
|
|
14264
|
+
const trimmed = raw.trim();
|
|
14265
|
+
if (!trimmed || trimmed.startsWith("//")) continue;
|
|
14266
|
+
const indent = measureIndent(raw);
|
|
14267
|
+
if (!headerParsed) {
|
|
14268
|
+
const firstLineResult = parseFirstLine(trimmed);
|
|
14269
|
+
if (firstLineResult && firstLineResult.chartType === "pyramid") {
|
|
14270
|
+
result.title = firstLineResult.title ?? "";
|
|
14271
|
+
result.titleLineNumber = lineNum;
|
|
14272
|
+
headerParsed = true;
|
|
14273
|
+
continue;
|
|
14274
|
+
}
|
|
14275
|
+
return fail(lineNum, 'Expected "pyramid [Title]" as the first line.');
|
|
14276
|
+
}
|
|
14277
|
+
if (indent === 0 && trimmed.toLowerCase() === "inverted") {
|
|
14278
|
+
result.inverted = true;
|
|
14279
|
+
continue;
|
|
14280
|
+
}
|
|
14281
|
+
if (indent === 0) {
|
|
14282
|
+
flushLayer();
|
|
14283
|
+
const pipeIdx = trimmed.indexOf("|");
|
|
14284
|
+
let label;
|
|
14285
|
+
const description = [];
|
|
14286
|
+
let color;
|
|
14287
|
+
let restMeta = {};
|
|
14288
|
+
if (pipeIdx < 0) {
|
|
14289
|
+
label = trimmed;
|
|
14290
|
+
} else {
|
|
14291
|
+
label = trimmed.substring(0, pipeIdx).trim();
|
|
14292
|
+
const after = trimmed.substring(pipeIdx + 1).trim();
|
|
14293
|
+
if (!after) {
|
|
14294
|
+
} else if (KEY_VALUE_PREFIX_RE.test(after)) {
|
|
14295
|
+
const metadata = parsePipeMetadata([label, after]);
|
|
14296
|
+
color = metadata["color"];
|
|
14297
|
+
const descFromPipe = metadata["description"];
|
|
14298
|
+
if (descFromPipe) description.push(descFromPipe);
|
|
14299
|
+
restMeta = { ...metadata };
|
|
14300
|
+
delete restMeta["color"];
|
|
14301
|
+
delete restMeta["description"];
|
|
14302
|
+
} else {
|
|
14303
|
+
description.push(after);
|
|
14304
|
+
}
|
|
14305
|
+
}
|
|
14306
|
+
if (!label) {
|
|
14307
|
+
warn(lineNum, "Empty layer label.");
|
|
14308
|
+
continue;
|
|
14309
|
+
}
|
|
14310
|
+
currentLayer = {
|
|
14311
|
+
label,
|
|
14312
|
+
lineNumber: lineNum,
|
|
14313
|
+
color,
|
|
14314
|
+
description,
|
|
14315
|
+
metadata: restMeta
|
|
14316
|
+
};
|
|
14317
|
+
continue;
|
|
14318
|
+
}
|
|
14319
|
+
if (!currentLayer) {
|
|
14320
|
+
warn(lineNum, `Unexpected indented line: "${trimmed}".`);
|
|
14321
|
+
continue;
|
|
14322
|
+
}
|
|
14323
|
+
const descLine = trimmed.startsWith("- ") ? `\u2022 ${trimmed.substring(2)}` : trimmed;
|
|
14324
|
+
currentLayer.description.push(descLine);
|
|
14325
|
+
}
|
|
14326
|
+
flushLayer();
|
|
14327
|
+
if (result.layers.length < 2) {
|
|
14328
|
+
return fail(
|
|
14329
|
+
result.titleLineNumber || 1,
|
|
14330
|
+
"pyramid requires at least 2 layers."
|
|
14331
|
+
);
|
|
14332
|
+
}
|
|
14333
|
+
return result;
|
|
14334
|
+
}
|
|
14335
|
+
var KEY_VALUE_PREFIX_RE;
|
|
14336
|
+
var init_parser16 = __esm({
|
|
14337
|
+
"src/pyramid/parser.ts"() {
|
|
14338
|
+
"use strict";
|
|
14339
|
+
init_diagnostics();
|
|
14340
|
+
init_parsing();
|
|
14341
|
+
KEY_VALUE_PREFIX_RE = /^\s*[A-Za-z][A-Za-z0-9_-]*\s*:/;
|
|
14342
|
+
}
|
|
14343
|
+
});
|
|
14344
|
+
|
|
14345
|
+
// src/chart-types.ts
|
|
14346
|
+
var chartTypes;
|
|
14347
|
+
var init_chart_types = __esm({
|
|
14348
|
+
"src/chart-types.ts"() {
|
|
14349
|
+
"use strict";
|
|
14350
|
+
chartTypes = [
|
|
14351
|
+
// ── Tier 1 — Narrative / architecture diagrams ────────────
|
|
14352
|
+
{
|
|
14353
|
+
id: "journey-map",
|
|
14354
|
+
description: "User experience flow with emotion scores, phases, and annotations",
|
|
14355
|
+
triggers: [
|
|
14356
|
+
"user journey",
|
|
14357
|
+
"customer journey",
|
|
14358
|
+
"customer experience",
|
|
14359
|
+
"customer goes through",
|
|
14360
|
+
"user goes through",
|
|
14361
|
+
"customer path",
|
|
14362
|
+
"customer touchpoints",
|
|
14363
|
+
"cx flow",
|
|
14364
|
+
"ux journey",
|
|
14365
|
+
"onboarding flow",
|
|
14366
|
+
"persona journey",
|
|
14367
|
+
"empathy map",
|
|
14368
|
+
"service blueprint"
|
|
14369
|
+
]
|
|
14370
|
+
},
|
|
14371
|
+
{
|
|
14372
|
+
id: "c4",
|
|
14373
|
+
description: "System architecture (context, container, component, deployment)",
|
|
14374
|
+
triggers: [
|
|
14375
|
+
"c4 diagram",
|
|
14376
|
+
"system context",
|
|
14377
|
+
"container diagram",
|
|
14378
|
+
"component diagram",
|
|
14379
|
+
"architecture overview",
|
|
14380
|
+
"software architecture"
|
|
14381
|
+
]
|
|
14382
|
+
},
|
|
14383
|
+
{
|
|
14384
|
+
id: "er",
|
|
14385
|
+
description: "Database schemas and relationships",
|
|
14386
|
+
triggers: [
|
|
14387
|
+
"database schema",
|
|
14388
|
+
"er diagram",
|
|
14389
|
+
"entity relationship",
|
|
14390
|
+
"data model",
|
|
14391
|
+
"tables and relationships",
|
|
14392
|
+
"foreign keys"
|
|
14393
|
+
]
|
|
14394
|
+
},
|
|
14395
|
+
{
|
|
14396
|
+
id: "class",
|
|
14397
|
+
description: "UML class hierarchies",
|
|
14398
|
+
triggers: [
|
|
14399
|
+
"uml class",
|
|
14400
|
+
"class hierarchy",
|
|
14401
|
+
"class diagram",
|
|
14402
|
+
"inheritance tree",
|
|
14403
|
+
"oop structure"
|
|
14404
|
+
]
|
|
14405
|
+
},
|
|
14406
|
+
{
|
|
14407
|
+
id: "sequence",
|
|
14408
|
+
description: "Message / interaction flows",
|
|
14409
|
+
triggers: [
|
|
14410
|
+
"sequence diagram",
|
|
14411
|
+
"message flow",
|
|
14412
|
+
"api call flow",
|
|
14413
|
+
"request lifecycle",
|
|
14414
|
+
"interaction diagram",
|
|
14415
|
+
"call sequence"
|
|
14416
|
+
],
|
|
14417
|
+
fallback: true
|
|
14418
|
+
},
|
|
14419
|
+
{
|
|
14420
|
+
id: "state",
|
|
14421
|
+
description: "State machine / lifecycle transitions",
|
|
14422
|
+
triggers: [
|
|
14423
|
+
"state diagram",
|
|
14424
|
+
"state machine",
|
|
14425
|
+
"state transitions",
|
|
14426
|
+
"lifecycle diagram",
|
|
14427
|
+
"status transitions"
|
|
14428
|
+
]
|
|
14429
|
+
},
|
|
14430
|
+
{
|
|
14431
|
+
id: "infra",
|
|
14432
|
+
description: "Infrastructure traffic flow with RPS computation",
|
|
14433
|
+
triggers: [
|
|
14434
|
+
"infrastructure diagram",
|
|
14435
|
+
"traffic flow",
|
|
14436
|
+
"request path",
|
|
14437
|
+
"rps",
|
|
14438
|
+
"capacity planning",
|
|
14439
|
+
"network topology"
|
|
14440
|
+
]
|
|
14441
|
+
},
|
|
14442
|
+
{
|
|
14443
|
+
id: "gantt",
|
|
14444
|
+
description: "Project scheduling with task dependencies and milestones",
|
|
14445
|
+
triggers: [
|
|
14446
|
+
"gantt chart",
|
|
14447
|
+
"project schedule",
|
|
14448
|
+
"sprint plan",
|
|
14449
|
+
"project timeline",
|
|
14450
|
+
"task dependencies",
|
|
14451
|
+
"project milestones"
|
|
14452
|
+
]
|
|
14453
|
+
},
|
|
14454
|
+
// ── Tier 2 — Specialized structural diagrams ──────────────
|
|
14455
|
+
{
|
|
14456
|
+
id: "timeline",
|
|
14457
|
+
description: "Events, eras, and date ranges",
|
|
14458
|
+
triggers: [
|
|
14459
|
+
"event timeline",
|
|
14460
|
+
"historical timeline",
|
|
14461
|
+
"era chart",
|
|
14462
|
+
"period chart",
|
|
14463
|
+
"project history"
|
|
14464
|
+
]
|
|
14465
|
+
},
|
|
14466
|
+
{
|
|
14467
|
+
id: "org",
|
|
14468
|
+
description: "Reporting hierarchy",
|
|
14469
|
+
triggers: [
|
|
14470
|
+
"org chart",
|
|
14471
|
+
"organization chart",
|
|
14472
|
+
"reporting structure",
|
|
14473
|
+
"hierarchy chart",
|
|
14474
|
+
"team structure"
|
|
14475
|
+
]
|
|
14476
|
+
},
|
|
14477
|
+
{
|
|
14478
|
+
id: "sitemap",
|
|
14479
|
+
description: "Site / app navigation structure",
|
|
14480
|
+
triggers: [
|
|
14481
|
+
"sitemap",
|
|
14482
|
+
"site structure",
|
|
14483
|
+
"page hierarchy",
|
|
14484
|
+
"navigation structure",
|
|
14485
|
+
"app navigation"
|
|
14486
|
+
]
|
|
14487
|
+
},
|
|
14488
|
+
{
|
|
14489
|
+
id: "kanban",
|
|
14490
|
+
description: "Task board columns",
|
|
14491
|
+
triggers: [
|
|
14492
|
+
"kanban board",
|
|
14493
|
+
"task board",
|
|
14494
|
+
"workflow columns",
|
|
14495
|
+
"todo doing done",
|
|
14496
|
+
"agile board"
|
|
14497
|
+
]
|
|
14498
|
+
},
|
|
14499
|
+
{
|
|
14500
|
+
id: "tech-radar",
|
|
14501
|
+
description: "Technology adoption quadrants (adopt/trial/assess/hold)",
|
|
14502
|
+
triggers: [
|
|
14503
|
+
"tech radar",
|
|
14504
|
+
"technology radar",
|
|
14505
|
+
"tech adoption",
|
|
14506
|
+
"adopt trial assess hold",
|
|
14507
|
+
"tech choices"
|
|
14508
|
+
]
|
|
14509
|
+
},
|
|
14510
|
+
{
|
|
14511
|
+
id: "mindmap",
|
|
14512
|
+
description: "Radial hierarchy of ideas branching from a central topic",
|
|
14513
|
+
triggers: [
|
|
14514
|
+
"mind map",
|
|
14515
|
+
"brainstorm diagram",
|
|
14516
|
+
"concept map",
|
|
14517
|
+
"idea tree",
|
|
14518
|
+
"radial ideas"
|
|
14519
|
+
]
|
|
14520
|
+
},
|
|
14521
|
+
{
|
|
14522
|
+
id: "wireframe",
|
|
14523
|
+
description: "Low-fidelity UI layout with panels, controls, and annotations",
|
|
14524
|
+
triggers: [
|
|
14525
|
+
"wireframe",
|
|
14526
|
+
"ui mockup",
|
|
14527
|
+
"screen layout",
|
|
14528
|
+
"page layout",
|
|
14529
|
+
"low-fidelity mockup"
|
|
14530
|
+
]
|
|
14531
|
+
},
|
|
14532
|
+
{
|
|
14533
|
+
id: "cycle",
|
|
14534
|
+
description: "Cyclical process visualization (PDCA, OODA, DevOps loops)",
|
|
14535
|
+
triggers: [
|
|
14536
|
+
"pdca cycle",
|
|
14537
|
+
"ooda loop",
|
|
14538
|
+
"feedback loop",
|
|
14539
|
+
"cyclical process",
|
|
14540
|
+
"devops loop",
|
|
14541
|
+
"continuous loop"
|
|
14542
|
+
]
|
|
14543
|
+
},
|
|
14544
|
+
{
|
|
14545
|
+
id: "pyramid",
|
|
14546
|
+
description: "Stacked hierarchy of layers with descriptions (Maslow, DIKW)",
|
|
14547
|
+
triggers: [
|
|
14548
|
+
"pyramid diagram",
|
|
14549
|
+
"layered hierarchy",
|
|
14550
|
+
"maslow hierarchy",
|
|
14551
|
+
"dikw pyramid",
|
|
14552
|
+
"layered model"
|
|
14553
|
+
]
|
|
14554
|
+
},
|
|
14555
|
+
// ── Tier 3 — Specialized analytical charts ────────────────
|
|
14556
|
+
{
|
|
14557
|
+
id: "quadrant",
|
|
14558
|
+
description: "2x2 positioning matrix",
|
|
14559
|
+
triggers: [
|
|
14560
|
+
"2x2 matrix",
|
|
14561
|
+
"priority matrix",
|
|
14562
|
+
"quadrant chart",
|
|
14563
|
+
"impact effort matrix",
|
|
14564
|
+
"positioning matrix"
|
|
14565
|
+
]
|
|
14566
|
+
},
|
|
14567
|
+
{
|
|
14568
|
+
id: "venn",
|
|
14569
|
+
description: "Set overlaps",
|
|
14570
|
+
triggers: [
|
|
14571
|
+
"venn diagram",
|
|
14572
|
+
"set overlap",
|
|
14573
|
+
"intersection of",
|
|
14574
|
+
"shared traits",
|
|
14575
|
+
"overlapping circles"
|
|
14576
|
+
]
|
|
14577
|
+
},
|
|
14578
|
+
{
|
|
14579
|
+
id: "funnel",
|
|
14580
|
+
description: "Conversion pipeline",
|
|
14581
|
+
triggers: [
|
|
14582
|
+
"conversion funnel",
|
|
14583
|
+
"sales funnel",
|
|
14584
|
+
"user funnel",
|
|
14585
|
+
"pipeline stages",
|
|
14586
|
+
"drop-off funnel"
|
|
14587
|
+
]
|
|
14588
|
+
},
|
|
14589
|
+
{
|
|
14590
|
+
id: "slope",
|
|
14591
|
+
description: "Change between two periods",
|
|
14592
|
+
triggers: [
|
|
14593
|
+
"slope chart",
|
|
14594
|
+
"before and after",
|
|
14595
|
+
"two-period change",
|
|
14596
|
+
"delta chart",
|
|
14597
|
+
"shift comparison"
|
|
14598
|
+
]
|
|
14599
|
+
},
|
|
14600
|
+
{
|
|
14601
|
+
id: "sankey",
|
|
14602
|
+
description: "Flow / allocation visualization",
|
|
14603
|
+
triggers: [
|
|
14604
|
+
"sankey diagram",
|
|
14605
|
+
"flow allocation",
|
|
14606
|
+
"budget flow",
|
|
14607
|
+
"energy flow",
|
|
14608
|
+
"traffic allocation"
|
|
14609
|
+
]
|
|
14610
|
+
},
|
|
14611
|
+
{
|
|
14612
|
+
id: "chord",
|
|
14613
|
+
description: "Circular flow relationships",
|
|
14614
|
+
triggers: [
|
|
14615
|
+
"chord diagram",
|
|
14616
|
+
"circular flow",
|
|
14617
|
+
"relationship wheel",
|
|
14618
|
+
"team connections"
|
|
14619
|
+
]
|
|
14620
|
+
},
|
|
14621
|
+
{
|
|
14622
|
+
id: "arc",
|
|
14623
|
+
description: "Network relationships",
|
|
14624
|
+
triggers: [
|
|
14625
|
+
"arc diagram",
|
|
14626
|
+
"relationship chart",
|
|
14627
|
+
"connection arcs",
|
|
14628
|
+
"network arcs"
|
|
14629
|
+
]
|
|
14630
|
+
},
|
|
14631
|
+
{
|
|
14632
|
+
id: "wordcloud",
|
|
14633
|
+
description: "Term frequency visualization",
|
|
14634
|
+
triggers: [
|
|
14635
|
+
"word cloud",
|
|
14636
|
+
"tag cloud",
|
|
14637
|
+
"term frequency",
|
|
14638
|
+
"keyword frequency"
|
|
14639
|
+
]
|
|
14640
|
+
},
|
|
14641
|
+
{
|
|
14642
|
+
id: "heatmap",
|
|
14643
|
+
description: "Matrix intensity visualization",
|
|
14644
|
+
triggers: [
|
|
14645
|
+
"heatmap",
|
|
14646
|
+
"intensity matrix",
|
|
14647
|
+
"activity heatmap",
|
|
14648
|
+
"correlation matrix"
|
|
14649
|
+
]
|
|
14650
|
+
},
|
|
14651
|
+
{
|
|
14652
|
+
id: "function",
|
|
14653
|
+
description: "Mathematical expressions",
|
|
14654
|
+
triggers: [
|
|
14655
|
+
"function plot",
|
|
14656
|
+
"mathematical plot",
|
|
14657
|
+
"equation chart",
|
|
14658
|
+
"graph y=f(x)"
|
|
14659
|
+
]
|
|
14660
|
+
},
|
|
14661
|
+
// ── Tier 4 — General-purpose data charts ──────────────────
|
|
14662
|
+
{
|
|
14663
|
+
id: "bar",
|
|
14664
|
+
description: "Categorical comparisons",
|
|
14665
|
+
triggers: ["bar chart", "categorical comparison", "bar graph"],
|
|
14666
|
+
fallback: true
|
|
14667
|
+
},
|
|
14668
|
+
{
|
|
14669
|
+
id: "line",
|
|
14670
|
+
description: "Trends over time",
|
|
14671
|
+
triggers: ["line chart", "trend over time", "time series"],
|
|
14672
|
+
fallback: true
|
|
14673
|
+
},
|
|
14674
|
+
{
|
|
14675
|
+
id: "multi-line",
|
|
14676
|
+
description: "Multiple series trends over time",
|
|
14677
|
+
triggers: [
|
|
14678
|
+
"multi-line chart",
|
|
14679
|
+
"multiple trends",
|
|
14680
|
+
"multiple series over time"
|
|
14681
|
+
]
|
|
14682
|
+
},
|
|
14683
|
+
{
|
|
14684
|
+
id: "area",
|
|
14685
|
+
description: "Filled line chart",
|
|
14686
|
+
triggers: ["area chart", "filled line", "cumulative trend"]
|
|
14687
|
+
},
|
|
14688
|
+
{
|
|
14689
|
+
id: "pie",
|
|
14690
|
+
description: "Part-to-whole proportions",
|
|
14691
|
+
triggers: ["pie chart", "part to whole", "percentage breakdown"]
|
|
14692
|
+
},
|
|
14693
|
+
{
|
|
14694
|
+
id: "doughnut",
|
|
14695
|
+
description: "Ring-style pie chart",
|
|
14696
|
+
triggers: ["doughnut chart", "donut chart", "ring chart"]
|
|
14697
|
+
},
|
|
14698
|
+
{
|
|
14699
|
+
id: "radar",
|
|
14700
|
+
description: "Multi-dimensional metrics",
|
|
14701
|
+
triggers: ["radar chart", "spider chart", "multi-dimensional metrics"]
|
|
14702
|
+
},
|
|
14703
|
+
{
|
|
14704
|
+
id: "polar-area",
|
|
14705
|
+
description: "Radial bar chart",
|
|
14706
|
+
triggers: ["polar area", "radial bar chart"]
|
|
14707
|
+
},
|
|
14708
|
+
{
|
|
14709
|
+
id: "bar-stacked",
|
|
14710
|
+
description: "Multi-series categorical",
|
|
14711
|
+
triggers: [
|
|
14712
|
+
"stacked bar",
|
|
14713
|
+
"stacked bar chart",
|
|
14714
|
+
"multi-series bar",
|
|
14715
|
+
"composite bar"
|
|
14716
|
+
]
|
|
14717
|
+
},
|
|
14718
|
+
{
|
|
14719
|
+
id: "scatter",
|
|
14720
|
+
description: "2D data points or bubble chart",
|
|
14721
|
+
triggers: [
|
|
14722
|
+
"scatter plot",
|
|
14723
|
+
"correlation plot",
|
|
14724
|
+
"bubble chart",
|
|
14725
|
+
"2d data points"
|
|
14726
|
+
]
|
|
14727
|
+
},
|
|
14728
|
+
// ── Tier 5 — Generic catch-alls (listed last on purpose) ──
|
|
14729
|
+
{
|
|
14730
|
+
id: "flowchart",
|
|
14731
|
+
description: "Decision trees and process flows",
|
|
14732
|
+
triggers: [
|
|
14733
|
+
"flowchart",
|
|
14734
|
+
"decision tree",
|
|
14735
|
+
"if-then diagram",
|
|
14736
|
+
"process flow with decisions"
|
|
14737
|
+
],
|
|
14738
|
+
fallback: true
|
|
14739
|
+
},
|
|
14740
|
+
{
|
|
14741
|
+
id: "boxes-and-lines",
|
|
14742
|
+
description: "General-purpose node-edge diagrams with groups and tags",
|
|
14743
|
+
triggers: [
|
|
14744
|
+
"boxes and lines",
|
|
14745
|
+
"nodes and edges",
|
|
14746
|
+
"generic diagram",
|
|
14747
|
+
"general-purpose network"
|
|
14748
|
+
],
|
|
14749
|
+
fallback: true
|
|
14750
|
+
}
|
|
14751
|
+
];
|
|
14752
|
+
}
|
|
14753
|
+
});
|
|
14754
|
+
|
|
14161
14755
|
// src/dgmo-router.ts
|
|
14162
14756
|
var dgmo_router_exports = {};
|
|
14163
14757
|
__export(dgmo_router_exports, {
|
|
14758
|
+
CHART_TYPE_DESCRIPTIONS: () => CHART_TYPE_DESCRIPTIONS,
|
|
14759
|
+
chartTypeParsers: () => chartTypeParsers,
|
|
14164
14760
|
getAllChartTypes: () => getAllChartTypes,
|
|
14165
14761
|
getRenderCategory: () => getRenderCategory,
|
|
14166
14762
|
isExtendedChartType: () => isExtendedChartType,
|
|
14763
|
+
knownChartTypeIds: () => knownChartTypeIds,
|
|
14167
14764
|
looksLikeC4: () => looksLikeC4,
|
|
14168
14765
|
looksLikeGantt: () => looksLikeGantt,
|
|
14169
14766
|
parseDgmo: () => parseDgmo,
|
|
@@ -14222,7 +14819,7 @@ function isExtendedChartType(chartType) {
|
|
|
14222
14819
|
return EXTENDED_CHART_TYPES.has(chartType.toLowerCase());
|
|
14223
14820
|
}
|
|
14224
14821
|
function getAllChartTypes() {
|
|
14225
|
-
return
|
|
14822
|
+
return chartTypes.map((c) => c.id);
|
|
14226
14823
|
}
|
|
14227
14824
|
function parseDgmo(content) {
|
|
14228
14825
|
const chartType = parseDgmoChartType(content);
|
|
@@ -14230,32 +14827,25 @@ function parseDgmo(content) {
|
|
|
14230
14827
|
const colonDiag = detectColonChartType(content);
|
|
14231
14828
|
if (colonDiag) {
|
|
14232
14829
|
const fallback = parseVisualization(content).diagnostics;
|
|
14233
|
-
return { diagnostics: [colonDiag, ...fallback] };
|
|
14830
|
+
return { diagnostics: [colonDiag, ...fallback], chartType: null };
|
|
14234
14831
|
}
|
|
14235
|
-
return { diagnostics: parseVisualization(content).diagnostics };
|
|
14236
|
-
}
|
|
14237
|
-
const directParser = PARSE_DISPATCH.get(chartType);
|
|
14238
|
-
if (directParser) {
|
|
14239
|
-
const result2 = directParser(content);
|
|
14240
|
-
return {
|
|
14241
|
-
diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)]
|
|
14242
|
-
};
|
|
14243
|
-
}
|
|
14244
|
-
if (STANDARD_CHART_TYPES2.has(chartType)) {
|
|
14245
|
-
const result2 = parseChart(content);
|
|
14246
14832
|
return {
|
|
14247
|
-
diagnostics:
|
|
14833
|
+
diagnostics: parseVisualization(content).diagnostics,
|
|
14834
|
+
chartType: null
|
|
14248
14835
|
};
|
|
14249
14836
|
}
|
|
14250
|
-
|
|
14251
|
-
|
|
14837
|
+
const parser = PARSER_BY_ID.get(chartType);
|
|
14838
|
+
if (parser) {
|
|
14839
|
+
const result2 = parser(content);
|
|
14252
14840
|
return {
|
|
14253
|
-
diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)]
|
|
14841
|
+
diagnostics: [...result2.diagnostics, ...detectEmptyContent(content)],
|
|
14842
|
+
chartType
|
|
14254
14843
|
};
|
|
14255
14844
|
}
|
|
14256
14845
|
const result = parseVisualization(content);
|
|
14257
14846
|
return {
|
|
14258
|
-
diagnostics: [...result.diagnostics, ...detectEmptyContent(content)]
|
|
14847
|
+
diagnostics: [...result.diagnostics, ...detectEmptyContent(content)],
|
|
14848
|
+
chartType
|
|
14259
14849
|
};
|
|
14260
14850
|
}
|
|
14261
14851
|
function detectColonChartType(content) {
|
|
@@ -14298,7 +14888,7 @@ function detectEmptyContent(content) {
|
|
|
14298
14888
|
}
|
|
14299
14889
|
return [];
|
|
14300
14890
|
}
|
|
14301
|
-
var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, DATA_CHART_TYPES, VISUALIZATION_TYPES, DIAGRAM_TYPES, EXTENDED_CHART_TYPES,
|
|
14891
|
+
var GANTT_DURATION_RE, GANTT_DATE_RE, C4_TYPE_RE, DATA_CHART_TYPES, VISUALIZATION_TYPES, DIAGRAM_TYPES, EXTENDED_CHART_TYPES, CHART_TYPE_DESCRIPTIONS, chartTypeParsers, knownChartTypeIds, PARSER_BY_ID, ALL_KNOWN_TYPES;
|
|
14302
14892
|
var init_dgmo_router = __esm({
|
|
14303
14893
|
"src/dgmo-router.ts"() {
|
|
14304
14894
|
"use strict";
|
|
@@ -14322,8 +14912,10 @@ var init_dgmo_router = __esm({
|
|
|
14322
14912
|
init_parser13();
|
|
14323
14913
|
init_parser14();
|
|
14324
14914
|
init_parser15();
|
|
14915
|
+
init_parser16();
|
|
14325
14916
|
init_parsing();
|
|
14326
14917
|
init_diagnostics();
|
|
14918
|
+
init_chart_types();
|
|
14327
14919
|
GANTT_DURATION_RE = /^\d+(?:\.\d+)?(?:min|bd|d|w|m|q|y|h)(?:\?)?\s+/;
|
|
14328
14920
|
GANTT_DATE_RE = /^\d{4}-\d{2}-\d{2}(?:\s\d{2}:\d{2})?\s+/;
|
|
14329
14921
|
C4_TYPE_RE = /\bis\s+an?\s+(person|system|container|component)\b/i;
|
|
@@ -14352,7 +14944,8 @@ var init_dgmo_router = __esm({
|
|
|
14352
14944
|
"venn",
|
|
14353
14945
|
"quadrant",
|
|
14354
14946
|
"tech-radar",
|
|
14355
|
-
"cycle"
|
|
14947
|
+
"cycle",
|
|
14948
|
+
"pyramid"
|
|
14356
14949
|
]);
|
|
14357
14950
|
DIAGRAM_TYPES = /* @__PURE__ */ new Set([
|
|
14358
14951
|
"sequence",
|
|
@@ -14379,49 +14972,57 @@ var init_dgmo_router = __esm({
|
|
|
14379
14972
|
"heatmap",
|
|
14380
14973
|
"funnel"
|
|
14381
14974
|
]);
|
|
14382
|
-
|
|
14383
|
-
|
|
14384
|
-
|
|
14385
|
-
"
|
|
14386
|
-
"
|
|
14387
|
-
"
|
|
14388
|
-
"
|
|
14389
|
-
"
|
|
14390
|
-
"
|
|
14391
|
-
"
|
|
14392
|
-
|
|
14393
|
-
|
|
14394
|
-
"
|
|
14395
|
-
"
|
|
14396
|
-
"
|
|
14397
|
-
"
|
|
14398
|
-
"
|
|
14399
|
-
"
|
|
14400
|
-
|
|
14401
|
-
|
|
14402
|
-
["
|
|
14403
|
-
|
|
14404
|
-
["
|
|
14405
|
-
["
|
|
14406
|
-
["
|
|
14407
|
-
["
|
|
14408
|
-
["
|
|
14409
|
-
["
|
|
14410
|
-
["
|
|
14411
|
-
["
|
|
14412
|
-
["
|
|
14413
|
-
|
|
14414
|
-
["
|
|
14415
|
-
["
|
|
14416
|
-
["
|
|
14417
|
-
["
|
|
14418
|
-
["
|
|
14419
|
-
|
|
14420
|
-
|
|
14421
|
-
|
|
14422
|
-
|
|
14423
|
-
|
|
14424
|
-
|
|
14975
|
+
CHART_TYPE_DESCRIPTIONS = Object.fromEntries(chartTypes.map((c) => [c.id, c.description]));
|
|
14976
|
+
chartTypeParsers = [
|
|
14977
|
+
// Structured diagrams (direct parsers)
|
|
14978
|
+
["sequence", parseSequenceDgmo],
|
|
14979
|
+
["flowchart", parseFlowchart],
|
|
14980
|
+
["class", parseClassDiagram],
|
|
14981
|
+
["er", parseERDiagram],
|
|
14982
|
+
["state", parseState],
|
|
14983
|
+
["org", parseOrg],
|
|
14984
|
+
["kanban", parseKanban],
|
|
14985
|
+
["c4", parseC4],
|
|
14986
|
+
["sitemap", parseSitemap],
|
|
14987
|
+
["infra", parseInfra],
|
|
14988
|
+
["gantt", parseGantt],
|
|
14989
|
+
["boxes-and-lines", parseBoxesAndLines],
|
|
14990
|
+
["mindmap", parseMindmap],
|
|
14991
|
+
["wireframe", parseWireframe],
|
|
14992
|
+
["tech-radar", parseTechRadar],
|
|
14993
|
+
["cycle", parseCycle],
|
|
14994
|
+
["journey-map", parseJourneyMap],
|
|
14995
|
+
["pyramid", parsePyramid],
|
|
14996
|
+
// Standard ECharts charts (parseChart)
|
|
14997
|
+
["bar", parseChart],
|
|
14998
|
+
["line", parseChart],
|
|
14999
|
+
["multi-line", parseChart],
|
|
15000
|
+
["area", parseChart],
|
|
15001
|
+
["pie", parseChart],
|
|
15002
|
+
["doughnut", parseChart],
|
|
15003
|
+
["radar", parseChart],
|
|
15004
|
+
["polar-area", parseChart],
|
|
15005
|
+
["bar-stacked", parseChart],
|
|
15006
|
+
// Extended ECharts charts (parseExtendedChart)
|
|
15007
|
+
["scatter", parseExtendedChart],
|
|
15008
|
+
["sankey", parseExtendedChart],
|
|
15009
|
+
["chord", parseExtendedChart],
|
|
15010
|
+
["function", parseExtendedChart],
|
|
15011
|
+
["heatmap", parseExtendedChart],
|
|
15012
|
+
["funnel", parseExtendedChart],
|
|
15013
|
+
// D3 visualizations (parseVisualization)
|
|
15014
|
+
["slope", parseVisualization],
|
|
15015
|
+
["wordcloud", parseVisualization],
|
|
15016
|
+
["arc", parseVisualization],
|
|
15017
|
+
["timeline", parseVisualization],
|
|
15018
|
+
["venn", parseVisualization],
|
|
15019
|
+
["quadrant", parseVisualization]
|
|
15020
|
+
];
|
|
15021
|
+
knownChartTypeIds = chartTypeParsers.map(
|
|
15022
|
+
([id]) => id
|
|
15023
|
+
);
|
|
15024
|
+
PARSER_BY_ID = new Map(chartTypeParsers);
|
|
15025
|
+
ALL_KNOWN_TYPES = new Set(knownChartTypeIds);
|
|
14425
15026
|
}
|
|
14426
15027
|
});
|
|
14427
15028
|
|
|
@@ -15224,7 +15825,8 @@ var init_layout = __esm({
|
|
|
15224
15825
|
// src/org/collapse.ts
|
|
15225
15826
|
var collapse_exports = {};
|
|
15226
15827
|
__export(collapse_exports, {
|
|
15227
|
-
collapseOrgTree: () => collapseOrgTree
|
|
15828
|
+
collapseOrgTree: () => collapseOrgTree,
|
|
15829
|
+
focusOrgTree: () => focusOrgTree
|
|
15228
15830
|
});
|
|
15229
15831
|
function cloneNode(node) {
|
|
15230
15832
|
return {
|
|
@@ -15279,6 +15881,49 @@ function collapseOrgTree(original, collapsedIds) {
|
|
|
15279
15881
|
hiddenCounts
|
|
15280
15882
|
};
|
|
15281
15883
|
}
|
|
15884
|
+
function findNodeWithPath(nodes, targetId, path) {
|
|
15885
|
+
for (const node of nodes) {
|
|
15886
|
+
if (node.id === targetId) {
|
|
15887
|
+
return { node, path };
|
|
15888
|
+
}
|
|
15889
|
+
const result = findNodeWithPath(node.children, targetId, [
|
|
15890
|
+
...path,
|
|
15891
|
+
{
|
|
15892
|
+
id: node.id,
|
|
15893
|
+
label: node.label,
|
|
15894
|
+
lineNumber: node.lineNumber,
|
|
15895
|
+
color: node.color,
|
|
15896
|
+
metadata: { ...node.metadata },
|
|
15897
|
+
isContainer: node.isContainer
|
|
15898
|
+
}
|
|
15899
|
+
]);
|
|
15900
|
+
if (result) return result;
|
|
15901
|
+
}
|
|
15902
|
+
return null;
|
|
15903
|
+
}
|
|
15904
|
+
function focusOrgTree(original, focusNodeId) {
|
|
15905
|
+
const found = findNodeWithPath(original.roots, focusNodeId, []);
|
|
15906
|
+
if (!found) return null;
|
|
15907
|
+
const isRoot = original.roots.some((r) => r.id === focusNodeId);
|
|
15908
|
+
if (isRoot) {
|
|
15909
|
+
return {
|
|
15910
|
+
parsed: {
|
|
15911
|
+
...original,
|
|
15912
|
+
roots: [cloneNode(found.node)]
|
|
15913
|
+
},
|
|
15914
|
+
ancestorPath: []
|
|
15915
|
+
};
|
|
15916
|
+
}
|
|
15917
|
+
const cloned = cloneNode(found.node);
|
|
15918
|
+
cloned.parentId = null;
|
|
15919
|
+
return {
|
|
15920
|
+
parsed: {
|
|
15921
|
+
...original,
|
|
15922
|
+
roots: [cloned]
|
|
15923
|
+
},
|
|
15924
|
+
ancestorPath: found.path
|
|
15925
|
+
};
|
|
15926
|
+
}
|
|
15282
15927
|
var init_collapse = __esm({
|
|
15283
15928
|
"src/org/collapse.ts"() {
|
|
15284
15929
|
"use strict";
|
|
@@ -15338,7 +15983,7 @@ function containerFill(palette, isDark, nodeColor2) {
|
|
|
15338
15983
|
function containerStroke(palette, nodeColor2) {
|
|
15339
15984
|
return nodeColor2 ?? palette.textMuted;
|
|
15340
15985
|
}
|
|
15341
|
-
function renderOrg(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, hiddenAttributes) {
|
|
15986
|
+
function renderOrg(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup, hiddenAttributes, ancestorPath) {
|
|
15342
15987
|
d3Selection.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
15343
15988
|
const width = exportDims?.width ?? container.clientWidth;
|
|
15344
15989
|
const height = exportDims?.height ?? container.clientHeight;
|
|
@@ -15351,8 +15996,10 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
15351
15996
|
const legendReserve = fixedLegend ? LEGEND_HEIGHT + LEGEND_FIXED_GAP : 0;
|
|
15352
15997
|
const fixedTitle = !exportDims && !!parsed.title;
|
|
15353
15998
|
const titleReserve = fixedTitle ? TITLE_HEIGHT : 0;
|
|
15999
|
+
const hasAncestorTrail = !exportDims && ancestorPath && ancestorPath.length > 0;
|
|
16000
|
+
const ancestorTrailHeight = hasAncestorTrail ? ancestorPath.length * ANCESTOR_ROW_HEIGHT + ANCESTOR_TRAIL_BOTTOM_GAP : 0;
|
|
15354
16001
|
const diagramW = layout.width;
|
|
15355
|
-
let diagramH = layout.height + (fixedTitle ? 0 : titleOffset);
|
|
16002
|
+
let diagramH = layout.height + (fixedTitle ? 0 : titleOffset) + ancestorTrailHeight;
|
|
15356
16003
|
if (fixedLegend) {
|
|
15357
16004
|
diagramH -= layoutLegendShift;
|
|
15358
16005
|
}
|
|
@@ -15384,11 +16031,13 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
15384
16031
|
}
|
|
15385
16032
|
}
|
|
15386
16033
|
}
|
|
15387
|
-
const
|
|
16034
|
+
const contentYShift = (fixedTitle ? 0 : titleOffset) + ancestorTrailHeight;
|
|
16035
|
+
const contentG = mainG.append("g").attr("transform", `translate(0, ${contentYShift})`);
|
|
15388
16036
|
const displayNames = /* @__PURE__ */ new Map();
|
|
15389
16037
|
for (const group of parsed.tagGroups) {
|
|
15390
16038
|
displayNames.set(group.name.toLowerCase(), group.name);
|
|
15391
16039
|
}
|
|
16040
|
+
const rootNodeIds = new Set(parsed.roots.map((r) => r.id));
|
|
15392
16041
|
const colorOff = parsed.options?.color === "off";
|
|
15393
16042
|
for (const c of layout.containers) {
|
|
15394
16043
|
const cG = contentG.append("g").attr("transform", `translate(${c.x}, ${c.y})`).attr("class", "org-container").attr("data-line-number", String(c.lineNumber));
|
|
@@ -15435,6 +16084,18 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
15435
16084
|
cG.append("clipPath").attr("id", clipId).append("rect").attr("width", c.width).attr("height", c.height).attr("rx", CONTAINER_RADIUS);
|
|
15436
16085
|
cG.append("rect").attr("x", COLLAPSE_BAR_INSET).attr("y", c.height - COLLAPSE_BAR_HEIGHT).attr("width", c.width - COLLAPSE_BAR_INSET * 2).attr("height", COLLAPSE_BAR_HEIGHT).attr("fill", containerStroke(palette, colorOff ? void 0 : c.color)).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
|
|
15437
16086
|
}
|
|
16087
|
+
if (!exportDims && c.hasChildren && !rootNodeIds.has(c.nodeId)) {
|
|
16088
|
+
const iconSize = 14;
|
|
16089
|
+
const iconPad = 5;
|
|
16090
|
+
const iconX = c.width - iconSize - iconPad;
|
|
16091
|
+
const iconY = iconPad;
|
|
16092
|
+
const focusG = cG.append("g").attr("class", "org-focus-icon").attr("data-focus-node", c.nodeId).attr("transform", `translate(${iconX}, ${iconY})`);
|
|
16093
|
+
focusG.append("rect").attr("x", -3).attr("y", -3).attr("width", iconSize + 6).attr("height", iconSize + 6).attr("fill", "transparent");
|
|
16094
|
+
const cx = iconSize / 2;
|
|
16095
|
+
const cy = iconSize / 2;
|
|
16096
|
+
focusG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", iconSize / 2 - 1).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1.5);
|
|
16097
|
+
focusG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", 2).attr("fill", palette.textMuted);
|
|
16098
|
+
}
|
|
15438
16099
|
}
|
|
15439
16100
|
for (const edge of layout.edges) {
|
|
15440
16101
|
if (edge.points.length < 2) continue;
|
|
@@ -15493,6 +16154,58 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
15493
16154
|
nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS);
|
|
15494
16155
|
nodeG.append("rect").attr("x", COLLAPSE_BAR_INSET).attr("y", node.height - COLLAPSE_BAR_HEIGHT).attr("width", node.width - COLLAPSE_BAR_INSET * 2).attr("height", COLLAPSE_BAR_HEIGHT).attr("fill", nodeStroke(palette, colorOff ? void 0 : node.color)).attr("clip-path", `url(#${clipId})`).attr("class", "org-collapse-bar");
|
|
15495
16156
|
}
|
|
16157
|
+
if (!exportDims && node.hasChildren && !rootNodeIds.has(node.id)) {
|
|
16158
|
+
const iconSize = 14;
|
|
16159
|
+
const iconPad = 5;
|
|
16160
|
+
const iconX = node.width - iconSize - iconPad;
|
|
16161
|
+
const iconY = iconPad;
|
|
16162
|
+
const focusG = nodeG.append("g").attr("class", "org-focus-icon").attr("data-focus-node", node.id).attr("transform", `translate(${iconX}, ${iconY})`);
|
|
16163
|
+
focusG.append("rect").attr("x", -3).attr("y", -3).attr("width", iconSize + 6).attr("height", iconSize + 6).attr("fill", "transparent");
|
|
16164
|
+
const cx = iconSize / 2;
|
|
16165
|
+
const cy = iconSize / 2;
|
|
16166
|
+
focusG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", iconSize / 2 - 1).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1.5);
|
|
16167
|
+
focusG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", 2).attr("fill", palette.textMuted);
|
|
16168
|
+
}
|
|
16169
|
+
}
|
|
16170
|
+
if (hasAncestorTrail) {
|
|
16171
|
+
const rootNode = layout.nodes.find((n) => rootNodeIds.has(n.id));
|
|
16172
|
+
const rootContainer = !rootNode ? layout.containers.find((c) => rootNodeIds.has(c.nodeId)) : null;
|
|
16173
|
+
const rootCenterX = rootNode ? rootNode.x : rootContainer ? rootContainer.x + rootContainer.width / 2 : null;
|
|
16174
|
+
const rootTopY = rootNode ? rootNode.y : rootContainer ? rootContainer.y : null;
|
|
16175
|
+
if (rootCenterX !== null && rootTopY !== null) {
|
|
16176
|
+
const trailBottomY = rootTopY - ANCESTOR_TRAIL_BOTTOM_GAP;
|
|
16177
|
+
const trailG = contentG.append("g").attr("class", "org-ancestor-trail");
|
|
16178
|
+
const count = ancestorPath.length;
|
|
16179
|
+
const dotPositions = [];
|
|
16180
|
+
for (let i = 0; i < count; i++) {
|
|
16181
|
+
const fromBottom = count - 1 - i;
|
|
16182
|
+
dotPositions.push(trailBottomY - fromBottom * ANCESTOR_ROW_HEIGHT);
|
|
16183
|
+
}
|
|
16184
|
+
const lineTopY = dotPositions[0];
|
|
16185
|
+
trailG.append("line").attr("x1", rootCenterX).attr("y1", lineTopY).attr("x2", rootCenterX).attr("y2", rootTopY).attr("stroke", palette.textMuted).attr("stroke-width", 1.5).attr("stroke-opacity", 0.4);
|
|
16186
|
+
for (let i = 0; i < count; i++) {
|
|
16187
|
+
const ancestor = ancestorPath[i];
|
|
16188
|
+
const dotY = dotPositions[i];
|
|
16189
|
+
const resolvedColor = ancestor.color ?? resolveTagColor(
|
|
16190
|
+
ancestor.metadata,
|
|
16191
|
+
parsed.tagGroups,
|
|
16192
|
+
activeTagGroup ?? null,
|
|
16193
|
+
ancestor.isContainer
|
|
16194
|
+
);
|
|
16195
|
+
const dotColor = resolvedColor ?? palette.textMuted;
|
|
16196
|
+
const rowG = trailG.append("g").attr("class", "org-ancestor-node").attr("data-focus-ancestor", ancestor.id).style("cursor", "pointer").attr("transform", `translate(${rootCenterX}, ${dotY})`);
|
|
16197
|
+
rowG.append("rect").attr("x", -ANCESTOR_DOT_R - 2).attr("y", -ANCESTOR_DOT_R - 2).attr("width", 120).attr("height", ANCESTOR_DOT_R * 2 + 4).attr("fill", "transparent");
|
|
16198
|
+
rowG.append("circle").attr("cx", 0).attr("cy", 0).attr("r", ANCESTOR_DOT_R).attr("fill", dotColor);
|
|
16199
|
+
rowG.append("text").attr("x", ANCESTOR_DOT_R + 6).attr("y", ANCESTOR_LABEL_FONT_SIZE * 0.35).attr("fill", palette.textMuted).attr("font-size", ANCESTOR_LABEL_FONT_SIZE).text(ancestor.label);
|
|
16200
|
+
rowG.on("mouseenter", function() {
|
|
16201
|
+
d3Selection.select(this).select("circle").attr("r", ANCESTOR_DOT_R + 1);
|
|
16202
|
+
d3Selection.select(this).select("text").attr("fill", palette.text);
|
|
16203
|
+
}).on("mouseleave", function() {
|
|
16204
|
+
d3Selection.select(this).select("circle").attr("r", ANCESTOR_DOT_R);
|
|
16205
|
+
d3Selection.select(this).select("text").attr("fill", palette.textMuted);
|
|
16206
|
+
});
|
|
16207
|
+
}
|
|
16208
|
+
}
|
|
15496
16209
|
}
|
|
15497
16210
|
if (fixedLegend || legendOnly || exportDims && hasLegend) {
|
|
15498
16211
|
const groups = layout.legend.map((g) => ({
|
|
@@ -15589,13 +16302,14 @@ function renderOrgForExport(content, theme, palette) {
|
|
|
15589
16302
|
return extractExportSvg(container, theme);
|
|
15590
16303
|
});
|
|
15591
16304
|
}
|
|
15592
|
-
var DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, LABEL_FONT_SIZE, META_FONT_SIZE, META_LINE_HEIGHT2, HEADER_HEIGHT2, SEPARATOR_GAP2, EDGE_STROKE_WIDTH, NODE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2, CONTAINER_HEADER_HEIGHT, COLLAPSE_BAR_HEIGHT, COLLAPSE_BAR_INSET, LEGEND_FIXED_GAP;
|
|
16305
|
+
var DIAGRAM_PADDING, MAX_SCALE, TITLE_HEIGHT, LABEL_FONT_SIZE, META_FONT_SIZE, META_LINE_HEIGHT2, HEADER_HEIGHT2, SEPARATOR_GAP2, EDGE_STROKE_WIDTH, NODE_STROKE_WIDTH, CARD_RADIUS, CONTAINER_RADIUS, CONTAINER_LABEL_FONT_SIZE, CONTAINER_META_FONT_SIZE, CONTAINER_META_LINE_HEIGHT2, CONTAINER_HEADER_HEIGHT, COLLAPSE_BAR_HEIGHT, COLLAPSE_BAR_INSET, ANCESTOR_DOT_R, ANCESTOR_LABEL_FONT_SIZE, ANCESTOR_ROW_HEIGHT, ANCESTOR_TRAIL_BOTTOM_GAP, LEGEND_FIXED_GAP;
|
|
15593
16306
|
var init_renderer = __esm({
|
|
15594
16307
|
"src/org/renderer.ts"() {
|
|
15595
16308
|
"use strict";
|
|
15596
16309
|
init_fonts();
|
|
15597
16310
|
init_export_container();
|
|
15598
16311
|
init_color_utils();
|
|
16312
|
+
init_tag_groups();
|
|
15599
16313
|
init_parser4();
|
|
15600
16314
|
init_layout();
|
|
15601
16315
|
init_legend_constants();
|
|
@@ -15619,6 +16333,10 @@ var init_renderer = __esm({
|
|
|
15619
16333
|
CONTAINER_HEADER_HEIGHT = 28;
|
|
15620
16334
|
COLLAPSE_BAR_HEIGHT = 6;
|
|
15621
16335
|
COLLAPSE_BAR_INSET = 0;
|
|
16336
|
+
ANCESTOR_DOT_R = 4;
|
|
16337
|
+
ANCESTOR_LABEL_FONT_SIZE = 11;
|
|
16338
|
+
ANCESTOR_ROW_HEIGHT = 22;
|
|
16339
|
+
ANCESTOR_TRAIL_BOTTOM_GAP = 16;
|
|
15622
16340
|
LEGEND_FIXED_GAP = 8;
|
|
15623
16341
|
}
|
|
15624
16342
|
});
|
|
@@ -19342,7 +20060,16 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
19342
20060
|
const clipId = `bl-clip-${group.label.replace(/[[\]\s]/g, "")}`;
|
|
19343
20061
|
groupG.append("clipPath").attr("id", clipId).append("rect").attr("x", gx).attr("y", gy).attr("width", group.width).attr("height", group.height).attr("rx", NODE_RX);
|
|
19344
20062
|
groupG.append("rect").attr("x", gx).attr("y", gy + group.height - COLLAPSE_BAR_HEIGHT3).attr("width", group.width).attr("height", COLLAPSE_BAR_HEIGHT3).attr("fill", strokeColor).attr("clip-path", `url(#${clipId})`).attr("class", "bl-collapse-bar");
|
|
19345
|
-
|
|
20063
|
+
const maxLabelLines = Math.max(
|
|
20064
|
+
2,
|
|
20065
|
+
Math.floor((group.height - 16) / (MIN_NODE_FONT_SIZE * 1.3))
|
|
20066
|
+
);
|
|
20067
|
+
const fitted = fitLabelToHeader(group.label, group.width, maxLabelLines);
|
|
20068
|
+
const lineH = fitted.fontSize * 1.3;
|
|
20069
|
+
const totalH = fitted.lines.length * lineH;
|
|
20070
|
+
for (let li = 0; li < fitted.lines.length; li++) {
|
|
20071
|
+
groupG.append("text").attr("class", "bl-group-label").attr("x", group.x).attr("y", group.y - totalH / 2 + lineH / 2 + li * lineH).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-family", FONT_FAMILY).attr("font-size", fitted.fontSize).attr("font-weight", "600").attr("fill", palette.text).text(fitted.lines[li]);
|
|
20072
|
+
}
|
|
19346
20073
|
} else {
|
|
19347
20074
|
groupG.append("rect").attr("x", gx).attr("y", gy).attr("width", group.width).attr("height", groupHeight).attr("rx", GROUP_RX).attr("ry", GROUP_RX).attr("fill", mix(palette.surface, palette.bg, 40)).attr("stroke", palette.textMuted).attr("stroke-width", 1).attr("stroke-opacity", 0.35);
|
|
19348
20075
|
groupG.append("text").attr("class", "bl-group-label").attr("x", gx + group.width / 2).attr("y", gy + 18).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).attr("font-size", GROUP_LABEL_FONT_SIZE).attr("font-weight", "600").attr("fill", palette.text).text(group.label);
|
|
@@ -30603,7 +31330,22 @@ function renderQuarterCircle(svg, parsed, quadrant, qColor, palette, isDark, wid
|
|
|
30603
31330
|
const innerR = ri * ringBandWidth;
|
|
30604
31331
|
const outerR = (ri + 1) * ringBandWidth;
|
|
30605
31332
|
const fillColor = ri % 2 === 0 ? palette.bg : mix(palette.bg, palette.border, 0.15);
|
|
31333
|
+
const ringName = parsed.rings[ri].name;
|
|
30606
31334
|
svg.append("path").attr("d", arcGen(innerR, outerR)).attr("fill", fillColor).attr("stroke", mutedColor).attr("stroke-width", 0.5);
|
|
31335
|
+
svg.append("path").attr("d", arcGen(innerR, outerR)).attr("fill", "transparent").attr("data-ring-arc", ringName).style("cursor", "pointer").on("mouseenter", () => {
|
|
31336
|
+
d3Selection14.select(rootContainer).selectAll("[data-ring-arc]").each(function() {
|
|
31337
|
+
const el = d3Selection14.select(this);
|
|
31338
|
+
const isMatch = this.getAttribute("data-ring-arc") === ringName;
|
|
31339
|
+
el.attr("fill", isMatch ? qColor : "transparent").attr(
|
|
31340
|
+
"opacity",
|
|
31341
|
+
isMatch ? 0.15 : 1
|
|
31342
|
+
);
|
|
31343
|
+
});
|
|
31344
|
+
dimExceptRing(rootContainer, ringName);
|
|
31345
|
+
}).on("mouseleave", () => {
|
|
31346
|
+
d3Selection14.select(rootContainer).selectAll("[data-ring-arc]").attr("fill", "transparent").attr("opacity", 1);
|
|
31347
|
+
clearDim(rootContainer);
|
|
31348
|
+
});
|
|
30607
31349
|
}
|
|
30608
31350
|
const ringOrder = parsed.rings.map((r) => r.name);
|
|
30609
31351
|
const angularPadding = 0.08;
|
|
@@ -30666,10 +31408,21 @@ function dimExcept(root, lineNum) {
|
|
|
30666
31408
|
el.style.opacity = el.getAttribute("data-line-number") === lineNum ? "1" : String(DIM_OPACITY);
|
|
30667
31409
|
});
|
|
30668
31410
|
}
|
|
31411
|
+
function dimExceptRing(root, ringName) {
|
|
31412
|
+
root.querySelectorAll("[data-line-number]").forEach((el) => {
|
|
31413
|
+
el.style.opacity = el.getAttribute("data-ring") === ringName ? "1" : String(DIM_OPACITY);
|
|
31414
|
+
});
|
|
31415
|
+
root.querySelectorAll("[data-ring-group]").forEach((el) => {
|
|
31416
|
+
el.style.opacity = el.getAttribute("data-ring-group") === ringName ? "1" : String(DIM_OPACITY);
|
|
31417
|
+
});
|
|
31418
|
+
}
|
|
30669
31419
|
function clearDim(root) {
|
|
30670
31420
|
root.querySelectorAll("[data-line-number]").forEach((el) => {
|
|
30671
31421
|
el.style.opacity = "1";
|
|
30672
31422
|
});
|
|
31423
|
+
root.querySelectorAll("[data-ring-group]").forEach((el) => {
|
|
31424
|
+
el.style.opacity = "1";
|
|
31425
|
+
});
|
|
30673
31426
|
}
|
|
30674
31427
|
function renderHtmlPanel(panel, parsed, quadrant, qColor, palette, isDark, rootContainer, onClickItem) {
|
|
30675
31428
|
const ringOrder = parsed.rings.map((r) => r.name);
|
|
@@ -30681,11 +31434,13 @@ function renderHtmlPanel(panel, parsed, quadrant, qColor, palette, isDark, rootC
|
|
|
30681
31434
|
const blips = quadrant.blips.filter((b) => b.ring === ringName);
|
|
30682
31435
|
if (blips.length === 0) continue;
|
|
30683
31436
|
const ringGroup = document.createElement("div");
|
|
31437
|
+
ringGroup.setAttribute("data-ring-group", ringName);
|
|
30684
31438
|
ringGroup.style.cssText = `
|
|
30685
31439
|
background: ${palette.surface};
|
|
30686
31440
|
border-radius: 8px;
|
|
30687
31441
|
padding: 10px;
|
|
30688
31442
|
margin-bottom: 12px;
|
|
31443
|
+
transition: opacity 0.15s;
|
|
30689
31444
|
`;
|
|
30690
31445
|
const header = document.createElement("div");
|
|
30691
31446
|
header.style.cssText = `
|
|
@@ -31823,7 +32578,8 @@ function layoutJourneyMap(parsed, palette, options) {
|
|
|
31823
32578
|
const annoIconIndent = ANNO_ICON_SIZE + ANNO_ICON_GAP;
|
|
31824
32579
|
const annoTextW = STEP_CARD_WIDTH - CARD_PADDING_X2 * 2 - annoIconIndent;
|
|
31825
32580
|
const descTextWidth = STEP_CARD_WIDTH - CARD_PADDING_X2 * 2;
|
|
31826
|
-
const
|
|
32581
|
+
const FONT_SIZE_META2 = 10;
|
|
32582
|
+
const charWidth = FONT_SIZE_META2 * 0.6;
|
|
31827
32583
|
const titleTextWidth = STEP_CARD_WIDTH - CARD_PADDING_X2 * 2;
|
|
31828
32584
|
const titleCharWidth = 6.5;
|
|
31829
32585
|
const TITLE_LINE_HEIGHT2 = 16;
|
|
@@ -32039,7 +32795,13 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
32039
32795
|
const containerW = exportDims?.width ?? container.clientWidth;
|
|
32040
32796
|
const containerH = exportDims?.height ?? container.clientHeight;
|
|
32041
32797
|
const useContainerFit = !exportDims && containerW > 0 && containerH > 0;
|
|
32042
|
-
const svg = d3.select(container).append("svg").attr("xmlns", "http://www.w3.org/2000/svg").attr(
|
|
32798
|
+
const svg = d3.select(container).append("svg").attr("xmlns", "http://www.w3.org/2000/svg").attr(
|
|
32799
|
+
"width",
|
|
32800
|
+
useContainerFit ? containerW : exportDims?.width ?? layout.totalWidth
|
|
32801
|
+
).attr(
|
|
32802
|
+
"height",
|
|
32803
|
+
useContainerFit ? containerH : exportDims?.height ?? layout.totalHeight
|
|
32804
|
+
).attr("viewBox", `0 0 ${layout.totalWidth} ${layout.totalHeight}`).attr("preserveAspectRatio", "xMidYMin meet").attr("font-family", FONT_FAMILY);
|
|
32043
32805
|
svg.append("rect").attr("width", layout.totalWidth).attr("height", layout.totalHeight).attr("fill", palette.bg);
|
|
32044
32806
|
const defs = svg.append("defs");
|
|
32045
32807
|
const curveGradient = defs.append("linearGradient").attr("id", "journey-curve-gradient").attr("x1", "0").attr("y1", "0").attr("x2", "0").attr("y2", "1");
|
|
@@ -32111,7 +32873,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
32111
32873
|
const legendY = PADDING2 + (parsed.title ? FONT_SIZE_TITLE + 8 : 0);
|
|
32112
32874
|
const legendG = svg.append("g").attr("class", "journey-legend").attr("transform", `translate(${legendX},${legendY})`);
|
|
32113
32875
|
const legendConfig = {
|
|
32114
|
-
groups:
|
|
32876
|
+
groups: parsed.tagGroups,
|
|
32115
32877
|
position: {
|
|
32116
32878
|
placement: "top-center",
|
|
32117
32879
|
titleRelation: "inline-with-title"
|
|
@@ -32180,7 +32942,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
32180
32942
|
const y = layout.curveAreaBottom - (score - 1) / 4 * (layout.curveAreaBottom - layout.curveAreaTop - 120) - 10;
|
|
32181
32943
|
curveG.append("line").attr("x1", PADDING2).attr("x2", layout.totalWidth - PADDING2).attr("y1", y).attr("y2", y).attr("stroke", palette.textMuted).attr("stroke-opacity", GRID_LINE_OPACITY).attr("stroke-dasharray", "4,4");
|
|
32182
32944
|
const SCORE_LABEL_R = 8;
|
|
32183
|
-
const labelG = curveG.append("g").attr("class", "journey-score-label");
|
|
32945
|
+
const labelG = curveG.append("g").attr("class", "journey-score-label").attr("data-score", String(score));
|
|
32184
32946
|
renderScoreFace(
|
|
32185
32947
|
labelG,
|
|
32186
32948
|
PADDING2 - SCORE_LABEL_R - 2,
|
|
@@ -32190,35 +32952,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
32190
32952
|
SCORE_LABEL_R
|
|
32191
32953
|
);
|
|
32192
32954
|
if (!exportDims) {
|
|
32193
|
-
const scoreStr = String(score);
|
|
32194
32955
|
labelG.style("cursor", "pointer");
|
|
32195
|
-
labelG.on("mouseenter", () => {
|
|
32196
|
-
svg.selectAll(".journey-step").each(function() {
|
|
32197
|
-
const hit = this.getAttribute("data-score") === scoreStr;
|
|
32198
|
-
d3.select(this).style("opacity", hit ? "1" : String(DIM_HOVER));
|
|
32199
|
-
});
|
|
32200
|
-
svg.selectAll(".journey-face").each(function() {
|
|
32201
|
-
const hit = this.getAttribute("data-score") === scoreStr;
|
|
32202
|
-
const sel = d3.select(this);
|
|
32203
|
-
sel.style("opacity", hit ? "1" : String(DIM_HOVER));
|
|
32204
|
-
if (hit) {
|
|
32205
|
-
const fcx = parseFloat(sel.attr("data-cx") ?? "0");
|
|
32206
|
-
const fcy = parseFloat(sel.attr("data-cy") ?? "0");
|
|
32207
|
-
sel.attr(
|
|
32208
|
-
"transform",
|
|
32209
|
-
`translate(${fcx},${fcy}) scale(1.3) translate(${-fcx},${-fcy})`
|
|
32210
|
-
);
|
|
32211
|
-
} else {
|
|
32212
|
-
sel.attr("transform", null);
|
|
32213
|
-
}
|
|
32214
|
-
});
|
|
32215
|
-
svg.selectAll(".journey-thought").style("opacity", String(DIM_HOVER));
|
|
32216
|
-
});
|
|
32217
|
-
labelG.on("mouseleave", () => {
|
|
32218
|
-
svg.selectAll(".journey-step").style("opacity", null);
|
|
32219
|
-
svg.selectAll(".journey-face").style("opacity", null).attr("transform", null);
|
|
32220
|
-
svg.selectAll(".journey-thought").style("opacity", null);
|
|
32221
|
-
});
|
|
32222
32956
|
}
|
|
32223
32957
|
}
|
|
32224
32958
|
if (layout.curvePoints.length >= 2) {
|
|
@@ -32404,6 +33138,41 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
32404
33138
|
if (!exportDims) {
|
|
32405
33139
|
const DIM_OPACITY2 = 0.35;
|
|
32406
33140
|
let lockedLine = null;
|
|
33141
|
+
let lockedScore = null;
|
|
33142
|
+
const applyScoreDimming = (activeScore) => {
|
|
33143
|
+
const scoreStr = String(activeScore);
|
|
33144
|
+
svg.selectAll(".journey-step").each(function() {
|
|
33145
|
+
const hit = this.getAttribute("data-score") === scoreStr;
|
|
33146
|
+
d3.select(this).style("opacity", hit ? "1" : String(DIM_HOVER));
|
|
33147
|
+
});
|
|
33148
|
+
svg.selectAll(".journey-face").each(function() {
|
|
33149
|
+
const hit = this.getAttribute("data-score") === scoreStr;
|
|
33150
|
+
const sel = d3.select(this);
|
|
33151
|
+
sel.style("opacity", hit ? "1" : String(DIM_HOVER));
|
|
33152
|
+
if (hit) {
|
|
33153
|
+
const fcx = parseFloat(sel.attr("data-cx") ?? "0");
|
|
33154
|
+
const fcy = parseFloat(sel.attr("data-cy") ?? "0");
|
|
33155
|
+
sel.attr(
|
|
33156
|
+
"transform",
|
|
33157
|
+
`translate(${fcx},${fcy}) scale(1.3) translate(${-fcx},${-fcy})`
|
|
33158
|
+
);
|
|
33159
|
+
} else {
|
|
33160
|
+
sel.attr("transform", null);
|
|
33161
|
+
}
|
|
33162
|
+
});
|
|
33163
|
+
svg.selectAll(".journey-thought").style("opacity", String(DIM_HOVER));
|
|
33164
|
+
svg.selectAll(".journey-score-label").each(function() {
|
|
33165
|
+
const sel = d3.select(this);
|
|
33166
|
+
const s = sel.attr("data-score");
|
|
33167
|
+
sel.style("opacity", s === scoreStr ? "1" : String(DIM_HOVER));
|
|
33168
|
+
});
|
|
33169
|
+
};
|
|
33170
|
+
const clearScoreDimming = () => {
|
|
33171
|
+
svg.selectAll(".journey-step").style("opacity", null);
|
|
33172
|
+
svg.selectAll(".journey-face").style("opacity", null).attr("transform", null);
|
|
33173
|
+
svg.selectAll(".journey-thought").style("opacity", null);
|
|
33174
|
+
svg.selectAll(".journey-score-label").style("opacity", null);
|
|
33175
|
+
};
|
|
32407
33176
|
const applyDimming = (activeLine) => {
|
|
32408
33177
|
svg.selectAll(".journey-step").each(function() {
|
|
32409
33178
|
const el = d3.select(this);
|
|
@@ -32458,7 +33227,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
32458
33227
|
const lines = wrapText4(thoughtText, THOUGHT_MAX_W, THOUGHT_FONT);
|
|
32459
33228
|
const textW = Math.min(
|
|
32460
33229
|
THOUGHT_MAX_W,
|
|
32461
|
-
Math.max(...lines.map((l) => l.length *
|
|
33230
|
+
Math.max(...lines.map((l) => l.length * THOUGHT_FONT * 0.6))
|
|
32462
33231
|
);
|
|
32463
33232
|
const bw = textW + THOUGHT_PAD_X * 2;
|
|
32464
33233
|
const bh = lines.length * THOUGHT_LINE_H + THOUGHT_PAD_Y * 2;
|
|
@@ -32479,9 +33248,11 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
32479
33248
|
};
|
|
32480
33249
|
svg.on("click", (event) => {
|
|
32481
33250
|
const target = event.target;
|
|
32482
|
-
if (!target.closest(".journey-face") && !target.closest(".journey-step") && !target.closest(".journey-phase")) {
|
|
33251
|
+
if (!target.closest(".journey-face") && !target.closest(".journey-step") && !target.closest(".journey-phase") && !target.closest(".journey-score-label")) {
|
|
32483
33252
|
lockedLine = null;
|
|
33253
|
+
lockedScore = null;
|
|
32484
33254
|
clearDimming();
|
|
33255
|
+
clearScoreDimming();
|
|
32485
33256
|
}
|
|
32486
33257
|
});
|
|
32487
33258
|
const showThoughtForLine = (ln) => {
|
|
@@ -32495,17 +33266,22 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
32495
33266
|
svg.selectAll(".journey-face").each(function() {
|
|
32496
33267
|
const el = d3.select(this);
|
|
32497
33268
|
el.on("mouseenter", () => {
|
|
32498
|
-
if (lockedLine !== null) return;
|
|
33269
|
+
if (lockedLine !== null || lockedScore !== null) return;
|
|
32499
33270
|
const ln = parseInt(el.attr("data-line-number") ?? "0", 10);
|
|
32500
33271
|
if (ln) {
|
|
32501
33272
|
applyDimming(ln);
|
|
32502
33273
|
showThoughtForLine(ln);
|
|
32503
33274
|
}
|
|
32504
33275
|
}).on("mouseleave", () => {
|
|
32505
|
-
if (lockedLine !== null) return;
|
|
33276
|
+
if (lockedLine !== null || lockedScore !== null) return;
|
|
32506
33277
|
clearDimming();
|
|
32507
33278
|
}).on("click", (event) => {
|
|
32508
33279
|
event.stopPropagation();
|
|
33280
|
+
if (lockedScore !== null) {
|
|
33281
|
+
lockedScore = null;
|
|
33282
|
+
clearScoreDimming();
|
|
33283
|
+
return;
|
|
33284
|
+
}
|
|
32509
33285
|
const ln = parseInt(el.attr("data-line-number") ?? "0", 10);
|
|
32510
33286
|
if (lockedLine === ln) {
|
|
32511
33287
|
lockedLine = null;
|
|
@@ -32521,17 +33297,22 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
32521
33297
|
svg.selectAll(".journey-step").each(function() {
|
|
32522
33298
|
const el = d3.select(this);
|
|
32523
33299
|
el.on("mouseenter", () => {
|
|
32524
|
-
if (lockedLine !== null) return;
|
|
33300
|
+
if (lockedLine !== null || lockedScore !== null) return;
|
|
32525
33301
|
const ln = parseInt(el.attr("data-line-number") ?? "0", 10);
|
|
32526
33302
|
if (ln) {
|
|
32527
33303
|
applyDimming(ln);
|
|
32528
33304
|
showThoughtForLine(ln);
|
|
32529
33305
|
}
|
|
32530
33306
|
}).on("mouseleave", () => {
|
|
32531
|
-
if (lockedLine !== null) return;
|
|
33307
|
+
if (lockedLine !== null || lockedScore !== null) return;
|
|
32532
33308
|
clearDimming();
|
|
32533
33309
|
}).on("click", (event) => {
|
|
32534
33310
|
event.stopPropagation();
|
|
33311
|
+
if (lockedScore !== null) {
|
|
33312
|
+
lockedScore = null;
|
|
33313
|
+
clearScoreDimming();
|
|
33314
|
+
return;
|
|
33315
|
+
}
|
|
32535
33316
|
const ln = parseInt(el.attr("data-line-number") ?? "0", 10);
|
|
32536
33317
|
if (lockedLine === ln) {
|
|
32537
33318
|
lockedLine = null;
|
|
@@ -32544,6 +33325,30 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
32544
33325
|
}
|
|
32545
33326
|
});
|
|
32546
33327
|
});
|
|
33328
|
+
svg.selectAll(".journey-score-label").each(function() {
|
|
33329
|
+
const el = d3.select(this);
|
|
33330
|
+
const score = parseInt(el.attr("data-score") ?? "0", 10);
|
|
33331
|
+
el.on("mouseenter", () => {
|
|
33332
|
+
if (lockedLine !== null || lockedScore !== null) return;
|
|
33333
|
+
applyScoreDimming(score);
|
|
33334
|
+
}).on("mouseleave", () => {
|
|
33335
|
+
if (lockedLine !== null || lockedScore !== null) return;
|
|
33336
|
+
clearScoreDimming();
|
|
33337
|
+
}).on("click", (event) => {
|
|
33338
|
+
event.stopPropagation();
|
|
33339
|
+
if (lockedLine !== null) {
|
|
33340
|
+
lockedLine = null;
|
|
33341
|
+
clearDimming();
|
|
33342
|
+
}
|
|
33343
|
+
if (lockedScore === score) {
|
|
33344
|
+
lockedScore = null;
|
|
33345
|
+
clearScoreDimming();
|
|
33346
|
+
} else {
|
|
33347
|
+
lockedScore = score;
|
|
33348
|
+
applyScoreDimming(score);
|
|
33349
|
+
}
|
|
33350
|
+
});
|
|
33351
|
+
});
|
|
32547
33352
|
}
|
|
32548
33353
|
}
|
|
32549
33354
|
function resolveStepColor(step, scoreColor, activeGroup, tagGroups, _palette) {
|
|
@@ -32695,8 +33500,8 @@ function renderScoreFace(parent, cx, cy, score, palette, radius) {
|
|
|
32695
33500
|
).attr("fill", "none").attr("stroke", eyeColor).attr("stroke-width", 1.2).attr("stroke-linecap", "round");
|
|
32696
33501
|
return g;
|
|
32697
33502
|
}
|
|
32698
|
-
function wrapText4(text, maxWidth,
|
|
32699
|
-
const charWidth =
|
|
33503
|
+
function wrapText4(text, maxWidth, fontSize) {
|
|
33504
|
+
const charWidth = fontSize * 0.6;
|
|
32700
33505
|
const maxChars = Math.floor(maxWidth / charWidth);
|
|
32701
33506
|
if (maxChars <= 0) return [text];
|
|
32702
33507
|
const words = text.split(/\s+/);
|
|
@@ -32715,7 +33520,7 @@ function wrapText4(text, maxWidth, _fontSize) {
|
|
|
32715
33520
|
return lines;
|
|
32716
33521
|
}
|
|
32717
33522
|
function truncateText(text, maxWidth) {
|
|
32718
|
-
const maxChars = Math.floor(maxWidth /
|
|
33523
|
+
const maxChars = Math.floor(maxWidth / 6.6);
|
|
32719
33524
|
if (text.length <= maxChars) return text;
|
|
32720
33525
|
return text.substring(0, maxChars - 1) + "\u2026";
|
|
32721
33526
|
}
|
|
@@ -32815,6 +33620,21 @@ var init_renderer13 = __esm({
|
|
|
32815
33620
|
}
|
|
32816
33621
|
});
|
|
32817
33622
|
|
|
33623
|
+
// src/cycle/types.ts
|
|
33624
|
+
function arrowHeadLength(strokeWidth) {
|
|
33625
|
+
return BASE_ARROW_SIZE + ARROW_SCALE * Math.sqrt(strokeWidth);
|
|
33626
|
+
}
|
|
33627
|
+
var DEFAULT_EDGE_WIDTH, MIN_EDGE_WIDTH, BASE_ARROW_SIZE, ARROW_SCALE;
|
|
33628
|
+
var init_types2 = __esm({
|
|
33629
|
+
"src/cycle/types.ts"() {
|
|
33630
|
+
"use strict";
|
|
33631
|
+
DEFAULT_EDGE_WIDTH = 3;
|
|
33632
|
+
MIN_EDGE_WIDTH = 2;
|
|
33633
|
+
BASE_ARROW_SIZE = 8;
|
|
33634
|
+
ARROW_SCALE = 6;
|
|
33635
|
+
}
|
|
33636
|
+
});
|
|
33637
|
+
|
|
32818
33638
|
// src/cycle/layout.ts
|
|
32819
33639
|
function computeCycleLayout(parsed, options) {
|
|
32820
33640
|
const width = options?.width ?? 800;
|
|
@@ -33149,8 +33969,11 @@ function computeEdgePaths(layoutNodes, parsed, cx, cy, radius, isClockwise) {
|
|
|
33149
33969
|
return parsed.edges.map((edge) => {
|
|
33150
33970
|
const src = layoutNodes[edge.sourceIndex];
|
|
33151
33971
|
const tgt = layoutNodes[edge.targetIndex];
|
|
33152
|
-
const strokeWidth =
|
|
33153
|
-
|
|
33972
|
+
const strokeWidth = Math.max(
|
|
33973
|
+
edge.width ?? DEFAULT_EDGE_WIDTH,
|
|
33974
|
+
MIN_EDGE_WIDTH
|
|
33975
|
+
);
|
|
33976
|
+
const arrowLen = arrowHeadLength(strokeWidth) * 0.9;
|
|
33154
33977
|
const { path, labelX, labelY, labelAngle } = buildEdgeArc(
|
|
33155
33978
|
src,
|
|
33156
33979
|
tgt,
|
|
@@ -33172,7 +33995,7 @@ function computeEdgePaths(layoutNodes, parsed, cx, cy, radius, isClockwise) {
|
|
|
33172
33995
|
});
|
|
33173
33996
|
}
|
|
33174
33997
|
function fitToCanvas(nodes, edges, parsed, cx, cy, radius, width, height, _isClockwise) {
|
|
33175
|
-
const PADDING3 =
|
|
33998
|
+
const PADDING3 = 30;
|
|
33176
33999
|
let contentMinX = Infinity, contentMaxX = -Infinity;
|
|
33177
34000
|
let contentMinY = Infinity, contentMaxY = -Infinity;
|
|
33178
34001
|
for (const n of nodes) {
|
|
@@ -33225,17 +34048,7 @@ function fitToCanvas(nodes, edges, parsed, cx, cy, radius, width, height, _isClo
|
|
|
33225
34048
|
}
|
|
33226
34049
|
function buildEdgeArc(src, tgt, cx, cy, radius, isClockwise, arrowLength = 0) {
|
|
33227
34050
|
const dir = isClockwise ? 1 : -1;
|
|
33228
|
-
const startAngle = src.
|
|
33229
|
-
src.x,
|
|
33230
|
-
src.y,
|
|
33231
|
-
src.width / 2,
|
|
33232
|
-
src.height / 2,
|
|
33233
|
-
cx,
|
|
33234
|
-
cy,
|
|
33235
|
-
radius,
|
|
33236
|
-
src.angle,
|
|
33237
|
-
dir
|
|
33238
|
-
);
|
|
34051
|
+
const startAngle = src.angle;
|
|
33239
34052
|
const nodeEndAngle = tgt.isCircle ? circleNodeExitAngle(tgt.width / 2, radius, tgt.angle, -dir) : circleRectExitAngle(
|
|
33240
34053
|
tgt.x,
|
|
33241
34054
|
tgt.y,
|
|
@@ -33265,10 +34078,11 @@ function buildEdgeArc(src, tgt, cx, cy, radius, isClockwise, arrowLength = 0) {
|
|
|
33265
34078
|
const labelY = cy + labelR * Math.sin(midAngle);
|
|
33266
34079
|
return { path, labelX, labelY, labelAngle: midAngle };
|
|
33267
34080
|
}
|
|
33268
|
-
var MIN_ARC_ANGLE, LABEL_CHAR_W, CIRCLE_LABEL_CHAR_W, DESC_CHAR_W, MIN_NODE_WIDTH3, MAX_NODE_WIDTH2, PLAIN_NODE_HEIGHT, HEADER_HEIGHT5, DESC_LINE_HEIGHT7, DESC_PAD_Y, NODE_PAD_X, MIN_CIRCLE_RADIUS, CIRCLE_PAD,
|
|
34081
|
+
var MIN_ARC_ANGLE, LABEL_CHAR_W, CIRCLE_LABEL_CHAR_W, DESC_CHAR_W, MIN_NODE_WIDTH3, MAX_NODE_WIDTH2, PLAIN_NODE_HEIGHT, HEADER_HEIGHT5, DESC_LINE_HEIGHT7, DESC_PAD_Y, NODE_PAD_X, MIN_CIRCLE_RADIUS, CIRCLE_PAD, EDGE_LABEL_CHAR_W;
|
|
33269
34082
|
var init_layout13 = __esm({
|
|
33270
34083
|
"src/cycle/layout.ts"() {
|
|
33271
34084
|
"use strict";
|
|
34085
|
+
init_types2();
|
|
33272
34086
|
MIN_ARC_ANGLE = 15 * Math.PI / 180;
|
|
33273
34087
|
LABEL_CHAR_W = 8;
|
|
33274
34088
|
CIRCLE_LABEL_CHAR_W = 10;
|
|
@@ -33282,8 +34096,6 @@ var init_layout13 = __esm({
|
|
|
33282
34096
|
NODE_PAD_X = 20;
|
|
33283
34097
|
MIN_CIRCLE_RADIUS = 35;
|
|
33284
34098
|
CIRCLE_PAD = 14;
|
|
33285
|
-
DEFAULT_EDGE_WIDTH = 3;
|
|
33286
|
-
ARROWHEAD_MARKER_W = 8;
|
|
33287
34099
|
EDGE_LABEL_CHAR_W = 7;
|
|
33288
34100
|
}
|
|
33289
34101
|
});
|
|
@@ -33367,19 +34179,25 @@ function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims
|
|
|
33367
34179
|
const g = svg.append("g").attr("transform", `translate(0, ${diagramTop})`);
|
|
33368
34180
|
const defs = svg.append("defs");
|
|
33369
34181
|
const defaultNodeColor = palette.primary;
|
|
33370
|
-
const
|
|
33371
|
-
for (
|
|
33372
|
-
const edge = parsed.edges[i];
|
|
34182
|
+
const markerKeys = /* @__PURE__ */ new Set();
|
|
34183
|
+
for (const edge of parsed.edges) {
|
|
33373
34184
|
const color = resolveEdgeColor(edge, parsed, palette, defaultNodeColor);
|
|
33374
|
-
|
|
34185
|
+
const sw = Math.max(edge.width ?? DEFAULT_EDGE_WIDTH, MIN_EDGE_WIDTH);
|
|
34186
|
+
const key = `${color}|${sw}`;
|
|
34187
|
+
if (!markerKeys.has(key)) {
|
|
34188
|
+
markerKeys.add(key);
|
|
34189
|
+
ensureArrowMarker(defs, color, sw);
|
|
34190
|
+
}
|
|
33375
34191
|
}
|
|
33376
|
-
ensureArrowMarkers2(defs, arrowColors);
|
|
33377
34192
|
for (let i = 0; i < layout.edges.length; i++) {
|
|
33378
34193
|
const le = layout.edges[i];
|
|
33379
34194
|
const edge = parsed.edges[i];
|
|
33380
34195
|
const color = resolveEdgeColor(edge, parsed, palette, defaultNodeColor);
|
|
33381
|
-
const strokeWidth =
|
|
33382
|
-
|
|
34196
|
+
const strokeWidth = Math.max(
|
|
34197
|
+
edge.width ?? DEFAULT_EDGE_WIDTH,
|
|
34198
|
+
MIN_EDGE_WIDTH
|
|
34199
|
+
);
|
|
34200
|
+
const markerId = arrowMarkerId(color, strokeWidth);
|
|
33383
34201
|
const edgeG = g.append("g").attr("class", "cycle-edge");
|
|
33384
34202
|
if (edge.lineNumber) {
|
|
33385
34203
|
edgeG.attr("data-line-number", edge.lineNumber);
|
|
@@ -33525,16 +34343,16 @@ function resolveEdgeColor(edge, parsed, palette, defaultNodeColor) {
|
|
|
33525
34343
|
}
|
|
33526
34344
|
return defaultNodeColor;
|
|
33527
34345
|
}
|
|
33528
|
-
function
|
|
33529
|
-
|
|
33530
|
-
|
|
33531
|
-
|
|
33532
|
-
|
|
33533
|
-
|
|
33534
|
-
|
|
33535
|
-
}
|
|
34346
|
+
function arrowMarkerId(color, strokeWidth) {
|
|
34347
|
+
return `cycle-arrow-${color.replace("#", "")}-w${strokeWidth}`;
|
|
34348
|
+
}
|
|
34349
|
+
function ensureArrowMarker(defs, color, strokeWidth) {
|
|
34350
|
+
const id = arrowMarkerId(color, strokeWidth);
|
|
34351
|
+
const mw = arrowHeadLength(strokeWidth) / strokeWidth;
|
|
34352
|
+
const mh = Math.max(1.5, mw * 0.5);
|
|
34353
|
+
defs.append("marker").attr("id", id).attr("viewBox", `0 0 ${mw} ${mh}`).attr("refX", mw * 0.1).attr("refY", mh / 2).attr("markerWidth", mw).attr("markerHeight", mh).attr("orient", "auto").append("polygon").attr("points", `0,0 ${mw},${mh / 2} 0,${mh}`).attr("fill", color);
|
|
33536
34354
|
}
|
|
33537
|
-
var
|
|
34355
|
+
var NODE_FONT_SIZE5, DESC_FONT_SIZE5, EDGE_LABEL_FONT_SIZE9, DESC_LINE_HEIGHT8, TITLE_AREA_HEIGHT;
|
|
33538
34356
|
var init_renderer14 = __esm({
|
|
33539
34357
|
"src/cycle/renderer.ts"() {
|
|
33540
34358
|
"use strict";
|
|
@@ -33545,10 +34363,8 @@ var init_renderer14 = __esm({
|
|
|
33545
34363
|
init_color_utils();
|
|
33546
34364
|
init_colors();
|
|
33547
34365
|
init_inline_markdown();
|
|
34366
|
+
init_types2();
|
|
33548
34367
|
init_layout13();
|
|
33549
|
-
DEFAULT_EDGE_WIDTH2 = 3;
|
|
33550
|
-
ARROWHEAD_W5 = 8;
|
|
33551
|
-
ARROWHEAD_H5 = 8;
|
|
33552
34368
|
NODE_FONT_SIZE5 = 13;
|
|
33553
34369
|
DESC_FONT_SIZE5 = 11;
|
|
33554
34370
|
EDGE_LABEL_FONT_SIZE9 = 11;
|
|
@@ -33557,6 +34373,397 @@ var init_renderer14 = __esm({
|
|
|
33557
34373
|
}
|
|
33558
34374
|
});
|
|
33559
34375
|
|
|
34376
|
+
// src/pyramid/renderer.ts
|
|
34377
|
+
var renderer_exports15 = {};
|
|
34378
|
+
__export(renderer_exports15, {
|
|
34379
|
+
renderPyramid: () => renderPyramid,
|
|
34380
|
+
renderPyramidForExport: () => renderPyramidForExport
|
|
34381
|
+
});
|
|
34382
|
+
import * as d3Selection17 from "d3-selection";
|
|
34383
|
+
function renderPyramid(container, parsed, palette, isDark, onClickItem, exportDims) {
|
|
34384
|
+
if (parsed.layers.length === 0) return;
|
|
34385
|
+
d3Selection17.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
34386
|
+
const width = exportDims?.width ?? container.clientWidth;
|
|
34387
|
+
const height = exportDims?.height ?? container.clientHeight;
|
|
34388
|
+
if (width <= 0 || height <= 0) return;
|
|
34389
|
+
const hasAnyDescription = parsed.layers.some((l) => l.description.length > 0);
|
|
34390
|
+
const titleH = parsed.title ? TITLE_AREA_HEIGHT2 : 0;
|
|
34391
|
+
const bodyTop = titleH + V_MARGIN;
|
|
34392
|
+
const bodyBottom = height - V_MARGIN;
|
|
34393
|
+
const bodyHeight = Math.max(60, bodyBottom - bodyTop);
|
|
34394
|
+
const sideMargin = width * H_MARGIN_FRAC;
|
|
34395
|
+
const usableWidth = width - sideMargin * 2;
|
|
34396
|
+
const N = parsed.layers.length;
|
|
34397
|
+
const singleProbe = computeLayout2({
|
|
34398
|
+
width,
|
|
34399
|
+
usableWidth,
|
|
34400
|
+
sideMargin,
|
|
34401
|
+
bodyTop,
|
|
34402
|
+
bodyHeight,
|
|
34403
|
+
layers: parsed.layers,
|
|
34404
|
+
hasDescription: hasAnyDescription,
|
|
34405
|
+
alternate: false
|
|
34406
|
+
});
|
|
34407
|
+
const anyOverflow = singleProbe.wraps.some((w) => w.overflows);
|
|
34408
|
+
const useAlternate = anyOverflow && hasAnyDescription && N >= 2;
|
|
34409
|
+
const layout = useAlternate ? computeLayout2({
|
|
34410
|
+
width,
|
|
34411
|
+
usableWidth,
|
|
34412
|
+
sideMargin,
|
|
34413
|
+
bodyTop,
|
|
34414
|
+
bodyHeight,
|
|
34415
|
+
layers: parsed.layers,
|
|
34416
|
+
hasDescription: true,
|
|
34417
|
+
alternate: true
|
|
34418
|
+
}) : singleProbe;
|
|
34419
|
+
const svg = d3Selection17.select(container).append("svg").attr("width", width).attr("height", height).attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY);
|
|
34420
|
+
svg.append("style").text(
|
|
34421
|
+
".pyramid-desc-full{display:none}.dgmo-pyramid-layer-highlight.pyramid-desc-short{display:none}.dgmo-pyramid-layer-highlight.pyramid-desc-full{display:inline}.dgmo-pyramid-hidden{display:none}"
|
|
34422
|
+
);
|
|
34423
|
+
svg.append("rect").attr("width", width).attr("height", height).attr("fill", palette.bg);
|
|
34424
|
+
if (parsed.title) {
|
|
34425
|
+
const titleText = svg.append("text").attr("class", "chart-title").attr("x", width / 2).attr("y", TITLE_Y).attr("text-anchor", "middle").attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).attr("data-line-number", parsed.titleLineNumber).text(parsed.title).style("cursor", onClickItem ? "pointer" : "default");
|
|
34426
|
+
if (onClickItem) {
|
|
34427
|
+
titleText.on("click", () => onClickItem(parsed.titleLineNumber));
|
|
34428
|
+
}
|
|
34429
|
+
}
|
|
34430
|
+
const seriesColors2 = getSeriesColors(palette);
|
|
34431
|
+
const layerBase = isDark ? palette.surface : palette.bg;
|
|
34432
|
+
const resolveSolid = (layer, i) => {
|
|
34433
|
+
if (layer.color) {
|
|
34434
|
+
const named = resolveColor(layer.color, palette);
|
|
34435
|
+
if (named) return named;
|
|
34436
|
+
}
|
|
34437
|
+
return seriesColors2[i % seriesColors2.length];
|
|
34438
|
+
};
|
|
34439
|
+
const diagramG = svg.append("g").attr("class", "pyramid-body");
|
|
34440
|
+
for (let i = 0; i < N; i++) {
|
|
34441
|
+
const layer = parsed.layers[i];
|
|
34442
|
+
const topEdgeY = layout.pyramidTop + i * layout.layerH;
|
|
34443
|
+
const botEdgeY = topEdgeY + layout.layerH;
|
|
34444
|
+
const topHalf = halfWidthAt(i, N, layout.baseWidth, parsed.inverted);
|
|
34445
|
+
const botHalf = halfWidthAt(i + 1, N, layout.baseWidth, parsed.inverted);
|
|
34446
|
+
const polyPoints = [
|
|
34447
|
+
[layout.pyramidCx - topHalf, topEdgeY],
|
|
34448
|
+
[layout.pyramidCx + topHalf, topEdgeY],
|
|
34449
|
+
[layout.pyramidCx + botHalf, botEdgeY],
|
|
34450
|
+
[layout.pyramidCx - botHalf, botEdgeY]
|
|
34451
|
+
].map((p) => `${p[0]},${p[1]}`).join(" ");
|
|
34452
|
+
const solidColor = resolveSolid(layer, i);
|
|
34453
|
+
const fillColor = mix(solidColor, layerBase, 30);
|
|
34454
|
+
const layerG = diagramG.append("g").attr("class", "pyramid-layer").attr("data-line-number", layer.lineNumber);
|
|
34455
|
+
if (onClickItem) {
|
|
34456
|
+
const ln = layer.lineNumber;
|
|
34457
|
+
layerG.style("cursor", "pointer").on("click", () => onClickItem(ln));
|
|
34458
|
+
}
|
|
34459
|
+
layerG.append("polygon").attr("points", polyPoints).attr("fill", fillColor).attr("stroke", solidColor).attr("stroke-width", 2);
|
|
34460
|
+
const midY = (topEdgeY + botEdgeY) / 2;
|
|
34461
|
+
const labelFitsInside = Math.min(topHalf, botHalf) * 2 > layout.labelFont * 4;
|
|
34462
|
+
const textColor = labelFitsInside ? contrastText(fillColor, "#eceff4", "#2e3440") : palette.text;
|
|
34463
|
+
const labelText = layerG.append("text").attr("x", layout.pyramidCx).attr("y", midY).attr("dy", "0.35em").attr("text-anchor", "middle").attr("fill", textColor).attr("font-family", FONT_FAMILY).attr("font-size", layout.labelFont).attr("font-weight", 600);
|
|
34464
|
+
renderInlineText(labelText, layer.label, palette);
|
|
34465
|
+
if (layer.description.length > 0) {
|
|
34466
|
+
const side = useAlternate ? i % 2 === 0 ? "right" : "left" : "right";
|
|
34467
|
+
const wrap = layout.wraps[i];
|
|
34468
|
+
renderLayerDescriptions(
|
|
34469
|
+
diagramG,
|
|
34470
|
+
layer,
|
|
34471
|
+
side,
|
|
34472
|
+
wrap,
|
|
34473
|
+
layout,
|
|
34474
|
+
midY,
|
|
34475
|
+
solidColor,
|
|
34476
|
+
palette,
|
|
34477
|
+
titleH + V_MARGIN,
|
|
34478
|
+
height - V_MARGIN,
|
|
34479
|
+
onClickItem
|
|
34480
|
+
);
|
|
34481
|
+
}
|
|
34482
|
+
}
|
|
34483
|
+
}
|
|
34484
|
+
function renderPyramidForExport(container, parsed, palette, isDark, exportDims) {
|
|
34485
|
+
renderPyramid(container, parsed, palette, isDark, void 0, exportDims);
|
|
34486
|
+
}
|
|
34487
|
+
function computeLayout2(input) {
|
|
34488
|
+
const {
|
|
34489
|
+
width,
|
|
34490
|
+
usableWidth,
|
|
34491
|
+
sideMargin,
|
|
34492
|
+
bodyTop,
|
|
34493
|
+
bodyHeight,
|
|
34494
|
+
layers,
|
|
34495
|
+
hasDescription,
|
|
34496
|
+
alternate
|
|
34497
|
+
} = input;
|
|
34498
|
+
const N = layers.length;
|
|
34499
|
+
const pyramidShareFrac = hasDescription ? alternate ? PYRAMID_SHARE_ALTERNATE : PYRAMID_SHARE_WITH_DESC : BASE_WIDTH_FRAC_NO_DESC;
|
|
34500
|
+
const pyramidBandWidth = usableWidth * pyramidShareFrac;
|
|
34501
|
+
const maxBaseByHeight = bodyHeight / PITCH_RATIO;
|
|
34502
|
+
const baseWidth = Math.min(pyramidBandWidth, maxBaseByHeight);
|
|
34503
|
+
const pyramidH = baseWidth * PITCH_RATIO;
|
|
34504
|
+
let pyramidCx;
|
|
34505
|
+
if (!hasDescription) {
|
|
34506
|
+
pyramidCx = width / 2;
|
|
34507
|
+
} else if (alternate) {
|
|
34508
|
+
pyramidCx = width / 2;
|
|
34509
|
+
} else {
|
|
34510
|
+
pyramidCx = sideMargin + pyramidBandWidth / 2;
|
|
34511
|
+
}
|
|
34512
|
+
const pyramidTop = bodyTop + (bodyHeight - pyramidH) / 2;
|
|
34513
|
+
const layerH = pyramidH / N;
|
|
34514
|
+
const labelFont = clamp(
|
|
34515
|
+
Math.round(layerH * 0.38),
|
|
34516
|
+
LABEL_FONT_MIN,
|
|
34517
|
+
LABEL_FONT_MAX
|
|
34518
|
+
);
|
|
34519
|
+
const descFont = clamp(
|
|
34520
|
+
Math.round(layerH * 0.22),
|
|
34521
|
+
DESC_FONT_MIN,
|
|
34522
|
+
DESC_FONT_MAX
|
|
34523
|
+
);
|
|
34524
|
+
const descLineHeight = Math.round(descFont * 1.35);
|
|
34525
|
+
const pyramidRightEdge = pyramidCx + baseWidth / 2;
|
|
34526
|
+
const pyramidLeftEdge = pyramidCx - baseWidth / 2;
|
|
34527
|
+
const rightAccentX = pyramidRightEdge + DESC_GAP;
|
|
34528
|
+
const rightTextX = rightAccentX + DESC_ACCENT_WIDTH + DESC_ACCENT_GAP;
|
|
34529
|
+
const rightTextWidth = Math.max(80, width - sideMargin - rightTextX);
|
|
34530
|
+
const leftAccentX = pyramidLeftEdge - DESC_GAP - DESC_ACCENT_WIDTH;
|
|
34531
|
+
const leftTextWidth = Math.max(
|
|
34532
|
+
80,
|
|
34533
|
+
leftAccentX - DESC_ACCENT_GAP - sideMargin
|
|
34534
|
+
);
|
|
34535
|
+
const leftTextX = sideMargin;
|
|
34536
|
+
const wraps = layers.map((layer, i) => {
|
|
34537
|
+
if (layer.description.length === 0) {
|
|
34538
|
+
return { allLines: [], overflows: false, shortLineCount: 0 };
|
|
34539
|
+
}
|
|
34540
|
+
const side = alternate ? i % 2 === 0 ? "right" : "left" : "right";
|
|
34541
|
+
const colWidth = side === "right" ? rightTextWidth : leftTextWidth;
|
|
34542
|
+
const wrapped = [];
|
|
34543
|
+
for (const line11 of layer.description) {
|
|
34544
|
+
wrapped.push(...wrapText5(line11, colWidth, descFont));
|
|
34545
|
+
}
|
|
34546
|
+
const bandCap = Math.max(1, Math.floor(layerH / descLineHeight) - 0);
|
|
34547
|
+
const overflows = wrapped.length > bandCap;
|
|
34548
|
+
const shortLineCount = overflows ? bandCap : wrapped.length;
|
|
34549
|
+
return { allLines: wrapped, overflows, shortLineCount };
|
|
34550
|
+
});
|
|
34551
|
+
return {
|
|
34552
|
+
alternate,
|
|
34553
|
+
baseWidth,
|
|
34554
|
+
pyramidCx,
|
|
34555
|
+
pyramidTop,
|
|
34556
|
+
pyramidH,
|
|
34557
|
+
layerH,
|
|
34558
|
+
labelFont,
|
|
34559
|
+
descFont,
|
|
34560
|
+
descLineHeight,
|
|
34561
|
+
rightTextX,
|
|
34562
|
+
rightTextWidth,
|
|
34563
|
+
leftTextX,
|
|
34564
|
+
leftTextWidth,
|
|
34565
|
+
rightAccentX,
|
|
34566
|
+
leftAccentX,
|
|
34567
|
+
wraps
|
|
34568
|
+
};
|
|
34569
|
+
}
|
|
34570
|
+
function halfWidthAt(edgeIdx, n, baseWidth, inverted) {
|
|
34571
|
+
const topNarrow = !inverted;
|
|
34572
|
+
const frac = topNarrow ? edgeIdx / n : (n - edgeIdx) / n;
|
|
34573
|
+
return frac * baseWidth / 2;
|
|
34574
|
+
}
|
|
34575
|
+
function renderLayerDescriptions(parentG, layer, side, wrap, layout, midY, accentColor, palette, topBound, bottomBound, onClickItem) {
|
|
34576
|
+
const { descFont, descLineHeight } = layout;
|
|
34577
|
+
const accentX = side === "right" ? layout.rightAccentX : layout.leftAccentX;
|
|
34578
|
+
const textX = side === "right" ? layout.rightTextX : layout.leftTextX;
|
|
34579
|
+
const textAnchor = side === "right" ? "start" : "end";
|
|
34580
|
+
const textLineX = side === "right" ? textX : layout.leftAccentX - DESC_ACCENT_GAP;
|
|
34581
|
+
const availableH = bottomBound - topBound;
|
|
34582
|
+
const fullMaxLines = Math.max(1, Math.floor(availableH / descLineHeight));
|
|
34583
|
+
const fullLines = truncateWithEllipsis(wrap.allLines, fullMaxLines);
|
|
34584
|
+
if (!wrap.overflows) {
|
|
34585
|
+
renderDescriptionVariant({
|
|
34586
|
+
parentG,
|
|
34587
|
+
layer,
|
|
34588
|
+
lines: wrap.allLines,
|
|
34589
|
+
className: "pyramid-desc",
|
|
34590
|
+
accentX,
|
|
34591
|
+
accentColor,
|
|
34592
|
+
textX: textLineX,
|
|
34593
|
+
textAnchor,
|
|
34594
|
+
midY,
|
|
34595
|
+
descFont,
|
|
34596
|
+
descLineHeight,
|
|
34597
|
+
palette,
|
|
34598
|
+
topBound,
|
|
34599
|
+
bottomBound,
|
|
34600
|
+
onClickItem,
|
|
34601
|
+
variant: "short"
|
|
34602
|
+
});
|
|
34603
|
+
return;
|
|
34604
|
+
}
|
|
34605
|
+
const shortLines = buildShortLines(wrap);
|
|
34606
|
+
renderDescriptionVariant({
|
|
34607
|
+
parentG,
|
|
34608
|
+
layer,
|
|
34609
|
+
lines: shortLines,
|
|
34610
|
+
className: "pyramid-desc pyramid-desc-short",
|
|
34611
|
+
accentX,
|
|
34612
|
+
accentColor,
|
|
34613
|
+
textX: textLineX,
|
|
34614
|
+
textAnchor,
|
|
34615
|
+
midY,
|
|
34616
|
+
descFont,
|
|
34617
|
+
descLineHeight,
|
|
34618
|
+
palette,
|
|
34619
|
+
topBound,
|
|
34620
|
+
bottomBound,
|
|
34621
|
+
onClickItem,
|
|
34622
|
+
variant: "short"
|
|
34623
|
+
});
|
|
34624
|
+
renderDescriptionVariant({
|
|
34625
|
+
parentG,
|
|
34626
|
+
layer,
|
|
34627
|
+
lines: fullLines,
|
|
34628
|
+
className: "pyramid-desc pyramid-desc-full",
|
|
34629
|
+
accentX,
|
|
34630
|
+
accentColor,
|
|
34631
|
+
textX: textLineX,
|
|
34632
|
+
textAnchor,
|
|
34633
|
+
midY,
|
|
34634
|
+
descFont,
|
|
34635
|
+
descLineHeight,
|
|
34636
|
+
palette,
|
|
34637
|
+
topBound,
|
|
34638
|
+
bottomBound,
|
|
34639
|
+
onClickItem,
|
|
34640
|
+
variant: "full"
|
|
34641
|
+
});
|
|
34642
|
+
}
|
|
34643
|
+
function truncateWithEllipsis(lines, maxLines) {
|
|
34644
|
+
if (lines.length <= maxLines) return lines.slice();
|
|
34645
|
+
const visible = lines.slice(0, maxLines);
|
|
34646
|
+
if (visible.length === 0) return visible;
|
|
34647
|
+
const last = visible[visible.length - 1];
|
|
34648
|
+
visible[visible.length - 1] = last.endsWith("\u2026") ? last : `${last} \u2026`;
|
|
34649
|
+
return visible;
|
|
34650
|
+
}
|
|
34651
|
+
function buildShortLines(wrap) {
|
|
34652
|
+
if (!wrap.overflows) return wrap.allLines.slice();
|
|
34653
|
+
const visible = wrap.allLines.slice(0, wrap.shortLineCount);
|
|
34654
|
+
if (visible.length === 0) return [];
|
|
34655
|
+
const last = visible[visible.length - 1];
|
|
34656
|
+
visible[visible.length - 1] = last.endsWith("\u2026") ? last : `${last} \u2026`;
|
|
34657
|
+
return visible;
|
|
34658
|
+
}
|
|
34659
|
+
function renderDescriptionVariant(args) {
|
|
34660
|
+
const {
|
|
34661
|
+
parentG,
|
|
34662
|
+
layer,
|
|
34663
|
+
lines,
|
|
34664
|
+
className,
|
|
34665
|
+
accentX,
|
|
34666
|
+
accentColor,
|
|
34667
|
+
textX,
|
|
34668
|
+
textAnchor,
|
|
34669
|
+
midY,
|
|
34670
|
+
descFont,
|
|
34671
|
+
descLineHeight,
|
|
34672
|
+
palette,
|
|
34673
|
+
topBound,
|
|
34674
|
+
bottomBound,
|
|
34675
|
+
onClickItem,
|
|
34676
|
+
variant
|
|
34677
|
+
} = args;
|
|
34678
|
+
if (lines.length === 0) return;
|
|
34679
|
+
const totalH = lines.length * descLineHeight;
|
|
34680
|
+
let startY = midY - totalH / 2 + descLineHeight / 2;
|
|
34681
|
+
const accentPad = Math.max(4, Math.round(descFont * 0.3));
|
|
34682
|
+
const blockTop = startY - descLineHeight / 2 - accentPad;
|
|
34683
|
+
const blockBottom = startY + (lines.length - 1) * descLineHeight + descLineHeight / 2 + accentPad;
|
|
34684
|
+
let shift = 0;
|
|
34685
|
+
if (blockTop < topBound) shift = topBound - blockTop;
|
|
34686
|
+
else if (blockBottom > bottomBound) shift = bottomBound - blockBottom;
|
|
34687
|
+
startY += shift;
|
|
34688
|
+
const accentTop = startY - descLineHeight / 2 - accentPad;
|
|
34689
|
+
const accentH = totalH + accentPad * 2;
|
|
34690
|
+
const descG = parentG.append("g").attr("class", className).attr("data-line-number", layer.lineNumber).attr("data-variant", variant);
|
|
34691
|
+
if (onClickItem) {
|
|
34692
|
+
const ln = layer.lineNumber;
|
|
34693
|
+
descG.style("cursor", "pointer").on("click", () => onClickItem(ln));
|
|
34694
|
+
}
|
|
34695
|
+
descG.append("rect").attr("x", accentX).attr("y", accentTop).attr("width", DESC_ACCENT_WIDTH).attr("height", accentH).attr("rx", DESC_ACCENT_WIDTH / 2).attr("fill", accentColor);
|
|
34696
|
+
for (let j = 0; j < lines.length; j++) {
|
|
34697
|
+
const t = descG.append("text").attr("x", textX).attr("y", startY + j * descLineHeight).attr("dy", "0.35em").attr("text-anchor", textAnchor).attr("fill", palette.text).attr("font-family", FONT_FAMILY).attr("font-size", descFont).attr("font-weight", j === 0 ? 500 : 400);
|
|
34698
|
+
renderInlineText(t, lines[j], palette);
|
|
34699
|
+
}
|
|
34700
|
+
}
|
|
34701
|
+
function wrapText5(line11, maxWidth, fontSize) {
|
|
34702
|
+
if (line11 === "") return [""];
|
|
34703
|
+
const avgCharW = fontSize * CHAR_WIDTH_RATIO4;
|
|
34704
|
+
const maxChars = Math.max(8, Math.floor(maxWidth / avgCharW));
|
|
34705
|
+
const bulletMatch = line11.match(/^(\s*(?:•|-)\s+)(.*)$/);
|
|
34706
|
+
const indent = bulletMatch ? bulletMatch[1] : "";
|
|
34707
|
+
const body = bulletMatch ? bulletMatch[2] : line11;
|
|
34708
|
+
const hangingIndent = " ".repeat(indent.length);
|
|
34709
|
+
const words = body.split(/\s+/);
|
|
34710
|
+
const out = [];
|
|
34711
|
+
let current = indent;
|
|
34712
|
+
for (const word of words) {
|
|
34713
|
+
if (word === "") continue;
|
|
34714
|
+
const tentative = current.length === indent.length ? current + word : `${current} ${word}`;
|
|
34715
|
+
if (tentative.length <= maxChars) {
|
|
34716
|
+
current = tentative;
|
|
34717
|
+
} else {
|
|
34718
|
+
if (current.length > indent.length) out.push(current);
|
|
34719
|
+
if (word.length > maxChars - hangingIndent.length) {
|
|
34720
|
+
let remaining = word;
|
|
34721
|
+
while (remaining.length > maxChars - hangingIndent.length) {
|
|
34722
|
+
const slice = remaining.slice(0, maxChars - hangingIndent.length);
|
|
34723
|
+
out.push(hangingIndent + slice);
|
|
34724
|
+
remaining = remaining.slice(maxChars - hangingIndent.length);
|
|
34725
|
+
}
|
|
34726
|
+
current = remaining.length > 0 ? hangingIndent + remaining : "";
|
|
34727
|
+
} else {
|
|
34728
|
+
current = hangingIndent + word;
|
|
34729
|
+
}
|
|
34730
|
+
}
|
|
34731
|
+
}
|
|
34732
|
+
if (current.length > (out.length === 0 ? 0 : indent.length)) {
|
|
34733
|
+
if (current.trim().length > 0) out.push(current);
|
|
34734
|
+
}
|
|
34735
|
+
return out.length > 0 ? out : [line11];
|
|
34736
|
+
}
|
|
34737
|
+
function clamp(x, lo, hi) {
|
|
34738
|
+
return Math.max(lo, Math.min(hi, x));
|
|
34739
|
+
}
|
|
34740
|
+
var TITLE_AREA_HEIGHT2, H_MARGIN_FRAC, V_MARGIN, BASE_WIDTH_FRAC_NO_DESC, PYRAMID_SHARE_WITH_DESC, PYRAMID_SHARE_ALTERNATE, PITCH_RATIO, DESC_GAP, DESC_ACCENT_WIDTH, DESC_ACCENT_GAP, CHAR_WIDTH_RATIO4, LABEL_FONT_MIN, LABEL_FONT_MAX, DESC_FONT_MIN, DESC_FONT_MAX;
|
|
34741
|
+
var init_renderer15 = __esm({
|
|
34742
|
+
"src/pyramid/renderer.ts"() {
|
|
34743
|
+
"use strict";
|
|
34744
|
+
init_fonts();
|
|
34745
|
+
init_title_constants();
|
|
34746
|
+
init_color_utils();
|
|
34747
|
+
init_colors();
|
|
34748
|
+
init_inline_markdown();
|
|
34749
|
+
TITLE_AREA_HEIGHT2 = 50;
|
|
34750
|
+
H_MARGIN_FRAC = 0.03;
|
|
34751
|
+
V_MARGIN = 16;
|
|
34752
|
+
BASE_WIDTH_FRAC_NO_DESC = 0.78;
|
|
34753
|
+
PYRAMID_SHARE_WITH_DESC = 0.58;
|
|
34754
|
+
PYRAMID_SHARE_ALTERNATE = 0.42;
|
|
34755
|
+
PITCH_RATIO = 0.85;
|
|
34756
|
+
DESC_GAP = 28;
|
|
34757
|
+
DESC_ACCENT_WIDTH = 3;
|
|
34758
|
+
DESC_ACCENT_GAP = 12;
|
|
34759
|
+
CHAR_WIDTH_RATIO4 = 0.55;
|
|
34760
|
+
LABEL_FONT_MIN = 12;
|
|
34761
|
+
LABEL_FONT_MAX = 22;
|
|
34762
|
+
DESC_FONT_MIN = 11;
|
|
34763
|
+
DESC_FONT_MAX = 15;
|
|
34764
|
+
}
|
|
34765
|
+
});
|
|
34766
|
+
|
|
33560
34767
|
// src/sequence/collapse.ts
|
|
33561
34768
|
function applyCollapseProjection(parsed, collapsedGroups) {
|
|
33562
34769
|
if (collapsedGroups.size === 0) {
|
|
@@ -33749,20 +34956,19 @@ var init_tag_resolution = __esm({
|
|
|
33749
34956
|
});
|
|
33750
34957
|
|
|
33751
34958
|
// src/sequence/renderer.ts
|
|
33752
|
-
var
|
|
33753
|
-
__export(
|
|
34959
|
+
var renderer_exports16 = {};
|
|
34960
|
+
__export(renderer_exports16, {
|
|
33754
34961
|
applyGroupOrdering: () => applyGroupOrdering,
|
|
33755
34962
|
applyPositionOverrides: () => applyPositionOverrides,
|
|
33756
34963
|
buildNoteMessageMap: () => buildNoteMessageMap,
|
|
33757
34964
|
buildRenderSequence: () => buildRenderSequence,
|
|
33758
|
-
collectNoteLineNumbers: () => collectNoteLineNumbers,
|
|
33759
34965
|
computeActivations: () => computeActivations,
|
|
33760
34966
|
groupMessagesBySection: () => groupMessagesBySection,
|
|
33761
34967
|
parseInlineMarkdown: () => parseInlineMarkdown,
|
|
33762
34968
|
renderSequenceDiagram: () => renderSequenceDiagram,
|
|
33763
34969
|
truncateBareUrl: () => truncateBareUrl
|
|
33764
34970
|
});
|
|
33765
|
-
import * as
|
|
34971
|
+
import * as d3Selection18 from "d3-selection";
|
|
33766
34972
|
function wrapTextLines(text, maxChars) {
|
|
33767
34973
|
const rawLines = text.split("\n");
|
|
33768
34974
|
const wrapped = [];
|
|
@@ -34118,7 +35324,7 @@ function applyGroupOrdering(participants, groups, messages = []) {
|
|
|
34118
35324
|
return result;
|
|
34119
35325
|
}
|
|
34120
35326
|
function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateToLine, options) {
|
|
34121
|
-
|
|
35327
|
+
d3Selection18.select(container).selectAll("*").remove();
|
|
34122
35328
|
const { title, options: parsedOptions } = parsed;
|
|
34123
35329
|
const effectiveCollapsedGroups = /* @__PURE__ */ new Set();
|
|
34124
35330
|
for (const group of parsed.groups) {
|
|
@@ -34139,9 +35345,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
34139
35345
|
const groups = collapsed ? collapsed.groups : parsed.groups;
|
|
34140
35346
|
const collapsedGroupIds = collapsed?.collapsedGroupIds ?? /* @__PURE__ */ new Map();
|
|
34141
35347
|
const collapsedSections = options?.collapsedSections;
|
|
34142
|
-
const expandedNoteLines = options?.expandedNoteLines;
|
|
34143
|
-
const collapseNotesDisabled = parsedOptions["collapse-notes"]?.toLowerCase() === "no";
|
|
34144
|
-
const isNoteExpanded = (note) => expandedNoteLines === void 0 || collapseNotesDisabled || expandedNoteLines.has(note.lineNumber);
|
|
34145
35348
|
const sourceParticipants = collapsed ? collapsed.participants : parsed.participants;
|
|
34146
35349
|
const participants = applyPositionOverrides(
|
|
34147
35350
|
applyGroupOrdering(sourceParticipants, groups, messages)
|
|
@@ -34310,7 +35513,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
34310
35513
|
const note = els[j];
|
|
34311
35514
|
const sc = isNoteAfterSelfCall(note);
|
|
34312
35515
|
const maxW = noteEffectiveMaxW(note.participantId, note.position, sc);
|
|
34313
|
-
const noteH =
|
|
35516
|
+
const noteH = computeNoteHeight(note.text, charsForWidth(maxW));
|
|
34314
35517
|
totalExtent += noteH + NOTE_OFFSET_BELOW;
|
|
34315
35518
|
j++;
|
|
34316
35519
|
}
|
|
@@ -34506,7 +35709,10 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
34506
35709
|
prevNote.position,
|
|
34507
35710
|
isNoteAfterSelfCall(prevNote)
|
|
34508
35711
|
);
|
|
34509
|
-
const prevNoteH =
|
|
35712
|
+
const prevNoteH = computeNoteHeight(
|
|
35713
|
+
prevNote.text,
|
|
35714
|
+
charsForWidth(prevMaxW)
|
|
35715
|
+
);
|
|
34510
35716
|
noteTopY = prevNoteY + prevNoteH + NOTE_OFFSET_BELOW;
|
|
34511
35717
|
} else {
|
|
34512
35718
|
noteTopY = stepY(si) + noteOffsetBelow(el);
|
|
@@ -34537,7 +35743,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
34537
35743
|
note.position,
|
|
34538
35744
|
isNoteAfterSelfCall(note)
|
|
34539
35745
|
);
|
|
34540
|
-
const noteH =
|
|
35746
|
+
const noteH = computeNoteHeight(note.text, charsForWidth(maxW));
|
|
34541
35747
|
contentBottomY = Math.max(
|
|
34542
35748
|
contentBottomY,
|
|
34543
35749
|
noteTopY + noteH + NOTE_TRAILING_GAP
|
|
@@ -34559,7 +35765,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
34559
35765
|
participants.forEach((p, i) => {
|
|
34560
35766
|
participantX.set(p.id, offsetX + i * PARTICIPANT_GAP);
|
|
34561
35767
|
});
|
|
34562
|
-
const svg =
|
|
35768
|
+
const svg = d3Selection18.select(container).append("svg").attr("width", "100%").attr("height", totalHeight).attr("viewBox", `0 0 ${svgWidth} ${totalHeight}`).attr("preserveAspectRatio", "xMidYMin meet").attr("class", "sequence-diagram").style("font-family", FONT_FAMILY);
|
|
34563
35769
|
const defs = svg.append("defs");
|
|
34564
35770
|
defs.append("marker").attr("id", "seq-arrowhead").attr("viewBox", `0 0 ${ARROWHEAD_SIZE} ${ARROWHEAD_SIZE}`).attr("refX", ARROWHEAD_SIZE).attr("refY", ARROWHEAD_SIZE / 2).attr("markerWidth", ARROWHEAD_SIZE).attr("markerHeight", ARROWHEAD_SIZE).attr("orient", "auto").append("polygon").attr(
|
|
34565
35771
|
"points",
|
|
@@ -34607,24 +35813,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
34607
35813
|
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
34608
35814
|
}
|
|
34609
35815
|
}
|
|
34610
|
-
const allNoteLineNumbers = [];
|
|
34611
|
-
const collectNoteLines = (els) => {
|
|
34612
|
-
for (const el of els) {
|
|
34613
|
-
if (isSequenceNote(el)) {
|
|
34614
|
-
allNoteLineNumbers.push(el.lineNumber);
|
|
34615
|
-
} else if (isSequenceBlock(el)) {
|
|
34616
|
-
collectNoteLines(el.children);
|
|
34617
|
-
if ("elseChildren" in el) collectNoteLines(el.elseChildren);
|
|
34618
|
-
if ("branches" in el && Array.isArray(el.branches)) {
|
|
34619
|
-
for (const branch of el.branches) {
|
|
34620
|
-
collectNoteLines(branch.children);
|
|
34621
|
-
}
|
|
34622
|
-
}
|
|
34623
|
-
}
|
|
34624
|
-
}
|
|
34625
|
-
};
|
|
34626
|
-
collectNoteLines(elements);
|
|
34627
|
-
const showNotesControl = allNoteLineNumbers.length > 0 && !collapseNotesDisabled && expandedNoteLines !== void 0;
|
|
34628
35816
|
const hasTagGroups = parsed.tagGroups.length > 0;
|
|
34629
35817
|
const collapsedGroupNames = /* @__PURE__ */ new Set();
|
|
34630
35818
|
const collapsedGroupMeta = /* @__PURE__ */ new Map();
|
|
@@ -34804,7 +35992,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
34804
35992
|
firstBranchStep = Math.min(firstBranchStep, first);
|
|
34805
35993
|
}
|
|
34806
35994
|
if (firstBranchStep < Infinity) {
|
|
34807
|
-
const dividerY = stepY(firstBranchStep) -
|
|
35995
|
+
const dividerY = stepY(firstBranchStep) - BLOCK_HEADER_SPACE;
|
|
34808
35996
|
deferredLines.push({
|
|
34809
35997
|
x1: frameX,
|
|
34810
35998
|
y1: dividerY,
|
|
@@ -34831,7 +36019,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
34831
36019
|
firstElseStep = Math.min(firstElseStep, first);
|
|
34832
36020
|
}
|
|
34833
36021
|
if (firstElseStep < Infinity) {
|
|
34834
|
-
const dividerY = stepY(firstElseStep) -
|
|
36022
|
+
const dividerY = stepY(firstElseStep) - BLOCK_HEADER_SPACE;
|
|
34835
36023
|
deferredLines.push({
|
|
34836
36024
|
x1: frameX,
|
|
34837
36025
|
y1: dividerY,
|
|
@@ -35036,7 +36224,6 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
35036
36224
|
}
|
|
35037
36225
|
});
|
|
35038
36226
|
const noteFill = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.bg, palette.surface, 15);
|
|
35039
|
-
const collapsedNoteFill = mix(palette.textMuted, palette.bg, 15);
|
|
35040
36227
|
const renderNoteElements = (els) => {
|
|
35041
36228
|
for (const el of els) {
|
|
35042
36229
|
if (isSequenceNote(el)) {
|
|
@@ -35044,83 +36231,54 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
35044
36231
|
if (px === void 0) continue;
|
|
35045
36232
|
const noteTopY = noteYMap.get(el);
|
|
35046
36233
|
if (noteTopY === void 0) continue;
|
|
35047
|
-
const expanded = isNoteExpanded(el);
|
|
35048
36234
|
const isRight = el.position === "right";
|
|
35049
|
-
|
|
35050
|
-
|
|
35051
|
-
|
|
35052
|
-
|
|
35053
|
-
|
|
35054
|
-
|
|
35055
|
-
|
|
35056
|
-
|
|
35057
|
-
|
|
35058
|
-
|
|
35059
|
-
|
|
35060
|
-
|
|
35061
|
-
|
|
35062
|
-
|
|
35063
|
-
|
|
35064
|
-
|
|
35065
|
-
|
|
35066
|
-
|
|
35067
|
-
|
|
35068
|
-
|
|
35069
|
-
|
|
35070
|
-
|
|
35071
|
-
|
|
35072
|
-
|
|
35073
|
-
|
|
35074
|
-
|
|
35075
|
-
|
|
35076
|
-
|
|
35077
|
-
|
|
35078
|
-
|
|
35079
|
-
|
|
35080
|
-
|
|
35081
|
-
|
|
35082
|
-
|
|
35083
|
-
|
|
35084
|
-
|
|
35085
|
-
|
|
35086
|
-
|
|
35087
|
-
|
|
35088
|
-
|
|
35089
|
-
|
|
35090
|
-
|
|
35091
|
-
|
|
35092
|
-
|
|
35093
|
-
|
|
35094
|
-
|
|
35095
|
-
|
|
35096
|
-
});
|
|
35097
|
-
} else {
|
|
35098
|
-
const cFold = 6;
|
|
35099
|
-
const afterSelfCallC = isNoteAfterSelfCall(el);
|
|
35100
|
-
const rightOffsetC = afterSelfCallC && isRight ? ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH + NOTE_GAP : ACTIVATION_WIDTH + NOTE_GAP;
|
|
35101
|
-
const noteX = isRight ? px + rightOffsetC : px - ACTIVATION_WIDTH - NOTE_GAP - COLLAPSED_NOTE_W;
|
|
35102
|
-
const noteG = svg.append("g").attr("class", "note note-collapsed").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber)).style("cursor", "pointer");
|
|
35103
|
-
noteG.append("path").attr(
|
|
35104
|
-
"d",
|
|
35105
|
-
[
|
|
35106
|
-
`M ${noteX} ${noteTopY}`,
|
|
35107
|
-
`L ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY}`,
|
|
35108
|
-
`L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + cFold}`,
|
|
35109
|
-
`L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + COLLAPSED_NOTE_H}`,
|
|
35110
|
-
`L ${noteX} ${noteTopY + COLLAPSED_NOTE_H}`,
|
|
35111
|
-
"Z"
|
|
35112
|
-
].join(" ")
|
|
35113
|
-
).attr("fill", collapsedNoteFill).attr("stroke", palette.border).attr("stroke-width", 0.75).attr("class", "note-box");
|
|
35114
|
-
noteG.append("path").attr(
|
|
35115
|
-
"d",
|
|
35116
|
-
[
|
|
35117
|
-
`M ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY}`,
|
|
35118
|
-
`L ${noteX + COLLAPSED_NOTE_W - cFold} ${noteTopY + cFold}`,
|
|
35119
|
-
`L ${noteX + COLLAPSED_NOTE_W} ${noteTopY + cFold}`
|
|
35120
|
-
].join(" ")
|
|
35121
|
-
).attr("fill", "none").attr("stroke", palette.border).attr("stroke-width", 0.75).attr("class", "note-fold");
|
|
35122
|
-
noteG.append("text").attr("x", noteX + COLLAPSED_NOTE_W / 2).attr("y", noteTopY + COLLAPSED_NOTE_H / 2 + 3).attr("text-anchor", "middle").attr("fill", palette.textMuted).attr("font-size", 9).attr("class", "note-text").text("\u2026");
|
|
35123
|
-
}
|
|
36235
|
+
const afterSelfCall = isNoteAfterSelfCall(el);
|
|
36236
|
+
const maxW = noteEffectiveMaxW(
|
|
36237
|
+
el.participantId,
|
|
36238
|
+
el.position,
|
|
36239
|
+
afterSelfCall
|
|
36240
|
+
);
|
|
36241
|
+
const maxChars = charsForWidth(maxW);
|
|
36242
|
+
const wrappedLines = wrapTextLines(el.text, maxChars);
|
|
36243
|
+
const noteH = wrappedLines.length * NOTE_LINE_H + NOTE_PAD_V * 2;
|
|
36244
|
+
const maxLineLen = Math.max(...wrappedLines.map((l) => l.length));
|
|
36245
|
+
const noteW = Math.min(
|
|
36246
|
+
maxW,
|
|
36247
|
+
Math.max(80, maxLineLen * NOTE_CHAR_W + NOTE_PAD_H * 2 + NOTE_FOLD)
|
|
36248
|
+
);
|
|
36249
|
+
const rightOffset = afterSelfCall && isRight ? ACTIVATION_WIDTH / 2 + SELF_CALL_WIDTH + NOTE_GAP : ACTIVATION_WIDTH + NOTE_GAP;
|
|
36250
|
+
const noteX = isRight ? px + rightOffset : px - ACTIVATION_WIDTH - NOTE_GAP - noteW;
|
|
36251
|
+
const noteG = svg.append("g").attr("class", "note").attr("data-note-toggle", "").attr("data-line-number", String(el.lineNumber)).attr("data-line-end", String(el.endLineNumber));
|
|
36252
|
+
noteG.append("path").attr(
|
|
36253
|
+
"d",
|
|
36254
|
+
[
|
|
36255
|
+
`M ${noteX} ${noteTopY}`,
|
|
36256
|
+
`L ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,
|
|
36257
|
+
`L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`,
|
|
36258
|
+
`L ${noteX + noteW} ${noteTopY + noteH}`,
|
|
36259
|
+
`L ${noteX} ${noteTopY + noteH}`,
|
|
36260
|
+
"Z"
|
|
36261
|
+
].join(" ")
|
|
36262
|
+
).attr("fill", noteFill).attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-box");
|
|
36263
|
+
noteG.append("path").attr(
|
|
36264
|
+
"d",
|
|
36265
|
+
[
|
|
36266
|
+
`M ${noteX + noteW - NOTE_FOLD} ${noteTopY}`,
|
|
36267
|
+
`L ${noteX + noteW - NOTE_FOLD} ${noteTopY + NOTE_FOLD}`,
|
|
36268
|
+
`L ${noteX + noteW} ${noteTopY + NOTE_FOLD}`
|
|
36269
|
+
].join(" ")
|
|
36270
|
+
).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 0.75).attr("class", "note-fold");
|
|
36271
|
+
wrappedLines.forEach((line11, li) => {
|
|
36272
|
+
const textY = noteTopY + NOTE_PAD_V + (li + 1) * NOTE_LINE_H - 3;
|
|
36273
|
+
const isBullet = line11.startsWith("- ");
|
|
36274
|
+
const bulletIndent = isBullet ? 10 : 0;
|
|
36275
|
+
const displayLine = isBullet ? line11.slice(2) : line11;
|
|
36276
|
+
const textEl = noteG.append("text").attr("x", noteX + NOTE_PAD_H + bulletIndent).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).attr("class", "note-text");
|
|
36277
|
+
if (isBullet) {
|
|
36278
|
+
noteG.append("text").attr("x", noteX + NOTE_PAD_H).attr("y", textY).attr("fill", palette.text).attr("font-size", NOTE_FONT_SIZE).text("\u2022");
|
|
36279
|
+
}
|
|
36280
|
+
renderInlineText(textEl, displayLine, palette, NOTE_FONT_SIZE);
|
|
36281
|
+
});
|
|
35124
36282
|
} else if (isSequenceBlock(el)) {
|
|
35125
36283
|
renderNoteElements(el.children);
|
|
35126
36284
|
if (el.elseIfBranches) {
|
|
@@ -35135,8 +36293,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
35135
36293
|
if (elements && elements.length > 0) {
|
|
35136
36294
|
renderNoteElements(elements);
|
|
35137
36295
|
}
|
|
35138
|
-
if (hasTagGroups
|
|
35139
|
-
const controlsExpanded = options?.controlsExpanded ?? false;
|
|
36296
|
+
if (hasTagGroups) {
|
|
35140
36297
|
const legendY = TOP_MARGIN + titleOffset;
|
|
35141
36298
|
const resolvedGroups = parsed.tagGroups.filter((tg) => tg.entries.length > 0).map((tg) => ({
|
|
35142
36299
|
name: tg.name,
|
|
@@ -35145,37 +36302,16 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
35145
36302
|
color: e.color
|
|
35146
36303
|
}))
|
|
35147
36304
|
}));
|
|
35148
|
-
const allExpanded = showNotesControl && (options?.expandAllNotes ?? false);
|
|
35149
|
-
const controlsGroup = showNotesControl ? {
|
|
35150
|
-
toggles: [
|
|
35151
|
-
{
|
|
35152
|
-
id: "expand-all-notes",
|
|
35153
|
-
type: "toggle",
|
|
35154
|
-
label: "Expand Notes",
|
|
35155
|
-
active: allExpanded,
|
|
35156
|
-
onToggle: () => {
|
|
35157
|
-
}
|
|
35158
|
-
}
|
|
35159
|
-
]
|
|
35160
|
-
} : void 0;
|
|
35161
36305
|
const legendConfig = {
|
|
35162
36306
|
groups: resolvedGroups,
|
|
35163
36307
|
position: { placement: "top-center", titleRelation: "below-title" },
|
|
35164
|
-
mode: "fixed"
|
|
35165
|
-
controlsGroup
|
|
36308
|
+
mode: "fixed"
|
|
35166
36309
|
};
|
|
35167
36310
|
const legendState = {
|
|
35168
36311
|
activeGroup: activeTagGroup ?? null,
|
|
35169
|
-
controlsExpanded
|
|
35170
|
-
};
|
|
35171
|
-
const legendCallbacks = {
|
|
35172
|
-
onControlsExpand: () => {
|
|
35173
|
-
options?.onToggleControlsExpand?.();
|
|
35174
|
-
},
|
|
35175
|
-
onControlsToggle: (_toggleId, active) => {
|
|
35176
|
-
options?.onExpandAllNotes?.(active);
|
|
35177
|
-
}
|
|
36312
|
+
controlsExpanded: false
|
|
35178
36313
|
};
|
|
36314
|
+
const legendCallbacks = {};
|
|
35179
36315
|
const legendG = svg.append("g").attr("class", "sequence-legend").attr("transform", `translate(0,${legendY})`);
|
|
35180
36316
|
renderLegendD3(
|
|
35181
36317
|
legendG,
|
|
@@ -35214,26 +36350,6 @@ function buildNoteMessageMap(elements) {
|
|
|
35214
36350
|
walk(elements);
|
|
35215
36351
|
return map;
|
|
35216
36352
|
}
|
|
35217
|
-
function collectNoteLineNumbers(elements) {
|
|
35218
|
-
const result = [];
|
|
35219
|
-
const walk = (els) => {
|
|
35220
|
-
for (const el of els) {
|
|
35221
|
-
if (isSequenceNote(el)) {
|
|
35222
|
-
result.push(el.lineNumber);
|
|
35223
|
-
} else if (isSequenceBlock(el)) {
|
|
35224
|
-
walk(el.children);
|
|
35225
|
-
if (el.elseIfBranches) {
|
|
35226
|
-
for (const branch of el.elseIfBranches) {
|
|
35227
|
-
walk(branch.children);
|
|
35228
|
-
}
|
|
35229
|
-
}
|
|
35230
|
-
walk(el.elseChildren);
|
|
35231
|
-
}
|
|
35232
|
-
}
|
|
35233
|
-
};
|
|
35234
|
-
walk(elements);
|
|
35235
|
-
return result;
|
|
35236
|
-
}
|
|
35237
36353
|
function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr) {
|
|
35238
36354
|
const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
|
|
35239
36355
|
if (tagAttr) {
|
|
@@ -35289,8 +36405,8 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
|
|
|
35289
36405
|
});
|
|
35290
36406
|
}
|
|
35291
36407
|
}
|
|
35292
|
-
var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE,
|
|
35293
|
-
var
|
|
36408
|
+
var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, SERVICE_BORDER_RADIUS, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W, NOTE_FOLD, NOTE_PAD_H, NOTE_PAD_V, NOTE_FONT_SIZE, NOTE_LINE_H, NOTE_GAP, NOTE_CHAR_W, NOTE_CHARS_PER_LINE, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, NOTE_LANE_MAX, LABEL_CHAR_WIDTH, LABEL_MAX_CHARS, fill, stroke, SW, W, H;
|
|
36409
|
+
var init_renderer16 = __esm({
|
|
35294
36410
|
"src/sequence/renderer.ts"() {
|
|
35295
36411
|
"use strict";
|
|
35296
36412
|
init_color_utils();
|
|
@@ -35324,8 +36440,6 @@ var init_renderer15 = __esm({
|
|
|
35324
36440
|
NOTE_CHARS_PER_LINE = Math.floor(
|
|
35325
36441
|
(NOTE_MAX_W - NOTE_PAD_H * 2 - NOTE_FOLD) / NOTE_CHAR_W
|
|
35326
36442
|
);
|
|
35327
|
-
COLLAPSED_NOTE_H = 20;
|
|
35328
|
-
COLLAPSED_NOTE_W = 40;
|
|
35329
36443
|
ACTIVATION_WIDTH = 10;
|
|
35330
36444
|
SELF_CALL_HEIGHT = 25;
|
|
35331
36445
|
SELF_CALL_WIDTH = 30;
|
|
@@ -35344,7 +36458,7 @@ var init_renderer15 = __esm({
|
|
|
35344
36458
|
|
|
35345
36459
|
// src/d3.ts
|
|
35346
36460
|
import * as d3Scale2 from "d3-scale";
|
|
35347
|
-
import * as
|
|
36461
|
+
import * as d3Selection19 from "d3-selection";
|
|
35348
36462
|
import * as d3Shape10 from "d3-shape";
|
|
35349
36463
|
import * as d3Array from "d3-array";
|
|
35350
36464
|
import cloud from "d3-cloud";
|
|
@@ -35355,15 +36469,15 @@ function renderChartTitle(svg, title, titleLineNumber, width, textColor, onClick
|
|
|
35355
36469
|
titleEl.attr("data-line-number", titleLineNumber);
|
|
35356
36470
|
if (onClickItem) {
|
|
35357
36471
|
titleEl.on("click", () => onClickItem(titleLineNumber)).on("mouseenter", function() {
|
|
35358
|
-
|
|
36472
|
+
d3Selection19.select(this).attr("opacity", 0.7);
|
|
35359
36473
|
}).on("mouseleave", function() {
|
|
35360
|
-
|
|
36474
|
+
d3Selection19.select(this).attr("opacity", 1);
|
|
35361
36475
|
});
|
|
35362
36476
|
}
|
|
35363
36477
|
}
|
|
35364
36478
|
}
|
|
35365
36479
|
function initD3Chart(container, palette, exportDims) {
|
|
35366
|
-
|
|
36480
|
+
d3Selection19.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
35367
36481
|
const width = exportDims?.width ?? container.clientWidth;
|
|
35368
36482
|
const height = exportDims?.height ?? container.clientHeight;
|
|
35369
36483
|
if (width <= 0 || height <= 0) return null;
|
|
@@ -35371,7 +36485,7 @@ function initD3Chart(container, palette, exportDims) {
|
|
|
35371
36485
|
const mutedColor = palette.border;
|
|
35372
36486
|
const bgColor = palette.bg;
|
|
35373
36487
|
const colors = getSeriesColors(palette);
|
|
35374
|
-
const svg =
|
|
36488
|
+
const svg = d3Selection19.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
35375
36489
|
return { svg, width, height, textColor, mutedColor, bgColor, colors };
|
|
35376
36490
|
}
|
|
35377
36491
|
function parseTimelineDate(s) {
|
|
@@ -36296,7 +37410,12 @@ function parseVisualization(content, palette) {
|
|
|
36296
37410
|
);
|
|
36297
37411
|
validateTagGroupNames(
|
|
36298
37412
|
result.timelineTagGroups,
|
|
36299
|
-
(line11, msg) => result.diagnostics.push(makeDgmoError(line11, msg, "warning"))
|
|
37413
|
+
(line11, msg) => result.diagnostics.push(makeDgmoError(line11, msg, "warning")),
|
|
37414
|
+
(line11, msg) => {
|
|
37415
|
+
const diag = makeDgmoError(line11, msg);
|
|
37416
|
+
result.diagnostics.push(diag);
|
|
37417
|
+
if (!result.error) result.error = formatDgmoError(diag);
|
|
37418
|
+
}
|
|
36300
37419
|
);
|
|
36301
37420
|
for (const group of result.timelineTagGroups) {
|
|
36302
37421
|
if (!group.defaultValue) continue;
|
|
@@ -36714,14 +37833,14 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
|
|
|
36714
37833
|
function handleMouseEnter(hovered) {
|
|
36715
37834
|
const connected = neighbors.get(hovered);
|
|
36716
37835
|
g.selectAll(".arc-link").each(function() {
|
|
36717
|
-
const el =
|
|
37836
|
+
const el = d3Selection19.select(this);
|
|
36718
37837
|
const src = el.attr("data-source");
|
|
36719
37838
|
const tgt = el.attr("data-target");
|
|
36720
37839
|
const isRelated = src === hovered || tgt === hovered;
|
|
36721
37840
|
el.attr("stroke-opacity", isRelated ? 0.85 : FADE_OPACITY2);
|
|
36722
37841
|
});
|
|
36723
37842
|
g.selectAll(".arc-node").each(function() {
|
|
36724
|
-
const el =
|
|
37843
|
+
const el = d3Selection19.select(this);
|
|
36725
37844
|
const name = el.attr("data-node");
|
|
36726
37845
|
const isRelated = name === hovered || connected.has(name);
|
|
36727
37846
|
el.attr("opacity", isRelated ? 1 : FADE_OPACITY2);
|
|
@@ -36746,23 +37865,23 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
|
|
|
36746
37865
|
const members = groupNodeSets.get(groupName);
|
|
36747
37866
|
if (!members) return;
|
|
36748
37867
|
g.selectAll(".arc-link").each(function() {
|
|
36749
|
-
const el =
|
|
37868
|
+
const el = d3Selection19.select(this);
|
|
36750
37869
|
const isRelated = members.has(el.attr("data-source")) || members.has(el.attr("data-target"));
|
|
36751
37870
|
el.attr("stroke-opacity", isRelated ? 0.85 : FADE_OPACITY2);
|
|
36752
37871
|
});
|
|
36753
37872
|
g.selectAll(".arc-node").each(function() {
|
|
36754
|
-
const el =
|
|
37873
|
+
const el = d3Selection19.select(this);
|
|
36755
37874
|
el.attr("opacity", members.has(el.attr("data-node")) ? 1 : FADE_OPACITY2);
|
|
36756
37875
|
});
|
|
36757
37876
|
g.selectAll(".arc-group-band").each(function() {
|
|
36758
|
-
const el =
|
|
37877
|
+
const el = d3Selection19.select(this);
|
|
36759
37878
|
el.attr(
|
|
36760
37879
|
"fill-opacity",
|
|
36761
37880
|
el.attr("data-group") === groupName ? 0.18 : 0.03
|
|
36762
37881
|
);
|
|
36763
37882
|
});
|
|
36764
37883
|
g.selectAll(".arc-group-label").each(function() {
|
|
36765
|
-
const el =
|
|
37884
|
+
const el = d3Selection19.select(this);
|
|
36766
37885
|
el.attr("fill-opacity", el.attr("data-group") === groupName ? 1 : 0.2);
|
|
36767
37886
|
});
|
|
36768
37887
|
}
|
|
@@ -37020,7 +38139,7 @@ function showEventDatesOnScale(g, scale, startDate, endDate, innerHeight, accent
|
|
|
37020
38139
|
function hideEventDatesOnScale(g) {
|
|
37021
38140
|
g.selectAll(".tl-event-date").remove();
|
|
37022
38141
|
g.selectAll(".tl-scale-tick").each(function() {
|
|
37023
|
-
const el =
|
|
38142
|
+
const el = d3Selection19.select(this);
|
|
37024
38143
|
const isDashed = el.attr("stroke-dasharray");
|
|
37025
38144
|
el.attr("opacity", isDashed ? 0.15 : 0.4);
|
|
37026
38145
|
});
|
|
@@ -37098,7 +38217,7 @@ function renderTimelineGroupLegend(g, groups, groupColorMap, textColor, palette,
|
|
|
37098
38217
|
}
|
|
37099
38218
|
}
|
|
37100
38219
|
function renderTimeline(container, parsed, palette, isDark, onClickItem, exportDims, activeTagGroup, swimlaneTagGroup, onTagStateChange, viewMode) {
|
|
37101
|
-
|
|
38220
|
+
d3Selection19.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
37102
38221
|
const {
|
|
37103
38222
|
timelineEvents,
|
|
37104
38223
|
timelineGroups,
|
|
@@ -37196,13 +38315,13 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37196
38315
|
const FADE_OPACITY2 = 0.1;
|
|
37197
38316
|
function fadeToGroup(g, groupName) {
|
|
37198
38317
|
g.selectAll(".tl-event").each(function() {
|
|
37199
|
-
const el =
|
|
38318
|
+
const el = d3Selection19.select(this);
|
|
37200
38319
|
const evGroup = el.attr("data-group");
|
|
37201
38320
|
el.attr("opacity", evGroup === groupName ? 1 : FADE_OPACITY2);
|
|
37202
38321
|
});
|
|
37203
38322
|
g.selectAll(".tl-legend-item, .tl-lane-header").each(
|
|
37204
38323
|
function() {
|
|
37205
|
-
const el =
|
|
38324
|
+
const el = d3Selection19.select(this);
|
|
37206
38325
|
const name = el.attr("data-group");
|
|
37207
38326
|
el.attr("opacity", name === groupName ? 1 : FADE_OPACITY2);
|
|
37208
38327
|
}
|
|
@@ -37214,7 +38333,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37214
38333
|
}
|
|
37215
38334
|
function fadeToEra(g, eraStart, eraEnd) {
|
|
37216
38335
|
g.selectAll(".tl-event").each(function() {
|
|
37217
|
-
const el =
|
|
38336
|
+
const el = d3Selection19.select(this);
|
|
37218
38337
|
const date = parseFloat(el.attr("data-date"));
|
|
37219
38338
|
const endDate = el.attr("data-end-date");
|
|
37220
38339
|
const evEnd = endDate ? parseFloat(endDate) : date;
|
|
@@ -37226,14 +38345,14 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37226
38345
|
FADE_OPACITY2
|
|
37227
38346
|
);
|
|
37228
38347
|
g.selectAll(".tl-era").each(function() {
|
|
37229
|
-
const el =
|
|
38348
|
+
const el = d3Selection19.select(this);
|
|
37230
38349
|
const s = parseFloat(el.attr("data-era-start"));
|
|
37231
38350
|
const e = parseFloat(el.attr("data-era-end"));
|
|
37232
38351
|
const isSelf = s === eraStart && e === eraEnd;
|
|
37233
38352
|
el.attr("opacity", isSelf ? 1 : FADE_OPACITY2);
|
|
37234
38353
|
});
|
|
37235
38354
|
g.selectAll(".tl-marker").each(function() {
|
|
37236
|
-
const el =
|
|
38355
|
+
const el = d3Selection19.select(this);
|
|
37237
38356
|
const date = parseFloat(el.attr("data-marker-date"));
|
|
37238
38357
|
const inside = date >= eraStart && date <= eraEnd;
|
|
37239
38358
|
el.attr("opacity", inside ? 1 : FADE_OPACITY2);
|
|
@@ -37248,7 +38367,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37248
38367
|
function fadeToTagValue(g, tagKey, tagValue) {
|
|
37249
38368
|
const attrName = `data-tag-${tagKey}`;
|
|
37250
38369
|
g.selectAll(".tl-event").each(function() {
|
|
37251
|
-
const el =
|
|
38370
|
+
const el = d3Selection19.select(this);
|
|
37252
38371
|
const val = el.attr(attrName);
|
|
37253
38372
|
el.attr("opacity", val === tagValue ? 1 : FADE_OPACITY2);
|
|
37254
38373
|
});
|
|
@@ -37261,7 +38380,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37261
38380
|
FADE_OPACITY2
|
|
37262
38381
|
);
|
|
37263
38382
|
g.selectAll(".tl-tag-legend-entry").each(function() {
|
|
37264
|
-
const el =
|
|
38383
|
+
const el = d3Selection19.select(this);
|
|
37265
38384
|
const entryValue = el.attr("data-legend-entry");
|
|
37266
38385
|
if (entryValue === "__group__") return;
|
|
37267
38386
|
const entryGroup = el.attr("data-tag-group");
|
|
@@ -37313,7 +38432,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37313
38432
|
const innerHeight = height - margin.top - margin.bottom;
|
|
37314
38433
|
const laneWidth = innerWidth / laneCount;
|
|
37315
38434
|
const yScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
|
|
37316
|
-
const svg =
|
|
38435
|
+
const svg = d3Selection19.select(container).append("svg").attr("viewBox", `0 0 ${width} ${height}`).attr("width", exportDims ? width : "100%").attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
37317
38436
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
37318
38437
|
renderChartTitle(
|
|
37319
38438
|
svg,
|
|
@@ -37403,7 +38522,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37403
38522
|
const gradientId = `uncertain-vg-${ev.lineNumber}`;
|
|
37404
38523
|
const strokeGradientId = `uncertain-vg-s-${ev.lineNumber}`;
|
|
37405
38524
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
37406
|
-
const defsEl =
|
|
38525
|
+
const defsEl = d3Selection19.select(defs);
|
|
37407
38526
|
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
37408
38527
|
{ offset: "0%", opacity: 1 },
|
|
37409
38528
|
{ offset: "80%", opacity: 1 },
|
|
@@ -37439,7 +38558,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37439
38558
|
const axisX = 20;
|
|
37440
38559
|
const yScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerHeight]);
|
|
37441
38560
|
const sorted = timelineEvents.slice().sort((a, b) => parseTimelineDate(a.date) - parseTimelineDate(b.date));
|
|
37442
|
-
const svg =
|
|
38561
|
+
const svg = d3Selection19.select(container).append("svg").attr("viewBox", `0 0 ${width} ${height}`).attr("width", exportDims ? width : "100%").attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
37443
38562
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
37444
38563
|
renderChartTitle(
|
|
37445
38564
|
svg,
|
|
@@ -37528,7 +38647,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37528
38647
|
const gradientId = `uncertain-v-${ev.lineNumber}`;
|
|
37529
38648
|
const strokeGradientId = `uncertain-v-s-${ev.lineNumber}`;
|
|
37530
38649
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
37531
|
-
const defsEl =
|
|
38650
|
+
const defsEl = d3Selection19.select(defs);
|
|
37532
38651
|
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
|
|
37533
38652
|
{ offset: "0%", opacity: 1 },
|
|
37534
38653
|
{ offset: "80%", opacity: 1 },
|
|
@@ -37596,7 +38715,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37596
38715
|
const totalGaps = (lanes.length - 1) * GROUP_GAP3;
|
|
37597
38716
|
const rowH = Math.min(28, (innerHeight - totalGaps) / totalEventRows);
|
|
37598
38717
|
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
37599
|
-
const svg =
|
|
38718
|
+
const svg = d3Selection19.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
37600
38719
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
37601
38720
|
renderChartTitle(
|
|
37602
38721
|
svg,
|
|
@@ -37709,7 +38828,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37709
38828
|
const gradientId = `uncertain-${ev.lineNumber}`;
|
|
37710
38829
|
const strokeGradientId = `uncertain-s-${ev.lineNumber}`;
|
|
37711
38830
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
37712
|
-
const defsEl =
|
|
38831
|
+
const defsEl = d3Selection19.select(defs);
|
|
37713
38832
|
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
37714
38833
|
{ offset: "0%", opacity: 1 },
|
|
37715
38834
|
{ offset: "80%", opacity: 1 },
|
|
@@ -37757,7 +38876,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37757
38876
|
const innerHeight = height - margin.top - margin.bottom;
|
|
37758
38877
|
const rowH = Math.min(28, innerHeight / sorted.length);
|
|
37759
38878
|
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
37760
|
-
const svg =
|
|
38879
|
+
const svg = d3Selection19.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
37761
38880
|
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);
|
|
37762
38881
|
renderChartTitle(
|
|
37763
38882
|
svg,
|
|
@@ -37866,7 +38985,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37866
38985
|
const gradientId = `uncertain-ts-${ev.lineNumber}`;
|
|
37867
38986
|
const strokeGradientId = `uncertain-ts-s-${ev.lineNumber}`;
|
|
37868
38987
|
const defs = svg.select("defs").node() || svg.append("defs").node();
|
|
37869
|
-
const defsEl =
|
|
38988
|
+
const defsEl = d3Selection19.select(defs);
|
|
37870
38989
|
defsEl.append("linearGradient").attr("id", gradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
|
|
37871
38990
|
{ offset: "0%", opacity: 1 },
|
|
37872
38991
|
{ offset: "80%", opacity: 1 },
|
|
@@ -37909,7 +39028,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37909
39028
|
const LG_ENTRY_DOT_GAP = LEGEND_ENTRY_DOT_GAP;
|
|
37910
39029
|
const LG_ENTRY_TRAIL = LEGEND_ENTRY_TRAIL;
|
|
37911
39030
|
const LG_ICON_W = 20;
|
|
37912
|
-
const mainSvg =
|
|
39031
|
+
const mainSvg = d3Selection19.select(container).select("svg");
|
|
37913
39032
|
const mainG = mainSvg.select("g");
|
|
37914
39033
|
if (!mainSvg.empty() && !mainG.empty()) {
|
|
37915
39034
|
let drawSwimlaneIcon4 = function(parent, x, y, isSwimActive) {
|
|
@@ -37982,7 +39101,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
37982
39101
|
const tagVal = entryValue.toLowerCase();
|
|
37983
39102
|
fadeToTagValue(mainG, tagKey, tagVal);
|
|
37984
39103
|
mainSvg.selectAll("[data-legend-entry]").each(function() {
|
|
37985
|
-
const el =
|
|
39104
|
+
const el = d3Selection19.select(this);
|
|
37986
39105
|
const ev = el.attr("data-legend-entry");
|
|
37987
39106
|
const eg = el.attr("data-tag-group") ?? el.node()?.closest?.("[data-tag-group]")?.getAttribute("data-tag-group");
|
|
37988
39107
|
el.attr(
|
|
@@ -38035,7 +39154,7 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
38035
39154
|
}, recolorEvents2 = function() {
|
|
38036
39155
|
const colorTG = currentActiveGroup ?? swimlaneTagGroup ?? null;
|
|
38037
39156
|
mainG.selectAll(".tl-event").each(function() {
|
|
38038
|
-
const el =
|
|
39157
|
+
const el = d3Selection19.select(this);
|
|
38039
39158
|
const lineNum = el.attr("data-line-number");
|
|
38040
39159
|
const ev = lineNum ? eventByLine.get(lineNum) : void 0;
|
|
38041
39160
|
if (!ev) return;
|
|
@@ -38133,7 +39252,7 @@ function renderWordCloud(container, parsed, palette, _isDark, onClickItem, expor
|
|
|
38133
39252
|
}
|
|
38134
39253
|
function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
|
|
38135
39254
|
return new Promise((resolve) => {
|
|
38136
|
-
|
|
39255
|
+
d3Selection19.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
38137
39256
|
const { words, title, cloudOptions } = parsed;
|
|
38138
39257
|
if (words.length === 0) {
|
|
38139
39258
|
resolve();
|
|
@@ -38160,7 +39279,7 @@ function renderWordCloudAsync(container, parsed, palette, _isDark, exportDims) {
|
|
|
38160
39279
|
return minSize + Math.sqrt(t) * (maxSize - minSize);
|
|
38161
39280
|
};
|
|
38162
39281
|
const rotateFn = getRotateFn(cloudOptions.rotate);
|
|
38163
|
-
const svg =
|
|
39282
|
+
const svg = d3Selection19.select(container).append("svg").attr("width", width).attr("height", height).style("background", bgColor);
|
|
38164
39283
|
renderChartTitle(svg, title, parsed.titleLineNumber, width, textColor);
|
|
38165
39284
|
const g = svg.append("g").attr(
|
|
38166
39285
|
"transform",
|
|
@@ -38662,8 +39781,8 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
38662
39781
|
const LABEL_MAX_FONT = 48;
|
|
38663
39782
|
const LABEL_MIN_FONT = 14;
|
|
38664
39783
|
const LABEL_PAD3 = 40;
|
|
38665
|
-
const
|
|
38666
|
-
const estTextWidth = (text, fontSize) => text.length * fontSize *
|
|
39784
|
+
const CHAR_WIDTH_RATIO5 = 0.6;
|
|
39785
|
+
const estTextWidth = (text, fontSize) => text.length * fontSize * CHAR_WIDTH_RATIO5;
|
|
38667
39786
|
const quadrantLabelLayout = (text, qw2, qh2) => {
|
|
38668
39787
|
const availW = qw2 - LABEL_PAD3;
|
|
38669
39788
|
const availH = qh2 - LABEL_PAD3;
|
|
@@ -38726,7 +39845,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
38726
39845
|
(d) => onClickItem && d.label?.lineNumber ? "pointer" : "default"
|
|
38727
39846
|
).each(function(d) {
|
|
38728
39847
|
const layout = labelLayouts.get(d.label.text);
|
|
38729
|
-
const el =
|
|
39848
|
+
const el = d3Selection19.select(this);
|
|
38730
39849
|
if (layout.lines.length === 1) {
|
|
38731
39850
|
el.text(layout.lines[0]);
|
|
38732
39851
|
} else {
|
|
@@ -38742,9 +39861,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
38742
39861
|
quadrantLabelTexts.on("click", (_, d) => {
|
|
38743
39862
|
if (d.label?.lineNumber) onClickItem(d.label.lineNumber);
|
|
38744
39863
|
}).on("mouseenter", function() {
|
|
38745
|
-
|
|
39864
|
+
d3Selection19.select(this).attr("opacity", 0.7);
|
|
38746
39865
|
}).on("mouseleave", function() {
|
|
38747
|
-
|
|
39866
|
+
d3Selection19.select(this).attr("opacity", 1);
|
|
38748
39867
|
});
|
|
38749
39868
|
}
|
|
38750
39869
|
if (quadrantXAxis) {
|
|
@@ -38765,9 +39884,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
38765
39884
|
if (onClickItem && quadrantXAxisLineNumber) {
|
|
38766
39885
|
[xLowLabel, xHighLabel].forEach((label) => {
|
|
38767
39886
|
label.on("click", () => onClickItem(quadrantXAxisLineNumber)).on("mouseenter", function() {
|
|
38768
|
-
|
|
39887
|
+
d3Selection19.select(this).attr("opacity", 0.7);
|
|
38769
39888
|
}).on("mouseleave", function() {
|
|
38770
|
-
|
|
39889
|
+
d3Selection19.select(this).attr("opacity", 1);
|
|
38771
39890
|
});
|
|
38772
39891
|
});
|
|
38773
39892
|
}
|
|
@@ -38792,9 +39911,9 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
38792
39911
|
if (onClickItem && quadrantYAxisLineNumber) {
|
|
38793
39912
|
[yLowLabel, yHighLabel].forEach((label) => {
|
|
38794
39913
|
label.on("click", () => onClickItem(quadrantYAxisLineNumber)).on("mouseenter", function() {
|
|
38795
|
-
|
|
39914
|
+
d3Selection19.select(this).attr("opacity", 0.7);
|
|
38796
39915
|
}).on("mouseleave", function() {
|
|
38797
|
-
|
|
39916
|
+
d3Selection19.select(this).attr("opacity", 1);
|
|
38798
39917
|
});
|
|
38799
39918
|
});
|
|
38800
39919
|
}
|
|
@@ -38811,7 +39930,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
38811
39930
|
const POINT_LABEL_FONT_SIZE = 12;
|
|
38812
39931
|
const quadrantLabelObstacles = quadrantDefsWithLabel.map((d) => {
|
|
38813
39932
|
const layout = labelLayouts.get(d.label.text);
|
|
38814
|
-
const totalW = Math.max(...layout.lines.map((l) => l.length)) * layout.fontSize *
|
|
39933
|
+
const totalW = Math.max(...layout.lines.map((l) => l.length)) * layout.fontSize * CHAR_WIDTH_RATIO5;
|
|
38815
39934
|
const totalH = layout.lines.length * layout.fontSize * 1.2;
|
|
38816
39935
|
return {
|
|
38817
39936
|
x: d.labelX - totalW / 2,
|
|
@@ -38871,7 +39990,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
38871
39990
|
pointsG.selectAll("g.point-group").each(function(_2, i) {
|
|
38872
39991
|
const pt = quadrantPoints[i];
|
|
38873
39992
|
const ptQuad = getPointQuadrant(pt.x, pt.y);
|
|
38874
|
-
|
|
39993
|
+
d3Selection19.select(this).attr("opacity", ptQuad === d.position ? 1 : 0.2);
|
|
38875
39994
|
});
|
|
38876
39995
|
}).on("mouseleave", () => {
|
|
38877
39996
|
quadrantRects.attr("opacity", 1);
|
|
@@ -39390,6 +40509,22 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
39390
40509
|
);
|
|
39391
40510
|
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
39392
40511
|
}
|
|
40512
|
+
if (detectedType === "pyramid") {
|
|
40513
|
+
const { parsePyramid: parsePyramid2 } = await Promise.resolve().then(() => (init_parser16(), parser_exports16));
|
|
40514
|
+
const { renderPyramidForExport: renderPyramidForExport2 } = await Promise.resolve().then(() => (init_renderer15(), renderer_exports15));
|
|
40515
|
+
const effectivePalette2 = await resolveExportPalette(theme, palette);
|
|
40516
|
+
const pyramidParsed = parsePyramid2(content);
|
|
40517
|
+
if (pyramidParsed.error || pyramidParsed.layers.length === 0) return "";
|
|
40518
|
+
const container2 = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
|
|
40519
|
+
renderPyramidForExport2(
|
|
40520
|
+
container2,
|
|
40521
|
+
pyramidParsed,
|
|
40522
|
+
effectivePalette2,
|
|
40523
|
+
theme === "dark",
|
|
40524
|
+
{ width: EXPORT_WIDTH, height: EXPORT_HEIGHT }
|
|
40525
|
+
);
|
|
40526
|
+
return finalizeSvgExport(container2, theme, effectivePalette2);
|
|
40527
|
+
}
|
|
39393
40528
|
const parsed = parseVisualization(content, palette);
|
|
39394
40529
|
if (parsed.error && parsed.type !== "sequence") {
|
|
39395
40530
|
const looksLikeSequence2 = /->|~>|<-/.test(content);
|
|
@@ -39413,7 +40548,7 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
39413
40548
|
};
|
|
39414
40549
|
if (parsed.type === "sequence") {
|
|
39415
40550
|
const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser(), parser_exports));
|
|
39416
|
-
const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (
|
|
40551
|
+
const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer16(), renderer_exports16));
|
|
39417
40552
|
const seqParsed = parseSequenceDgmo2(content);
|
|
39418
40553
|
if (seqParsed.error || seqParsed.participants.length === 0) return "";
|
|
39419
40554
|
renderSequenceDiagram2(
|
|
@@ -40120,8 +41255,7 @@ async function render(content, options) {
|
|
|
40120
41255
|
const theme = options?.theme ?? "light";
|
|
40121
41256
|
const paletteName = options?.palette ?? "nord";
|
|
40122
41257
|
const paletteColors = getPalette(paletteName)[theme === "dark" ? "dark" : "light"];
|
|
40123
|
-
const { diagnostics } = parseDgmo(content);
|
|
40124
|
-
const chartType = parseDgmoChartType(content);
|
|
41258
|
+
const { diagnostics, chartType } = parseDgmo(content);
|
|
40125
41259
|
const category = chartType ? getRenderCategory(chartType) : null;
|
|
40126
41260
|
const viewState = options?.viewState ?? (options?.legendState ? {
|
|
40127
41261
|
tag: options.legendState.activeGroup ?? void 0,
|
|
@@ -40145,6 +41279,83 @@ async function render(content, options) {
|
|
|
40145
41279
|
return { svg, diagnostics };
|
|
40146
41280
|
}
|
|
40147
41281
|
|
|
41282
|
+
// src/index.ts
|
|
41283
|
+
init_chart_types();
|
|
41284
|
+
|
|
41285
|
+
// src/chart-type-scoring.ts
|
|
41286
|
+
init_chart_types();
|
|
41287
|
+
var TYPOGRAPHIC_REPLACEMENTS = [
|
|
41288
|
+
[/[‘’]/g, "'"],
|
|
41289
|
+
// curly single quotes
|
|
41290
|
+
[/[“”]/g, '"'],
|
|
41291
|
+
// curly double quotes
|
|
41292
|
+
[/[–—]/g, "-"],
|
|
41293
|
+
// en/em dash
|
|
41294
|
+
[/×/g, "x"]
|
|
41295
|
+
// unicode multiplication → ASCII (for "2×2" vs "2x2")
|
|
41296
|
+
];
|
|
41297
|
+
function normalize(s) {
|
|
41298
|
+
let out = s.normalize("NFKD").toLowerCase();
|
|
41299
|
+
for (const [re, repl] of TYPOGRAPHIC_REPLACEMENTS)
|
|
41300
|
+
out = out.replace(re, repl);
|
|
41301
|
+
return out.split(/[^a-z0-9]+/).filter(Boolean);
|
|
41302
|
+
}
|
|
41303
|
+
function matchesContiguously(promptTokens, triggerTokens) {
|
|
41304
|
+
if (triggerTokens.length === 0 || triggerTokens.length > promptTokens.length)
|
|
41305
|
+
return false;
|
|
41306
|
+
outer: for (let i = 0; i <= promptTokens.length - triggerTokens.length; i++) {
|
|
41307
|
+
for (let j = 0; j < triggerTokens.length; j++) {
|
|
41308
|
+
if (promptTokens[i + j] !== triggerTokens[j]) continue outer;
|
|
41309
|
+
}
|
|
41310
|
+
return true;
|
|
41311
|
+
}
|
|
41312
|
+
return false;
|
|
41313
|
+
}
|
|
41314
|
+
function scoreChartType(prompt, type) {
|
|
41315
|
+
const promptTokens = normalize(prompt);
|
|
41316
|
+
const matched = [];
|
|
41317
|
+
let score = 0;
|
|
41318
|
+
for (const trigger of type.triggers) {
|
|
41319
|
+
const triggerTokens = normalize(trigger);
|
|
41320
|
+
if (matchesContiguously(promptTokens, triggerTokens)) {
|
|
41321
|
+
matched.push(trigger);
|
|
41322
|
+
score += triggerTokens.length;
|
|
41323
|
+
}
|
|
41324
|
+
}
|
|
41325
|
+
const descTokens = new Set(normalize(type.description));
|
|
41326
|
+
let descHits = 0;
|
|
41327
|
+
for (const t of promptTokens) if (descTokens.has(t)) descHits++;
|
|
41328
|
+
score += descHits * 0.25;
|
|
41329
|
+
return { score, matched };
|
|
41330
|
+
}
|
|
41331
|
+
var MIN_PRIMARY_SCORE = 1;
|
|
41332
|
+
var AMBIGUITY_THRESHOLD = 0.5;
|
|
41333
|
+
function confidence(top, second) {
|
|
41334
|
+
if (top < MIN_PRIMARY_SCORE) return "ambiguous";
|
|
41335
|
+
if (second === 0) return "high";
|
|
41336
|
+
if (top >= second * 2) return "high";
|
|
41337
|
+
if (top - second < AMBIGUITY_THRESHOLD) return "ambiguous";
|
|
41338
|
+
return "medium";
|
|
41339
|
+
}
|
|
41340
|
+
function suggestChartTypes(prompt) {
|
|
41341
|
+
const scored = [];
|
|
41342
|
+
for (const type of chartTypes) {
|
|
41343
|
+
const { score, matched } = scoreChartType(prompt, type);
|
|
41344
|
+
if (score > 0) scored.push({ type, score, matched });
|
|
41345
|
+
}
|
|
41346
|
+
scored.sort((a, b) => b.score - a.score);
|
|
41347
|
+
const fallback = chartTypes.filter((c) => c.fallback);
|
|
41348
|
+
const topScore = scored[0]?.score ?? 0;
|
|
41349
|
+
const secondScore = scored[1]?.score ?? 0;
|
|
41350
|
+
const fellBack = topScore < MIN_PRIMARY_SCORE;
|
|
41351
|
+
return {
|
|
41352
|
+
ranked: scored,
|
|
41353
|
+
fallback,
|
|
41354
|
+
confidence: confidence(topScore, secondScore),
|
|
41355
|
+
fellBack
|
|
41356
|
+
};
|
|
41357
|
+
}
|
|
41358
|
+
|
|
40148
41359
|
// src/index.ts
|
|
40149
41360
|
init_dgmo_router();
|
|
40150
41361
|
init_chart();
|
|
@@ -40442,6 +41653,8 @@ init_renderer14();
|
|
|
40442
41653
|
init_parser15();
|
|
40443
41654
|
init_layout12();
|
|
40444
41655
|
init_renderer13();
|
|
41656
|
+
init_parser16();
|
|
41657
|
+
init_renderer15();
|
|
40445
41658
|
|
|
40446
41659
|
// src/org/resolver.ts
|
|
40447
41660
|
init_diagnostics();
|
|
@@ -40777,7 +41990,7 @@ init_legend_constants();
|
|
|
40777
41990
|
init_legend_d3();
|
|
40778
41991
|
init_legend_layout();
|
|
40779
41992
|
init_d3();
|
|
40780
|
-
|
|
41993
|
+
init_renderer16();
|
|
40781
41994
|
init_collapse4();
|
|
40782
41995
|
init_colors();
|
|
40783
41996
|
init_palettes();
|
|
@@ -40880,6 +42093,7 @@ init_flowchart_parser();
|
|
|
40880
42093
|
init_parser8();
|
|
40881
42094
|
init_parser2();
|
|
40882
42095
|
init_parsing();
|
|
42096
|
+
init_dgmo_router();
|
|
40883
42097
|
var extractorRegistry = /* @__PURE__ */ new Map();
|
|
40884
42098
|
function registerExtractor(kind, fn) {
|
|
40885
42099
|
extractorRegistry.set(kind, fn);
|
|
@@ -41053,10 +42267,6 @@ var COMPLETION_REGISTRY = /* @__PURE__ */ new Map([
|
|
|
41053
42267
|
description: "Show activation bars",
|
|
41054
42268
|
values: ["on", "off"]
|
|
41055
42269
|
},
|
|
41056
|
-
"collapse-notes": {
|
|
41057
|
-
description: "Collapse note blocks",
|
|
41058
|
-
values: ["yes", "no"]
|
|
41059
|
-
},
|
|
41060
42270
|
"active-tag": { description: "Active tag group name" }
|
|
41061
42271
|
})
|
|
41062
42272
|
],
|
|
@@ -41195,51 +42405,16 @@ var COMPLETION_REGISTRY = /* @__PURE__ */ new Map([
|
|
|
41195
42405
|
"no-legend": { description: "Hide the score legend" },
|
|
41196
42406
|
persona: { description: "Define the journey persona" }
|
|
41197
42407
|
})
|
|
42408
|
+
],
|
|
42409
|
+
[
|
|
42410
|
+
"pyramid",
|
|
42411
|
+
withGlobals({
|
|
42412
|
+
inverted: { description: "Flip apex to the bottom (funnel orientation)" },
|
|
42413
|
+
color: { description: "Override layer color (pipe metadata)" },
|
|
42414
|
+
description: { description: "Layer description (pipe or indented body)" }
|
|
42415
|
+
})
|
|
41198
42416
|
]
|
|
41199
42417
|
]);
|
|
41200
|
-
var CHART_TYPE_DESCRIPTIONS = {
|
|
41201
|
-
// Data charts
|
|
41202
|
-
bar: "Bar chart",
|
|
41203
|
-
line: "Line chart",
|
|
41204
|
-
pie: "Pie chart",
|
|
41205
|
-
doughnut: "Doughnut chart",
|
|
41206
|
-
area: "Area chart",
|
|
41207
|
-
"polar-area": "Polar area chart",
|
|
41208
|
-
radar: "Radar chart",
|
|
41209
|
-
"bar-stacked": "Stacked bar chart",
|
|
41210
|
-
// Extended charts
|
|
41211
|
-
scatter: "Scatter plot",
|
|
41212
|
-
heatmap: "Heatmap",
|
|
41213
|
-
sankey: "Sankey flow diagram",
|
|
41214
|
-
chord: "Chord diagram",
|
|
41215
|
-
funnel: "Funnel chart",
|
|
41216
|
-
function: "Mathematical function plot",
|
|
41217
|
-
// Visualizations
|
|
41218
|
-
slope: "Slope chart",
|
|
41219
|
-
wordcloud: "Word cloud",
|
|
41220
|
-
arc: "Arc diagram",
|
|
41221
|
-
timeline: "Timeline",
|
|
41222
|
-
venn: "Venn diagram",
|
|
41223
|
-
quadrant: "Quadrant chart",
|
|
41224
|
-
// Diagrams
|
|
41225
|
-
sequence: "Sequence diagram",
|
|
41226
|
-
flowchart: "Flowchart",
|
|
41227
|
-
class: "Class diagram",
|
|
41228
|
-
er: "Entity-relationship diagram",
|
|
41229
|
-
org: "Organization chart",
|
|
41230
|
-
kanban: "Kanban board",
|
|
41231
|
-
c4: "C4 architecture diagram",
|
|
41232
|
-
state: "State diagram",
|
|
41233
|
-
sitemap: "Sitemap diagram",
|
|
41234
|
-
infra: "Infrastructure diagram",
|
|
41235
|
-
gantt: "Gantt chart",
|
|
41236
|
-
"boxes-and-lines": "Boxes and lines diagram",
|
|
41237
|
-
mindmap: "Mindmap diagram",
|
|
41238
|
-
wireframe: "UI wireframe diagram",
|
|
41239
|
-
"tech-radar": "Technology adoption radar (ThoughtWorks style)",
|
|
41240
|
-
cycle: "Cycle diagram (circular process flow)",
|
|
41241
|
-
"journey-map": "User journey map with emotion curve"
|
|
41242
|
-
};
|
|
41243
42418
|
var CHART_TYPES = [...ALL_CHART_TYPES].filter((t) => t !== "multi-line").map((name) => ({
|
|
41244
42419
|
name,
|
|
41245
42420
|
description: CHART_TYPE_DESCRIPTIONS[name] ?? name
|
|
@@ -41828,13 +43003,16 @@ function extractJourneyMapSymbols(docText) {
|
|
|
41828
43003
|
init_parsing();
|
|
41829
43004
|
export {
|
|
41830
43005
|
ALL_CHART_TYPES,
|
|
43006
|
+
AMBIGUITY_THRESHOLD,
|
|
41831
43007
|
ARROW_DIAGNOSTIC_CODES,
|
|
41832
43008
|
CHART_TYPES,
|
|
43009
|
+
CHART_TYPE_DESCRIPTIONS,
|
|
41833
43010
|
COMPLETION_REGISTRY,
|
|
41834
43011
|
ENTITY_TYPES,
|
|
41835
43012
|
INFRA_BEHAVIOR_KEYS,
|
|
41836
43013
|
LEGEND_HEIGHT,
|
|
41837
43014
|
METADATA_KEY_SET,
|
|
43015
|
+
MIN_PRIMARY_SCORE,
|
|
41838
43016
|
PIPE_METADATA,
|
|
41839
43017
|
RECOGNIZED_COLOR_NAMES,
|
|
41840
43018
|
RULE_COUNT,
|
|
@@ -41850,13 +43028,15 @@ export {
|
|
|
41850
43028
|
buildTagLaneRowList,
|
|
41851
43029
|
calculateSchedule,
|
|
41852
43030
|
catppuccinPalette,
|
|
43031
|
+
confidence as chartTypeConfidence,
|
|
43032
|
+
chartTypeParsers,
|
|
43033
|
+
chartTypes,
|
|
41853
43034
|
collapseBoxesAndLines,
|
|
41854
43035
|
collapseMindmapTree,
|
|
41855
43036
|
collapseOrgTree,
|
|
41856
43037
|
collapseSitemapTree,
|
|
41857
43038
|
collapseStateGroups,
|
|
41858
43039
|
collectDiagramRoles,
|
|
41859
|
-
collectNoteLineNumbers,
|
|
41860
43040
|
collectTasks,
|
|
41861
43041
|
colorNames,
|
|
41862
43042
|
computeActivations,
|
|
@@ -41877,8 +43057,10 @@ export {
|
|
|
41877
43057
|
encodeViewState,
|
|
41878
43058
|
extractDiagramSymbols,
|
|
41879
43059
|
extractTagDeclarations,
|
|
43060
|
+
focusOrgTree,
|
|
41880
43061
|
formatDateLabel,
|
|
41881
43062
|
formatDgmoError,
|
|
43063
|
+
getAllChartTypes,
|
|
41882
43064
|
getAvailablePalettes,
|
|
41883
43065
|
getExtendedChartLegendGroups,
|
|
41884
43066
|
getLegendReservedHeight,
|
|
@@ -41900,6 +43082,7 @@ export {
|
|
|
41900
43082
|
isSequenceBlock,
|
|
41901
43083
|
isSequenceNote,
|
|
41902
43084
|
isValidHex,
|
|
43085
|
+
knownChartTypeIds,
|
|
41903
43086
|
layoutBoxesAndLines,
|
|
41904
43087
|
layoutC4Components,
|
|
41905
43088
|
layoutC4Containers,
|
|
@@ -41922,10 +43105,12 @@ export {
|
|
|
41922
43105
|
looksLikeState,
|
|
41923
43106
|
makeDgmoError,
|
|
41924
43107
|
matchColorParens,
|
|
43108
|
+
matchesContiguously,
|
|
41925
43109
|
mix,
|
|
41926
43110
|
monokaiPalette,
|
|
41927
43111
|
nord,
|
|
41928
43112
|
nordPalette,
|
|
43113
|
+
normalize as normalizeChartTypePrompt,
|
|
41929
43114
|
oneDarkPalette,
|
|
41930
43115
|
orderArcNodes,
|
|
41931
43116
|
parseAndLayoutInfra,
|
|
@@ -41949,7 +43134,9 @@ export {
|
|
|
41949
43134
|
parseKanban,
|
|
41950
43135
|
parseMindmap,
|
|
41951
43136
|
parseOrg,
|
|
43137
|
+
parsePyramid,
|
|
41952
43138
|
parseSequenceDgmo,
|
|
43139
|
+
parseSequenceDgmo as parseSequenceDiagram,
|
|
41953
43140
|
parseSitemap,
|
|
41954
43141
|
parseState,
|
|
41955
43142
|
parseTechRadar,
|
|
@@ -41992,6 +43179,8 @@ export {
|
|
|
41992
43179
|
renderMindmapForExport,
|
|
41993
43180
|
renderOrg,
|
|
41994
43181
|
renderOrgForExport,
|
|
43182
|
+
renderPyramid,
|
|
43183
|
+
renderPyramidForExport,
|
|
41995
43184
|
renderQuadrant,
|
|
41996
43185
|
renderQuadrantFocus,
|
|
41997
43186
|
renderQuadrantFocusForExport,
|
|
@@ -42013,9 +43202,11 @@ export {
|
|
|
42013
43202
|
resolveTaskName,
|
|
42014
43203
|
rollUpContextRelationships,
|
|
42015
43204
|
rosePinePalette,
|
|
43205
|
+
scoreChartType,
|
|
42016
43206
|
seriesColors,
|
|
42017
43207
|
shade,
|
|
42018
43208
|
solarizedPalette,
|
|
43209
|
+
suggestChartTypes,
|
|
42019
43210
|
tint,
|
|
42020
43211
|
tokyoNightPalette,
|
|
42021
43212
|
truncateBareUrl,
|