@opendata-ai/openchart-vanilla 6.25.4 → 6.26.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/index.d.ts +54 -2
- package/dist/index.js +644 -29
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -3
- package/src/__tests__/compound-labels.test.ts +122 -0
- package/src/__tests__/crosshair.test.ts +121 -0
- package/src/__tests__/tilemap.test.ts +158 -0
- package/src/graph-mount.ts +1 -1
- package/src/index.ts +3 -0
- package/src/mount.ts +22 -2
- package/src/renderers/axes.ts +81 -20
- package/src/renderers/legend.ts +6 -2
- package/src/sankey-renderer.ts +4 -2
- package/src/svg-renderer.ts +21 -1
- package/src/tilemap-mount.ts +394 -0
- package/src/tilemap-renderer.ts +425 -0
package/dist/index.js
CHANGED
|
@@ -2805,7 +2805,7 @@ function createGraph(container, spec, options) {
|
|
|
2805
2805
|
}
|
|
2806
2806
|
chromeEl = document.createElement("div");
|
|
2807
2807
|
chromeEl.className = "oc-graph-chrome";
|
|
2808
|
-
|
|
2808
|
+
renderChrome4();
|
|
2809
2809
|
wrapper.appendChild(chromeEl);
|
|
2810
2810
|
canvas = document.createElement("canvas");
|
|
2811
2811
|
canvas.className = "oc-graph-canvas";
|
|
@@ -2825,7 +2825,7 @@ function createGraph(container, spec, options) {
|
|
|
2825
2825
|
renderer = new GraphCanvasRenderer(canvas);
|
|
2826
2826
|
renderer.resize(width, canvasHeight);
|
|
2827
2827
|
}
|
|
2828
|
-
function
|
|
2828
|
+
function renderChrome4() {
|
|
2829
2829
|
if (!chromeEl) return;
|
|
2830
2830
|
let html = "";
|
|
2831
2831
|
if (compilation.chrome.title) {
|
|
@@ -2843,7 +2843,7 @@ function createGraph(container, spec, options) {
|
|
|
2843
2843
|
}
|
|
2844
2844
|
function renderLegend3() {
|
|
2845
2845
|
if (!legendEl) return;
|
|
2846
|
-
const entries = compilation.legend.entries;
|
|
2846
|
+
const entries = "entries" in compilation.legend ? compilation.legend.entries : [];
|
|
2847
2847
|
if (entries.length === 0) {
|
|
2848
2848
|
legendEl.style.display = "none";
|
|
2849
2849
|
return;
|
|
@@ -3139,7 +3139,7 @@ function createGraph(container, spec, options) {
|
|
|
3139
3139
|
compilation = compile();
|
|
3140
3140
|
adjacencyMap = buildAdjacencyMap(compilation.edges);
|
|
3141
3141
|
buildDataMaps();
|
|
3142
|
-
|
|
3142
|
+
renderChrome4();
|
|
3143
3143
|
renderLegend3();
|
|
3144
3144
|
initSimulation();
|
|
3145
3145
|
initInteraction();
|
|
@@ -3174,7 +3174,7 @@ function createGraph(container, spec, options) {
|
|
|
3174
3174
|
};
|
|
3175
3175
|
});
|
|
3176
3176
|
spatialIndex.rebuild(positionedNodes);
|
|
3177
|
-
|
|
3177
|
+
renderChrome4();
|
|
3178
3178
|
renderLegend3();
|
|
3179
3179
|
needsRender = true;
|
|
3180
3180
|
scheduleRender();
|
|
@@ -3637,6 +3637,18 @@ import {
|
|
|
3637
3637
|
getAxisTitleOffset,
|
|
3638
3638
|
TICK_LABEL_OFFSET
|
|
3639
3639
|
} from "@opendata-ai/openchart-core";
|
|
3640
|
+
function appendCompoundLabel(parent, primaryText, subtitle, fontWeight) {
|
|
3641
|
+
const primarySpan = createSVGElement("tspan");
|
|
3642
|
+
primarySpan.setAttribute("font-weight", String(fontWeight));
|
|
3643
|
+
primarySpan.textContent = primaryText;
|
|
3644
|
+
parent.appendChild(primarySpan);
|
|
3645
|
+
const subtitleSpan = createSVGElement("tspan");
|
|
3646
|
+
subtitleSpan.setAttribute("dx", "0.5em");
|
|
3647
|
+
subtitleSpan.textContent = subtitle;
|
|
3648
|
+
subtitleSpan.setAttribute("font-weight", "400");
|
|
3649
|
+
subtitleSpan.setAttribute("fill-opacity", "0.6");
|
|
3650
|
+
parent.appendChild(subtitleSpan);
|
|
3651
|
+
}
|
|
3640
3652
|
function renderAxis(parent, axis, orientation, layout) {
|
|
3641
3653
|
const g = createSVGElement("g");
|
|
3642
3654
|
const isRight = orientation === "y" && axis.orient === "right";
|
|
@@ -3693,27 +3705,62 @@ function renderAxis(parent, axis, orientation, layout) {
|
|
|
3693
3705
|
const availableWidth = area.x - TICK_LABEL_OFFSET;
|
|
3694
3706
|
const fontSize = axis.tickLabelStyle.fontSize;
|
|
3695
3707
|
const fontWeight = axis.tickLabelStyle.fontWeight;
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
const
|
|
3699
|
-
const
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
const
|
|
3704
|
-
const
|
|
3705
|
-
|
|
3706
|
-
|
|
3708
|
+
if (tick.subtitle) {
|
|
3709
|
+
const gapWidth = fontSize * 0.5;
|
|
3710
|
+
const subtitleWidth = estimateTextWidth2(tick.subtitle, fontSize, fontWeight);
|
|
3711
|
+
const primaryWidth = estimateTextWidth2(tick.label, fontSize, fontWeight);
|
|
3712
|
+
const totalWidth = primaryWidth + gapWidth + subtitleWidth;
|
|
3713
|
+
if (totalWidth > availableWidth && availableWidth > 20) {
|
|
3714
|
+
const ellipsis = "\u2026";
|
|
3715
|
+
const ellipsisWidth = estimateTextWidth2(ellipsis, fontSize, fontWeight);
|
|
3716
|
+
const budgetForPrimary = availableWidth - gapWidth - subtitleWidth - ellipsisWidth;
|
|
3717
|
+
let primaryText = tick.label;
|
|
3718
|
+
if (budgetForPrimary > 0) {
|
|
3719
|
+
let lo = 0;
|
|
3720
|
+
let hi = tick.label.length;
|
|
3721
|
+
while (lo < hi) {
|
|
3722
|
+
const mid = lo + hi + 1 >>> 1;
|
|
3723
|
+
const candidate = tick.label.slice(0, mid);
|
|
3724
|
+
if (estimateTextWidth2(candidate, fontSize, fontWeight) <= budgetForPrimary) {
|
|
3725
|
+
lo = mid;
|
|
3726
|
+
} else {
|
|
3727
|
+
hi = mid - 1;
|
|
3728
|
+
}
|
|
3729
|
+
}
|
|
3730
|
+
primaryText = lo > 0 ? tick.label.slice(0, lo).trimEnd() + ellipsis : ellipsis;
|
|
3707
3731
|
} else {
|
|
3708
|
-
|
|
3732
|
+
primaryText = ellipsis;
|
|
3709
3733
|
}
|
|
3734
|
+
appendCompoundLabel(label, primaryText, tick.subtitle, fontWeight);
|
|
3735
|
+
const titleEl = createSVGElement("title");
|
|
3736
|
+
titleEl.textContent = `${tick.label} ${tick.subtitle}`;
|
|
3737
|
+
label.appendChild(titleEl);
|
|
3738
|
+
} else {
|
|
3739
|
+
appendCompoundLabel(label, tick.label, tick.subtitle, fontWeight);
|
|
3710
3740
|
}
|
|
3711
|
-
label.textContent = lo > 0 ? tick.label.slice(0, lo).trimEnd() + ellipsis : ellipsis;
|
|
3712
|
-
const titleEl = createSVGElement("title");
|
|
3713
|
-
titleEl.textContent = tick.label;
|
|
3714
|
-
label.appendChild(titleEl);
|
|
3715
3741
|
} else {
|
|
3716
|
-
|
|
3742
|
+
const fullWidth = estimateTextWidth2(tick.label, fontSize, fontWeight);
|
|
3743
|
+
if (fullWidth > availableWidth && availableWidth > 20) {
|
|
3744
|
+
const ellipsis = "\u2026";
|
|
3745
|
+
const ellipsisWidth = estimateTextWidth2(ellipsis, fontSize, fontWeight);
|
|
3746
|
+
let lo = 0;
|
|
3747
|
+
let hi = tick.label.length;
|
|
3748
|
+
while (lo < hi) {
|
|
3749
|
+
const mid = lo + hi + 1 >>> 1;
|
|
3750
|
+
const candidate = tick.label.slice(0, mid);
|
|
3751
|
+
if (estimateTextWidth2(candidate, fontSize, fontWeight) + ellipsisWidth <= availableWidth) {
|
|
3752
|
+
lo = mid;
|
|
3753
|
+
} else {
|
|
3754
|
+
hi = mid - 1;
|
|
3755
|
+
}
|
|
3756
|
+
}
|
|
3757
|
+
label.textContent = lo > 0 ? tick.label.slice(0, lo).trimEnd() + ellipsis : ellipsis;
|
|
3758
|
+
const titleEl = createSVGElement("title");
|
|
3759
|
+
titleEl.textContent = tick.label;
|
|
3760
|
+
label.appendChild(titleEl);
|
|
3761
|
+
} else {
|
|
3762
|
+
label.textContent = tick.label;
|
|
3763
|
+
}
|
|
3717
3764
|
}
|
|
3718
3765
|
} else {
|
|
3719
3766
|
label.textContent = tick.label;
|
|
@@ -3930,8 +3977,11 @@ function renderChrome(parent, layout) {
|
|
|
3930
3977
|
|
|
3931
3978
|
// src/renderers/legend.ts
|
|
3932
3979
|
import { estimateTextWidth as estimateTextWidth3 } from "@opendata-ai/openchart-core";
|
|
3980
|
+
function isCategorical(legend) {
|
|
3981
|
+
return !legend.type || legend.type === "categorical";
|
|
3982
|
+
}
|
|
3933
3983
|
function renderLegend(parent, legend) {
|
|
3934
|
-
if (legend.entries.length === 0) return;
|
|
3984
|
+
if (!isCategorical(legend) || legend.entries.length === 0) return;
|
|
3935
3985
|
const g = createSVGElement("g");
|
|
3936
3986
|
g.setAttribute("class", "oc-legend");
|
|
3937
3987
|
g.setAttribute("role", "list");
|
|
@@ -4434,6 +4484,24 @@ function renderChartSVG(layout, container, opts) {
|
|
|
4434
4484
|
overlay.setAttribute("class", "oc-voronoi-overlay");
|
|
4435
4485
|
overlay.setAttribute("data-voronoi-overlay", "true");
|
|
4436
4486
|
clippedGroup.appendChild(overlay);
|
|
4487
|
+
if (opts?.crosshair) {
|
|
4488
|
+
const crosshairLine = createSVGElement("line");
|
|
4489
|
+
crosshairLine.setAttribute("data-crosshair", "true");
|
|
4490
|
+
crosshairLine.setAttribute("class", "oc-crosshair");
|
|
4491
|
+
setAttrs(crosshairLine, {
|
|
4492
|
+
x1: 0,
|
|
4493
|
+
y1: layout.area.y,
|
|
4494
|
+
x2: 0,
|
|
4495
|
+
y2: layout.area.y + layout.area.height,
|
|
4496
|
+
stroke: layout.theme.colors.gridline,
|
|
4497
|
+
"stroke-opacity": "0.5",
|
|
4498
|
+
"stroke-dasharray": "4,3",
|
|
4499
|
+
"stroke-width": "1",
|
|
4500
|
+
"pointer-events": "none"
|
|
4501
|
+
});
|
|
4502
|
+
crosshairLine.style.display = "none";
|
|
4503
|
+
clippedGroup.appendChild(crosshairLine);
|
|
4504
|
+
}
|
|
4437
4505
|
}
|
|
4438
4506
|
svg.appendChild(clippedGroup);
|
|
4439
4507
|
renderAnnotations(svg, layout);
|
|
@@ -4695,6 +4763,7 @@ function wireVoronoiTooltipEvents(svg, layout, tooltipManager) {
|
|
|
4695
4763
|
const voronoiPoints = collectVoronoiPoints(layout);
|
|
4696
4764
|
if (voronoiPoints.length === 0) return () => {
|
|
4697
4765
|
};
|
|
4766
|
+
const crosshair = svg.querySelector("[data-crosshair]");
|
|
4698
4767
|
const cleanups = [];
|
|
4699
4768
|
const handleMouseMove = (e) => {
|
|
4700
4769
|
const mouseEvent = e;
|
|
@@ -4707,11 +4776,17 @@ function wireVoronoiTooltipEvents(svg, layout, tooltipManager) {
|
|
|
4707
4776
|
const svgY = (mouseEvent.clientY - svgRect.top) * scaleY;
|
|
4708
4777
|
const nearest = findNearestPoint(voronoiPoints, svgX, svgY);
|
|
4709
4778
|
if (!nearest?.tooltip) return;
|
|
4779
|
+
if (crosshair) {
|
|
4780
|
+
crosshair.setAttribute("x1", String(nearest.x));
|
|
4781
|
+
crosshair.setAttribute("x2", String(nearest.x));
|
|
4782
|
+
crosshair.style.display = "";
|
|
4783
|
+
}
|
|
4710
4784
|
const containerX = mouseEvent.clientX - svgRect.left;
|
|
4711
4785
|
const containerY = mouseEvent.clientY - svgRect.top;
|
|
4712
4786
|
tooltipManager.show(nearest.tooltip, containerX, containerY);
|
|
4713
4787
|
};
|
|
4714
4788
|
const handleMouseLeave = () => {
|
|
4789
|
+
if (crosshair) crosshair.style.display = "none";
|
|
4715
4790
|
tooltipManager.hide();
|
|
4716
4791
|
};
|
|
4717
4792
|
const handleTouchStart = (e) => {
|
|
@@ -4727,6 +4802,11 @@ function wireVoronoiTooltipEvents(svg, layout, tooltipManager) {
|
|
|
4727
4802
|
const svgY = (touch.clientY - svgRect.top) * scaleY;
|
|
4728
4803
|
const nearest = findNearestPoint(voronoiPoints, svgX, svgY);
|
|
4729
4804
|
if (!nearest?.tooltip) return;
|
|
4805
|
+
if (crosshair) {
|
|
4806
|
+
crosshair.setAttribute("x1", String(nearest.x));
|
|
4807
|
+
crosshair.setAttribute("x2", String(nearest.x));
|
|
4808
|
+
crosshair.style.display = "";
|
|
4809
|
+
}
|
|
4730
4810
|
const containerX = touch.clientX - svgRect.left;
|
|
4731
4811
|
const containerY = touch.clientY - svgRect.top;
|
|
4732
4812
|
tooltipManager.show(nearest.tooltip, containerX, containerY);
|
|
@@ -5058,7 +5138,7 @@ function wireAnnotationDrag(svg, specAnnotations, onAnnotationEdit, onEdit, setD
|
|
|
5058
5138
|
};
|
|
5059
5139
|
}
|
|
5060
5140
|
function wireConnectorEndpointDrag(svg, specAnnotations, onEdit, setDragging) {
|
|
5061
|
-
const
|
|
5141
|
+
const SVG_NS5 = "http://www.w3.org/2000/svg";
|
|
5062
5142
|
const cleanups = [];
|
|
5063
5143
|
const annotationGroups = svg.querySelectorAll(".oc-annotation-text");
|
|
5064
5144
|
for (const el of annotationGroups) {
|
|
@@ -5097,7 +5177,7 @@ function wireConnectorEndpointDrag(svg, specAnnotations, onEdit, setDragging) {
|
|
|
5097
5177
|
const createdHandles = [];
|
|
5098
5178
|
for (const ep of endpoints) {
|
|
5099
5179
|
if (!Number.isFinite(ep.cx) || !Number.isFinite(ep.cy)) continue;
|
|
5100
|
-
const handleEl = document.createElementNS(
|
|
5180
|
+
const handleEl = document.createElementNS(SVG_NS5, "circle");
|
|
5101
5181
|
handleEl.setAttribute("class", "oc-connector-handle");
|
|
5102
5182
|
handleEl.setAttribute("data-endpoint", ep.name);
|
|
5103
5183
|
handleEl.setAttribute("cx", String(ep.cx));
|
|
@@ -5612,7 +5692,7 @@ function getEditableElements(spec, layout) {
|
|
|
5612
5692
|
for (const series of seriesLabels) {
|
|
5613
5693
|
refs.push(elementRef.seriesLabel(series));
|
|
5614
5694
|
}
|
|
5615
|
-
if (layout.legend.entries.length > 0) {
|
|
5695
|
+
if ("entries" in layout.legend && layout.legend.entries.length > 0) {
|
|
5616
5696
|
refs.push(elementRef.legend());
|
|
5617
5697
|
}
|
|
5618
5698
|
return refs;
|
|
@@ -5994,7 +6074,11 @@ function createChart(container, spec, options) {
|
|
|
5994
6074
|
}
|
|
5995
6075
|
currentLayout = compile();
|
|
5996
6076
|
const shouldAnimate = isFirstRender && !!currentLayout.animation?.enabled;
|
|
5997
|
-
|
|
6077
|
+
const crosshair = "crosshair" in currentSpec && !!currentSpec.crosshair;
|
|
6078
|
+
svgElement = renderChartSVG(currentLayout, container, {
|
|
6079
|
+
animate: shouldAnimate,
|
|
6080
|
+
crosshair
|
|
6081
|
+
});
|
|
5998
6082
|
tooltipManager = createTooltipManager(container);
|
|
5999
6083
|
cleanupTooltipEvents = wireTooltipEvents(
|
|
6000
6084
|
svgElement,
|
|
@@ -6706,8 +6790,9 @@ function renderBrand2(parent, layout) {
|
|
|
6706
6790
|
a2.appendChild(text);
|
|
6707
6791
|
parent.appendChild(a2);
|
|
6708
6792
|
}
|
|
6709
|
-
function renderLegend2(parent,
|
|
6710
|
-
if (
|
|
6793
|
+
function renderLegend2(parent, legendLayout) {
|
|
6794
|
+
if (!("entries" in legendLayout) || legendLayout.entries.length === 0) return;
|
|
6795
|
+
const legend = legendLayout;
|
|
6711
6796
|
const g = createSVGElement2("g");
|
|
6712
6797
|
g.setAttribute("class", "oc-legend");
|
|
6713
6798
|
g.setAttribute("role", "list");
|
|
@@ -8125,6 +8210,535 @@ function createTable(container, spec, options) {
|
|
|
8125
8210
|
destroy
|
|
8126
8211
|
};
|
|
8127
8212
|
}
|
|
8213
|
+
|
|
8214
|
+
// src/tilemap-mount.ts
|
|
8215
|
+
import { compileTileMap } from "@opendata-ai/openchart-engine";
|
|
8216
|
+
|
|
8217
|
+
// src/tilemap-renderer.ts
|
|
8218
|
+
var SVG_NS4 = "http://www.w3.org/2000/svg";
|
|
8219
|
+
var XLINK_NS3 = "http://www.w3.org/1999/xlink";
|
|
8220
|
+
var BRAND_URL4 = "https://tryopendata.ai";
|
|
8221
|
+
var EASE_VAR_MAP4 = {
|
|
8222
|
+
smooth: "var(--oc-ease-smooth)",
|
|
8223
|
+
snappy: "var(--oc-ease-snappy)"
|
|
8224
|
+
};
|
|
8225
|
+
var gradientIdCounter = 0;
|
|
8226
|
+
function createSVGElement3(tag) {
|
|
8227
|
+
return document.createElementNS(SVG_NS4, tag);
|
|
8228
|
+
}
|
|
8229
|
+
function setAttrs3(el, attrs) {
|
|
8230
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
8231
|
+
el.setAttribute(key, String(value));
|
|
8232
|
+
}
|
|
8233
|
+
}
|
|
8234
|
+
function renderChrome3(parent, layout) {
|
|
8235
|
+
const g = createSVGElement3("g");
|
|
8236
|
+
g.setAttribute("class", "oc-chrome");
|
|
8237
|
+
const { chrome } = layout;
|
|
8238
|
+
const bottomOffset = layout.area.y + layout.area.height;
|
|
8239
|
+
if (chrome.title) {
|
|
8240
|
+
const text = createSVGElement3("text");
|
|
8241
|
+
setAttrs3(text, { x: chrome.title.x, y: chrome.title.y });
|
|
8242
|
+
text.setAttribute("class", "oc-title");
|
|
8243
|
+
text.setAttribute("font-family", chrome.title.style.fontFamily);
|
|
8244
|
+
text.setAttribute("font-size", String(chrome.title.style.fontSize));
|
|
8245
|
+
text.setAttribute("font-weight", String(chrome.title.style.fontWeight));
|
|
8246
|
+
text.style.setProperty("fill", chrome.title.style.fill);
|
|
8247
|
+
text.textContent = chrome.title.text;
|
|
8248
|
+
g.appendChild(text);
|
|
8249
|
+
}
|
|
8250
|
+
if (chrome.subtitle) {
|
|
8251
|
+
const text = createSVGElement3("text");
|
|
8252
|
+
setAttrs3(text, { x: chrome.subtitle.x, y: chrome.subtitle.y });
|
|
8253
|
+
text.setAttribute("class", "oc-subtitle");
|
|
8254
|
+
text.setAttribute("font-family", chrome.subtitle.style.fontFamily);
|
|
8255
|
+
text.setAttribute("font-size", String(chrome.subtitle.style.fontSize));
|
|
8256
|
+
text.setAttribute("font-weight", String(chrome.subtitle.style.fontWeight));
|
|
8257
|
+
text.style.setProperty(
|
|
8258
|
+
"fill",
|
|
8259
|
+
chrome.subtitle.style.fill
|
|
8260
|
+
);
|
|
8261
|
+
text.textContent = chrome.subtitle.text;
|
|
8262
|
+
g.appendChild(text);
|
|
8263
|
+
}
|
|
8264
|
+
if (chrome.source) {
|
|
8265
|
+
const text = createSVGElement3("text");
|
|
8266
|
+
setAttrs3(text, { x: chrome.source.x, y: bottomOffset + chrome.source.y });
|
|
8267
|
+
text.setAttribute("class", "oc-source");
|
|
8268
|
+
text.setAttribute("font-family", chrome.source.style.fontFamily);
|
|
8269
|
+
text.setAttribute("font-size", String(chrome.source.style.fontSize));
|
|
8270
|
+
text.setAttribute("font-weight", String(chrome.source.style.fontWeight));
|
|
8271
|
+
text.style.setProperty(
|
|
8272
|
+
"fill",
|
|
8273
|
+
chrome.source.style.fill
|
|
8274
|
+
);
|
|
8275
|
+
text.textContent = chrome.source.text;
|
|
8276
|
+
g.appendChild(text);
|
|
8277
|
+
}
|
|
8278
|
+
if (chrome.byline) {
|
|
8279
|
+
const text = createSVGElement3("text");
|
|
8280
|
+
setAttrs3(text, { x: chrome.byline.x, y: bottomOffset + chrome.byline.y });
|
|
8281
|
+
text.setAttribute("class", "oc-byline");
|
|
8282
|
+
text.setAttribute("font-family", chrome.byline.style.fontFamily);
|
|
8283
|
+
text.setAttribute("font-size", String(chrome.byline.style.fontSize));
|
|
8284
|
+
text.setAttribute("font-weight", String(chrome.byline.style.fontWeight));
|
|
8285
|
+
text.style.setProperty(
|
|
8286
|
+
"fill",
|
|
8287
|
+
chrome.byline.style.fill
|
|
8288
|
+
);
|
|
8289
|
+
text.textContent = chrome.byline.text;
|
|
8290
|
+
g.appendChild(text);
|
|
8291
|
+
}
|
|
8292
|
+
if (chrome.footer) {
|
|
8293
|
+
const text = createSVGElement3("text");
|
|
8294
|
+
setAttrs3(text, { x: chrome.footer.x, y: bottomOffset + chrome.footer.y });
|
|
8295
|
+
text.setAttribute("class", "oc-footer");
|
|
8296
|
+
text.setAttribute("font-family", chrome.footer.style.fontFamily);
|
|
8297
|
+
text.setAttribute("font-size", String(chrome.footer.style.fontSize));
|
|
8298
|
+
text.setAttribute("font-weight", String(chrome.footer.style.fontWeight));
|
|
8299
|
+
text.style.setProperty(
|
|
8300
|
+
"fill",
|
|
8301
|
+
chrome.footer.style.fill
|
|
8302
|
+
);
|
|
8303
|
+
text.textContent = chrome.footer.text;
|
|
8304
|
+
g.appendChild(text);
|
|
8305
|
+
}
|
|
8306
|
+
parent.appendChild(g);
|
|
8307
|
+
}
|
|
8308
|
+
function renderWatermark(parent, layout) {
|
|
8309
|
+
if (layout.width < 480) return;
|
|
8310
|
+
const { width, height } = layout;
|
|
8311
|
+
const { theme } = layout;
|
|
8312
|
+
const padding = theme.spacing.padding;
|
|
8313
|
+
const rightEdge = width - padding;
|
|
8314
|
+
const bottomEdge = height - padding;
|
|
8315
|
+
const fill = theme.colors.axis;
|
|
8316
|
+
const a2 = createSVGElement3("a");
|
|
8317
|
+
a2.setAttribute("href", BRAND_URL4);
|
|
8318
|
+
a2.setAttributeNS(XLINK_NS3, "xlink:href", BRAND_URL4);
|
|
8319
|
+
a2.setAttribute("target", "_blank");
|
|
8320
|
+
a2.setAttribute("rel", "noopener");
|
|
8321
|
+
a2.setAttribute("class", "oc-chrome-ref");
|
|
8322
|
+
const text = createSVGElement3("text");
|
|
8323
|
+
setAttrs3(text, {
|
|
8324
|
+
x: rightEdge,
|
|
8325
|
+
y: bottomEdge,
|
|
8326
|
+
"dominant-baseline": "alphabetic",
|
|
8327
|
+
"text-anchor": "end",
|
|
8328
|
+
"font-family": theme.fonts.family,
|
|
8329
|
+
"font-size": 12,
|
|
8330
|
+
"fill-opacity": 0.55
|
|
8331
|
+
});
|
|
8332
|
+
text.style.setProperty("fill", fill);
|
|
8333
|
+
const trySpan = createSVGElement3("tspan");
|
|
8334
|
+
setAttrs3(trySpan, { "font-weight": 500 });
|
|
8335
|
+
trySpan.textContent = "try";
|
|
8336
|
+
const openDataSpan = createSVGElement3("tspan");
|
|
8337
|
+
setAttrs3(openDataSpan, { "font-weight": 600, "font-size": 16 });
|
|
8338
|
+
openDataSpan.textContent = "OpenData";
|
|
8339
|
+
const aiSpan = createSVGElement3("tspan");
|
|
8340
|
+
setAttrs3(aiSpan, { "font-weight": 500 });
|
|
8341
|
+
aiSpan.textContent = ".ai";
|
|
8342
|
+
text.appendChild(trySpan);
|
|
8343
|
+
text.appendChild(openDataSpan);
|
|
8344
|
+
text.appendChild(aiSpan);
|
|
8345
|
+
a2.appendChild(text);
|
|
8346
|
+
parent.appendChild(a2);
|
|
8347
|
+
}
|
|
8348
|
+
function renderTiles(parent, tiles, animation) {
|
|
8349
|
+
const g = createSVGElement3("g");
|
|
8350
|
+
g.setAttribute("class", "oc-tilemap-tiles");
|
|
8351
|
+
g.setAttribute("role", "list");
|
|
8352
|
+
const tileDelays = [];
|
|
8353
|
+
if (animation?.enabled) {
|
|
8354
|
+
const baseStagger = 800 / Math.max(tiles.length, 1);
|
|
8355
|
+
let seed = 17;
|
|
8356
|
+
for (let i = 0; i < tiles.length; i++) {
|
|
8357
|
+
const idx = tiles[i].animationIndex ?? i;
|
|
8358
|
+
seed = seed * 1103515245 + 12345 & 2147483647;
|
|
8359
|
+
const jitter = (seed % 1e3 / 1e3 - 0.5) * 0.8;
|
|
8360
|
+
tileDelays.push(Math.max(0, Math.round(idx * baseStagger * (1 + jitter))));
|
|
8361
|
+
}
|
|
8362
|
+
}
|
|
8363
|
+
for (let i = 0; i < tiles.length; i++) {
|
|
8364
|
+
const tile = tiles[i];
|
|
8365
|
+
const tileGroup = createSVGElement3("g");
|
|
8366
|
+
tileGroup.setAttribute("class", "oc-tilemap-tile");
|
|
8367
|
+
tileGroup.setAttribute("data-state", tile.stateCode);
|
|
8368
|
+
tileGroup.setAttribute("role", "listitem");
|
|
8369
|
+
if (tile.aria?.label) {
|
|
8370
|
+
tileGroup.setAttribute("aria-label", tile.aria.label);
|
|
8371
|
+
}
|
|
8372
|
+
if (animation?.enabled) {
|
|
8373
|
+
const idx = tile.animationIndex ?? i;
|
|
8374
|
+
tileGroup.setAttribute("data-animation-index", String(idx));
|
|
8375
|
+
tileGroup.style.setProperty(
|
|
8376
|
+
"--oc-mark-index",
|
|
8377
|
+
String(idx)
|
|
8378
|
+
);
|
|
8379
|
+
tileGroup.style.setProperty(
|
|
8380
|
+
"--oc-tile-delay",
|
|
8381
|
+
`${tileDelays[i]}ms`
|
|
8382
|
+
);
|
|
8383
|
+
}
|
|
8384
|
+
const rect = createSVGElement3("rect");
|
|
8385
|
+
setAttrs3(rect, {
|
|
8386
|
+
x: tile.x,
|
|
8387
|
+
y: tile.y,
|
|
8388
|
+
width: tile.size,
|
|
8389
|
+
height: tile.size,
|
|
8390
|
+
rx: tile.cornerRadius,
|
|
8391
|
+
fill: tile.fill,
|
|
8392
|
+
stroke: tile.stroke,
|
|
8393
|
+
"stroke-width": tile.strokeWidth
|
|
8394
|
+
});
|
|
8395
|
+
tileGroup.appendChild(rect);
|
|
8396
|
+
const codeLabel = createSVGElement3("text");
|
|
8397
|
+
setAttrs3(codeLabel, {
|
|
8398
|
+
x: tile.label.x,
|
|
8399
|
+
y: tile.label.y,
|
|
8400
|
+
"text-anchor": "middle",
|
|
8401
|
+
"dominant-baseline": "central",
|
|
8402
|
+
"font-family": tile.label.style.fontFamily,
|
|
8403
|
+
"font-size": tile.label.style.fontSize,
|
|
8404
|
+
"font-weight": tile.label.style.fontWeight
|
|
8405
|
+
});
|
|
8406
|
+
codeLabel.style.setProperty(
|
|
8407
|
+
"fill",
|
|
8408
|
+
tile.label.style.fill
|
|
8409
|
+
);
|
|
8410
|
+
codeLabel.textContent = tile.label.text;
|
|
8411
|
+
tileGroup.appendChild(codeLabel);
|
|
8412
|
+
if (tile.valueLabel.visible && tile.valueLabel.text) {
|
|
8413
|
+
const valueLabel = createSVGElement3("text");
|
|
8414
|
+
setAttrs3(valueLabel, {
|
|
8415
|
+
x: tile.valueLabel.x,
|
|
8416
|
+
y: tile.valueLabel.y,
|
|
8417
|
+
"text-anchor": "middle",
|
|
8418
|
+
"dominant-baseline": "central",
|
|
8419
|
+
"font-family": tile.valueLabel.style.fontFamily,
|
|
8420
|
+
"font-size": tile.valueLabel.style.fontSize,
|
|
8421
|
+
"font-weight": tile.valueLabel.style.fontWeight
|
|
8422
|
+
});
|
|
8423
|
+
valueLabel.style.setProperty(
|
|
8424
|
+
"fill",
|
|
8425
|
+
tile.valueLabel.style.fill
|
|
8426
|
+
);
|
|
8427
|
+
valueLabel.textContent = tile.valueLabel.text;
|
|
8428
|
+
tileGroup.appendChild(valueLabel);
|
|
8429
|
+
}
|
|
8430
|
+
g.appendChild(tileGroup);
|
|
8431
|
+
}
|
|
8432
|
+
parent.appendChild(g);
|
|
8433
|
+
}
|
|
8434
|
+
function renderGradientLegend(parent, layout) {
|
|
8435
|
+
if (!layout.gradientLegend) return;
|
|
8436
|
+
const { gradientLegend } = layout;
|
|
8437
|
+
const g = createSVGElement3("g");
|
|
8438
|
+
g.setAttribute("class", "oc-tilemap-legend");
|
|
8439
|
+
const defs = parent.querySelector("defs") || createSVGElement3("defs");
|
|
8440
|
+
const exists = parent.querySelector("defs");
|
|
8441
|
+
if (!exists) {
|
|
8442
|
+
parent.insertBefore(defs, parent.firstChild);
|
|
8443
|
+
}
|
|
8444
|
+
const gradientId = `oc-tilemap-legend-gradient-${gradientIdCounter++}`;
|
|
8445
|
+
const grad = createSVGElement3("linearGradient");
|
|
8446
|
+
grad.id = gradientId;
|
|
8447
|
+
grad.setAttribute("x1", "0%");
|
|
8448
|
+
grad.setAttribute("y1", "0%");
|
|
8449
|
+
grad.setAttribute("x2", "100%");
|
|
8450
|
+
grad.setAttribute("y2", "0%");
|
|
8451
|
+
for (const stop of gradientLegend.colorStops) {
|
|
8452
|
+
const s = createSVGElement3("stop");
|
|
8453
|
+
setAttrs3(s, { offset: `${stop.offset * 100}%`, "stop-color": stop.color });
|
|
8454
|
+
grad.appendChild(s);
|
|
8455
|
+
}
|
|
8456
|
+
defs.appendChild(grad);
|
|
8457
|
+
const bar = createSVGElement3("rect");
|
|
8458
|
+
setAttrs3(bar, {
|
|
8459
|
+
x: gradientLegend.bounds.x,
|
|
8460
|
+
y: gradientLegend.bounds.y,
|
|
8461
|
+
width: gradientLegend.bounds.width,
|
|
8462
|
+
height: gradientLegend.bounds.height,
|
|
8463
|
+
rx: 3,
|
|
8464
|
+
fill: `url(#${gradientId})`
|
|
8465
|
+
});
|
|
8466
|
+
g.appendChild(bar);
|
|
8467
|
+
const minText = createSVGElement3("text");
|
|
8468
|
+
setAttrs3(minText, {
|
|
8469
|
+
x: gradientLegend.bounds.x,
|
|
8470
|
+
y: gradientLegend.bounds.y + gradientLegend.bounds.height + 14,
|
|
8471
|
+
"text-anchor": "start",
|
|
8472
|
+
"font-family": gradientLegend.labelStyle.fontFamily,
|
|
8473
|
+
"font-size": gradientLegend.labelStyle.fontSize,
|
|
8474
|
+
"font-weight": gradientLegend.labelStyle.fontWeight
|
|
8475
|
+
});
|
|
8476
|
+
minText.style.setProperty(
|
|
8477
|
+
"fill",
|
|
8478
|
+
gradientLegend.labelStyle.fill
|
|
8479
|
+
);
|
|
8480
|
+
minText.textContent = gradientLegend.minLabel;
|
|
8481
|
+
g.appendChild(minText);
|
|
8482
|
+
const maxText = createSVGElement3("text");
|
|
8483
|
+
setAttrs3(maxText, {
|
|
8484
|
+
x: gradientLegend.bounds.x + gradientLegend.bounds.width,
|
|
8485
|
+
y: gradientLegend.bounds.y + gradientLegend.bounds.height + 14,
|
|
8486
|
+
"text-anchor": "end",
|
|
8487
|
+
"font-family": gradientLegend.labelStyle.fontFamily,
|
|
8488
|
+
"font-size": gradientLegend.labelStyle.fontSize,
|
|
8489
|
+
"font-weight": gradientLegend.labelStyle.fontWeight
|
|
8490
|
+
});
|
|
8491
|
+
maxText.style.setProperty(
|
|
8492
|
+
"fill",
|
|
8493
|
+
gradientLegend.labelStyle.fill
|
|
8494
|
+
);
|
|
8495
|
+
maxText.textContent = gradientLegend.maxLabel;
|
|
8496
|
+
g.appendChild(maxText);
|
|
8497
|
+
parent.appendChild(g);
|
|
8498
|
+
}
|
|
8499
|
+
function renderTileMapSVG(layout, opts) {
|
|
8500
|
+
const { width, height, tiles, a11y, watermark, animation } = layout;
|
|
8501
|
+
const animate = opts?.animate && animation?.enabled;
|
|
8502
|
+
const svg = createSVGElement3("svg");
|
|
8503
|
+
svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
8504
|
+
svg.setAttribute("width", String(width));
|
|
8505
|
+
svg.setAttribute("height", String(height));
|
|
8506
|
+
svg.setAttribute("role", "img");
|
|
8507
|
+
if (a11y.altText) {
|
|
8508
|
+
svg.setAttribute("aria-label", a11y.altText);
|
|
8509
|
+
}
|
|
8510
|
+
const classes = animate ? "oc-tilemap oc-animate" : "oc-tilemap";
|
|
8511
|
+
svg.setAttribute("class", classes);
|
|
8512
|
+
if (animate && animation) {
|
|
8513
|
+
const stagger = Math.max(5, Math.round(800 / Math.max(tiles.length, 1)));
|
|
8514
|
+
svg.style.setProperty("--oc-animation-duration", `${animation.duration}ms`);
|
|
8515
|
+
svg.style.setProperty("--oc-animation-stagger", `${stagger}ms`);
|
|
8516
|
+
svg.style.setProperty("--oc-annotation-delay", `${animation.annotationDelay}ms`);
|
|
8517
|
+
const easeVar = EASE_VAR_MAP4[animation.ease] || EASE_VAR_MAP4.smooth;
|
|
8518
|
+
svg.style.setProperty("--oc-animation-ease", easeVar);
|
|
8519
|
+
}
|
|
8520
|
+
const defs = createSVGElement3("defs");
|
|
8521
|
+
svg.appendChild(defs);
|
|
8522
|
+
renderChrome3(svg, layout);
|
|
8523
|
+
renderTiles(svg, tiles, animate ? animation : void 0);
|
|
8524
|
+
renderGradientLegend(svg, layout);
|
|
8525
|
+
if (watermark) {
|
|
8526
|
+
renderWatermark(svg, layout);
|
|
8527
|
+
}
|
|
8528
|
+
return svg;
|
|
8529
|
+
}
|
|
8530
|
+
|
|
8531
|
+
// src/tilemap-mount.ts
|
|
8532
|
+
function resolveDarkMode5(mode) {
|
|
8533
|
+
if (mode === "force") return true;
|
|
8534
|
+
if (mode === "off" || mode === void 0) return false;
|
|
8535
|
+
if (typeof window !== "undefined" && window.matchMedia) {
|
|
8536
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
8537
|
+
}
|
|
8538
|
+
return false;
|
|
8539
|
+
}
|
|
8540
|
+
function createTileMap(container, spec, options) {
|
|
8541
|
+
let currentSpec = spec;
|
|
8542
|
+
let currentLayout;
|
|
8543
|
+
let destroyed = false;
|
|
8544
|
+
let svgElement = null;
|
|
8545
|
+
let tooltipManager = null;
|
|
8546
|
+
let cleanupTooltipEvents = null;
|
|
8547
|
+
let disconnectResize = null;
|
|
8548
|
+
let animationCleanup = null;
|
|
8549
|
+
let pendingResize = false;
|
|
8550
|
+
const measureText = createMeasureText();
|
|
8551
|
+
function getContainerDimensions() {
|
|
8552
|
+
const rect = container.getBoundingClientRect();
|
|
8553
|
+
return {
|
|
8554
|
+
width: Math.max(rect.width || 600, 100),
|
|
8555
|
+
height: Math.max(rect.height || 400, 100)
|
|
8556
|
+
};
|
|
8557
|
+
}
|
|
8558
|
+
function compile() {
|
|
8559
|
+
const { width, height } = getContainerDimensions();
|
|
8560
|
+
const darkMode = resolveDarkMode5(options?.darkMode);
|
|
8561
|
+
const compileOpts = {
|
|
8562
|
+
width,
|
|
8563
|
+
height,
|
|
8564
|
+
theme: options?.theme,
|
|
8565
|
+
darkMode,
|
|
8566
|
+
watermark: options?.watermark,
|
|
8567
|
+
measureText
|
|
8568
|
+
};
|
|
8569
|
+
return compileTileMap(currentSpec, compileOpts);
|
|
8570
|
+
}
|
|
8571
|
+
function wireTooltipAndInteraction(svg, layout) {
|
|
8572
|
+
const cleanups = [];
|
|
8573
|
+
const tileElements = svg.querySelectorAll(".oc-tilemap-tile");
|
|
8574
|
+
for (const el of tileElements) {
|
|
8575
|
+
const stateCode = el.getAttribute("data-state");
|
|
8576
|
+
if (!stateCode) continue;
|
|
8577
|
+
const content = layout.tooltipDescriptors.get(stateCode);
|
|
8578
|
+
const tile = layout.tiles.find((t) => t.stateCode === stateCode);
|
|
8579
|
+
const handleMouseEnter = (e) => {
|
|
8580
|
+
const mouseEvent = e;
|
|
8581
|
+
if (content && tooltipManager && options?.tooltip !== false) {
|
|
8582
|
+
const svgRect = svg.getBoundingClientRect();
|
|
8583
|
+
const x3 = mouseEvent.clientX - svgRect.left;
|
|
8584
|
+
const y3 = mouseEvent.clientY - svgRect.top;
|
|
8585
|
+
tooltipManager.show(content, x3, y3);
|
|
8586
|
+
}
|
|
8587
|
+
if (tile) {
|
|
8588
|
+
options?.onTileHover?.({
|
|
8589
|
+
stateCode: tile.stateCode,
|
|
8590
|
+
stateName: tile.data.stateName,
|
|
8591
|
+
value: tile.value,
|
|
8592
|
+
data: tile.data
|
|
8593
|
+
});
|
|
8594
|
+
}
|
|
8595
|
+
};
|
|
8596
|
+
const handleMouseMove = (e) => {
|
|
8597
|
+
if (content && tooltipManager && options?.tooltip !== false) {
|
|
8598
|
+
const mouseEvent = e;
|
|
8599
|
+
const svgRect = svg.getBoundingClientRect();
|
|
8600
|
+
const x3 = mouseEvent.clientX - svgRect.left;
|
|
8601
|
+
const y3 = mouseEvent.clientY - svgRect.top;
|
|
8602
|
+
tooltipManager.show(content, x3, y3);
|
|
8603
|
+
}
|
|
8604
|
+
};
|
|
8605
|
+
const handleMouseLeave = () => {
|
|
8606
|
+
tooltipManager?.hide();
|
|
8607
|
+
options?.onTileHover?.(null);
|
|
8608
|
+
};
|
|
8609
|
+
const handleClick = () => {
|
|
8610
|
+
if (tile) {
|
|
8611
|
+
options?.onTileClick?.({
|
|
8612
|
+
stateCode: tile.stateCode,
|
|
8613
|
+
stateName: tile.data.stateName,
|
|
8614
|
+
value: tile.value,
|
|
8615
|
+
data: tile.data
|
|
8616
|
+
});
|
|
8617
|
+
}
|
|
8618
|
+
};
|
|
8619
|
+
el.addEventListener("mouseenter", handleMouseEnter);
|
|
8620
|
+
el.addEventListener("mousemove", handleMouseMove);
|
|
8621
|
+
el.addEventListener("mouseleave", handleMouseLeave);
|
|
8622
|
+
el.addEventListener("click", handleClick);
|
|
8623
|
+
cleanups.push(() => {
|
|
8624
|
+
el.removeEventListener("mouseenter", handleMouseEnter);
|
|
8625
|
+
el.removeEventListener("mousemove", handleMouseMove);
|
|
8626
|
+
el.removeEventListener("mouseleave", handleMouseLeave);
|
|
8627
|
+
el.removeEventListener("click", handleClick);
|
|
8628
|
+
});
|
|
8629
|
+
}
|
|
8630
|
+
return () => {
|
|
8631
|
+
for (const cleanup of cleanups) {
|
|
8632
|
+
cleanup();
|
|
8633
|
+
}
|
|
8634
|
+
};
|
|
8635
|
+
}
|
|
8636
|
+
function render(animate = false) {
|
|
8637
|
+
if (animationCleanup) {
|
|
8638
|
+
animationCleanup();
|
|
8639
|
+
animationCleanup = null;
|
|
8640
|
+
}
|
|
8641
|
+
if (svgElement) {
|
|
8642
|
+
if (cleanupTooltipEvents) {
|
|
8643
|
+
cleanupTooltipEvents();
|
|
8644
|
+
cleanupTooltipEvents = null;
|
|
8645
|
+
}
|
|
8646
|
+
svgElement.remove();
|
|
8647
|
+
}
|
|
8648
|
+
const newSvg = renderTileMapSVG(currentLayout, { animate });
|
|
8649
|
+
container.appendChild(newSvg);
|
|
8650
|
+
svgElement = newSvg;
|
|
8651
|
+
cleanupTooltipEvents = wireTooltipAndInteraction(newSvg, currentLayout);
|
|
8652
|
+
if (options?.tooltip !== false) {
|
|
8653
|
+
if (!tooltipManager) {
|
|
8654
|
+
tooltipManager = createTooltipManager(container);
|
|
8655
|
+
}
|
|
8656
|
+
}
|
|
8657
|
+
if (currentLayout.animation?.enabled) {
|
|
8658
|
+
animationCleanup = setupAnimationCleanup(newSvg, () => {
|
|
8659
|
+
if (pendingResize && !destroyed) {
|
|
8660
|
+
pendingResize = false;
|
|
8661
|
+
resize();
|
|
8662
|
+
}
|
|
8663
|
+
});
|
|
8664
|
+
}
|
|
8665
|
+
}
|
|
8666
|
+
function update(newSpec) {
|
|
8667
|
+
currentSpec = newSpec;
|
|
8668
|
+
currentLayout = compile();
|
|
8669
|
+
render();
|
|
8670
|
+
}
|
|
8671
|
+
function resize() {
|
|
8672
|
+
if (destroyed) return;
|
|
8673
|
+
if (animationCleanup) {
|
|
8674
|
+
pendingResize = true;
|
|
8675
|
+
return;
|
|
8676
|
+
}
|
|
8677
|
+
currentLayout = compile();
|
|
8678
|
+
render();
|
|
8679
|
+
}
|
|
8680
|
+
function exportChart(format, options_) {
|
|
8681
|
+
if (!svgElement) return "";
|
|
8682
|
+
switch (format) {
|
|
8683
|
+
case "svg":
|
|
8684
|
+
return exportSVG(svgElement);
|
|
8685
|
+
case "svg-with-fonts":
|
|
8686
|
+
return exportSVGWithFonts(svgElement);
|
|
8687
|
+
case "png":
|
|
8688
|
+
return exportPNG(svgElement, options_);
|
|
8689
|
+
case "jpg":
|
|
8690
|
+
return exportJPG(svgElement, options_);
|
|
8691
|
+
default:
|
|
8692
|
+
return "";
|
|
8693
|
+
}
|
|
8694
|
+
}
|
|
8695
|
+
function destroy() {
|
|
8696
|
+
if (destroyed) return;
|
|
8697
|
+
destroyed = true;
|
|
8698
|
+
if (animationCleanup) {
|
|
8699
|
+
cancelAnimations(svgElement);
|
|
8700
|
+
animationCleanup();
|
|
8701
|
+
animationCleanup = null;
|
|
8702
|
+
}
|
|
8703
|
+
if (cleanupTooltipEvents) {
|
|
8704
|
+
cleanupTooltipEvents();
|
|
8705
|
+
cleanupTooltipEvents = null;
|
|
8706
|
+
}
|
|
8707
|
+
if (svgElement) {
|
|
8708
|
+
svgElement.remove();
|
|
8709
|
+
svgElement = null;
|
|
8710
|
+
}
|
|
8711
|
+
if (tooltipManager) {
|
|
8712
|
+
tooltipManager.destroy();
|
|
8713
|
+
tooltipManager = null;
|
|
8714
|
+
}
|
|
8715
|
+
if (disconnectResize) {
|
|
8716
|
+
disconnectResize();
|
|
8717
|
+
disconnectResize = null;
|
|
8718
|
+
}
|
|
8719
|
+
container.classList.remove("oc-tilemap-root", "oc-dark");
|
|
8720
|
+
}
|
|
8721
|
+
container.classList.add("oc-tilemap-root");
|
|
8722
|
+
if (resolveDarkMode5(options?.darkMode)) {
|
|
8723
|
+
container.classList.add("oc-dark");
|
|
8724
|
+
}
|
|
8725
|
+
currentLayout = compile();
|
|
8726
|
+
render(true);
|
|
8727
|
+
if (options?.responsive !== false) {
|
|
8728
|
+
disconnectResize = observeResize(container, () => {
|
|
8729
|
+
resize();
|
|
8730
|
+
});
|
|
8731
|
+
}
|
|
8732
|
+
return {
|
|
8733
|
+
update,
|
|
8734
|
+
resize,
|
|
8735
|
+
export: exportChart,
|
|
8736
|
+
destroy,
|
|
8737
|
+
get layout() {
|
|
8738
|
+
return currentLayout;
|
|
8739
|
+
}
|
|
8740
|
+
};
|
|
8741
|
+
}
|
|
8128
8742
|
export {
|
|
8129
8743
|
attachKeyboardNav,
|
|
8130
8744
|
createChart,
|
|
@@ -8133,6 +8747,7 @@ export {
|
|
|
8133
8747
|
createSimulationWorker,
|
|
8134
8748
|
createTable,
|
|
8135
8749
|
createTextEditOverlay,
|
|
8750
|
+
createTileMap,
|
|
8136
8751
|
createTooltipManager,
|
|
8137
8752
|
exportCSV,
|
|
8138
8753
|
exportJPG,
|