@diagrammo/dgmo 0.36.0 → 0.38.0
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/.cursorrules +3 -0
- package/.github/copilot-instructions.md +3 -0
- package/.windsurfrules +3 -0
- package/SKILL.md +3 -0
- package/dist/advanced.cjs +1058 -135
- package/dist/advanced.d.cts +122 -8
- package/dist/advanced.d.ts +122 -8
- package/dist/advanced.js +1055 -133
- package/dist/auto.cjs +1047 -132
- package/dist/auto.js +96 -95
- package/dist/auto.mjs +1048 -130
- package/dist/cli.cjs +117 -116
- package/dist/editor.cjs +4 -1
- package/dist/editor.js +4 -1
- package/dist/highlight.cjs +3 -0
- package/dist/highlight.js +3 -0
- package/dist/index.cjs +1043 -131
- package/dist/index.js +1044 -129
- package/docs/ai-integration.md +3 -0
- package/docs/language-reference.md +106 -7
- package/gallery/fixtures/map-coastline.dgmo +2 -2
- package/gallery/fixtures/map-route.dgmo +5 -5
- package/gallery/fixtures/treemap-branch.dgmo +15 -0
- package/gallery/fixtures/treemap-heat.dgmo +12 -0
- package/gallery/fixtures/treemap-tag-heat.dgmo +21 -0
- package/gallery/fixtures/treemap-tags.dgmo +18 -0
- package/package.json +1 -1
- package/src/advanced.ts +11 -0
- package/src/boxes-and-lines/layout-search.ts +19 -1
- package/src/chart-type-registry.ts +4 -0
- package/src/chart-types.ts +5 -0
- package/src/completion.ts +64 -0
- package/src/d3.ts +30 -18
- package/src/editor/highlight-api.ts +2 -0
- package/src/editor/keywords.ts +3 -0
- package/src/infra/parser.ts +95 -38
- package/src/map/dimensions.ts +19 -2
- package/src/map/layout.ts +91 -7
- package/src/map/parser.ts +51 -29
- package/src/map/renderer.ts +10 -0
- package/src/map/types.ts +9 -8
- package/src/treemap/layout.ts +189 -0
- package/src/treemap/parser.ts +475 -0
- package/src/treemap/renderer.ts +698 -0
- package/src/treemap/types.ts +57 -0
- package/src/utils/parsing.ts +1 -0
- package/src/utils/reserved-key-registry.ts +5 -0
package/dist/index.js
CHANGED
|
@@ -600,7 +600,7 @@ function withTagAliases(base, aliases) {
|
|
|
600
600
|
function isReservedKey(registry, key) {
|
|
601
601
|
return registry.keys.has(key) || registry.tagAliases.has(key);
|
|
602
602
|
}
|
|
603
|
-
var SEQUENCE_REGISTRY, INFRA_REGISTRY, MAP_REGISTRY, ORG_REGISTRY, C4_REGISTRY, ER_REGISTRY, KANBAN_REGISTRY, SITEMAP_REGISTRY, GANTT_REGISTRY, PERT_REGISTRY, BOXES_AND_LINES_REGISTRY, TIMELINE_REGISTRY, MINDMAP_REGISTRY, TECH_RADAR_REGISTRY, CYCLE_REGISTRY, JOURNEY_MAP_REGISTRY, PYRAMID_REGISTRY, RING_REGISTRY, RACI_REGISTRY;
|
|
603
|
+
var SEQUENCE_REGISTRY, INFRA_REGISTRY, MAP_REGISTRY, ORG_REGISTRY, C4_REGISTRY, ER_REGISTRY, KANBAN_REGISTRY, SITEMAP_REGISTRY, GANTT_REGISTRY, PERT_REGISTRY, BOXES_AND_LINES_REGISTRY, TIMELINE_REGISTRY, MINDMAP_REGISTRY, TECH_RADAR_REGISTRY, CYCLE_REGISTRY, JOURNEY_MAP_REGISTRY, PYRAMID_REGISTRY, RING_REGISTRY, TREEMAP_REGISTRY, RACI_REGISTRY;
|
|
604
604
|
var init_reserved_key_registry = __esm({
|
|
605
605
|
"src/utils/reserved-key-registry.ts"() {
|
|
606
606
|
"use strict";
|
|
@@ -719,6 +719,7 @@ var init_reserved_key_registry = __esm({
|
|
|
719
719
|
"color",
|
|
720
720
|
"description"
|
|
721
721
|
]);
|
|
722
|
+
TREEMAP_REGISTRY = staticRegistry(["heat"]);
|
|
722
723
|
RACI_REGISTRY = staticRegistry([
|
|
723
724
|
"color",
|
|
724
725
|
"description"
|
|
@@ -1148,6 +1149,7 @@ var init_parsing = __esm({
|
|
|
1148
1149
|
"journey-map",
|
|
1149
1150
|
"pyramid",
|
|
1150
1151
|
"ring",
|
|
1152
|
+
"treemap",
|
|
1151
1153
|
"raci",
|
|
1152
1154
|
"rasci",
|
|
1153
1155
|
"daci",
|
|
@@ -11807,6 +11809,10 @@ var init_chart_types = __esm({
|
|
|
11807
11809
|
id: "ring",
|
|
11808
11810
|
description: "Concentric rings showing nested or hierarchical categories (read core-out)"
|
|
11809
11811
|
},
|
|
11812
|
+
{
|
|
11813
|
+
id: "treemap",
|
|
11814
|
+
description: "Nested rectangles sized by value \u2014 show a hierarchy\u2019s proportions (budgets, disk usage, portfolios) with color by category, value heatmap, or branch"
|
|
11815
|
+
},
|
|
11810
11816
|
{
|
|
11811
11817
|
id: "map",
|
|
11812
11818
|
description: "Geographic concept map: highlight/score regions, drop points of interest, connect with routes or edges"
|
|
@@ -16681,6 +16687,7 @@ function parseInfra(content) {
|
|
|
16681
16687
|
let currentGroup = null;
|
|
16682
16688
|
let currentTagGroup = null;
|
|
16683
16689
|
let baseIndent = 0;
|
|
16690
|
+
let firstLineConsumed = false;
|
|
16684
16691
|
function finishCurrentNode() {
|
|
16685
16692
|
if (!currentNode) return;
|
|
16686
16693
|
const key = currentNode.id;
|
|
@@ -16688,7 +16695,8 @@ function parseInfra(content) {
|
|
|
16688
16695
|
if (existing) {
|
|
16689
16696
|
const incomingDisplay = displayName(currentNode.label);
|
|
16690
16697
|
const existingDisplay = displayName(existing.label);
|
|
16691
|
-
|
|
16698
|
+
const isAliasRef = nameAliasMap.get(currentNode.label) === key;
|
|
16699
|
+
if (incomingDisplay !== existingDisplay && !isAliasRef) {
|
|
16692
16700
|
result.diagnostics.push(
|
|
16693
16701
|
makeDgmoError(
|
|
16694
16702
|
currentNode.lineNumber,
|
|
@@ -16754,19 +16762,22 @@ function parseInfra(content) {
|
|
|
16754
16762
|
if (indent === 0 && currentNode && !trimmed.startsWith("-")) {
|
|
16755
16763
|
finishCurrentNode();
|
|
16756
16764
|
}
|
|
16757
|
-
|
|
16758
|
-
|
|
16759
|
-
|
|
16760
|
-
|
|
16761
|
-
|
|
16762
|
-
|
|
16763
|
-
|
|
16764
|
-
|
|
16765
|
-
|
|
16766
|
-
|
|
16767
|
-
|
|
16765
|
+
if (!firstLineConsumed) {
|
|
16766
|
+
firstLineConsumed = true;
|
|
16767
|
+
const firstLineResult = parseFirstLine(trimmed);
|
|
16768
|
+
if (firstLineResult) {
|
|
16769
|
+
if (firstLineResult.chartType !== "infra") {
|
|
16770
|
+
setError(
|
|
16771
|
+
lineNumber,
|
|
16772
|
+
`Expected chart type 'infra', got '${firstLineResult.chartType}'`
|
|
16773
|
+
);
|
|
16774
|
+
}
|
|
16775
|
+
if (firstLineResult.title) {
|
|
16776
|
+
result.title = firstLineResult.title;
|
|
16777
|
+
result.titleLineNumber = lineNumber;
|
|
16778
|
+
}
|
|
16779
|
+
continue;
|
|
16768
16780
|
}
|
|
16769
|
-
continue;
|
|
16770
16781
|
}
|
|
16771
16782
|
if (/^direction-tb$/i.test(trimmed)) {
|
|
16772
16783
|
result.direction = "TB";
|
|
@@ -16832,18 +16843,20 @@ function parseInfra(content) {
|
|
|
16832
16843
|
if (compMatch) {
|
|
16833
16844
|
finishCurrentNode();
|
|
16834
16845
|
finishCurrentTagGroup();
|
|
16835
|
-
const
|
|
16846
|
+
const { qname, uname, alias: asAlias, meta } = compMatch.groups;
|
|
16847
|
+
const rawName = (qname ?? uname ?? "").trim();
|
|
16836
16848
|
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
16837
16849
|
const name = peeled.label;
|
|
16838
|
-
const
|
|
16850
|
+
const alias = asAlias ?? peeled.alias;
|
|
16851
|
+
const rest = meta ?? "";
|
|
16839
16852
|
const { tags } = extractPipeMetadata(rest);
|
|
16840
16853
|
warnUnknownMetaKeys(
|
|
16841
16854
|
tags,
|
|
16842
16855
|
withTagAliases(INFRA_REGISTRY, tagAliasSet),
|
|
16843
16856
|
(msg) => warn(lineNumber, msg)
|
|
16844
16857
|
);
|
|
16845
|
-
const id = nodeId2(name);
|
|
16846
|
-
if (
|
|
16858
|
+
const id = nameAliasMap.get(name) ?? nodeId2(name);
|
|
16859
|
+
if (alias) nameAliasMap.set(alias, id);
|
|
16847
16860
|
const isEdge = EDGE_NODE_NAMES.has(id.toLowerCase());
|
|
16848
16861
|
currentNode = {
|
|
16849
16862
|
id,
|
|
@@ -16927,18 +16940,20 @@ function parseInfra(content) {
|
|
|
16927
16940
|
const compMatch = trimmed.match(COMPONENT_RE);
|
|
16928
16941
|
if (compMatch) {
|
|
16929
16942
|
finishCurrentTagGroup();
|
|
16930
|
-
const
|
|
16943
|
+
const { qname, uname, alias: asAlias, meta } = compMatch.groups;
|
|
16944
|
+
const rawName = (qname ?? uname ?? "").trim();
|
|
16931
16945
|
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
16932
16946
|
const name = peeled.label;
|
|
16933
|
-
const
|
|
16947
|
+
const alias = asAlias ?? peeled.alias;
|
|
16948
|
+
const rest = meta ?? "";
|
|
16934
16949
|
const { tags: nodeTags } = extractPipeMetadata(rest);
|
|
16935
16950
|
warnUnknownMetaKeys(
|
|
16936
16951
|
nodeTags,
|
|
16937
16952
|
withTagAliases(INFRA_REGISTRY, tagAliasSet),
|
|
16938
16953
|
(msg) => warn(lineNumber, msg)
|
|
16939
16954
|
);
|
|
16940
|
-
const id = nodeId2(name);
|
|
16941
|
-
if (
|
|
16955
|
+
const id = nameAliasMap.get(name) ?? nodeId2(name);
|
|
16956
|
+
if (alias) nameAliasMap.set(alias, id);
|
|
16942
16957
|
const tags = currentGroup.metadata ? { ...currentGroup.metadata, ...nodeTags } : nodeTags;
|
|
16943
16958
|
currentNode = {
|
|
16944
16959
|
id,
|
|
@@ -17129,6 +17144,11 @@ function parseInfra(content) {
|
|
|
17129
17144
|
}
|
|
17130
17145
|
continue;
|
|
17131
17146
|
}
|
|
17147
|
+
if (currentNode && tagAliasSet.has(normalizeName(key))) {
|
|
17148
|
+
const mut = nodeMutableTags.get(currentNode.id);
|
|
17149
|
+
if (mut) mut[tagAttrKey(key)] = rawVal;
|
|
17150
|
+
continue;
|
|
17151
|
+
}
|
|
17132
17152
|
if (!INFRA_BEHAVIOR_KEYS.has(key) && !EDGE_ONLY_KEYS.has(key)) {
|
|
17133
17153
|
const allKeys = [...INFRA_BEHAVIOR_KEYS, ...EDGE_ONLY_KEYS];
|
|
17134
17154
|
const hint = suggest(key, allKeys);
|
|
@@ -17194,18 +17214,20 @@ function parseInfra(content) {
|
|
|
17194
17214
|
finishCurrentNode();
|
|
17195
17215
|
const compMatch = trimmed.match(COMPONENT_RE);
|
|
17196
17216
|
if (compMatch) {
|
|
17197
|
-
const
|
|
17217
|
+
const { qname, uname, alias: asAlias, meta } = compMatch.groups;
|
|
17218
|
+
const rawName = (qname ?? uname ?? "").trim();
|
|
17198
17219
|
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
17199
17220
|
const name = peeled.label;
|
|
17200
|
-
const
|
|
17221
|
+
const alias = asAlias ?? peeled.alias;
|
|
17222
|
+
const rest = meta ?? "";
|
|
17201
17223
|
const { tags: nodeTags } = extractPipeMetadata(rest);
|
|
17202
17224
|
warnUnknownMetaKeys(
|
|
17203
17225
|
nodeTags,
|
|
17204
17226
|
withTagAliases(INFRA_REGISTRY, tagAliasSet),
|
|
17205
17227
|
(msg) => warn(lineNumber, msg)
|
|
17206
17228
|
);
|
|
17207
|
-
const id = nodeId2(name);
|
|
17208
|
-
if (
|
|
17229
|
+
const id = nameAliasMap.get(name) ?? nodeId2(name);
|
|
17230
|
+
if (alias) nameAliasMap.set(alias, id);
|
|
17209
17231
|
const tags = currentGroup.metadata ? { ...currentGroup.metadata, ...nodeTags } : nodeTags;
|
|
17210
17232
|
currentNode = {
|
|
17211
17233
|
id,
|
|
@@ -17227,18 +17249,20 @@ function parseInfra(content) {
|
|
|
17227
17249
|
finishCurrentNode();
|
|
17228
17250
|
finishCurrentTagGroup();
|
|
17229
17251
|
currentGroup = null;
|
|
17230
|
-
const
|
|
17252
|
+
const { qname, uname, alias: asAlias, meta } = compMatch.groups;
|
|
17253
|
+
const rawName = (qname ?? uname ?? "").trim();
|
|
17231
17254
|
const peeled = peelInfraDecorations(rawName, lineNumber);
|
|
17232
17255
|
const name = peeled.label;
|
|
17233
|
-
const
|
|
17256
|
+
const alias = asAlias ?? peeled.alias;
|
|
17257
|
+
const rest = meta ?? "";
|
|
17234
17258
|
const { tags } = extractPipeMetadata(rest);
|
|
17235
17259
|
warnUnknownMetaKeys(
|
|
17236
17260
|
tags,
|
|
17237
17261
|
withTagAliases(INFRA_REGISTRY, tagAliasSet),
|
|
17238
17262
|
(msg) => warn(lineNumber, msg)
|
|
17239
17263
|
);
|
|
17240
|
-
const id = nodeId2(name);
|
|
17241
|
-
if (
|
|
17264
|
+
const id = nameAliasMap.get(name) ?? nodeId2(name);
|
|
17265
|
+
if (alias) nameAliasMap.set(alias, id);
|
|
17242
17266
|
currentNode = {
|
|
17243
17267
|
id,
|
|
17244
17268
|
label: name,
|
|
@@ -17438,7 +17462,7 @@ var init_parser15 = __esm({
|
|
|
17438
17462
|
DEPRECATED_FANOUT_RE = /\bx(\d+)\s*$/;
|
|
17439
17463
|
GROUP_RE = /^\[([^\]]+)\]\s*(?:as\s+([A-Za-z][A-Za-z0-9_]{0,11})\s*)?((?:\|.*)|(?:[a-zA-Z_]\w*\s*:.*))?$/;
|
|
17440
17464
|
TAG_VALUE_RE = /^(\w[\w\s]+?)\s*$/;
|
|
17441
|
-
COMPONENT_RE = /^(?:"([^"]+)"|([a-zA-Z_][\w -]*?))\s*((?:\|.*)|(?:[a-zA-Z_]\w*\s*:.*))?$/;
|
|
17465
|
+
COMPONENT_RE = /^(?:"(?<qname>[^"]+)"|(?<uname>[a-zA-Z_][\w -]*?))(?:\s+as\s+(?<alias>[A-Za-z][A-Za-z0-9_]{0,11}))?\s*(?<meta>(?:\|.*)|(?:[a-zA-Z_]\w*\s*:.*))?$/;
|
|
17442
17466
|
PIPE_META_RE = /[|,]\s*(\w+)\s*:\s*([^|,]+)/g;
|
|
17443
17467
|
SAMELINE_META_RE = /(?:^|[\s,])(\w+)\s*:\s*([^,]+?)(?=\s*,|\s*$)/g;
|
|
17444
17468
|
PROPERTY_RE = /^([\w-]+):\s*(.+)$/;
|
|
@@ -18922,8 +18946,8 @@ function parseMap(content, palette) {
|
|
|
18922
18946
|
continue;
|
|
18923
18947
|
}
|
|
18924
18948
|
if (open.route && indent > open.route.indent) {
|
|
18925
|
-
const leg = parseLeg(trimmed, lineNumber
|
|
18926
|
-
open.route.route.legs.push(leg);
|
|
18949
|
+
const leg = parseLeg(trimmed, lineNumber);
|
|
18950
|
+
if (leg) open.route.route.legs.push(leg);
|
|
18927
18951
|
continue;
|
|
18928
18952
|
}
|
|
18929
18953
|
if (open.poi && indent > open.poi.indent) {
|
|
@@ -18952,6 +18976,14 @@ function parseMap(content, palette) {
|
|
|
18952
18976
|
Object.assign(open.poi.poi.meta, split.meta);
|
|
18953
18977
|
continue;
|
|
18954
18978
|
}
|
|
18979
|
+
if (split.name) {
|
|
18980
|
+
const src = open.poi.poi.alias ?? poiName(open.poi.poi.pos) ?? "the poi";
|
|
18981
|
+
pushError(
|
|
18982
|
+
lineNumber,
|
|
18983
|
+
`Malformed hub edge: "${trimmed}" \u2014 an indented line under a poi is an edge from "${src}" and needs an arrow glyph (\`-> dest\`, \`~> dest\`, or labeled \`-label-> dest\`). For a standalone place, declare it at the top level. (\xA724B.5)`
|
|
18984
|
+
);
|
|
18985
|
+
continue;
|
|
18986
|
+
}
|
|
18955
18987
|
}
|
|
18956
18988
|
closeBlocks();
|
|
18957
18989
|
const firstWord = trimmed.split(/\s+/)[0];
|
|
@@ -18960,7 +18992,7 @@ function parseMap(content, palette) {
|
|
|
18960
18992
|
continue;
|
|
18961
18993
|
}
|
|
18962
18994
|
if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
|
|
18963
|
-
|
|
18995
|
+
handleDirective2(
|
|
18964
18996
|
firstWord,
|
|
18965
18997
|
trimmed.slice(firstWord.length).trim(),
|
|
18966
18998
|
lineNumber
|
|
@@ -18999,7 +19031,7 @@ function parseMap(content, palette) {
|
|
|
18999
19031
|
}
|
|
19000
19032
|
}
|
|
19001
19033
|
return result;
|
|
19002
|
-
function
|
|
19034
|
+
function handleDirective2(key, value, line11) {
|
|
19003
19035
|
const d = result.directives;
|
|
19004
19036
|
const dup = (have) => {
|
|
19005
19037
|
if (have !== void 0)
|
|
@@ -19200,31 +19232,44 @@ function parseMap(content, palette) {
|
|
|
19200
19232
|
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
19201
19233
|
const originLabel = meta["label"];
|
|
19202
19234
|
const originValue = meta["value"];
|
|
19203
|
-
|
|
19235
|
+
if (meta["style"] !== void 0) {
|
|
19236
|
+
pushError(
|
|
19237
|
+
line11,
|
|
19238
|
+
"route header no longer takes `style:` \u2014 set leg shape with the arrow glyph instead (`~\u2026~>` for an arc leg, `-\u2026->` for a straight one). (\xA724B.6)"
|
|
19239
|
+
);
|
|
19240
|
+
}
|
|
19204
19241
|
const route = {
|
|
19205
19242
|
origin: pos,
|
|
19206
19243
|
...split.alias !== void 0 && { originAlias: split.alias },
|
|
19207
19244
|
...originLabel !== void 0 && { originLabel },
|
|
19208
19245
|
...originValue !== void 0 && { originValue },
|
|
19209
19246
|
originTags: tags,
|
|
19210
|
-
style,
|
|
19211
19247
|
legs: [],
|
|
19212
19248
|
lineNumber: line11
|
|
19213
19249
|
};
|
|
19214
19250
|
routes.push(route);
|
|
19215
19251
|
open.route = { route, indent };
|
|
19216
19252
|
}
|
|
19217
|
-
function parseLeg(trimmed, line11
|
|
19218
|
-
let arrowStyle = "straight";
|
|
19219
|
-
let label;
|
|
19220
|
-
let rest = trimmed;
|
|
19253
|
+
function parseLeg(trimmed, line11) {
|
|
19221
19254
|
const m = trimmed.match(LEG_ARROW_RE);
|
|
19222
|
-
if (m) {
|
|
19223
|
-
|
|
19224
|
-
|
|
19225
|
-
|
|
19226
|
-
|
|
19255
|
+
if (!m) {
|
|
19256
|
+
pushError(
|
|
19257
|
+
line11,
|
|
19258
|
+
`Malformed route leg: "${trimmed}" \u2014 a leg needs an arrow glyph (\`-> dest\`, \`~> dest\`, or labeled \`-label-> dest\` / \`~label~> dest\`). (\xA724B.6)`
|
|
19259
|
+
);
|
|
19260
|
+
return null;
|
|
19227
19261
|
}
|
|
19262
|
+
const arr = classifyArrow(m[1], line11);
|
|
19263
|
+
if (!arr.directed) {
|
|
19264
|
+
pushError(
|
|
19265
|
+
line11,
|
|
19266
|
+
`A route leg is directional \u2014 "${trimmed}" uses an undirected glyph; use \`-> \` (straight) or \`~> \` (arc). (\xA724B.6)`
|
|
19267
|
+
);
|
|
19268
|
+
return null;
|
|
19269
|
+
}
|
|
19270
|
+
const arrowStyle = arr.style;
|
|
19271
|
+
const label = arr.label;
|
|
19272
|
+
const rest = m[2];
|
|
19228
19273
|
const split = splitNameAndMeta(
|
|
19229
19274
|
rest,
|
|
19230
19275
|
registry(),
|
|
@@ -19240,10 +19285,9 @@ function parseMap(content, palette) {
|
|
|
19240
19285
|
const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
|
|
19241
19286
|
const value = meta["value"];
|
|
19242
19287
|
const destLabel = meta["label"];
|
|
19243
|
-
const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
|
|
19244
19288
|
return {
|
|
19245
19289
|
...label !== void 0 && { label },
|
|
19246
|
-
style,
|
|
19290
|
+
style: arrowStyle,
|
|
19247
19291
|
...value !== void 0 && { value },
|
|
19248
19292
|
dest: pos,
|
|
19249
19293
|
...split.alias !== void 0 && { destAlias: split.alias },
|
|
@@ -22857,6 +22901,344 @@ var init_parser25 = __esm({
|
|
|
22857
22901
|
}
|
|
22858
22902
|
});
|
|
22859
22903
|
|
|
22904
|
+
// src/treemap/parser.ts
|
|
22905
|
+
var parser_exports20 = {};
|
|
22906
|
+
__export(parser_exports20, {
|
|
22907
|
+
TREEMAP_DIAGNOSTIC_CODES: () => TREEMAP_DIAGNOSTIC_CODES,
|
|
22908
|
+
parseTreemap: () => parseTreemap
|
|
22909
|
+
});
|
|
22910
|
+
function isFullyQuoted(s) {
|
|
22911
|
+
return s.length >= 2 && (s.startsWith('"') && s.endsWith('"') || s.startsWith("'") && s.endsWith("'"));
|
|
22912
|
+
}
|
|
22913
|
+
function parseTreemap(content, palette) {
|
|
22914
|
+
const options = {
|
|
22915
|
+
heatColors: [],
|
|
22916
|
+
noValues: false,
|
|
22917
|
+
noPercent: false,
|
|
22918
|
+
noHeaders: false,
|
|
22919
|
+
noLegend: false
|
|
22920
|
+
};
|
|
22921
|
+
const result = {
|
|
22922
|
+
type: "treemap",
|
|
22923
|
+
title: null,
|
|
22924
|
+
titleLineNumber: null,
|
|
22925
|
+
roots: [],
|
|
22926
|
+
tagGroups: [],
|
|
22927
|
+
hasHeat: false,
|
|
22928
|
+
defaultColorMode: "branch",
|
|
22929
|
+
options,
|
|
22930
|
+
diagnostics: [],
|
|
22931
|
+
error: null
|
|
22932
|
+
};
|
|
22933
|
+
const fail = makeFail(result);
|
|
22934
|
+
const pushError = (line11, message, code) => {
|
|
22935
|
+
const diag = makeDgmoError(line11, message, "error", code);
|
|
22936
|
+
result.diagnostics.push(diag);
|
|
22937
|
+
if (!result.error) result.error = formatDgmoError(diag);
|
|
22938
|
+
};
|
|
22939
|
+
const pushWarning = (line11, message, code) => {
|
|
22940
|
+
result.diagnostics.push(makeDgmoError(line11, message, "warning", code));
|
|
22941
|
+
};
|
|
22942
|
+
if (!content?.trim()) {
|
|
22943
|
+
return fail(0, "No content provided");
|
|
22944
|
+
}
|
|
22945
|
+
const lines = content.split("\n");
|
|
22946
|
+
let contentStarted = false;
|
|
22947
|
+
let nodeCounter = 0;
|
|
22948
|
+
let currentTagGroup = null;
|
|
22949
|
+
const aliasMap = /* @__PURE__ */ new Map();
|
|
22950
|
+
const indentStack = [];
|
|
22951
|
+
for (let i = 0; i < lines.length; i++) {
|
|
22952
|
+
const line11 = lines[i];
|
|
22953
|
+
const lineNumber = i + 1;
|
|
22954
|
+
const trimmed = line11.trim();
|
|
22955
|
+
if (!trimmed) {
|
|
22956
|
+
currentTagGroup = null;
|
|
22957
|
+
continue;
|
|
22958
|
+
}
|
|
22959
|
+
if (trimmed.startsWith("//")) continue;
|
|
22960
|
+
if (!contentStarted) {
|
|
22961
|
+
const firstLine = parseFirstLine(trimmed);
|
|
22962
|
+
if (firstLine && result.titleLineNumber === null && i === 0) {
|
|
22963
|
+
if (firstLine.chartType !== "treemap") {
|
|
22964
|
+
let msg = `Expected chart type "treemap", got "${firstLine.chartType}"`;
|
|
22965
|
+
const hint = suggest(firstLine.chartType, ["treemap"]);
|
|
22966
|
+
if (hint) msg += `. ${hint}`;
|
|
22967
|
+
return fail(lineNumber, msg);
|
|
22968
|
+
}
|
|
22969
|
+
result.title = firstLine.title ?? null;
|
|
22970
|
+
result.titleLineNumber = lineNumber;
|
|
22971
|
+
continue;
|
|
22972
|
+
}
|
|
22973
|
+
}
|
|
22974
|
+
const tagBlockMatch = matchTagBlockHeading(trimmed);
|
|
22975
|
+
if (tagBlockMatch) {
|
|
22976
|
+
emitTagLegacyDiagnostic(tagBlockMatch, lineNumber, result.diagnostics);
|
|
22977
|
+
if (contentStarted) {
|
|
22978
|
+
pushError(
|
|
22979
|
+
lineNumber,
|
|
22980
|
+
"Tag groups must appear before treemap content",
|
|
22981
|
+
"E_TAG_DECLARED_AFTER_CONTENT"
|
|
22982
|
+
);
|
|
22983
|
+
continue;
|
|
22984
|
+
}
|
|
22985
|
+
currentTagGroup = {
|
|
22986
|
+
name: tagBlockMatch.name,
|
|
22987
|
+
...tagBlockMatch.alias !== void 0 && {
|
|
22988
|
+
alias: tagBlockMatch.alias
|
|
22989
|
+
},
|
|
22990
|
+
entries: [],
|
|
22991
|
+
lineNumber
|
|
22992
|
+
};
|
|
22993
|
+
if (tagBlockMatch.alias) {
|
|
22994
|
+
aliasMap.set(
|
|
22995
|
+
tagBlockMatch.alias.toLowerCase(),
|
|
22996
|
+
tagAttrKey(tagBlockMatch.name)
|
|
22997
|
+
);
|
|
22998
|
+
}
|
|
22999
|
+
aliasMap.set(
|
|
23000
|
+
tagAttrKey(tagBlockMatch.name),
|
|
23001
|
+
tagAttrKey(tagBlockMatch.name)
|
|
23002
|
+
);
|
|
23003
|
+
result.tagGroups.push(currentTagGroup);
|
|
23004
|
+
continue;
|
|
23005
|
+
}
|
|
23006
|
+
if (currentTagGroup && !contentStarted) {
|
|
23007
|
+
const indent2 = measureIndent(line11);
|
|
23008
|
+
if (indent2 > 0) {
|
|
23009
|
+
const { text: cleanEntry, isDefault } = stripDefaultModifier(trimmed);
|
|
23010
|
+
const { label, color } = extractColor(
|
|
23011
|
+
cleanEntry,
|
|
23012
|
+
palette,
|
|
23013
|
+
result.diagnostics,
|
|
23014
|
+
lineNumber
|
|
23015
|
+
);
|
|
23016
|
+
if (isDefault) {
|
|
23017
|
+
currentTagGroup.defaultValue = label;
|
|
23018
|
+
} else if (currentTagGroup.entries.length === 0) {
|
|
23019
|
+
currentTagGroup.defaultValue = label;
|
|
23020
|
+
}
|
|
23021
|
+
currentTagGroup.entries.push({
|
|
23022
|
+
value: label,
|
|
23023
|
+
color: color ?? AUTO_TAG_COLOR_SENTINEL,
|
|
23024
|
+
lineNumber
|
|
23025
|
+
});
|
|
23026
|
+
continue;
|
|
23027
|
+
}
|
|
23028
|
+
currentTagGroup = null;
|
|
23029
|
+
}
|
|
23030
|
+
if (!contentStarted && measureIndent(line11) === 0) {
|
|
23031
|
+
if (handleDirective(trimmed, options, result, pushWarning, lineNumber)) {
|
|
23032
|
+
continue;
|
|
23033
|
+
}
|
|
23034
|
+
}
|
|
23035
|
+
contentStarted = true;
|
|
23036
|
+
currentTagGroup = null;
|
|
23037
|
+
const indent = measureIndent(line11);
|
|
23038
|
+
const node = parseNodeLine3(
|
|
23039
|
+
trimmed,
|
|
23040
|
+
lineNumber,
|
|
23041
|
+
++nodeCounter,
|
|
23042
|
+
aliasMap,
|
|
23043
|
+
result.diagnostics,
|
|
23044
|
+
pushWarning
|
|
23045
|
+
);
|
|
23046
|
+
if (node.heat !== void 0) result.hasHeat = true;
|
|
23047
|
+
attachNode4(node, indent, indentStack, result);
|
|
23048
|
+
}
|
|
23049
|
+
finalizeAutoTagColors(result.tagGroups, palette);
|
|
23050
|
+
const allNodes = [];
|
|
23051
|
+
const collectAll = (nodes) => {
|
|
23052
|
+
for (const n of nodes) {
|
|
23053
|
+
allNodes.push(n);
|
|
23054
|
+
collectAll(n.children);
|
|
23055
|
+
}
|
|
23056
|
+
};
|
|
23057
|
+
collectAll(result.roots);
|
|
23058
|
+
for (const n of allNodes) {
|
|
23059
|
+
const node = n;
|
|
23060
|
+
const isBranch = node.children.length > 0;
|
|
23061
|
+
if (isBranch) {
|
|
23062
|
+
if (node.value !== void 0) {
|
|
23063
|
+
pushWarning(
|
|
23064
|
+
node.lineNumber,
|
|
23065
|
+
`"${node.label}" is a branch \u2014 its trailing number is ignored; the area is the auto-sum of its children`,
|
|
23066
|
+
TREEMAP_DIAGNOSTIC_CODES.BRANCH_VALUE_IGNORED
|
|
23067
|
+
);
|
|
23068
|
+
delete node.value;
|
|
23069
|
+
}
|
|
23070
|
+
} else if (node.value === void 0) {
|
|
23071
|
+
pushWarning(
|
|
23072
|
+
node.lineNumber,
|
|
23073
|
+
`Leaf "${node.label}" has no value \u2014 it renders with zero area`,
|
|
23074
|
+
TREEMAP_DIAGNOSTIC_CODES.LEAF_NO_VALUE
|
|
23075
|
+
);
|
|
23076
|
+
node.value = 0;
|
|
23077
|
+
} else if (node.value < 0) {
|
|
23078
|
+
pushError(
|
|
23079
|
+
node.lineNumber,
|
|
23080
|
+
`Leaf "${node.label}" has a negative value (${node.value}) \u2014 treemap sizes must be \u2265 0`,
|
|
23081
|
+
TREEMAP_DIAGNOSTIC_CODES.NEGATIVE_VALUE
|
|
23082
|
+
);
|
|
23083
|
+
}
|
|
23084
|
+
}
|
|
23085
|
+
if (result.hasHeat || options.heatLabel !== void 0) {
|
|
23086
|
+
result.hasHeat = true;
|
|
23087
|
+
}
|
|
23088
|
+
if (result.tagGroups.length > 0) {
|
|
23089
|
+
validateTagValues(allNodes, result.tagGroups, pushWarning, suggest);
|
|
23090
|
+
validateTagGroupNames(result.tagGroups, pushWarning);
|
|
23091
|
+
cascadeTagMetadata(result.roots, result.tagGroups);
|
|
23092
|
+
}
|
|
23093
|
+
result.defaultColorMode = resolveDefaultColorMode(result);
|
|
23094
|
+
if (result.roots.length === 0 && !result.error) {
|
|
23095
|
+
const diag = makeDgmoError(1, "No nodes found in treemap");
|
|
23096
|
+
result.diagnostics.push(diag);
|
|
23097
|
+
result.error = formatDgmoError(diag);
|
|
23098
|
+
}
|
|
23099
|
+
return result;
|
|
23100
|
+
}
|
|
23101
|
+
function handleDirective(trimmed, options, result, pushWarning, lineNumber) {
|
|
23102
|
+
const depthMatch = trimmed.match(/^depth\s+(-?\d+)\s*$/i);
|
|
23103
|
+
if (depthMatch) {
|
|
23104
|
+
const n = parseInt(depthMatch[1], 10);
|
|
23105
|
+
if (n >= 1) options.maxDepth = n;
|
|
23106
|
+
else pushWarning(lineNumber, '"depth" must be \u2265 1 \u2014 ignored');
|
|
23107
|
+
return true;
|
|
23108
|
+
}
|
|
23109
|
+
if (/^other-below\b/i.test(trimmed)) {
|
|
23110
|
+
pushWarning(
|
|
23111
|
+
lineNumber,
|
|
23112
|
+
'"other-below" is no longer supported \u2014 remove this line'
|
|
23113
|
+
);
|
|
23114
|
+
return true;
|
|
23115
|
+
}
|
|
23116
|
+
const heatMatch = trimmed.match(/^heat\s+(.+)$/i);
|
|
23117
|
+
if (heatMatch) {
|
|
23118
|
+
const { label, low, high } = peelRampColors(heatMatch[1].trim());
|
|
23119
|
+
options.heatLabel = label || "Value";
|
|
23120
|
+
const colors = [];
|
|
23121
|
+
if (low !== void 0) colors.push(low);
|
|
23122
|
+
if (high !== void 0) colors.push(high);
|
|
23123
|
+
options.heatColors = colors;
|
|
23124
|
+
result.hasHeat = true;
|
|
23125
|
+
return true;
|
|
23126
|
+
}
|
|
23127
|
+
const noMatch = trimmed.match(/^no-(values|percent|headers|legend)\s*$/i);
|
|
23128
|
+
if (noMatch) {
|
|
23129
|
+
const key = noMatch[1].toLowerCase();
|
|
23130
|
+
if (key === "values") options.noValues = true;
|
|
23131
|
+
else if (key === "percent") options.noPercent = true;
|
|
23132
|
+
else if (key === "headers") options.noHeaders = true;
|
|
23133
|
+
else if (key === "legend") options.noLegend = true;
|
|
23134
|
+
return true;
|
|
23135
|
+
}
|
|
23136
|
+
return false;
|
|
23137
|
+
}
|
|
23138
|
+
function resolveDefaultColorMode(result) {
|
|
23139
|
+
if (result.tagGroups.length > 0) return "tag";
|
|
23140
|
+
if (result.hasHeat) return "heat";
|
|
23141
|
+
return "branch";
|
|
23142
|
+
}
|
|
23143
|
+
function parseNodeLine3(trimmed, lineNumber, counter, aliasMap, diagnostics, pushWarning) {
|
|
23144
|
+
if (trimmed.includes("|")) {
|
|
23145
|
+
diagnostics.push(
|
|
23146
|
+
makeDgmoError(
|
|
23147
|
+
lineNumber,
|
|
23148
|
+
pipeOperatorRemovedMessage(),
|
|
23149
|
+
"error",
|
|
23150
|
+
METADATA_DIAGNOSTIC_CODES.PIPE_OPERATOR_REMOVED
|
|
23151
|
+
)
|
|
23152
|
+
);
|
|
23153
|
+
}
|
|
23154
|
+
const registry = withTagAliases(TREEMAP_REGISTRY, new Set(aliasMap.keys()));
|
|
23155
|
+
const split = splitNameAndMeta(
|
|
23156
|
+
trimmed,
|
|
23157
|
+
registry,
|
|
23158
|
+
aliasMap,
|
|
23159
|
+
void 0,
|
|
23160
|
+
diagnostics,
|
|
23161
|
+
lineNumber
|
|
23162
|
+
);
|
|
23163
|
+
warnUnknownMetaKeys(
|
|
23164
|
+
split.meta,
|
|
23165
|
+
registry,
|
|
23166
|
+
(msg) => diagnostics.push(makeDgmoError(lineNumber, msg, "warning")),
|
|
23167
|
+
split.name
|
|
23168
|
+
);
|
|
23169
|
+
const metadata = { ...split.meta };
|
|
23170
|
+
let heat;
|
|
23171
|
+
if ("heat" in metadata) {
|
|
23172
|
+
const h = parseFloat(metadata["heat"].replace(/_/g, ""));
|
|
23173
|
+
if (Number.isFinite(h)) heat = h;
|
|
23174
|
+
delete metadata["heat"];
|
|
23175
|
+
}
|
|
23176
|
+
const rawName = split.name;
|
|
23177
|
+
let label;
|
|
23178
|
+
let value;
|
|
23179
|
+
if (isFullyQuoted(rawName)) {
|
|
23180
|
+
label = stripQuotes(rawName);
|
|
23181
|
+
} else {
|
|
23182
|
+
const vm = rawName.match(VALUE_TOKEN_RE);
|
|
23183
|
+
if (vm) {
|
|
23184
|
+
const labelPart = vm[1].trim();
|
|
23185
|
+
const token = vm[2];
|
|
23186
|
+
if (token.includes(",")) {
|
|
23187
|
+
pushWarning(lineNumber, dataCommaRemovedMessage(labelPart));
|
|
23188
|
+
}
|
|
23189
|
+
const cleaned = token.replace(/[_,]/g, "");
|
|
23190
|
+
const parsed = parseFloat(cleaned);
|
|
23191
|
+
if (Number.isFinite(parsed)) {
|
|
23192
|
+
value = parsed;
|
|
23193
|
+
label = isFullyQuoted(labelPart) ? stripQuotes(labelPart) : labelPart;
|
|
23194
|
+
} else {
|
|
23195
|
+
label = rawName;
|
|
23196
|
+
}
|
|
23197
|
+
} else {
|
|
23198
|
+
label = rawName;
|
|
23199
|
+
}
|
|
23200
|
+
}
|
|
23201
|
+
return {
|
|
23202
|
+
id: `treemap-node-${counter}`,
|
|
23203
|
+
label,
|
|
23204
|
+
...value !== void 0 && { value },
|
|
23205
|
+
...heat !== void 0 && { heat },
|
|
23206
|
+
metadata,
|
|
23207
|
+
children: [],
|
|
23208
|
+
lineNumber
|
|
23209
|
+
};
|
|
23210
|
+
}
|
|
23211
|
+
function attachNode4(node, indent, indentStack, result) {
|
|
23212
|
+
while (indentStack.length > 0) {
|
|
23213
|
+
const top = indentStack[indentStack.length - 1];
|
|
23214
|
+
if (top.indent < indent) break;
|
|
23215
|
+
indentStack.pop();
|
|
23216
|
+
}
|
|
23217
|
+
if (indentStack.length > 0) {
|
|
23218
|
+
const parent = indentStack[indentStack.length - 1].node;
|
|
23219
|
+
parent.children.push(node);
|
|
23220
|
+
} else {
|
|
23221
|
+
result.roots.push(node);
|
|
23222
|
+
}
|
|
23223
|
+
indentStack.push({ node, indent });
|
|
23224
|
+
}
|
|
23225
|
+
var TREEMAP_DIAGNOSTIC_CODES, VALUE_TOKEN_RE;
|
|
23226
|
+
var init_parser26 = __esm({
|
|
23227
|
+
"src/treemap/parser.ts"() {
|
|
23228
|
+
"use strict";
|
|
23229
|
+
init_diagnostics();
|
|
23230
|
+
init_tag_groups();
|
|
23231
|
+
init_parsing();
|
|
23232
|
+
init_reserved_key_registry();
|
|
23233
|
+
TREEMAP_DIAGNOSTIC_CODES = {
|
|
23234
|
+
NEGATIVE_VALUE: "E_TREEMAP_NEGATIVE_VALUE",
|
|
23235
|
+
LEAF_NO_VALUE: "W_TREEMAP_LEAF_NO_VALUE",
|
|
23236
|
+
BRANCH_VALUE_IGNORED: "W_TREEMAP_BRANCH_VALUE_IGNORED"
|
|
23237
|
+
};
|
|
23238
|
+
VALUE_TOKEN_RE = /^(.+?)\s+(-?\d[\d_,.]*)$/;
|
|
23239
|
+
}
|
|
23240
|
+
});
|
|
23241
|
+
|
|
22860
23242
|
// src/raci/variants.ts
|
|
22861
23243
|
function inferVariant(markers) {
|
|
22862
23244
|
let hasD = false;
|
|
@@ -23111,8 +23493,8 @@ var init_variants = __esm({
|
|
|
23111
23493
|
});
|
|
23112
23494
|
|
|
23113
23495
|
// src/raci/parser.ts
|
|
23114
|
-
var
|
|
23115
|
-
__export(
|
|
23496
|
+
var parser_exports21 = {};
|
|
23497
|
+
__export(parser_exports21, {
|
|
23116
23498
|
allTasks: () => allTasks,
|
|
23117
23499
|
parseRaci: () => parseRaci
|
|
23118
23500
|
});
|
|
@@ -23633,7 +24015,7 @@ function* allTasks(parsed) {
|
|
|
23633
24015
|
}
|
|
23634
24016
|
}
|
|
23635
24017
|
var RACI_CHART_TYPE_IDS, CHART_TYPE_VARIANT_LOCK, VARIANT_LOCK_DIRECTIVES, KNOWN_OPTIONS10, KNOWN_BOOLEANS7, REMOVED_BOOLEANS3, PHASE_RE2, PHASE_PALETTE_COLOR_RE, ROLE_ASSIGNMENT_RE;
|
|
23636
|
-
var
|
|
24018
|
+
var init_parser27 = __esm({
|
|
23637
24019
|
"src/raci/parser.ts"() {
|
|
23638
24020
|
"use strict";
|
|
23639
24021
|
init_diagnostics();
|
|
@@ -23879,6 +24261,7 @@ var init_chart_type_registry = __esm({
|
|
|
23879
24261
|
init_parser24();
|
|
23880
24262
|
init_parser25();
|
|
23881
24263
|
init_parser26();
|
|
24264
|
+
init_parser27();
|
|
23882
24265
|
CHART_TYPE_REGISTRY = [
|
|
23883
24266
|
// ── Structured diagrams ───────────────────────────────────
|
|
23884
24267
|
{
|
|
@@ -24019,6 +24402,9 @@ var init_chart_type_registry = __esm({
|
|
|
24019
24402
|
{ id: "cycle", category: "visualization", parse: parseCycle },
|
|
24020
24403
|
{ id: "pyramid", category: "visualization", parse: parsePyramid },
|
|
24021
24404
|
{ id: "ring", category: "visualization", parse: parseRing },
|
|
24405
|
+
// Treemap: squarified hierarchy. No measure/minDims — a treemap fills whatever
|
|
24406
|
+
// rectangle it's given and has no intrinsic aspect/size (F11).
|
|
24407
|
+
{ id: "treemap", category: "visualization", parse: parseTreemap },
|
|
24022
24408
|
// ── Geographic map (own parser → resolver → layout → renderer) ──
|
|
24023
24409
|
{ id: "map", category: "visualization", parse: parseMap }
|
|
24024
24410
|
];
|
|
@@ -26753,10 +27139,10 @@ async function renderSitemapForExport(content, theme, palette) {
|
|
|
26753
27139
|
const parsed = parseSitemap2(content, effectivePalette);
|
|
26754
27140
|
if (parsed.error || parsed.roots.length === 0) return "";
|
|
26755
27141
|
const sitemapLayout = layoutSitemap2(parsed, void 0, null, void 0, true);
|
|
26756
|
-
const
|
|
27142
|
+
const PADDING4 = 20;
|
|
26757
27143
|
const titleOffset = parsed.title ? 30 : 0;
|
|
26758
|
-
const exportWidth = sitemapLayout.width +
|
|
26759
|
-
const exportHeight = sitemapLayout.height +
|
|
27144
|
+
const exportWidth = sitemapLayout.width + PADDING4 * 2;
|
|
27145
|
+
const exportHeight = sitemapLayout.height + PADDING4 * 2 + titleOffset;
|
|
26760
27146
|
const container = document.createElement("div");
|
|
26761
27147
|
container.style.width = `${exportWidth}px`;
|
|
26762
27148
|
container.style.height = `${exportHeight}px`;
|
|
@@ -31784,6 +32170,10 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
31784
32170
|
const reserveEdgeLabels = opts?.reserveEdgeLabels ?? false;
|
|
31785
32171
|
const onProgress = opts?.onProgress;
|
|
31786
32172
|
const tick = onProgress ? () => new Promise((r) => setTimeout(r)) : () => void 0;
|
|
32173
|
+
const YIELD_AFTER_MS = 150;
|
|
32174
|
+
const YIELD_EVERY_MS = 30;
|
|
32175
|
+
const searchStart = performance.now();
|
|
32176
|
+
let lastYield = searchStart;
|
|
31787
32177
|
const collapsedGroupLabels = /* @__PURE__ */ new Set();
|
|
31788
32178
|
if (collapseInfo) {
|
|
31789
32179
|
const missing = /* @__PURE__ */ new Set();
|
|
@@ -32213,7 +32603,11 @@ async function layoutBoxesAndLinesSearch(parsed, collapseInfo, opts) {
|
|
|
32213
32603
|
const step = async (phase) => {
|
|
32214
32604
|
if (!onProgress) return;
|
|
32215
32605
|
onProgress(++progressDone, progressTotal, phase);
|
|
32216
|
-
|
|
32606
|
+
const now = performance.now();
|
|
32607
|
+
if (now - searchStart > YIELD_AFTER_MS && now - lastYield > YIELD_EVERY_MS) {
|
|
32608
|
+
lastYield = now;
|
|
32609
|
+
await tick();
|
|
32610
|
+
}
|
|
32217
32611
|
};
|
|
32218
32612
|
const pool = [];
|
|
32219
32613
|
for (const cfg of configs) {
|
|
@@ -50601,7 +50995,7 @@ function computeEdgeLabelPosition(midAngle, radius, cx, cy, lineCount, labelPxW,
|
|
|
50601
50995
|
};
|
|
50602
50996
|
}
|
|
50603
50997
|
function fitToCanvas(nodes, edges, parsed, _cx, _cy, radius, width, height, _isClockwise) {
|
|
50604
|
-
const
|
|
50998
|
+
const PADDING4 = 30;
|
|
50605
50999
|
let contentMinX = Infinity, contentMaxX = -Infinity;
|
|
50606
51000
|
let contentMinY = Infinity, contentMaxY = -Infinity;
|
|
50607
51001
|
for (const n of nodes) {
|
|
@@ -50643,13 +51037,13 @@ function fitToCanvas(nodes, edges, parsed, _cx, _cy, radius, width, height, _isC
|
|
|
50643
51037
|
contentMinY = Math.min(contentMinY, le.labelY - 12);
|
|
50644
51038
|
contentMaxY = Math.max(contentMaxY, le.labelY + (lineCount - 1) * 15);
|
|
50645
51039
|
}
|
|
50646
|
-
const overflowX = Math.max(0,
|
|
50647
|
-
const overflowY = Math.max(0,
|
|
51040
|
+
const overflowX = Math.max(0, PADDING4 - contentMinX) + Math.max(0, contentMaxX - (width - PADDING4));
|
|
51041
|
+
const overflowY = Math.max(0, PADDING4 - contentMinY) + Math.max(0, contentMaxY - (height - PADDING4));
|
|
50648
51042
|
if (overflowX <= 0 && overflowY <= 0) return null;
|
|
50649
51043
|
const contentW = contentMaxX - contentMinX;
|
|
50650
51044
|
const contentH = contentMaxY - contentMinY;
|
|
50651
|
-
const availW = width - 2 *
|
|
50652
|
-
const availH = height - 2 *
|
|
51045
|
+
const availW = width - 2 * PADDING4;
|
|
51046
|
+
const availH = height - 2 * PADDING4;
|
|
50653
51047
|
const shrink = Math.min(availW / contentW, availH / contentH);
|
|
50654
51048
|
const newRadius = Math.max(80, radius * shrink);
|
|
50655
51049
|
return { radius: newRadius };
|
|
@@ -50848,7 +51242,7 @@ function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims
|
|
|
50848
51242
|
}
|
|
50849
51243
|
edgeLabelInfo.push({ le, edge });
|
|
50850
51244
|
}
|
|
50851
|
-
const
|
|
51245
|
+
const HEADER_H2 = 36 * layout.scale;
|
|
50852
51246
|
const scaledNodeFont = Math.max(6, Math.round(NODE_FONT_SIZE7 * layout.scale));
|
|
50853
51247
|
const scaledEdgeLabelFont = Math.max(
|
|
50854
51248
|
6,
|
|
@@ -50912,10 +51306,10 @@ function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims
|
|
|
50912
51306
|
const rx = 6;
|
|
50913
51307
|
nodeG.append("rect").attr("x", ln.x - nodeW / 2).attr("y", ln.y - nodeH / 2).attr("width", nodeW).attr("height", nodeH).attr("rx", rx).attr("ry", rx).attr("fill", fillColor).attr("stroke", solidColor).attr("stroke-width", 2);
|
|
50914
51308
|
if (hasDesc) {
|
|
50915
|
-
const headerCenterY = ln.y - nodeH / 2 +
|
|
51309
|
+
const headerCenterY = ln.y - nodeH / 2 + HEADER_H2 / 2;
|
|
50916
51310
|
const labelText = nodeG.append("text").attr("x", ln.x).attr("y", headerCenterY + scaledNodeFont / 3).attr("text-anchor", "middle").attr("fill", textColor).attr("font-family", FONT_FAMILY).attr("font-size", scaledNodeFont).attr("font-weight", "600");
|
|
50917
51311
|
renderInlineText(labelText, node.label, palette, scaledNodeFont);
|
|
50918
|
-
const sepY = ln.y - nodeH / 2 +
|
|
51312
|
+
const sepY = ln.y - nodeH / 2 + HEADER_H2;
|
|
50919
51313
|
nodeG.append("line").attr("x1", ln.x - nodeW / 2).attr("y1", sepY).attr("x2", ln.x + nodeW / 2).attr("y2", sepY).attr("stroke", solid ? descColor : solidColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
|
|
50920
51314
|
const descStartY = sepY + 4 + scaledDescFont;
|
|
50921
51315
|
const descPadX = Math.max(8, 12 * layout.scale);
|
|
@@ -53745,13 +54139,15 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
53745
54139
|
labelY: lp.y
|
|
53746
54140
|
};
|
|
53747
54141
|
const routeLabelStyle = leg.label !== void 0 ? labelOnFill(fillAt(bow.labelX, bow.labelY)) : void 0;
|
|
54142
|
+
const routeVal = Number(leg.value);
|
|
53748
54143
|
legs.push({
|
|
53749
54144
|
d: legPath(a, b, bow.curved, bow.offset),
|
|
53750
|
-
width: routeWidthFor(
|
|
54145
|
+
width: routeWidthFor(routeVal),
|
|
53751
54146
|
color: lineColor(leg.tags) ?? mix(palette.text, palette.bg, 72),
|
|
53752
54147
|
arrow: true,
|
|
53753
54148
|
fromId: leg.fromId,
|
|
53754
54149
|
toId: leg.toId,
|
|
54150
|
+
...Number.isFinite(routeVal) && routeVal > 0 && { value: routeVal },
|
|
53755
54151
|
...Object.keys(leg.tags).length > 0 && { tags: leg.tags },
|
|
53756
54152
|
lineNumber: leg.lineNumber,
|
|
53757
54153
|
...leg.label !== void 0 && {
|
|
@@ -53798,6 +54194,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
53798
54194
|
labelY: lp.y
|
|
53799
54195
|
};
|
|
53800
54196
|
const edgeLabelStyle = e.label !== void 0 ? labelOnFill(fillAt(bow.labelX, bow.labelY)) : void 0;
|
|
54197
|
+
const edgeVal = Number(e.meta["value"]);
|
|
53801
54198
|
legs.push({
|
|
53802
54199
|
d: legPath(a, b, bow.curved, bow.offset),
|
|
53803
54200
|
width: widthFor(e),
|
|
@@ -53805,6 +54202,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
53805
54202
|
arrow: e.directed,
|
|
53806
54203
|
fromId: e.fromId,
|
|
53807
54204
|
toId: e.toId,
|
|
54205
|
+
...Number.isFinite(edgeVal) && edgeVal > 0 && { value: edgeVal },
|
|
53808
54206
|
...Object.keys(e.tags).length > 0 && { tags: e.tags },
|
|
53809
54207
|
lineNumber: e.lineNumber,
|
|
53810
54208
|
...e.label !== void 0 && {
|
|
@@ -53962,18 +54360,49 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
53962
54360
|
const SHORT_HOP_MAX = Math.max(46, Math.min(width, height) * 0.11);
|
|
53963
54361
|
const STEP = 4;
|
|
53964
54362
|
const HOP_GAP = 9;
|
|
54363
|
+
const CLEAR_STEP = 6;
|
|
54364
|
+
const CLEAR_MAX = SHORT_HOP_MAX * 3;
|
|
54365
|
+
const CLEAR_TOL = CLEAR_STEP;
|
|
54366
|
+
const clearanceAt = (px, py, ox, oy) => {
|
|
54367
|
+
const baseAng = Math.atan2(oy, ox);
|
|
54368
|
+
let minClear = CLEAR_MAX;
|
|
54369
|
+
for (let k = -2; k <= 2; k++) {
|
|
54370
|
+
const a = baseAng + k * Math.PI / 4;
|
|
54371
|
+
const rx = Math.cos(a);
|
|
54372
|
+
const ry = Math.sin(a);
|
|
54373
|
+
let d = CLEAR_STEP;
|
|
54374
|
+
for (; d <= CLEAR_MAX; d += CLEAR_STEP) {
|
|
54375
|
+
const qx = px + rx * d;
|
|
54376
|
+
const qy = py + ry * d;
|
|
54377
|
+
if (qx < FIT_PAD || qy < topPad || qx > width - FIT_PAD || qy > height - FIT_PAD)
|
|
54378
|
+
break;
|
|
54379
|
+
if (fillAt(qx, qy) !== water) break;
|
|
54380
|
+
}
|
|
54381
|
+
if (d < minClear) minClear = d;
|
|
54382
|
+
}
|
|
54383
|
+
return minClear;
|
|
54384
|
+
};
|
|
53965
54385
|
const tryShortHopCallout = (cx, cy, fill2, name, value, font = FONT2, gap = HOP_GAP, maxLen = SHORT_HOP_MAX) => {
|
|
53966
54386
|
const chipW = stackW(name, value, font);
|
|
53967
54387
|
const chipH = stackH(value !== void 0, font);
|
|
54388
|
+
const D = Math.SQRT1_2;
|
|
53968
54389
|
const dirs = [
|
|
53969
54390
|
[0, -1],
|
|
53970
|
-
// north
|
|
54391
|
+
// north
|
|
53971
54392
|
[0, 1],
|
|
53972
|
-
// south
|
|
54393
|
+
// south
|
|
53973
54394
|
[1, 0],
|
|
53974
|
-
// east
|
|
53975
|
-
[-1, 0]
|
|
53976
|
-
// west
|
|
54395
|
+
// east
|
|
54396
|
+
[-1, 0],
|
|
54397
|
+
// west
|
|
54398
|
+
[D, -D],
|
|
54399
|
+
// NE
|
|
54400
|
+
[D, D],
|
|
54401
|
+
// SE
|
|
54402
|
+
[-D, -D],
|
|
54403
|
+
// NW
|
|
54404
|
+
[-D, D]
|
|
54405
|
+
// SW
|
|
53977
54406
|
];
|
|
53978
54407
|
let best = null;
|
|
53979
54408
|
for (const [dx, dy] of dirs) {
|
|
@@ -54023,13 +54452,16 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54023
54452
|
(p) => segmentRectOverlap(cx, cy, innerX, innerY, p)
|
|
54024
54453
|
))
|
|
54025
54454
|
continue;
|
|
54026
|
-
|
|
54455
|
+
const clear = clearanceAt(ccx, ccy, dx, dy);
|
|
54456
|
+
const better = best === null || clear > best.clear + CLEAR_TOL || clear >= best.clear - CLEAR_TOL && len < best.len;
|
|
54457
|
+
if (better)
|
|
54027
54458
|
best = {
|
|
54028
54459
|
x: ccx,
|
|
54029
54460
|
y: ccy,
|
|
54030
54461
|
rect,
|
|
54031
54462
|
leader: [cx, cy, innerX, innerY],
|
|
54032
|
-
len
|
|
54463
|
+
len,
|
|
54464
|
+
clear
|
|
54033
54465
|
};
|
|
54034
54466
|
}
|
|
54035
54467
|
return best ? { x: best.x, y: best.y, rect: best.rect, leader: best.leader } : null;
|
|
@@ -54690,6 +55122,9 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54690
55122
|
const nx = -dy / len;
|
|
54691
55123
|
const ny = dx / len;
|
|
54692
55124
|
const perp = labelH + 2;
|
|
55125
|
+
const stroke2 = lg.width ?? W_MIN;
|
|
55126
|
+
const clearW = stroke2 / 2 + labelH / 2 + 3;
|
|
55127
|
+
const offList = stroke2 >= 4 ? [clearW, -clearW, clearW + perp, -(clearW + perp), 0] : [0, perp, -perp, 2 * perp, -2 * perp];
|
|
54693
55128
|
const pm = /^M(-?[\d.]+),(-?[\d.]+)(?:L(-?[\d.]+),(-?[\d.]+)|Q(-?[\d.]+),(-?[\d.]+) (-?[\d.]+),(-?[\d.]+))$/.exec(
|
|
54694
55129
|
lg.d
|
|
54695
55130
|
);
|
|
@@ -54709,7 +55144,7 @@ function layoutMap(resolvedIn, data, size, opts) {
|
|
|
54709
55144
|
return [a.cx + dx * t, a.cy + dy * t];
|
|
54710
55145
|
};
|
|
54711
55146
|
const candidates = [];
|
|
54712
|
-
for (const off of
|
|
55147
|
+
for (const off of offList)
|
|
54713
55148
|
for (const t of T_LIST) {
|
|
54714
55149
|
const [bx, by] = pointAt(t);
|
|
54715
55150
|
candidates.push([bx + nx * off, by + ny * off - 4]);
|
|
@@ -55460,6 +55895,12 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
55460
55895
|
}
|
|
55461
55896
|
}
|
|
55462
55897
|
wireSync(p, leg.lineNumber);
|
|
55898
|
+
if (leg.value !== void 0) {
|
|
55899
|
+
p.attr("data-value", leg.value);
|
|
55900
|
+
p.append("title").text(
|
|
55901
|
+
leg.label !== void 0 ? `${leg.label}: ${leg.value}` : `${leg.value}`
|
|
55902
|
+
);
|
|
55903
|
+
}
|
|
55463
55904
|
if (arrowTri) {
|
|
55464
55905
|
gLegs.append("path").attr("d", arrowTri).attr("fill", leg.color).attr("stroke", leg.color).attr("stroke-width", 1).attr("stroke-linejoin", "round").attr("data-from-id", leg.fromId).attr("data-to-id", leg.toId);
|
|
55465
55906
|
}
|
|
@@ -55689,7 +56130,9 @@ function mapContentAspect(resolved, data, ref = REF) {
|
|
|
55689
56130
|
function mapExportDimensions(resolved, data, baseWidth = 1200, aspectOverride) {
|
|
55690
56131
|
const useOverride = aspectOverride !== void 0 && Number.isFinite(aspectOverride) && aspectOverride > 0;
|
|
55691
56132
|
const raw = useOverride ? aspectOverride : mapContentAspect(resolved, data);
|
|
55692
|
-
const
|
|
56133
|
+
const isGlobal = !useOverride && buildMapProjection(resolved, data).fitIsGlobal;
|
|
56134
|
+
const target = isGlobal ? raw / GLOBAL_HEIGHT_BOOST : raw;
|
|
56135
|
+
const clamped = useOverride ? raw : Math.max(ASPECT_MIN, Math.min(ASPECT_MAX, target));
|
|
55693
56136
|
const width = baseWidth;
|
|
55694
56137
|
let height = Math.round(width / clamped);
|
|
55695
56138
|
let chromeReserve = 0;
|
|
@@ -55702,10 +56145,10 @@ function mapExportDimensions(resolved, data, baseWidth = 1200, aspectOverride) {
|
|
|
55702
56145
|
height = Math.round(chromeReserve + MIN_MAP_BAND);
|
|
55703
56146
|
floored = true;
|
|
55704
56147
|
}
|
|
55705
|
-
const preferContain = useOverride ? floored : clamped !==
|
|
56148
|
+
const preferContain = useOverride ? floored : clamped !== target || floored;
|
|
55706
56149
|
return { width, height, preferContain };
|
|
55707
56150
|
}
|
|
55708
|
-
var FIT_PAD2, TITLE_GAP, ASPECT_MAX, ASPECT_MIN, MIN_MAP_BAND, FALLBACK_ASPECT, REF;
|
|
56151
|
+
var FIT_PAD2, TITLE_GAP, ASPECT_MAX, ASPECT_MIN, GLOBAL_HEIGHT_BOOST, MIN_MAP_BAND, FALLBACK_ASPECT, REF;
|
|
55709
56152
|
var init_dimensions = __esm({
|
|
55710
56153
|
"src/map/dimensions.ts"() {
|
|
55711
56154
|
"use strict";
|
|
@@ -55715,6 +56158,7 @@ var init_dimensions = __esm({
|
|
|
55715
56158
|
TITLE_GAP = 16;
|
|
55716
56159
|
ASPECT_MAX = 3;
|
|
55717
56160
|
ASPECT_MIN = 0.9;
|
|
56161
|
+
GLOBAL_HEIGHT_BOOST = 1.12;
|
|
55718
56162
|
MIN_MAP_BAND = 200;
|
|
55719
56163
|
FALLBACK_ASPECT = 1.5;
|
|
55720
56164
|
REF = 1e3;
|
|
@@ -56503,14 +56947,477 @@ var init_renderer18 = __esm({
|
|
|
56503
56947
|
}
|
|
56504
56948
|
});
|
|
56505
56949
|
|
|
56506
|
-
// src/
|
|
56950
|
+
// src/treemap/layout.ts
|
|
56951
|
+
import {
|
|
56952
|
+
hierarchy as hierarchy2,
|
|
56953
|
+
treemap,
|
|
56954
|
+
treemapSquarify
|
|
56955
|
+
} from "d3-hierarchy";
|
|
56956
|
+
function toDatum(node) {
|
|
56957
|
+
if (node.children.length === 0) {
|
|
56958
|
+
return {
|
|
56959
|
+
ref: node,
|
|
56960
|
+
label: node.label,
|
|
56961
|
+
value: node.value ?? 0,
|
|
56962
|
+
...node.heat !== void 0 && { heat: node.heat },
|
|
56963
|
+
lineNumber: node.lineNumber
|
|
56964
|
+
};
|
|
56965
|
+
}
|
|
56966
|
+
return {
|
|
56967
|
+
ref: node,
|
|
56968
|
+
label: node.label,
|
|
56969
|
+
...node.heat !== void 0 && { heat: node.heat },
|
|
56970
|
+
lineNumber: node.lineNumber,
|
|
56971
|
+
children: node.children.map((c) => toDatum(c))
|
|
56972
|
+
};
|
|
56973
|
+
}
|
|
56974
|
+
function datumHeat(node) {
|
|
56975
|
+
if (node.data.heat !== void 0) return node.data.heat;
|
|
56976
|
+
const xs = [];
|
|
56977
|
+
for (const l of node.leaves()) {
|
|
56978
|
+
if (l.data.heat !== void 0) xs.push(l.data.heat);
|
|
56979
|
+
}
|
|
56980
|
+
if (xs.length === 0) return void 0;
|
|
56981
|
+
return xs.reduce((a, b) => a + b, 0) / xs.length;
|
|
56982
|
+
}
|
|
56983
|
+
function layoutTreemap(roots, opts) {
|
|
56984
|
+
const maxDepth = opts.maxDepth ?? Infinity;
|
|
56985
|
+
const rootDatum = {
|
|
56986
|
+
label: "__root",
|
|
56987
|
+
children: roots.map((r) => toDatum(r))
|
|
56988
|
+
};
|
|
56989
|
+
const h = hierarchy2(rootDatum).sum((d) => d.children?.length ? 0 : d.value ?? 0).sort((a, b) => (b.value ?? 0) - (a.value ?? 0));
|
|
56990
|
+
const hroot = treemap().tile(treemapSquarify).size([opts.width, opts.height]).paddingOuter(opts.paddingOuter ?? 3).paddingTop(opts.headerH > 0 ? opts.headerH : opts.paddingInner ?? 2).paddingInner(opts.paddingInner ?? 2).round(true)(h);
|
|
56991
|
+
const total = hroot.value ?? 0;
|
|
56992
|
+
(hroot.children ?? []).forEach((top, i) => {
|
|
56993
|
+
top.each((d) => {
|
|
56994
|
+
d._topIndex = i;
|
|
56995
|
+
});
|
|
56996
|
+
});
|
|
56997
|
+
const cells = [];
|
|
56998
|
+
for (const d of hroot.descendants()) {
|
|
56999
|
+
if (d.depth === 0) continue;
|
|
57000
|
+
if (d.depth > maxDepth) continue;
|
|
57001
|
+
const hasChildren = !!d.children && d.children.length > 0;
|
|
57002
|
+
const isCollapsed = hasChildren && d.depth >= maxDepth;
|
|
57003
|
+
const isContainer = hasChildren && !isCollapsed;
|
|
57004
|
+
const path = [];
|
|
57005
|
+
let p = d;
|
|
57006
|
+
while (p && p.depth > 0) {
|
|
57007
|
+
path.unshift(p.data.label);
|
|
57008
|
+
p = p.parent;
|
|
57009
|
+
}
|
|
57010
|
+
const heatVal = datumHeat(d);
|
|
57011
|
+
cells.push({
|
|
57012
|
+
node: d.data.ref ?? null,
|
|
57013
|
+
label: d.data.label,
|
|
57014
|
+
x0: d.x0,
|
|
57015
|
+
y0: d.y0,
|
|
57016
|
+
x1: d.x1,
|
|
57017
|
+
y1: d.y1,
|
|
57018
|
+
depth: d.depth,
|
|
57019
|
+
value: d.value ?? 0,
|
|
57020
|
+
isContainer,
|
|
57021
|
+
isCollapsed,
|
|
57022
|
+
topIndex: d._topIndex ?? 0,
|
|
57023
|
+
pctOfRoot: total > 0 ? (d.value ?? 0) / total : 0,
|
|
57024
|
+
pctOfParent: d.parent && (d.parent.value ?? 0) > 0 ? (d.value ?? 0) / (d.parent.value ?? 1) : 1,
|
|
57025
|
+
...heatVal !== void 0 && { heat: heatVal },
|
|
57026
|
+
path,
|
|
57027
|
+
...d.data.lineNumber !== void 0 && { lineNumber: d.data.lineNumber }
|
|
57028
|
+
});
|
|
57029
|
+
}
|
|
57030
|
+
return { cells, total };
|
|
57031
|
+
}
|
|
57032
|
+
var init_layout16 = __esm({
|
|
57033
|
+
"src/treemap/layout.ts"() {
|
|
57034
|
+
"use strict";
|
|
57035
|
+
}
|
|
57036
|
+
});
|
|
57037
|
+
|
|
57038
|
+
// src/treemap/renderer.ts
|
|
56507
57039
|
var renderer_exports19 = {};
|
|
56508
57040
|
__export(renderer_exports19, {
|
|
57041
|
+
compactNumber: () => compactNumber2,
|
|
57042
|
+
renderTreemap: () => renderTreemap,
|
|
57043
|
+
renderTreemapForExport: () => renderTreemapForExport
|
|
57044
|
+
});
|
|
57045
|
+
import * as d3Selection26 from "d3-selection";
|
|
57046
|
+
import { scaleLinear as scaleLinear6 } from "d3-scale";
|
|
57047
|
+
function renderTreemapForExport(container, parsed, palette, isDark, exportDims, options) {
|
|
57048
|
+
renderTreemap(container, parsed, palette, isDark, exportDims, {
|
|
57049
|
+
exportMode: true,
|
|
57050
|
+
...options
|
|
57051
|
+
});
|
|
57052
|
+
}
|
|
57053
|
+
function renderTreemap(container, parsed, palette, isDark, exportDims, options = {}) {
|
|
57054
|
+
if (parsed.error || parsed.roots.length === 0) return;
|
|
57055
|
+
void isDark;
|
|
57056
|
+
d3Selection26.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
57057
|
+
const width = exportDims?.width ?? container.clientWidth;
|
|
57058
|
+
const height = exportDims?.height ?? container.clientHeight;
|
|
57059
|
+
if (width <= 0 || height <= 0) return;
|
|
57060
|
+
const mode = resolveColorMode(parsed, options.colorMode);
|
|
57061
|
+
const opts = parsed.options;
|
|
57062
|
+
const exportMode = options.exportMode ?? false;
|
|
57063
|
+
const seriesColorsTop = getSeriesColors(palette);
|
|
57064
|
+
const showTitle = !!parsed.title;
|
|
57065
|
+
const titleH = showTitle ? TITLE_BAND : 0;
|
|
57066
|
+
const heat = buildHeatScale(parsed, palette);
|
|
57067
|
+
const legend = !opts.noLegend ? buildLegend(mode, parsed, heat, seriesColorsTop, options.colorOffset ?? 0) : null;
|
|
57068
|
+
const legendReserve = legend ? getMaxLegendReservedHeight(
|
|
57069
|
+
{ groups: legend.groups, position: LEGEND_POSITION, mode: "preview" },
|
|
57070
|
+
width
|
|
57071
|
+
) + LEGEND_GROUP_GAP : 0;
|
|
57072
|
+
const headerH = opts.noHeaders ? 0 : HEADER_H;
|
|
57073
|
+
const areaX = PADDING3;
|
|
57074
|
+
const areaY = titleH + legendReserve + PADDING3;
|
|
57075
|
+
const areaW = Math.max(1, width - PADDING3 * 2);
|
|
57076
|
+
const areaH = Math.max(1, height - areaY - PADDING3);
|
|
57077
|
+
const layout = layoutTreemap(parsed.roots, {
|
|
57078
|
+
width: areaW,
|
|
57079
|
+
height: areaH,
|
|
57080
|
+
headerH,
|
|
57081
|
+
...options.maxDepth !== void 0 && { maxDepth: options.maxDepth }
|
|
57082
|
+
});
|
|
57083
|
+
const svg = d3Selection26.select(container).append("svg").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").attr("class", "dgmo-treemap").style("font-family", FONT_FAMILY);
|
|
57084
|
+
svg.append("style").text(
|
|
57085
|
+
".dgmo-treemap-focus{opacity:.3;transition:opacity .12s}.dgmo-treemap-cell:hover .dgmo-treemap-focus{opacity:.7}"
|
|
57086
|
+
);
|
|
57087
|
+
svg.append("rect").attr("width", width).attr("height", height).attr("fill", palette.bg);
|
|
57088
|
+
if (showTitle) {
|
|
57089
|
+
const title = 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).text(parsed.title);
|
|
57090
|
+
if (parsed.titleLineNumber !== null) {
|
|
57091
|
+
title.attr("data-line-number", parsed.titleLineNumber);
|
|
57092
|
+
}
|
|
57093
|
+
}
|
|
57094
|
+
const root = svg.append("g").attr("class", "dgmo-treemap-cells").attr("transform", `translate(${areaX},${areaY})`);
|
|
57095
|
+
const seriesColors2 = seriesColorsTop;
|
|
57096
|
+
const colorOffset = options.colorOffset ?? 0;
|
|
57097
|
+
const activeGroup = parsed.tagGroups.length > 0 ? parsed.tagGroups[0].name : null;
|
|
57098
|
+
const rootIndexByLabel = new Map(parsed.roots.map((r, i) => [r.label, i]));
|
|
57099
|
+
const colorOf = (cell) => {
|
|
57100
|
+
if (mode === "heat") {
|
|
57101
|
+
return cell.heat !== void 0 && heat ? heat.scale(cell.heat) : MUTED_FILL;
|
|
57102
|
+
}
|
|
57103
|
+
if (mode === "tag") {
|
|
57104
|
+
if (!cell.node) return MUTED_FILL;
|
|
57105
|
+
return resolveTagColor(cell.node.metadata, parsed.tagGroups, activeGroup) ?? MUTED_FILL;
|
|
57106
|
+
}
|
|
57107
|
+
const topLabel = cell.path[0] ?? cell.label;
|
|
57108
|
+
const idx = (rootIndexByLabel.get(topLabel) ?? cell.topIndex) + colorOffset;
|
|
57109
|
+
const hue = seriesColors2[idx % seriesColors2.length];
|
|
57110
|
+
if (cell.depth <= 1) return hue;
|
|
57111
|
+
const keepPct = Math.max(55, 100 - (cell.depth - 1) * 18);
|
|
57112
|
+
return mix(hue, palette.bg, keepPct);
|
|
57113
|
+
};
|
|
57114
|
+
for (const cell of layout.cells) {
|
|
57115
|
+
const w = Math.max(0, cell.x1 - cell.x0);
|
|
57116
|
+
const h = Math.max(0, cell.y1 - cell.y0);
|
|
57117
|
+
if (w <= 0 || h <= 0) continue;
|
|
57118
|
+
const baseColor = colorOf(cell);
|
|
57119
|
+
const fill2 = cell.isContainer ? baseColor : mix(baseColor, palette.bg, LEAF_MUTE_PCT);
|
|
57120
|
+
const drillable = cell.isContainer || cell.isCollapsed;
|
|
57121
|
+
const g = root.append("g").attr("class", "dgmo-treemap-cell").attr("transform", `translate(${cell.x0},${cell.y0})`).attr("data-node-path", cell.path.join(" / "));
|
|
57122
|
+
if (cell.lineNumber !== void 0) {
|
|
57123
|
+
g.attr("data-line-number", cell.lineNumber);
|
|
57124
|
+
}
|
|
57125
|
+
if (cell.heat !== void 0) g.attr("data-heat", cell.heat);
|
|
57126
|
+
if (cell.node && activeGroup) {
|
|
57127
|
+
const key = tagAttrKey(activeGroup);
|
|
57128
|
+
const tagVal = cell.node.metadata[key];
|
|
57129
|
+
if (tagVal) g.attr(`data-tag-${key}`, tagVal);
|
|
57130
|
+
}
|
|
57131
|
+
const rect = g.append("rect").attr(
|
|
57132
|
+
"class",
|
|
57133
|
+
cell.isContainer ? "dgmo-treemap-rect branch" : "dgmo-treemap-rect"
|
|
57134
|
+
).attr("width", w).attr("height", h).attr("rx", 2).attr("fill", fill2).attr("fill-opacity", 1).attr("stroke", palette.bg).attr("stroke-width", cell.isContainer ? 1 : 0);
|
|
57135
|
+
if (drillable && options.onClickItem && cell.lineNumber !== void 0) {
|
|
57136
|
+
const ln = cell.lineNumber;
|
|
57137
|
+
rect.style("cursor", "pointer").on("click", () => options.onClickItem(ln));
|
|
57138
|
+
}
|
|
57139
|
+
const ink = contrastText(
|
|
57140
|
+
fill2,
|
|
57141
|
+
palette.textOnFillLight,
|
|
57142
|
+
palette.textOnFillDark
|
|
57143
|
+
);
|
|
57144
|
+
if (cell.isContainer && headerH > 0 && w > 34 && h > headerH) {
|
|
57145
|
+
const valParts = [];
|
|
57146
|
+
if (!opts.noValues) valParts.push(compactNumber2(cell.value));
|
|
57147
|
+
if (!opts.noPercent) valParts.push(formatPct(cell.pctOfRoot));
|
|
57148
|
+
const valStr = valParts.join(" \xB7 ");
|
|
57149
|
+
const ICON_RESERVE = drillable ? 16 : 4;
|
|
57150
|
+
const showVal = valStr.length > 0 && w > 110;
|
|
57151
|
+
const valW = showVal ? measureText(valStr, 10.5) : 0;
|
|
57152
|
+
const labelMax = w - 8 - ICON_RESERVE - (showVal ? valW + 10 : 0);
|
|
57153
|
+
g.append("text").attr("class", "dgmo-treemap-header").attr("x", 6).attr("y", 13).attr("font-size", 11).attr("font-weight", 700).attr("fill", ink).text(clipLabel(cell.label, Math.max(0, labelMax), 11));
|
|
57154
|
+
if (showVal) {
|
|
57155
|
+
g.append("text").attr("class", "dgmo-treemap-header-value").attr("x", w - ICON_RESERVE - 4).attr("y", 13).attr("text-anchor", "end").attr("font-size", 10.5).attr("fill", ink).attr("opacity", 0.75).text(valStr);
|
|
57156
|
+
}
|
|
57157
|
+
}
|
|
57158
|
+
const PAD = Math.max(4, Math.min(14, Math.floor(Math.min(w, h) / 5)));
|
|
57159
|
+
const MIN_FS = 7;
|
|
57160
|
+
if (!cell.isContainer && w >= 2 * PAD + 8 && h >= 2 * PAD + 8) {
|
|
57161
|
+
const maxW = w - 2 * PAD;
|
|
57162
|
+
let fs = clamp3(Math.round(Math.min(w / 3.6, h / 3.4)), MIN_FS, 72);
|
|
57163
|
+
const nameW = measureText(cell.label, fs) * 1.06;
|
|
57164
|
+
if (nameW > maxW) fs = Math.max(MIN_FS, Math.floor(fs * maxW / nameW));
|
|
57165
|
+
const tg = clamp3((fs - MIN_FS) / (72 - MIN_FS), 0, 1);
|
|
57166
|
+
const nameOpacity = 0.95 - tg * 0.5;
|
|
57167
|
+
const vfs = clamp3(Math.round(fs * 0.42), 11, 28);
|
|
57168
|
+
const valOpacity = Math.max(0.45, nameOpacity - 0.1);
|
|
57169
|
+
let y = PAD + Math.round(fs * 0.78);
|
|
57170
|
+
g.append("text").attr("class", "dgmo-treemap-label").attr("x", PAD).attr("y", y).attr("font-size", fs).attr("font-weight", 600).attr("fill", ink).attr("opacity", nameOpacity).text(clipLabel(cell.label, maxW, fs));
|
|
57171
|
+
const valParts = [
|
|
57172
|
+
opts.noValues ? "" : compactNumber2(cell.value),
|
|
57173
|
+
opts.noPercent ? "" : formatPct(cell.pctOfRoot)
|
|
57174
|
+
].filter(Boolean);
|
|
57175
|
+
const combined = valParts.join(" \xB7 ");
|
|
57176
|
+
const nameBaseY = y;
|
|
57177
|
+
const addLineAt = (text, yy, size, opacity) => {
|
|
57178
|
+
g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD).attr("y", yy).attr("font-size", size).attr("fill", ink).attr("opacity", opacity).text(text);
|
|
57179
|
+
};
|
|
57180
|
+
if (combined) {
|
|
57181
|
+
const fitsW = measureText(combined, vfs) <= maxW;
|
|
57182
|
+
const roomBelow = h - PAD > y + vfs + 6;
|
|
57183
|
+
if (fitsW && roomBelow) {
|
|
57184
|
+
addLineAt(combined, y + vfs + 6, vfs, valOpacity);
|
|
57185
|
+
} else if (fitsW) {
|
|
57186
|
+
const ivfs = clamp3(Math.round(fs * 0.5), 11, Math.max(11, vfs));
|
|
57187
|
+
const rendered = clipLabel(cell.label, maxW, fs);
|
|
57188
|
+
const nW = measureText(rendered, fs) * 1.12;
|
|
57189
|
+
const gap = Math.max(12, Math.round(fs * 0.25));
|
|
57190
|
+
if (PAD + nW + gap + measureText(combined, ivfs) <= w - PAD) {
|
|
57191
|
+
g.append("text").attr("class", "dgmo-treemap-value").attr("x", PAD + nW + gap).attr("y", nameBaseY).attr("font-size", ivfs).attr("fill", ink).attr("opacity", valOpacity).text(combined);
|
|
57192
|
+
}
|
|
57193
|
+
} else if (valParts.length === 2) {
|
|
57194
|
+
if (h - PAD > y + vfs + 6) {
|
|
57195
|
+
y += vfs + 6;
|
|
57196
|
+
addLineAt(valParts[0], y, vfs, valOpacity);
|
|
57197
|
+
}
|
|
57198
|
+
const pfs = Math.max(10, Math.round(vfs * 0.9));
|
|
57199
|
+
if (h - PAD > y + pfs + 4) {
|
|
57200
|
+
y += pfs + 4;
|
|
57201
|
+
addLineAt(valParts[1], y, pfs, valOpacity);
|
|
57202
|
+
}
|
|
57203
|
+
} else if (h - PAD > y + vfs + 6) {
|
|
57204
|
+
addLineAt(combined, y + vfs + 6, vfs, valOpacity);
|
|
57205
|
+
}
|
|
57206
|
+
}
|
|
57207
|
+
}
|
|
57208
|
+
if (drillable && w > 30 && h > 22) {
|
|
57209
|
+
drawFocusIcon(g, w, ink, 9);
|
|
57210
|
+
}
|
|
57211
|
+
}
|
|
57212
|
+
if (legend) {
|
|
57213
|
+
const legendG = svg.append("g").attr("class", "dgmo-treemap-legend").attr("transform", `translate(0, ${titleH})`);
|
|
57214
|
+
renderIntegratedLegend(legendG, {
|
|
57215
|
+
groups: legend.groups,
|
|
57216
|
+
palette: {
|
|
57217
|
+
bg: palette.bg,
|
|
57218
|
+
surface: palette.surface,
|
|
57219
|
+
text: palette.text,
|
|
57220
|
+
textMuted: palette.textMuted,
|
|
57221
|
+
primary: palette.primary
|
|
57222
|
+
},
|
|
57223
|
+
isDark,
|
|
57224
|
+
width,
|
|
57225
|
+
mode: exportMode ? "export" : "preview",
|
|
57226
|
+
position: LEGEND_POSITION,
|
|
57227
|
+
activeGroup: legend.activeGroup,
|
|
57228
|
+
// The color-mode switcher is the legend itself: each applicable mode is a
|
|
57229
|
+
// group pill; the active one is the open capsule, the rest are clickable
|
|
57230
|
+
// pills that switch mode. Export shows only the active group.
|
|
57231
|
+
showInactivePills: !exportMode,
|
|
57232
|
+
showEmptyGroups: !exportMode,
|
|
57233
|
+
...options.onSelectMode !== void 0 && {
|
|
57234
|
+
callbacks: {
|
|
57235
|
+
onGroupToggle: (name) => {
|
|
57236
|
+
const m = legend.modeByName.get(name);
|
|
57237
|
+
if (m) options.onSelectMode(m);
|
|
57238
|
+
}
|
|
57239
|
+
}
|
|
57240
|
+
}
|
|
57241
|
+
});
|
|
57242
|
+
}
|
|
57243
|
+
}
|
|
57244
|
+
function buildLegend(activeMode, parsed, heat, seriesColors2, colorOffset) {
|
|
57245
|
+
const groups = [];
|
|
57246
|
+
const modeByName = /* @__PURE__ */ new Map();
|
|
57247
|
+
let activeGroup = null;
|
|
57248
|
+
if (parsed.tagGroups.length > 0) {
|
|
57249
|
+
const tg = parsed.tagGroups[0];
|
|
57250
|
+
const used = /* @__PURE__ */ new Set();
|
|
57251
|
+
const collect = (nodes) => {
|
|
57252
|
+
for (const n of nodes) {
|
|
57253
|
+
const v = n.metadata[tagAttrKey(tg.name)];
|
|
57254
|
+
if (v) used.add(v.toLowerCase());
|
|
57255
|
+
collect(n.children);
|
|
57256
|
+
}
|
|
57257
|
+
};
|
|
57258
|
+
collect(parsed.roots);
|
|
57259
|
+
groups.push({
|
|
57260
|
+
name: tg.name,
|
|
57261
|
+
entries: tg.entries.filter((e) => used.has(e.value.toLowerCase())).map((e) => ({ value: e.value, color: e.color }))
|
|
57262
|
+
});
|
|
57263
|
+
modeByName.set(tg.name, "tag");
|
|
57264
|
+
if (activeMode === "tag") activeGroup = tg.name;
|
|
57265
|
+
}
|
|
57266
|
+
if (heat) {
|
|
57267
|
+
const name = parsed.options.heatLabel ?? "Value";
|
|
57268
|
+
groups.push({
|
|
57269
|
+
name,
|
|
57270
|
+
entries: [],
|
|
57271
|
+
gradient: {
|
|
57272
|
+
min: heat.min,
|
|
57273
|
+
max: heat.max,
|
|
57274
|
+
low: heat.stops[0],
|
|
57275
|
+
high: heat.stops[heat.stops.length - 1]
|
|
57276
|
+
}
|
|
57277
|
+
});
|
|
57278
|
+
modeByName.set(name, "heat");
|
|
57279
|
+
if (activeMode === "heat") activeGroup = name;
|
|
57280
|
+
}
|
|
57281
|
+
groups.push({
|
|
57282
|
+
name: "Branch",
|
|
57283
|
+
entries: parsed.roots.map((r, i) => ({
|
|
57284
|
+
value: r.label,
|
|
57285
|
+
color: seriesColors2[(i + colorOffset) % seriesColors2.length]
|
|
57286
|
+
}))
|
|
57287
|
+
});
|
|
57288
|
+
modeByName.set("Branch", "branch");
|
|
57289
|
+
if (activeMode === "branch" || activeGroup === null) activeGroup = "Branch";
|
|
57290
|
+
return { groups, activeGroup, modeByName };
|
|
57291
|
+
}
|
|
57292
|
+
function buildHeatScale(parsed, palette) {
|
|
57293
|
+
if (!parsed.hasHeat) return null;
|
|
57294
|
+
const values = [];
|
|
57295
|
+
const collect = (nodes) => {
|
|
57296
|
+
for (const n of nodes) {
|
|
57297
|
+
if (typeof n.heat === "number") values.push(n.heat);
|
|
57298
|
+
collect(n.children);
|
|
57299
|
+
}
|
|
57300
|
+
};
|
|
57301
|
+
collect(parsed.roots);
|
|
57302
|
+
if (values.length === 0) return null;
|
|
57303
|
+
const min = Math.min(...values);
|
|
57304
|
+
const max = Math.max(...values);
|
|
57305
|
+
const signed = min < 0 && max > 0;
|
|
57306
|
+
const neutral = palette.surface;
|
|
57307
|
+
const explicit = parsed.options.heatColors.map((c) => resolveColor(c, palette) ?? c).filter((c) => !!c);
|
|
57308
|
+
let stops;
|
|
57309
|
+
let domain;
|
|
57310
|
+
if (explicit.length >= 2) {
|
|
57311
|
+
stops = [explicit[0], neutral, explicit[1]];
|
|
57312
|
+
const mid = signed ? 0 : (min + max) / 2;
|
|
57313
|
+
domain = [min, mid, max];
|
|
57314
|
+
} else if (explicit.length === 1) {
|
|
57315
|
+
stops = [neutral, explicit[0]];
|
|
57316
|
+
domain = [min, max];
|
|
57317
|
+
} else if (signed) {
|
|
57318
|
+
stops = [palette.colors.red, neutral, palette.colors.green];
|
|
57319
|
+
domain = [min, 0, max];
|
|
57320
|
+
} else {
|
|
57321
|
+
stops = [neutral, palette.primary];
|
|
57322
|
+
domain = [min, max];
|
|
57323
|
+
}
|
|
57324
|
+
if (domain[0] === domain[domain.length - 1]) {
|
|
57325
|
+
const last = stops[stops.length - 1];
|
|
57326
|
+
return { scale: () => last, min, max, stops, signed };
|
|
57327
|
+
}
|
|
57328
|
+
const linear = scaleLinear6().domain(domain).range(stops).clamp(true);
|
|
57329
|
+
return { scale: (v) => toHex(linear(v)), min, max, stops, signed };
|
|
57330
|
+
}
|
|
57331
|
+
function toHex(c) {
|
|
57332
|
+
if (c.startsWith("#")) return c;
|
|
57333
|
+
const m = c.match(/rgba?\(([^)]+)\)/);
|
|
57334
|
+
if (!m) return c;
|
|
57335
|
+
const parts = m[1].split(",").map((s) => Math.round(parseFloat(s)));
|
|
57336
|
+
const h = (n) => Math.max(0, Math.min(255, n || 0)).toString(16).padStart(2, "0");
|
|
57337
|
+
return `#${h(parts[0] ?? 0)}${h(parts[1] ?? 0)}${h(parts[2] ?? 0)}`;
|
|
57338
|
+
}
|
|
57339
|
+
function resolveColorMode(parsed, override) {
|
|
57340
|
+
let mode = override ?? parsed.defaultColorMode;
|
|
57341
|
+
if (mode === "tag" && parsed.tagGroups.length === 0) {
|
|
57342
|
+
mode = parsed.hasHeat ? "heat" : "branch";
|
|
57343
|
+
}
|
|
57344
|
+
if (mode === "heat" && !parsed.hasHeat) mode = "branch";
|
|
57345
|
+
return mode;
|
|
57346
|
+
}
|
|
57347
|
+
function drawFocusIcon(g, w, ink, cy) {
|
|
57348
|
+
const r = 4.5;
|
|
57349
|
+
const cx = w - r - 5;
|
|
57350
|
+
const fi = g.append("g").attr("class", "dgmo-treemap-focus").attr("data-export-ignore", "true");
|
|
57351
|
+
fi.append("rect").attr("x", cx - 9).attr("y", cy - 9).attr("width", 18).attr("height", 18).attr("fill", "transparent");
|
|
57352
|
+
fi.append("circle").attr("cx", cx).attr("cy", cy).attr("r", r).attr("fill", "none").attr("stroke", ink).attr("stroke-width", 1.25);
|
|
57353
|
+
fi.append("circle").attr("cx", cx).attr("cy", cy).attr("r", 1.4).attr("fill", ink);
|
|
57354
|
+
}
|
|
57355
|
+
function clamp3(x, lo, hi) {
|
|
57356
|
+
return Math.max(lo, Math.min(hi, x));
|
|
57357
|
+
}
|
|
57358
|
+
function clipLabel(s, maxWidth, fs) {
|
|
57359
|
+
if (measureText(s, fs) <= maxWidth) return s;
|
|
57360
|
+
let lo = 0;
|
|
57361
|
+
let hi = s.length;
|
|
57362
|
+
while (lo < hi) {
|
|
57363
|
+
const mid = Math.ceil((lo + hi) / 2);
|
|
57364
|
+
if (measureText(s.slice(0, mid) + "\u2026", fs) <= maxWidth) lo = mid;
|
|
57365
|
+
else hi = mid - 1;
|
|
57366
|
+
}
|
|
57367
|
+
return lo <= 0 ? "" : s.slice(0, lo) + "\u2026";
|
|
57368
|
+
}
|
|
57369
|
+
function compactNumber2(v) {
|
|
57370
|
+
const abs = Math.abs(v);
|
|
57371
|
+
if (abs >= 1e9) return strip(v / 1e9) + "B";
|
|
57372
|
+
if (abs >= 1e6) return strip(v / 1e6) + "M";
|
|
57373
|
+
if (abs >= 1e3) return strip(v / 1e3) + "k";
|
|
57374
|
+
return strip(Math.round(v * 100) / 100);
|
|
57375
|
+
}
|
|
57376
|
+
function strip(n) {
|
|
57377
|
+
return parseFloat(
|
|
57378
|
+
n.toFixed(n < 10 && !Number.isInteger(n) ? 1 : 0)
|
|
57379
|
+
).toString();
|
|
57380
|
+
}
|
|
57381
|
+
function formatPct(frac) {
|
|
57382
|
+
const pct = frac * 100;
|
|
57383
|
+
if (pct >= 10) return `${Math.round(pct)}%`;
|
|
57384
|
+
if (pct >= 1) return `${pct.toFixed(0)}%`;
|
|
57385
|
+
return `${pct.toFixed(1)}%`;
|
|
57386
|
+
}
|
|
57387
|
+
var PADDING3, HEADER_H, TITLE_BAND, MUTED_FILL, LEAF_MUTE_PCT, LEGEND_POSITION;
|
|
57388
|
+
var init_renderer19 = __esm({
|
|
57389
|
+
"src/treemap/renderer.ts"() {
|
|
57390
|
+
"use strict";
|
|
57391
|
+
init_fonts();
|
|
57392
|
+
init_colors();
|
|
57393
|
+
init_color_utils();
|
|
57394
|
+
init_tag_groups();
|
|
57395
|
+
init_text_measure();
|
|
57396
|
+
init_legend_integration();
|
|
57397
|
+
init_legend_layout();
|
|
57398
|
+
init_legend_constants();
|
|
57399
|
+
init_title_constants();
|
|
57400
|
+
init_layout16();
|
|
57401
|
+
PADDING3 = 12;
|
|
57402
|
+
HEADER_H = 18;
|
|
57403
|
+
TITLE_BAND = 36;
|
|
57404
|
+
MUTED_FILL = "#cbd5e1";
|
|
57405
|
+
LEAF_MUTE_PCT = 50;
|
|
57406
|
+
LEGEND_POSITION = {
|
|
57407
|
+
placement: "top-center",
|
|
57408
|
+
titleRelation: "below-title"
|
|
57409
|
+
};
|
|
57410
|
+
}
|
|
57411
|
+
});
|
|
57412
|
+
|
|
57413
|
+
// src/raci/renderer.ts
|
|
57414
|
+
var renderer_exports20 = {};
|
|
57415
|
+
__export(renderer_exports20, {
|
|
56509
57416
|
MARKER_LABELS: () => MARKER_LABELS,
|
|
56510
57417
|
renderRaci: () => renderRaci,
|
|
56511
57418
|
renderRaciForExport: () => renderRaciForExport
|
|
56512
57419
|
});
|
|
56513
|
-
import * as
|
|
57420
|
+
import * as d3Selection27 from "d3-selection";
|
|
56514
57421
|
function groupDiagnosticsByTask(parsed) {
|
|
56515
57422
|
const map = /* @__PURE__ */ new Map();
|
|
56516
57423
|
if (parsed.diagnostics.length === 0) return map;
|
|
@@ -56582,7 +57489,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
|
|
|
56582
57489
|
const hideLegend = opts.hideLegend ?? false;
|
|
56583
57490
|
const collapsedPhases = opts.collapsedPhases ?? /* @__PURE__ */ new Set();
|
|
56584
57491
|
const hideTitle = (opts.hideTitle ?? false) || parsed.options["no-title"] === "on";
|
|
56585
|
-
|
|
57492
|
+
d3Selection27.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
56586
57493
|
const width = exportDims?.width ?? container.clientWidth;
|
|
56587
57494
|
const height = exportDims?.height ?? container.clientHeight;
|
|
56588
57495
|
if (width <= 0 || height <= 0) return;
|
|
@@ -56689,7 +57596,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
|
|
|
56689
57596
|
const colBottomY = cursorY + sColumnBottomPad;
|
|
56690
57597
|
const totalHeight = colBottomY + sVMargin;
|
|
56691
57598
|
const svgHeight = exportDims ? totalHeight : Math.max(height, totalHeight);
|
|
56692
|
-
const svg =
|
|
57599
|
+
const svg = d3Selection27.select(container).append("svg").attr("xmlns", "http://www.w3.org/2000/svg").attr("width", width).attr("height", svgHeight).attr("viewBox", `0 0 ${width} ${svgHeight}`).attr("preserveAspectRatio", "xMidYMin meet").attr("font-family", FONT_FAMILY).style("background", "transparent");
|
|
56693
57600
|
if (ctx.isBelowFloor) {
|
|
56694
57601
|
svg.attr("width", "100%");
|
|
56695
57602
|
}
|
|
@@ -57170,13 +58077,13 @@ function parseQuotedSegments(message) {
|
|
|
57170
58077
|
return out;
|
|
57171
58078
|
}
|
|
57172
58079
|
var MARKER_LABELS, TITLE_AREA_HEIGHT4, H_MARGIN, V_MARGIN3, LEGEND_HEIGHT2, LEGEND_CHIP_GAP, LEGEND_CHIP_LABEL_MIN, LEGEND_LETTER_CHIP_W, TITLE_LEGEND_GAP, LEGEND_LABEL_FONT, LEGEND_LETTER_FONT, HEADER_HEIGHT5, ROW_HEIGHT, PHASE_HEIGHT, TASK_LABEL_MIN, TASK_LABEL_MAX, ROLE_COL_MIN, ROLE_COL_MAX, CELL_PAD, VIOLATION_LINE_HEIGHT, STACK_TOP_GAP, DESC_FONT, COLUMN_RADIUS3, COLUMN_INSET, COLUMN_BOTTOM_PAD, MARKER_FONT, MARKER_FONT_WEIGHT, LABEL_FONT2, ROLE_HEADER_FONT, PHASE_FONT, TINT_PCT, NODE_RADIUS3, AUTO_ACCENTS, SLICE_GAP, NAME_LINE_HEIGHT, DESC_LINE_HEIGHT9;
|
|
57173
|
-
var
|
|
58080
|
+
var init_renderer20 = __esm({
|
|
57174
58081
|
"src/raci/renderer.ts"() {
|
|
57175
58082
|
"use strict";
|
|
57176
58083
|
init_fonts();
|
|
57177
58084
|
init_title_constants();
|
|
57178
58085
|
init_color_utils();
|
|
57179
|
-
|
|
58086
|
+
init_parser27();
|
|
57180
58087
|
init_variants();
|
|
57181
58088
|
init_scaling();
|
|
57182
58089
|
init_text_measure();
|
|
@@ -57433,8 +58340,8 @@ var init_tag_resolution = __esm({
|
|
|
57433
58340
|
});
|
|
57434
58341
|
|
|
57435
58342
|
// src/sequence/renderer.ts
|
|
57436
|
-
var
|
|
57437
|
-
__export(
|
|
58343
|
+
var renderer_exports21 = {};
|
|
58344
|
+
__export(renderer_exports21, {
|
|
57438
58345
|
applyGroupOrdering: () => applyGroupOrdering,
|
|
57439
58346
|
applyPositionOverrides: () => applyPositionOverrides,
|
|
57440
58347
|
buildNoteMessageMap: () => buildNoteMessageMap,
|
|
@@ -57445,7 +58352,7 @@ __export(renderer_exports20, {
|
|
|
57445
58352
|
renderSequenceDiagram: () => renderSequenceDiagram,
|
|
57446
58353
|
truncateBareUrl: () => truncateBareUrl
|
|
57447
58354
|
});
|
|
57448
|
-
import * as
|
|
58355
|
+
import * as d3Selection28 from "d3-selection";
|
|
57449
58356
|
function wrapTextLines(text, maxWidth, fontSize) {
|
|
57450
58357
|
const rawLines = text.split("\n").map((l) => l.startsWith("- ") ? "\u2022 " + l.slice(2) : l);
|
|
57451
58358
|
return wrapDescriptionLines(
|
|
@@ -57775,7 +58682,7 @@ function applyGroupOrdering(participants, groups, messages = []) {
|
|
|
57775
58682
|
return result;
|
|
57776
58683
|
}
|
|
57777
58684
|
function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateToLine, options) {
|
|
57778
|
-
|
|
58685
|
+
d3Selection28.select(container).selectAll("*").remove();
|
|
57779
58686
|
const { title, options: parsedOptions } = parsed;
|
|
57780
58687
|
const solid = parsedOptions["solid-fill"] === "on";
|
|
57781
58688
|
const effectiveCollapsedGroups = /* @__PURE__ */ new Set();
|
|
@@ -58426,7 +59333,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
58426
59333
|
offsetX = leftMargin + Math.max(0, (svgWidth - totalWidth) / 2);
|
|
58427
59334
|
buildParticipantX();
|
|
58428
59335
|
}
|
|
58429
|
-
const svg =
|
|
59336
|
+
const svg = d3Selection28.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);
|
|
58430
59337
|
const defs = svg.append("defs");
|
|
58431
59338
|
defs.append("marker").attr("id", "seq-arrowhead").attr("viewBox", `0 0 ${sArrowheadSize} ${sArrowheadSize}`).attr("refX", sArrowheadSize).attr("refY", sArrowheadSize / 2).attr("markerWidth", sArrowheadSize).attr("markerHeight", sArrowheadSize).attr("orient", "auto").append("polygon").attr(
|
|
58432
59339
|
"points",
|
|
@@ -59039,7 +59946,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
|
|
|
59039
59946
|
}
|
|
59040
59947
|
}
|
|
59041
59948
|
var PARTICIPANT_GAP, PARTICIPANT_BOX_WIDTH, PARTICIPANT_BOX_HEIGHT, LABEL_FONT_SIZE5, TOP_MARGIN, TITLE_HEIGHT8, PARTICIPANT_Y_OFFSET, MESSAGE_START_OFFSET, LIFELINE_TAIL, ARROWHEAD_SIZE, NOTE_MAX_W2, NOTE_FOLD2, NOTE_PAD_H2, NOTE_PAD_V2, NOTE_FONT_SIZE2, NOTE_LINE_H2, NOTE_GAP2, ACTIVATION_WIDTH, SELF_CALL_HEIGHT, SELF_CALL_WIDTH, ACTOR_LABEL_CLEARANCE, labelTextWidth, fill, stroke, SW, W, H;
|
|
59042
|
-
var
|
|
59949
|
+
var init_renderer21 = __esm({
|
|
59043
59950
|
"src/sequence/renderer.ts"() {
|
|
59044
59951
|
"use strict";
|
|
59045
59952
|
init_tag_groups();
|
|
@@ -62917,6 +63824,7 @@ var DIAGRAM_EXPORT_HANDLERS = {
|
|
|
62917
63824
|
map: exportMap,
|
|
62918
63825
|
pyramid: exportPyramid,
|
|
62919
63826
|
ring: exportRing,
|
|
63827
|
+
treemap: exportTreemap,
|
|
62920
63828
|
raci: exportRaci,
|
|
62921
63829
|
rasci: exportRaci,
|
|
62922
63830
|
daci: exportRaci,
|
|
@@ -62974,10 +63882,10 @@ async function exportOrg(ctx) {
|
|
|
62974
63882
|
false
|
|
62975
63883
|
// expandAllLegend off — collapsed-by-default per §1.3
|
|
62976
63884
|
);
|
|
62977
|
-
const
|
|
63885
|
+
const PADDING4 = 20;
|
|
62978
63886
|
const titleOffset = effectiveParsed.title ? 30 : 0;
|
|
62979
|
-
const exportWidth = orgLayout.width +
|
|
62980
|
-
const exportHeight = orgLayout.height +
|
|
63887
|
+
const exportWidth = orgLayout.width + PADDING4 * 2;
|
|
63888
|
+
const exportHeight = orgLayout.height + PADDING4 * 2 + titleOffset;
|
|
62981
63889
|
const container = createExportContainer(exportWidth, exportHeight);
|
|
62982
63890
|
renderOrg2(
|
|
62983
63891
|
container,
|
|
@@ -63019,10 +63927,10 @@ async function exportSitemap(ctx) {
|
|
|
63019
63927
|
hiddenAttributes,
|
|
63020
63928
|
true
|
|
63021
63929
|
);
|
|
63022
|
-
const
|
|
63930
|
+
const PADDING4 = 20;
|
|
63023
63931
|
const titleOffset = effectiveParsed.title ? 30 : 0;
|
|
63024
|
-
const exportWidth = sitemapLayout.width +
|
|
63025
|
-
const exportHeight = sitemapLayout.height +
|
|
63932
|
+
const exportWidth = sitemapLayout.width + PADDING4 * 2;
|
|
63933
|
+
const exportHeight = sitemapLayout.height + PADDING4 * 2 + titleOffset;
|
|
63026
63934
|
const container = createExportContainer(exportWidth, exportHeight);
|
|
63027
63935
|
renderSitemap2(
|
|
63028
63936
|
container,
|
|
@@ -63078,10 +63986,10 @@ async function exportClass(ctx) {
|
|
|
63078
63986
|
const classParsed = parseClassDiagram2(content, effectivePalette);
|
|
63079
63987
|
if (classParsed.error || classParsed.classes.length === 0) return "";
|
|
63080
63988
|
const classLayout = layoutClassDiagram2(classParsed);
|
|
63081
|
-
const
|
|
63989
|
+
const PADDING4 = 20;
|
|
63082
63990
|
const titleOffset = classParsed.title ? 40 : 0;
|
|
63083
|
-
const exportWidth = classLayout.width +
|
|
63084
|
-
const exportHeight = classLayout.height +
|
|
63991
|
+
const exportWidth = classLayout.width + PADDING4 * 2;
|
|
63992
|
+
const exportHeight = classLayout.height + PADDING4 * 2 + titleOffset;
|
|
63085
63993
|
const container = createExportContainer(exportWidth, exportHeight);
|
|
63086
63994
|
renderClassDiagram2(
|
|
63087
63995
|
container,
|
|
@@ -63105,10 +64013,10 @@ async function exportEr(ctx) {
|
|
|
63105
64013
|
const erParsed = parseERDiagram2(content, effectivePalette);
|
|
63106
64014
|
if (erParsed.error || erParsed.tables.length === 0) return "";
|
|
63107
64015
|
const erLayout = layoutERDiagram2(erParsed);
|
|
63108
|
-
const
|
|
64016
|
+
const PADDING4 = 20;
|
|
63109
64017
|
const titleOffset = erParsed.title ? 40 : 0;
|
|
63110
|
-
const exportWidth = erLayout.width +
|
|
63111
|
-
const exportHeight = erLayout.height +
|
|
64018
|
+
const exportWidth = erLayout.width + PADDING4 * 2;
|
|
64019
|
+
const exportHeight = erLayout.height + PADDING4 * 2 + titleOffset;
|
|
63112
64020
|
const container = createExportContainer(exportWidth, exportHeight);
|
|
63113
64021
|
renderERDiagram2(
|
|
63114
64022
|
container,
|
|
@@ -63144,10 +64052,10 @@ async function exportBoxesAndLines(ctx) {
|
|
|
63144
64052
|
const { renderBoxesAndLinesForExport: renderBoxesAndLinesForExport2 } = await Promise.resolve().then(() => (init_renderer6(), renderer_exports6));
|
|
63145
64053
|
const { layoutBoxesAndLines: layoutBoxesAndLines2 } = await Promise.resolve().then(() => (init_layout5(), layout_exports5));
|
|
63146
64054
|
const blLayout = await layoutBoxesAndLines2(blParsed);
|
|
63147
|
-
const
|
|
64055
|
+
const PADDING4 = 20;
|
|
63148
64056
|
const titleOffset = blParsed.title ? 40 : 0;
|
|
63149
|
-
const exportWidth = blLayout.width +
|
|
63150
|
-
const exportHeight = blLayout.height +
|
|
64057
|
+
const exportWidth = blLayout.width + PADDING4 * 2;
|
|
64058
|
+
const exportHeight = blLayout.height + PADDING4 * 2 + titleOffset;
|
|
63151
64059
|
const container = createExportContainer(exportWidth, exportHeight);
|
|
63152
64060
|
const blActiveTagGroup = ctxTagOverride(ctx);
|
|
63153
64061
|
renderBoxesAndLinesForExport2(
|
|
@@ -63194,10 +64102,10 @@ async function exportMindmap(ctx) {
|
|
|
63194
64102
|
activeTagGroup,
|
|
63195
64103
|
hideDescriptions
|
|
63196
64104
|
});
|
|
63197
|
-
const
|
|
64105
|
+
const PADDING4 = 20;
|
|
63198
64106
|
const titleOffset = effectiveParsed.title ? 30 : 0;
|
|
63199
|
-
const exportWidth = mmLayout.width +
|
|
63200
|
-
const exportHeight = mmLayout.height +
|
|
64107
|
+
const exportWidth = mmLayout.width + PADDING4 * 2;
|
|
64108
|
+
const exportHeight = mmLayout.height + PADDING4 * 2 + titleOffset;
|
|
63201
64109
|
const container = createExportContainer(exportWidth, exportHeight);
|
|
63202
64110
|
const colorByDepth = viewState?.cbd === true;
|
|
63203
64111
|
renderMindmap2(
|
|
@@ -63258,10 +64166,10 @@ async function exportC4(ctx) {
|
|
|
63258
64166
|
const c4Container = ctx.options?.c4Container ?? viewState?.c4c;
|
|
63259
64167
|
const c4Layout = c4Level === "deployment" ? layoutC4Deployment2(c4Parsed) : c4Level === "components" && c4System && c4Container ? layoutC4Components2(c4Parsed, c4System, c4Container) : c4Level === "containers" && c4System ? layoutC4Containers2(c4Parsed, c4System) : layoutC4Context2(c4Parsed);
|
|
63260
64168
|
if (c4Layout.nodes.length === 0) return "";
|
|
63261
|
-
const
|
|
64169
|
+
const PADDING4 = 20;
|
|
63262
64170
|
const titleOffset = c4Parsed.title ? 40 : 0;
|
|
63263
|
-
const exportWidth = c4Layout.width +
|
|
63264
|
-
const exportHeight = c4Layout.height +
|
|
64171
|
+
const exportWidth = c4Layout.width + PADDING4 * 2;
|
|
64172
|
+
const exportHeight = c4Layout.height + PADDING4 * 2 + titleOffset;
|
|
63265
64173
|
const container = createExportContainer(exportWidth, exportHeight);
|
|
63266
64174
|
const renderFn = c4Level === "deployment" || c4Level === "components" && c4System && c4Container || c4Level === "containers" && c4System ? renderC4Containers2 : renderC4Context2;
|
|
63267
64175
|
renderFn(
|
|
@@ -63577,30 +64485,44 @@ async function exportRing(ctx) {
|
|
|
63577
64485
|
const ringParsed = parseRing2(content);
|
|
63578
64486
|
if (ringParsed.error || ringParsed.layers.length === 0) return "";
|
|
63579
64487
|
const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
|
|
63580
|
-
renderRingForExport2(
|
|
64488
|
+
renderRingForExport2(container, ringParsed, effectivePalette, ctx.isDark, {
|
|
64489
|
+
width: EXPORT_WIDTH,
|
|
64490
|
+
height: EXPORT_HEIGHT
|
|
64491
|
+
});
|
|
64492
|
+
return finalizeSvgExport(container, theme, effectivePalette);
|
|
64493
|
+
}
|
|
64494
|
+
async function exportTreemap(ctx) {
|
|
64495
|
+
const { content, theme, palette } = ctx;
|
|
64496
|
+
const { parseTreemap: parseTreemap2 } = await Promise.resolve().then(() => (init_parser26(), parser_exports20));
|
|
64497
|
+
const { renderTreemapForExport: renderTreemapForExport2 } = await Promise.resolve().then(() => (init_renderer19(), renderer_exports19));
|
|
64498
|
+
const effectivePalette = await resolveExportPalette(theme, palette);
|
|
64499
|
+
const treemapParsed = parseTreemap2(content, effectivePalette);
|
|
64500
|
+
if (treemapParsed.error || treemapParsed.roots.length === 0) return "";
|
|
64501
|
+
const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
|
|
64502
|
+
renderTreemapForExport2(
|
|
63581
64503
|
container,
|
|
63582
|
-
|
|
64504
|
+
treemapParsed,
|
|
63583
64505
|
effectivePalette,
|
|
63584
64506
|
ctx.isDark,
|
|
63585
|
-
{
|
|
64507
|
+
{
|
|
64508
|
+
width: EXPORT_WIDTH,
|
|
64509
|
+
height: EXPORT_HEIGHT
|
|
64510
|
+
}
|
|
63586
64511
|
);
|
|
63587
64512
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
63588
64513
|
}
|
|
63589
64514
|
async function exportRaci(ctx) {
|
|
63590
64515
|
const { content, theme, palette } = ctx;
|
|
63591
|
-
const { parseRaci: parseRaci2 } = await Promise.resolve().then(() => (
|
|
63592
|
-
const { renderRaciForExport: renderRaciForExport2 } = await Promise.resolve().then(() => (
|
|
64516
|
+
const { parseRaci: parseRaci2 } = await Promise.resolve().then(() => (init_parser27(), parser_exports21));
|
|
64517
|
+
const { renderRaciForExport: renderRaciForExport2 } = await Promise.resolve().then(() => (init_renderer20(), renderer_exports20));
|
|
63593
64518
|
const effectivePalette = await resolveExportPalette(theme, palette);
|
|
63594
64519
|
const raciParsed = parseRaci2(content, effectivePalette);
|
|
63595
64520
|
if (raciParsed.error) return "";
|
|
63596
64521
|
const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
|
|
63597
|
-
renderRaciForExport2(
|
|
63598
|
-
|
|
63599
|
-
|
|
63600
|
-
|
|
63601
|
-
ctx.isDark,
|
|
63602
|
-
{ width: EXPORT_WIDTH, height: EXPORT_HEIGHT }
|
|
63603
|
-
);
|
|
64522
|
+
renderRaciForExport2(container, raciParsed, effectivePalette, ctx.isDark, {
|
|
64523
|
+
width: EXPORT_WIDTH,
|
|
64524
|
+
height: EXPORT_HEIGHT
|
|
64525
|
+
});
|
|
63604
64526
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
63605
64527
|
}
|
|
63606
64528
|
function beginVizExport() {
|
|
@@ -63689,14 +64611,7 @@ async function exportVenn(ctx) {
|
|
|
63689
64611
|
if (parsed.error || parsed.vennSets.length < 2) return "";
|
|
63690
64612
|
const effectivePalette = await resolveExportPalette(theme, palette);
|
|
63691
64613
|
const { container, dims } = beginVizExport();
|
|
63692
|
-
renderVenn(
|
|
63693
|
-
container,
|
|
63694
|
-
parsed,
|
|
63695
|
-
effectivePalette,
|
|
63696
|
-
ctx.isDark,
|
|
63697
|
-
void 0,
|
|
63698
|
-
dims
|
|
63699
|
-
);
|
|
64614
|
+
renderVenn(container, parsed, effectivePalette, ctx.isDark, void 0, dims);
|
|
63700
64615
|
return finalizeSvgExport(container, theme, effectivePalette);
|
|
63701
64616
|
}
|
|
63702
64617
|
async function exportQuadrant(ctx) {
|
|
@@ -63730,7 +64645,7 @@ async function exportVisualization(ctx) {
|
|
|
63730
64645
|
const isDark = ctx.isDark;
|
|
63731
64646
|
const container = createExportContainer(EXPORT_WIDTH, EXPORT_HEIGHT);
|
|
63732
64647
|
const { parseSequenceDgmo: parseSequenceDgmo2 } = await Promise.resolve().then(() => (init_parser7(), parser_exports));
|
|
63733
|
-
const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (
|
|
64648
|
+
const { renderSequenceDiagram: renderSequenceDiagram2 } = await Promise.resolve().then(() => (init_renderer21(), renderer_exports21));
|
|
63734
64649
|
const seqParsed = parseSequenceDgmo2(content, effectivePalette);
|
|
63735
64650
|
if (seqParsed.error || seqParsed.participants.length === 0) return "";
|
|
63736
64651
|
const collapsedSections = viewState?.cs ? new Set(viewState.cs) : void 0;
|