@diagrammo/dgmo 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.cjs +152 -73
- package/dist/advanced.d.cts +35 -19
- package/dist/advanced.d.ts +35 -19
- package/dist/advanced.js +152 -73
- package/dist/auto.cjs +153 -74
- package/dist/auto.js +110 -110
- package/dist/auto.mjs +153 -74
- package/dist/cli.cjs +150 -150
- package/dist/index.cjs +284 -73
- package/dist/index.d.cts +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +282 -73
- package/dist/internal.cjs +152 -73
- package/dist/internal.d.cts +35 -19
- package/dist/internal.d.ts +35 -19
- package/dist/internal.js +152 -73
- package/docs/language-reference.md +3 -2
- package/package.json +1 -1
- package/src/boxes-and-lines/renderer.ts +98 -51
- package/src/d3.ts +22 -10
- package/src/index.ts +8 -0
- package/src/map/dimensions.ts +21 -5
- package/src/map/layout.ts +57 -46
- package/src/map/legend-band.ts +99 -0
- package/src/map/renderer.ts +10 -28
- package/src/map/resolver.ts +43 -1
- package/src/map/types.ts +20 -0
- package/src/utils/svg-embed.ts +193 -0
package/dist/index.js
CHANGED
|
@@ -26585,7 +26585,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26585
26585
|
const VALUE_NAME = hasRamp ? parsed.boxMetric?.trim() || "Value" : null;
|
|
26586
26586
|
const matchColorGroup = (v) => {
|
|
26587
26587
|
const lv = v.trim().toLowerCase();
|
|
26588
|
-
if (lv === "none") return null;
|
|
26588
|
+
if (lv === "" || lv === "none") return null;
|
|
26589
26589
|
const tg = parsed.tagGroups.find((g) => g.name.toLowerCase() === lv);
|
|
26590
26590
|
if (tg) return tg.name;
|
|
26591
26591
|
if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
|
|
@@ -26926,6 +26926,22 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26926
26926
|
const tooltipText = fullText.length > 200 ? fullText.slice(0, 199) + "\u2026" : fullText;
|
|
26927
26927
|
nodeG.append("title").text(tooltipText);
|
|
26928
26928
|
}
|
|
26929
|
+
} else if (parsed.showValues && node.value !== void 0) {
|
|
26930
|
+
const valueLabel = parsed.boxMetric ? `${parsed.boxMetric}: ${node.value}` : String(node.value);
|
|
26931
|
+
const headerH = ln.height / 2;
|
|
26932
|
+
const sepY = -ln.height / 2 + headerH;
|
|
26933
|
+
const fitted = fitLabelToHeader(node.label, ln.width, 2);
|
|
26934
|
+
const labelLineH = fitted.fontSize * 1.3;
|
|
26935
|
+
const labelTotalH = fitted.lines.length * labelLineH;
|
|
26936
|
+
const headerCenterY = -ln.height / 2 + headerH / 2;
|
|
26937
|
+
for (let li = 0; li < fitted.lines.length; li++) {
|
|
26938
|
+
nodeG.append("text").attr("x", 0).attr(
|
|
26939
|
+
"y",
|
|
26940
|
+
headerCenterY - labelTotalH / 2 + labelLineH / 2 + li * labelLineH
|
|
26941
|
+
).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", fitted.fontSize).attr("font-weight", "600").attr("fill", colors.text).text(fitted.lines[li]);
|
|
26942
|
+
}
|
|
26943
|
+
nodeG.append("line").attr("x1", -ln.width / 2).attr("y1", sepY).attr("x2", ln.width / 2).attr("y2", sepY).attr("stroke", colors.stroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
|
|
26944
|
+
nodeG.append("text").attr("class", "bl-node-value").attr("x", 0).attr("y", (sepY + ln.height / 2) / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", VALUE_FONT_SIZE).attr("fill", colors.text).attr("opacity", 0.85).text(valueLabel);
|
|
26929
26945
|
} else {
|
|
26930
26946
|
const maxLabelLines = Math.max(
|
|
26931
26947
|
2,
|
|
@@ -26938,21 +26954,16 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26938
26954
|
nodeG.append("text").attr("x", 0).attr("y", -totalH / 2 + lineH / 2 + li * lineH).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", fitted.fontSize).attr("font-weight", "600").attr("fill", colors.text).text(fitted.lines[li]);
|
|
26939
26955
|
}
|
|
26940
26956
|
}
|
|
26941
|
-
if (parsed.showValues && node.value !== void 0) {
|
|
26957
|
+
if (parsed.showValues && node.value !== void 0 && desc && desc.length > 0 && !hideDescriptions) {
|
|
26942
26958
|
const valueText = String(node.value);
|
|
26943
|
-
const
|
|
26944
|
-
|
|
26945
|
-
|
|
26946
|
-
|
|
26947
|
-
|
|
26948
|
-
|
|
26949
|
-
|
|
26950
|
-
|
|
26951
|
-
nodeG.append("rect").attr("x", bx).attr("y", by).attr("width", bw).attr("height", bh).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.85);
|
|
26952
|
-
nodeG.append("text").attr("class", "bl-node-value").attr("x", bx + bw - padX).attr("y", by + padY).attr("text-anchor", "end").attr("dominant-baseline", "central").attr("font-size", VALUE_FONT_SIZE).attr("font-weight", "600").attr("fill", palette.textMuted).text(valueText);
|
|
26953
|
-
} else {
|
|
26954
|
-
nodeG.append("text").attr("class", "bl-node-value").attr("x", 0).attr("y", ln.height / 2 - VALUE_FONT_SIZE).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", VALUE_FONT_SIZE).attr("font-weight", "600").attr("fill", colors.text).attr("opacity", 0.8).text(valueText);
|
|
26955
|
-
}
|
|
26959
|
+
const padX = 6;
|
|
26960
|
+
const padY = 5;
|
|
26961
|
+
const bw = valueText.length * VALUE_FONT_SIZE * CHAR_WIDTH_RATIO2 + 8;
|
|
26962
|
+
const bh = VALUE_FONT_SIZE + 4;
|
|
26963
|
+
const bx = Math.max(-ln.width / 2 + 4, ln.width / 2 - bw - 4);
|
|
26964
|
+
const by = -ln.height / 2 + 4;
|
|
26965
|
+
nodeG.append("rect").attr("x", bx).attr("y", by).attr("width", bw).attr("height", bh).attr("rx", 3).attr("fill", palette.bg).attr("opacity", 0.85);
|
|
26966
|
+
nodeG.append("text").attr("class", "bl-node-value").attr("x", bx + bw - padX).attr("y", by + padY).attr("text-anchor", "end").attr("dominant-baseline", "central").attr("font-size", VALUE_FONT_SIZE).attr("font-weight", "600").attr("fill", palette.textMuted).text(valueText);
|
|
26956
26967
|
}
|
|
26957
26968
|
}
|
|
26958
26969
|
const hasDescriptions = parsed.nodes.some(
|
|
@@ -27046,7 +27057,7 @@ var init_renderer6 = __esm({
|
|
|
27046
27057
|
init_wrapped_desc();
|
|
27047
27058
|
init_scaling();
|
|
27048
27059
|
DIAGRAM_PADDING6 = 20;
|
|
27049
|
-
NODE_FONT_SIZE =
|
|
27060
|
+
NODE_FONT_SIZE = 11;
|
|
27050
27061
|
MIN_NODE_FONT_SIZE = 9;
|
|
27051
27062
|
EDGE_LABEL_FONT_SIZE4 = 11;
|
|
27052
27063
|
EDGE_STROKE_WIDTH5 = 1.5;
|
|
@@ -46783,7 +46794,11 @@ function resolveMap(parsed, data) {
|
|
|
46783
46794
|
if (bb && !isWholeSphere(bb)) containerBoxes.push(bb);
|
|
46784
46795
|
}
|
|
46785
46796
|
const containerUnion = unionExtent(containerBoxes, points);
|
|
46786
|
-
if (containerUnion)
|
|
46797
|
+
if (containerUnion)
|
|
46798
|
+
extent2 = pad(
|
|
46799
|
+
clampContainerToCluster(containerUnion, points),
|
|
46800
|
+
PAD_FRACTION
|
|
46801
|
+
);
|
|
46787
46802
|
}
|
|
46788
46803
|
if (isPoiOnly) {
|
|
46789
46804
|
const cx = (extent2[0][0] + extent2[1][0]) / 2;
|
|
@@ -46864,6 +46879,22 @@ function mostCommonCountry(regions, poiCountries) {
|
|
|
46864
46879
|
}
|
|
46865
46880
|
return best;
|
|
46866
46881
|
}
|
|
46882
|
+
function clampContainerToCluster(container, points) {
|
|
46883
|
+
const poi = unionExtent([], points);
|
|
46884
|
+
if (!poi) return container;
|
|
46885
|
+
let [[west, south], [east, north]] = container;
|
|
46886
|
+
const [[pWest, pSouth], [pEast, pNorth]] = poi;
|
|
46887
|
+
south = Math.max(south, pSouth - CONTAINER_OVERSHOOT_DEG);
|
|
46888
|
+
north = Math.min(north, pNorth + CONTAINER_OVERSHOOT_DEG);
|
|
46889
|
+
if (east <= 180 && pEast <= 180) {
|
|
46890
|
+
west = Math.max(west, pWest - CONTAINER_OVERSHOOT_DEG);
|
|
46891
|
+
east = Math.min(east, pEast + CONTAINER_OVERSHOOT_DEG);
|
|
46892
|
+
}
|
|
46893
|
+
return [
|
|
46894
|
+
[west, south],
|
|
46895
|
+
[east, north]
|
|
46896
|
+
];
|
|
46897
|
+
}
|
|
46867
46898
|
function pad(e, frac) {
|
|
46868
46899
|
const dLon = (e[1][0] - e[0][0]) * frac || 1;
|
|
46869
46900
|
const dLat = (e[1][1] - e[0][1]) * frac || 1;
|
|
@@ -46876,7 +46907,7 @@ function firstError(diags) {
|
|
|
46876
46907
|
const e = diags.find((d) => d.severity === "error");
|
|
46877
46908
|
return e ? formatDgmoError(e) : null;
|
|
46878
46909
|
}
|
|
46879
|
-
var WORLD_SPAN, MERCATOR_MAX_LAT, PAD_FRACTION, REGION_PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, POI_ZOOM_FLOOR_DEG, US_NATIONAL_LON_SPAN, REGION_ALIASES, US_STATE_POSTAL;
|
|
46910
|
+
var WORLD_SPAN, MERCATOR_MAX_LAT, PAD_FRACTION, REGION_PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, POI_ZOOM_FLOOR_DEG, CONTAINER_OVERSHOOT_DEG, US_NATIONAL_LON_SPAN, REGION_ALIASES, US_STATE_POSTAL;
|
|
46880
46911
|
var init_resolver2 = __esm({
|
|
46881
46912
|
"src/map/resolver.ts"() {
|
|
46882
46913
|
"use strict";
|
|
@@ -46889,6 +46920,7 @@ var init_resolver2 = __esm({
|
|
|
46889
46920
|
WORLD_LAT_SOUTH = -58;
|
|
46890
46921
|
WORLD_LAT_NORTH = 78;
|
|
46891
46922
|
POI_ZOOM_FLOOR_DEG = 7;
|
|
46923
|
+
CONTAINER_OVERSHOOT_DEG = 8;
|
|
46892
46924
|
US_NATIONAL_LON_SPAN = 48;
|
|
46893
46925
|
REGION_ALIASES = {
|
|
46894
46926
|
// Common everyday names → the Natural-Earth display name actually shipped.
|
|
@@ -46967,6 +46999,55 @@ var init_resolver2 = __esm({
|
|
|
46967
46999
|
}
|
|
46968
47000
|
});
|
|
46969
47001
|
|
|
47002
|
+
// src/map/legend-band.ts
|
|
47003
|
+
function mapLegendGroups(legend) {
|
|
47004
|
+
const ramp = legend.ramp;
|
|
47005
|
+
const scoreGroup = ramp ? {
|
|
47006
|
+
name: ramp.metric?.trim() || "Value",
|
|
47007
|
+
entries: [],
|
|
47008
|
+
gradient: {
|
|
47009
|
+
min: ramp.min,
|
|
47010
|
+
max: ramp.max,
|
|
47011
|
+
hue: ramp.hue,
|
|
47012
|
+
base: ramp.base
|
|
47013
|
+
}
|
|
47014
|
+
} : null;
|
|
47015
|
+
const tagGroups = legend.tagGroups.filter((g) => g.entries.length > 0).map((g) => ({ name: g.name, entries: [...g.entries] }));
|
|
47016
|
+
return [...scoreGroup ? [scoreGroup] : [], ...tagGroups];
|
|
47017
|
+
}
|
|
47018
|
+
function mapLegendConfig(groups, mode) {
|
|
47019
|
+
return {
|
|
47020
|
+
groups,
|
|
47021
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
47022
|
+
mode,
|
|
47023
|
+
showEmptyGroups: false,
|
|
47024
|
+
showInactivePills: true
|
|
47025
|
+
};
|
|
47026
|
+
}
|
|
47027
|
+
function mapLegendTop(hasTitle, hasSubtitle) {
|
|
47028
|
+
return (hasTitle ? TITLE_Y + TITLE_FONT_SIZE : 0) + (hasSubtitle ? TITLE_FONT_SIZE : 0) + LEGEND_TOP_GAP2;
|
|
47029
|
+
}
|
|
47030
|
+
function mapLegendBand(legend, opts) {
|
|
47031
|
+
if (!legend) return 0;
|
|
47032
|
+
const groups = mapLegendGroups(legend);
|
|
47033
|
+
if (groups.length === 0) return 0;
|
|
47034
|
+
const config = mapLegendConfig(groups, opts.mode);
|
|
47035
|
+
const state = { activeGroup: legend.activeGroup };
|
|
47036
|
+
const { height } = computeLegendLayout(config, state, opts.width);
|
|
47037
|
+
if (height <= 0) return 0;
|
|
47038
|
+
return mapLegendTop(opts.hasTitle, opts.hasSubtitle) + height + LEGEND_BOTTOM_GAP2;
|
|
47039
|
+
}
|
|
47040
|
+
var LEGEND_TOP_GAP2, LEGEND_BOTTOM_GAP2;
|
|
47041
|
+
var init_legend_band = __esm({
|
|
47042
|
+
"src/map/legend-band.ts"() {
|
|
47043
|
+
"use strict";
|
|
47044
|
+
init_legend_layout();
|
|
47045
|
+
init_title_constants();
|
|
47046
|
+
LEGEND_TOP_GAP2 = 8;
|
|
47047
|
+
LEGEND_BOTTOM_GAP2 = 10;
|
|
47048
|
+
}
|
|
47049
|
+
});
|
|
47050
|
+
|
|
46970
47051
|
// src/map/colorize.ts
|
|
46971
47052
|
function assignColors(isos, adjacency) {
|
|
46972
47053
|
const sorted = [...isos].sort();
|
|
@@ -47558,12 +47639,43 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47558
47639
|
return tagFill(r.tags, activeGroup) ?? neutralFill;
|
|
47559
47640
|
};
|
|
47560
47641
|
const regionById = new Map(resolved.regions.map((r) => [r.iso, r]));
|
|
47642
|
+
let legend = null;
|
|
47643
|
+
if (!resolved.directives.noLegend) {
|
|
47644
|
+
const legendTagGroups = resolved.tagGroups.map((g) => ({
|
|
47645
|
+
name: g.name,
|
|
47646
|
+
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
47647
|
+
}));
|
|
47648
|
+
if (legendTagGroups.length > 0 || hasRamp) {
|
|
47649
|
+
legend = {
|
|
47650
|
+
tagGroups: legendTagGroups,
|
|
47651
|
+
activeGroup,
|
|
47652
|
+
...hasRamp && {
|
|
47653
|
+
ramp: {
|
|
47654
|
+
...resolved.directives.regionMetric !== void 0 && {
|
|
47655
|
+
metric: resolved.directives.regionMetric
|
|
47656
|
+
},
|
|
47657
|
+
min: rampMin,
|
|
47658
|
+
max: rampMax,
|
|
47659
|
+
hue: rampHue,
|
|
47660
|
+
base: rampBase
|
|
47661
|
+
}
|
|
47662
|
+
}
|
|
47663
|
+
};
|
|
47664
|
+
}
|
|
47665
|
+
}
|
|
47561
47666
|
const TITLE_GAP2 = 16;
|
|
47562
47667
|
let topPad = FIT_PAD;
|
|
47563
47668
|
if (resolved.title && resolved.pois.length > 0) {
|
|
47564
47669
|
const bannerBottom = (resolved.subtitle ? TITLE_Y + TITLE_FONT_SIZE : TITLE_Y) + TITLE_FONT_SIZE / 2;
|
|
47565
47670
|
topPad = Math.max(FIT_PAD, bannerBottom + TITLE_GAP2);
|
|
47566
47671
|
}
|
|
47672
|
+
const legendBand = mapLegendBand(legend, {
|
|
47673
|
+
width,
|
|
47674
|
+
mode: opts.legendMode ?? "preview",
|
|
47675
|
+
hasTitle: Boolean(resolved.title),
|
|
47676
|
+
hasSubtitle: Boolean(resolved.subtitle)
|
|
47677
|
+
});
|
|
47678
|
+
if (legendBand > topPad) topPad = legendBand;
|
|
47567
47679
|
const fitBox = [
|
|
47568
47680
|
[FIT_PAD, topPad],
|
|
47569
47681
|
[
|
|
@@ -47581,7 +47693,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47581
47693
|
const by0 = cb[0][1];
|
|
47582
47694
|
const cw = cb[1][0] - bx0;
|
|
47583
47695
|
const ch = cb[1][1] - by0;
|
|
47584
|
-
const topReserve = resolved.title && resolved.pois.length > 0 ? topPad : 0;
|
|
47696
|
+
const topReserve = resolved.title && resolved.pois.length > 0 || legendBand > 0 ? topPad : 0;
|
|
47585
47697
|
const ox = 0;
|
|
47586
47698
|
const oy = topReserve;
|
|
47587
47699
|
const sx = cw > 0 ? width / cw : 1;
|
|
@@ -48645,30 +48757,6 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
48645
48757
|
});
|
|
48646
48758
|
labels.push(...contextLabels);
|
|
48647
48759
|
}
|
|
48648
|
-
let legend = null;
|
|
48649
|
-
if (!resolved.directives.noLegend) {
|
|
48650
|
-
const tagGroups = resolved.tagGroups.map((g) => ({
|
|
48651
|
-
name: g.name,
|
|
48652
|
-
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
48653
|
-
}));
|
|
48654
|
-
if (tagGroups.length > 0 || hasRamp) {
|
|
48655
|
-
legend = {
|
|
48656
|
-
tagGroups,
|
|
48657
|
-
activeGroup,
|
|
48658
|
-
...hasRamp && {
|
|
48659
|
-
ramp: {
|
|
48660
|
-
...resolved.directives.regionMetric !== void 0 && {
|
|
48661
|
-
metric: resolved.directives.regionMetric
|
|
48662
|
-
},
|
|
48663
|
-
min: rampMin,
|
|
48664
|
-
max: rampMax,
|
|
48665
|
-
hue: rampHue,
|
|
48666
|
-
base: rampBase
|
|
48667
|
-
}
|
|
48668
|
-
}
|
|
48669
|
-
};
|
|
48670
|
-
}
|
|
48671
|
-
}
|
|
48672
48760
|
return {
|
|
48673
48761
|
width,
|
|
48674
48762
|
height,
|
|
@@ -48704,6 +48792,7 @@ var init_layout15 = __esm({
|
|
|
48704
48792
|
init_label_layout();
|
|
48705
48793
|
init_legend_constants();
|
|
48706
48794
|
init_title_constants();
|
|
48795
|
+
init_legend_band();
|
|
48707
48796
|
init_context_labels();
|
|
48708
48797
|
FIT_PAD = 24;
|
|
48709
48798
|
RAMP_FLOOR2 = 15;
|
|
@@ -48904,6 +48993,9 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48904
48993
|
// stretch-distorting. The in-app preview pane passes no exportDims → unset →
|
|
48905
48994
|
// keeps the global stretch-fill.
|
|
48906
48995
|
preferContain: exportDims?.preferContain ?? false,
|
|
48996
|
+
// Reserve the legend band for the mode actually drawn below (export shows
|
|
48997
|
+
// only the active group; preview keeps the inactive pills).
|
|
48998
|
+
legendMode: exportDims ? "export" : "preview",
|
|
48907
48999
|
...activeGroupOverride !== void 0 && {
|
|
48908
49000
|
activeGroup: activeGroupOverride
|
|
48909
49001
|
}
|
|
@@ -49195,30 +49287,12 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
49195
49287
|
if (layout.legend) {
|
|
49196
49288
|
const legendY = (layout.title ? TITLE_Y + TITLE_FONT_SIZE : 0) + (layout.subtitle ? TITLE_FONT_SIZE : 0) + 8;
|
|
49197
49289
|
const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
|
|
49198
|
-
const
|
|
49199
|
-
const scoreGroup = ramp ? {
|
|
49200
|
-
name: ramp.metric?.trim() || "Value",
|
|
49201
|
-
entries: [],
|
|
49202
|
-
gradient: {
|
|
49203
|
-
min: ramp.min,
|
|
49204
|
-
max: ramp.max,
|
|
49205
|
-
hue: ramp.hue,
|
|
49206
|
-
base: ramp.base
|
|
49207
|
-
}
|
|
49208
|
-
} : null;
|
|
49209
|
-
const tagGroups = layout.legend.tagGroups.filter((g) => g.entries.length > 0).map((g) => ({ name: g.name, entries: [...g.entries] }));
|
|
49210
|
-
const groups = [...scoreGroup ? [scoreGroup] : [], ...tagGroups];
|
|
49290
|
+
const groups = mapLegendGroups(layout.legend);
|
|
49211
49291
|
if (groups.length > 0) {
|
|
49212
|
-
const config =
|
|
49292
|
+
const config = mapLegendConfig(
|
|
49213
49293
|
groups,
|
|
49214
|
-
|
|
49215
|
-
|
|
49216
|
-
showEmptyGroups: false,
|
|
49217
|
-
// Keep inactive siblings visible as pills so the user can click to flip
|
|
49218
|
-
// the active colouring dimension (preview only — export shows just the
|
|
49219
|
-
// active group).
|
|
49220
|
-
showInactivePills: true
|
|
49221
|
-
};
|
|
49294
|
+
exportDims ? "export" : "preview"
|
|
49295
|
+
);
|
|
49222
49296
|
const state = { activeGroup: layout.legend.activeGroup };
|
|
49223
49297
|
renderLegendD3(legendG, config, state, palette, isDark, void 0, width);
|
|
49224
49298
|
}
|
|
@@ -49262,6 +49336,7 @@ var init_renderer16 = __esm({
|
|
|
49262
49336
|
init_title_constants();
|
|
49263
49337
|
init_color_utils();
|
|
49264
49338
|
init_legend_d3();
|
|
49339
|
+
init_legend_band();
|
|
49265
49340
|
init_layout15();
|
|
49266
49341
|
LABEL_FONT = 11;
|
|
49267
49342
|
}
|
|
@@ -49283,9 +49358,10 @@ function mapContentAspect(resolved, data, ref = REF) {
|
|
|
49283
49358
|
const aspect = w / h;
|
|
49284
49359
|
return Number.isFinite(aspect) && aspect > 0 ? aspect : FALLBACK_ASPECT;
|
|
49285
49360
|
}
|
|
49286
|
-
function mapExportDimensions(resolved, data, baseWidth = 1200) {
|
|
49287
|
-
const
|
|
49288
|
-
const
|
|
49361
|
+
function mapExportDimensions(resolved, data, baseWidth = 1200, aspectOverride) {
|
|
49362
|
+
const useOverride = aspectOverride !== void 0 && Number.isFinite(aspectOverride) && aspectOverride > 0;
|
|
49363
|
+
const raw = useOverride ? aspectOverride : mapContentAspect(resolved, data);
|
|
49364
|
+
const clamped = useOverride ? raw : Math.max(ASPECT_MIN, Math.min(ASPECT_MAX, raw));
|
|
49289
49365
|
const width = baseWidth;
|
|
49290
49366
|
let height = Math.round(width / clamped);
|
|
49291
49367
|
let chromeReserve = 0;
|
|
@@ -49298,7 +49374,7 @@ function mapExportDimensions(resolved, data, baseWidth = 1200) {
|
|
|
49298
49374
|
height = Math.round(chromeReserve + MIN_MAP_BAND);
|
|
49299
49375
|
floored = true;
|
|
49300
49376
|
}
|
|
49301
|
-
const preferContain = clamped !== raw || floored;
|
|
49377
|
+
const preferContain = useOverride ? floored : clamped !== raw || floored;
|
|
49302
49378
|
return { width, height, preferContain };
|
|
49303
49379
|
}
|
|
49304
49380
|
var FIT_PAD2, TITLE_GAP, ASPECT_MAX, ASPECT_MIN, MIN_MAP_BAND, FALLBACK_ASPECT, REF;
|
|
@@ -55008,7 +55084,6 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
|
|
|
55008
55084
|
function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
55009
55085
|
const {
|
|
55010
55086
|
width,
|
|
55011
|
-
height,
|
|
55012
55087
|
tooltip,
|
|
55013
55088
|
solid,
|
|
55014
55089
|
textColor,
|
|
@@ -55057,8 +55132,7 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
|
|
|
55057
55132
|
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
55058
55133
|
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
55059
55134
|
const innerWidth = width - margin.left - margin.right;
|
|
55060
|
-
const
|
|
55061
|
-
const rowH = Math.min(ctx.structural(28), availInnerHeight / sorted.length);
|
|
55135
|
+
const rowH = ctx.structural(28);
|
|
55062
55136
|
const innerHeight = rowH * sorted.length;
|
|
55063
55137
|
const usedHeight = margin.top + innerHeight + margin.bottom;
|
|
55064
55138
|
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
@@ -57583,7 +57657,12 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
57583
57657
|
}
|
|
57584
57658
|
}
|
|
57585
57659
|
const mapResolved = resolveMap2(mapParsed, mapData);
|
|
57586
|
-
const dims2 = mapExportDimensions2(
|
|
57660
|
+
const dims2 = mapExportDimensions2(
|
|
57661
|
+
mapResolved,
|
|
57662
|
+
mapData,
|
|
57663
|
+
EXPORT_WIDTH,
|
|
57664
|
+
options?.mapAspect
|
|
57665
|
+
);
|
|
57587
57666
|
const container2 = createExportContainer(dims2.width, dims2.height);
|
|
57588
57667
|
renderMapForExport2(
|
|
57589
57668
|
container2,
|
|
@@ -58727,6 +58806,134 @@ function extractInfraCounts(content) {
|
|
|
58727
58806
|
return { nodes: parsed.nodes.length };
|
|
58728
58807
|
}
|
|
58729
58808
|
|
|
58809
|
+
// src/utils/svg-embed.ts
|
|
58810
|
+
function normalizeSvgForEmbed(input) {
|
|
58811
|
+
let svg = input;
|
|
58812
|
+
const rootMatch = svg.match(/<svg[^>]*>/);
|
|
58813
|
+
const rootTag = rootMatch?.[0] ?? "";
|
|
58814
|
+
if (rootTag && !rootTag.includes("viewBox")) {
|
|
58815
|
+
const wh = rootTag.match(/width="(\d+)"[^>]*height="(\d+)"/);
|
|
58816
|
+
if (wh) {
|
|
58817
|
+
svg = svg.replace(/<svg/, `<svg viewBox="0 0 ${wh[1]} ${wh[2]}"`);
|
|
58818
|
+
}
|
|
58819
|
+
}
|
|
58820
|
+
const tight = computeBBox(svg);
|
|
58821
|
+
if (tight && tight.width > 0 && tight.height > 0) {
|
|
58822
|
+
const pad2 = 16;
|
|
58823
|
+
const vb = `${tight.x - pad2} ${tight.y - pad2} ${tight.width + pad2 * 2} ${tight.height + pad2 * 2}`;
|
|
58824
|
+
svg = svg.replace(/(<svg[^>]*?)viewBox="[^"]*"/, `$1viewBox="${vb}"`);
|
|
58825
|
+
}
|
|
58826
|
+
svg = svg.replace(/(<svg[^>]*?) width="[^"]*"/g, "$1");
|
|
58827
|
+
svg = svg.replace(/(<svg[^>]*?) height="[^"]*"/g, "$1");
|
|
58828
|
+
svg = svg.replace(/(<svg[^>]*?style="[^"]*?)background:[^;"]*;?\s*/g, "$1");
|
|
58829
|
+
svg = svg.replace(/<svg\s{2,}/g, "<svg ");
|
|
58830
|
+
return svg;
|
|
58831
|
+
}
|
|
58832
|
+
function getEmbedSvgViewBox(svg) {
|
|
58833
|
+
const tight = computeBBox(svg);
|
|
58834
|
+
if (!tight || tight.width <= 0 || tight.height <= 0) return null;
|
|
58835
|
+
const pad2 = 16;
|
|
58836
|
+
return {
|
|
58837
|
+
x: tight.x - pad2,
|
|
58838
|
+
y: tight.y - pad2,
|
|
58839
|
+
width: tight.width + pad2 * 2,
|
|
58840
|
+
height: tight.height + pad2 * 2
|
|
58841
|
+
};
|
|
58842
|
+
}
|
|
58843
|
+
function computeBBox(svg) {
|
|
58844
|
+
const xs = [];
|
|
58845
|
+
const ys = [];
|
|
58846
|
+
function push(x, y) {
|
|
58847
|
+
if (Number.isFinite(x) && Number.isFinite(y)) {
|
|
58848
|
+
xs.push(x);
|
|
58849
|
+
ys.push(y);
|
|
58850
|
+
}
|
|
58851
|
+
}
|
|
58852
|
+
function attr(tag, name) {
|
|
58853
|
+
const m = tag.match(new RegExp(`\\b${name}="([^"]*)"`));
|
|
58854
|
+
if (!m) return null;
|
|
58855
|
+
const n = parseFloat(m[1]);
|
|
58856
|
+
return Number.isFinite(n) ? n : null;
|
|
58857
|
+
}
|
|
58858
|
+
for (const m of svg.matchAll(/<rect\b[^>]*?\/?>/g)) {
|
|
58859
|
+
const tag = m[0];
|
|
58860
|
+
const x = attr(tag, "x");
|
|
58861
|
+
const y = attr(tag, "y");
|
|
58862
|
+
const w = attr(tag, "width");
|
|
58863
|
+
const h = attr(tag, "height");
|
|
58864
|
+
if (x !== null && y !== null && w !== null && h !== null) {
|
|
58865
|
+
push(x, y);
|
|
58866
|
+
push(x + w, y + h);
|
|
58867
|
+
}
|
|
58868
|
+
}
|
|
58869
|
+
for (const m of svg.matchAll(/<line\b[^>]*?\/?>/g)) {
|
|
58870
|
+
const tag = m[0];
|
|
58871
|
+
const x1 = attr(tag, "x1");
|
|
58872
|
+
const y1 = attr(tag, "y1");
|
|
58873
|
+
const x2 = attr(tag, "x2");
|
|
58874
|
+
const y2 = attr(tag, "y2");
|
|
58875
|
+
if (x1 !== null && y1 !== null && x2 !== null && y2 !== null) {
|
|
58876
|
+
push(x1, y1);
|
|
58877
|
+
push(x2, y2);
|
|
58878
|
+
}
|
|
58879
|
+
}
|
|
58880
|
+
for (const m of svg.matchAll(/<circle\b[^>]*?\/?>/g)) {
|
|
58881
|
+
const tag = m[0];
|
|
58882
|
+
const cx = attr(tag, "cx");
|
|
58883
|
+
const cy = attr(tag, "cy");
|
|
58884
|
+
const r = attr(tag, "r");
|
|
58885
|
+
if (cx !== null && cy !== null && r !== null) {
|
|
58886
|
+
push(cx - r, cy - r);
|
|
58887
|
+
push(cx + r, cy + r);
|
|
58888
|
+
}
|
|
58889
|
+
}
|
|
58890
|
+
for (const m of svg.matchAll(/<ellipse\b[^>]*?\/?>/g)) {
|
|
58891
|
+
const tag = m[0];
|
|
58892
|
+
const cx = attr(tag, "cx");
|
|
58893
|
+
const cy = attr(tag, "cy");
|
|
58894
|
+
const rx = attr(tag, "rx");
|
|
58895
|
+
const ry = attr(tag, "ry");
|
|
58896
|
+
if (cx !== null && cy !== null && rx !== null && ry !== null) {
|
|
58897
|
+
push(cx - rx, cy - ry);
|
|
58898
|
+
push(cx + rx, cy + ry);
|
|
58899
|
+
}
|
|
58900
|
+
}
|
|
58901
|
+
for (const m of svg.matchAll(/<text\b([^>]*?)>([\s\S]*?)<\/text>/g)) {
|
|
58902
|
+
const tag = `<text${m[1]}>`;
|
|
58903
|
+
const text = m[2].replace(/<[^>]+>/g, "");
|
|
58904
|
+
const x = attr(tag, "x");
|
|
58905
|
+
const y = attr(tag, "y");
|
|
58906
|
+
if (x !== null && y !== null) {
|
|
58907
|
+
const w = text.length * 7;
|
|
58908
|
+
push(x - w / 2, y - 14);
|
|
58909
|
+
push(x + w / 2, y + 4);
|
|
58910
|
+
}
|
|
58911
|
+
}
|
|
58912
|
+
for (const m of svg.matchAll(/<path\b[^>]*?\bd="([^"]+)"/g)) {
|
|
58913
|
+
const d = m[1];
|
|
58914
|
+
const nums = d.match(/-?\d+(?:\.\d+)?/g);
|
|
58915
|
+
if (!nums) continue;
|
|
58916
|
+
for (let i = 0; i + 1 < nums.length; i += 2) {
|
|
58917
|
+
push(parseFloat(nums[i]), parseFloat(nums[i + 1]));
|
|
58918
|
+
}
|
|
58919
|
+
}
|
|
58920
|
+
for (const m of svg.matchAll(
|
|
58921
|
+
/<(?:polygon|polyline)\b[^>]*?\bpoints="([^"]+)"/g
|
|
58922
|
+
)) {
|
|
58923
|
+
const nums = m[1].match(/-?\d+(?:\.\d+)?/g);
|
|
58924
|
+
if (!nums) continue;
|
|
58925
|
+
for (let i = 0; i + 1 < nums.length; i += 2) {
|
|
58926
|
+
push(parseFloat(nums[i]), parseFloat(nums[i + 1]));
|
|
58927
|
+
}
|
|
58928
|
+
}
|
|
58929
|
+
if (xs.length === 0 || ys.length === 0) return null;
|
|
58930
|
+
const minX = Math.min(...xs);
|
|
58931
|
+
const maxX = Math.max(...xs);
|
|
58932
|
+
const minY = Math.min(...ys);
|
|
58933
|
+
const maxY = Math.max(...ys);
|
|
58934
|
+
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
58935
|
+
}
|
|
58936
|
+
|
|
58730
58937
|
// src/map/completion.ts
|
|
58731
58938
|
var fold2 = (s) => s.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase().trim();
|
|
58732
58939
|
var groupThousands = (n) => String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
@@ -58850,8 +59057,10 @@ export {
|
|
|
58850
59057
|
decodeDiagramUrl2 as decodeDiagramUrl,
|
|
58851
59058
|
encodeDiagramUrl2 as encodeDiagramUrl,
|
|
58852
59059
|
formatDgmoError,
|
|
59060
|
+
getEmbedSvgViewBox,
|
|
58853
59061
|
getMinDimensions,
|
|
58854
59062
|
getPalette,
|
|
59063
|
+
normalizeSvgForEmbed,
|
|
58855
59064
|
palettes,
|
|
58856
59065
|
render2 as render,
|
|
58857
59066
|
themes,
|