@diagrammo/dgmo 0.22.0 → 0.23.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 +238 -48
- package/dist/advanced.d.cts +17 -0
- package/dist/advanced.d.ts +17 -0
- package/dist/advanced.js +238 -48
- package/dist/auto.cjs +236 -42
- package/dist/auto.js +115 -115
- package/dist/auto.mjs +236 -42
- package/dist/cli.cjs +153 -153
- package/dist/editor.cjs +3 -0
- package/dist/editor.js +3 -0
- package/dist/highlight.cjs +3 -0
- package/dist/highlight.js +3 -0
- package/dist/index.cjs +232 -41
- package/dist/index.js +232 -41
- package/dist/internal.cjs +238 -48
- package/dist/internal.d.cts +17 -0
- package/dist/internal.d.ts +17 -0
- package/dist/internal.js +238 -48
- package/dist/map-data/PROVENANCE.json +1 -1
- package/dist/map-data/gazetteer.json +1 -1
- package/dist/map-data/mountain-ranges.json +1 -1
- package/dist/map-data/water-bodies.json +1 -1
- package/dist/map-data/world-coarse.json +1 -1
- package/dist/map-data/world-detail.json +1 -1
- package/docs/language-reference.md +35 -0
- package/gallery/fixtures/boxes-and-lines.dgmo +6 -4
- package/package.json +1 -1
- package/src/boxes-and-lines/parser.ts +39 -0
- package/src/boxes-and-lines/renderer.ts +171 -13
- package/src/boxes-and-lines/types.ts +9 -0
- package/src/completion.ts +4 -5
- package/src/d3.ts +12 -4
- package/src/editor/keywords.ts +3 -0
- package/src/map/data/PROVENANCE.json +1 -1
- package/src/map/data/README.md +6 -0
- package/src/map/data/gazetteer.json +1 -1
- package/src/map/data/mountain-ranges.json +1 -1
- package/src/map/data/water-bodies.json +1 -1
- package/src/map/data/world-coarse.json +1 -1
- package/src/map/data/world-detail.json +1 -1
- package/src/map/layout.ts +111 -18
- package/src/map/renderer.ts +95 -4
- package/src/utils/reserved-key-registry.ts +5 -3
package/dist/auto.cjs
CHANGED
|
@@ -820,9 +820,7 @@ var init_reserved_key_registry = __esm({
|
|
|
820
820
|
BOXES_AND_LINES_REGISTRY = staticRegistry([
|
|
821
821
|
"color",
|
|
822
822
|
"description",
|
|
823
|
-
"
|
|
824
|
-
"split",
|
|
825
|
-
"fanout"
|
|
823
|
+
"value"
|
|
826
824
|
]);
|
|
827
825
|
TIMELINE_REGISTRY = staticRegistry([
|
|
828
826
|
"color",
|
|
@@ -16824,6 +16822,21 @@ function parseBoxesAndLines(content) {
|
|
|
16824
16822
|
}
|
|
16825
16823
|
continue;
|
|
16826
16824
|
}
|
|
16825
|
+
if (!contentStarted) {
|
|
16826
|
+
const metricMatch = trimmed.match(/^box-metric\s+(.+)$/i);
|
|
16827
|
+
if (metricMatch) {
|
|
16828
|
+
const { label, colorName } = peelTrailingColorName(
|
|
16829
|
+
metricMatch[1].trim()
|
|
16830
|
+
);
|
|
16831
|
+
result.boxMetric = label;
|
|
16832
|
+
if (colorName !== void 0) result.boxMetricColor = colorName;
|
|
16833
|
+
continue;
|
|
16834
|
+
}
|
|
16835
|
+
if (/^show-values$/i.test(trimmed)) {
|
|
16836
|
+
result.showValues = true;
|
|
16837
|
+
continue;
|
|
16838
|
+
}
|
|
16839
|
+
}
|
|
16827
16840
|
if (!contentStarted) {
|
|
16828
16841
|
const optMatch = trimmed.match(OPTION_NOCOLON_RE);
|
|
16829
16842
|
if (optMatch) {
|
|
@@ -17202,6 +17215,19 @@ function parseNodeLine(trimmed, lineNum, metaAliasMap, diagnostics, nameAliasMap
|
|
|
17202
17215
|
description = [metadata["description"]];
|
|
17203
17216
|
delete metadata["description"];
|
|
17204
17217
|
}
|
|
17218
|
+
let value;
|
|
17219
|
+
if (metadata["value"] !== void 0) {
|
|
17220
|
+
const raw = metadata["value"];
|
|
17221
|
+
const num = Number(raw);
|
|
17222
|
+
if (Number.isFinite(num)) {
|
|
17223
|
+
value = num;
|
|
17224
|
+
} else {
|
|
17225
|
+
diagnostics.push(
|
|
17226
|
+
makeDgmoError(lineNum, `value must be a number (got "${raw}")`, "error")
|
|
17227
|
+
);
|
|
17228
|
+
}
|
|
17229
|
+
delete metadata["value"];
|
|
17230
|
+
}
|
|
17205
17231
|
if (split.alias) {
|
|
17206
17232
|
nameAliasMap?.set(normalizeName(split.alias), label);
|
|
17207
17233
|
}
|
|
@@ -17210,7 +17236,8 @@ function parseNodeLine(trimmed, lineNum, metaAliasMap, diagnostics, nameAliasMap
|
|
|
17210
17236
|
label,
|
|
17211
17237
|
lineNumber: lineNum,
|
|
17212
17238
|
metadata,
|
|
17213
|
-
...description !== void 0 && { description }
|
|
17239
|
+
...description !== void 0 && { description },
|
|
17240
|
+
...value !== void 0 && { value }
|
|
17214
17241
|
};
|
|
17215
17242
|
}
|
|
17216
17243
|
function splitTargetAndMeta(rest, metaAliasMap) {
|
|
@@ -26330,7 +26357,18 @@ function fitLabelToHeader(label, nodeWidth, maxLines) {
|
|
|
26330
26357
|
const truncated = label.length > maxChars ? label.slice(0, maxChars - 1) + "\u2026" : label;
|
|
26331
26358
|
return { lines: [truncated], fontSize: MIN_NODE_FONT_SIZE };
|
|
26332
26359
|
}
|
|
26333
|
-
function nodeColors(node, tagGroups, activeGroupName, palette, isDark, solid) {
|
|
26360
|
+
function nodeColors(node, tagGroups, activeGroupName, palette, isDark, value, solid) {
|
|
26361
|
+
const neutralFill = mix(palette.bg, palette.text, isDark ? 90 : 95);
|
|
26362
|
+
if (value.active) {
|
|
26363
|
+
const fill3 = node.value !== void 0 ? value.fillForValue(node.value) : neutralFill;
|
|
26364
|
+
const stroke3 = value.hue;
|
|
26365
|
+
const text2 = contrastText(
|
|
26366
|
+
fill3,
|
|
26367
|
+
palette.textOnFillLight,
|
|
26368
|
+
palette.textOnFillDark
|
|
26369
|
+
);
|
|
26370
|
+
return { fill: fill3, stroke: stroke3, text: text2 };
|
|
26371
|
+
}
|
|
26334
26372
|
const tagColor = resolveTagColor(
|
|
26335
26373
|
node.metadata,
|
|
26336
26374
|
[...tagGroups],
|
|
@@ -26439,25 +26477,65 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26439
26477
|
const sGroupLabelZone = sctx.structural(GROUP_LABEL_ZONE);
|
|
26440
26478
|
const sTitleFontSize = sctx.text(TITLE_FONT_SIZE);
|
|
26441
26479
|
const sTitleY = sctx.structural(TITLE_Y);
|
|
26480
|
+
const nodeValues = parsed.nodes.filter((n) => n.value !== void 0).map((n) => n.value);
|
|
26481
|
+
const hasRamp = nodeValues.length > 0;
|
|
26482
|
+
const allNonNegative = hasRamp && nodeValues.every((v) => v >= 0);
|
|
26483
|
+
const rampMin = allNonNegative ? 0 : Math.min(...nodeValues);
|
|
26484
|
+
const rampMax = Math.max(...nodeValues);
|
|
26485
|
+
const rampHue = resolveColor(parsed.boxMetricColor ?? "", palette) ?? palette.primary;
|
|
26486
|
+
const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
|
|
26487
|
+
const fillForValue = (v) => {
|
|
26488
|
+
const t = rampMax > rampMin ? (v - rampMin) / (rampMax - rampMin) : 1;
|
|
26489
|
+
const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
|
|
26490
|
+
return mix(rampHue, rampBase, pct);
|
|
26491
|
+
};
|
|
26492
|
+
const VALUE_NAME = hasRamp ? parsed.boxMetric?.trim() || "Value" : null;
|
|
26493
|
+
const matchColorGroup = (v) => {
|
|
26494
|
+
const lv = v.trim().toLowerCase();
|
|
26495
|
+
if (lv === "none") return null;
|
|
26496
|
+
const tg = parsed.tagGroups.find((g) => g.name.toLowerCase() === lv);
|
|
26497
|
+
if (tg) return tg.name;
|
|
26498
|
+
if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
|
|
26499
|
+
return v;
|
|
26500
|
+
};
|
|
26501
|
+
const override = activeTagGroup;
|
|
26502
|
+
let activeGroup;
|
|
26503
|
+
if (override !== void 0) {
|
|
26504
|
+
activeGroup = override === null ? null : matchColorGroup(override);
|
|
26505
|
+
} else if (parsed.options["active-tag"] !== void 0) {
|
|
26506
|
+
activeGroup = matchColorGroup(parsed.options["active-tag"]);
|
|
26507
|
+
} else {
|
|
26508
|
+
activeGroup = VALUE_NAME ?? (parsed.tagGroups.length > 0 ? parsed.tagGroups[0].name : null);
|
|
26509
|
+
}
|
|
26510
|
+
const activeIsValue = VALUE_NAME !== null && activeGroup === VALUE_NAME;
|
|
26511
|
+
const valueGroup = VALUE_NAME !== null ? {
|
|
26512
|
+
name: VALUE_NAME,
|
|
26513
|
+
entries: [],
|
|
26514
|
+
gradient: {
|
|
26515
|
+
min: rampMin,
|
|
26516
|
+
max: rampMax,
|
|
26517
|
+
hue: rampHue,
|
|
26518
|
+
base: rampBase
|
|
26519
|
+
}
|
|
26520
|
+
} : null;
|
|
26521
|
+
const legendGroups = [
|
|
26522
|
+
...valueGroup ? [valueGroup] : [],
|
|
26523
|
+
...parsed.tagGroups
|
|
26524
|
+
];
|
|
26442
26525
|
const reserveHasDescriptions = parsed.nodes.some(
|
|
26443
26526
|
(n) => n.description && n.description.length > 0
|
|
26444
26527
|
);
|
|
26445
|
-
const willRenderLegend =
|
|
26528
|
+
const willRenderLegend = legendGroups.length > 0 || reserveHasDescriptions && controlsHost !== "app";
|
|
26446
26529
|
const sLegendHeight = willRenderLegend ? sctx.structural(
|
|
26447
26530
|
getMaxLegendReservedHeight(
|
|
26448
26531
|
{
|
|
26449
|
-
groups:
|
|
26532
|
+
groups: legendGroups,
|
|
26450
26533
|
position: { placement: "top-center", titleRelation: "below-title" },
|
|
26451
26534
|
mode: exportMode ? "export" : "preview"
|
|
26452
26535
|
},
|
|
26453
26536
|
width
|
|
26454
26537
|
)
|
|
26455
26538
|
) : 0;
|
|
26456
|
-
const activeGroup = resolveActiveTagGroup(
|
|
26457
|
-
parsed.tagGroups,
|
|
26458
|
-
parsed.options["active-tag"],
|
|
26459
|
-
activeTagGroup
|
|
26460
|
-
);
|
|
26461
26539
|
const hidden = hiddenTagValues ?? parsed.initialHiddenTagValues;
|
|
26462
26540
|
const nodeMap = /* @__PURE__ */ new Map();
|
|
26463
26541
|
for (const node of parsed.nodes) nodeMap.set(node.label, node);
|
|
@@ -26468,7 +26546,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26468
26546
|
const hasAnyDescriptions = parsed.nodes.some(
|
|
26469
26547
|
(n) => n.description && n.description.length > 0
|
|
26470
26548
|
);
|
|
26471
|
-
const needsLegend =
|
|
26549
|
+
const needsLegend = legendGroups.length > 0 || hasAnyDescriptions && onToggleDescriptions;
|
|
26472
26550
|
const legendH = needsLegend ? sLegendHeight + 8 : 0;
|
|
26473
26551
|
const groupLabelsSet = new Set(layout.groups.map((g) => g.label));
|
|
26474
26552
|
let labelZoneExtension = 0;
|
|
@@ -26674,12 +26752,16 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26674
26752
|
activeGroup,
|
|
26675
26753
|
palette,
|
|
26676
26754
|
isDark,
|
|
26755
|
+
{ active: activeIsValue, hue: rampHue, fillForValue },
|
|
26677
26756
|
parsed.options["solid-fill"] === "on"
|
|
26678
26757
|
);
|
|
26679
26758
|
const nodeG = diagramG.append("g").attr("class", "bl-node").attr("transform", `translate(${ln.x},${ln.y})`).attr("data-line-number", node.lineNumber).attr("data-node-id", node.label).style("cursor", onClickItem ? "pointer" : "default").style("--bl-node-stroke", colors.stroke);
|
|
26680
26759
|
for (const [key, val] of Object.entries(node.metadata)) {
|
|
26681
26760
|
nodeG.attr(`data-tag-${key.toLowerCase()}`, val.toLowerCase());
|
|
26682
26761
|
}
|
|
26762
|
+
if (node.value !== void 0) {
|
|
26763
|
+
nodeG.attr("data-value", node.value);
|
|
26764
|
+
}
|
|
26683
26765
|
if (onClickItem) {
|
|
26684
26766
|
nodeG.on("click", (event) => {
|
|
26685
26767
|
const target = event.target;
|
|
@@ -26763,11 +26845,27 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26763
26845
|
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]);
|
|
26764
26846
|
}
|
|
26765
26847
|
}
|
|
26848
|
+
if (parsed.showValues && node.value !== void 0) {
|
|
26849
|
+
const valueText = String(node.value);
|
|
26850
|
+
const descShown = !!(desc && desc.length > 0 && !hideDescriptions);
|
|
26851
|
+
if (descShown) {
|
|
26852
|
+
const padX = 6;
|
|
26853
|
+
const padY = 5;
|
|
26854
|
+
const bw = valueText.length * VALUE_FONT_SIZE * CHAR_WIDTH_RATIO2 + 8;
|
|
26855
|
+
const bh = VALUE_FONT_SIZE + 4;
|
|
26856
|
+
const bx = ln.width / 2 - bw - 4;
|
|
26857
|
+
const by = -ln.height / 2 + 4;
|
|
26858
|
+
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);
|
|
26859
|
+
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);
|
|
26860
|
+
} else {
|
|
26861
|
+
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);
|
|
26862
|
+
}
|
|
26863
|
+
}
|
|
26766
26864
|
}
|
|
26767
26865
|
const hasDescriptions = parsed.nodes.some(
|
|
26768
26866
|
(n) => n.description && n.description.length > 0
|
|
26769
26867
|
);
|
|
26770
|
-
const hasLegend =
|
|
26868
|
+
const hasLegend = legendGroups.length > 0 || hasDescriptions && controlsHost !== "app";
|
|
26771
26869
|
if (hasLegend) {
|
|
26772
26870
|
let controlsGroup;
|
|
26773
26871
|
if (hasDescriptions && (onToggleDescriptions || controlsHost === "app")) {
|
|
@@ -26785,7 +26883,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26785
26883
|
};
|
|
26786
26884
|
}
|
|
26787
26885
|
const legendConfig = {
|
|
26788
|
-
groups:
|
|
26886
|
+
groups: legendGroups,
|
|
26789
26887
|
position: { placement: "top-center", titleRelation: "below-title" },
|
|
26790
26888
|
mode: exportMode ? "export" : "preview",
|
|
26791
26889
|
// Keep inactive sibling tag groups visible as collapsed pills so the user
|
|
@@ -26840,7 +26938,7 @@ function renderBoxesAndLinesForExport(container, parsed, layout, palette, isDark
|
|
|
26840
26938
|
}
|
|
26841
26939
|
});
|
|
26842
26940
|
}
|
|
26843
|
-
var d3Selection6, d3Shape4, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, CHAR_WIDTH_RATIO2, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, lineGeneratorLR, lineGeneratorTB;
|
|
26941
|
+
var d3Selection6, d3Shape4, DIAGRAM_PADDING6, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE4, EDGE_STROKE_WIDTH5, NODE_STROKE_WIDTH5, NODE_RX, COLLAPSE_BAR_HEIGHT3, ARROWHEAD_W2, ARROWHEAD_H2, DESC_FONT_SIZE, DESC_LINE_HEIGHT, MAX_DESC_LINES, CHAR_WIDTH_RATIO2, NODE_TEXT_PADDING, GROUP_RX, GROUP_LABEL_FONT_SIZE, GROUP_LABEL_ZONE, RAMP_FLOOR, VALUE_FONT_SIZE, lineGeneratorLR, lineGeneratorTB;
|
|
26844
26942
|
var init_renderer6 = __esm({
|
|
26845
26943
|
"src/boxes-and-lines/renderer.ts"() {
|
|
26846
26944
|
"use strict";
|
|
@@ -26851,6 +26949,7 @@ var init_renderer6 = __esm({
|
|
|
26851
26949
|
init_legend_layout();
|
|
26852
26950
|
init_title_constants();
|
|
26853
26951
|
init_color_utils();
|
|
26952
|
+
init_colors();
|
|
26854
26953
|
init_tag_groups();
|
|
26855
26954
|
init_inline_markdown();
|
|
26856
26955
|
init_wrapped_desc();
|
|
@@ -26873,6 +26972,8 @@ var init_renderer6 = __esm({
|
|
|
26873
26972
|
GROUP_RX = 8;
|
|
26874
26973
|
GROUP_LABEL_FONT_SIZE = 14;
|
|
26875
26974
|
GROUP_LABEL_ZONE = 32;
|
|
26975
|
+
RAMP_FLOOR = 15;
|
|
26976
|
+
VALUE_FONT_SIZE = 11;
|
|
26876
26977
|
lineGeneratorLR = d3Shape4.line().x((d) => d.x).y((d) => d.y).curve(d3Shape4.curveBasis);
|
|
26877
26978
|
lineGeneratorTB = d3Shape4.line().x((d) => d.x).y((d) => d.y).curve(d3Shape4.curveBasis);
|
|
26878
26979
|
}
|
|
@@ -47204,6 +47305,38 @@ function parsePathRings(d) {
|
|
|
47204
47305
|
if (cur.length) rings.push(cur);
|
|
47205
47306
|
return rings;
|
|
47206
47307
|
}
|
|
47308
|
+
function dropAntimeridianWrapSlivers(d, width, height) {
|
|
47309
|
+
const rings = parsePathRings(d);
|
|
47310
|
+
if (rings.length <= 1) return d;
|
|
47311
|
+
const eps = 0.75;
|
|
47312
|
+
const minArea = 3e-3 * width * height;
|
|
47313
|
+
const ringArea = (r) => {
|
|
47314
|
+
let s = 0;
|
|
47315
|
+
for (let i = 0; i < r.length; i++) {
|
|
47316
|
+
const a = r[i];
|
|
47317
|
+
const b = r[(i + 1) % r.length];
|
|
47318
|
+
s += a[0] * b[1] - b[0] * a[1];
|
|
47319
|
+
}
|
|
47320
|
+
return Math.abs(s) / 2;
|
|
47321
|
+
};
|
|
47322
|
+
const areas = rings.map(ringArea);
|
|
47323
|
+
const maxArea = Math.max(...areas);
|
|
47324
|
+
const onVEdge = (a, b) => Math.abs(a[0]) <= eps && Math.abs(b[0]) <= eps || Math.abs(a[0] - width) <= eps && Math.abs(b[0] - width) <= eps;
|
|
47325
|
+
let dropped = false;
|
|
47326
|
+
const kept = rings.filter((r, idx) => {
|
|
47327
|
+
if (areas[idx] >= maxArea || areas[idx] >= minArea) return true;
|
|
47328
|
+
const touches = r.some((p, i) => onVEdge(p, r[(i + 1) % r.length]));
|
|
47329
|
+
if (touches) {
|
|
47330
|
+
dropped = true;
|
|
47331
|
+
return false;
|
|
47332
|
+
}
|
|
47333
|
+
return true;
|
|
47334
|
+
});
|
|
47335
|
+
if (!dropped) return d;
|
|
47336
|
+
return kept.map(
|
|
47337
|
+
(r) => r.map((p, i) => (i ? "L" : "M") + p[0] + "," + p[1]).join("") + "Z"
|
|
47338
|
+
).join("");
|
|
47339
|
+
}
|
|
47207
47340
|
function layoutMap(resolved, data, size, opts) {
|
|
47208
47341
|
const { palette, isDark } = opts;
|
|
47209
47342
|
const { width, height } = size;
|
|
@@ -47287,7 +47420,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47287
47420
|
const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
|
|
47288
47421
|
const fillForValue = (s) => {
|
|
47289
47422
|
const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
|
|
47290
|
-
const pct =
|
|
47423
|
+
const pct = RAMP_FLOOR2 + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR2);
|
|
47291
47424
|
return mix(rampHue, rampBase, pct);
|
|
47292
47425
|
};
|
|
47293
47426
|
const tagFill = (tags, groupName) => {
|
|
@@ -47346,10 +47479,11 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47346
47479
|
const by0 = cb[0][1];
|
|
47347
47480
|
const cw = cb[1][0] - bx0;
|
|
47348
47481
|
const ch = cb[1][1] - by0;
|
|
47349
|
-
const
|
|
47350
|
-
const
|
|
47351
|
-
const
|
|
47352
|
-
const
|
|
47482
|
+
const topReserve = resolved.title && resolved.pois.length > 0 ? topPad : 0;
|
|
47483
|
+
const ox = 0;
|
|
47484
|
+
const oy = topReserve;
|
|
47485
|
+
const sx = cw > 0 ? width / cw : 1;
|
|
47486
|
+
const sy = ch > 0 ? (height - topReserve) / ch : 1;
|
|
47353
47487
|
stretchParams = { sx, sy, ox, oy, bx0, by0 };
|
|
47354
47488
|
const stretch = (x, y) => [
|
|
47355
47489
|
ox + (x - bx0) * sx,
|
|
@@ -47622,7 +47756,8 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47622
47756
|
const r = regionById.get(iso);
|
|
47623
47757
|
const viewF = shouldCull ? cullFeatureToView(f) : dropFrameFillers(f);
|
|
47624
47758
|
if (!viewF) continue;
|
|
47625
|
-
const
|
|
47759
|
+
const raw = path(viewF) ?? "";
|
|
47760
|
+
const d = fitIsGlobal ? dropAntimeridianWrapSlivers(raw, width, height) : raw;
|
|
47626
47761
|
if (!d) continue;
|
|
47627
47762
|
const isThisLayer = r?.layer === layerKind;
|
|
47628
47763
|
const isForeign = layerKind === "country" && usContext && iso !== "US";
|
|
@@ -47639,6 +47774,9 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47639
47774
|
} else {
|
|
47640
47775
|
label = f.properties?.name;
|
|
47641
47776
|
}
|
|
47777
|
+
const labelAnchor = WORLD_LABEL_ANCHORS[iso];
|
|
47778
|
+
const c = labelAnchor ? project(labelAnchor[0], labelAnchor[1]) : path.centroid(viewF);
|
|
47779
|
+
const hasCentroid = c != null && Number.isFinite(c[0]) && Number.isFinite(c[1]);
|
|
47642
47780
|
regions.push({
|
|
47643
47781
|
id: iso,
|
|
47644
47782
|
d,
|
|
@@ -47647,6 +47785,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47647
47785
|
lineNumber,
|
|
47648
47786
|
layer,
|
|
47649
47787
|
...label !== void 0 && { label },
|
|
47788
|
+
...hasCentroid && { labelX: c[0], labelY: c[1] },
|
|
47650
47789
|
...isThisLayer && r.value !== void 0 && { value: r.value },
|
|
47651
47790
|
...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
|
|
47652
47791
|
});
|
|
@@ -48087,10 +48226,6 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
48087
48226
|
lineNumber
|
|
48088
48227
|
});
|
|
48089
48228
|
};
|
|
48090
|
-
const WORLD_LABEL_ANCHORS = {
|
|
48091
|
-
US: [-98.5, 39.5]
|
|
48092
|
-
// CONUS geographic centre (near Lebanon, Kansas)
|
|
48093
|
-
};
|
|
48094
48229
|
const REGION_LABEL_GAP = 2;
|
|
48095
48230
|
const regionLabelRect = (cx, cy, text) => {
|
|
48096
48231
|
const w = measureLegendText(text, FONT2) + 2 * REGION_LABEL_GAP;
|
|
@@ -48456,7 +48591,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
48456
48591
|
diagnostics: []
|
|
48457
48592
|
};
|
|
48458
48593
|
}
|
|
48459
|
-
var import_d3_geo2, import_topojson_client2, FIT_PAD,
|
|
48594
|
+
var import_d3_geo2, import_topojson_client2, FIT_PAD, RAMP_FLOOR2, R_DEFAULT, R_MIN, R_MAX, W_MIN, W_MAX, FONT2, WORLD_LABEL_ANCHORS, MAX_CLUSTER_EXTENT_FACTOR, MAX_COLUMN_ROWS, REGION_LABEL_HALO_RATIO, LAND_TINT_LIGHT, LAND_TINT_DARK, TAG_TINT_LIGHT, TAG_TINT_DARK, WATER_TINT_LIGHT, WATER_TINT_DARK, RIVER_WIDTH, COMPACT_WIDTH_PX, RELIEF_MIN_AREA, RELIEF_MIN_DIM, RELIEF_HATCH_SPACING, RELIEF_HATCH_WIDTH, RELIEF_HATCH_STRENGTH, COASTLINE_RING_COUNT, COASTLINE_D0, COASTLINE_STEP, COASTLINE_THICKNESS, COASTLINE_OPACITY_NEAR, COASTLINE_OPACITY_FAR, COASTLINE_MIN_EXTENT, COASTLINE_MIN_EXTENT_GLOBAL, COASTLINE_STROKE_MIX, FOREIGN_TINT_LIGHT, FOREIGN_TINT_DARK, MUTED_FOREIGN_LIGHT, MUTED_FOREIGN_DARK, COLO_R, GOLDEN_ANGLE, STACK_OVERLAP, STACK_RING_MAX, STACK_RING_GAP, FAN_STEP, ARC_CURVE_FRAC, decodeCache, usConusProjection, alaskaProjection, hawaiiProjection, INSET_STATES, inAlaska, inHawaii, FOREIGN_BORDER, US_NON_CONUS;
|
|
48460
48595
|
var init_layout15 = __esm({
|
|
48461
48596
|
"src/map/layout.ts"() {
|
|
48462
48597
|
"use strict";
|
|
@@ -48471,13 +48606,17 @@ var init_layout15 = __esm({
|
|
|
48471
48606
|
init_title_constants();
|
|
48472
48607
|
init_context_labels();
|
|
48473
48608
|
FIT_PAD = 24;
|
|
48474
|
-
|
|
48609
|
+
RAMP_FLOOR2 = 15;
|
|
48475
48610
|
R_DEFAULT = 6;
|
|
48476
48611
|
R_MIN = 4;
|
|
48477
48612
|
R_MAX = 22;
|
|
48478
48613
|
W_MIN = 1.25;
|
|
48479
48614
|
W_MAX = 8;
|
|
48480
48615
|
FONT2 = 11;
|
|
48616
|
+
WORLD_LABEL_ANCHORS = {
|
|
48617
|
+
US: [-98.5, 39.5]
|
|
48618
|
+
// CONUS geographic centre (near Lebanon, Kansas)
|
|
48619
|
+
};
|
|
48481
48620
|
MAX_CLUSTER_EXTENT_FACTOR = 0.18;
|
|
48482
48621
|
MAX_COLUMN_ROWS = 7;
|
|
48483
48622
|
REGION_LABEL_HALO_RATIO = 4.5;
|
|
@@ -48491,9 +48630,9 @@ var init_layout15 = __esm({
|
|
|
48491
48630
|
COMPACT_WIDTH_PX = 480;
|
|
48492
48631
|
RELIEF_MIN_AREA = 12;
|
|
48493
48632
|
RELIEF_MIN_DIM = 2;
|
|
48494
|
-
RELIEF_HATCH_SPACING =
|
|
48495
|
-
RELIEF_HATCH_WIDTH = 0.
|
|
48496
|
-
RELIEF_HATCH_STRENGTH =
|
|
48633
|
+
RELIEF_HATCH_SPACING = 1.5;
|
|
48634
|
+
RELIEF_HATCH_WIDTH = 0.2;
|
|
48635
|
+
RELIEF_HATCH_STRENGTH = 26;
|
|
48497
48636
|
COASTLINE_RING_COUNT = 5;
|
|
48498
48637
|
COASTLINE_D0 = 16e-4;
|
|
48499
48638
|
COASTLINE_STEP = 28e-4;
|
|
@@ -48571,7 +48710,47 @@ function ringToPath(ring) {
|
|
|
48571
48710
|
d += (i ? "L" : "M") + ring[i][0] + "," + ring[i][1];
|
|
48572
48711
|
return d + "Z";
|
|
48573
48712
|
}
|
|
48574
|
-
function
|
|
48713
|
+
function polylineToPath(pts) {
|
|
48714
|
+
let d = "";
|
|
48715
|
+
for (let i = 0; i < pts.length; i++)
|
|
48716
|
+
d += (i ? "L" : "M") + pts[i][0] + "," + pts[i][1];
|
|
48717
|
+
return d;
|
|
48718
|
+
}
|
|
48719
|
+
function ringToCoastPaths(ring, frame) {
|
|
48720
|
+
if (!frame) return [ringToPath(ring)];
|
|
48721
|
+
const n = ring.length;
|
|
48722
|
+
const eps = 0.75;
|
|
48723
|
+
const onL = (x) => Math.abs(x) <= eps;
|
|
48724
|
+
const onR = (x) => Math.abs(x - frame.w) <= eps;
|
|
48725
|
+
const onT = (y) => Math.abs(y) <= eps;
|
|
48726
|
+
const onB = (y) => Math.abs(y - frame.h) <= eps;
|
|
48727
|
+
const isFrameEdge = (a, b) => onL(a[0]) && onL(b[0]) || onR(a[0]) && onR(b[0]) || onT(a[1]) && onT(b[1]) || onB(a[1]) && onB(b[1]);
|
|
48728
|
+
let firstBreak = -1;
|
|
48729
|
+
for (let i = 0; i < n; i++)
|
|
48730
|
+
if (isFrameEdge(ring[i], ring[(i + 1) % n])) {
|
|
48731
|
+
firstBreak = i;
|
|
48732
|
+
break;
|
|
48733
|
+
}
|
|
48734
|
+
if (firstBreak === -1) return [ringToPath(ring)];
|
|
48735
|
+
const paths = [];
|
|
48736
|
+
let cur = [];
|
|
48737
|
+
const start = (firstBreak + 1) % n;
|
|
48738
|
+
for (let k = 0; k < n; k++) {
|
|
48739
|
+
const i = (start + k) % n;
|
|
48740
|
+
const a = ring[i];
|
|
48741
|
+
const b = ring[(i + 1) % n];
|
|
48742
|
+
if (isFrameEdge(a, b)) {
|
|
48743
|
+
if (cur.length >= 2) paths.push(polylineToPath(cur));
|
|
48744
|
+
cur = [];
|
|
48745
|
+
continue;
|
|
48746
|
+
}
|
|
48747
|
+
if (cur.length === 0) cur.push(a);
|
|
48748
|
+
cur.push(b);
|
|
48749
|
+
}
|
|
48750
|
+
if (cur.length >= 2) paths.push(polylineToPath(cur));
|
|
48751
|
+
return paths;
|
|
48752
|
+
}
|
|
48753
|
+
function coastlineOuterRings(regions, minExtent, frame) {
|
|
48575
48754
|
const paths = [];
|
|
48576
48755
|
for (const r of regions) {
|
|
48577
48756
|
const rings = parsePathRings(r.d);
|
|
@@ -48594,7 +48773,7 @@ function coastlineOuterRings(regions, minExtent) {
|
|
|
48594
48773
|
for (let j = 0; j < rings.length; j++)
|
|
48595
48774
|
if (j !== i && pointInRing2(fx, fy, rings[j])) depth++;
|
|
48596
48775
|
if (depth % 2 === 1) continue;
|
|
48597
|
-
paths.push(
|
|
48776
|
+
paths.push(...ringToCoastPaths(ring, frame));
|
|
48598
48777
|
}
|
|
48599
48778
|
}
|
|
48600
48779
|
return paths;
|
|
@@ -48638,6 +48817,10 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48638
48817
|
const drawRegion = (g, r, strokeWidth) => {
|
|
48639
48818
|
const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
|
|
48640
48819
|
if (r.label) p.attr("data-region-name", r.label);
|
|
48820
|
+
if (r.id && r.id !== "lake") p.attr("data-iso", r.id);
|
|
48821
|
+
if (r.labelX !== void 0 && r.labelY !== void 0) {
|
|
48822
|
+
p.attr("data-label-x", r.labelX).attr("data-label-y", r.labelY);
|
|
48823
|
+
}
|
|
48641
48824
|
if (r.layer !== "base") {
|
|
48642
48825
|
p.classed("dgmo-map-region", true).attr("data-region", r.id);
|
|
48643
48826
|
if (r.value !== void 0) p.attr("data-value", r.value);
|
|
@@ -48667,7 +48850,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48667
48850
|
const landClip = defs.append("clipPath").attr("id", landClipId);
|
|
48668
48851
|
for (const r of layout.regions)
|
|
48669
48852
|
if (r.id !== "lake") landClip.append("path").attr("d", r.d);
|
|
48670
|
-
const gRelief = svg.append("g").attr("clip-path", `url(#${landClipId})`).append("g").attr("class", "dgmo-map-relief").attr("clip-path", `url(#${rangeClipId})`).attr("stroke", h.color).attr("stroke-width", h.width).attr("vector-effect", "non-scaling-stroke");
|
|
48853
|
+
const gRelief = svg.append("g").attr("clip-path", `url(#${landClipId})`).style("pointer-events", "none").append("g").attr("class", "dgmo-map-relief").attr("clip-path", `url(#${rangeClipId})`).attr("stroke", h.color).attr("stroke-width", h.width).attr("vector-effect", "non-scaling-stroke");
|
|
48671
48854
|
for (let y = h.spacing; y < height; y += h.spacing) {
|
|
48672
48855
|
gRelief.append("line").attr("x1", 0).attr("y1", y).attr("x2", width).attr("y2", y);
|
|
48673
48856
|
}
|
|
@@ -48688,10 +48871,16 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48688
48871
|
mask.append("path").attr("d", d).attr("fill", "black").attr("stroke", "black").attr("stroke-width", 2 * reach).attr("stroke-linejoin", "round");
|
|
48689
48872
|
}
|
|
48690
48873
|
}
|
|
48691
|
-
const gWater = svg.append("g").attr("class", "dgmo-map-water-lines").attr("fill", "none").attr("mask", `url(#${maskId})`);
|
|
48874
|
+
const gWater = svg.append("g").attr("class", "dgmo-map-water-lines").attr("fill", "none").style("pointer-events", "none").attr("mask", `url(#${maskId})`);
|
|
48692
48875
|
appendWaterLines(
|
|
48693
48876
|
gWater,
|
|
48694
|
-
|
|
48877
|
+
// Pass the canvas frame so edges collinear with it (the antimeridian on a
|
|
48878
|
+
// world map, regional clipExtent cuts) don't get ringed as fake coast —
|
|
48879
|
+
// land runs cleanly to the render-area edge.
|
|
48880
|
+
coastlineOuterRings(layout.regions, cs.minExtent, {
|
|
48881
|
+
w: width,
|
|
48882
|
+
h: height
|
|
48883
|
+
}),
|
|
48695
48884
|
cs,
|
|
48696
48885
|
layout.background
|
|
48697
48886
|
);
|
|
@@ -48705,7 +48894,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48705
48894
|
gWater.append("path").attr("d", ds.join(" ")).attr("stroke", stroke2).attr("stroke-width", 0.5).attr("stroke-linejoin", "round");
|
|
48706
48895
|
}
|
|
48707
48896
|
if (layout.rivers.length) {
|
|
48708
|
-
const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none");
|
|
48897
|
+
const gRivers = svg.append("g").attr("class", "dgmo-map-rivers").attr("fill", "none").style("pointer-events", "none");
|
|
48709
48898
|
for (const r of layout.rivers) {
|
|
48710
48899
|
gRivers.append("path").attr("d", r.d).attr("stroke", r.color).attr("stroke-width", r.width).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
48711
48900
|
}
|
|
@@ -48746,7 +48935,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
48746
48935
|
const d = box.points.map((p, i) => `${i ? "L" : "M"}${p[0]},${p[1]}`).join("") + "Z";
|
|
48747
48936
|
clip.append("path").attr("d", d);
|
|
48748
48937
|
}
|
|
48749
|
-
const gInsetWater = insetG.append("g").attr("clip-path", `url(#${clipId})`).append("g").attr("class", "dgmo-map-inset-water-lines").attr("fill", "none").attr("mask", `url(#${maskId})`);
|
|
48938
|
+
const gInsetWater = insetG.append("g").attr("clip-path", `url(#${clipId})`).append("g").attr("class", "dgmo-map-inset-water-lines").attr("fill", "none").style("pointer-events", "none").attr("mask", `url(#${maskId})`);
|
|
48750
48939
|
appendWaterLines(
|
|
48751
48940
|
gInsetWater,
|
|
48752
48941
|
coastlineOuterRings(layout.insetRegions, cs.minExtent),
|
|
@@ -54764,10 +54953,12 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
|
|
|
54764
54953
|
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
54765
54954
|
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
54766
54955
|
const innerWidth = width - margin.left - margin.right;
|
|
54767
|
-
const
|
|
54768
|
-
const rowH = Math.min(ctx.structural(28),
|
|
54956
|
+
const availInnerHeight = height - margin.top - margin.bottom;
|
|
54957
|
+
const rowH = Math.min(ctx.structural(28), availInnerHeight / sorted.length);
|
|
54958
|
+
const innerHeight = rowH * sorted.length;
|
|
54959
|
+
const usedHeight = margin.top + innerHeight + margin.bottom;
|
|
54769
54960
|
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
54770
|
-
const svg = d3Selection23.select(container).append("svg").attr("width", width).attr("height",
|
|
54961
|
+
const svg = d3Selection23.select(container).append("svg").attr("width", width).attr("height", usedHeight).attr("viewBox", `0 0 ${width} ${usedHeight}`).attr("preserveAspectRatio", "xMidYMin meet").style("background", bgColor);
|
|
54771
54962
|
if (ctx.isBelowFloor) {
|
|
54772
54963
|
svg.attr("width", "100%");
|
|
54773
54964
|
}
|
|
@@ -58298,6 +58489,9 @@ var DIRECTIVE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
58298
58489
|
"hide",
|
|
58299
58490
|
"mode",
|
|
58300
58491
|
"direction",
|
|
58492
|
+
// Boxes-and-lines
|
|
58493
|
+
"box-metric",
|
|
58494
|
+
"show-values",
|
|
58301
58495
|
// ER
|
|
58302
58496
|
"notation",
|
|
58303
58497
|
// Class
|
|
@@ -59020,7 +59214,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
|
|
|
59020
59214
|
|
|
59021
59215
|
// src/auto/index.ts
|
|
59022
59216
|
init_safe_href();
|
|
59023
|
-
var VERSION = "0.
|
|
59217
|
+
var VERSION = "0.23.0";
|
|
59024
59218
|
var DEFAULTS = {
|
|
59025
59219
|
theme: "auto",
|
|
59026
59220
|
palette: "nord",
|