@diagrammo/dgmo 0.8.8 → 0.8.10
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/AGENTS.md +3 -0
- package/dist/cli.cjs +181 -179
- package/dist/index.cjs +1425 -933
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +147 -1
- package/dist/index.d.ts +147 -1
- package/dist/index.js +1421 -933
- package/dist/index.js.map +1 -1
- package/docs/language-reference.md +28 -2
- package/gallery/fixtures/sitemap-full.dgmo +1 -0
- package/package.json +1 -1
- package/src/boxes-and-lines/layout.ts +48 -8
- package/src/boxes-and-lines/parser.ts +59 -13
- package/src/boxes-and-lines/renderer.ts +33 -137
- package/src/c4/renderer.ts +25 -138
- package/src/class/renderer.ts +185 -186
- package/src/d3.ts +114 -191
- package/src/echarts.ts +99 -214
- package/src/er/renderer.ts +52 -245
- package/src/gantt/renderer.ts +140 -182
- package/src/index.ts +21 -1
- package/src/infra/renderer.ts +91 -244
- package/src/kanban/renderer.ts +22 -129
- package/src/org/renderer.ts +103 -170
- package/src/render.ts +39 -9
- package/src/sequence/renderer.ts +31 -151
- package/src/sitemap/layout.ts +180 -38
- package/src/sitemap/parser.ts +64 -23
- package/src/sitemap/renderer.ts +73 -161
- package/src/utils/legend-constants.ts +6 -0
- package/src/utils/legend-d3.ts +400 -0
- package/src/utils/legend-layout.ts +495 -0
- package/src/utils/legend-svg.ts +26 -0
- package/src/utils/legend-types.ts +169 -0
package/dist/index.cjs
CHANGED
|
@@ -1923,6 +1923,493 @@ var init_legend_constants = __esm({
|
|
|
1923
1923
|
}
|
|
1924
1924
|
});
|
|
1925
1925
|
|
|
1926
|
+
// src/utils/legend-layout.ts
|
|
1927
|
+
function pillWidth(name) {
|
|
1928
|
+
return measureLegendText(name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
1929
|
+
}
|
|
1930
|
+
function entriesWidth(entries) {
|
|
1931
|
+
let w = 0;
|
|
1932
|
+
for (const e of entries) {
|
|
1933
|
+
w += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(e.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
1934
|
+
}
|
|
1935
|
+
return w;
|
|
1936
|
+
}
|
|
1937
|
+
function entryWidth(value) {
|
|
1938
|
+
return LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
1939
|
+
}
|
|
1940
|
+
function controlWidth(control) {
|
|
1941
|
+
let w = CONTROL_PILL_PAD;
|
|
1942
|
+
if (control.label) {
|
|
1943
|
+
w += measureLegendText(control.label, CONTROL_FONT_SIZE);
|
|
1944
|
+
if (control.icon) w += CONTROL_ICON_GAP;
|
|
1945
|
+
}
|
|
1946
|
+
if (control.icon) w += 14;
|
|
1947
|
+
if (control.children) {
|
|
1948
|
+
for (const child of control.children) {
|
|
1949
|
+
w += measureLegendText(child.label, CONTROL_FONT_SIZE) + 12;
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
return w;
|
|
1953
|
+
}
|
|
1954
|
+
function capsuleWidth(name, entries, containerWidth, addonWidth = 0) {
|
|
1955
|
+
const pw = pillWidth(name);
|
|
1956
|
+
const maxCapsuleW = containerWidth;
|
|
1957
|
+
const baseW = LEGEND_CAPSULE_PAD * 2 + pw + 4 + addonWidth;
|
|
1958
|
+
const ew = entriesWidth(entries);
|
|
1959
|
+
const singleRowW = baseW + ew;
|
|
1960
|
+
if (singleRowW <= maxCapsuleW) {
|
|
1961
|
+
return {
|
|
1962
|
+
width: singleRowW,
|
|
1963
|
+
entryRows: 1,
|
|
1964
|
+
moreCount: 0,
|
|
1965
|
+
visibleEntries: entries.length
|
|
1966
|
+
};
|
|
1967
|
+
}
|
|
1968
|
+
const rowWidth = maxCapsuleW - LEGEND_CAPSULE_PAD * 2;
|
|
1969
|
+
let row = 1;
|
|
1970
|
+
let rowX = pw + 4;
|
|
1971
|
+
let visible = 0;
|
|
1972
|
+
for (let i = 0; i < entries.length; i++) {
|
|
1973
|
+
const ew2 = entryWidth(entries[i].value);
|
|
1974
|
+
if (rowX + ew2 > rowWidth && rowX > pw + 4) {
|
|
1975
|
+
row++;
|
|
1976
|
+
rowX = 0;
|
|
1977
|
+
if (row > LEGEND_MAX_ENTRY_ROWS) {
|
|
1978
|
+
return {
|
|
1979
|
+
width: maxCapsuleW,
|
|
1980
|
+
entryRows: LEGEND_MAX_ENTRY_ROWS,
|
|
1981
|
+
moreCount: entries.length - visible,
|
|
1982
|
+
visibleEntries: visible
|
|
1983
|
+
};
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
rowX += ew2;
|
|
1987
|
+
visible++;
|
|
1988
|
+
}
|
|
1989
|
+
return {
|
|
1990
|
+
width: maxCapsuleW,
|
|
1991
|
+
entryRows: row,
|
|
1992
|
+
moreCount: 0,
|
|
1993
|
+
visibleEntries: entries.length
|
|
1994
|
+
};
|
|
1995
|
+
}
|
|
1996
|
+
function computeLegendLayout(config, state, containerWidth) {
|
|
1997
|
+
const { groups, controls: configControls, mode } = config;
|
|
1998
|
+
const isExport = mode === "inline";
|
|
1999
|
+
const activeGroupName = state.activeGroup?.toLowerCase() ?? null;
|
|
2000
|
+
if (isExport && !activeGroupName) {
|
|
2001
|
+
return {
|
|
2002
|
+
height: 0,
|
|
2003
|
+
width: 0,
|
|
2004
|
+
rows: [],
|
|
2005
|
+
controls: [],
|
|
2006
|
+
pills: [],
|
|
2007
|
+
activeCapsule: void 0
|
|
2008
|
+
};
|
|
2009
|
+
}
|
|
2010
|
+
const visibleGroups = config.showEmptyGroups ? groups : groups.filter((g) => g.entries.length > 0);
|
|
2011
|
+
if (visibleGroups.length === 0 && (!configControls || configControls.length === 0)) {
|
|
2012
|
+
return {
|
|
2013
|
+
height: 0,
|
|
2014
|
+
width: 0,
|
|
2015
|
+
rows: [],
|
|
2016
|
+
controls: [],
|
|
2017
|
+
pills: [],
|
|
2018
|
+
activeCapsule: void 0
|
|
2019
|
+
};
|
|
2020
|
+
}
|
|
2021
|
+
const controlLayouts = [];
|
|
2022
|
+
let totalControlsW = 0;
|
|
2023
|
+
if (configControls && !isExport) {
|
|
2024
|
+
for (const ctrl of configControls) {
|
|
2025
|
+
const w = controlWidth(ctrl);
|
|
2026
|
+
controlLayouts.push({
|
|
2027
|
+
id: ctrl.id,
|
|
2028
|
+
x: 0,
|
|
2029
|
+
// positioned later
|
|
2030
|
+
y: 0,
|
|
2031
|
+
width: w,
|
|
2032
|
+
height: LEGEND_HEIGHT,
|
|
2033
|
+
icon: ctrl.icon,
|
|
2034
|
+
label: ctrl.label,
|
|
2035
|
+
exportBehavior: ctrl.exportBehavior,
|
|
2036
|
+
children: ctrl.children?.map((c) => ({
|
|
2037
|
+
id: c.id,
|
|
2038
|
+
label: c.label,
|
|
2039
|
+
x: 0,
|
|
2040
|
+
y: 0,
|
|
2041
|
+
width: measureLegendText(c.label, CONTROL_FONT_SIZE) + 12,
|
|
2042
|
+
isActive: c.isActive
|
|
2043
|
+
}))
|
|
2044
|
+
});
|
|
2045
|
+
totalControlsW += w + CONTROL_GAP;
|
|
2046
|
+
}
|
|
2047
|
+
if (totalControlsW > 0) totalControlsW -= CONTROL_GAP;
|
|
2048
|
+
} else if (configControls && isExport) {
|
|
2049
|
+
for (const ctrl of configControls) {
|
|
2050
|
+
if (ctrl.exportBehavior === "strip") continue;
|
|
2051
|
+
const w = controlWidth(ctrl);
|
|
2052
|
+
controlLayouts.push({
|
|
2053
|
+
id: ctrl.id,
|
|
2054
|
+
x: 0,
|
|
2055
|
+
y: 0,
|
|
2056
|
+
width: w,
|
|
2057
|
+
height: LEGEND_HEIGHT,
|
|
2058
|
+
icon: ctrl.icon,
|
|
2059
|
+
label: ctrl.label,
|
|
2060
|
+
exportBehavior: ctrl.exportBehavior,
|
|
2061
|
+
children: ctrl.children?.map((c) => ({
|
|
2062
|
+
id: c.id,
|
|
2063
|
+
label: c.label,
|
|
2064
|
+
x: 0,
|
|
2065
|
+
y: 0,
|
|
2066
|
+
width: measureLegendText(c.label, CONTROL_FONT_SIZE) + 12,
|
|
2067
|
+
isActive: c.isActive
|
|
2068
|
+
}))
|
|
2069
|
+
});
|
|
2070
|
+
totalControlsW += w + CONTROL_GAP;
|
|
2071
|
+
}
|
|
2072
|
+
if (totalControlsW > 0) totalControlsW -= CONTROL_GAP;
|
|
2073
|
+
}
|
|
2074
|
+
const controlsSpace = totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0;
|
|
2075
|
+
const groupAvailW = containerWidth - controlsSpace;
|
|
2076
|
+
const pills = [];
|
|
2077
|
+
let activeCapsule;
|
|
2078
|
+
for (const g of visibleGroups) {
|
|
2079
|
+
const isActive = activeGroupName === g.name.toLowerCase();
|
|
2080
|
+
if (isExport && !isActive) continue;
|
|
2081
|
+
if (isActive) {
|
|
2082
|
+
activeCapsule = buildCapsuleLayout(
|
|
2083
|
+
g,
|
|
2084
|
+
containerWidth,
|
|
2085
|
+
config.capsulePillAddonWidth ?? 0
|
|
2086
|
+
);
|
|
2087
|
+
} else {
|
|
2088
|
+
const pw = pillWidth(g.name);
|
|
2089
|
+
pills.push({
|
|
2090
|
+
groupName: g.name,
|
|
2091
|
+
x: 0,
|
|
2092
|
+
y: 0,
|
|
2093
|
+
width: pw,
|
|
2094
|
+
height: LEGEND_HEIGHT,
|
|
2095
|
+
isActive: false
|
|
2096
|
+
});
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
const rows = layoutRows(
|
|
2100
|
+
activeCapsule,
|
|
2101
|
+
pills,
|
|
2102
|
+
controlLayouts,
|
|
2103
|
+
groupAvailW,
|
|
2104
|
+
containerWidth,
|
|
2105
|
+
totalControlsW
|
|
2106
|
+
);
|
|
2107
|
+
const height = rows.length * LEGEND_HEIGHT;
|
|
2108
|
+
const width = containerWidth;
|
|
2109
|
+
return {
|
|
2110
|
+
height,
|
|
2111
|
+
width,
|
|
2112
|
+
rows,
|
|
2113
|
+
activeCapsule,
|
|
2114
|
+
controls: controlLayouts,
|
|
2115
|
+
pills
|
|
2116
|
+
};
|
|
2117
|
+
}
|
|
2118
|
+
function buildCapsuleLayout(group, containerWidth, addonWidth = 0) {
|
|
2119
|
+
const pw = pillWidth(group.name);
|
|
2120
|
+
const info = capsuleWidth(
|
|
2121
|
+
group.name,
|
|
2122
|
+
group.entries,
|
|
2123
|
+
containerWidth,
|
|
2124
|
+
addonWidth
|
|
2125
|
+
);
|
|
2126
|
+
const pill = {
|
|
2127
|
+
groupName: group.name,
|
|
2128
|
+
x: LEGEND_CAPSULE_PAD,
|
|
2129
|
+
y: LEGEND_CAPSULE_PAD,
|
|
2130
|
+
width: pw,
|
|
2131
|
+
height: LEGEND_HEIGHT - LEGEND_CAPSULE_PAD * 2,
|
|
2132
|
+
isActive: true
|
|
2133
|
+
};
|
|
2134
|
+
const entries = [];
|
|
2135
|
+
let ex = LEGEND_CAPSULE_PAD + pw + 4 + addonWidth;
|
|
2136
|
+
let ey = 0;
|
|
2137
|
+
let rowX = ex;
|
|
2138
|
+
const maxRowW = containerWidth - LEGEND_CAPSULE_PAD * 2;
|
|
2139
|
+
let currentRow = 0;
|
|
2140
|
+
for (let i = 0; i < info.visibleEntries; i++) {
|
|
2141
|
+
const entry = group.entries[i];
|
|
2142
|
+
const ew = entryWidth(entry.value);
|
|
2143
|
+
if (rowX + ew > maxRowW && rowX > ex && i > 0) {
|
|
2144
|
+
currentRow++;
|
|
2145
|
+
rowX = 0;
|
|
2146
|
+
ey = currentRow * LEGEND_HEIGHT;
|
|
2147
|
+
if (currentRow === 0) ex = LEGEND_CAPSULE_PAD + pw + 4;
|
|
2148
|
+
}
|
|
2149
|
+
const dotCx = rowX + LEGEND_DOT_R;
|
|
2150
|
+
const dotCy = ey + LEGEND_HEIGHT / 2;
|
|
2151
|
+
const textX = rowX + LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP;
|
|
2152
|
+
const textY = ey + LEGEND_HEIGHT / 2;
|
|
2153
|
+
entries.push({
|
|
2154
|
+
value: entry.value,
|
|
2155
|
+
color: entry.color,
|
|
2156
|
+
x: rowX,
|
|
2157
|
+
y: ey,
|
|
2158
|
+
dotCx,
|
|
2159
|
+
dotCy,
|
|
2160
|
+
textX,
|
|
2161
|
+
textY
|
|
2162
|
+
});
|
|
2163
|
+
rowX += ew;
|
|
2164
|
+
}
|
|
2165
|
+
const totalRows = info.entryRows;
|
|
2166
|
+
const capsuleH = totalRows * LEGEND_HEIGHT;
|
|
2167
|
+
return {
|
|
2168
|
+
groupName: group.name,
|
|
2169
|
+
x: 0,
|
|
2170
|
+
y: 0,
|
|
2171
|
+
width: info.width,
|
|
2172
|
+
height: capsuleH,
|
|
2173
|
+
pill,
|
|
2174
|
+
entries,
|
|
2175
|
+
moreCount: info.moreCount > 0 ? info.moreCount : void 0,
|
|
2176
|
+
addonX: addonWidth > 0 ? LEGEND_CAPSULE_PAD + pw + 4 : void 0
|
|
2177
|
+
};
|
|
2178
|
+
}
|
|
2179
|
+
function layoutRows(activeCapsule, pills, controls, groupAvailW, containerWidth, totalControlsW) {
|
|
2180
|
+
const rows = [];
|
|
2181
|
+
const groupItems = [];
|
|
2182
|
+
if (activeCapsule) groupItems.push(activeCapsule);
|
|
2183
|
+
groupItems.push(...pills);
|
|
2184
|
+
let currentRowItems = [];
|
|
2185
|
+
let currentRowW = 0;
|
|
2186
|
+
let rowY = 0;
|
|
2187
|
+
for (const item of groupItems) {
|
|
2188
|
+
const itemW = item.width + LEGEND_GROUP_GAP;
|
|
2189
|
+
if (currentRowW + item.width > groupAvailW && currentRowItems.length > 0) {
|
|
2190
|
+
centerRowItems(currentRowItems, containerWidth, totalControlsW);
|
|
2191
|
+
rows.push({ y: rowY, items: currentRowItems });
|
|
2192
|
+
rowY += LEGEND_HEIGHT;
|
|
2193
|
+
currentRowItems = [];
|
|
2194
|
+
currentRowW = 0;
|
|
2195
|
+
}
|
|
2196
|
+
item.x = currentRowW;
|
|
2197
|
+
item.y = rowY;
|
|
2198
|
+
currentRowItems.push(item);
|
|
2199
|
+
currentRowW += itemW;
|
|
2200
|
+
}
|
|
2201
|
+
if (controls.length > 0) {
|
|
2202
|
+
let cx = containerWidth;
|
|
2203
|
+
for (let i = controls.length - 1; i >= 0; i--) {
|
|
2204
|
+
cx -= controls[i].width;
|
|
2205
|
+
controls[i].x = cx;
|
|
2206
|
+
controls[i].y = 0;
|
|
2207
|
+
cx -= CONTROL_GAP;
|
|
2208
|
+
}
|
|
2209
|
+
if (rows.length > 0) {
|
|
2210
|
+
rows[0].items.push(...controls);
|
|
2211
|
+
} else if (currentRowItems.length > 0) {
|
|
2212
|
+
currentRowItems.push(...controls);
|
|
2213
|
+
} else {
|
|
2214
|
+
currentRowItems.push(...controls);
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
if (currentRowItems.length > 0) {
|
|
2218
|
+
centerRowItems(currentRowItems, containerWidth, totalControlsW);
|
|
2219
|
+
rows.push({ y: rowY, items: currentRowItems });
|
|
2220
|
+
}
|
|
2221
|
+
if (rows.length === 0) {
|
|
2222
|
+
rows.push({ y: 0, items: [] });
|
|
2223
|
+
}
|
|
2224
|
+
return rows;
|
|
2225
|
+
}
|
|
2226
|
+
function centerRowItems(items, containerWidth, totalControlsW) {
|
|
2227
|
+
const groupItems = items.filter((it) => "groupName" in it);
|
|
2228
|
+
if (groupItems.length === 0) return;
|
|
2229
|
+
const totalGroupW = groupItems.reduce((s, it) => s + it.width, 0) + (groupItems.length - 1) * LEGEND_GROUP_GAP;
|
|
2230
|
+
const availW = containerWidth - (totalControlsW > 0 ? totalControlsW + LEGEND_GROUP_GAP * 2 : 0);
|
|
2231
|
+
const offset = Math.max(0, (availW - totalGroupW) / 2);
|
|
2232
|
+
let x = offset;
|
|
2233
|
+
for (const item of groupItems) {
|
|
2234
|
+
item.x = x;
|
|
2235
|
+
x += item.width + LEGEND_GROUP_GAP;
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
function getLegendReservedHeight(config, state, containerWidth) {
|
|
2239
|
+
const layout = computeLegendLayout(config, state, containerWidth);
|
|
2240
|
+
return layout.height;
|
|
2241
|
+
}
|
|
2242
|
+
var LEGEND_MAX_ENTRY_ROWS, CONTROL_PILL_PAD, CONTROL_FONT_SIZE, CONTROL_ICON_GAP, CONTROL_GAP;
|
|
2243
|
+
var init_legend_layout = __esm({
|
|
2244
|
+
"src/utils/legend-layout.ts"() {
|
|
2245
|
+
"use strict";
|
|
2246
|
+
init_legend_constants();
|
|
2247
|
+
LEGEND_MAX_ENTRY_ROWS = 3;
|
|
2248
|
+
CONTROL_PILL_PAD = 16;
|
|
2249
|
+
CONTROL_FONT_SIZE = 11;
|
|
2250
|
+
CONTROL_ICON_GAP = 4;
|
|
2251
|
+
CONTROL_GAP = 8;
|
|
2252
|
+
}
|
|
2253
|
+
});
|
|
2254
|
+
|
|
2255
|
+
// src/utils/legend-d3.ts
|
|
2256
|
+
function renderLegendD3(container, config, state, palette, isDark, callbacks, containerWidth) {
|
|
2257
|
+
const width = containerWidth ?? parseFloat(container.attr("width") || "800");
|
|
2258
|
+
let currentState = { ...state };
|
|
2259
|
+
let currentLayout;
|
|
2260
|
+
const legendG = container.append("g").attr("class", "dgmo-legend");
|
|
2261
|
+
function render2() {
|
|
2262
|
+
currentLayout = computeLegendLayout(config, currentState, width);
|
|
2263
|
+
legendG.selectAll("*").remove();
|
|
2264
|
+
if (currentLayout.height === 0) return;
|
|
2265
|
+
if (currentState.activeGroup) {
|
|
2266
|
+
legendG.attr(
|
|
2267
|
+
"data-legend-active",
|
|
2268
|
+
currentState.activeGroup.toLowerCase()
|
|
2269
|
+
);
|
|
2270
|
+
} else {
|
|
2271
|
+
legendG.attr("data-legend-active", null);
|
|
2272
|
+
}
|
|
2273
|
+
const groupBg = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.surface, palette.bg, 30);
|
|
2274
|
+
const pillBorder = mix(palette.textMuted, palette.bg, 50);
|
|
2275
|
+
if (currentLayout.activeCapsule) {
|
|
2276
|
+
renderCapsule(
|
|
2277
|
+
legendG,
|
|
2278
|
+
currentLayout.activeCapsule,
|
|
2279
|
+
palette,
|
|
2280
|
+
groupBg,
|
|
2281
|
+
pillBorder,
|
|
2282
|
+
isDark,
|
|
2283
|
+
callbacks
|
|
2284
|
+
);
|
|
2285
|
+
}
|
|
2286
|
+
for (const pill of currentLayout.pills) {
|
|
2287
|
+
renderPill(legendG, pill, palette, groupBg, callbacks);
|
|
2288
|
+
}
|
|
2289
|
+
for (const ctrl of currentLayout.controls) {
|
|
2290
|
+
renderControl(
|
|
2291
|
+
legendG,
|
|
2292
|
+
ctrl,
|
|
2293
|
+
palette,
|
|
2294
|
+
groupBg,
|
|
2295
|
+
pillBorder,
|
|
2296
|
+
isDark,
|
|
2297
|
+
config.controls
|
|
2298
|
+
);
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
render2();
|
|
2302
|
+
return {
|
|
2303
|
+
setState(newState) {
|
|
2304
|
+
currentState = { ...newState };
|
|
2305
|
+
render2();
|
|
2306
|
+
},
|
|
2307
|
+
destroy() {
|
|
2308
|
+
legendG.remove();
|
|
2309
|
+
},
|
|
2310
|
+
getHeight() {
|
|
2311
|
+
return currentLayout?.height ?? 0;
|
|
2312
|
+
},
|
|
2313
|
+
getLayout() {
|
|
2314
|
+
return currentLayout;
|
|
2315
|
+
}
|
|
2316
|
+
};
|
|
2317
|
+
}
|
|
2318
|
+
function renderCapsule(parent, capsule, palette, groupBg, pillBorder, _isDark, callbacks) {
|
|
2319
|
+
const g = parent.append("g").attr("transform", `translate(${capsule.x},${capsule.y})`).attr("data-legend-group", capsule.groupName.toLowerCase()).style("cursor", "pointer");
|
|
2320
|
+
g.append("rect").attr("width", capsule.width).attr("height", capsule.height).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
2321
|
+
const pill = capsule.pill;
|
|
2322
|
+
g.append("rect").attr("x", pill.x).attr("y", pill.y).attr("width", pill.width).attr("height", pill.height).attr("rx", pill.height / 2).attr("fill", palette.bg);
|
|
2323
|
+
g.append("rect").attr("x", pill.x).attr("y", pill.y).attr("width", pill.width).attr("height", pill.height).attr("rx", pill.height / 2).attr("fill", "none").attr("stroke", pillBorder).attr("stroke-width", 0.75);
|
|
2324
|
+
g.append("text").attr("x", pill.x + pill.width / 2).attr("y", LEGEND_HEIGHT / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", 500).attr("fill", palette.text).attr("pointer-events", "none").attr("font-family", FONT_FAMILY).text(capsule.groupName);
|
|
2325
|
+
for (const entry of capsule.entries) {
|
|
2326
|
+
const entryG = g.append("g").attr("data-legend-entry", entry.value.toLowerCase()).attr("data-series-name", entry.value).style("cursor", "pointer");
|
|
2327
|
+
entryG.append("circle").attr("cx", entry.dotCx).attr("cy", entry.dotCy).attr("r", LEGEND_DOT_R).attr("fill", entry.color);
|
|
2328
|
+
entryG.append("text").attr("x", entry.textX).attr("y", entry.textY).attr("dominant-baseline", "central").attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).attr("font-family", FONT_FAMILY).text(entry.value);
|
|
2329
|
+
if (callbacks?.onEntryHover) {
|
|
2330
|
+
const groupName = capsule.groupName;
|
|
2331
|
+
const entryValue = entry.value;
|
|
2332
|
+
const onHover = callbacks.onEntryHover;
|
|
2333
|
+
entryG.on("mouseenter", () => onHover(groupName, entryValue)).on("mouseleave", () => onHover(groupName, null));
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
if (capsule.moreCount) {
|
|
2337
|
+
const lastEntry = capsule.entries[capsule.entries.length - 1];
|
|
2338
|
+
const moreX = lastEntry ? lastEntry.textX + measureLegendText(lastEntry.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_DOT_GAP * 2 : pill.x + pill.width + 8;
|
|
2339
|
+
const moreY = lastEntry?.textY ?? LEGEND_HEIGHT / 2;
|
|
2340
|
+
g.append("text").attr("x", moreX).attr("y", moreY).attr("dominant-baseline", "central").attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("font-style", "italic").attr("fill", palette.textMuted).attr("font-family", FONT_FAMILY).text(`+${capsule.moreCount} more`);
|
|
2341
|
+
}
|
|
2342
|
+
if (callbacks?.onGroupToggle) {
|
|
2343
|
+
const cb = callbacks.onGroupToggle;
|
|
2344
|
+
const name = capsule.groupName;
|
|
2345
|
+
g.on("click", () => cb(name));
|
|
2346
|
+
}
|
|
2347
|
+
if (callbacks?.onGroupRendered) {
|
|
2348
|
+
callbacks.onGroupRendered(capsule.groupName, g, true);
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
function renderPill(parent, pill, palette, groupBg, callbacks) {
|
|
2352
|
+
const g = parent.append("g").attr("transform", `translate(${pill.x},${pill.y})`).attr("data-legend-group", pill.groupName.toLowerCase()).style("cursor", "pointer");
|
|
2353
|
+
g.append("rect").attr("width", pill.width).attr("height", pill.height).attr("rx", pill.height / 2).attr("fill", groupBg);
|
|
2354
|
+
g.append("text").attr("x", pill.width / 2).attr("y", pill.height / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", 500).attr("fill", palette.textMuted).attr("pointer-events", "none").attr("font-family", FONT_FAMILY).text(pill.groupName);
|
|
2355
|
+
if (callbacks?.onGroupToggle) {
|
|
2356
|
+
const cb = callbacks.onGroupToggle;
|
|
2357
|
+
const name = pill.groupName;
|
|
2358
|
+
g.on("click", () => cb(name));
|
|
2359
|
+
}
|
|
2360
|
+
if (callbacks?.onGroupRendered) {
|
|
2361
|
+
callbacks.onGroupRendered(pill.groupName, g, false);
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
function renderControl(parent, ctrl, palette, _groupBg, pillBorder, _isDark, configControls) {
|
|
2365
|
+
const g = parent.append("g").attr("transform", `translate(${ctrl.x},${ctrl.y})`).attr("data-legend-control", ctrl.id).style("cursor", "pointer");
|
|
2366
|
+
if (ctrl.exportBehavior === "strip") {
|
|
2367
|
+
g.attr("data-export-ignore", "true");
|
|
2368
|
+
}
|
|
2369
|
+
g.append("rect").attr("width", ctrl.width).attr("height", ctrl.height).attr("rx", ctrl.height / 2).attr("fill", "none").attr("stroke", pillBorder).attr("stroke-width", 0.75);
|
|
2370
|
+
let textX = ctrl.width / 2;
|
|
2371
|
+
if (ctrl.icon && ctrl.label) {
|
|
2372
|
+
const iconG = g.append("g").attr("transform", `translate(8,${(ctrl.height - 14) / 2})`);
|
|
2373
|
+
iconG.html(ctrl.icon);
|
|
2374
|
+
textX = 8 + 14 + LEGEND_ENTRY_DOT_GAP + measureLegendText(ctrl.label, LEGEND_PILL_FONT_SIZE) / 2;
|
|
2375
|
+
}
|
|
2376
|
+
if (ctrl.label) {
|
|
2377
|
+
g.append("text").attr("x", textX).attr("y", ctrl.height / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", 500).attr("fill", palette.textMuted).attr("pointer-events", "none").attr("font-family", FONT_FAMILY).text(ctrl.label);
|
|
2378
|
+
}
|
|
2379
|
+
if (ctrl.children) {
|
|
2380
|
+
let cx = ctrl.width + 4;
|
|
2381
|
+
for (const child of ctrl.children) {
|
|
2382
|
+
const childG = g.append("g").attr("transform", `translate(${cx},0)`).style("cursor", "pointer");
|
|
2383
|
+
childG.append("rect").attr("width", child.width).attr("height", ctrl.height).attr("rx", ctrl.height / 2).attr(
|
|
2384
|
+
"fill",
|
|
2385
|
+
child.isActive ? palette.primary ?? palette.text : "none"
|
|
2386
|
+
).attr("stroke", pillBorder).attr("stroke-width", 0.75);
|
|
2387
|
+
childG.append("text").attr("x", child.width / 2).attr("y", ctrl.height / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", child.isActive ? palette.bg : palette.textMuted).attr("font-family", FONT_FAMILY).text(child.label);
|
|
2388
|
+
const configCtrl2 = configControls?.find((c) => c.id === ctrl.id);
|
|
2389
|
+
const configChild = configCtrl2?.children?.find((c) => c.id === child.id);
|
|
2390
|
+
if (configChild?.onClick) {
|
|
2391
|
+
const onClick = configChild.onClick;
|
|
2392
|
+
childG.on("click", () => onClick());
|
|
2393
|
+
}
|
|
2394
|
+
cx += child.width + 4;
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
const configCtrl = configControls?.find((c) => c.id === ctrl.id);
|
|
2398
|
+
if (configCtrl?.onClick) {
|
|
2399
|
+
const onClick = configCtrl.onClick;
|
|
2400
|
+
g.on("click", () => onClick());
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
var init_legend_d3 = __esm({
|
|
2404
|
+
"src/utils/legend-d3.ts"() {
|
|
2405
|
+
"use strict";
|
|
2406
|
+
init_legend_constants();
|
|
2407
|
+
init_legend_layout();
|
|
2408
|
+
init_color_utils();
|
|
2409
|
+
init_fonts();
|
|
2410
|
+
}
|
|
2411
|
+
});
|
|
2412
|
+
|
|
1926
2413
|
// src/utils/title-constants.ts
|
|
1927
2414
|
var TITLE_FONT_SIZE, TITLE_FONT_WEIGHT, TITLE_Y, TITLE_OFFSET;
|
|
1928
2415
|
var init_title_constants = __esm({
|
|
@@ -4852,10 +5339,10 @@ var init_chart = __esm({
|
|
|
4852
5339
|
function esc(s) {
|
|
4853
5340
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
4854
5341
|
}
|
|
4855
|
-
function
|
|
5342
|
+
function pillWidth2(name) {
|
|
4856
5343
|
return measureLegendText(name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
4857
5344
|
}
|
|
4858
|
-
function
|
|
5345
|
+
function entriesWidth2(entries) {
|
|
4859
5346
|
let w = 0;
|
|
4860
5347
|
for (const e of entries) {
|
|
4861
5348
|
w += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(e.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
@@ -4863,9 +5350,9 @@ function entriesWidth(entries) {
|
|
|
4863
5350
|
return w;
|
|
4864
5351
|
}
|
|
4865
5352
|
function groupTotalWidth(name, entries, isActive) {
|
|
4866
|
-
const pw =
|
|
5353
|
+
const pw = pillWidth2(name);
|
|
4867
5354
|
if (!isActive) return pw;
|
|
4868
|
-
return LEGEND_CAPSULE_PAD * 2 + pw + 4 +
|
|
5355
|
+
return LEGEND_CAPSULE_PAD * 2 + pw + 4 + entriesWidth2(entries);
|
|
4869
5356
|
}
|
|
4870
5357
|
function renderLegendSvg(groups, options) {
|
|
4871
5358
|
if (groups.length === 0) return { svg: "", height: 0, width: 0 };
|
|
@@ -4873,7 +5360,7 @@ function renderLegendSvg(groups, options) {
|
|
|
4873
5360
|
const groupBg = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.surface, palette.bg, 30);
|
|
4874
5361
|
const items = groups.filter((g) => g.entries.length > 0).map((g) => {
|
|
4875
5362
|
const isActive = !!activeGroup && g.name.toLowerCase() === activeGroup.toLowerCase();
|
|
4876
|
-
const pw =
|
|
5363
|
+
const pw = pillWidth2(g.name);
|
|
4877
5364
|
const tw = groupTotalWidth(g.name, g.entries, isActive);
|
|
4878
5365
|
return { group: g, isActive, pillWidth: pw, totalWidth: tw };
|
|
4879
5366
|
});
|
|
@@ -4927,6 +5414,19 @@ function renderLegendSvg(groups, options) {
|
|
|
4927
5414
|
const svg = `<g${classAttr}${activeAttr}>${parts.join("")}</g>`;
|
|
4928
5415
|
return { svg, height: LEGEND_HEIGHT, width: totalWidth };
|
|
4929
5416
|
}
|
|
5417
|
+
function renderLegendSvgFromConfig(config, state, palette, containerWidth) {
|
|
5418
|
+
return renderLegendSvg(config.groups, {
|
|
5419
|
+
palette: {
|
|
5420
|
+
bg: palette.bg,
|
|
5421
|
+
surface: palette.surface,
|
|
5422
|
+
text: palette.text,
|
|
5423
|
+
textMuted: palette.textMuted
|
|
5424
|
+
},
|
|
5425
|
+
isDark: palette.isDark,
|
|
5426
|
+
containerWidth,
|
|
5427
|
+
activeGroup: state.activeGroup
|
|
5428
|
+
});
|
|
5429
|
+
}
|
|
4930
5430
|
var init_legend_svg = __esm({
|
|
4931
5431
|
"src/utils/legend-svg.ts"() {
|
|
4932
5432
|
"use strict";
|
|
@@ -5355,52 +5855,26 @@ function buildChartCommons(parsed, palette, isDark) {
|
|
|
5355
5855
|
fontFamily: FONT_FAMILY
|
|
5356
5856
|
}
|
|
5357
5857
|
} : void 0;
|
|
5358
|
-
const tooltipTheme = {
|
|
5359
|
-
backgroundColor: palette.surface,
|
|
5360
|
-
borderColor: palette.border,
|
|
5361
|
-
textStyle: { color: palette.text }
|
|
5362
|
-
};
|
|
5363
5858
|
return {
|
|
5364
5859
|
textColor,
|
|
5365
5860
|
axisLineColor,
|
|
5366
5861
|
splitLineColor,
|
|
5367
5862
|
gridOpacity,
|
|
5368
5863
|
colors,
|
|
5369
|
-
titleConfig
|
|
5370
|
-
tooltipTheme
|
|
5864
|
+
titleConfig
|
|
5371
5865
|
};
|
|
5372
5866
|
}
|
|
5373
5867
|
function buildExtendedChartOption(parsed, palette, isDark) {
|
|
5374
5868
|
if (parsed.error) {
|
|
5375
5869
|
return {};
|
|
5376
5870
|
}
|
|
5377
|
-
const {
|
|
5378
|
-
textColor,
|
|
5379
|
-
axisLineColor,
|
|
5380
|
-
gridOpacity,
|
|
5381
|
-
colors,
|
|
5382
|
-
titleConfig,
|
|
5383
|
-
tooltipTheme
|
|
5384
|
-
} = buildChartCommons(parsed, palette, isDark);
|
|
5871
|
+
const { textColor, axisLineColor, gridOpacity, colors, titleConfig } = buildChartCommons(parsed, palette, isDark);
|
|
5385
5872
|
if (parsed.type === "sankey") {
|
|
5386
|
-
return buildSankeyOption(
|
|
5387
|
-
parsed,
|
|
5388
|
-
textColor,
|
|
5389
|
-
colors,
|
|
5390
|
-
titleConfig,
|
|
5391
|
-
tooltipTheme
|
|
5392
|
-
);
|
|
5873
|
+
return buildSankeyOption(parsed, textColor, colors, titleConfig);
|
|
5393
5874
|
}
|
|
5394
5875
|
if (parsed.type === "chord") {
|
|
5395
5876
|
const bg = isDark ? palette.surface : palette.bg;
|
|
5396
|
-
return buildChordOption(
|
|
5397
|
-
parsed,
|
|
5398
|
-
textColor,
|
|
5399
|
-
colors,
|
|
5400
|
-
bg,
|
|
5401
|
-
titleConfig,
|
|
5402
|
-
tooltipTheme
|
|
5403
|
-
);
|
|
5877
|
+
return buildChordOption(parsed, textColor, colors, bg, titleConfig);
|
|
5404
5878
|
}
|
|
5405
5879
|
if (parsed.type === "function") {
|
|
5406
5880
|
return buildFunctionOption(
|
|
@@ -5410,8 +5884,7 @@ function buildExtendedChartOption(parsed, palette, isDark) {
|
|
|
5410
5884
|
axisLineColor,
|
|
5411
5885
|
gridOpacity,
|
|
5412
5886
|
colors,
|
|
5413
|
-
titleConfig
|
|
5414
|
-
tooltipTheme
|
|
5887
|
+
titleConfig
|
|
5415
5888
|
);
|
|
5416
5889
|
}
|
|
5417
5890
|
if (parsed.type === "scatter") {
|
|
@@ -5424,20 +5897,12 @@ function buildExtendedChartOption(parsed, palette, isDark) {
|
|
|
5424
5897
|
gridOpacity,
|
|
5425
5898
|
colors,
|
|
5426
5899
|
bg,
|
|
5427
|
-
titleConfig
|
|
5428
|
-
tooltipTheme
|
|
5900
|
+
titleConfig
|
|
5429
5901
|
);
|
|
5430
5902
|
}
|
|
5431
5903
|
if (parsed.type === "funnel") {
|
|
5432
5904
|
const bg = isDark ? palette.surface : palette.bg;
|
|
5433
|
-
return buildFunnelOption(
|
|
5434
|
-
parsed,
|
|
5435
|
-
textColor,
|
|
5436
|
-
colors,
|
|
5437
|
-
bg,
|
|
5438
|
-
titleConfig,
|
|
5439
|
-
tooltipTheme
|
|
5440
|
-
);
|
|
5905
|
+
return buildFunnelOption(parsed, textColor, colors, bg, titleConfig);
|
|
5441
5906
|
}
|
|
5442
5907
|
return buildHeatmapOption(
|
|
5443
5908
|
parsed,
|
|
@@ -5445,11 +5910,10 @@ function buildExtendedChartOption(parsed, palette, isDark) {
|
|
|
5445
5910
|
isDark,
|
|
5446
5911
|
textColor,
|
|
5447
5912
|
axisLineColor,
|
|
5448
|
-
titleConfig
|
|
5449
|
-
tooltipTheme
|
|
5913
|
+
titleConfig
|
|
5450
5914
|
);
|
|
5451
5915
|
}
|
|
5452
|
-
function buildSankeyOption(parsed, textColor, colors, titleConfig
|
|
5916
|
+
function buildSankeyOption(parsed, textColor, colors, titleConfig) {
|
|
5453
5917
|
const nodeSet = /* @__PURE__ */ new Set();
|
|
5454
5918
|
if (parsed.links) {
|
|
5455
5919
|
for (const link of parsed.links) {
|
|
@@ -5468,17 +5932,15 @@ function buildSankeyOption(parsed, textColor, colors, titleConfig, tooltipTheme)
|
|
|
5468
5932
|
title: titleConfig,
|
|
5469
5933
|
xAxis: { show: false },
|
|
5470
5934
|
yAxis: { show: false },
|
|
5471
|
-
tooltip: {
|
|
5472
|
-
show: false,
|
|
5473
|
-
...tooltipTheme
|
|
5474
|
-
},
|
|
5475
5935
|
series: [
|
|
5476
5936
|
{
|
|
5477
5937
|
type: "sankey",
|
|
5478
5938
|
emphasis: {
|
|
5479
5939
|
focus: "adjacency",
|
|
5480
|
-
blurScope: "global"
|
|
5940
|
+
blurScope: "global",
|
|
5941
|
+
itemStyle: { opacity: 1 }
|
|
5481
5942
|
},
|
|
5943
|
+
blur: BLUR_DIM,
|
|
5482
5944
|
nodeAlign: "left",
|
|
5483
5945
|
nodeGap: 12,
|
|
5484
5946
|
nodeWidth: 20,
|
|
@@ -5501,7 +5963,7 @@ function buildSankeyOption(parsed, textColor, colors, titleConfig, tooltipTheme)
|
|
|
5501
5963
|
]
|
|
5502
5964
|
};
|
|
5503
5965
|
}
|
|
5504
|
-
function buildChordOption(parsed, textColor, colors, bg, titleConfig
|
|
5966
|
+
function buildChordOption(parsed, textColor, colors, bg, titleConfig) {
|
|
5505
5967
|
const nodeSet = /* @__PURE__ */ new Set();
|
|
5506
5968
|
if (parsed.links) {
|
|
5507
5969
|
for (const link of parsed.links) {
|
|
@@ -5535,17 +5997,6 @@ function buildChordOption(parsed, textColor, colors, bg, titleConfig, tooltipThe
|
|
|
5535
5997
|
return {
|
|
5536
5998
|
...CHART_BASE,
|
|
5537
5999
|
title: titleConfig,
|
|
5538
|
-
tooltip: {
|
|
5539
|
-
trigger: "item",
|
|
5540
|
-
...tooltipTheme,
|
|
5541
|
-
formatter: (params) => {
|
|
5542
|
-
const p = params;
|
|
5543
|
-
if (p.data && p.data.source && p.data.target) {
|
|
5544
|
-
return `${p.data.source} \u2192 ${p.data.target}: ${p.data.value}`;
|
|
5545
|
-
}
|
|
5546
|
-
return "";
|
|
5547
|
-
}
|
|
5548
|
-
},
|
|
5549
6000
|
xAxis: { show: false },
|
|
5550
6001
|
yAxis: { show: false },
|
|
5551
6002
|
series: [
|
|
@@ -5604,11 +6055,13 @@ function buildChordOption(parsed, textColor, colors, bg, titleConfig, tooltipThe
|
|
|
5604
6055
|
},
|
|
5605
6056
|
emphasis: {
|
|
5606
6057
|
focus: "adjacency",
|
|
6058
|
+
itemStyle: { opacity: 1 },
|
|
5607
6059
|
lineStyle: {
|
|
5608
6060
|
width: 5,
|
|
5609
6061
|
opacity: 1
|
|
5610
6062
|
}
|
|
5611
|
-
}
|
|
6063
|
+
},
|
|
6064
|
+
blur: BLUR_DIM
|
|
5612
6065
|
}
|
|
5613
6066
|
]
|
|
5614
6067
|
};
|
|
@@ -5622,7 +6075,7 @@ function evaluateExpression(expr, x) {
|
|
|
5622
6075
|
return NaN;
|
|
5623
6076
|
}
|
|
5624
6077
|
}
|
|
5625
|
-
function buildFunctionOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, titleConfig
|
|
6078
|
+
function buildFunctionOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, titleConfig) {
|
|
5626
6079
|
const xRange = parsed.xRange ?? { min: -10, max: 10 };
|
|
5627
6080
|
const samples = 200;
|
|
5628
6081
|
const step = (xRange.max - xRange.min) / samples;
|
|
@@ -5655,19 +6108,13 @@ function buildFunctionOption(parsed, palette, textColor, axisLineColor, gridOpac
|
|
|
5655
6108
|
opacity: 0.15
|
|
5656
6109
|
}
|
|
5657
6110
|
},
|
|
5658
|
-
emphasis: EMPHASIS_SELF
|
|
6111
|
+
emphasis: EMPHASIS_SELF,
|
|
6112
|
+
blur: BLUR_DIM
|
|
5659
6113
|
};
|
|
5660
6114
|
});
|
|
5661
6115
|
return {
|
|
5662
6116
|
...CHART_BASE,
|
|
5663
6117
|
title: titleConfig,
|
|
5664
|
-
tooltip: {
|
|
5665
|
-
trigger: "axis",
|
|
5666
|
-
...tooltipTheme,
|
|
5667
|
-
axisPointer: {
|
|
5668
|
-
type: "cross"
|
|
5669
|
-
}
|
|
5670
|
-
},
|
|
5671
6118
|
legend: {
|
|
5672
6119
|
data: (parsed.functions ?? []).map((fn) => fn.name),
|
|
5673
6120
|
bottom: 10,
|
|
@@ -5916,7 +6363,7 @@ function dataToPixel(dataX, dataY, xMin, xMax, yMin, yMax, gridLeftPct, gridRigh
|
|
|
5916
6363
|
const py = gridTopPx + (yMax - dataY) / (yMax - yMin) * plotHeight;
|
|
5917
6364
|
return { px, py };
|
|
5918
6365
|
}
|
|
5919
|
-
function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, bg, titleConfig
|
|
6366
|
+
function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpacity, colors, bg, titleConfig) {
|
|
5920
6367
|
const points = parsed.scatterPoints ?? [];
|
|
5921
6368
|
const defaultSize = 15;
|
|
5922
6369
|
const hasCategories = points.some((p) => p.category !== void 0);
|
|
@@ -5932,11 +6379,9 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
|
|
|
5932
6379
|
};
|
|
5933
6380
|
const emphasisConfig = {
|
|
5934
6381
|
focus: "self",
|
|
5935
|
-
itemStyle: {
|
|
5936
|
-
shadowBlur: 10,
|
|
5937
|
-
shadowColor: "rgba(0, 0, 0, 0.3)"
|
|
5938
|
-
}
|
|
6382
|
+
itemStyle: { opacity: 1 }
|
|
5939
6383
|
};
|
|
6384
|
+
const blurConfig = BLUR_DIM;
|
|
5940
6385
|
let series;
|
|
5941
6386
|
if (hasCategories) {
|
|
5942
6387
|
const categories2 = [
|
|
@@ -5967,7 +6412,8 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
|
|
|
5967
6412
|
borderWidth: CHART_BORDER_WIDTH
|
|
5968
6413
|
},
|
|
5969
6414
|
label: labelConfig,
|
|
5970
|
-
emphasis: emphasisConfig
|
|
6415
|
+
emphasis: emphasisConfig,
|
|
6416
|
+
blur: blurConfig
|
|
5971
6417
|
};
|
|
5972
6418
|
});
|
|
5973
6419
|
} else {
|
|
@@ -5989,24 +6435,11 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
|
|
|
5989
6435
|
type: "scatter",
|
|
5990
6436
|
data,
|
|
5991
6437
|
label: labelConfig,
|
|
5992
|
-
emphasis: emphasisConfig
|
|
6438
|
+
emphasis: emphasisConfig,
|
|
6439
|
+
blur: blurConfig
|
|
5993
6440
|
}
|
|
5994
6441
|
];
|
|
5995
6442
|
}
|
|
5996
|
-
const tooltip = {
|
|
5997
|
-
trigger: "item",
|
|
5998
|
-
...tooltipTheme,
|
|
5999
|
-
formatter: (params) => {
|
|
6000
|
-
const p = params;
|
|
6001
|
-
const xLabel = parsed.xlabel || "x";
|
|
6002
|
-
const yLabel = parsed.ylabel || "y";
|
|
6003
|
-
let html = `<strong>${p.name}</strong>`;
|
|
6004
|
-
if (hasCategories) html += `<br/>${p.seriesName}`;
|
|
6005
|
-
html += `<br/>${xLabel}: ${p.value[0]}<br/>${yLabel}: ${p.value[1]}`;
|
|
6006
|
-
if (hasSize) html += `<br/>${parsed.sizelabel || "size"}: ${p.value[2]}`;
|
|
6007
|
-
return html;
|
|
6008
|
-
}
|
|
6009
|
-
};
|
|
6010
6443
|
const xValues = points.map((p) => p.x);
|
|
6011
6444
|
const yValues = points.map((p) => p.y);
|
|
6012
6445
|
const xMin = Math.min(...xValues);
|
|
@@ -6087,7 +6520,6 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
|
|
|
6087
6520
|
...CHART_BASE,
|
|
6088
6521
|
title: titleConfig,
|
|
6089
6522
|
...legendConfig && { legend: legendConfig },
|
|
6090
|
-
tooltip,
|
|
6091
6523
|
grid: {
|
|
6092
6524
|
left: `${gridLeft}%`,
|
|
6093
6525
|
right: `${gridRight}%`,
|
|
@@ -6149,7 +6581,7 @@ function buildScatterOption(parsed, palette, textColor, axisLineColor, gridOpaci
|
|
|
6149
6581
|
...graphic && { graphic }
|
|
6150
6582
|
};
|
|
6151
6583
|
}
|
|
6152
|
-
function buildHeatmapOption(parsed, palette, isDark, textColor, axisLineColor, titleConfig
|
|
6584
|
+
function buildHeatmapOption(parsed, palette, isDark, textColor, axisLineColor, titleConfig) {
|
|
6153
6585
|
const bg = isDark ? palette.surface : palette.bg;
|
|
6154
6586
|
const heatmapRows = parsed.heatmapRows ?? [];
|
|
6155
6587
|
const columns = parsed.columns ?? [];
|
|
@@ -6167,16 +6599,6 @@ function buildHeatmapOption(parsed, palette, isDark, textColor, axisLineColor, t
|
|
|
6167
6599
|
return {
|
|
6168
6600
|
...CHART_BASE,
|
|
6169
6601
|
title: titleConfig,
|
|
6170
|
-
tooltip: {
|
|
6171
|
-
trigger: "item",
|
|
6172
|
-
...tooltipTheme,
|
|
6173
|
-
formatter: (params) => {
|
|
6174
|
-
const p = params;
|
|
6175
|
-
const colName = columns[p.data[0]] ?? p.data[0];
|
|
6176
|
-
const rowName = rowLabels[p.data[1]] ?? p.data[1];
|
|
6177
|
-
return `${rowName} / ${colName}: <strong>${p.data[2]}</strong>`;
|
|
6178
|
-
}
|
|
6179
|
-
},
|
|
6180
6602
|
grid: {
|
|
6181
6603
|
left: "3%",
|
|
6182
6604
|
right: "10%",
|
|
@@ -6246,19 +6668,15 @@ function buildHeatmapOption(parsed, palette, isDark, textColor, axisLineColor, t
|
|
|
6246
6668
|
fontWeight: "bold"
|
|
6247
6669
|
},
|
|
6248
6670
|
emphasis: {
|
|
6249
|
-
...EMPHASIS_SELF
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
shadowColor: "rgba(0, 0, 0, 0.5)"
|
|
6253
|
-
}
|
|
6254
|
-
}
|
|
6671
|
+
...EMPHASIS_SELF
|
|
6672
|
+
},
|
|
6673
|
+
blur: BLUR_DIM
|
|
6255
6674
|
}
|
|
6256
6675
|
]
|
|
6257
6676
|
};
|
|
6258
6677
|
}
|
|
6259
|
-
function buildFunnelOption(parsed, textColor, colors, bg, titleConfig
|
|
6678
|
+
function buildFunnelOption(parsed, textColor, colors, bg, titleConfig) {
|
|
6260
6679
|
const sorted = [...parsed.data].sort((a, b) => b.value - a.value);
|
|
6261
|
-
const topValue = sorted.length > 0 ? sorted[0].value : 1;
|
|
6262
6680
|
const data = sorted.map((d) => {
|
|
6263
6681
|
const stroke2 = d.color ?? colors[parsed.data.indexOf(d) % colors.length];
|
|
6264
6682
|
return {
|
|
@@ -6293,25 +6711,6 @@ function buildFunnelOption(parsed, textColor, colors, bg, titleConfig, tooltipTh
|
|
|
6293
6711
|
title: titleConfig,
|
|
6294
6712
|
xAxis: { show: false },
|
|
6295
6713
|
yAxis: { show: false },
|
|
6296
|
-
tooltip: {
|
|
6297
|
-
trigger: "item",
|
|
6298
|
-
...tooltipTheme,
|
|
6299
|
-
formatter: (params) => {
|
|
6300
|
-
const p = params;
|
|
6301
|
-
const val = p.value;
|
|
6302
|
-
const prev = prevValueMap.get(p.name) ?? val;
|
|
6303
|
-
const isFirst = p.dataIndex === 0;
|
|
6304
|
-
if (isFirst) return "";
|
|
6305
|
-
const parts = [];
|
|
6306
|
-
const stepDrop = ((1 - val / prev) * 100).toFixed(1);
|
|
6307
|
-
parts.push(`Step drop-off: ${stepDrop}%`);
|
|
6308
|
-
if (topValue > 0) {
|
|
6309
|
-
const totalDrop = ((1 - val / topValue) * 100).toFixed(1);
|
|
6310
|
-
parts.push(`Overall drop-off: ${totalDrop}%`);
|
|
6311
|
-
}
|
|
6312
|
-
return parts.join("<br/>");
|
|
6313
|
-
}
|
|
6314
|
-
},
|
|
6315
6714
|
series: [
|
|
6316
6715
|
{
|
|
6317
6716
|
type: "funnel",
|
|
@@ -6329,11 +6728,9 @@ function buildFunnelOption(parsed, textColor, colors, bg, titleConfig, tooltipTh
|
|
|
6329
6728
|
lineStyle: { color: textColor, opacity: 0.3 }
|
|
6330
6729
|
},
|
|
6331
6730
|
emphasis: {
|
|
6332
|
-
...EMPHASIS_SELF
|
|
6333
|
-
label: {
|
|
6334
|
-
fontSize: 15
|
|
6335
|
-
}
|
|
6731
|
+
...EMPHASIS_SELF
|
|
6336
6732
|
},
|
|
6733
|
+
blur: BLUR_DIM,
|
|
6337
6734
|
data
|
|
6338
6735
|
},
|
|
6339
6736
|
{
|
|
@@ -6427,8 +6824,7 @@ function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
|
|
|
6427
6824
|
splitLineColor,
|
|
6428
6825
|
gridOpacity,
|
|
6429
6826
|
colors,
|
|
6430
|
-
titleConfig
|
|
6431
|
-
tooltipTheme
|
|
6827
|
+
titleConfig
|
|
6432
6828
|
} = buildChartCommons(parsed, palette, isDark);
|
|
6433
6829
|
const bg = isDark ? palette.surface : palette.bg;
|
|
6434
6830
|
switch (parsed.type) {
|
|
@@ -6442,7 +6838,6 @@ function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
|
|
|
6442
6838
|
colors,
|
|
6443
6839
|
bg,
|
|
6444
6840
|
titleConfig,
|
|
6445
|
-
tooltipTheme,
|
|
6446
6841
|
chartWidth
|
|
6447
6842
|
);
|
|
6448
6843
|
case "bar-stacked":
|
|
@@ -6455,7 +6850,6 @@ function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
|
|
|
6455
6850
|
colors,
|
|
6456
6851
|
bg,
|
|
6457
6852
|
titleConfig,
|
|
6458
|
-
tooltipTheme,
|
|
6459
6853
|
chartWidth
|
|
6460
6854
|
);
|
|
6461
6855
|
case "line":
|
|
@@ -6468,7 +6862,6 @@ function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
|
|
|
6468
6862
|
gridOpacity,
|
|
6469
6863
|
colors,
|
|
6470
6864
|
titleConfig,
|
|
6471
|
-
tooltipTheme,
|
|
6472
6865
|
chartWidth
|
|
6473
6866
|
) : buildLineOption(
|
|
6474
6867
|
parsed,
|
|
@@ -6478,7 +6871,6 @@ function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
|
|
|
6478
6871
|
splitLineColor,
|
|
6479
6872
|
gridOpacity,
|
|
6480
6873
|
titleConfig,
|
|
6481
|
-
tooltipTheme,
|
|
6482
6874
|
chartWidth
|
|
6483
6875
|
);
|
|
6484
6876
|
case "area":
|
|
@@ -6490,7 +6882,6 @@ function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
|
|
|
6490
6882
|
splitLineColor,
|
|
6491
6883
|
gridOpacity,
|
|
6492
6884
|
titleConfig,
|
|
6493
|
-
tooltipTheme,
|
|
6494
6885
|
chartWidth
|
|
6495
6886
|
);
|
|
6496
6887
|
case "pie":
|
|
@@ -6500,7 +6891,6 @@ function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
|
|
|
6500
6891
|
getSegmentColors(palette, parsed.data.length),
|
|
6501
6892
|
bg,
|
|
6502
6893
|
titleConfig,
|
|
6503
|
-
tooltipTheme,
|
|
6504
6894
|
false
|
|
6505
6895
|
);
|
|
6506
6896
|
case "doughnut":
|
|
@@ -6510,7 +6900,6 @@ function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
|
|
|
6510
6900
|
getSegmentColors(palette, parsed.data.length),
|
|
6511
6901
|
bg,
|
|
6512
6902
|
titleConfig,
|
|
6513
|
-
tooltipTheme,
|
|
6514
6903
|
true
|
|
6515
6904
|
);
|
|
6516
6905
|
case "radar":
|
|
@@ -6520,8 +6909,7 @@ function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
|
|
|
6520
6909
|
isDark,
|
|
6521
6910
|
textColor,
|
|
6522
6911
|
gridOpacity,
|
|
6523
|
-
titleConfig
|
|
6524
|
-
tooltipTheme
|
|
6912
|
+
titleConfig
|
|
6525
6913
|
);
|
|
6526
6914
|
case "polar-area":
|
|
6527
6915
|
return buildPolarAreaOption(
|
|
@@ -6529,21 +6917,36 @@ function buildSimpleChartOption(parsed, palette, isDark, chartWidth) {
|
|
|
6529
6917
|
textColor,
|
|
6530
6918
|
getSegmentColors(palette, parsed.data.length),
|
|
6531
6919
|
bg,
|
|
6532
|
-
titleConfig
|
|
6533
|
-
tooltipTheme
|
|
6920
|
+
titleConfig
|
|
6534
6921
|
);
|
|
6535
6922
|
}
|
|
6536
6923
|
}
|
|
6537
6924
|
function makeChartGrid(options) {
|
|
6925
|
+
const left = options.yLabel ? "12%" : "3%";
|
|
6538
6926
|
return {
|
|
6539
|
-
left
|
|
6927
|
+
left,
|
|
6540
6928
|
right: "4%",
|
|
6541
6929
|
bottom: options.hasLegend ? "15%" : options.xLabel ? "10%" : "3%",
|
|
6542
6930
|
top: options.hasTitle ? "15%" : "5%",
|
|
6543
6931
|
containLabel: true
|
|
6544
6932
|
};
|
|
6545
6933
|
}
|
|
6546
|
-
function
|
|
6934
|
+
function wrapLabel(text, maxChars) {
|
|
6935
|
+
const words = text.split(" ");
|
|
6936
|
+
const lines = [];
|
|
6937
|
+
let current = "";
|
|
6938
|
+
for (const word of words) {
|
|
6939
|
+
if (current && current.length + 1 + word.length > maxChars) {
|
|
6940
|
+
lines.push(current);
|
|
6941
|
+
current = word;
|
|
6942
|
+
} else {
|
|
6943
|
+
current = current ? current + " " + word : word;
|
|
6944
|
+
}
|
|
6945
|
+
}
|
|
6946
|
+
if (current) lines.push(current);
|
|
6947
|
+
return lines.join("\n");
|
|
6948
|
+
}
|
|
6949
|
+
function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig, chartWidth) {
|
|
6547
6950
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
6548
6951
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
6549
6952
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -6558,7 +6961,11 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOp
|
|
|
6558
6961
|
}
|
|
6559
6962
|
};
|
|
6560
6963
|
});
|
|
6561
|
-
const
|
|
6964
|
+
const catLabels = isHorizontal ? labels.map((l) => wrapLabel(l, 12)) : labels;
|
|
6965
|
+
const maxVisibleLen = Math.max(
|
|
6966
|
+
...catLabels.map((l) => Math.max(...l.split("\n").map((seg) => seg.length)))
|
|
6967
|
+
);
|
|
6968
|
+
const hCatGap = isHorizontal && yLabel ? Math.max(40, maxVisibleLen * 8 + 16) : void 0;
|
|
6562
6969
|
const categoryAxis = makeGridAxis(
|
|
6563
6970
|
"category",
|
|
6564
6971
|
textColor,
|
|
@@ -6566,29 +6973,38 @@ function buildBarOption(parsed, textColor, axisLineColor, splitLineColor, gridOp
|
|
|
6566
6973
|
splitLineColor,
|
|
6567
6974
|
gridOpacity,
|
|
6568
6975
|
isHorizontal ? yLabel : xLabel,
|
|
6569
|
-
|
|
6976
|
+
catLabels,
|
|
6570
6977
|
hCatGap,
|
|
6571
6978
|
!isHorizontal ? chartWidth : void 0
|
|
6572
6979
|
);
|
|
6980
|
+
const hValueGap = isHorizontal && xLabel ? 40 : void 0;
|
|
6573
6981
|
const valueAxis = makeGridAxis(
|
|
6574
6982
|
"value",
|
|
6575
6983
|
textColor,
|
|
6576
6984
|
axisLineColor,
|
|
6577
6985
|
splitLineColor,
|
|
6578
6986
|
gridOpacity,
|
|
6579
|
-
isHorizontal ? xLabel : yLabel
|
|
6987
|
+
isHorizontal ? xLabel : yLabel,
|
|
6988
|
+
void 0,
|
|
6989
|
+
hValueGap
|
|
6580
6990
|
);
|
|
6581
6991
|
return {
|
|
6582
6992
|
...CHART_BASE,
|
|
6583
6993
|
title: titleConfig,
|
|
6584
|
-
grid: makeChartGrid({
|
|
6994
|
+
grid: makeChartGrid({
|
|
6995
|
+
xLabel,
|
|
6996
|
+
yLabel,
|
|
6997
|
+
hasTitle: !!parsed.title,
|
|
6998
|
+
isHorizontal
|
|
6999
|
+
}),
|
|
6585
7000
|
xAxis: isHorizontal ? valueAxis : categoryAxis,
|
|
6586
|
-
yAxis: isHorizontal ? categoryAxis : valueAxis,
|
|
7001
|
+
yAxis: isHorizontal ? { ...categoryAxis, inverse: true } : valueAxis,
|
|
6587
7002
|
series: [
|
|
6588
7003
|
{
|
|
6589
7004
|
type: "bar",
|
|
6590
7005
|
data,
|
|
6591
|
-
emphasis: EMPHASIS_SELF
|
|
7006
|
+
emphasis: EMPHASIS_SELF,
|
|
7007
|
+
blur: BLUR_DIM
|
|
6592
7008
|
}
|
|
6593
7009
|
]
|
|
6594
7010
|
};
|
|
@@ -6605,7 +7021,7 @@ function buildMarkArea(eras, labels, textColor, defaultColor) {
|
|
|
6605
7021
|
if (eras.length === 0) return void 0;
|
|
6606
7022
|
return {
|
|
6607
7023
|
silent: false,
|
|
6608
|
-
tooltip: { show:
|
|
7024
|
+
tooltip: { show: false },
|
|
6609
7025
|
data: eras.map((era) => {
|
|
6610
7026
|
const startIdx = labels.indexOf(era.start);
|
|
6611
7027
|
const endIdx = labels.indexOf(era.end);
|
|
@@ -6628,7 +7044,7 @@ function buildMarkArea(eras, labels, textColor, defaultColor) {
|
|
|
6628
7044
|
})
|
|
6629
7045
|
};
|
|
6630
7046
|
}
|
|
6631
|
-
function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig,
|
|
7047
|
+
function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, chartWidth) {
|
|
6632
7048
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
6633
7049
|
const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
|
|
6634
7050
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -6639,11 +7055,6 @@ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineCol
|
|
|
6639
7055
|
return {
|
|
6640
7056
|
...CHART_BASE,
|
|
6641
7057
|
title: titleConfig,
|
|
6642
|
-
tooltip: {
|
|
6643
|
-
trigger: "axis",
|
|
6644
|
-
...tooltipTheme,
|
|
6645
|
-
axisPointer: { type: "line" }
|
|
6646
|
-
},
|
|
6647
7058
|
grid: makeChartGrid({ xLabel, yLabel, hasTitle: !!parsed.title }),
|
|
6648
7059
|
xAxis: makeGridAxis(
|
|
6649
7060
|
"category",
|
|
@@ -6674,12 +7085,13 @@ function buildLineOption(parsed, palette, textColor, axisLineColor, splitLineCol
|
|
|
6674
7085
|
lineStyle: { color: lineColor, width: 3 },
|
|
6675
7086
|
itemStyle: { color: lineColor },
|
|
6676
7087
|
emphasis: EMPHASIS_LINE,
|
|
7088
|
+
blur: BLUR_DIM,
|
|
6677
7089
|
...markArea && { markArea }
|
|
6678
7090
|
}
|
|
6679
7091
|
]
|
|
6680
7092
|
};
|
|
6681
7093
|
}
|
|
6682
|
-
function buildMultiLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig,
|
|
7094
|
+
function buildMultiLineOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, colors, titleConfig, chartWidth) {
|
|
6683
7095
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
6684
7096
|
const seriesNames = parsed.seriesNames ?? [];
|
|
6685
7097
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -6700,17 +7112,13 @@ function buildMultiLineOption(parsed, palette, textColor, axisLineColor, splitLi
|
|
|
6700
7112
|
lineStyle: { color, width: 3 },
|
|
6701
7113
|
itemStyle: { color },
|
|
6702
7114
|
emphasis: EMPHASIS_LINE,
|
|
7115
|
+
blur: BLUR_DIM,
|
|
6703
7116
|
...idx === 0 && markArea && { markArea }
|
|
6704
7117
|
};
|
|
6705
7118
|
});
|
|
6706
7119
|
return {
|
|
6707
7120
|
...CHART_BASE,
|
|
6708
7121
|
title: titleConfig,
|
|
6709
|
-
tooltip: {
|
|
6710
|
-
trigger: "axis",
|
|
6711
|
-
...tooltipTheme,
|
|
6712
|
-
axisPointer: { type: "line" }
|
|
6713
|
-
},
|
|
6714
7122
|
legend: {
|
|
6715
7123
|
data: seriesNames,
|
|
6716
7124
|
bottom: 10,
|
|
@@ -6745,7 +7153,7 @@ function buildMultiLineOption(parsed, palette, textColor, axisLineColor, splitLi
|
|
|
6745
7153
|
series
|
|
6746
7154
|
};
|
|
6747
7155
|
}
|
|
6748
|
-
function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig,
|
|
7156
|
+
function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineColor, gridOpacity, titleConfig, chartWidth) {
|
|
6749
7157
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
6750
7158
|
const lineColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
|
|
6751
7159
|
const labels = parsed.data.map((d) => d.label);
|
|
@@ -6756,11 +7164,6 @@ function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineCol
|
|
|
6756
7164
|
return {
|
|
6757
7165
|
...CHART_BASE,
|
|
6758
7166
|
title: titleConfig,
|
|
6759
|
-
tooltip: {
|
|
6760
|
-
trigger: "axis",
|
|
6761
|
-
...tooltipTheme,
|
|
6762
|
-
axisPointer: { type: "line" }
|
|
6763
|
-
},
|
|
6764
7167
|
grid: makeChartGrid({ xLabel, yLabel, hasTitle: !!parsed.title }),
|
|
6765
7168
|
xAxis: makeGridAxis(
|
|
6766
7169
|
"category",
|
|
@@ -6792,6 +7195,7 @@ function buildAreaOption(parsed, palette, textColor, axisLineColor, splitLineCol
|
|
|
6792
7195
|
itemStyle: { color: lineColor },
|
|
6793
7196
|
areaStyle: { opacity: 0.25 },
|
|
6794
7197
|
emphasis: EMPHASIS_LINE,
|
|
7198
|
+
blur: BLUR_DIM,
|
|
6795
7199
|
...markArea && { markArea }
|
|
6796
7200
|
}
|
|
6797
7201
|
]
|
|
@@ -6823,7 +7227,7 @@ function pieLabelLayout(parsed) {
|
|
|
6823
7227
|
if (maxLen > 18) return { outerRadius: 55, fontSize: 13 };
|
|
6824
7228
|
return { outerRadius: 70, fontSize: 14 };
|
|
6825
7229
|
}
|
|
6826
|
-
function buildPieOption(parsed, textColor, colors, bg, titleConfig,
|
|
7230
|
+
function buildPieOption(parsed, textColor, colors, bg, titleConfig, isDoughnut) {
|
|
6827
7231
|
const HIDE_AXES = { xAxis: { show: false }, yAxis: { show: false } };
|
|
6828
7232
|
const data = parsed.data.map((d, i) => {
|
|
6829
7233
|
const stroke2 = d.color ?? colors[i % colors.length];
|
|
@@ -6842,10 +7246,6 @@ function buildPieOption(parsed, textColor, colors, bg, titleConfig, tooltipTheme
|
|
|
6842
7246
|
...CHART_BASE,
|
|
6843
7247
|
...HIDE_AXES,
|
|
6844
7248
|
title: titleConfig,
|
|
6845
|
-
tooltip: {
|
|
6846
|
-
trigger: "item",
|
|
6847
|
-
...tooltipTheme
|
|
6848
|
-
},
|
|
6849
7249
|
series: [
|
|
6850
7250
|
{
|
|
6851
7251
|
type: "pie",
|
|
@@ -6859,12 +7259,13 @@ function buildPieOption(parsed, textColor, colors, bg, titleConfig, tooltipTheme
|
|
|
6859
7259
|
fontSize
|
|
6860
7260
|
},
|
|
6861
7261
|
labelLine: { show: true },
|
|
6862
|
-
emphasis: EMPHASIS_SELF
|
|
7262
|
+
emphasis: EMPHASIS_SELF,
|
|
7263
|
+
blur: BLUR_DIM
|
|
6863
7264
|
}
|
|
6864
7265
|
]
|
|
6865
7266
|
};
|
|
6866
7267
|
}
|
|
6867
|
-
function buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, titleConfig
|
|
7268
|
+
function buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, titleConfig) {
|
|
6868
7269
|
const bg = isDark ? palette.surface : palette.bg;
|
|
6869
7270
|
const radarColor = parsed.color ?? parsed.seriesNameColors?.[0] ?? palette.primary;
|
|
6870
7271
|
const values = parsed.data.map((d) => d.value);
|
|
@@ -6878,10 +7279,6 @@ function buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, title
|
|
|
6878
7279
|
title: titleConfig,
|
|
6879
7280
|
xAxis: { show: false },
|
|
6880
7281
|
yAxis: { show: false },
|
|
6881
|
-
tooltip: {
|
|
6882
|
-
trigger: "item",
|
|
6883
|
-
...tooltipTheme
|
|
6884
|
-
},
|
|
6885
7282
|
radar: {
|
|
6886
7283
|
indicator,
|
|
6887
7284
|
axisName: {
|
|
@@ -6918,12 +7315,13 @@ function buildRadarOption(parsed, palette, isDark, textColor, gridOpacity, title
|
|
|
6918
7315
|
}
|
|
6919
7316
|
}
|
|
6920
7317
|
],
|
|
6921
|
-
emphasis: EMPHASIS_SELF
|
|
7318
|
+
emphasis: EMPHASIS_SELF,
|
|
7319
|
+
blur: BLUR_DIM
|
|
6922
7320
|
}
|
|
6923
7321
|
]
|
|
6924
7322
|
};
|
|
6925
7323
|
}
|
|
6926
|
-
function buildPolarAreaOption(parsed, textColor, colors, bg, titleConfig
|
|
7324
|
+
function buildPolarAreaOption(parsed, textColor, colors, bg, titleConfig) {
|
|
6927
7325
|
const data = parsed.data.map((d, i) => {
|
|
6928
7326
|
const stroke2 = d.color ?? colors[i % colors.length];
|
|
6929
7327
|
return {
|
|
@@ -6941,10 +7339,6 @@ function buildPolarAreaOption(parsed, textColor, colors, bg, titleConfig, toolti
|
|
|
6941
7339
|
title: titleConfig,
|
|
6942
7340
|
xAxis: { show: false },
|
|
6943
7341
|
yAxis: { show: false },
|
|
6944
|
-
tooltip: {
|
|
6945
|
-
trigger: "item",
|
|
6946
|
-
...tooltipTheme
|
|
6947
|
-
},
|
|
6948
7342
|
series: [
|
|
6949
7343
|
{
|
|
6950
7344
|
type: "pie",
|
|
@@ -6962,12 +7356,13 @@ function buildPolarAreaOption(parsed, textColor, colors, bg, titleConfig, toolti
|
|
|
6962
7356
|
fontSize: pieLabelLayout(parsed).fontSize
|
|
6963
7357
|
},
|
|
6964
7358
|
labelLine: { show: true },
|
|
6965
|
-
emphasis: EMPHASIS_SELF
|
|
7359
|
+
emphasis: EMPHASIS_SELF,
|
|
7360
|
+
blur: BLUR_DIM
|
|
6966
7361
|
}
|
|
6967
7362
|
]
|
|
6968
7363
|
};
|
|
6969
7364
|
}
|
|
6970
|
-
function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig,
|
|
7365
|
+
function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor, gridOpacity, colors, bg, titleConfig, chartWidth) {
|
|
6971
7366
|
const { xLabel, yLabel } = resolveAxisLabels(parsed);
|
|
6972
7367
|
const isHorizontal = parsed.orientation === "horizontal";
|
|
6973
7368
|
const seriesNames = parsed.seriesNames ?? [];
|
|
@@ -6996,7 +7391,8 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
|
|
|
6996
7391
|
fontWeight: "bold",
|
|
6997
7392
|
fontFamily: FONT_FAMILY
|
|
6998
7393
|
},
|
|
6999
|
-
emphasis:
|
|
7394
|
+
emphasis: EMPHASIS_SERIES,
|
|
7395
|
+
blur: BLUR_DIM
|
|
7000
7396
|
};
|
|
7001
7397
|
});
|
|
7002
7398
|
const hCatGap = isHorizontal && yLabel ? Math.max(40, Math.max(...labels.map((l) => l.length)) * 8 + 16) : void 0;
|
|
@@ -7037,7 +7433,7 @@ function buildBarStackedOption(parsed, textColor, axisLineColor, splitLineColor,
|
|
|
7037
7433
|
hasLegend: true
|
|
7038
7434
|
}),
|
|
7039
7435
|
xAxis: isHorizontal ? valueAxis : categoryAxis,
|
|
7040
|
-
yAxis: isHorizontal ? categoryAxis : valueAxis,
|
|
7436
|
+
yAxis: isHorizontal ? { ...categoryAxis, inverse: true } : valueAxis,
|
|
7041
7437
|
series
|
|
7042
7438
|
};
|
|
7043
7439
|
}
|
|
@@ -7121,7 +7517,7 @@ async function renderExtendedChartForExport(content, theme, palette, options) {
|
|
|
7121
7517
|
chart.dispose();
|
|
7122
7518
|
}
|
|
7123
7519
|
}
|
|
7124
|
-
var echarts, EMPHASIS_SELF, EMPHASIS_LINE, CHART_BASE, CHART_BORDER_WIDTH, VALID_EXTENDED_TYPES, KNOWN_EXTENDED_OPTIONS, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
|
|
7520
|
+
var echarts, EMPHASIS_SELF, EMPHASIS_SERIES, BLUR_DIM, EMPHASIS_LINE, CHART_BASE, CHART_BORDER_WIDTH, VALID_EXTENDED_TYPES, KNOWN_EXTENDED_OPTIONS, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
|
|
7125
7521
|
var init_echarts = __esm({
|
|
7126
7522
|
"src/echarts.ts"() {
|
|
7127
7523
|
"use strict";
|
|
@@ -7136,20 +7532,22 @@ var init_echarts = __esm({
|
|
|
7136
7532
|
init_colors();
|
|
7137
7533
|
init_parsing();
|
|
7138
7534
|
init_chart();
|
|
7139
|
-
EMPHASIS_SELF = {
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
}
|
|
7535
|
+
EMPHASIS_SELF = {
|
|
7536
|
+
focus: "self",
|
|
7537
|
+
blurScope: "global",
|
|
7538
|
+
itemStyle: { opacity: 1 }
|
|
7539
|
+
};
|
|
7540
|
+
EMPHASIS_SERIES = {
|
|
7541
|
+
focus: "series",
|
|
7542
|
+
blurScope: "global",
|
|
7543
|
+
itemStyle: { opacity: 1 }
|
|
7149
7544
|
};
|
|
7545
|
+
BLUR_DIM = { itemStyle: { opacity: 0.15 }, lineStyle: { opacity: 0.15 } };
|
|
7546
|
+
EMPHASIS_LINE = { ...EMPHASIS_SELF };
|
|
7150
7547
|
CHART_BASE = {
|
|
7151
7548
|
backgroundColor: "transparent",
|
|
7152
|
-
animation: false
|
|
7549
|
+
animation: false,
|
|
7550
|
+
tooltip: { show: false }
|
|
7153
7551
|
};
|
|
7154
7552
|
CHART_BORDER_WIDTH = 2;
|
|
7155
7553
|
VALID_EXTENDED_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -8481,7 +8879,12 @@ __export(parser_exports7, {
|
|
|
8481
8879
|
function parseArrowLine(trimmed, palette) {
|
|
8482
8880
|
const bareMatch = trimmed.match(BARE_ARROW_RE);
|
|
8483
8881
|
if (bareMatch) {
|
|
8484
|
-
|
|
8882
|
+
const rawTarget = bareMatch[1].trim();
|
|
8883
|
+
const groupMatch = rawTarget.match(/^\[(.+)\]$/);
|
|
8884
|
+
return {
|
|
8885
|
+
target: groupMatch ? groupMatch[1].trim() : rawTarget,
|
|
8886
|
+
targetIsGroup: !!groupMatch
|
|
8887
|
+
};
|
|
8485
8888
|
}
|
|
8486
8889
|
const arrowMatch = trimmed.match(ARROW_RE);
|
|
8487
8890
|
if (arrowMatch) {
|
|
@@ -8490,8 +8893,14 @@ function parseArrowLine(trimmed, palette) {
|
|
|
8490
8893
|
if (label && !color) {
|
|
8491
8894
|
color = inferArrowColor(label);
|
|
8492
8895
|
}
|
|
8493
|
-
const
|
|
8494
|
-
|
|
8896
|
+
const rawTarget = arrowMatch[3].trim();
|
|
8897
|
+
const groupMatch = rawTarget.match(/^\[(.+)\]$/);
|
|
8898
|
+
return {
|
|
8899
|
+
label,
|
|
8900
|
+
color,
|
|
8901
|
+
target: groupMatch ? groupMatch[1].trim() : rawTarget,
|
|
8902
|
+
targetIsGroup: !!groupMatch
|
|
8903
|
+
};
|
|
8495
8904
|
}
|
|
8496
8905
|
return null;
|
|
8497
8906
|
}
|
|
@@ -8553,6 +8962,7 @@ function parseSitemap(content, palette) {
|
|
|
8553
8962
|
const aliasMap = /* @__PURE__ */ new Map();
|
|
8554
8963
|
const indentStack = [];
|
|
8555
8964
|
const labelToNode = /* @__PURE__ */ new Map();
|
|
8965
|
+
const labelToContainer = /* @__PURE__ */ new Map();
|
|
8556
8966
|
const deferredArrows = [];
|
|
8557
8967
|
for (let i = 0; i < lines.length; i++) {
|
|
8558
8968
|
const line10 = lines[i];
|
|
@@ -8654,6 +9064,7 @@ function parseSitemap(content, palette) {
|
|
|
8654
9064
|
deferredArrows.push({
|
|
8655
9065
|
sourceNode: source,
|
|
8656
9066
|
targetLabel: arrowInfo.target,
|
|
9067
|
+
targetIsGroup: arrowInfo.targetIsGroup,
|
|
8657
9068
|
label: arrowInfo.label,
|
|
8658
9069
|
color: arrowInfo.color,
|
|
8659
9070
|
lineNumber
|
|
@@ -8687,6 +9098,7 @@ function parseSitemap(content, palette) {
|
|
|
8687
9098
|
color
|
|
8688
9099
|
};
|
|
8689
9100
|
attachNode2(node, indent, indentStack, result);
|
|
9101
|
+
labelToContainer.set(label.toLowerCase(), node);
|
|
8690
9102
|
} else if (metadataMatch && indentStack.length > 0) {
|
|
8691
9103
|
const rawKey = metadataMatch[1].trim().toLowerCase();
|
|
8692
9104
|
const key = aliasMap.get(rawKey) ?? rawKey;
|
|
@@ -8727,22 +9139,41 @@ function parseSitemap(content, palette) {
|
|
|
8727
9139
|
}
|
|
8728
9140
|
for (const arrow of deferredArrows) {
|
|
8729
9141
|
const targetKey = arrow.targetLabel.toLowerCase();
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
9142
|
+
if (arrow.targetIsGroup) {
|
|
9143
|
+
const targetContainer = labelToContainer.get(targetKey);
|
|
9144
|
+
if (!targetContainer) {
|
|
9145
|
+
const allLabels = Array.from(labelToContainer.keys());
|
|
9146
|
+
let msg = `Group '[${arrow.targetLabel}]' not found`;
|
|
9147
|
+
const hint = suggest(targetKey, allLabels);
|
|
9148
|
+
if (hint) msg += `. ${hint}`;
|
|
9149
|
+
pushError(arrow.lineNumber, msg);
|
|
9150
|
+
continue;
|
|
9151
|
+
}
|
|
9152
|
+
result.edges.push({
|
|
9153
|
+
sourceId: arrow.sourceNode.id,
|
|
9154
|
+
targetId: targetContainer.id,
|
|
9155
|
+
label: arrow.label,
|
|
9156
|
+
color: arrow.color,
|
|
9157
|
+
lineNumber: arrow.lineNumber
|
|
9158
|
+
});
|
|
9159
|
+
} else {
|
|
9160
|
+
const targetNode = labelToNode.get(targetKey);
|
|
9161
|
+
if (!targetNode) {
|
|
9162
|
+
const allLabels = Array.from(labelToNode.keys());
|
|
9163
|
+
let msg = `Arrow target "${arrow.targetLabel}" not found`;
|
|
9164
|
+
const hint = suggest(targetKey, allLabels);
|
|
9165
|
+
if (hint) msg += `. ${hint}`;
|
|
9166
|
+
pushError(arrow.lineNumber, msg);
|
|
9167
|
+
continue;
|
|
9168
|
+
}
|
|
9169
|
+
result.edges.push({
|
|
9170
|
+
sourceId: arrow.sourceNode.id,
|
|
9171
|
+
targetId: targetNode.id,
|
|
9172
|
+
label: arrow.label,
|
|
9173
|
+
color: arrow.color,
|
|
9174
|
+
lineNumber: arrow.lineNumber
|
|
9175
|
+
});
|
|
8738
9176
|
}
|
|
8739
|
-
result.edges.push({
|
|
8740
|
-
sourceId: arrow.sourceNode.id,
|
|
8741
|
-
targetId: targetNode.id,
|
|
8742
|
-
label: arrow.label,
|
|
8743
|
-
color: arrow.color,
|
|
8744
|
-
lineNumber: arrow.lineNumber
|
|
8745
|
-
});
|
|
8746
9177
|
}
|
|
8747
9178
|
if (result.tagGroups.length > 0) {
|
|
8748
9179
|
const allNodes = [];
|
|
@@ -10456,6 +10887,7 @@ function parseBoxesAndLines(content) {
|
|
|
10456
10887
|
const nodeLabels = /* @__PURE__ */ new Set();
|
|
10457
10888
|
const groupLabels = /* @__PURE__ */ new Set();
|
|
10458
10889
|
let lastNodeLabel = null;
|
|
10890
|
+
let lastSourceIsGroup = false;
|
|
10459
10891
|
const groupStack = [];
|
|
10460
10892
|
let contentStarted = false;
|
|
10461
10893
|
let currentTagGroup = null;
|
|
@@ -10694,6 +11126,8 @@ function parseBoxesAndLines(content) {
|
|
|
10694
11126
|
};
|
|
10695
11127
|
groupLabels.add(label);
|
|
10696
11128
|
groupStack.push({ group, indent, depth: currentDepth });
|
|
11129
|
+
lastNodeLabel = label;
|
|
11130
|
+
lastSourceIsGroup = true;
|
|
10697
11131
|
continue;
|
|
10698
11132
|
}
|
|
10699
11133
|
if (trimmed.includes("->") || trimmed.includes("<->")) {
|
|
@@ -10711,7 +11145,8 @@ function parseBoxesAndLines(content) {
|
|
|
10711
11145
|
);
|
|
10712
11146
|
continue;
|
|
10713
11147
|
}
|
|
10714
|
-
|
|
11148
|
+
const sourcePrefix = lastSourceIsGroup ? `[${lastNodeLabel}]` : lastNodeLabel;
|
|
11149
|
+
edgeText = `${sourcePrefix} ${trimmed}`;
|
|
10715
11150
|
}
|
|
10716
11151
|
const edge = parseEdgeLine(
|
|
10717
11152
|
edgeText,
|
|
@@ -10734,6 +11169,7 @@ function parseBoxesAndLines(content) {
|
|
|
10734
11169
|
continue;
|
|
10735
11170
|
}
|
|
10736
11171
|
lastNodeLabel = node.label;
|
|
11172
|
+
lastSourceIsGroup = false;
|
|
10737
11173
|
const gs = currentGroupState();
|
|
10738
11174
|
const isGroupChild = gs && indent > gs.indent;
|
|
10739
11175
|
if (nodeLabels.has(node.label)) {
|
|
@@ -10761,14 +11197,42 @@ function parseBoxesAndLines(content) {
|
|
|
10761
11197
|
const gs = groupStack.pop();
|
|
10762
11198
|
result.groups.push(gs.group);
|
|
10763
11199
|
}
|
|
11200
|
+
const validEdges = [];
|
|
10764
11201
|
for (const edge of result.edges) {
|
|
10765
|
-
|
|
11202
|
+
let valid = true;
|
|
11203
|
+
if (edge.source.startsWith("__group_")) {
|
|
11204
|
+
const label = edge.source.slice("__group_".length);
|
|
11205
|
+
const found = [...groupLabels].some(
|
|
11206
|
+
(g) => g.toLowerCase() === label.toLowerCase()
|
|
11207
|
+
);
|
|
11208
|
+
if (!found) {
|
|
11209
|
+
result.diagnostics.push(
|
|
11210
|
+
makeDgmoError(edge.lineNumber, `Group '[${label}]' not found`)
|
|
11211
|
+
);
|
|
11212
|
+
valid = false;
|
|
11213
|
+
}
|
|
11214
|
+
} else {
|
|
10766
11215
|
ensureNode(edge.source, edge.lineNumber);
|
|
10767
11216
|
}
|
|
10768
|
-
if (
|
|
11217
|
+
if (edge.target.startsWith("__group_")) {
|
|
11218
|
+
const label = edge.target.slice("__group_".length);
|
|
11219
|
+
const found = [...groupLabels].some(
|
|
11220
|
+
(g) => g.toLowerCase() === label.toLowerCase()
|
|
11221
|
+
);
|
|
11222
|
+
if (!found) {
|
|
11223
|
+
result.diagnostics.push(
|
|
11224
|
+
makeDgmoError(edge.lineNumber, `Group '[${label}]' not found`)
|
|
11225
|
+
);
|
|
11226
|
+
valid = false;
|
|
11227
|
+
}
|
|
11228
|
+
} else {
|
|
10769
11229
|
ensureNode(edge.target, edge.lineNumber);
|
|
10770
11230
|
}
|
|
11231
|
+
if (valid) {
|
|
11232
|
+
validEdges.push(edge);
|
|
11233
|
+
}
|
|
10771
11234
|
}
|
|
11235
|
+
result.edges = validEdges;
|
|
10772
11236
|
if (result.tagGroups.length > 0) {
|
|
10773
11237
|
injectDefaultTagMetadata(result.nodes, result.tagGroups);
|
|
10774
11238
|
validateTagValues(result.nodes, result.tagGroups, pushWarning, suggest);
|
|
@@ -10797,10 +11261,14 @@ function parseNodeLine(trimmed, lineNum, aliasMap, _diagnostics) {
|
|
|
10797
11261
|
description
|
|
10798
11262
|
};
|
|
10799
11263
|
}
|
|
11264
|
+
function resolveEndpoint(name) {
|
|
11265
|
+
const m = name.match(/^\[(.+)\]$/);
|
|
11266
|
+
return m ? groupId2(m[1].trim()) : name;
|
|
11267
|
+
}
|
|
10800
11268
|
function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
10801
11269
|
const biLabeledMatch = trimmed.match(/^(.+?)\s*<-(.+)->\s*(.+)$/);
|
|
10802
11270
|
if (biLabeledMatch) {
|
|
10803
|
-
const source2 = biLabeledMatch[1].trim();
|
|
11271
|
+
const source2 = resolveEndpoint(biLabeledMatch[1].trim());
|
|
10804
11272
|
const label = biLabeledMatch[2].trim();
|
|
10805
11273
|
let rest2 = biLabeledMatch[3].trim();
|
|
10806
11274
|
let metadata2 = {};
|
|
@@ -10821,7 +11289,7 @@ function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
|
10821
11289
|
}
|
|
10822
11290
|
return {
|
|
10823
11291
|
source: source2,
|
|
10824
|
-
target: rest2,
|
|
11292
|
+
target: resolveEndpoint(rest2),
|
|
10825
11293
|
label: label || void 0,
|
|
10826
11294
|
bidirectional: true,
|
|
10827
11295
|
lineNumber: lineNum,
|
|
@@ -10830,7 +11298,7 @@ function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
|
10830
11298
|
}
|
|
10831
11299
|
const biIdx = trimmed.indexOf("<->");
|
|
10832
11300
|
if (biIdx >= 0) {
|
|
10833
|
-
const source2 = trimmed.slice(0, biIdx).trim();
|
|
11301
|
+
const source2 = resolveEndpoint(trimmed.slice(0, biIdx).trim());
|
|
10834
11302
|
let rest2 = trimmed.slice(biIdx + 3).trim();
|
|
10835
11303
|
let metadata2 = {};
|
|
10836
11304
|
const pipeIdx2 = rest2.indexOf("|");
|
|
@@ -10850,7 +11318,7 @@ function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
|
10850
11318
|
}
|
|
10851
11319
|
return {
|
|
10852
11320
|
source: source2,
|
|
10853
|
-
target: rest2,
|
|
11321
|
+
target: resolveEndpoint(rest2),
|
|
10854
11322
|
bidirectional: true,
|
|
10855
11323
|
lineNumber: lineNum,
|
|
10856
11324
|
metadata: metadata2
|
|
@@ -10858,7 +11326,7 @@ function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
|
10858
11326
|
}
|
|
10859
11327
|
const labeledMatch = trimmed.match(/^(.+?)\s+-(.+)->\s*(.+)$/);
|
|
10860
11328
|
if (labeledMatch) {
|
|
10861
|
-
const source2 = labeledMatch[1].trim();
|
|
11329
|
+
const source2 = resolveEndpoint(labeledMatch[1].trim());
|
|
10862
11330
|
const label = labeledMatch[2].trim();
|
|
10863
11331
|
let rest2 = labeledMatch[3].trim();
|
|
10864
11332
|
if (label) {
|
|
@@ -10880,7 +11348,7 @@ function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
|
10880
11348
|
}
|
|
10881
11349
|
return {
|
|
10882
11350
|
source: source2,
|
|
10883
|
-
target: rest2,
|
|
11351
|
+
target: resolveEndpoint(rest2),
|
|
10884
11352
|
label,
|
|
10885
11353
|
bidirectional: false,
|
|
10886
11354
|
lineNumber: lineNum,
|
|
@@ -10890,7 +11358,7 @@ function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
|
10890
11358
|
}
|
|
10891
11359
|
const arrowIdx = trimmed.indexOf("->");
|
|
10892
11360
|
if (arrowIdx < 0) return null;
|
|
10893
|
-
const source = trimmed.slice(0, arrowIdx).trim();
|
|
11361
|
+
const source = resolveEndpoint(trimmed.slice(0, arrowIdx).trim());
|
|
10894
11362
|
let rest = trimmed.slice(arrowIdx + 2).trim();
|
|
10895
11363
|
if (!source || !rest) {
|
|
10896
11364
|
diagnostics.push(
|
|
@@ -10911,7 +11379,7 @@ function parseEdgeLine(trimmed, lineNum, aliasMap, diagnostics) {
|
|
|
10911
11379
|
}
|
|
10912
11380
|
return {
|
|
10913
11381
|
source,
|
|
10914
|
-
target: rest,
|
|
11382
|
+
target: resolveEndpoint(rest),
|
|
10915
11383
|
bidirectional: false,
|
|
10916
11384
|
lineNumber: lineNum,
|
|
10917
11385
|
metadata
|
|
@@ -11225,14 +11693,14 @@ function computeLegendGroups(tagGroups, showEyeIcons, usedValuesByGroup) {
|
|
|
11225
11693
|
const usedValues = usedValuesByGroup?.get(group.name.toLowerCase());
|
|
11226
11694
|
const visibleEntries = usedValues ? group.entries.filter((e) => usedValues.has(e.value.toLowerCase())) : group.entries;
|
|
11227
11695
|
if (visibleEntries.length === 0) continue;
|
|
11228
|
-
const
|
|
11229
|
-
const minPillWidth =
|
|
11230
|
-
let
|
|
11696
|
+
const pillWidth3 = measureLegendText(group.name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD2;
|
|
11697
|
+
const minPillWidth = pillWidth3;
|
|
11698
|
+
let entriesWidth3 = 0;
|
|
11231
11699
|
for (const entry of visibleEntries) {
|
|
11232
|
-
|
|
11700
|
+
entriesWidth3 += LEGEND_DOT_R2 * 2 + LEGEND_ENTRY_DOT_GAP2 + measureLegendText(entry.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL2;
|
|
11233
11701
|
}
|
|
11234
11702
|
const eyeSpace = showEyeIcons ? LEGEND_EYE_SIZE2 + LEGEND_EYE_GAP2 : 0;
|
|
11235
|
-
const
|
|
11703
|
+
const capsuleWidth2 = LEGEND_CAPSULE_PAD2 * 2 + pillWidth3 + 4 + eyeSpace + entriesWidth3;
|
|
11236
11704
|
groups.push({
|
|
11237
11705
|
name: group.name,
|
|
11238
11706
|
alias: group.alias,
|
|
@@ -11242,7 +11710,7 @@ function computeLegendGroups(tagGroups, showEyeIcons, usedValuesByGroup) {
|
|
|
11242
11710
|
})),
|
|
11243
11711
|
x: 0,
|
|
11244
11712
|
y: 0,
|
|
11245
|
-
width:
|
|
11713
|
+
width: capsuleWidth2,
|
|
11246
11714
|
height: LEGEND_HEIGHT2,
|
|
11247
11715
|
minifiedWidth: minPillWidth,
|
|
11248
11716
|
minifiedHeight: LEGEND_HEIGHT2
|
|
@@ -12183,66 +12651,77 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
|
|
|
12183
12651
|
}
|
|
12184
12652
|
}
|
|
12185
12653
|
if (fixedLegend || legendOnly || exportDims && hasLegend) {
|
|
12186
|
-
const
|
|
12187
|
-
|
|
12188
|
-
|
|
12189
|
-
|
|
12190
|
-
|
|
12191
|
-
|
|
12192
|
-
|
|
12193
|
-
|
|
12194
|
-
|
|
12195
|
-
|
|
12196
|
-
|
|
12197
|
-
|
|
12198
|
-
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12202
|
-
|
|
12203
|
-
|
|
12204
|
-
|
|
12205
|
-
|
|
12654
|
+
const groups = layout.legend.map((g) => ({
|
|
12655
|
+
name: g.name,
|
|
12656
|
+
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
12657
|
+
}));
|
|
12658
|
+
const eyeAddonWidth = fixedLegend ? LEGEND_EYE_SIZE + LEGEND_EYE_GAP : 0;
|
|
12659
|
+
const legendParentBase = fixedLegend ? svg.append("g").attr("class", "org-legend-fixed").attr("transform", `translate(0, ${DIAGRAM_PADDING + titleReserve})`) : contentG.append("g");
|
|
12660
|
+
let legendHandle;
|
|
12661
|
+
if (legendOnly) {
|
|
12662
|
+
for (const lg of layout.legend) {
|
|
12663
|
+
const singleConfig = {
|
|
12664
|
+
groups: [
|
|
12665
|
+
{
|
|
12666
|
+
name: lg.name,
|
|
12667
|
+
entries: lg.entries.map((e) => ({
|
|
12668
|
+
value: e.value,
|
|
12669
|
+
color: e.color
|
|
12670
|
+
}))
|
|
12671
|
+
}
|
|
12672
|
+
],
|
|
12673
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
12674
|
+
mode: "fixed"
|
|
12675
|
+
};
|
|
12676
|
+
const singleState = { activeGroup: lg.name };
|
|
12677
|
+
const groupG = legendParentBase.append("g").attr("transform", `translate(${lg.x}, ${lg.y})`);
|
|
12678
|
+
renderLegendD3(
|
|
12679
|
+
groupG,
|
|
12680
|
+
singleConfig,
|
|
12681
|
+
singleState,
|
|
12682
|
+
palette,
|
|
12683
|
+
isDark,
|
|
12684
|
+
void 0,
|
|
12685
|
+
lg.width
|
|
12686
|
+
);
|
|
12687
|
+
groupG.selectAll("[data-legend-group]").classed("org-legend-group", true);
|
|
12688
|
+
}
|
|
12689
|
+
legendHandle = null;
|
|
12690
|
+
} else {
|
|
12691
|
+
const legendConfig = {
|
|
12692
|
+
groups,
|
|
12693
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
12694
|
+
mode: "fixed",
|
|
12695
|
+
capsulePillAddonWidth: eyeAddonWidth
|
|
12696
|
+
};
|
|
12697
|
+
const legendState = { activeGroup: activeTagGroup ?? null };
|
|
12698
|
+
legendHandle = renderLegendD3(
|
|
12699
|
+
legendParentBase,
|
|
12700
|
+
legendConfig,
|
|
12701
|
+
legendState,
|
|
12702
|
+
palette,
|
|
12703
|
+
isDark,
|
|
12704
|
+
void 0,
|
|
12705
|
+
fixedLegend ? width : layout.width
|
|
12706
|
+
);
|
|
12707
|
+
legendParentBase.selectAll("[data-legend-group]").classed("org-legend-group", true);
|
|
12206
12708
|
}
|
|
12207
|
-
|
|
12208
|
-
const
|
|
12209
|
-
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
const gX = fixedPositions?.get(group.name) ?? group.x;
|
|
12213
|
-
const gY = fixedPositions ? 0 : group.y;
|
|
12214
|
-
const gEl = legendParent.append("g").attr("transform", `translate(${gX}, ${gY})`).attr("class", "org-legend-group").attr("data-legend-group", group.name.toLowerCase()).style("cursor", legendOnly ? "default" : "pointer");
|
|
12215
|
-
if (isActive) {
|
|
12216
|
-
gEl.append("rect").attr("width", group.width).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
12217
|
-
}
|
|
12218
|
-
const pillXOff = isActive ? LEGEND_CAPSULE_PAD : 0;
|
|
12219
|
-
const pillYOff = LEGEND_CAPSULE_PAD;
|
|
12220
|
-
const pillH = LEGEND_HEIGHT - LEGEND_CAPSULE_PAD * 2;
|
|
12221
|
-
gEl.append("rect").attr("x", pillXOff).attr("y", pillYOff).attr("width", pillWidth2).attr("height", pillH).attr("rx", pillH / 2).attr("fill", isActive ? palette.bg : groupBg);
|
|
12222
|
-
if (isActive) {
|
|
12223
|
-
gEl.append("rect").attr("x", pillXOff).attr("y", pillYOff).attr("width", pillWidth2).attr("height", pillH).attr("rx", pillH / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
|
|
12224
|
-
}
|
|
12225
|
-
gEl.append("text").attr("x", pillXOff + pillWidth2 / 2).attr("y", LEGEND_HEIGHT / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", "500").attr("fill", isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(pillLabel);
|
|
12226
|
-
if (isActive && fixedLegend) {
|
|
12227
|
-
const groupKey = group.name.toLowerCase();
|
|
12709
|
+
if (fixedLegend && legendHandle) {
|
|
12710
|
+
const computedLayout = legendHandle.getLayout();
|
|
12711
|
+
if (computedLayout.activeCapsule?.addonX != null) {
|
|
12712
|
+
const capsule = computedLayout.activeCapsule;
|
|
12713
|
+
const groupKey = capsule.groupName.toLowerCase();
|
|
12228
12714
|
const isHidden = hiddenAttributes?.has(groupKey) ?? false;
|
|
12229
|
-
const
|
|
12230
|
-
|
|
12231
|
-
|
|
12232
|
-
|
|
12233
|
-
|
|
12234
|
-
|
|
12235
|
-
|
|
12236
|
-
|
|
12237
|
-
|
|
12238
|
-
|
|
12239
|
-
for (const entry of group.entries) {
|
|
12240
|
-
const entryG = gEl.append("g").attr("data-legend-entry", entry.value.toLowerCase()).style("cursor", "pointer");
|
|
12241
|
-
entryG.append("circle").attr("cx", entryX + LEGEND_DOT_R).attr("cy", LEGEND_HEIGHT / 2).attr("r", LEGEND_DOT_R).attr("fill", entry.color);
|
|
12242
|
-
const textX = entryX + LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP;
|
|
12243
|
-
const entryLabel = entry.value;
|
|
12244
|
-
entryG.append("text").attr("x", textX).attr("y", LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).text(entryLabel);
|
|
12245
|
-
entryX = textX + measureLegendText(entryLabel, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
12715
|
+
const activeGroupEl = legendParentBase.select(
|
|
12716
|
+
`[data-legend-group="${groupKey}"]`
|
|
12717
|
+
);
|
|
12718
|
+
if (!activeGroupEl.empty()) {
|
|
12719
|
+
const eyeX = capsule.addonX;
|
|
12720
|
+
const eyeY = (LEGEND_HEIGHT - LEGEND_EYE_SIZE) / 2;
|
|
12721
|
+
const hitPad = 6;
|
|
12722
|
+
const eyeG = activeGroupEl.append("g").attr("class", "org-legend-eye").attr("data-legend-visibility", groupKey).style("cursor", "pointer").attr("opacity", isHidden ? 0.4 : 0.7);
|
|
12723
|
+
eyeG.append("rect").attr("x", eyeX - hitPad).attr("y", eyeY - hitPad).attr("width", LEGEND_EYE_SIZE + hitPad * 2).attr("height", LEGEND_EYE_SIZE + hitPad * 2).attr("fill", "transparent").attr("pointer-events", "all");
|
|
12724
|
+
eyeG.append("path").attr("d", isHidden ? EYE_CLOSED_PATH : EYE_OPEN_PATH).attr("transform", `translate(${eyeX}, ${eyeY})`).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1.2).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
12246
12725
|
}
|
|
12247
12726
|
}
|
|
12248
12727
|
}
|
|
@@ -12277,6 +12756,7 @@ var init_renderer = __esm({
|
|
|
12277
12756
|
init_parser4();
|
|
12278
12757
|
init_layout();
|
|
12279
12758
|
init_legend_constants();
|
|
12759
|
+
init_legend_d3();
|
|
12280
12760
|
init_title_constants();
|
|
12281
12761
|
DIAGRAM_PADDING = 20;
|
|
12282
12762
|
MAX_SCALE = 3;
|
|
@@ -12305,6 +12785,17 @@ var layout_exports2 = {};
|
|
|
12305
12785
|
__export(layout_exports2, {
|
|
12306
12786
|
layoutSitemap: () => layoutSitemap
|
|
12307
12787
|
});
|
|
12788
|
+
function clipToRectBorder(cx, cy, w, h, tx, ty) {
|
|
12789
|
+
const dx = tx - cx;
|
|
12790
|
+
const dy = ty - cy;
|
|
12791
|
+
if (dx === 0 && dy === 0) return { x: cx, y: cy };
|
|
12792
|
+
const hw = w / 2;
|
|
12793
|
+
const hh = h / 2;
|
|
12794
|
+
const sx = dx !== 0 ? hw / Math.abs(dx) : Infinity;
|
|
12795
|
+
const sy = dy !== 0 ? hh / Math.abs(dy) : Infinity;
|
|
12796
|
+
const s = Math.min(sx, sy);
|
|
12797
|
+
return { x: cx + dx * s, y: cy + dy * s };
|
|
12798
|
+
}
|
|
12308
12799
|
function filterMetadata2(metadata, hiddenAttributes) {
|
|
12309
12800
|
if (!hiddenAttributes || hiddenAttributes.size === 0) return metadata;
|
|
12310
12801
|
const filtered = {};
|
|
@@ -12321,7 +12812,10 @@ function computeCardWidth2(label, meta) {
|
|
|
12321
12812
|
const lineChars = key.length + 2 + value.length;
|
|
12322
12813
|
if (lineChars > maxChars) maxChars = lineChars;
|
|
12323
12814
|
}
|
|
12324
|
-
return Math.max(
|
|
12815
|
+
return Math.max(
|
|
12816
|
+
MIN_CARD_WIDTH2,
|
|
12817
|
+
Math.ceil(maxChars * CHAR_WIDTH2) + CARD_H_PAD2 * 2
|
|
12818
|
+
);
|
|
12325
12819
|
}
|
|
12326
12820
|
function computeCardHeight2(meta) {
|
|
12327
12821
|
const metaCount = Object.keys(meta).length;
|
|
@@ -12330,7 +12824,12 @@ function computeCardHeight2(meta) {
|
|
|
12330
12824
|
}
|
|
12331
12825
|
function resolveNodeColor2(node, tagGroups, activeGroupName) {
|
|
12332
12826
|
if (node.color) return node.color;
|
|
12333
|
-
return resolveTagColor(
|
|
12827
|
+
return resolveTagColor(
|
|
12828
|
+
node.metadata,
|
|
12829
|
+
tagGroups,
|
|
12830
|
+
activeGroupName,
|
|
12831
|
+
node.isContainer
|
|
12832
|
+
);
|
|
12334
12833
|
}
|
|
12335
12834
|
function computeLegendGroups2(tagGroups, usedValuesByGroup) {
|
|
12336
12835
|
const groups = [];
|
|
@@ -12339,21 +12838,21 @@ function computeLegendGroups2(tagGroups, usedValuesByGroup) {
|
|
|
12339
12838
|
const usedValues = usedValuesByGroup?.get(group.name.toLowerCase());
|
|
12340
12839
|
const visibleEntries = usedValues ? group.entries.filter((e) => usedValues.has(e.value.toLowerCase())) : group.entries;
|
|
12341
12840
|
if (visibleEntries.length === 0) continue;
|
|
12342
|
-
const
|
|
12343
|
-
const minPillWidth =
|
|
12344
|
-
let
|
|
12841
|
+
const pillWidth3 = measureLegendText(group.name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD3;
|
|
12842
|
+
const minPillWidth = pillWidth3;
|
|
12843
|
+
let entriesWidth3 = 0;
|
|
12345
12844
|
for (const entry of visibleEntries) {
|
|
12346
|
-
|
|
12845
|
+
entriesWidth3 += LEGEND_DOT_R3 * 2 + LEGEND_ENTRY_DOT_GAP3 + measureLegendText(entry.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL3;
|
|
12347
12846
|
}
|
|
12348
12847
|
const eyeSpace = LEGEND_EYE_SIZE3 + LEGEND_EYE_GAP3;
|
|
12349
|
-
const
|
|
12848
|
+
const capsuleWidth2 = LEGEND_CAPSULE_PAD3 * 2 + pillWidth3 + 4 + eyeSpace + entriesWidth3;
|
|
12350
12849
|
groups.push({
|
|
12351
12850
|
name: group.name,
|
|
12352
12851
|
alias: group.alias,
|
|
12353
12852
|
entries: visibleEntries.map((e) => ({ value: e.value, color: e.color })),
|
|
12354
12853
|
x: 0,
|
|
12355
12854
|
y: 0,
|
|
12356
|
-
width:
|
|
12855
|
+
width: capsuleWidth2,
|
|
12357
12856
|
height: LEGEND_HEIGHT3,
|
|
12358
12857
|
minifiedWidth: minPillWidth,
|
|
12359
12858
|
minifiedHeight: LEGEND_HEIGHT3
|
|
@@ -12373,10 +12872,20 @@ function flattenNodes(nodes, parentContainerId, parentPageId, hiddenCounts, hidd
|
|
|
12373
12872
|
parentPageId,
|
|
12374
12873
|
meta,
|
|
12375
12874
|
fullMeta: { ...node.metadata },
|
|
12376
|
-
width: Math.max(
|
|
12875
|
+
width: Math.max(
|
|
12876
|
+
MIN_CARD_WIDTH2,
|
|
12877
|
+
node.label.length * CHAR_WIDTH2 + CARD_H_PAD2 * 2
|
|
12878
|
+
),
|
|
12377
12879
|
height: labelHeight + CONTAINER_PAD_BOTTOM2
|
|
12378
12880
|
});
|
|
12379
|
-
flattenNodes(
|
|
12881
|
+
flattenNodes(
|
|
12882
|
+
node.children,
|
|
12883
|
+
node.id,
|
|
12884
|
+
parentPageId,
|
|
12885
|
+
hiddenCounts,
|
|
12886
|
+
hiddenAttributes,
|
|
12887
|
+
result
|
|
12888
|
+
);
|
|
12380
12889
|
} else {
|
|
12381
12890
|
result.push({
|
|
12382
12891
|
sitemapNode: node,
|
|
@@ -12388,14 +12897,28 @@ function flattenNodes(nodes, parentContainerId, parentPageId, hiddenCounts, hidd
|
|
|
12388
12897
|
height: computeCardHeight2(meta)
|
|
12389
12898
|
});
|
|
12390
12899
|
if (node.children.length > 0) {
|
|
12391
|
-
flattenNodes(
|
|
12900
|
+
flattenNodes(
|
|
12901
|
+
node.children,
|
|
12902
|
+
parentContainerId,
|
|
12903
|
+
node.id,
|
|
12904
|
+
hiddenCounts,
|
|
12905
|
+
hiddenAttributes,
|
|
12906
|
+
result
|
|
12907
|
+
);
|
|
12392
12908
|
}
|
|
12393
12909
|
}
|
|
12394
12910
|
}
|
|
12395
12911
|
}
|
|
12396
12912
|
function layoutSitemap(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, expandAllLegend) {
|
|
12397
12913
|
if (parsed.roots.length === 0) {
|
|
12398
|
-
return {
|
|
12914
|
+
return {
|
|
12915
|
+
nodes: [],
|
|
12916
|
+
edges: [],
|
|
12917
|
+
containers: [],
|
|
12918
|
+
legend: [],
|
|
12919
|
+
width: 0,
|
|
12920
|
+
height: 0
|
|
12921
|
+
};
|
|
12399
12922
|
}
|
|
12400
12923
|
const allNodes = [];
|
|
12401
12924
|
const collect = (node) => {
|
|
@@ -12403,9 +12926,20 @@ function layoutSitemap(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, e
|
|
|
12403
12926
|
for (const child of node.children) collect(child);
|
|
12404
12927
|
};
|
|
12405
12928
|
for (const root of parsed.roots) collect(root);
|
|
12406
|
-
injectDefaultTagMetadata(
|
|
12929
|
+
injectDefaultTagMetadata(
|
|
12930
|
+
allNodes,
|
|
12931
|
+
parsed.tagGroups,
|
|
12932
|
+
(e) => e.isContainer
|
|
12933
|
+
);
|
|
12407
12934
|
const flatNodes = [];
|
|
12408
|
-
flattenNodes(
|
|
12935
|
+
flattenNodes(
|
|
12936
|
+
parsed.roots,
|
|
12937
|
+
null,
|
|
12938
|
+
null,
|
|
12939
|
+
hiddenCounts,
|
|
12940
|
+
hiddenAttributes,
|
|
12941
|
+
flatNodes
|
|
12942
|
+
);
|
|
12409
12943
|
const nodeMap = /* @__PURE__ */ new Map();
|
|
12410
12944
|
for (const flat of flatNodes) {
|
|
12411
12945
|
nodeMap.set(flat.sitemapNode.id, flat);
|
|
@@ -12467,14 +13001,29 @@ function layoutSitemap(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, e
|
|
|
12467
13001
|
g.setParent(flat.sitemapNode.id, flat.parentContainerId);
|
|
12468
13002
|
}
|
|
12469
13003
|
}
|
|
13004
|
+
const expandedContainerIds = /* @__PURE__ */ new Set();
|
|
13005
|
+
for (const cid of containerIds) {
|
|
13006
|
+
if (!collapsedContainerIds.has(cid)) {
|
|
13007
|
+
expandedContainerIds.add(cid);
|
|
13008
|
+
}
|
|
13009
|
+
}
|
|
13010
|
+
const deferredEdgeIndices = [];
|
|
12470
13011
|
for (let i = 0; i < parsed.edges.length; i++) {
|
|
12471
13012
|
const edge = parsed.edges[i];
|
|
12472
|
-
if (g.hasNode(edge.sourceId)
|
|
12473
|
-
|
|
13013
|
+
if (!g.hasNode(edge.sourceId) || !g.hasNode(edge.targetId)) continue;
|
|
13014
|
+
if (expandedContainerIds.has(edge.sourceId) || expandedContainerIds.has(edge.targetId)) {
|
|
13015
|
+
deferredEdgeIndices.push(i);
|
|
13016
|
+
continue;
|
|
13017
|
+
}
|
|
13018
|
+
g.setEdge(
|
|
13019
|
+
edge.sourceId,
|
|
13020
|
+
edge.targetId,
|
|
13021
|
+
{
|
|
12474
13022
|
label: edge.label ?? "",
|
|
12475
13023
|
minlen: 1
|
|
12476
|
-
},
|
|
12477
|
-
|
|
13024
|
+
},
|
|
13025
|
+
`e${i}`
|
|
13026
|
+
);
|
|
12478
13027
|
}
|
|
12479
13028
|
import_dagre.default.layout(g);
|
|
12480
13029
|
const layoutNodes = [];
|
|
@@ -12542,19 +13091,52 @@ function layoutSitemap(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, e
|
|
|
12542
13091
|
});
|
|
12543
13092
|
}
|
|
12544
13093
|
}
|
|
13094
|
+
const deferredSet = new Set(deferredEdgeIndices);
|
|
12545
13095
|
const layoutEdges = [];
|
|
12546
13096
|
for (let i = 0; i < parsed.edges.length; i++) {
|
|
12547
13097
|
const edge = parsed.edges[i];
|
|
12548
13098
|
if (!g.hasNode(edge.sourceId) || !g.hasNode(edge.targetId)) continue;
|
|
12549
|
-
|
|
12550
|
-
if (
|
|
13099
|
+
let points;
|
|
13100
|
+
if (deferredSet.has(i)) {
|
|
13101
|
+
const srcNode = g.node(edge.sourceId);
|
|
13102
|
+
const tgtNode = g.node(edge.targetId);
|
|
13103
|
+
if (!srcNode || !tgtNode) continue;
|
|
13104
|
+
const srcPt = clipToRectBorder(
|
|
13105
|
+
srcNode.x,
|
|
13106
|
+
srcNode.y,
|
|
13107
|
+
srcNode.width,
|
|
13108
|
+
srcNode.height,
|
|
13109
|
+
tgtNode.x,
|
|
13110
|
+
tgtNode.y
|
|
13111
|
+
);
|
|
13112
|
+
const tgtPt = clipToRectBorder(
|
|
13113
|
+
tgtNode.x,
|
|
13114
|
+
tgtNode.y,
|
|
13115
|
+
tgtNode.width,
|
|
13116
|
+
tgtNode.height,
|
|
13117
|
+
srcNode.x,
|
|
13118
|
+
srcNode.y
|
|
13119
|
+
);
|
|
13120
|
+
const midX = (srcPt.x + tgtPt.x) / 2;
|
|
13121
|
+
const midY = (srcPt.y + tgtPt.y) / 2;
|
|
13122
|
+
points = [srcPt, { x: midX, y: midY }, tgtPt];
|
|
13123
|
+
} else {
|
|
13124
|
+
const edgeData = g.edge({
|
|
13125
|
+
v: edge.sourceId,
|
|
13126
|
+
w: edge.targetId,
|
|
13127
|
+
name: `e${i}`
|
|
13128
|
+
});
|
|
13129
|
+
if (!edgeData) continue;
|
|
13130
|
+
points = edgeData.points ?? [];
|
|
13131
|
+
}
|
|
12551
13132
|
layoutEdges.push({
|
|
12552
13133
|
sourceId: edge.sourceId,
|
|
12553
13134
|
targetId: edge.targetId,
|
|
12554
|
-
points
|
|
13135
|
+
points,
|
|
12555
13136
|
label: edge.label,
|
|
12556
13137
|
color: edge.color,
|
|
12557
|
-
lineNumber: edge.lineNumber
|
|
13138
|
+
lineNumber: edge.lineNumber,
|
|
13139
|
+
deferred: deferredSet.has(i) || void 0
|
|
12558
13140
|
});
|
|
12559
13141
|
}
|
|
12560
13142
|
{
|
|
@@ -12715,7 +13297,9 @@ function layoutSitemap(parsed, hiddenCounts, activeTagGroup, hiddenAttributes, e
|
|
|
12715
13297
|
usedValuesByGroup.set(key, used);
|
|
12716
13298
|
}
|
|
12717
13299
|
const legendGroups = computeLegendGroups2(parsed.tagGroups, usedValuesByGroup);
|
|
12718
|
-
const visibleGroups = activeTagGroup != null ? legendGroups.filter(
|
|
13300
|
+
const visibleGroups = activeTagGroup != null ? legendGroups.filter(
|
|
13301
|
+
(g2) => g2.name.toLowerCase() === activeTagGroup.toLowerCase()
|
|
13302
|
+
) : legendGroups;
|
|
12719
13303
|
const allExpanded = expandAllLegend && activeTagGroup == null;
|
|
12720
13304
|
const effectiveW = (g2) => activeTagGroup != null || allExpanded ? g2.width : g2.minifiedWidth;
|
|
12721
13305
|
if (visibleGroups.length > 0) {
|
|
@@ -13030,7 +13614,8 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
|
|
|
13030
13614
|
const edgeG = contentG.append("g").attr("class", "sitemap-edge-group").attr("data-line-number", String(edge.lineNumber));
|
|
13031
13615
|
const edgeColor3 = edge.color ?? palette.textMuted;
|
|
13032
13616
|
const markerId = edge.color ? `sm-arrow-${edge.color.replace("#", "")}` : "sm-arrow";
|
|
13033
|
-
const
|
|
13617
|
+
const gen = edge.deferred ? lineGeneratorLinear : lineGenerator;
|
|
13618
|
+
const pathD = gen(edge.points);
|
|
13034
13619
|
if (pathD) {
|
|
13035
13620
|
edgeG.append("path").attr("d", pathD).attr("fill", "none").attr("stroke", edgeColor3).attr("stroke-width", EDGE_STROKE_WIDTH2).attr("marker-end", `url(#${markerId})`).attr("class", "sitemap-edge");
|
|
13036
13621
|
}
|
|
@@ -13121,57 +13706,44 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
|
|
|
13121
13706
|
}
|
|
13122
13707
|
function renderLegend(parent, legendGroups, palette, isDark, activeTagGroup, fixedWidth, hiddenAttributes) {
|
|
13123
13708
|
if (legendGroups.length === 0) return;
|
|
13124
|
-
const
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
|
|
13128
|
-
|
|
13129
|
-
|
|
13130
|
-
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
|
|
13137
|
-
|
|
13138
|
-
|
|
13139
|
-
|
|
13140
|
-
|
|
13141
|
-
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
|
|
13145
|
-
|
|
13146
|
-
|
|
13147
|
-
|
|
13148
|
-
|
|
13149
|
-
const
|
|
13150
|
-
|
|
13151
|
-
|
|
13152
|
-
|
|
13153
|
-
legendG.append("rect").attr("x", pillXOff).attr("y", pillYOff).attr("width", pillW).attr("height", pillH).attr("rx", pillH / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
|
|
13154
|
-
}
|
|
13155
|
-
legendG.append("text").attr("x", pillXOff + pillW / 2).attr("y", LEGEND_HEIGHT / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", "500").attr("fill", isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(group.name);
|
|
13156
|
-
if (isActive && fixedWidth != null) {
|
|
13157
|
-
const groupKey = group.name.toLowerCase();
|
|
13709
|
+
const groups = legendGroups.map((g) => ({
|
|
13710
|
+
name: g.name,
|
|
13711
|
+
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
13712
|
+
}));
|
|
13713
|
+
const isFixedMode = fixedWidth != null;
|
|
13714
|
+
const eyeAddonWidth = isFixedMode ? LEGEND_EYE_SIZE + LEGEND_EYE_GAP : 0;
|
|
13715
|
+
const legendConfig = {
|
|
13716
|
+
groups,
|
|
13717
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
13718
|
+
mode: "fixed",
|
|
13719
|
+
capsulePillAddonWidth: eyeAddonWidth
|
|
13720
|
+
};
|
|
13721
|
+
const legendState = { activeGroup: activeTagGroup ?? null };
|
|
13722
|
+
const containerWidth = fixedWidth ?? legendGroups[0]?.x + (legendGroups[0]?.width ?? 200);
|
|
13723
|
+
const legendHandle = renderLegendD3(
|
|
13724
|
+
parent,
|
|
13725
|
+
legendConfig,
|
|
13726
|
+
legendState,
|
|
13727
|
+
palette,
|
|
13728
|
+
isDark,
|
|
13729
|
+
void 0,
|
|
13730
|
+
containerWidth
|
|
13731
|
+
);
|
|
13732
|
+
parent.selectAll("[data-legend-group]").classed("sitemap-legend-group", true);
|
|
13733
|
+
if (isFixedMode) {
|
|
13734
|
+
const computedLayout = legendHandle.getLayout();
|
|
13735
|
+
if (computedLayout.activeCapsule?.addonX != null) {
|
|
13736
|
+
const capsule = computedLayout.activeCapsule;
|
|
13737
|
+
const groupKey = capsule.groupName.toLowerCase();
|
|
13158
13738
|
const isHidden = hiddenAttributes?.has(groupKey) ?? false;
|
|
13159
|
-
const
|
|
13160
|
-
|
|
13161
|
-
|
|
13162
|
-
|
|
13163
|
-
|
|
13164
|
-
|
|
13165
|
-
|
|
13166
|
-
|
|
13167
|
-
const eyeShift = fixedWidth != null ? LEGEND_EYE_SIZE + LEGEND_EYE_GAP : 0;
|
|
13168
|
-
let entryX = pillXOff + pillW + 4 + eyeShift;
|
|
13169
|
-
for (const entry of group.entries) {
|
|
13170
|
-
const entryG = legendG.append("g").attr("data-legend-entry", entry.value.toLowerCase()).style("cursor", "pointer");
|
|
13171
|
-
entryG.append("circle").attr("cx", entryX + LEGEND_DOT_R).attr("cy", LEGEND_HEIGHT / 2).attr("r", LEGEND_DOT_R).attr("fill", entry.color);
|
|
13172
|
-
const textX = entryX + LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP;
|
|
13173
|
-
entryG.append("text").attr("x", textX).attr("y", LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).text(entry.value);
|
|
13174
|
-
entryX = textX + measureLegendText(entry.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
13739
|
+
const activeGroupEl = parent.select(`[data-legend-group="${groupKey}"]`);
|
|
13740
|
+
if (!activeGroupEl.empty()) {
|
|
13741
|
+
const eyeX = capsule.addonX;
|
|
13742
|
+
const eyeY = (LEGEND_HEIGHT - LEGEND_EYE_SIZE) / 2;
|
|
13743
|
+
const hitPad = 6;
|
|
13744
|
+
const eyeG = activeGroupEl.append("g").attr("class", "sitemap-legend-eye").attr("data-legend-visibility", groupKey).style("cursor", "pointer").attr("opacity", isHidden ? 0.4 : 0.7);
|
|
13745
|
+
eyeG.append("rect").attr("x", eyeX - hitPad).attr("y", eyeY - hitPad).attr("width", LEGEND_EYE_SIZE + hitPad * 2).attr("height", LEGEND_EYE_SIZE + hitPad * 2).attr("fill", "transparent").attr("pointer-events", "all");
|
|
13746
|
+
eyeG.append("path").attr("d", isHidden ? EYE_CLOSED_PATH : EYE_OPEN_PATH).attr("transform", `translate(${eyeX}, ${eyeY})`).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1.2).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
13175
13747
|
}
|
|
13176
13748
|
}
|
|
13177
13749
|
}
|
|
@@ -13225,7 +13797,7 @@ async function renderSitemapForExport(content, theme, palette) {
|
|
|
13225
13797
|
const brandColor = theme === "transparent" ? "#888" : effectivePalette.textMuted;
|
|
13226
13798
|
return injectBranding2(svgHtml, brandColor);
|
|
13227
13799
|
}
|
|
13228
|
-
var d3Selection2, d3Shape, DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, LABEL_FONT_SIZE2, META_FONT_SIZE2, META_LINE_HEIGHT4, HEADER_HEIGHT4, SEPARATOR_GAP4, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, CARD_RADIUS2, CONTAINER_RADIUS2, CONTAINER_LABEL_FONT_SIZE2, CONTAINER_META_FONT_SIZE2, CONTAINER_META_LINE_HEIGHT4, CONTAINER_HEADER_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, COLLAPSE_BAR_HEIGHT2, LEGEND_FIXED_GAP2, lineGenerator;
|
|
13800
|
+
var d3Selection2, d3Shape, DIAGRAM_PADDING2, MAX_SCALE2, TITLE_HEIGHT2, LABEL_FONT_SIZE2, META_FONT_SIZE2, META_LINE_HEIGHT4, HEADER_HEIGHT4, SEPARATOR_GAP4, EDGE_STROKE_WIDTH2, NODE_STROKE_WIDTH2, CARD_RADIUS2, CONTAINER_RADIUS2, CONTAINER_LABEL_FONT_SIZE2, CONTAINER_META_FONT_SIZE2, CONTAINER_META_LINE_HEIGHT4, CONTAINER_HEADER_HEIGHT2, ARROWHEAD_W, ARROWHEAD_H, EDGE_LABEL_FONT_SIZE, COLLAPSE_BAR_HEIGHT2, LEGEND_FIXED_GAP2, lineGenerator, lineGeneratorLinear;
|
|
13229
13801
|
var init_renderer2 = __esm({
|
|
13230
13802
|
"src/sitemap/renderer.ts"() {
|
|
13231
13803
|
"use strict";
|
|
@@ -13234,6 +13806,7 @@ var init_renderer2 = __esm({
|
|
|
13234
13806
|
init_fonts();
|
|
13235
13807
|
init_color_utils();
|
|
13236
13808
|
init_legend_constants();
|
|
13809
|
+
init_legend_d3();
|
|
13237
13810
|
init_title_constants();
|
|
13238
13811
|
DIAGRAM_PADDING2 = 20;
|
|
13239
13812
|
MAX_SCALE2 = 3;
|
|
@@ -13257,6 +13830,7 @@ var init_renderer2 = __esm({
|
|
|
13257
13830
|
COLLAPSE_BAR_HEIGHT2 = 6;
|
|
13258
13831
|
LEGEND_FIXED_GAP2 = 8;
|
|
13259
13832
|
lineGenerator = d3Shape.line().x((d) => d.x).y((d) => d.y).curve(d3Shape.curveBasis);
|
|
13833
|
+
lineGeneratorLinear = d3Shape.line().x((d) => d.x).y((d) => d.y).curve(d3Shape.curveLinear);
|
|
13260
13834
|
}
|
|
13261
13835
|
});
|
|
13262
13836
|
|
|
@@ -13533,53 +14107,22 @@ function renderKanban(container, parsed, palette, isDark, _onNavigateToLine, exp
|
|
|
13533
14107
|
}
|
|
13534
14108
|
if (parsed.tagGroups.length > 0) {
|
|
13535
14109
|
const legendY = height - LEGEND_HEIGHT;
|
|
13536
|
-
|
|
13537
|
-
|
|
13538
|
-
|
|
13539
|
-
|
|
13540
|
-
|
|
13541
|
-
|
|
13542
|
-
}
|
|
13543
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
capsuleContentWidth += LEGEND_DOT_R * 2 + 4 + entry.value.length * LEGEND_ENTRY_FONT_SIZE * 0.6 + 8;
|
|
13553
|
-
}
|
|
13554
|
-
}
|
|
13555
|
-
const capsuleWidth = capsuleContentWidth + capsulePad * 2;
|
|
13556
|
-
if (isActive) {
|
|
13557
|
-
legendContainer.append("rect").attr("x", legendX).attr("y", legendY).attr("width", capsuleWidth).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
13558
|
-
}
|
|
13559
|
-
const pillX = legendX + (isActive ? capsulePad : 0);
|
|
13560
|
-
const pillBg = isActive ? palette.bg : groupBg;
|
|
13561
|
-
legendContainer.append("rect").attr("x", pillX).attr("y", legendY + capsulePad).attr("width", pillWidth2).attr("height", LEGEND_HEIGHT - capsulePad * 2).attr("rx", (LEGEND_HEIGHT - capsulePad * 2) / 2).attr("fill", pillBg).attr("class", "kanban-legend-group").attr("data-legend-group", group.name.toLowerCase());
|
|
13562
|
-
if (isActive) {
|
|
13563
|
-
legendContainer.append("rect").attr("x", pillX).attr("y", legendY + capsulePad).attr("width", pillWidth2).attr("height", LEGEND_HEIGHT - capsulePad * 2).attr("rx", (LEGEND_HEIGHT - capsulePad * 2) / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
|
|
13564
|
-
}
|
|
13565
|
-
legendContainer.append("text").attr("x", pillX + pillWidth2 / 2).attr("y", legendY + LEGEND_HEIGHT / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", "500").attr("fill", isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(group.name);
|
|
13566
|
-
if (isActive) {
|
|
13567
|
-
let entryX = pillX + pillWidth2 + 4;
|
|
13568
|
-
for (const entry of group.entries) {
|
|
13569
|
-
const entryG = legendContainer.append("g").attr("data-legend-entry", entry.value.toLowerCase()).style("cursor", "pointer");
|
|
13570
|
-
entryG.append("circle").attr("cx", entryX + LEGEND_DOT_R).attr("cy", legendY + LEGEND_HEIGHT / 2).attr("r", LEGEND_DOT_R).attr("fill", entry.color);
|
|
13571
|
-
const entryTextX = entryX + LEGEND_DOT_R * 2 + 4;
|
|
13572
|
-
entryG.append("text").attr("x", entryTextX).attr(
|
|
13573
|
-
"y",
|
|
13574
|
-
legendY + LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1
|
|
13575
|
-
).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).text(entry.value);
|
|
13576
|
-
entryX = entryTextX + entry.value.length * LEGEND_ENTRY_FONT_SIZE * 0.6 + 8;
|
|
13577
|
-
}
|
|
13578
|
-
legendX += capsuleWidth + 12;
|
|
13579
|
-
} else {
|
|
13580
|
-
legendX += pillWidth2 + 12;
|
|
13581
|
-
}
|
|
13582
|
-
}
|
|
14110
|
+
const legendConfig = {
|
|
14111
|
+
groups: parsed.tagGroups,
|
|
14112
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
14113
|
+
mode: exportDims ? "inline" : "fixed"
|
|
14114
|
+
};
|
|
14115
|
+
const legendState = { activeGroup: activeTagGroup ?? null };
|
|
14116
|
+
const legendG = svg.append("g").attr("class", "kanban-legend").attr("transform", `translate(${DIAGRAM_PADDING3},${legendY})`);
|
|
14117
|
+
renderLegendD3(
|
|
14118
|
+
legendG,
|
|
14119
|
+
legendConfig,
|
|
14120
|
+
legendState,
|
|
14121
|
+
palette,
|
|
14122
|
+
isDark,
|
|
14123
|
+
void 0,
|
|
14124
|
+
width - DIAGRAM_PADDING3 * 2
|
|
14125
|
+
);
|
|
13583
14126
|
}
|
|
13584
14127
|
const defaultColBg = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.surface, palette.bg, 30);
|
|
13585
14128
|
const defaultColHeaderBg = isDark ? mix(palette.surface, palette.bg, 70) : mix(palette.surface, palette.bg, 50);
|
|
@@ -13675,6 +14218,7 @@ var init_renderer3 = __esm({
|
|
|
13675
14218
|
init_parser5();
|
|
13676
14219
|
init_mutations();
|
|
13677
14220
|
init_legend_constants();
|
|
14221
|
+
init_legend_d3();
|
|
13678
14222
|
init_title_constants();
|
|
13679
14223
|
DIAGRAM_PADDING3 = 20;
|
|
13680
14224
|
COLUMN_GAP = 16;
|
|
@@ -13868,14 +14412,9 @@ function collectClassTypes(parsed) {
|
|
|
13868
14412
|
if (c.color) continue;
|
|
13869
14413
|
present.add(c.modifier ?? "class");
|
|
13870
14414
|
}
|
|
13871
|
-
return CLASS_TYPE_ORDER.filter((k) => present.has(k)).map(
|
|
13872
|
-
|
|
13873
|
-
|
|
13874
|
-
let w = 0;
|
|
13875
|
-
for (const e of entries) {
|
|
13876
|
-
w += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(e.label, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
13877
|
-
}
|
|
13878
|
-
return w;
|
|
14415
|
+
return CLASS_TYPE_ORDER.filter((k) => present.has(k)).map(
|
|
14416
|
+
(k) => CLASS_TYPE_MAP[k]
|
|
14417
|
+
);
|
|
13879
14418
|
}
|
|
13880
14419
|
function classTypeKey(modifier) {
|
|
13881
14420
|
return modifier ?? "class";
|
|
@@ -13944,7 +14483,10 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
|
|
|
13944
14483
|
defs.append("marker").attr("id", "cd-arrow-depend").attr("viewBox", `0 0 ${AW} ${AH}`).attr("refX", AW).attr("refY", AH / 2).attr("markerWidth", AW).attr("markerHeight", AH).attr("orient", "auto").append("polyline").attr("points", `0,0 ${AW},${AH / 2} 0,${AH}`).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1.5);
|
|
13945
14484
|
defs.append("marker").attr("id", "cd-arrow-assoc").attr("viewBox", `0 0 ${AW} ${AH}`).attr("refX", AW).attr("refY", AH / 2).attr("markerWidth", AW).attr("markerHeight", AH).attr("orient", "auto").append("polyline").attr("points", `0,0 ${AW},${AH / 2} 0,${AH}`).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1.5);
|
|
13946
14485
|
if (parsed.title) {
|
|
13947
|
-
const titleEl = 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-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).style(
|
|
14486
|
+
const titleEl = 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-size", TITLE_FONT_SIZE).attr("font-weight", TITLE_FONT_WEIGHT).style(
|
|
14487
|
+
"cursor",
|
|
14488
|
+
onClickItem && parsed.titleLineNumber ? "pointer" : "default"
|
|
14489
|
+
).text(parsed.title);
|
|
13948
14490
|
if (parsed.titleLineNumber) {
|
|
13949
14491
|
titleEl.attr("data-line-number", parsed.titleLineNumber);
|
|
13950
14492
|
if (onClickItem) {
|
|
@@ -13958,32 +14500,33 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
|
|
|
13958
14500
|
}
|
|
13959
14501
|
const isLegendExpanded = legendActive !== false;
|
|
13960
14502
|
if (hasLegend) {
|
|
13961
|
-
const
|
|
13962
|
-
|
|
13963
|
-
|
|
13964
|
-
|
|
13965
|
-
|
|
13966
|
-
|
|
13967
|
-
|
|
13968
|
-
const legendG = svg.append("g").attr("class", "cd-legend").attr("data-legend-group", "type").attr("transform", `translate(${legendX}, ${legendY})`).style("cursor", "pointer");
|
|
13969
|
-
if (isLegendExpanded) {
|
|
13970
|
-
legendG.append("rect").attr("width", totalW).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
13971
|
-
legendG.append("rect").attr("x", LEGEND_CAPSULE_PAD).attr("y", LEGEND_CAPSULE_PAD).attr("width", pillWidth2).attr("height", pillH).attr("rx", pillH / 2).attr("fill", palette.bg);
|
|
13972
|
-
legendG.append("rect").attr("x", LEGEND_CAPSULE_PAD).attr("y", LEGEND_CAPSULE_PAD).attr("width", pillWidth2).attr("height", pillH).attr("rx", pillH / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
|
|
13973
|
-
legendG.append("text").attr("x", LEGEND_CAPSULE_PAD + pillWidth2 / 2).attr("y", LEGEND_HEIGHT / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", "500").attr("fill", palette.text).attr("text-anchor", "middle").attr("font-family", FONT_FAMILY).text(LEGEND_GROUP_NAME);
|
|
13974
|
-
let entryX = LEGEND_CAPSULE_PAD + pillWidth2 + LEGEND_ENTRY_TRAIL;
|
|
13975
|
-
for (const entry of legendEntries) {
|
|
13976
|
-
const color = palette.colors[entry.colorKey];
|
|
13977
|
-
const typeKey = CLASS_TYPE_ORDER.find((k) => CLASS_TYPE_MAP[k] === entry);
|
|
13978
|
-
const entryG = legendG.append("g").attr("data-legend-entry", typeKey);
|
|
13979
|
-
entryG.append("circle").attr("cx", entryX + LEGEND_DOT_R).attr("cy", LEGEND_HEIGHT / 2).attr("r", LEGEND_DOT_R).attr("fill", color);
|
|
13980
|
-
entryG.append("text").attr("x", entryX + LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP).attr("y", LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).attr("font-family", FONT_FAMILY).text(entry.label);
|
|
13981
|
-
entryX += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(entry.label, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
14503
|
+
const legendGroups = [
|
|
14504
|
+
{
|
|
14505
|
+
name: LEGEND_GROUP_NAME,
|
|
14506
|
+
entries: legendEntries.map((entry) => ({
|
|
14507
|
+
value: entry.label,
|
|
14508
|
+
color: palette.colors[entry.colorKey]
|
|
14509
|
+
}))
|
|
13982
14510
|
}
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
|
|
13986
|
-
|
|
14511
|
+
];
|
|
14512
|
+
const legendConfig = {
|
|
14513
|
+
groups: legendGroups,
|
|
14514
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
14515
|
+
mode: "fixed"
|
|
14516
|
+
};
|
|
14517
|
+
const legendState = {
|
|
14518
|
+
activeGroup: isLegendExpanded ? LEGEND_GROUP_NAME : null
|
|
14519
|
+
};
|
|
14520
|
+
const legendG = svg.append("g").attr("class", "cd-legend").attr("transform", `translate(0,${titleHeight})`);
|
|
14521
|
+
renderLegendD3(
|
|
14522
|
+
legendG,
|
|
14523
|
+
legendConfig,
|
|
14524
|
+
legendState,
|
|
14525
|
+
palette,
|
|
14526
|
+
isDark,
|
|
14527
|
+
void 0,
|
|
14528
|
+
width
|
|
14529
|
+
);
|
|
13987
14530
|
}
|
|
13988
14531
|
const contentG = svg.append("g").attr("transform", `translate(${offsetX}, ${offsetY}) scale(${scale})`);
|
|
13989
14532
|
for (const edge of layout.edges) {
|
|
@@ -14027,7 +14570,13 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
|
|
|
14027
14570
|
const colorOff = !!parsed.options?.["no-auto-color"];
|
|
14028
14571
|
const neutralize = hasLegend && !isLegendExpanded && !node.color;
|
|
14029
14572
|
const effectiveColor = neutralize ? palette.primary : node.color;
|
|
14030
|
-
const fill2 = nodeFill3(
|
|
14573
|
+
const fill2 = nodeFill3(
|
|
14574
|
+
palette,
|
|
14575
|
+
isDark,
|
|
14576
|
+
node.modifier,
|
|
14577
|
+
effectiveColor,
|
|
14578
|
+
colorOff
|
|
14579
|
+
);
|
|
14031
14580
|
const stroke2 = nodeStroke3(palette, node.modifier, effectiveColor, colorOff);
|
|
14032
14581
|
nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", 3).attr("ry", 3).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", NODE_STROKE_WIDTH3);
|
|
14033
14582
|
let yPos = -h / 2;
|
|
@@ -14096,15 +14645,10 @@ function renderClassDiagramForExport(content, theme, palette) {
|
|
|
14096
14645
|
const exportWidth = layout.width + DIAGRAM_PADDING4 * 2;
|
|
14097
14646
|
const exportHeight = layout.height + DIAGRAM_PADDING4 * 2 + (parsed.title ? 40 : 0) + legendReserve;
|
|
14098
14647
|
return runInExportContainer(exportWidth, exportHeight, (container) => {
|
|
14099
|
-
renderClassDiagram(
|
|
14100
|
-
|
|
14101
|
-
|
|
14102
|
-
|
|
14103
|
-
palette,
|
|
14104
|
-
isDark,
|
|
14105
|
-
void 0,
|
|
14106
|
-
{ width: exportWidth, height: exportHeight }
|
|
14107
|
-
);
|
|
14648
|
+
renderClassDiagram(container, parsed, layout, palette, isDark, void 0, {
|
|
14649
|
+
width: exportWidth,
|
|
14650
|
+
height: exportHeight
|
|
14651
|
+
});
|
|
14108
14652
|
return extractExportSvg(container, theme);
|
|
14109
14653
|
});
|
|
14110
14654
|
}
|
|
@@ -14117,6 +14661,7 @@ var init_renderer4 = __esm({
|
|
|
14117
14661
|
init_fonts();
|
|
14118
14662
|
init_export_container();
|
|
14119
14663
|
init_legend_constants();
|
|
14664
|
+
init_legend_d3();
|
|
14120
14665
|
init_title_constants();
|
|
14121
14666
|
init_color_utils();
|
|
14122
14667
|
init_parser2();
|
|
@@ -14723,35 +15268,24 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
|
|
|
14723
15268
|
}
|
|
14724
15269
|
}
|
|
14725
15270
|
if (parsed.tagGroups.length > 0) {
|
|
14726
|
-
const LEGEND_PILL_H = LEGEND_HEIGHT - 6;
|
|
14727
|
-
const LEGEND_PILL_RX = Math.floor(LEGEND_PILL_H / 2);
|
|
14728
|
-
const LEGEND_GAP = 8;
|
|
14729
|
-
const legendG = svg.append("g").attr("class", "er-tag-legend");
|
|
14730
|
-
if (activeTagGroup) {
|
|
14731
|
-
legendG.attr("data-legend-active", activeTagGroup.toLowerCase());
|
|
14732
|
-
}
|
|
14733
|
-
let legendX = DIAGRAM_PADDING5;
|
|
14734
15271
|
const legendY = DIAGRAM_PADDING5 + titleHeight;
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14743
|
-
|
|
14744
|
-
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
}
|
|
14753
|
-
legendX += LEGEND_GROUP_GAP;
|
|
14754
|
-
}
|
|
15272
|
+
const legendConfig = {
|
|
15273
|
+
groups: parsed.tagGroups,
|
|
15274
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
15275
|
+
mode: "fixed"
|
|
15276
|
+
};
|
|
15277
|
+
const legendState = { activeGroup: activeTagGroup ?? null };
|
|
15278
|
+
const legendG = svg.append("g").attr("class", "er-tag-legend").attr("transform", `translate(0,${legendY})`);
|
|
15279
|
+
renderLegendD3(
|
|
15280
|
+
legendG,
|
|
15281
|
+
legendConfig,
|
|
15282
|
+
legendState,
|
|
15283
|
+
palette,
|
|
15284
|
+
isDark,
|
|
15285
|
+
void 0,
|
|
15286
|
+
viewW
|
|
15287
|
+
);
|
|
15288
|
+
legendG.selectAll("[data-legend-group]").classed("er-legend-group", true);
|
|
14755
15289
|
}
|
|
14756
15290
|
if (semanticRoles) {
|
|
14757
15291
|
const presentRoles = ROLE_ORDER.filter((role) => {
|
|
@@ -14761,55 +15295,35 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
|
|
|
14761
15295
|
return false;
|
|
14762
15296
|
});
|
|
14763
15297
|
if (presentRoles.length > 0) {
|
|
14764
|
-
const measureLabelW = (text, fontSize) => {
|
|
14765
|
-
const dummy = svg.append("text").attr("font-size", fontSize).attr("font-family", FONT_FAMILY).attr("visibility", "hidden").text(text);
|
|
14766
|
-
const measured = dummy.node()?.getComputedTextLength?.() ?? 0;
|
|
14767
|
-
dummy.remove();
|
|
14768
|
-
return measured > 0 ? measured : text.length * fontSize * 0.6;
|
|
14769
|
-
};
|
|
14770
|
-
const labelWidths = /* @__PURE__ */ new Map();
|
|
14771
|
-
for (const role of presentRoles) {
|
|
14772
|
-
labelWidths.set(
|
|
14773
|
-
role,
|
|
14774
|
-
measureLabelW(ROLE_LABELS[role], LEGEND_ENTRY_FONT_SIZE)
|
|
14775
|
-
);
|
|
14776
|
-
}
|
|
14777
|
-
const groupBg = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.surface, palette.bg, 30);
|
|
14778
|
-
const groupName = "Role";
|
|
14779
|
-
const pillWidth2 = measureLegendText(groupName, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
14780
|
-
const pillH = LEGEND_HEIGHT - LEGEND_CAPSULE_PAD * 2;
|
|
14781
|
-
let totalWidth;
|
|
14782
|
-
let entriesWidth2 = 0;
|
|
14783
|
-
if (semanticActive) {
|
|
14784
|
-
for (const role of presentRoles) {
|
|
14785
|
-
entriesWidth2 += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + labelWidths.get(role) + LEGEND_ENTRY_TRAIL;
|
|
14786
|
-
}
|
|
14787
|
-
totalWidth = LEGEND_CAPSULE_PAD * 2 + pillWidth2 + LEGEND_ENTRY_TRAIL + entriesWidth2;
|
|
14788
|
-
} else {
|
|
14789
|
-
totalWidth = pillWidth2;
|
|
14790
|
-
}
|
|
14791
|
-
const legendX = (viewW - totalWidth) / 2;
|
|
14792
15298
|
const legendY = DIAGRAM_PADDING5 + titleHeight;
|
|
14793
|
-
const
|
|
14794
|
-
|
|
14795
|
-
|
|
14796
|
-
|
|
14797
|
-
|
|
14798
|
-
|
|
14799
|
-
|
|
14800
|
-
for (const role of presentRoles) {
|
|
14801
|
-
const label = ROLE_LABELS[role];
|
|
14802
|
-
const roleColor = palette.colors[ROLE_COLORS[role]];
|
|
14803
|
-
const entryG = semanticLegendG.append("g").attr("data-legend-entry", role);
|
|
14804
|
-
entryG.append("circle").attr("cx", entryX + LEGEND_DOT_R).attr("cy", LEGEND_HEIGHT / 2).attr("r", LEGEND_DOT_R).attr("fill", roleColor);
|
|
14805
|
-
const textX = entryX + LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP;
|
|
14806
|
-
entryG.append("text").attr("x", textX).attr("y", LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).attr("font-family", FONT_FAMILY).text(label);
|
|
14807
|
-
entryX = textX + labelWidths.get(role) + LEGEND_ENTRY_TRAIL;
|
|
15299
|
+
const semanticGroups = [
|
|
15300
|
+
{
|
|
15301
|
+
name: "Role",
|
|
15302
|
+
entries: presentRoles.map((role) => ({
|
|
15303
|
+
value: ROLE_LABELS[role],
|
|
15304
|
+
color: palette.colors[ROLE_COLORS[role]]
|
|
15305
|
+
}))
|
|
14808
15306
|
}
|
|
14809
|
-
|
|
14810
|
-
|
|
14811
|
-
|
|
14812
|
-
|
|
15307
|
+
];
|
|
15308
|
+
const legendConfig = {
|
|
15309
|
+
groups: semanticGroups,
|
|
15310
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
15311
|
+
mode: "fixed"
|
|
15312
|
+
};
|
|
15313
|
+
const legendState = {
|
|
15314
|
+
activeGroup: semanticActive ? "Role" : null
|
|
15315
|
+
};
|
|
15316
|
+
const legendG = svg.append("g").attr("class", "er-semantic-legend").attr("transform", `translate(0,${legendY})`);
|
|
15317
|
+
renderLegendD3(
|
|
15318
|
+
legendG,
|
|
15319
|
+
legendConfig,
|
|
15320
|
+
legendState,
|
|
15321
|
+
palette,
|
|
15322
|
+
isDark,
|
|
15323
|
+
void 0,
|
|
15324
|
+
viewW
|
|
15325
|
+
);
|
|
15326
|
+
legendG.selectAll("[data-legend-group]").classed("er-legend-group", true);
|
|
14813
15327
|
}
|
|
14814
15328
|
}
|
|
14815
15329
|
}
|
|
@@ -14854,6 +15368,7 @@ var init_renderer5 = __esm({
|
|
|
14854
15368
|
init_palettes();
|
|
14855
15369
|
init_tag_groups();
|
|
14856
15370
|
init_legend_constants();
|
|
15371
|
+
init_legend_d3();
|
|
14857
15372
|
init_title_constants();
|
|
14858
15373
|
init_parser3();
|
|
14859
15374
|
init_layout4();
|
|
@@ -14877,6 +15392,17 @@ var layout_exports5 = {};
|
|
|
14877
15392
|
__export(layout_exports5, {
|
|
14878
15393
|
layoutBoxesAndLines: () => layoutBoxesAndLines
|
|
14879
15394
|
});
|
|
15395
|
+
function clipToRectBorder2(cx, cy, w, h, tx, ty) {
|
|
15396
|
+
const dx = tx - cx;
|
|
15397
|
+
const dy = ty - cy;
|
|
15398
|
+
if (dx === 0 && dy === 0) return { x: cx, y: cy };
|
|
15399
|
+
const hw = w / 2;
|
|
15400
|
+
const hh = h / 2;
|
|
15401
|
+
const sx = dx !== 0 ? hw / Math.abs(dx) : Infinity;
|
|
15402
|
+
const sy = dy !== 0 ? hh / Math.abs(dy) : Infinity;
|
|
15403
|
+
const s = Math.min(sx, sy);
|
|
15404
|
+
return { x: cx + dx * s, y: cy + dy * s };
|
|
15405
|
+
}
|
|
14880
15406
|
function computeNodeSize(_node) {
|
|
14881
15407
|
const PHI = 1.618;
|
|
14882
15408
|
const NODE_HEIGHT = 60;
|
|
@@ -15029,13 +15555,25 @@ function layoutBoxesAndLines(parsed, collapseInfo) {
|
|
|
15029
15555
|
const srcNode = g.node(edge.source);
|
|
15030
15556
|
const tgtNode = g.node(edge.target);
|
|
15031
15557
|
if (!srcNode || !tgtNode) continue;
|
|
15032
|
-
const
|
|
15033
|
-
|
|
15034
|
-
|
|
15035
|
-
|
|
15036
|
-
|
|
15037
|
-
|
|
15038
|
-
|
|
15558
|
+
const srcPt = clipToRectBorder2(
|
|
15559
|
+
srcNode.x,
|
|
15560
|
+
srcNode.y,
|
|
15561
|
+
srcNode.width,
|
|
15562
|
+
srcNode.height,
|
|
15563
|
+
tgtNode.x,
|
|
15564
|
+
tgtNode.y
|
|
15565
|
+
);
|
|
15566
|
+
const tgtPt = clipToRectBorder2(
|
|
15567
|
+
tgtNode.x,
|
|
15568
|
+
tgtNode.y,
|
|
15569
|
+
tgtNode.width,
|
|
15570
|
+
tgtNode.height,
|
|
15571
|
+
srcNode.x,
|
|
15572
|
+
srcNode.y
|
|
15573
|
+
);
|
|
15574
|
+
const midX = (srcPt.x + tgtPt.x) / 2;
|
|
15575
|
+
const midY = (srcPt.y + tgtPt.y) / 2;
|
|
15576
|
+
points = [srcPt, { x: midX, y: midY }, tgtPt];
|
|
15039
15577
|
} else {
|
|
15040
15578
|
const dagreEdge = g.edge(edge.source, edge.target, `e${i}`);
|
|
15041
15579
|
points = dagreEdge?.points ?? [];
|
|
@@ -15058,7 +15596,8 @@ function layoutBoxesAndLines(parsed, collapseInfo) {
|
|
|
15058
15596
|
labelY,
|
|
15059
15597
|
yOffset: edgeYOffsets[i],
|
|
15060
15598
|
parallelCount: edgeParallelCounts[i],
|
|
15061
|
-
metadata: edge.metadata
|
|
15599
|
+
metadata: edge.metadata,
|
|
15600
|
+
deferred: deferredSet.has(i) || void 0
|
|
15062
15601
|
});
|
|
15063
15602
|
}
|
|
15064
15603
|
let maxX = 0;
|
|
@@ -15327,12 +15866,8 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
15327
15866
|
const edgeG = diagramG.append("g").attr("class", "bl-edge-group").attr("data-line-number", String(le.lineNumber));
|
|
15328
15867
|
edgeGroups.set(i, edgeG);
|
|
15329
15868
|
const markerId = `bl-arrow-${color.replace("#", "")}`;
|
|
15330
|
-
const
|
|
15331
|
-
|
|
15332
|
-
(parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR)(
|
|
15333
|
-
points
|
|
15334
|
-
) ?? ""
|
|
15335
|
-
).attr("fill", "none").attr("stroke", color).attr("stroke-width", EDGE_STROKE_WIDTH5).attr("marker-end", `url(#${markerId})`);
|
|
15869
|
+
const gen = le.deferred ? lineGeneratorLinear2 : parsed.direction === "TB" ? lineGeneratorTB : lineGeneratorLR;
|
|
15870
|
+
const path = edgeG.append("path").attr("class", "bl-edge").attr("d", gen(points) ?? "").attr("fill", "none").attr("stroke", color).attr("stroke-width", EDGE_STROKE_WIDTH5).attr("marker-end", `url(#${markerId})`);
|
|
15336
15871
|
if (le.bidirectional) {
|
|
15337
15872
|
const revId = `bl-arrow-rev-${color.replace("#", "")}`;
|
|
15338
15873
|
path.attr("marker-start", `url(#${revId})`);
|
|
@@ -15413,50 +15948,23 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
15413
15948
|
}
|
|
15414
15949
|
}
|
|
15415
15950
|
if (parsed.tagGroups.length > 0) {
|
|
15416
|
-
|
|
15417
|
-
|
|
15418
|
-
}
|
|
15419
|
-
|
|
15420
|
-
|
|
15421
|
-
|
|
15422
|
-
|
|
15423
|
-
|
|
15424
|
-
|
|
15425
|
-
|
|
15426
|
-
|
|
15427
|
-
|
|
15428
|
-
|
|
15429
|
-
|
|
15430
|
-
|
|
15431
|
-
|
|
15432
|
-
|
|
15433
|
-
}
|
|
15434
|
-
const legendX = Math.max(LEGEND_CAPSULE_PAD, (svgWidth - totalW) / 2);
|
|
15435
|
-
const legendY = titleOffset + 4;
|
|
15436
|
-
const legendG = svg.append("g").attr("transform", `translate(${legendX},${legendY})`);
|
|
15437
|
-
let x = 0;
|
|
15438
|
-
for (const tg of parsed.tagGroups) {
|
|
15439
|
-
const isActiveGroup = activeGroup?.toLowerCase() === tg.name.toLowerCase();
|
|
15440
|
-
const groupG = legendG.append("g").attr("class", "bl-legend-group").attr("data-legend-group", tg.name.toLowerCase()).style("cursor", "pointer");
|
|
15441
|
-
const nameW = measureLegendText(tg.name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
15442
|
-
const tagPill = groupG.append("rect").attr("x", x).attr("y", 0).attr("width", nameW).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
15443
|
-
if (isActiveGroup) {
|
|
15444
|
-
tagPill.attr("stroke", pillBorder).attr("stroke-width", 0.75);
|
|
15445
|
-
}
|
|
15446
|
-
groupG.append("text").attr("x", x + nameW / 2).attr("y", LEGEND_HEIGHT / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", 500).attr("fill", isActiveGroup ? palette.text : palette.textMuted).attr("pointer-events", "none").text(tg.name);
|
|
15447
|
-
x += nameW;
|
|
15448
|
-
if (isActiveGroup) {
|
|
15449
|
-
x += 6;
|
|
15450
|
-
for (const entry of tg.entries) {
|
|
15451
|
-
const entryColor = entry.color || palette.textMuted;
|
|
15452
|
-
const ew = measureLegendText(entry.value, LEGEND_ENTRY_FONT_SIZE);
|
|
15453
|
-
const entryG = groupG.append("g").attr("data-legend-entry", entry.value.toLowerCase()).style("cursor", "pointer");
|
|
15454
|
-
entryG.append("circle").attr("cx", x + LEGEND_DOT_R).attr("cy", LEGEND_HEIGHT / 2).attr("r", LEGEND_DOT_R).attr("fill", entryColor);
|
|
15455
|
-
entryG.append("text").attr("x", x + LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP).attr("y", LEGEND_HEIGHT / 2).attr("dominant-baseline", "central").attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).text(entry.value);
|
|
15456
|
-
x += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + ew + LEGEND_ENTRY_TRAIL;
|
|
15457
|
-
}
|
|
15458
|
-
}
|
|
15459
|
-
x += LEGEND_GROUP_GAP;
|
|
15951
|
+
const legendConfig = {
|
|
15952
|
+
groups: parsed.tagGroups,
|
|
15953
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
15954
|
+
mode: "fixed"
|
|
15955
|
+
};
|
|
15956
|
+
const legendState = { activeGroup };
|
|
15957
|
+
const legendG = svg.append("g").attr("transform", `translate(0,${titleOffset + 4})`);
|
|
15958
|
+
renderLegendD3(
|
|
15959
|
+
legendG,
|
|
15960
|
+
legendConfig,
|
|
15961
|
+
legendState,
|
|
15962
|
+
palette,
|
|
15963
|
+
isDark,
|
|
15964
|
+
void 0,
|
|
15965
|
+
width
|
|
15966
|
+
);
|
|
15967
|
+
legendG.selectAll("[data-legend-group]").classed("bl-legend-group", true);
|
|
15460
15968
|
}
|
|
15461
15969
|
}
|
|
15462
15970
|
function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark, options) {
|
|
@@ -15464,7 +15972,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
|
|
|
15464
15972
|
exportDims: options?.exportDims
|
|
15465
15973
|
});
|
|
15466
15974
|
}
|
|
15467
|
-
var d3Selection6, d3Shape4, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, META_FONT_SIZE3, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, CHAR_WIDTH_RATIO, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, lineGeneratorLR, lineGeneratorTB;
|
|
15975
|
+
var d3Selection6, d3Shape4, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, META_FONT_SIZE3, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, CHAR_WIDTH_RATIO, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, lineGeneratorLR, lineGeneratorTB, lineGeneratorLinear2;
|
|
15468
15976
|
var init_renderer6 = __esm({
|
|
15469
15977
|
"src/boxes-and-lines/renderer.ts"() {
|
|
15470
15978
|
"use strict";
|
|
@@ -15472,6 +15980,7 @@ var init_renderer6 = __esm({
|
|
|
15472
15980
|
d3Shape4 = __toESM(require("d3-shape"), 1);
|
|
15473
15981
|
init_fonts();
|
|
15474
15982
|
init_legend_constants();
|
|
15983
|
+
init_legend_d3();
|
|
15475
15984
|
init_title_constants();
|
|
15476
15985
|
init_color_utils();
|
|
15477
15986
|
init_tag_groups();
|
|
@@ -15492,6 +16001,7 @@ var init_renderer6 = __esm({
|
|
|
15492
16001
|
GROUP_LABEL_FONT_SIZE = 14;
|
|
15493
16002
|
lineGeneratorLR = d3Shape4.line().x((d) => d.x).y((d) => d.y).curve(d3Shape4.curveMonotoneX);
|
|
15494
16003
|
lineGeneratorTB = d3Shape4.line().x((d) => d.x).y((d) => d.y).curve(d3Shape4.curveMonotoneY);
|
|
16004
|
+
lineGeneratorLinear2 = d3Shape4.line().x((d) => d.x).y((d) => d.y).curve(d3Shape4.curveLinear);
|
|
15495
16005
|
}
|
|
15496
16006
|
});
|
|
15497
16007
|
|
|
@@ -17398,7 +17908,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
|
|
|
17398
17908
|
if (activeTagGroup) {
|
|
17399
17909
|
legendParent.attr("data-legend-active", activeTagGroup.toLowerCase());
|
|
17400
17910
|
}
|
|
17401
|
-
|
|
17911
|
+
renderLegend2(
|
|
17402
17912
|
legendParent,
|
|
17403
17913
|
layout,
|
|
17404
17914
|
palette,
|
|
@@ -17759,52 +18269,28 @@ function placeEdgeLabels(labels, edges, obstacleRects) {
|
|
|
17759
18269
|
placedRects.push({ x: lbl.x, y: lbl.y, w: lbl.bgW, h: lbl.bgH });
|
|
17760
18270
|
}
|
|
17761
18271
|
}
|
|
17762
|
-
function
|
|
17763
|
-
const
|
|
17764
|
-
|
|
17765
|
-
|
|
17766
|
-
|
|
17767
|
-
const
|
|
17768
|
-
|
|
17769
|
-
|
|
17770
|
-
|
|
17771
|
-
|
|
17772
|
-
|
|
17773
|
-
|
|
17774
|
-
|
|
17775
|
-
|
|
17776
|
-
|
|
17777
|
-
|
|
17778
|
-
|
|
17779
|
-
|
|
17780
|
-
|
|
17781
|
-
|
|
17782
|
-
|
|
17783
|
-
|
|
17784
|
-
const gY = fixedPositions != null ? 0 : group.y;
|
|
17785
|
-
const gEl = parent.append("g").attr("transform", `translate(${gX}, ${gY})`).attr("class", "c4-legend-group").attr("data-legend-group", group.name.toLowerCase()).style("cursor", "pointer");
|
|
17786
|
-
if (isActive) {
|
|
17787
|
-
gEl.append("rect").attr("width", group.width).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
17788
|
-
}
|
|
17789
|
-
const pillX = isActive ? LEGEND_CAPSULE_PAD : 0;
|
|
17790
|
-
const pillY = LEGEND_CAPSULE_PAD;
|
|
17791
|
-
const pillH = LEGEND_HEIGHT - LEGEND_CAPSULE_PAD * 2;
|
|
17792
|
-
gEl.append("rect").attr("x", pillX).attr("y", pillY).attr("width", pillWidth2).attr("height", pillH).attr("rx", pillH / 2).attr("fill", isActive ? palette.bg : groupBg);
|
|
17793
|
-
if (isActive) {
|
|
17794
|
-
gEl.append("rect").attr("x", pillX).attr("y", pillY).attr("width", pillWidth2).attr("height", pillH).attr("rx", pillH / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
|
|
17795
|
-
}
|
|
17796
|
-
gEl.append("text").attr("x", pillX + pillWidth2 / 2).attr("y", LEGEND_HEIGHT / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", "500").attr("fill", isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(pillLabel);
|
|
17797
|
-
if (isActive) {
|
|
17798
|
-
let entryX = pillX + pillWidth2 + 4;
|
|
17799
|
-
for (const entry of group.entries) {
|
|
17800
|
-
const entryG = gEl.append("g").attr("data-legend-entry", entry.value.toLowerCase()).style("cursor", "pointer");
|
|
17801
|
-
entryG.append("circle").attr("cx", entryX + LEGEND_DOT_R).attr("cy", LEGEND_HEIGHT / 2).attr("r", LEGEND_DOT_R).attr("fill", entry.color);
|
|
17802
|
-
const textX = entryX + LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP;
|
|
17803
|
-
entryG.append("text").attr("x", textX).attr("y", LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).text(entry.value);
|
|
17804
|
-
entryX = textX + measureLegendText(entry.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
17805
|
-
}
|
|
17806
|
-
}
|
|
17807
|
-
}
|
|
18272
|
+
function renderLegend2(parent, layout, palette, isDark, activeTagGroup, fixedWidth) {
|
|
18273
|
+
const groups = layout.legend.map((g) => ({
|
|
18274
|
+
name: g.name,
|
|
18275
|
+
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
18276
|
+
}));
|
|
18277
|
+
const legendConfig = {
|
|
18278
|
+
groups,
|
|
18279
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
18280
|
+
mode: "fixed"
|
|
18281
|
+
};
|
|
18282
|
+
const legendState = { activeGroup: activeTagGroup ?? null };
|
|
18283
|
+
const containerWidth = fixedWidth ?? layout.width;
|
|
18284
|
+
renderLegendD3(
|
|
18285
|
+
parent,
|
|
18286
|
+
legendConfig,
|
|
18287
|
+
legendState,
|
|
18288
|
+
palette,
|
|
18289
|
+
isDark,
|
|
18290
|
+
void 0,
|
|
18291
|
+
containerWidth
|
|
18292
|
+
);
|
|
18293
|
+
parent.selectAll("[data-legend-group]").classed("c4-legend-group", true);
|
|
17808
18294
|
}
|
|
17809
18295
|
function renderC4Containers(container, parsed, layout, palette, isDark, onClickItem, exportDims, activeTagGroup) {
|
|
17810
18296
|
d3Selection7.select(container).selectAll(":not([data-d3-tooltip])").remove();
|
|
@@ -18015,7 +18501,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
|
|
|
18015
18501
|
if (activeTagGroup) {
|
|
18016
18502
|
legendParent.attr("data-legend-active", activeTagGroup.toLowerCase());
|
|
18017
18503
|
}
|
|
18018
|
-
|
|
18504
|
+
renderLegend2(
|
|
18019
18505
|
legendParent,
|
|
18020
18506
|
layout,
|
|
18021
18507
|
palette,
|
|
@@ -18145,6 +18631,7 @@ var init_renderer7 = __esm({
|
|
|
18145
18631
|
init_parser6();
|
|
18146
18632
|
init_layout6();
|
|
18147
18633
|
init_legend_constants();
|
|
18634
|
+
init_legend_d3();
|
|
18148
18635
|
init_title_constants();
|
|
18149
18636
|
DIAGRAM_PADDING7 = 20;
|
|
18150
18637
|
MAX_SCALE5 = 3;
|
|
@@ -21032,17 +21519,17 @@ function computeInfraLegendGroups(nodes, tagGroups, palette, edges) {
|
|
|
21032
21519
|
color: r.color,
|
|
21033
21520
|
key: r.name.toLowerCase().replace(/\s+/g, "-")
|
|
21034
21521
|
}));
|
|
21035
|
-
const
|
|
21036
|
-
let
|
|
21522
|
+
const pillWidth3 = measureLegendText("Capabilities", LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
21523
|
+
let entriesWidth3 = 0;
|
|
21037
21524
|
for (const e of entries) {
|
|
21038
|
-
|
|
21525
|
+
entriesWidth3 += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(e.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
21039
21526
|
}
|
|
21040
21527
|
groups.push({
|
|
21041
21528
|
name: "Capabilities",
|
|
21042
21529
|
type: "role",
|
|
21043
21530
|
entries,
|
|
21044
|
-
width: LEGEND_CAPSULE_PAD * 2 +
|
|
21045
|
-
minifiedWidth:
|
|
21531
|
+
width: LEGEND_CAPSULE_PAD * 2 + pillWidth3 + 4 + entriesWidth3,
|
|
21532
|
+
minifiedWidth: pillWidth3
|
|
21046
21533
|
});
|
|
21047
21534
|
}
|
|
21048
21535
|
for (const tg of tagGroups) {
|
|
@@ -21057,113 +21544,88 @@ function computeInfraLegendGroups(nodes, tagGroups, palette, edges) {
|
|
|
21057
21544
|
}
|
|
21058
21545
|
}
|
|
21059
21546
|
if (entries.length === 0) continue;
|
|
21060
|
-
const
|
|
21061
|
-
let
|
|
21547
|
+
const pillWidth3 = measureLegendText(tg.name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
21548
|
+
let entriesWidth3 = 0;
|
|
21062
21549
|
for (const e of entries) {
|
|
21063
|
-
|
|
21550
|
+
entriesWidth3 += LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP + measureLegendText(e.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
21064
21551
|
}
|
|
21065
21552
|
groups.push({
|
|
21066
21553
|
name: tg.name,
|
|
21067
21554
|
type: "tag",
|
|
21068
21555
|
tagKey: (tg.alias ?? tg.name).toLowerCase(),
|
|
21069
21556
|
entries,
|
|
21070
|
-
width: LEGEND_CAPSULE_PAD * 2 +
|
|
21071
|
-
minifiedWidth:
|
|
21557
|
+
width: LEGEND_CAPSULE_PAD * 2 + pillWidth3 + 4 + entriesWidth3,
|
|
21558
|
+
minifiedWidth: pillWidth3
|
|
21072
21559
|
});
|
|
21073
21560
|
}
|
|
21074
21561
|
return groups;
|
|
21075
21562
|
}
|
|
21076
|
-
function
|
|
21077
|
-
if (!playback) return 0;
|
|
21078
|
-
const pillWidth2 = measureLegendText("Playback", LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
21079
|
-
if (!playback.expanded) return pillWidth2;
|
|
21080
|
-
let entriesW = 8;
|
|
21081
|
-
entriesW += LEGEND_PILL_FONT_SIZE * 0.8 + 6;
|
|
21082
|
-
for (const s of playback.speedOptions) {
|
|
21083
|
-
entriesW += measureLegendText(`${s}x`, LEGEND_ENTRY_FONT_SIZE) + SPEED_BADGE_H_PAD * 2 + SPEED_BADGE_GAP;
|
|
21084
|
-
}
|
|
21085
|
-
return LEGEND_CAPSULE_PAD * 2 + pillWidth2 + entriesW;
|
|
21086
|
-
}
|
|
21087
|
-
function renderLegend4(rootSvg, legendGroups, totalWidth, legendY, palette, isDark, activeGroup, playback) {
|
|
21563
|
+
function renderLegend3(rootSvg, legendGroups, totalWidth, legendY, palette, isDark, activeGroup, playback) {
|
|
21088
21564
|
if (legendGroups.length === 0 && !playback) return;
|
|
21089
21565
|
const legendG = rootSvg.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
21090
21566
|
if (activeGroup) {
|
|
21091
21567
|
legendG.attr("data-legend-active", activeGroup.toLowerCase());
|
|
21092
21568
|
}
|
|
21093
|
-
const
|
|
21094
|
-
|
|
21095
|
-
|
|
21096
|
-
|
|
21097
|
-
|
|
21569
|
+
const allGroups = legendGroups.map((g) => ({
|
|
21570
|
+
name: g.name,
|
|
21571
|
+
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
21572
|
+
}));
|
|
21573
|
+
if (playback) {
|
|
21574
|
+
allGroups.push({ name: "Playback", entries: [] });
|
|
21575
|
+
}
|
|
21576
|
+
const legendConfig = {
|
|
21577
|
+
groups: allGroups,
|
|
21578
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
21579
|
+
mode: "fixed",
|
|
21580
|
+
showEmptyGroups: true
|
|
21581
|
+
};
|
|
21582
|
+
const legendState = { activeGroup };
|
|
21583
|
+
renderLegendD3(
|
|
21584
|
+
legendG,
|
|
21585
|
+
legendConfig,
|
|
21586
|
+
legendState,
|
|
21587
|
+
palette,
|
|
21588
|
+
isDark,
|
|
21589
|
+
void 0,
|
|
21590
|
+
totalWidth
|
|
21591
|
+
);
|
|
21592
|
+
legendG.selectAll("[data-legend-group]").classed("infra-legend-group", true);
|
|
21098
21593
|
for (const group of legendGroups) {
|
|
21099
|
-
const
|
|
21100
|
-
const
|
|
21101
|
-
|
|
21102
|
-
|
|
21103
|
-
|
|
21104
|
-
|
|
21105
|
-
|
|
21106
|
-
}
|
|
21107
|
-
const pillXOff = isActive ? LEGEND_CAPSULE_PAD : 0;
|
|
21108
|
-
const pillYOff = LEGEND_CAPSULE_PAD;
|
|
21109
|
-
const pillH = LEGEND_HEIGHT - LEGEND_CAPSULE_PAD * 2;
|
|
21110
|
-
gEl.append("rect").attr("x", pillXOff).attr("y", pillYOff).attr("width", pillWidth2).attr("height", pillH).attr("rx", pillH / 2).attr("fill", isActive ? palette.bg : groupBg);
|
|
21111
|
-
if (isActive) {
|
|
21112
|
-
gEl.append("rect").attr("x", pillXOff).attr("y", pillYOff).attr("width", pillWidth2).attr("height", pillH).attr("rx", pillH / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
|
|
21113
|
-
}
|
|
21114
|
-
gEl.append("text").attr("x", pillXOff + pillWidth2 / 2).attr("y", LEGEND_HEIGHT / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("font-family", FONT_FAMILY).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", "500").attr("fill", isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(pillLabel);
|
|
21115
|
-
if (isActive) {
|
|
21116
|
-
let entryX = pillXOff + pillWidth2 + 4;
|
|
21117
|
-
for (const entry of group.entries) {
|
|
21118
|
-
const entryG = gEl.append("g").attr("class", "infra-legend-entry").attr("data-legend-entry", entry.key.toLowerCase()).attr("data-legend-color", entry.color).attr("data-legend-type", group.type).attr(
|
|
21594
|
+
const groupKey = group.name.toLowerCase();
|
|
21595
|
+
for (const entry of group.entries) {
|
|
21596
|
+
const entryEl = legendG.select(
|
|
21597
|
+
`[data-legend-group="${groupKey}"] [data-legend-entry="${entry.value.toLowerCase()}"]`
|
|
21598
|
+
);
|
|
21599
|
+
if (!entryEl.empty()) {
|
|
21600
|
+
entryEl.attr("data-legend-entry", entry.key.toLowerCase()).attr("data-legend-color", entry.color).attr("data-legend-type", group.type).attr(
|
|
21119
21601
|
"data-legend-tag-group",
|
|
21120
21602
|
group.type === "tag" ? group.tagKey ?? "" : null
|
|
21121
|
-
)
|
|
21122
|
-
entryG.append("circle").attr("cx", entryX + LEGEND_DOT_R).attr("cy", LEGEND_HEIGHT / 2).attr("r", LEGEND_DOT_R).attr("fill", entry.color);
|
|
21123
|
-
const textX = entryX + LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP;
|
|
21124
|
-
entryG.append("text").attr("x", textX).attr("y", LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1).attr("font-family", FONT_FAMILY).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).text(entry.value);
|
|
21125
|
-
entryX = textX + measureLegendText(entry.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
21603
|
+
);
|
|
21126
21604
|
}
|
|
21127
21605
|
}
|
|
21128
|
-
cursorX += effectiveW(group) + LEGEND_GROUP_GAP;
|
|
21129
21606
|
}
|
|
21130
|
-
|
|
21131
|
-
|
|
21132
|
-
|
|
21133
|
-
|
|
21134
|
-
|
|
21135
|
-
const
|
|
21136
|
-
|
|
21137
|
-
|
|
21138
|
-
|
|
21139
|
-
|
|
21140
|
-
|
|
21141
|
-
const
|
|
21142
|
-
|
|
21143
|
-
|
|
21144
|
-
|
|
21145
|
-
|
|
21146
|
-
|
|
21147
|
-
|
|
21148
|
-
|
|
21149
|
-
|
|
21150
|
-
|
|
21151
|
-
|
|
21152
|
-
pbG.append("text").attr("x", entryX).attr("y", entryY).attr("font-family", FONT_FAMILY).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("fill", palette.textMuted).attr("data-playback-action", "toggle-pause").style("cursor", "pointer").text(ppLabel);
|
|
21153
|
-
entryX += LEGEND_PILL_FONT_SIZE * 0.8 + 6;
|
|
21154
|
-
for (const s of playback.speedOptions) {
|
|
21155
|
-
const label = `${s}x`;
|
|
21156
|
-
const isActive = playback.speed === s;
|
|
21157
|
-
const slotW = measureLegendText(label, LEGEND_ENTRY_FONT_SIZE) + SPEED_BADGE_H_PAD * 2;
|
|
21158
|
-
const badgeH = LEGEND_ENTRY_FONT_SIZE + SPEED_BADGE_V_PAD * 2;
|
|
21159
|
-
const badgeY = (LEGEND_HEIGHT - badgeH) / 2;
|
|
21160
|
-
const speedG = pbG.append("g").attr("data-playback-action", "set-speed").attr("data-playback-value", String(s)).style("cursor", "pointer");
|
|
21161
|
-
speedG.append("rect").attr("x", entryX).attr("y", badgeY).attr("width", slotW).attr("height", badgeH).attr("rx", badgeH / 2).attr("fill", isActive ? palette.primary : "transparent");
|
|
21162
|
-
speedG.append("text").attr("x", entryX + slotW / 2).attr("y", entryY).attr("font-family", FONT_FAMILY).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("font-weight", isActive ? "600" : "400").attr("fill", isActive ? palette.bg : palette.textMuted).attr("text-anchor", "middle").text(label);
|
|
21163
|
-
entryX += slotW + SPEED_BADGE_GAP;
|
|
21164
|
-
}
|
|
21165
|
-
}
|
|
21166
|
-
cursorX += fullW + LEGEND_GROUP_GAP;
|
|
21607
|
+
const playbackEl = legendG.select('[data-legend-group="playback"]');
|
|
21608
|
+
if (!playbackEl.empty()) {
|
|
21609
|
+
playbackEl.classed("infra-playback-pill", true);
|
|
21610
|
+
}
|
|
21611
|
+
if (playback && playback.expanded && !playbackEl.empty()) {
|
|
21612
|
+
const pillWidth3 = measureLegendText("Playback", LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
21613
|
+
let entryX = pillWidth3 + 8;
|
|
21614
|
+
const entryY = LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1;
|
|
21615
|
+
const ppLabel = playback.paused ? "\u25B6" : "\u23F8";
|
|
21616
|
+
playbackEl.append("text").attr("x", entryX).attr("y", entryY).attr("font-family", FONT_FAMILY).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("fill", palette.textMuted).attr("data-playback-action", "toggle-pause").style("cursor", "pointer").text(ppLabel);
|
|
21617
|
+
entryX += LEGEND_PILL_FONT_SIZE * 0.8 + 6;
|
|
21618
|
+
for (const s of playback.speedOptions) {
|
|
21619
|
+
const label = `${s}x`;
|
|
21620
|
+
const isSpeedActive = playback.speed === s;
|
|
21621
|
+
const slotW = measureLegendText(label, LEGEND_ENTRY_FONT_SIZE) + SPEED_BADGE_H_PAD * 2;
|
|
21622
|
+
const badgeH = LEGEND_ENTRY_FONT_SIZE + SPEED_BADGE_V_PAD * 2;
|
|
21623
|
+
const badgeY = (LEGEND_HEIGHT - badgeH) / 2;
|
|
21624
|
+
const speedG = playbackEl.append("g").attr("data-playback-action", "set-speed").attr("data-playback-value", String(s)).style("cursor", "pointer");
|
|
21625
|
+
speedG.append("rect").attr("x", entryX).attr("y", badgeY).attr("width", slotW).attr("height", badgeH).attr("rx", badgeH / 2).attr("fill", isSpeedActive ? palette.primary : "transparent");
|
|
21626
|
+
speedG.append("text").attr("x", entryX + slotW / 2).attr("y", entryY).attr("font-family", FONT_FAMILY).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("font-weight", isSpeedActive ? "600" : "400").attr("fill", isSpeedActive ? palette.bg : palette.textMuted).attr("text-anchor", "middle").text(label);
|
|
21627
|
+
entryX += slotW + SPEED_BADGE_GAP;
|
|
21628
|
+
}
|
|
21167
21629
|
}
|
|
21168
21630
|
}
|
|
21169
21631
|
function renderInfra(container, layout, palette, isDark, title, titleLineNumber, tagGroups, activeGroup, animate, playback, expandedNodeIds, exportMode, collapsedNodes) {
|
|
@@ -21294,7 +21756,7 @@ function renderInfra(container, layout, palette, isDark, title, titleLineNumber,
|
|
|
21294
21756
|
"viewBox",
|
|
21295
21757
|
`0 0 ${containerWidth} ${LEGEND_HEIGHT + LEGEND_FIXED_GAP3}`
|
|
21296
21758
|
).attr("preserveAspectRatio", "xMidYMid meet").style("display", "block").style("pointer-events", "none");
|
|
21297
|
-
|
|
21759
|
+
renderLegend3(
|
|
21298
21760
|
legendSvg,
|
|
21299
21761
|
legendGroups,
|
|
21300
21762
|
containerWidth,
|
|
@@ -21306,7 +21768,7 @@ function renderInfra(container, layout, palette, isDark, title, titleLineNumber,
|
|
|
21306
21768
|
);
|
|
21307
21769
|
legendSvg.selectAll(".infra-legend-group").style("pointer-events", "auto");
|
|
21308
21770
|
} else {
|
|
21309
|
-
|
|
21771
|
+
renderLegend3(
|
|
21310
21772
|
rootSvg,
|
|
21311
21773
|
legendGroups,
|
|
21312
21774
|
totalWidth,
|
|
@@ -21340,6 +21802,7 @@ var init_renderer8 = __esm({
|
|
|
21340
21802
|
init_compute();
|
|
21341
21803
|
init_layout8();
|
|
21342
21804
|
init_legend_constants();
|
|
21805
|
+
init_legend_d3();
|
|
21343
21806
|
init_title_constants();
|
|
21344
21807
|
NODE_FONT_SIZE3 = 13;
|
|
21345
21808
|
META_FONT_SIZE5 = 10;
|
|
@@ -22965,7 +23428,7 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
22965
23428
|
const isActive = activeGroupName?.toLowerCase() === group.name.toLowerCase();
|
|
22966
23429
|
const isSwimlane = currentSwimlaneGroup?.toLowerCase() === group.name.toLowerCase();
|
|
22967
23430
|
const showIcon = !legendViewMode && tagGroups.length > 0;
|
|
22968
|
-
const iconReserve = showIcon ? LEGEND_ICON_W : 0;
|
|
23431
|
+
const iconReserve = showIcon && isActive ? LEGEND_ICON_W : 0;
|
|
22969
23432
|
const pillW = measureLegendText(group.name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD + iconReserve;
|
|
22970
23433
|
let groupW = pillW;
|
|
22971
23434
|
if (isActive) {
|
|
@@ -22992,83 +23455,110 @@ function renderTagLegend(svg, chartG, tagGroups, activeGroupName, chartLeftMargi
|
|
|
22992
23455
|
const legendX = (containerWidth - totalW) / 2;
|
|
22993
23456
|
const legendRow = svg.append("g").attr("class", "gantt-tag-legend-container").attr("transform", `translate(${legendX}, ${legendY})`);
|
|
22994
23457
|
let cursorX = 0;
|
|
22995
|
-
|
|
22996
|
-
const group = visibleGroups[i];
|
|
22997
|
-
const isActive = activeGroupName?.toLowerCase() === group.name.toLowerCase();
|
|
22998
|
-
const isSwimlane = currentSwimlaneGroup?.toLowerCase() === group.name.toLowerCase();
|
|
23458
|
+
if (visibleGroups.length > 0) {
|
|
22999
23459
|
const showIcon = !legendViewMode && tagGroups.length > 0;
|
|
23000
23460
|
const iconReserve = showIcon ? LEGEND_ICON_W : 0;
|
|
23001
|
-
const
|
|
23002
|
-
|
|
23003
|
-
|
|
23004
|
-
|
|
23005
|
-
|
|
23461
|
+
const legendGroups = visibleGroups.map((g) => {
|
|
23462
|
+
const key = g.name.toLowerCase();
|
|
23463
|
+
const entries = filteredEntries.get(key) ?? g.entries;
|
|
23464
|
+
return {
|
|
23465
|
+
name: g.name,
|
|
23466
|
+
entries: entries.map((e) => ({ value: e.value, color: e.color }))
|
|
23467
|
+
};
|
|
23006
23468
|
});
|
|
23007
|
-
|
|
23008
|
-
|
|
23009
|
-
|
|
23010
|
-
|
|
23011
|
-
|
|
23012
|
-
|
|
23013
|
-
|
|
23014
|
-
|
|
23015
|
-
}
|
|
23016
|
-
const
|
|
23017
|
-
|
|
23018
|
-
|
|
23019
|
-
|
|
23020
|
-
|
|
23021
|
-
|
|
23022
|
-
|
|
23023
|
-
|
|
23024
|
-
|
|
23025
|
-
if (onSwimlaneChange) {
|
|
23026
|
-
onSwimlaneChange(
|
|
23027
|
-
currentSwimlaneGroup?.toLowerCase() === group.name.toLowerCase() ? null : group.name
|
|
23028
|
-
);
|
|
23029
|
-
}
|
|
23030
|
-
});
|
|
23031
|
-
}
|
|
23032
|
-
if (isActive) {
|
|
23033
|
-
const tagKey = group.name.toLowerCase();
|
|
23034
|
-
const entries = filteredEntries.get(tagKey) ?? group.entries;
|
|
23035
|
-
let ex = pillXOff + pillW + LEGEND_CAPSULE_PAD + 4;
|
|
23036
|
-
for (const entry of entries) {
|
|
23037
|
-
const entryValue = entry.value.toLowerCase();
|
|
23038
|
-
const entryG = gEl.append("g").attr("class", "gantt-legend-entry").attr("data-line-number", String(entry.lineNumber)).style("cursor", "pointer");
|
|
23039
|
-
entryG.append("circle").attr("cx", ex + LEGEND_DOT_R).attr("cy", LEGEND_HEIGHT / 2).attr("r", LEGEND_DOT_R).attr("fill", entry.color);
|
|
23040
|
-
entryG.append("text").attr("x", ex + LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP).attr("y", LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 2).attr("text-anchor", "start").attr("font-size", `${LEGEND_ENTRY_FONT_SIZE}px`).attr("fill", palette.textMuted).text(entry.value);
|
|
23041
|
-
entryG.on("mouseenter", () => {
|
|
23469
|
+
const legendConfig = {
|
|
23470
|
+
groups: legendGroups,
|
|
23471
|
+
position: {
|
|
23472
|
+
placement: "top-center",
|
|
23473
|
+
titleRelation: "below-title"
|
|
23474
|
+
},
|
|
23475
|
+
mode: "fixed",
|
|
23476
|
+
capsulePillAddonWidth: iconReserve
|
|
23477
|
+
};
|
|
23478
|
+
const legendState = { activeGroup: activeGroupName };
|
|
23479
|
+
const tagGroupsW = visibleGroups.reduce((s, _, i) => s + groupWidths[i], 0) + Math.max(0, (visibleGroups.length - 1) * LEGEND_GROUP_GAP);
|
|
23480
|
+
const tagGroupG = legendRow.append("g");
|
|
23481
|
+
const legendCallbacks = {
|
|
23482
|
+
onGroupToggle: onToggle,
|
|
23483
|
+
onEntryHover: (groupName, entryValue) => {
|
|
23484
|
+
const tagKey = groupName.toLowerCase();
|
|
23485
|
+
if (entryValue) {
|
|
23486
|
+
const ev = entryValue.toLowerCase();
|
|
23042
23487
|
chartG.selectAll(".gantt-task").each(function() {
|
|
23043
23488
|
const el = d3Selection10.select(this);
|
|
23044
|
-
|
|
23045
|
-
|
|
23489
|
+
el.attr(
|
|
23490
|
+
"opacity",
|
|
23491
|
+
el.attr(`data-tag-${tagKey}`) === ev ? 1 : FADE_OPACITY
|
|
23492
|
+
);
|
|
23046
23493
|
});
|
|
23047
23494
|
chartG.selectAll(".gantt-milestone").attr("opacity", FADE_OPACITY);
|
|
23048
23495
|
chartG.selectAll(".gantt-group-bar, .gantt-group-summary").attr("opacity", FADE_OPACITY);
|
|
23049
23496
|
svg.selectAll(".gantt-task-label").each(function() {
|
|
23050
23497
|
const el = d3Selection10.select(this);
|
|
23051
|
-
|
|
23052
|
-
|
|
23498
|
+
el.attr(
|
|
23499
|
+
"opacity",
|
|
23500
|
+
el.attr(`data-tag-${tagKey}`) === ev ? 1 : FADE_OPACITY
|
|
23501
|
+
);
|
|
23053
23502
|
});
|
|
23054
23503
|
svg.selectAll(".gantt-group-label").attr("opacity", FADE_OPACITY);
|
|
23055
23504
|
svg.selectAll(".gantt-lane-header").each(function() {
|
|
23056
23505
|
const el = d3Selection10.select(this);
|
|
23057
|
-
|
|
23058
|
-
|
|
23506
|
+
el.attr(
|
|
23507
|
+
"opacity",
|
|
23508
|
+
el.attr(`data-tag-${tagKey}`) === ev ? 1 : FADE_OPACITY
|
|
23509
|
+
);
|
|
23059
23510
|
});
|
|
23060
23511
|
chartG.selectAll(".gantt-lane-band, .gantt-lane-accent").attr("opacity", FADE_OPACITY);
|
|
23061
|
-
}
|
|
23512
|
+
} else {
|
|
23062
23513
|
if (criticalPathActive) {
|
|
23063
23514
|
applyCriticalPathHighlight(svg, chartG);
|
|
23064
23515
|
} else {
|
|
23065
23516
|
resetHighlightAll(svg, chartG);
|
|
23066
23517
|
}
|
|
23067
|
-
}
|
|
23068
|
-
|
|
23518
|
+
}
|
|
23519
|
+
},
|
|
23520
|
+
onGroupRendered: (groupName, groupEl, _isActive) => {
|
|
23521
|
+
const group = visibleGroups.find((g) => g.name === groupName);
|
|
23522
|
+
if (group) {
|
|
23523
|
+
groupEl.attr("data-tag-group", group.name).attr("data-line-number", String(group.lineNumber));
|
|
23524
|
+
}
|
|
23525
|
+
if (showIcon && _isActive) {
|
|
23526
|
+
const isSwimlane = currentSwimlaneGroup?.toLowerCase() === groupName.toLowerCase();
|
|
23527
|
+
const textW = measureLegendText(groupName, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
23528
|
+
const pillXOff = LEGEND_CAPSULE_PAD;
|
|
23529
|
+
const iconX = pillXOff + textW + 3;
|
|
23530
|
+
const iconY = (LEGEND_HEIGHT - 10) / 2;
|
|
23531
|
+
const iconEl = drawSwimlaneIcon(
|
|
23532
|
+
groupEl,
|
|
23533
|
+
iconX,
|
|
23534
|
+
iconY,
|
|
23535
|
+
isSwimlane,
|
|
23536
|
+
palette
|
|
23537
|
+
);
|
|
23538
|
+
iconEl.append("title").text(`Group by ${groupName}`);
|
|
23539
|
+
iconEl.style("cursor", "pointer").on("click", (event) => {
|
|
23540
|
+
event.stopPropagation();
|
|
23541
|
+
if (onSwimlaneChange) {
|
|
23542
|
+
onSwimlaneChange(
|
|
23543
|
+
currentSwimlaneGroup?.toLowerCase() === groupName.toLowerCase() ? null : groupName
|
|
23544
|
+
);
|
|
23545
|
+
}
|
|
23546
|
+
});
|
|
23547
|
+
}
|
|
23069
23548
|
}
|
|
23549
|
+
};
|
|
23550
|
+
renderLegendD3(
|
|
23551
|
+
tagGroupG,
|
|
23552
|
+
legendConfig,
|
|
23553
|
+
legendState,
|
|
23554
|
+
palette,
|
|
23555
|
+
isDark,
|
|
23556
|
+
legendCallbacks,
|
|
23557
|
+
tagGroupsW
|
|
23558
|
+
);
|
|
23559
|
+
for (let i = 0; i < visibleGroups.length; i++) {
|
|
23560
|
+
cursorX += groupWidths[i] + LEGEND_GROUP_GAP;
|
|
23070
23561
|
}
|
|
23071
|
-
cursorX += groupW + LEGEND_GROUP_GAP;
|
|
23072
23562
|
}
|
|
23073
23563
|
if (hasCriticalPath) {
|
|
23074
23564
|
const cpLineNum = optionLineNumbers["critical-path"];
|
|
@@ -23697,6 +24187,7 @@ var init_renderer9 = __esm({
|
|
|
23697
24187
|
init_tag_groups();
|
|
23698
24188
|
init_d3();
|
|
23699
24189
|
init_legend_constants();
|
|
24190
|
+
init_legend_d3();
|
|
23700
24191
|
init_title_constants();
|
|
23701
24192
|
BAR_H = 22;
|
|
23702
24193
|
ROW_GAP = 6;
|
|
@@ -24866,57 +25357,29 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
|
|
|
24866
25357
|
}
|
|
24867
25358
|
if (parsed.tagGroups.length > 0) {
|
|
24868
25359
|
const legendY = TOP_MARGIN + titleOffset;
|
|
24869
|
-
const
|
|
24870
|
-
|
|
24871
|
-
|
|
24872
|
-
if (tg.entries.length === 0) continue;
|
|
24873
|
-
const isActive = !!activeTagGroup && tg.name.toLowerCase() === activeTagGroup.toLowerCase();
|
|
24874
|
-
const pillWidth2 = measureLegendText(tg.name, LEGEND_PILL_FONT_SIZE) + LEGEND_PILL_PAD;
|
|
24875
|
-
const entries = tg.entries.map((e) => ({
|
|
25360
|
+
const resolvedGroups = parsed.tagGroups.filter((tg) => tg.entries.length > 0).map((tg) => ({
|
|
25361
|
+
name: tg.name,
|
|
25362
|
+
entries: tg.entries.map((e) => ({
|
|
24876
25363
|
value: e.value,
|
|
24877
25364
|
color: resolveColor(e.color) ?? e.color
|
|
24878
|
-
}))
|
|
24879
|
-
|
|
24880
|
-
|
|
24881
|
-
|
|
24882
|
-
|
|
24883
|
-
|
|
24884
|
-
|
|
24885
|
-
|
|
24886
|
-
|
|
24887
|
-
|
|
24888
|
-
|
|
24889
|
-
|
|
24890
|
-
|
|
24891
|
-
|
|
24892
|
-
|
|
24893
|
-
|
|
24894
|
-
|
|
24895
|
-
|
|
24896
|
-
const gEl = legendContainer.append("g").attr("transform", `translate(${legendX}, ${legendY})`).attr("class", "sequence-legend-group").attr("data-legend-group", item.group.name.toLowerCase()).style("cursor", "pointer");
|
|
24897
|
-
if (item.isActive) {
|
|
24898
|
-
gEl.append("rect").attr("width", item.totalWidth).attr("height", LEGEND_HEIGHT).attr("rx", LEGEND_HEIGHT / 2).attr("fill", groupBg);
|
|
24899
|
-
}
|
|
24900
|
-
const pillXOff = item.isActive ? LEGEND_CAPSULE_PAD : 0;
|
|
24901
|
-
const pillYOff = LEGEND_CAPSULE_PAD;
|
|
24902
|
-
const pillH = LEGEND_HEIGHT - LEGEND_CAPSULE_PAD * 2;
|
|
24903
|
-
gEl.append("rect").attr("x", pillXOff).attr("y", pillYOff).attr("width", item.pillWidth).attr("height", pillH).attr("rx", pillH / 2).attr("fill", item.isActive ? palette.bg : groupBg);
|
|
24904
|
-
if (item.isActive) {
|
|
24905
|
-
gEl.append("rect").attr("x", pillXOff).attr("y", pillYOff).attr("width", item.pillWidth).attr("height", pillH).attr("rx", pillH / 2).attr("fill", "none").attr("stroke", mix(palette.textMuted, palette.bg, 50)).attr("stroke-width", 0.75);
|
|
24906
|
-
}
|
|
24907
|
-
gEl.append("text").attr("x", pillXOff + item.pillWidth / 2).attr("y", LEGEND_HEIGHT / 2 + LEGEND_PILL_FONT_SIZE / 2 - 2).attr("font-size", LEGEND_PILL_FONT_SIZE).attr("font-weight", "500").attr("fill", item.isActive ? palette.text : palette.textMuted).attr("text-anchor", "middle").text(item.group.name);
|
|
24908
|
-
if (item.isActive) {
|
|
24909
|
-
let entryX = pillXOff + item.pillWidth + 4;
|
|
24910
|
-
for (const entry of item.entries) {
|
|
24911
|
-
const entryG = gEl.append("g").attr("data-legend-entry", entry.value.toLowerCase()).style("cursor", "pointer");
|
|
24912
|
-
entryG.append("circle").attr("cx", entryX + LEGEND_DOT_R).attr("cy", LEGEND_HEIGHT / 2).attr("r", LEGEND_DOT_R).attr("fill", entry.color);
|
|
24913
|
-
const textX = entryX + LEGEND_DOT_R * 2 + LEGEND_ENTRY_DOT_GAP;
|
|
24914
|
-
entryG.append("text").attr("x", textX).attr("y", LEGEND_HEIGHT / 2 + LEGEND_ENTRY_FONT_SIZE / 2 - 1).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).text(entry.value);
|
|
24915
|
-
entryX = textX + measureLegendText(entry.value, LEGEND_ENTRY_FONT_SIZE) + LEGEND_ENTRY_TRAIL;
|
|
24916
|
-
}
|
|
24917
|
-
}
|
|
24918
|
-
legendX += item.totalWidth + LEGEND_GROUP_GAP;
|
|
24919
|
-
}
|
|
25365
|
+
}))
|
|
25366
|
+
}));
|
|
25367
|
+
const legendConfig = {
|
|
25368
|
+
groups: resolvedGroups,
|
|
25369
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
25370
|
+
mode: "fixed"
|
|
25371
|
+
};
|
|
25372
|
+
const legendState = { activeGroup: activeTagGroup ?? null };
|
|
25373
|
+
const legendG = svg.append("g").attr("class", "sequence-legend").attr("transform", `translate(0,${legendY})`);
|
|
25374
|
+
renderLegendD3(
|
|
25375
|
+
legendG,
|
|
25376
|
+
legendConfig,
|
|
25377
|
+
legendState,
|
|
25378
|
+
palette,
|
|
25379
|
+
isDark,
|
|
25380
|
+
void 0,
|
|
25381
|
+
svgWidth
|
|
25382
|
+
);
|
|
24920
25383
|
}
|
|
24921
25384
|
for (const group of groups) {
|
|
24922
25385
|
if (group.participantIds.length === 0) continue;
|
|
@@ -25476,6 +25939,7 @@ var init_renderer10 = __esm({
|
|
|
25476
25939
|
init_parser();
|
|
25477
25940
|
init_tag_resolution();
|
|
25478
25941
|
init_legend_constants();
|
|
25942
|
+
init_legend_d3();
|
|
25479
25943
|
init_title_constants();
|
|
25480
25944
|
PARTICIPANT_GAP = 160;
|
|
25481
25945
|
PARTICIPANT_BOX_WIDTH = 120;
|
|
@@ -28131,7 +28595,6 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
28131
28595
|
const LG_ENTRY_FONT_SIZE = LEGEND_ENTRY_FONT_SIZE;
|
|
28132
28596
|
const LG_ENTRY_DOT_GAP = LEGEND_ENTRY_DOT_GAP;
|
|
28133
28597
|
const LG_ENTRY_TRAIL = LEGEND_ENTRY_TRAIL;
|
|
28134
|
-
const LG_GROUP_GAP = LEGEND_GROUP_GAP;
|
|
28135
28598
|
const LG_ICON_W = 20;
|
|
28136
28599
|
const mainSvg = d3Selection13.select(container).select("svg");
|
|
28137
28600
|
const mainG = mainSvg.select("g");
|
|
@@ -28170,11 +28633,6 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
28170
28633
|
(lg) => effectiveColorKey != null && lg.group.name.toLowerCase() === effectiveColorKey
|
|
28171
28634
|
) : legendGroups;
|
|
28172
28635
|
if (visibleGroups.length === 0) return;
|
|
28173
|
-
const totalW = visibleGroups.reduce((s, lg) => {
|
|
28174
|
-
const isActive = viewMode || currentActiveGroup != null && lg.group.name.toLowerCase() === currentActiveGroup.toLowerCase();
|
|
28175
|
-
return s + (isActive ? lg.expandedWidth : lg.minifiedWidth);
|
|
28176
|
-
}, 0) + (visibleGroups.length - 1) * LG_GROUP_GAP;
|
|
28177
|
-
let cx = (width - totalW) / 2;
|
|
28178
28636
|
const legendContainer = mainSvg.append("g").attr("class", "tl-tag-legend-container");
|
|
28179
28637
|
if (currentActiveGroup) {
|
|
28180
28638
|
legendContainer.attr(
|
|
@@ -28182,82 +28640,85 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
28182
28640
|
currentActiveGroup.toLowerCase()
|
|
28183
28641
|
);
|
|
28184
28642
|
}
|
|
28185
|
-
|
|
28186
|
-
|
|
28187
|
-
|
|
28188
|
-
|
|
28189
|
-
|
|
28190
|
-
|
|
28191
|
-
|
|
28192
|
-
|
|
28193
|
-
|
|
28194
|
-
|
|
28195
|
-
|
|
28196
|
-
|
|
28197
|
-
|
|
28198
|
-
|
|
28199
|
-
|
|
28200
|
-
|
|
28201
|
-
|
|
28202
|
-
|
|
28203
|
-
|
|
28204
|
-
|
|
28205
|
-
|
|
28206
|
-
|
|
28207
|
-
|
|
28208
|
-
|
|
28209
|
-
|
|
28210
|
-
|
|
28211
|
-
|
|
28212
|
-
|
|
28213
|
-
|
|
28214
|
-
|
|
28643
|
+
const iconAddon = viewMode ? 0 : LG_ICON_W;
|
|
28644
|
+
const centralGroups = visibleGroups.map((lg) => ({
|
|
28645
|
+
name: lg.group.name,
|
|
28646
|
+
entries: lg.group.entries.map((e) => ({
|
|
28647
|
+
value: e.value,
|
|
28648
|
+
color: e.color
|
|
28649
|
+
}))
|
|
28650
|
+
}));
|
|
28651
|
+
const centralActive = viewMode ? effectiveColorKey : currentActiveGroup;
|
|
28652
|
+
const centralConfig = {
|
|
28653
|
+
groups: centralGroups,
|
|
28654
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
28655
|
+
mode: "fixed",
|
|
28656
|
+
capsulePillAddonWidth: iconAddon
|
|
28657
|
+
};
|
|
28658
|
+
const centralState = { activeGroup: centralActive };
|
|
28659
|
+
const centralCallbacks = viewMode ? {} : {
|
|
28660
|
+
onGroupToggle: (groupName) => {
|
|
28661
|
+
currentActiveGroup = currentActiveGroup === groupName.toLowerCase() ? null : groupName.toLowerCase();
|
|
28662
|
+
drawLegend2();
|
|
28663
|
+
recolorEvents2();
|
|
28664
|
+
onTagStateChange?.(currentActiveGroup, currentSwimlaneGroup);
|
|
28665
|
+
},
|
|
28666
|
+
onEntryHover: (groupName, entryValue) => {
|
|
28667
|
+
const tagKey = groupName.toLowerCase();
|
|
28668
|
+
if (entryValue) {
|
|
28669
|
+
const tagVal = entryValue.toLowerCase();
|
|
28670
|
+
fadeToTagValue(mainG, tagKey, tagVal);
|
|
28671
|
+
mainSvg.selectAll("[data-legend-entry]").each(function() {
|
|
28672
|
+
const el = d3Selection13.select(this);
|
|
28673
|
+
const ev = el.attr("data-legend-entry");
|
|
28674
|
+
const eg = el.attr("data-tag-group") ?? el.node()?.closest?.("[data-tag-group]")?.getAttribute("data-tag-group");
|
|
28675
|
+
el.attr(
|
|
28676
|
+
"opacity",
|
|
28677
|
+
eg === tagKey && ev === tagVal ? 1 : FADE_OPACITY2
|
|
28678
|
+
);
|
|
28679
|
+
});
|
|
28680
|
+
} else {
|
|
28681
|
+
fadeReset(mainG);
|
|
28682
|
+
mainSvg.selectAll("[data-legend-entry]").attr("opacity", 1);
|
|
28683
|
+
}
|
|
28684
|
+
},
|
|
28685
|
+
onGroupRendered: (groupName, groupEl, isActive) => {
|
|
28686
|
+
const groupKey = groupName.toLowerCase();
|
|
28687
|
+
groupEl.attr("data-tag-group", groupKey);
|
|
28688
|
+
if (isActive && !viewMode) {
|
|
28689
|
+
const isSwimActive = currentSwimlaneGroup != null && currentSwimlaneGroup.toLowerCase() === groupKey;
|
|
28690
|
+
const pillWidth3 = measureLegendText(groupName, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
28691
|
+
const pillXOff = LG_CAPSULE_PAD;
|
|
28692
|
+
const iconX = pillXOff + pillWidth3 + 5;
|
|
28215
28693
|
const iconY = (LG_HEIGHT - 10) / 2;
|
|
28216
|
-
const iconEl = drawSwimlaneIcon3(
|
|
28694
|
+
const iconEl = drawSwimlaneIcon3(
|
|
28695
|
+
groupEl,
|
|
28696
|
+
iconX,
|
|
28697
|
+
iconY,
|
|
28698
|
+
isSwimActive
|
|
28699
|
+
);
|
|
28217
28700
|
iconEl.attr("data-swimlane-toggle", groupKey).on("click", (event) => {
|
|
28218
28701
|
event.stopPropagation();
|
|
28219
28702
|
currentSwimlaneGroup = currentSwimlaneGroup === groupKey ? null : groupKey;
|
|
28220
|
-
onTagStateChange?.(
|
|
28703
|
+
onTagStateChange?.(
|
|
28704
|
+
currentActiveGroup,
|
|
28705
|
+
currentSwimlaneGroup
|
|
28706
|
+
);
|
|
28221
28707
|
relayout2();
|
|
28222
28708
|
});
|
|
28223
|
-
entryX = pillXOff + pillWidth2 + LG_ICON_W + 4;
|
|
28224
|
-
} else {
|
|
28225
|
-
entryX = pillXOff + pillWidth2 + 8;
|
|
28226
|
-
}
|
|
28227
|
-
for (const entry of lg.group.entries) {
|
|
28228
|
-
const tagKey = lg.group.name.toLowerCase();
|
|
28229
|
-
const tagVal = entry.value.toLowerCase();
|
|
28230
|
-
const entryG = gEl.append("g").attr("class", "tl-tag-legend-entry").attr("data-tag-group", tagKey).attr("data-legend-entry", tagVal);
|
|
28231
|
-
if (!viewMode) {
|
|
28232
|
-
entryG.style("cursor", "pointer").on("mouseenter", (event) => {
|
|
28233
|
-
event.stopPropagation();
|
|
28234
|
-
fadeToTagValue(mainG, tagKey, tagVal);
|
|
28235
|
-
mainSvg.selectAll(".tl-tag-legend-entry").each(function() {
|
|
28236
|
-
const el = d3Selection13.select(this);
|
|
28237
|
-
const ev = el.attr("data-legend-entry");
|
|
28238
|
-
if (ev === "__group__") return;
|
|
28239
|
-
const eg = el.attr("data-tag-group");
|
|
28240
|
-
el.attr(
|
|
28241
|
-
"opacity",
|
|
28242
|
-
eg === tagKey && ev === tagVal ? 1 : FADE_OPACITY2
|
|
28243
|
-
);
|
|
28244
|
-
});
|
|
28245
|
-
}).on("mouseleave", (event) => {
|
|
28246
|
-
event.stopPropagation();
|
|
28247
|
-
fadeReset(mainG);
|
|
28248
|
-
mainSvg.selectAll(".tl-tag-legend-entry").attr("opacity", 1);
|
|
28249
|
-
}).on("click", (event) => {
|
|
28250
|
-
event.stopPropagation();
|
|
28251
|
-
});
|
|
28252
|
-
}
|
|
28253
|
-
entryG.append("circle").attr("cx", entryX + LG_DOT_R).attr("cy", LG_HEIGHT / 2).attr("r", LG_DOT_R).attr("fill", entry.color);
|
|
28254
|
-
const textX = entryX + LG_DOT_R * 2 + LG_ENTRY_DOT_GAP;
|
|
28255
|
-
entryG.append("text").attr("x", textX).attr("y", LG_HEIGHT / 2 + LG_ENTRY_FONT_SIZE / 2 - 1).attr("font-size", LG_ENTRY_FONT_SIZE).attr("font-family", FONT_FAMILY).attr("fill", palette.textMuted).text(entry.value);
|
|
28256
|
-
entryX = textX + measureLegendText(entry.value, LG_ENTRY_FONT_SIZE) + LG_ENTRY_TRAIL;
|
|
28257
28709
|
}
|
|
28258
28710
|
}
|
|
28259
|
-
|
|
28260
|
-
}
|
|
28711
|
+
};
|
|
28712
|
+
const legendInnerG = legendContainer.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
28713
|
+
renderLegendD3(
|
|
28714
|
+
legendInnerG,
|
|
28715
|
+
centralConfig,
|
|
28716
|
+
centralState,
|
|
28717
|
+
palette,
|
|
28718
|
+
isDark,
|
|
28719
|
+
centralCallbacks,
|
|
28720
|
+
width
|
|
28721
|
+
);
|
|
28261
28722
|
}, recolorEvents2 = function() {
|
|
28262
28723
|
const colorTG = currentActiveGroup ?? swimlaneTagGroup ?? null;
|
|
28263
28724
|
mainG.selectAll(".tl-event").each(function() {
|
|
@@ -28282,7 +28743,6 @@ function renderTimeline(container, parsed, palette, isDark, onClickItem, exportD
|
|
|
28282
28743
|
};
|
|
28283
28744
|
var drawSwimlaneIcon2 = drawSwimlaneIcon3, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
|
|
28284
28745
|
const legendY = title ? 50 : 10;
|
|
28285
|
-
const groupBg = isDark ? mix(palette.surface, palette.bg, 50) : mix(palette.surface, palette.bg, 30);
|
|
28286
28746
|
const legendGroups = parsed.timelineTagGroups.map((g) => {
|
|
28287
28747
|
const pillW = measureLegendText(g.name, LG_PILL_FONT_SIZE) + LG_PILL_PAD;
|
|
28288
28748
|
const iconSpace = viewMode ? 8 : LG_ICON_W + 4;
|
|
@@ -29529,6 +29989,7 @@ var init_d3 = __esm({
|
|
|
29529
29989
|
init_parsing();
|
|
29530
29990
|
init_tag_groups();
|
|
29531
29991
|
init_legend_constants();
|
|
29992
|
+
init_legend_d3();
|
|
29532
29993
|
init_title_constants();
|
|
29533
29994
|
DEFAULT_CLOUD_OPTIONS = {
|
|
29534
29995
|
rotate: "none",
|
|
@@ -29707,6 +30168,7 @@ __export(index_exports, {
|
|
|
29707
30168
|
computeCardMove: () => computeCardMove,
|
|
29708
30169
|
computeInfra: () => computeInfra,
|
|
29709
30170
|
computeInfraLegendGroups: () => computeInfraLegendGroups,
|
|
30171
|
+
computeLegendLayout: () => computeLegendLayout,
|
|
29710
30172
|
computeScatterLabelGraphics: () => computeScatterLabelGraphics,
|
|
29711
30173
|
computeTimeTicks: () => computeTimeTicks,
|
|
29712
30174
|
contrastText: () => contrastText,
|
|
@@ -29718,6 +30180,7 @@ __export(index_exports, {
|
|
|
29718
30180
|
formatDgmoError: () => formatDgmoError,
|
|
29719
30181
|
getAvailablePalettes: () => getAvailablePalettes,
|
|
29720
30182
|
getExtendedChartLegendGroups: () => getExtendedChartLegendGroups,
|
|
30183
|
+
getLegendReservedHeight: () => getLegendReservedHeight,
|
|
29721
30184
|
getPalette: () => getPalette,
|
|
29722
30185
|
getRenderCategory: () => getRenderCategory,
|
|
29723
30186
|
getSeriesColors: () => getSeriesColors,
|
|
@@ -29806,7 +30269,9 @@ __export(index_exports, {
|
|
|
29806
30269
|
renderInfra: () => renderInfra,
|
|
29807
30270
|
renderKanban: () => renderKanban,
|
|
29808
30271
|
renderKanbanForExport: () => renderKanbanForExport,
|
|
30272
|
+
renderLegendD3: () => renderLegendD3,
|
|
29809
30273
|
renderLegendSvg: () => renderLegendSvg,
|
|
30274
|
+
renderLegendSvgFromConfig: () => renderLegendSvgFromConfig,
|
|
29810
30275
|
renderOrg: () => renderOrg,
|
|
29811
30276
|
renderOrgForExport: () => renderOrgForExport,
|
|
29812
30277
|
renderQuadrant: () => renderQuadrant,
|
|
@@ -29846,11 +30311,26 @@ async function ensureDom() {
|
|
|
29846
30311
|
const { JSDOM } = await import("jsdom");
|
|
29847
30312
|
const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>");
|
|
29848
30313
|
const win = dom.window;
|
|
29849
|
-
Object.defineProperty(globalThis, "document", {
|
|
29850
|
-
|
|
29851
|
-
|
|
29852
|
-
|
|
29853
|
-
Object.defineProperty(globalThis, "
|
|
30314
|
+
Object.defineProperty(globalThis, "document", {
|
|
30315
|
+
value: win.document,
|
|
30316
|
+
configurable: true
|
|
30317
|
+
});
|
|
30318
|
+
Object.defineProperty(globalThis, "window", {
|
|
30319
|
+
value: win,
|
|
30320
|
+
configurable: true
|
|
30321
|
+
});
|
|
30322
|
+
Object.defineProperty(globalThis, "navigator", {
|
|
30323
|
+
value: win.navigator,
|
|
30324
|
+
configurable: true
|
|
30325
|
+
});
|
|
30326
|
+
Object.defineProperty(globalThis, "HTMLElement", {
|
|
30327
|
+
value: win.HTMLElement,
|
|
30328
|
+
configurable: true
|
|
30329
|
+
});
|
|
30330
|
+
Object.defineProperty(globalThis, "SVGElement", {
|
|
30331
|
+
value: win.SVGElement,
|
|
30332
|
+
configurable: true
|
|
30333
|
+
});
|
|
29854
30334
|
}
|
|
29855
30335
|
async function render(content, options) {
|
|
29856
30336
|
const theme = options?.theme ?? "light";
|
|
@@ -29859,11 +30339,17 @@ async function render(content, options) {
|
|
|
29859
30339
|
const paletteColors = getPalette(paletteName)[theme === "dark" ? "dark" : "light"];
|
|
29860
30340
|
const chartType = parseDgmoChartType(content);
|
|
29861
30341
|
const category = chartType ? getRenderCategory(chartType) : null;
|
|
30342
|
+
const legendExportState = options?.legendState ? {
|
|
30343
|
+
activeTagGroup: options.legendState.activeGroup ?? null,
|
|
30344
|
+
hiddenAttributes: options.legendState.hiddenAttributes ? new Set(options.legendState.hiddenAttributes) : void 0
|
|
30345
|
+
} : void 0;
|
|
29862
30346
|
if (category === "data-chart") {
|
|
29863
|
-
return renderExtendedChartForExport(content, theme, paletteColors, {
|
|
30347
|
+
return renderExtendedChartForExport(content, theme, paletteColors, {
|
|
30348
|
+
branding
|
|
30349
|
+
});
|
|
29864
30350
|
}
|
|
29865
30351
|
await ensureDom();
|
|
29866
|
-
return renderForExport(content, theme, paletteColors,
|
|
30352
|
+
return renderForExport(content, theme, paletteColors, legendExportState, {
|
|
29867
30353
|
branding,
|
|
29868
30354
|
c4Level: options?.c4Level,
|
|
29869
30355
|
c4System: options?.c4System,
|
|
@@ -30586,6 +31072,8 @@ init_flowchart_renderer();
|
|
|
30586
31072
|
init_echarts();
|
|
30587
31073
|
init_legend_svg();
|
|
30588
31074
|
init_legend_constants();
|
|
31075
|
+
init_legend_d3();
|
|
31076
|
+
init_legend_layout();
|
|
30589
31077
|
init_d3();
|
|
30590
31078
|
init_renderer10();
|
|
30591
31079
|
init_colors();
|
|
@@ -31430,6 +31918,7 @@ init_branding();
|
|
|
31430
31918
|
computeCardMove,
|
|
31431
31919
|
computeInfra,
|
|
31432
31920
|
computeInfraLegendGroups,
|
|
31921
|
+
computeLegendLayout,
|
|
31433
31922
|
computeScatterLabelGraphics,
|
|
31434
31923
|
computeTimeTicks,
|
|
31435
31924
|
contrastText,
|
|
@@ -31441,6 +31930,7 @@ init_branding();
|
|
|
31441
31930
|
formatDgmoError,
|
|
31442
31931
|
getAvailablePalettes,
|
|
31443
31932
|
getExtendedChartLegendGroups,
|
|
31933
|
+
getLegendReservedHeight,
|
|
31444
31934
|
getPalette,
|
|
31445
31935
|
getRenderCategory,
|
|
31446
31936
|
getSeriesColors,
|
|
@@ -31529,7 +32019,9 @@ init_branding();
|
|
|
31529
32019
|
renderInfra,
|
|
31530
32020
|
renderKanban,
|
|
31531
32021
|
renderKanbanForExport,
|
|
32022
|
+
renderLegendD3,
|
|
31532
32023
|
renderLegendSvg,
|
|
32024
|
+
renderLegendSvgFromConfig,
|
|
31533
32025
|
renderOrg,
|
|
31534
32026
|
renderOrgForExport,
|
|
31535
32027
|
renderQuadrant,
|