@diagrammo/dgmo 0.23.0 → 0.25.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/LICENSE +1 -1
- package/dist/advanced.cjs +166 -91
- package/dist/advanced.d.cts +35 -19
- package/dist/advanced.d.ts +35 -19
- package/dist/advanced.js +166 -91
- package/dist/auto.cjs +167 -92
- package/dist/auto.js +110 -110
- package/dist/auto.mjs +167 -92
- package/dist/cli.cjs +150 -150
- package/dist/index.cjs +298 -91
- package/dist/index.d.cts +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +296 -91
- package/dist/internal.cjs +166 -91
- package/dist/internal.d.cts +35 -19
- package/dist/internal.d.ts +35 -19
- package/dist/internal.js +166 -91
- 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/diagnostics.ts +0 -19
- package/src/index.ts +8 -0
- package/src/map/dimensions.ts +21 -5
- package/src/map/geo.ts +0 -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/sequence/parser.ts +0 -4
- package/src/utils/brand.ts +0 -17
- package/src/utils/legend-d3.ts +18 -8
- package/src/utils/parsing.ts +0 -16
- package/src/utils/reserved-key-registry.ts +0 -12
- package/src/utils/svg-embed.ts +193 -0
package/dist/internal.d.ts
CHANGED
|
@@ -236,6 +236,28 @@ interface ParsedMap {
|
|
|
236
236
|
readonly diagnostics: readonly DgmoError[];
|
|
237
237
|
readonly error: string | null;
|
|
238
238
|
}
|
|
239
|
+
/** Legend descriptor for a rendered map (a layout-stage output, re-exported from
|
|
240
|
+
* `layout.ts`). It lives here so the `legend-band` helper can consume it without
|
|
241
|
+
* importing `layout` — `layout` already value-imports `mapLegendBand`, so the
|
|
242
|
+
* reverse type import would form a layout↔legend-band cycle. */
|
|
243
|
+
interface MapLayoutLegend {
|
|
244
|
+
readonly tagGroups: ReadonlyArray<{
|
|
245
|
+
name: string;
|
|
246
|
+
entries: ReadonlyArray<{
|
|
247
|
+
value: string;
|
|
248
|
+
color: string;
|
|
249
|
+
}>;
|
|
250
|
+
}>;
|
|
251
|
+
readonly activeGroup: string | null;
|
|
252
|
+
readonly ramp?: {
|
|
253
|
+
metric?: string;
|
|
254
|
+
min: number;
|
|
255
|
+
max: number;
|
|
256
|
+
hue: string;
|
|
257
|
+
/** Low end of the ramp gradient (the land colour the fills blend from). */
|
|
258
|
+
base: string;
|
|
259
|
+
};
|
|
260
|
+
}
|
|
239
261
|
|
|
240
262
|
/** A TopoJSON topology (world-coarse/world-detail keyed by ISO 3166-1 alpha-2;
|
|
241
263
|
* us-states keyed by ISO 3166-2). Geometry feature `id` is the ISO code;
|
|
@@ -1568,6 +1590,7 @@ declare function renderForExport(content: string, theme: 'light' | 'dark' | 'tra
|
|
|
1568
1590
|
tagGroup?: string;
|
|
1569
1591
|
exportMode?: boolean;
|
|
1570
1592
|
mapData?: MapData;
|
|
1593
|
+
mapAspect?: number;
|
|
1571
1594
|
}): Promise<string>;
|
|
1572
1595
|
|
|
1573
1596
|
/**
|
|
@@ -4839,24 +4862,7 @@ interface PlacedLabel {
|
|
|
4839
4862
|
readonly clusterMember?: string;
|
|
4840
4863
|
readonly lineNumber: number;
|
|
4841
4864
|
}
|
|
4842
|
-
|
|
4843
|
-
readonly tagGroups: ReadonlyArray<{
|
|
4844
|
-
name: string;
|
|
4845
|
-
entries: ReadonlyArray<{
|
|
4846
|
-
value: string;
|
|
4847
|
-
color: string;
|
|
4848
|
-
}>;
|
|
4849
|
-
}>;
|
|
4850
|
-
readonly activeGroup: string | null;
|
|
4851
|
-
readonly ramp?: {
|
|
4852
|
-
metric?: string;
|
|
4853
|
-
min: number;
|
|
4854
|
-
max: number;
|
|
4855
|
-
hue: string;
|
|
4856
|
-
/** Low end of the ramp gradient (the land colour the fills blend from). */
|
|
4857
|
-
base: string;
|
|
4858
|
-
};
|
|
4859
|
-
}
|
|
4865
|
+
|
|
4860
4866
|
/** A drawn river centerline — an open stroked path (no fill). */
|
|
4861
4867
|
interface MapLayoutRiver {
|
|
4862
4868
|
readonly d: string;
|
|
@@ -4955,6 +4961,10 @@ interface LayoutOptions {
|
|
|
4955
4961
|
* canvas away from the content aspect, so the off-aspect canvas doesn't
|
|
4956
4962
|
* re-distort. The in-app preview pane leaves this unset (keeps stretch-fill). */
|
|
4957
4963
|
readonly preferContain?: boolean;
|
|
4964
|
+
/** Which legend variant gets drawn — `'export'` shows only the active group,
|
|
4965
|
+
* `'preview'` keeps inactive pills. Used to size the reserved legend band so
|
|
4966
|
+
* the projected land starts below the legend. Defaults to `'preview'`. */
|
|
4967
|
+
readonly legendMode?: LegendMode;
|
|
4958
4968
|
}
|
|
4959
4969
|
interface Size {
|
|
4960
4970
|
readonly width: number;
|
|
@@ -5007,7 +5017,13 @@ interface MapExportDimensions {
|
|
|
5007
5017
|
readonly height: number;
|
|
5008
5018
|
readonly preferContain: boolean;
|
|
5009
5019
|
}
|
|
5010
|
-
declare function mapExportDimensions(resolved: ResolvedMap, data: MapData, baseWidth?: number
|
|
5020
|
+
declare function mapExportDimensions(resolved: ResolvedMap, data: MapData, baseWidth?: number,
|
|
5021
|
+
/** WYSIWYG override (app export): the live preview pane's displayed aspect
|
|
5022
|
+
* (width / height). When provided, the canvas adopts it verbatim and
|
|
5023
|
+
* stretch-fills (no clamp, no contain) so the PNG matches exactly what's on
|
|
5024
|
+
* screen. Omitted by every headless consumer (CLI / MCP / SSG / Obsidian),
|
|
5025
|
+
* which keep the intrinsic-aspect sizing below. */
|
|
5026
|
+
aspectOverride?: number): MapExportDimensions;
|
|
5011
5027
|
|
|
5012
5028
|
/** Nearest gazetteer city to a point: the real haversine distance, plus the
|
|
5013
5029
|
* canonical name + ISO + (US-only) subdivision for token shaping. `lon`/`lat`
|
package/dist/internal.js
CHANGED
|
@@ -838,7 +838,7 @@ function withTagAliases(base, aliases) {
|
|
|
838
838
|
function isReservedKey(registry, key) {
|
|
839
839
|
return registry.keys.has(key) || registry.tagAliases.has(key);
|
|
840
840
|
}
|
|
841
|
-
var SEQUENCE_REGISTRY, INFRA_REGISTRY, MAP_REGISTRY, ORG_REGISTRY, C4_REGISTRY, ER_REGISTRY,
|
|
841
|
+
var SEQUENCE_REGISTRY, INFRA_REGISTRY, MAP_REGISTRY, ORG_REGISTRY, C4_REGISTRY, ER_REGISTRY, KANBAN_REGISTRY, SITEMAP_REGISTRY, GANTT_REGISTRY, PERT_REGISTRY, BOXES_AND_LINES_REGISTRY, TIMELINE_REGISTRY, MINDMAP_REGISTRY, TECH_RADAR_REGISTRY, CYCLE_REGISTRY, JOURNEY_MAP_REGISTRY, PYRAMID_REGISTRY, RING_REGISTRY, RACI_REGISTRY;
|
|
842
842
|
var init_reserved_key_registry = __esm({
|
|
843
843
|
"src/utils/reserved-key-registry.ts"() {
|
|
844
844
|
"use strict";
|
|
@@ -882,10 +882,6 @@ var init_reserved_key_registry = __esm({
|
|
|
882
882
|
"description",
|
|
883
883
|
"domain"
|
|
884
884
|
]);
|
|
885
|
-
CLASS_REGISTRY = staticRegistry([
|
|
886
|
-
"color",
|
|
887
|
-
"description"
|
|
888
|
-
]);
|
|
889
885
|
KANBAN_REGISTRY = staticRegistry([
|
|
890
886
|
"color",
|
|
891
887
|
"description",
|
|
@@ -961,7 +957,6 @@ var init_reserved_key_registry = __esm({
|
|
|
961
957
|
"color",
|
|
962
958
|
"description"
|
|
963
959
|
]);
|
|
964
|
-
WIREFRAME_REGISTRY = staticRegistry([]);
|
|
965
960
|
}
|
|
966
961
|
});
|
|
967
962
|
|
|
@@ -4234,6 +4229,9 @@ var init_legend_layout = __esm({
|
|
|
4234
4229
|
});
|
|
4235
4230
|
|
|
4236
4231
|
// src/utils/legend-d3.ts
|
|
4232
|
+
function centerText(sel) {
|
|
4233
|
+
return sel.attr("dy", LEGEND_TEXT_DY);
|
|
4234
|
+
}
|
|
4237
4235
|
function renderLegendD3(container, config, state, palette, isDark, callbacks, containerWidth) {
|
|
4238
4236
|
const width = containerWidth ?? parseFloat(container.attr("width") || "800");
|
|
4239
4237
|
let currentState = { ...state };
|
|
@@ -4316,21 +4314,21 @@ function renderCapsule(parent, capsule, palette, groupBg, pillBorder, _isDark, c
|
|
|
4316
4314
|
const pill = capsule.pill;
|
|
4317
4315
|
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);
|
|
4318
4316
|
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);
|
|
4319
|
-
g.append("text").attr("x", pill.x + pill.width / 2).attr("y", LEGEND_HEIGHT / 2).attr("text-anchor", "middle").
|
|
4317
|
+
g.append("text").attr("x", pill.x + pill.width / 2).attr("y", LEGEND_HEIGHT / 2).attr("text-anchor", "middle").call(centerText).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);
|
|
4320
4318
|
if (capsule.gradient) {
|
|
4321
4319
|
const gr = capsule.gradient;
|
|
4322
4320
|
const gradId = `dgmo-legend-ramp-${capsule.groupName.toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
|
|
4323
4321
|
const def = g.append("defs").append("linearGradient").attr("id", gradId);
|
|
4324
4322
|
def.append("stop").attr("offset", "0%").attr("stop-color", mix(gr.hue, gr.base, 15));
|
|
4325
4323
|
def.append("stop").attr("offset", "100%").attr("stop-color", gr.hue);
|
|
4326
|
-
g.append("text").attr("x", gr.minX).attr("y", gr.textY).
|
|
4324
|
+
g.append("text").attr("x", gr.minX).attr("y", gr.textY).call(centerText).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).attr("pointer-events", "none").attr("font-family", FONT_FAMILY).text(gr.minText);
|
|
4327
4325
|
g.append("rect").attr("class", "dgmo-legend-gradient-ramp").attr("data-ramp-min", gr.min).attr("data-ramp-max", gr.max).attr("x", gr.rampX).attr("y", gr.rampY).attr("width", gr.rampW).attr("height", gr.rampH).attr("rx", 2).attr("fill", `url(#${gradId})`);
|
|
4328
|
-
g.append("text").attr("x", gr.maxX).attr("y", gr.textY).
|
|
4326
|
+
g.append("text").attr("x", gr.maxX).attr("y", gr.textY).call(centerText).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).attr("pointer-events", "none").attr("font-family", FONT_FAMILY).text(gr.maxText);
|
|
4329
4327
|
}
|
|
4330
4328
|
for (const entry of capsule.entries) {
|
|
4331
4329
|
const entryG = g.append("g").attr("data-legend-entry", entry.value.toLowerCase()).attr("data-series-name", entry.value).style("cursor", "pointer");
|
|
4332
4330
|
entryG.append("circle").attr("cx", entry.dotCx).attr("cy", entry.dotCy).attr("r", LEGEND_DOT_R).attr("fill", entry.color);
|
|
4333
|
-
entryG.append("text").attr("x", entry.textX).attr("y", entry.textY).
|
|
4331
|
+
entryG.append("text").attr("x", entry.textX).attr("y", entry.textY).call(centerText).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).attr("font-family", FONT_FAMILY).text(entry.displayValue ?? entry.value);
|
|
4334
4332
|
if (callbacks?.onEntryHover) {
|
|
4335
4333
|
const groupName = capsule.groupName;
|
|
4336
4334
|
const entryValue = entry.value;
|
|
@@ -4350,7 +4348,7 @@ function renderCapsule(parent, capsule, palette, groupBg, pillBorder, _isDark, c
|
|
|
4350
4348
|
function renderPill(parent, pill, palette, groupBg, callbacks) {
|
|
4351
4349
|
const g = parent.append("g").attr("transform", `translate(${pill.x},${pill.y})`).attr("data-legend-group", pill.groupName.toLowerCase()).style("cursor", "pointer");
|
|
4352
4350
|
g.append("rect").attr("width", pill.width).attr("height", pill.height).attr("rx", pill.height / 2).attr("fill", groupBg);
|
|
4353
|
-
g.append("text").attr("x", pill.width / 2).attr("y", pill.height / 2).attr("text-anchor", "middle").
|
|
4351
|
+
g.append("text").attr("x", pill.width / 2).attr("y", pill.height / 2).attr("text-anchor", "middle").call(centerText).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);
|
|
4354
4352
|
if (callbacks?.onGroupToggle) {
|
|
4355
4353
|
const cb = callbacks.onGroupToggle;
|
|
4356
4354
|
const name = pill.groupName;
|
|
@@ -4373,7 +4371,7 @@ function renderControl(parent, ctrl, palette, _groupBg, pillBorder, _isDark, con
|
|
|
4373
4371
|
textX = 8 + 14 + LEGEND_ENTRY_DOT_GAP + measureLegendText(ctrl.label, LEGEND_PILL_FONT_SIZE) / 2;
|
|
4374
4372
|
}
|
|
4375
4373
|
if (ctrl.label) {
|
|
4376
|
-
g.append("text").attr("x", textX).attr("y", ctrl.height / 2).attr("text-anchor", "middle").
|
|
4374
|
+
g.append("text").attr("x", textX).attr("y", ctrl.height / 2).attr("text-anchor", "middle").call(centerText).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);
|
|
4377
4375
|
}
|
|
4378
4376
|
if (ctrl.children) {
|
|
4379
4377
|
let cx = ctrl.width + 4;
|
|
@@ -4383,7 +4381,7 @@ function renderControl(parent, ctrl, palette, _groupBg, pillBorder, _isDark, con
|
|
|
4383
4381
|
"fill",
|
|
4384
4382
|
child.isActive ? palette.primary ?? palette.text : "none"
|
|
4385
4383
|
).attr("stroke", pillBorder).attr("stroke-width", 0.75);
|
|
4386
|
-
childG.append("text").attr("x", child.width / 2).attr("y", ctrl.height / 2).attr("text-anchor", "middle").
|
|
4384
|
+
childG.append("text").attr("x", child.width / 2).attr("y", ctrl.height / 2).attr("text-anchor", "middle").call(centerText).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", child.isActive ? palette.bg : palette.textMuted).attr("font-family", FONT_FAMILY).text(child.label);
|
|
4387
4385
|
const configCtrl2 = configControls?.find((c) => c.id === ctrl.id);
|
|
4388
4386
|
const configChild = configCtrl2?.children?.find((c) => c.id === child.id);
|
|
4389
4387
|
if (configChild?.onClick) {
|
|
@@ -4437,7 +4435,7 @@ function renderControlsGroup(parent, layout, palette, groupBg, pillBorder, callb
|
|
|
4437
4435
|
} else {
|
|
4438
4436
|
entryG.append("circle").attr("cx", tl.dotCx).attr("cy", tl.dotCy).attr("r", LEGEND_TOGGLE_DOT_R).attr("fill", "none").attr("stroke", palette.textMuted).attr("stroke-width", 1);
|
|
4439
4437
|
}
|
|
4440
|
-
entryG.append("text").attr("x", tl.textX).attr("y", tl.textY).
|
|
4438
|
+
entryG.append("text").attr("x", tl.textX).attr("y", tl.textY).call(centerText).attr("font-size", LEGEND_ENTRY_FONT_SIZE).attr("fill", palette.textMuted).attr("opacity", tl.active ? 1 : LEGEND_TOGGLE_OFF_OPACITY).attr("font-family", FONT_FAMILY).text(tl.label);
|
|
4441
4439
|
if (callbacks?.onControlsToggle && toggle) {
|
|
4442
4440
|
const cb = callbacks.onControlsToggle;
|
|
4443
4441
|
const id = tl.id;
|
|
@@ -4450,6 +4448,7 @@ function renderControlsGroup(parent, layout, palette, groupBg, pillBorder, callb
|
|
|
4450
4448
|
}
|
|
4451
4449
|
}
|
|
4452
4450
|
}
|
|
4451
|
+
var LEGEND_TEXT_DY;
|
|
4453
4452
|
var init_legend_d3 = __esm({
|
|
4454
4453
|
"src/utils/legend-d3.ts"() {
|
|
4455
4454
|
"use strict";
|
|
@@ -4457,6 +4456,7 @@ var init_legend_d3 = __esm({
|
|
|
4457
4456
|
init_legend_layout();
|
|
4458
4457
|
init_color_utils();
|
|
4459
4458
|
init_fonts();
|
|
4459
|
+
LEGEND_TEXT_DY = "0.32em";
|
|
4460
4460
|
}
|
|
4461
4461
|
});
|
|
4462
4462
|
|
|
@@ -4642,7 +4642,6 @@ var init_name_normalize = __esm({
|
|
|
4642
4642
|
var parser_exports = {};
|
|
4643
4643
|
__export(parser_exports, {
|
|
4644
4644
|
isSequenceBlock: () => isSequenceBlock,
|
|
4645
|
-
isSequenceMessage: () => isSequenceMessage,
|
|
4646
4645
|
isSequenceNote: () => isSequenceNote,
|
|
4647
4646
|
isSequenceSection: () => isSequenceSection,
|
|
4648
4647
|
looksLikeSequence: () => looksLikeSequence,
|
|
@@ -4658,9 +4657,6 @@ function isHardRemovedToken(remainder) {
|
|
|
4658
4657
|
}
|
|
4659
4658
|
return { removed: false };
|
|
4660
4659
|
}
|
|
4661
|
-
function isSequenceMessage(el) {
|
|
4662
|
-
return el.kind === "message";
|
|
4663
|
-
}
|
|
4664
4660
|
function isSequenceBlock(el) {
|
|
4665
4661
|
return el.kind === "block";
|
|
4666
4662
|
}
|
|
@@ -26649,7 +26645,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26649
26645
|
const VALUE_NAME = hasRamp ? parsed.boxMetric?.trim() || "Value" : null;
|
|
26650
26646
|
const matchColorGroup = (v) => {
|
|
26651
26647
|
const lv = v.trim().toLowerCase();
|
|
26652
|
-
if (lv === "none") return null;
|
|
26648
|
+
if (lv === "" || lv === "none") return null;
|
|
26653
26649
|
const tg = parsed.tagGroups.find((g) => g.name.toLowerCase() === lv);
|
|
26654
26650
|
if (tg) return tg.name;
|
|
26655
26651
|
if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
|
|
@@ -26990,6 +26986,22 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
26990
26986
|
const tooltipText = fullText.length > 200 ? fullText.slice(0, 199) + "\u2026" : fullText;
|
|
26991
26987
|
nodeG.append("title").text(tooltipText);
|
|
26992
26988
|
}
|
|
26989
|
+
} else if (parsed.showValues && node.value !== void 0) {
|
|
26990
|
+
const valueLabel = parsed.boxMetric ? `${parsed.boxMetric}: ${node.value}` : String(node.value);
|
|
26991
|
+
const headerH = ln.height / 2;
|
|
26992
|
+
const sepY = -ln.height / 2 + headerH;
|
|
26993
|
+
const fitted = fitLabelToHeader(node.label, ln.width, 2);
|
|
26994
|
+
const labelLineH = fitted.fontSize * 1.3;
|
|
26995
|
+
const labelTotalH = fitted.lines.length * labelLineH;
|
|
26996
|
+
const headerCenterY = -ln.height / 2 + headerH / 2;
|
|
26997
|
+
for (let li = 0; li < fitted.lines.length; li++) {
|
|
26998
|
+
nodeG.append("text").attr("x", 0).attr(
|
|
26999
|
+
"y",
|
|
27000
|
+
headerCenterY - labelTotalH / 2 + labelLineH / 2 + li * labelLineH
|
|
27001
|
+
).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]);
|
|
27002
|
+
}
|
|
27003
|
+
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);
|
|
27004
|
+
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);
|
|
26993
27005
|
} else {
|
|
26994
27006
|
const maxLabelLines = Math.max(
|
|
26995
27007
|
2,
|
|
@@ -27002,21 +27014,16 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
|
|
|
27002
27014
|
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]);
|
|
27003
27015
|
}
|
|
27004
27016
|
}
|
|
27005
|
-
if (parsed.showValues && node.value !== void 0) {
|
|
27017
|
+
if (parsed.showValues && node.value !== void 0 && desc && desc.length > 0 && !hideDescriptions) {
|
|
27006
27018
|
const valueText = String(node.value);
|
|
27007
|
-
const
|
|
27008
|
-
|
|
27009
|
-
|
|
27010
|
-
|
|
27011
|
-
|
|
27012
|
-
|
|
27013
|
-
|
|
27014
|
-
|
|
27015
|
-
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);
|
|
27016
|
-
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);
|
|
27017
|
-
} else {
|
|
27018
|
-
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);
|
|
27019
|
-
}
|
|
27019
|
+
const padX = 6;
|
|
27020
|
+
const padY = 5;
|
|
27021
|
+
const bw = valueText.length * VALUE_FONT_SIZE * CHAR_WIDTH_RATIO2 + 8;
|
|
27022
|
+
const bh = VALUE_FONT_SIZE + 4;
|
|
27023
|
+
const bx = Math.max(-ln.width / 2 + 4, ln.width / 2 - bw - 4);
|
|
27024
|
+
const by = -ln.height / 2 + 4;
|
|
27025
|
+
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);
|
|
27026
|
+
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);
|
|
27020
27027
|
}
|
|
27021
27028
|
}
|
|
27022
27029
|
const hasDescriptions = parsed.nodes.some(
|
|
@@ -27110,7 +27117,7 @@ var init_renderer6 = __esm({
|
|
|
27110
27117
|
init_wrapped_desc();
|
|
27111
27118
|
init_scaling();
|
|
27112
27119
|
DIAGRAM_PADDING6 = 20;
|
|
27113
|
-
NODE_FONT_SIZE =
|
|
27120
|
+
NODE_FONT_SIZE = 11;
|
|
27114
27121
|
MIN_NODE_FONT_SIZE = 9;
|
|
27115
27122
|
EDGE_LABEL_FONT_SIZE4 = 11;
|
|
27116
27123
|
EDGE_STROKE_WIDTH5 = 1.5;
|
|
@@ -47070,7 +47077,11 @@ function resolveMap(parsed, data) {
|
|
|
47070
47077
|
if (bb && !isWholeSphere(bb)) containerBoxes.push(bb);
|
|
47071
47078
|
}
|
|
47072
47079
|
const containerUnion = unionExtent(containerBoxes, points);
|
|
47073
|
-
if (containerUnion)
|
|
47080
|
+
if (containerUnion)
|
|
47081
|
+
extent2 = pad(
|
|
47082
|
+
clampContainerToCluster(containerUnion, points),
|
|
47083
|
+
PAD_FRACTION
|
|
47084
|
+
);
|
|
47074
47085
|
}
|
|
47075
47086
|
if (isPoiOnly) {
|
|
47076
47087
|
const cx = (extent2[0][0] + extent2[1][0]) / 2;
|
|
@@ -47151,6 +47162,22 @@ function mostCommonCountry(regions, poiCountries) {
|
|
|
47151
47162
|
}
|
|
47152
47163
|
return best;
|
|
47153
47164
|
}
|
|
47165
|
+
function clampContainerToCluster(container, points) {
|
|
47166
|
+
const poi = unionExtent([], points);
|
|
47167
|
+
if (!poi) return container;
|
|
47168
|
+
let [[west, south], [east, north]] = container;
|
|
47169
|
+
const [[pWest, pSouth], [pEast, pNorth]] = poi;
|
|
47170
|
+
south = Math.max(south, pSouth - CONTAINER_OVERSHOOT_DEG);
|
|
47171
|
+
north = Math.min(north, pNorth + CONTAINER_OVERSHOOT_DEG);
|
|
47172
|
+
if (east <= 180 && pEast <= 180) {
|
|
47173
|
+
west = Math.max(west, pWest - CONTAINER_OVERSHOOT_DEG);
|
|
47174
|
+
east = Math.min(east, pEast + CONTAINER_OVERSHOOT_DEG);
|
|
47175
|
+
}
|
|
47176
|
+
return [
|
|
47177
|
+
[west, south],
|
|
47178
|
+
[east, north]
|
|
47179
|
+
];
|
|
47180
|
+
}
|
|
47154
47181
|
function pad(e, frac) {
|
|
47155
47182
|
const dLon = (e[1][0] - e[0][0]) * frac || 1;
|
|
47156
47183
|
const dLat = (e[1][1] - e[0][1]) * frac || 1;
|
|
@@ -47163,7 +47190,7 @@ function firstError(diags) {
|
|
|
47163
47190
|
const e = diags.find((d) => d.severity === "error");
|
|
47164
47191
|
return e ? formatDgmoError(e) : null;
|
|
47165
47192
|
}
|
|
47166
|
-
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;
|
|
47193
|
+
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;
|
|
47167
47194
|
var init_resolver2 = __esm({
|
|
47168
47195
|
"src/map/resolver.ts"() {
|
|
47169
47196
|
"use strict";
|
|
@@ -47176,6 +47203,7 @@ var init_resolver2 = __esm({
|
|
|
47176
47203
|
WORLD_LAT_SOUTH = -58;
|
|
47177
47204
|
WORLD_LAT_NORTH = 78;
|
|
47178
47205
|
POI_ZOOM_FLOOR_DEG = 7;
|
|
47206
|
+
CONTAINER_OVERSHOOT_DEG = 8;
|
|
47179
47207
|
US_NATIONAL_LON_SPAN = 48;
|
|
47180
47208
|
REGION_ALIASES = {
|
|
47181
47209
|
// Common everyday names → the Natural-Earth display name actually shipped.
|
|
@@ -47254,6 +47282,55 @@ var init_resolver2 = __esm({
|
|
|
47254
47282
|
}
|
|
47255
47283
|
});
|
|
47256
47284
|
|
|
47285
|
+
// src/map/legend-band.ts
|
|
47286
|
+
function mapLegendGroups(legend) {
|
|
47287
|
+
const ramp = legend.ramp;
|
|
47288
|
+
const scoreGroup = ramp ? {
|
|
47289
|
+
name: ramp.metric?.trim() || "Value",
|
|
47290
|
+
entries: [],
|
|
47291
|
+
gradient: {
|
|
47292
|
+
min: ramp.min,
|
|
47293
|
+
max: ramp.max,
|
|
47294
|
+
hue: ramp.hue,
|
|
47295
|
+
base: ramp.base
|
|
47296
|
+
}
|
|
47297
|
+
} : null;
|
|
47298
|
+
const tagGroups = legend.tagGroups.filter((g) => g.entries.length > 0).map((g) => ({ name: g.name, entries: [...g.entries] }));
|
|
47299
|
+
return [...scoreGroup ? [scoreGroup] : [], ...tagGroups];
|
|
47300
|
+
}
|
|
47301
|
+
function mapLegendConfig(groups, mode) {
|
|
47302
|
+
return {
|
|
47303
|
+
groups,
|
|
47304
|
+
position: { placement: "top-center", titleRelation: "below-title" },
|
|
47305
|
+
mode,
|
|
47306
|
+
showEmptyGroups: false,
|
|
47307
|
+
showInactivePills: true
|
|
47308
|
+
};
|
|
47309
|
+
}
|
|
47310
|
+
function mapLegendTop(hasTitle, hasSubtitle) {
|
|
47311
|
+
return (hasTitle ? TITLE_Y + TITLE_FONT_SIZE : 0) + (hasSubtitle ? TITLE_FONT_SIZE : 0) + LEGEND_TOP_GAP2;
|
|
47312
|
+
}
|
|
47313
|
+
function mapLegendBand(legend, opts) {
|
|
47314
|
+
if (!legend) return 0;
|
|
47315
|
+
const groups = mapLegendGroups(legend);
|
|
47316
|
+
if (groups.length === 0) return 0;
|
|
47317
|
+
const config = mapLegendConfig(groups, opts.mode);
|
|
47318
|
+
const state = { activeGroup: legend.activeGroup };
|
|
47319
|
+
const { height } = computeLegendLayout(config, state, opts.width);
|
|
47320
|
+
if (height <= 0) return 0;
|
|
47321
|
+
return mapLegendTop(opts.hasTitle, opts.hasSubtitle) + height + LEGEND_BOTTOM_GAP2;
|
|
47322
|
+
}
|
|
47323
|
+
var LEGEND_TOP_GAP2, LEGEND_BOTTOM_GAP2;
|
|
47324
|
+
var init_legend_band = __esm({
|
|
47325
|
+
"src/map/legend-band.ts"() {
|
|
47326
|
+
"use strict";
|
|
47327
|
+
init_legend_layout();
|
|
47328
|
+
init_title_constants();
|
|
47329
|
+
LEGEND_TOP_GAP2 = 8;
|
|
47330
|
+
LEGEND_BOTTOM_GAP2 = 10;
|
|
47331
|
+
}
|
|
47332
|
+
});
|
|
47333
|
+
|
|
47257
47334
|
// src/map/colorize.ts
|
|
47258
47335
|
function assignColors(isos, adjacency) {
|
|
47259
47336
|
const sorted = [...isos].sort();
|
|
@@ -47845,12 +47922,43 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47845
47922
|
return tagFill(r.tags, activeGroup) ?? neutralFill;
|
|
47846
47923
|
};
|
|
47847
47924
|
const regionById = new Map(resolved.regions.map((r) => [r.iso, r]));
|
|
47925
|
+
let legend = null;
|
|
47926
|
+
if (!resolved.directives.noLegend) {
|
|
47927
|
+
const legendTagGroups = resolved.tagGroups.map((g) => ({
|
|
47928
|
+
name: g.name,
|
|
47929
|
+
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
47930
|
+
}));
|
|
47931
|
+
if (legendTagGroups.length > 0 || hasRamp) {
|
|
47932
|
+
legend = {
|
|
47933
|
+
tagGroups: legendTagGroups,
|
|
47934
|
+
activeGroup,
|
|
47935
|
+
...hasRamp && {
|
|
47936
|
+
ramp: {
|
|
47937
|
+
...resolved.directives.regionMetric !== void 0 && {
|
|
47938
|
+
metric: resolved.directives.regionMetric
|
|
47939
|
+
},
|
|
47940
|
+
min: rampMin,
|
|
47941
|
+
max: rampMax,
|
|
47942
|
+
hue: rampHue,
|
|
47943
|
+
base: rampBase
|
|
47944
|
+
}
|
|
47945
|
+
}
|
|
47946
|
+
};
|
|
47947
|
+
}
|
|
47948
|
+
}
|
|
47848
47949
|
const TITLE_GAP2 = 16;
|
|
47849
47950
|
let topPad = FIT_PAD;
|
|
47850
47951
|
if (resolved.title && resolved.pois.length > 0) {
|
|
47851
47952
|
const bannerBottom = (resolved.subtitle ? TITLE_Y + TITLE_FONT_SIZE : TITLE_Y) + TITLE_FONT_SIZE / 2;
|
|
47852
47953
|
topPad = Math.max(FIT_PAD, bannerBottom + TITLE_GAP2);
|
|
47853
47954
|
}
|
|
47955
|
+
const legendBand = mapLegendBand(legend, {
|
|
47956
|
+
width,
|
|
47957
|
+
mode: opts.legendMode ?? "preview",
|
|
47958
|
+
hasTitle: Boolean(resolved.title),
|
|
47959
|
+
hasSubtitle: Boolean(resolved.subtitle)
|
|
47960
|
+
});
|
|
47961
|
+
if (legendBand > topPad) topPad = legendBand;
|
|
47854
47962
|
const fitBox = [
|
|
47855
47963
|
[FIT_PAD, topPad],
|
|
47856
47964
|
[
|
|
@@ -47868,7 +47976,7 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
47868
47976
|
const by0 = cb[0][1];
|
|
47869
47977
|
const cw = cb[1][0] - bx0;
|
|
47870
47978
|
const ch = cb[1][1] - by0;
|
|
47871
|
-
const topReserve = resolved.title && resolved.pois.length > 0 ? topPad : 0;
|
|
47979
|
+
const topReserve = resolved.title && resolved.pois.length > 0 || legendBand > 0 ? topPad : 0;
|
|
47872
47980
|
const ox = 0;
|
|
47873
47981
|
const oy = topReserve;
|
|
47874
47982
|
const sx = cw > 0 ? width / cw : 1;
|
|
@@ -48932,30 +49040,6 @@ function layoutMap(resolved, data, size, opts) {
|
|
|
48932
49040
|
});
|
|
48933
49041
|
labels.push(...contextLabels);
|
|
48934
49042
|
}
|
|
48935
|
-
let legend = null;
|
|
48936
|
-
if (!resolved.directives.noLegend) {
|
|
48937
|
-
const tagGroups = resolved.tagGroups.map((g) => ({
|
|
48938
|
-
name: g.name,
|
|
48939
|
-
entries: g.entries.map((e) => ({ value: e.value, color: e.color }))
|
|
48940
|
-
}));
|
|
48941
|
-
if (tagGroups.length > 0 || hasRamp) {
|
|
48942
|
-
legend = {
|
|
48943
|
-
tagGroups,
|
|
48944
|
-
activeGroup,
|
|
48945
|
-
...hasRamp && {
|
|
48946
|
-
ramp: {
|
|
48947
|
-
...resolved.directives.regionMetric !== void 0 && {
|
|
48948
|
-
metric: resolved.directives.regionMetric
|
|
48949
|
-
},
|
|
48950
|
-
min: rampMin,
|
|
48951
|
-
max: rampMax,
|
|
48952
|
-
hue: rampHue,
|
|
48953
|
-
base: rampBase
|
|
48954
|
-
}
|
|
48955
|
-
}
|
|
48956
|
-
};
|
|
48957
|
-
}
|
|
48958
|
-
}
|
|
48959
49043
|
return {
|
|
48960
49044
|
width,
|
|
48961
49045
|
height,
|
|
@@ -48991,6 +49075,7 @@ var init_layout15 = __esm({
|
|
|
48991
49075
|
init_label_layout();
|
|
48992
49076
|
init_legend_constants();
|
|
48993
49077
|
init_title_constants();
|
|
49078
|
+
init_legend_band();
|
|
48994
49079
|
init_context_labels();
|
|
48995
49080
|
FIT_PAD = 24;
|
|
48996
49081
|
RAMP_FLOOR2 = 15;
|
|
@@ -49191,6 +49276,9 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
49191
49276
|
// stretch-distorting. The in-app preview pane passes no exportDims → unset →
|
|
49192
49277
|
// keeps the global stretch-fill.
|
|
49193
49278
|
preferContain: exportDims?.preferContain ?? false,
|
|
49279
|
+
// Reserve the legend band for the mode actually drawn below (export shows
|
|
49280
|
+
// only the active group; preview keeps the inactive pills).
|
|
49281
|
+
legendMode: exportDims ? "export" : "preview",
|
|
49194
49282
|
...activeGroupOverride !== void 0 && {
|
|
49195
49283
|
activeGroup: activeGroupOverride
|
|
49196
49284
|
}
|
|
@@ -49482,30 +49570,12 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
|
|
|
49482
49570
|
if (layout.legend) {
|
|
49483
49571
|
const legendY = (layout.title ? TITLE_Y + TITLE_FONT_SIZE : 0) + (layout.subtitle ? TITLE_FONT_SIZE : 0) + 8;
|
|
49484
49572
|
const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
|
|
49485
|
-
const
|
|
49486
|
-
const scoreGroup = ramp ? {
|
|
49487
|
-
name: ramp.metric?.trim() || "Value",
|
|
49488
|
-
entries: [],
|
|
49489
|
-
gradient: {
|
|
49490
|
-
min: ramp.min,
|
|
49491
|
-
max: ramp.max,
|
|
49492
|
-
hue: ramp.hue,
|
|
49493
|
-
base: ramp.base
|
|
49494
|
-
}
|
|
49495
|
-
} : null;
|
|
49496
|
-
const tagGroups = layout.legend.tagGroups.filter((g) => g.entries.length > 0).map((g) => ({ name: g.name, entries: [...g.entries] }));
|
|
49497
|
-
const groups = [...scoreGroup ? [scoreGroup] : [], ...tagGroups];
|
|
49573
|
+
const groups = mapLegendGroups(layout.legend);
|
|
49498
49574
|
if (groups.length > 0) {
|
|
49499
|
-
const config =
|
|
49575
|
+
const config = mapLegendConfig(
|
|
49500
49576
|
groups,
|
|
49501
|
-
|
|
49502
|
-
|
|
49503
|
-
showEmptyGroups: false,
|
|
49504
|
-
// Keep inactive siblings visible as pills so the user can click to flip
|
|
49505
|
-
// the active colouring dimension (preview only — export shows just the
|
|
49506
|
-
// active group).
|
|
49507
|
-
showInactivePills: true
|
|
49508
|
-
};
|
|
49577
|
+
exportDims ? "export" : "preview"
|
|
49578
|
+
);
|
|
49509
49579
|
const state = { activeGroup: layout.legend.activeGroup };
|
|
49510
49580
|
renderLegendD3(legendG, config, state, palette, isDark, void 0, width);
|
|
49511
49581
|
}
|
|
@@ -49549,6 +49619,7 @@ var init_renderer16 = __esm({
|
|
|
49549
49619
|
init_title_constants();
|
|
49550
49620
|
init_color_utils();
|
|
49551
49621
|
init_legend_d3();
|
|
49622
|
+
init_legend_band();
|
|
49552
49623
|
init_layout15();
|
|
49553
49624
|
LABEL_FONT = 11;
|
|
49554
49625
|
}
|
|
@@ -49570,9 +49641,10 @@ function mapContentAspect(resolved, data, ref = REF) {
|
|
|
49570
49641
|
const aspect = w / h;
|
|
49571
49642
|
return Number.isFinite(aspect) && aspect > 0 ? aspect : FALLBACK_ASPECT;
|
|
49572
49643
|
}
|
|
49573
|
-
function mapExportDimensions(resolved, data, baseWidth = 1200) {
|
|
49574
|
-
const
|
|
49575
|
-
const
|
|
49644
|
+
function mapExportDimensions(resolved, data, baseWidth = 1200, aspectOverride) {
|
|
49645
|
+
const useOverride = aspectOverride !== void 0 && Number.isFinite(aspectOverride) && aspectOverride > 0;
|
|
49646
|
+
const raw = useOverride ? aspectOverride : mapContentAspect(resolved, data);
|
|
49647
|
+
const clamped = useOverride ? raw : Math.max(ASPECT_MIN, Math.min(ASPECT_MAX, raw));
|
|
49576
49648
|
const width = baseWidth;
|
|
49577
49649
|
let height = Math.round(width / clamped);
|
|
49578
49650
|
let chromeReserve = 0;
|
|
@@ -49585,7 +49657,7 @@ function mapExportDimensions(resolved, data, baseWidth = 1200) {
|
|
|
49585
49657
|
height = Math.round(chromeReserve + MIN_MAP_BAND);
|
|
49586
49658
|
floored = true;
|
|
49587
49659
|
}
|
|
49588
|
-
const preferContain = clamped !== raw || floored;
|
|
49660
|
+
const preferContain = useOverride ? floored : clamped !== raw || floored;
|
|
49589
49661
|
return { width, height, preferContain };
|
|
49590
49662
|
}
|
|
49591
49663
|
var FIT_PAD2, TITLE_GAP, ASPECT_MAX, ASPECT_MIN, MIN_MAP_BAND, FALLBACK_ASPECT, REF;
|
|
@@ -55295,7 +55367,6 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
|
|
|
55295
55367
|
function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, setup, hovers, onClickItem, _exportDims, _swimlaneTagGroup, _activeTagGroup, _onTagStateChange, _viewMode) {
|
|
55296
55368
|
const {
|
|
55297
55369
|
width,
|
|
55298
|
-
height,
|
|
55299
55370
|
tooltip,
|
|
55300
55371
|
solid,
|
|
55301
55372
|
textColor,
|
|
@@ -55344,8 +55415,7 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
|
|
|
55344
55415
|
const markerLabelY = markerReserve ? -(topScaleH + MARKER_ROW_H / 2) : 0;
|
|
55345
55416
|
const eraLabelY = eraReserve ? -(topScaleH + markerReserve + ERA_ROW_H / 2) : 0;
|
|
55346
55417
|
const innerWidth = width - margin.left - margin.right;
|
|
55347
|
-
const
|
|
55348
|
-
const rowH = Math.min(ctx.structural(28), availInnerHeight / sorted.length);
|
|
55418
|
+
const rowH = ctx.structural(28);
|
|
55349
55419
|
const innerHeight = rowH * sorted.length;
|
|
55350
55420
|
const usedHeight = margin.top + innerHeight + margin.bottom;
|
|
55351
55421
|
const xScale = d3Scale2.scaleLinear().domain([minDate - datePadding, maxDate + datePadding]).range([0, innerWidth]);
|
|
@@ -57926,7 +57996,12 @@ async function renderForExport(content, theme, palette, viewState, options) {
|
|
|
57926
57996
|
}
|
|
57927
57997
|
}
|
|
57928
57998
|
const mapResolved = resolveMap2(mapParsed, mapData);
|
|
57929
|
-
const dims2 = mapExportDimensions2(
|
|
57999
|
+
const dims2 = mapExportDimensions2(
|
|
58000
|
+
mapResolved,
|
|
58001
|
+
mapData,
|
|
58002
|
+
EXPORT_WIDTH,
|
|
58003
|
+
options?.mapAspect
|
|
58004
|
+
);
|
|
57930
58005
|
const container2 = createExportContainer(dims2.width, dims2.height);
|
|
57931
58006
|
renderMapForExport2(
|
|
57932
58007
|
container2,
|
|
@@ -2786,7 +2786,8 @@ route Miami style: arc
|
|
|
2786
2786
|
- Title is the declaration line; `caption` (data-source attribution, travels with the exported PNG) is the only chrome directive. There is no `subtitle`.
|
|
2787
2787
|
- Legend auto-composes below the title: the value ramp + `region-metric` and each tag group are **selectable colouring groups** (collapse/activate to flip the fill); POI size (`poi-metric`) and edge thickness (`flow-metric`) are self-evident from scale and carry no legend key in v1. `no-legend` suppresses all of it.
|
|
2788
2788
|
- **Region and POI labels are on by default.** Region labels auto-fit **full → abbrev → hide** (a US-state 2-letter abbreviation is tried when the full name doesn't fit; other regions degrade full → hide); POI labels are collision-managed. Labels render **on the map** (export-safe), escalating inline → leader line → numbered pin in dense clusters; markers never move. A wide map in a narrow column (< ~480px) prefers abbreviations and drops reference relief, as if zoomed out.
|
|
2789
|
-
- **Cosmetic features are on by default**; the only switches are bare `no-*` opt-outs (no positive opt-in flag): `no-coastline`, `no-relief`, `no-context-labels`, `no-region-labels`, `no-poi-labels`, `no-legend`. A plain look = the four basemap flags together.
|
|
2789
|
+
- **Cosmetic features are on by default**; the only switches are bare `no-*` opt-outs (no positive opt-in flag): `no-coastline`, `no-relief`, `no-context-labels`, `no-region-labels`, `no-poi-labels`, `no-legend`, `no-colorize`. A plain look = the four basemap flags together (`no-colorize` is **not** one of the four — it toggles region *fill style*, not a basemap backdrop layer).
|
|
2790
|
+
- **Colorize (distinct political fills) is the default for any map without region data.** Unless a region carries data (a `value:` or a tag), every region drawn at the resolved extent is filled a **distinct light pastel** such that no two bordering regions share a hue — the conventional "colour the countries/states so neighbours separate" look, with zero config. It applies to named-region maps, POI/route-only maps, and even a bare `map` (the whole world colours as the backdrop). The fills are **non-semantic** (no legend entry) and **extent-independent** (a region's colour is the same at any width and in an inset). A direct trailing colour (`Texas red`) paints on top as a highlight and does not suppress colorize; adding any `value:`/tag flips the map to the data dress (colorize auto-suppressed, no error). `no-colorize` forces the plain green-land + blue-water dress — useful when many POIs/routes should pop against a calm map.
|
|
2790
2791
|
|
|
2791
2792
|
### Name resolution
|
|
2792
2793
|
|
|
@@ -2802,7 +2803,7 @@ route Miami style: arc
|
|
|
2802
2803
|
|
|
2803
2804
|
### Directives & reserved keys
|
|
2804
2805
|
|
|
2805
|
-
The directive set is **
|
|
2806
|
+
The directive set is **13, all colon-free**: six naming intent the renderer can't infer — `region-metric`, `poi-metric`, `flow-metric`, `locale`, `active-tag`, `caption` — and seven `no-*` cosmetic opt-outs — `no-legend`, `no-coastline`, `no-relief`, `no-context-labels`, `no-region-labels`, `no-poi-labels`, `no-colorize`. There is **no** `projection`, `scale`, `subtitle`, `surface`, `region`, or label-enum directive, and cosmetics have no positive opt-in form. Reserved metadata keys (need colons): `value`, `label`, `style` (`value` = the one numeric channel: region shade / POI size / edge thickness); `surface:` is no longer recognized. A bare US state postal code resolves to that state (`poi Portland OR` → Oregon; `CA` = California). Coordinates are positional (no `at:` key). Projection is inferred from extent + whether the map carries data (US → albers-usa; world data → Equal Earth; world reference → natural-earth; regional → mercator) and cannot be overridden.
|
|
2806
2807
|
|
|
2807
2808
|
---
|
|
2808
2809
|
|