@opendata-ai/openchart-vanilla 8.4.0 → 8.5.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/README.md +59 -0
- package/dist/chunk-2OJZBMXM.js +377 -0
- package/dist/chunk-2OJZBMXM.js.map +1 -0
- package/dist/{chunk-45XZOWYC.js → chunk-5KV3ZBBL.js} +58 -437
- package/dist/chunk-5KV3ZBBL.js.map +1 -0
- package/dist/{chunk-HGRNXLDF.js → chunk-5RX6ZQGZ.js} +10 -1
- package/dist/chunk-5RX6ZQGZ.js.map +1 -0
- package/dist/{chunk-UOB422LY.js → chunk-6B5OBGIO.js} +2 -2
- package/dist/chunk-NG7CVCI2.js +58 -0
- package/dist/chunk-NG7CVCI2.js.map +1 -0
- package/dist/{chunk-FETYAVTZ.js → chunk-RYVV3YIG.js} +3 -3
- package/dist/{chunk-LNPRDSK3.js → chunk-UAK6HWOC.js} +2 -2
- package/dist/chunk-WOLX5EZT.js +3577 -0
- package/dist/chunk-WOLX5EZT.js.map +1 -0
- package/dist/{chunk-YGYMB7KB.js → chunk-XGII4ZRT.js} +55 -30
- package/dist/chunk-XGII4ZRT.js.map +1 -0
- package/dist/export-gif.js +3 -3
- package/dist/graph-3d/index.d.ts +272 -0
- package/dist/graph-3d/index.js +1556 -0
- package/dist/graph-3d/index.js.map +1 -0
- package/dist/index.d.ts +4 -252
- package/dist/index.js +27 -3471
- package/dist/index.js.map +1 -1
- package/dist/renderer-registry-B5tW6yAZ.d.ts +376 -0
- package/dist/static.js +4 -3
- package/dist/static.js.map +1 -1
- package/dist/story/index.js +10 -7
- package/dist/story/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +26 -5
- package/dist/chunk-45XZOWYC.js.map +0 -1
- package/dist/chunk-HGRNXLDF.js.map +0 -1
- package/dist/chunk-YGYMB7KB.js.map +0 -1
- /package/dist/{chunk-UOB422LY.js.map → chunk-6B5OBGIO.js.map} +0 -0
- /package/dist/{chunk-FETYAVTZ.js.map → chunk-RYVV3YIG.js.map} +0 -0
- /package/dist/{chunk-LNPRDSK3.js.map → chunk-UAK6HWOC.js.map} +0 -0
|
@@ -4,9 +4,10 @@ import {
|
|
|
4
4
|
exportPNG,
|
|
5
5
|
exportSVG,
|
|
6
6
|
exportSVGWithFonts
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-6B5OBGIO.js";
|
|
8
8
|
import {
|
|
9
9
|
buildGradientDefs,
|
|
10
|
+
buildPatternDefs,
|
|
10
11
|
nextSvgId,
|
|
11
12
|
rectPathWithCorners,
|
|
12
13
|
renderChartSVG,
|
|
@@ -14,161 +15,33 @@ import {
|
|
|
14
15
|
renderLegend,
|
|
15
16
|
renderSingleMark,
|
|
16
17
|
resolveMarkFill,
|
|
18
|
+
resolvePatternFill,
|
|
17
19
|
stampAnimationVars
|
|
18
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-XGII4ZRT.js";
|
|
19
21
|
import {
|
|
20
22
|
SVG_NS,
|
|
21
23
|
createSVGElement,
|
|
22
24
|
setAttrs
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
timeoutId = null;
|
|
44
|
-
}, DEBOUNCE_MS);
|
|
45
|
-
});
|
|
46
|
-
observer.observe(container);
|
|
47
|
-
return () => {
|
|
48
|
-
if (timeoutId !== null) {
|
|
49
|
-
clearTimeout(timeoutId);
|
|
50
|
-
}
|
|
51
|
-
observer.disconnect();
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// src/tooltip.ts
|
|
56
|
-
import { computePosition, flip, offset, shift } from "@floating-ui/dom";
|
|
57
|
-
var TOOLTIP_OFFSET = 12;
|
|
58
|
-
function createTooltipManager(container) {
|
|
59
|
-
const tooltip = document.createElement("div");
|
|
60
|
-
tooltip.className = "oc-tooltip";
|
|
61
|
-
tooltip.setAttribute("role", "tooltip");
|
|
62
|
-
container.style.position = container.style.position || "relative";
|
|
63
|
-
container.appendChild(tooltip);
|
|
64
|
-
let lastContentKey = "";
|
|
65
|
-
let currentPositionId = 0;
|
|
66
|
-
const handleDocumentTouch = (e) => {
|
|
67
|
-
if (!container.contains(e.target)) {
|
|
68
|
-
hide();
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
document.addEventListener("touchstart", handleDocumentTouch);
|
|
72
|
-
const handleDocumentKeydown = (e) => {
|
|
73
|
-
if (e.key === "Escape" && tooltip.style.display === "block") {
|
|
74
|
-
hide();
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
document.addEventListener("keydown", handleDocumentKeydown);
|
|
78
|
-
function show(input, x, y, opts) {
|
|
79
|
-
if ("element" in input) {
|
|
80
|
-
lastContentKey = "";
|
|
81
|
-
tooltip.replaceChildren(input.element);
|
|
82
|
-
position(x, y, opts);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if ("text" in input) {
|
|
86
|
-
lastContentKey = "";
|
|
87
|
-
tooltip.textContent = input.text;
|
|
88
|
-
position(x, y, opts);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
const content = input;
|
|
92
|
-
const emphasisIndex = content.fields.findIndex((f) => f.emphasis);
|
|
93
|
-
const contentKey = `${content.title}|${content.fields.length}|${content.fields[0]?.value}|${content.fields[content.fields.length - 1]?.value}|${emphasisIndex}`;
|
|
94
|
-
if (contentKey !== lastContentKey) {
|
|
95
|
-
lastContentKey = contentKey;
|
|
96
|
-
let html = "";
|
|
97
|
-
const colorRowCount = content.fields.filter((f) => f.color && f.role !== "total").length;
|
|
98
|
-
const perRowSwatches = colorRowCount > 1;
|
|
99
|
-
if (content.title) {
|
|
100
|
-
const titleColor = perRowSwatches ? void 0 : content.fields.find((f) => f.color)?.color;
|
|
101
|
-
html += '<div class="oc-tooltip-header">';
|
|
102
|
-
if (titleColor) {
|
|
103
|
-
html += `<span class="oc-tooltip-dot" style="background:${esc(titleColor)}"></span>`;
|
|
104
|
-
}
|
|
105
|
-
html += `<span class="oc-tooltip-title">${esc(content.title)}</span>`;
|
|
106
|
-
html += "</div>";
|
|
107
|
-
}
|
|
108
|
-
if (content.fields.length > 0) {
|
|
109
|
-
html += '<div class="oc-tooltip-body">';
|
|
110
|
-
for (const field of content.fields) {
|
|
111
|
-
let rowClass = "oc-tooltip-row";
|
|
112
|
-
if (field.emphasis) rowClass += " oc-tooltip-row--emphasis";
|
|
113
|
-
if (field.role === "total") rowClass += " oc-tooltip-row--total";
|
|
114
|
-
html += `<div class="${rowClass}">`;
|
|
115
|
-
html += '<span class="oc-tooltip-label">';
|
|
116
|
-
if (perRowSwatches && field.color) {
|
|
117
|
-
html += `<span class="oc-tooltip-row-swatch" style="background:${esc(field.color)}"></span>`;
|
|
118
|
-
}
|
|
119
|
-
html += `${esc(field.label)}</span>`;
|
|
120
|
-
html += `<span class="oc-tooltip-value">${esc(field.value)}</span>`;
|
|
121
|
-
html += "</div>";
|
|
122
|
-
}
|
|
123
|
-
html += "</div>";
|
|
124
|
-
}
|
|
125
|
-
tooltip.innerHTML = html;
|
|
126
|
-
}
|
|
127
|
-
position(x, y, opts);
|
|
128
|
-
}
|
|
129
|
-
function position(x, y, opts) {
|
|
130
|
-
tooltip.style.display = "block";
|
|
131
|
-
const positionId = ++currentPositionId;
|
|
132
|
-
const virtualRef = {
|
|
133
|
-
getBoundingClientRect() {
|
|
134
|
-
const rect = container.getBoundingClientRect();
|
|
135
|
-
return {
|
|
136
|
-
x: rect.left + x,
|
|
137
|
-
y: rect.top + y,
|
|
138
|
-
width: 0,
|
|
139
|
-
height: 0,
|
|
140
|
-
top: rect.top + y,
|
|
141
|
-
left: rect.left + x,
|
|
142
|
-
right: rect.left + x,
|
|
143
|
-
bottom: rect.top + y
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
computePosition(virtualRef, tooltip, {
|
|
148
|
-
placement: opts?.placement ?? "bottom-start",
|
|
149
|
-
middleware: [offset(TOOLTIP_OFFSET), flip(), shift({ padding: 8 })]
|
|
150
|
-
}).then(({ x: fx, y: fy }) => {
|
|
151
|
-
if (positionId !== currentPositionId) return;
|
|
152
|
-
tooltip.style.left = `${fx}px`;
|
|
153
|
-
tooltip.style.top = `${fy}px`;
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
function hide() {
|
|
157
|
-
tooltip.style.display = "none";
|
|
158
|
-
lastContentKey = "";
|
|
159
|
-
}
|
|
160
|
-
function destroy() {
|
|
161
|
-
document.removeEventListener("touchstart", handleDocumentTouch);
|
|
162
|
-
document.removeEventListener("keydown", handleDocumentKeydown);
|
|
163
|
-
if (tooltip.parentNode) {
|
|
164
|
-
tooltip.parentNode.removeChild(tooltip);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return { show, hide, destroy };
|
|
168
|
-
}
|
|
169
|
-
function esc(str) {
|
|
170
|
-
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
171
|
-
}
|
|
25
|
+
} from "./chunk-5RX6ZQGZ.js";
|
|
26
|
+
import {
|
|
27
|
+
AnimationScheduler,
|
|
28
|
+
SpatialIndex,
|
|
29
|
+
clamp01,
|
|
30
|
+
createTooltipManager,
|
|
31
|
+
createTween,
|
|
32
|
+
cubicInOut,
|
|
33
|
+
cubicOut,
|
|
34
|
+
lerp,
|
|
35
|
+
linear,
|
|
36
|
+
observeResize,
|
|
37
|
+
prefersReducedMotion,
|
|
38
|
+
resolveDarkMode,
|
|
39
|
+
resolveEase
|
|
40
|
+
} from "./chunk-2OJZBMXM.js";
|
|
41
|
+
import {
|
|
42
|
+
resolvedSurface,
|
|
43
|
+
stampThemeProperties
|
|
44
|
+
} from "./chunk-NG7CVCI2.js";
|
|
172
45
|
|
|
173
46
|
// src/scatter-canvas/renderer.ts
|
|
174
47
|
var TWO_PI = Math.PI * 2;
|
|
@@ -580,20 +453,6 @@ function materializeCanvasModeSVG(layout, opts) {
|
|
|
580
453
|
return materializeRasterMarkSVG(layout);
|
|
581
454
|
}
|
|
582
455
|
|
|
583
|
-
// src/motion/easing.ts
|
|
584
|
-
function linear(t) {
|
|
585
|
-
return t;
|
|
586
|
-
}
|
|
587
|
-
function cubicOut(t) {
|
|
588
|
-
const f = 1 - t;
|
|
589
|
-
return 1 - f * f * f;
|
|
590
|
-
}
|
|
591
|
-
function cubicInOut(t) {
|
|
592
|
-
return t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2;
|
|
593
|
-
}
|
|
594
|
-
var clamp01 = (t) => Math.min(1, Math.max(0, t));
|
|
595
|
-
var lerp = (a, b, t) => a + (b - a) * t;
|
|
596
|
-
|
|
597
456
|
// src/text-edit-overlay.ts
|
|
598
457
|
function getScale(svg) {
|
|
599
458
|
const viewBox = svg.viewBox?.baseVal;
|
|
@@ -625,7 +484,7 @@ function getTextStyles(targetElement, scale) {
|
|
|
625
484
|
lineHeight: "1.3"
|
|
626
485
|
};
|
|
627
486
|
}
|
|
628
|
-
function
|
|
487
|
+
function computePosition(targetElement, svg, container) {
|
|
629
488
|
const bbox = targetElement.getBBox();
|
|
630
489
|
const scale = getScale(svg);
|
|
631
490
|
const svgRect = svg.getBoundingClientRect();
|
|
@@ -649,7 +508,7 @@ function createTextEditOverlay(config) {
|
|
|
649
508
|
targetElement.setAttribute("opacity", "0");
|
|
650
509
|
const scale = getScale(svg);
|
|
651
510
|
const styles = getTextStyles(targetElement, scale);
|
|
652
|
-
const position =
|
|
511
|
+
const position = computePosition(targetElement, svg, container);
|
|
653
512
|
const textarea = document.createElement("textarea");
|
|
654
513
|
textarea.value = currentText;
|
|
655
514
|
const containerPosition = window.getComputedStyle(container).position;
|
|
@@ -738,7 +597,7 @@ function createTextEditOverlay(config) {
|
|
|
738
597
|
});
|
|
739
598
|
const resizeObserver = new ResizeObserver(() => {
|
|
740
599
|
if (destroyed) return;
|
|
741
|
-
const newPosition =
|
|
600
|
+
const newPosition = computePosition(targetElement, svg, container);
|
|
742
601
|
textarea.style.top = `${newPosition.top}px`;
|
|
743
602
|
textarea.style.left = `${newPosition.left}px`;
|
|
744
603
|
textarea.style.width = `${newPosition.width}px`;
|
|
@@ -3564,7 +3423,7 @@ function createYouDrawIt(options) {
|
|
|
3564
3423
|
}
|
|
3565
3424
|
|
|
3566
3425
|
// src/mount.ts
|
|
3567
|
-
import { cssTokenDefault
|
|
3426
|
+
import { cssTokenDefault, isGraphSpec, isLayerSpec } from "@opendata-ai/openchart-core";
|
|
3568
3427
|
import {
|
|
3569
3428
|
compileChart,
|
|
3570
3429
|
compileLayer,
|
|
@@ -5308,16 +5167,6 @@ function scheduleFontReload(fontFamily, isAlive, onReady) {
|
|
|
5308
5167
|
return true;
|
|
5309
5168
|
}
|
|
5310
5169
|
|
|
5311
|
-
// src/resolve-dark-mode.ts
|
|
5312
|
-
function resolveDarkMode(mode) {
|
|
5313
|
-
if (mode === "force") return true;
|
|
5314
|
-
if (mode === "off" || mode === void 0) return false;
|
|
5315
|
-
if (typeof window !== "undefined" && window.matchMedia) {
|
|
5316
|
-
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
5317
|
-
}
|
|
5318
|
-
return false;
|
|
5319
|
-
}
|
|
5320
|
-
|
|
5321
5170
|
// src/scatter-canvas/interactions.ts
|
|
5322
5171
|
var HIT_TOLERANCE_MOUSE = 8;
|
|
5323
5172
|
var HIT_TOLERANCE_TOUCH = 24;
|
|
@@ -5415,191 +5264,6 @@ function wireCanvasInteractions({
|
|
|
5415
5264
|
};
|
|
5416
5265
|
}
|
|
5417
5266
|
|
|
5418
|
-
// src/motion/scheduler.ts
|
|
5419
|
-
var AnimationScheduler = class {
|
|
5420
|
-
animations = /* @__PURE__ */ new Set();
|
|
5421
|
-
requestFrame;
|
|
5422
|
-
/**
|
|
5423
|
-
* @param requestFrame Called on the idle→active transition to arm the first
|
|
5424
|
-
* frame (typically the mount's `scheduleRender`).
|
|
5425
|
-
*/
|
|
5426
|
-
constructor(requestFrame) {
|
|
5427
|
-
this.requestFrame = requestFrame;
|
|
5428
|
-
}
|
|
5429
|
-
/** Add an animation. Arms the first frame if the scheduler was idle. */
|
|
5430
|
-
add(a) {
|
|
5431
|
-
const wasIdle = this.animations.size === 0;
|
|
5432
|
-
this.animations.add(a);
|
|
5433
|
-
if (wasIdle) this.requestFrame();
|
|
5434
|
-
}
|
|
5435
|
-
/** Remove an animation without finishing or cancelling it. Safe mid-tick. */
|
|
5436
|
-
remove(a) {
|
|
5437
|
-
this.animations.delete(a);
|
|
5438
|
-
}
|
|
5439
|
-
/**
|
|
5440
|
-
* Advance all animations to `now`. Completed animations are removed. Returns
|
|
5441
|
-
* true if any animation ran this frame (so the caller marks the frame dirty).
|
|
5442
|
-
*
|
|
5443
|
-
* Iterates a snapshot so an `onDone` that mutates the set (via update/destroy)
|
|
5444
|
-
* can't corrupt the loop.
|
|
5445
|
-
*/
|
|
5446
|
-
tick(now) {
|
|
5447
|
-
if (this.animations.size === 0) return false;
|
|
5448
|
-
const snapshot = [...this.animations];
|
|
5449
|
-
let ran = false;
|
|
5450
|
-
for (const a of snapshot) {
|
|
5451
|
-
if (!this.animations.has(a)) continue;
|
|
5452
|
-
ran = true;
|
|
5453
|
-
const running = a.tick(now);
|
|
5454
|
-
if (!running) this.animations.delete(a);
|
|
5455
|
-
}
|
|
5456
|
-
return ran;
|
|
5457
|
-
}
|
|
5458
|
-
/** True while any animation is active (drives rAF re-arming). */
|
|
5459
|
-
get active() {
|
|
5460
|
-
return this.animations.size > 0;
|
|
5461
|
-
}
|
|
5462
|
-
/** Cancel every animation (no final state, no onDone). Used on teardown. */
|
|
5463
|
-
cancelAll() {
|
|
5464
|
-
const snapshot = [...this.animations];
|
|
5465
|
-
this.animations.clear();
|
|
5466
|
-
for (const a of snapshot) a.cancel();
|
|
5467
|
-
}
|
|
5468
|
-
/** Finish every animation (snap to final, fire onDone). Used before update(). */
|
|
5469
|
-
finishAll() {
|
|
5470
|
-
const snapshot = [...this.animations];
|
|
5471
|
-
this.animations.clear();
|
|
5472
|
-
for (const a of snapshot) a.finish();
|
|
5473
|
-
}
|
|
5474
|
-
};
|
|
5475
|
-
|
|
5476
|
-
// src/spatial-index.ts
|
|
5477
|
-
import { quadtree } from "d3-quadtree";
|
|
5478
|
-
var SpatialIndex = class {
|
|
5479
|
-
tree = null;
|
|
5480
|
-
nodes = [];
|
|
5481
|
-
maxRadius = 0;
|
|
5482
|
-
generation = 0;
|
|
5483
|
-
/** Rebuild the quadtree from the current set of positioned nodes. */
|
|
5484
|
-
rebuild(nodes) {
|
|
5485
|
-
this.nodes = nodes;
|
|
5486
|
-
this.maxRadius = 0;
|
|
5487
|
-
for (const n of nodes) {
|
|
5488
|
-
if (n.radius > this.maxRadius) this.maxRadius = n.radius;
|
|
5489
|
-
}
|
|
5490
|
-
this.tree = quadtree().x((d) => d.x).y((d) => d.y).addAll(nodes);
|
|
5491
|
-
this.generation++;
|
|
5492
|
-
}
|
|
5493
|
-
/** Current generation counter. Increments on each rebuild. */
|
|
5494
|
-
getGeneration() {
|
|
5495
|
-
return this.generation;
|
|
5496
|
-
}
|
|
5497
|
-
/**
|
|
5498
|
-
* Find the nearest node to (x, y) within maxDistance.
|
|
5499
|
-
* Accounts for node radius: a hit occurs if the point is inside
|
|
5500
|
-
* the node circle (distance to center < node.radius), or if the
|
|
5501
|
-
* edge-to-edge distance is within maxDistance.
|
|
5502
|
-
*/
|
|
5503
|
-
findNearest(x, y, maxDistance = Infinity) {
|
|
5504
|
-
if (!this.tree || this.nodes.length === 0) return null;
|
|
5505
|
-
const searchRadius = maxDistance + this.maxRadius;
|
|
5506
|
-
let best = null;
|
|
5507
|
-
let bestEffectiveDist = maxDistance + this.maxRadius + 1;
|
|
5508
|
-
this.tree.visit((node, x0, y0, x1, y1) => {
|
|
5509
|
-
const closestX = Math.max(x0, Math.min(x, x1));
|
|
5510
|
-
const closestY = Math.max(y0, Math.min(y, y1));
|
|
5511
|
-
const quadDist = Math.hypot(closestX - x, closestY - y);
|
|
5512
|
-
if (quadDist > searchRadius) return true;
|
|
5513
|
-
if (!node.length) {
|
|
5514
|
-
let current = node;
|
|
5515
|
-
do {
|
|
5516
|
-
const d = current.data;
|
|
5517
|
-
if (d) {
|
|
5518
|
-
const dist = Math.hypot(d.x - x, d.y - y);
|
|
5519
|
-
const effectiveDist = Math.max(0, dist - d.radius);
|
|
5520
|
-
if (effectiveDist <= maxDistance && effectiveDist < bestEffectiveDist) {
|
|
5521
|
-
bestEffectiveDist = effectiveDist;
|
|
5522
|
-
best = d;
|
|
5523
|
-
}
|
|
5524
|
-
}
|
|
5525
|
-
} while (current = current.next);
|
|
5526
|
-
}
|
|
5527
|
-
return false;
|
|
5528
|
-
});
|
|
5529
|
-
return best;
|
|
5530
|
-
}
|
|
5531
|
-
/** Find all nodes whose centers fall within the given rectangle. */
|
|
5532
|
-
findInRect(x1, y1, x2, y2) {
|
|
5533
|
-
if (!this.tree) return [];
|
|
5534
|
-
const minX = Math.min(x1, x2);
|
|
5535
|
-
const minY = Math.min(y1, y2);
|
|
5536
|
-
const maxX = Math.max(x1, x2);
|
|
5537
|
-
const maxY = Math.max(y1, y2);
|
|
5538
|
-
const results = [];
|
|
5539
|
-
this.tree.visit((node, qx0, qy0, qx1, qy1) => {
|
|
5540
|
-
if (qx0 > maxX || qx1 < minX || qy0 > maxY || qy1 < minY) {
|
|
5541
|
-
return true;
|
|
5542
|
-
}
|
|
5543
|
-
if (!node.length) {
|
|
5544
|
-
let current = node;
|
|
5545
|
-
do {
|
|
5546
|
-
const d = current.data;
|
|
5547
|
-
if (d && d.x >= minX && d.x <= maxX && d.y >= minY && d.y <= maxY) {
|
|
5548
|
-
results.push(d);
|
|
5549
|
-
}
|
|
5550
|
-
} while (current = current.next);
|
|
5551
|
-
}
|
|
5552
|
-
return false;
|
|
5553
|
-
});
|
|
5554
|
-
return results;
|
|
5555
|
-
}
|
|
5556
|
-
};
|
|
5557
|
-
|
|
5558
|
-
// src/motion/tween.ts
|
|
5559
|
-
function resolveEase(ease) {
|
|
5560
|
-
return ease === "snappy" ? cubicOut : cubicInOut;
|
|
5561
|
-
}
|
|
5562
|
-
function prefersReducedMotion() {
|
|
5563
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
5564
|
-
try {
|
|
5565
|
-
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
5566
|
-
} catch {
|
|
5567
|
-
return false;
|
|
5568
|
-
}
|
|
5569
|
-
}
|
|
5570
|
-
function createTween(opts) {
|
|
5571
|
-
const { duration, ease, apply, onDone } = opts;
|
|
5572
|
-
let startTime = null;
|
|
5573
|
-
let finished = false;
|
|
5574
|
-
function settleAt(t) {
|
|
5575
|
-
apply(ease(t));
|
|
5576
|
-
}
|
|
5577
|
-
return {
|
|
5578
|
-
tick(now) {
|
|
5579
|
-
if (finished) return false;
|
|
5580
|
-
if (startTime === null) startTime = now;
|
|
5581
|
-
const elapsed = now - startTime;
|
|
5582
|
-
const raw = duration <= 0 ? 1 : Math.min(1, elapsed / duration);
|
|
5583
|
-
settleAt(raw);
|
|
5584
|
-
if (raw >= 1) {
|
|
5585
|
-
finished = true;
|
|
5586
|
-
onDone?.();
|
|
5587
|
-
return false;
|
|
5588
|
-
}
|
|
5589
|
-
return true;
|
|
5590
|
-
},
|
|
5591
|
-
finish() {
|
|
5592
|
-
if (finished) return;
|
|
5593
|
-
finished = true;
|
|
5594
|
-
settleAt(1);
|
|
5595
|
-
onDone?.();
|
|
5596
|
-
},
|
|
5597
|
-
cancel() {
|
|
5598
|
-
finished = true;
|
|
5599
|
-
}
|
|
5600
|
-
};
|
|
5601
|
-
}
|
|
5602
|
-
|
|
5603
5267
|
// src/scatter-canvas/entrance.ts
|
|
5604
5268
|
var MAX_TOTAL_STAGGER_MS = 300;
|
|
5605
5269
|
var POINT_DURATION_FRACTION = 0.4;
|
|
@@ -6036,64 +5700,11 @@ function createSeriesSearch(options) {
|
|
|
6036
5700
|
};
|
|
6037
5701
|
}
|
|
6038
5702
|
|
|
6039
|
-
// src/theme-tokens.ts
|
|
6040
|
-
import { adaptForLightLineStroke, cssTokenDefault } from "@opendata-ai/openchart-core";
|
|
6041
|
-
function resolvedSurface(theme) {
|
|
6042
|
-
return theme.colors.neutral.surface;
|
|
6043
|
-
}
|
|
6044
|
-
function stampThemeProperties(el, theme) {
|
|
6045
|
-
const accent = theme.colors.categorical[0] ?? cssTokenDefault("--oc-accent", "light");
|
|
6046
|
-
const bg = resolvedSurface(theme);
|
|
6047
|
-
const n = theme.colors.neutral;
|
|
6048
|
-
const props = [
|
|
6049
|
-
["--oc-font-family", theme.fonts.family],
|
|
6050
|
-
["--oc-font-mono", theme.fonts.mono],
|
|
6051
|
-
["--oc-title-size", `${theme.chrome.title.fontSize}px`],
|
|
6052
|
-
["--oc-title-weight", `${theme.chrome.title.fontWeight}`],
|
|
6053
|
-
["--oc-subtitle-size", `${theme.chrome.subtitle.fontSize}px`],
|
|
6054
|
-
["--oc-subtitle-weight", `${theme.chrome.subtitle.fontWeight}`],
|
|
6055
|
-
["--oc-source-size", `${theme.chrome.source.fontSize}px`],
|
|
6056
|
-
["--oc-source-weight", `${theme.chrome.source.fontWeight}`],
|
|
6057
|
-
["--oc-body-size", `${theme.fonts.sizes.body}px`],
|
|
6058
|
-
["--oc-eyebrow-size", `${theme.chrome.eyebrow.fontSize}px`],
|
|
6059
|
-
["--oc-eyebrow-weight", `${theme.chrome.eyebrow.fontWeight}`],
|
|
6060
|
-
["--oc-bg", bg],
|
|
6061
|
-
["--oc-text", theme.colors.text],
|
|
6062
|
-
["--oc-text-muted", theme.colors.axis],
|
|
6063
|
-
// Secondary grays are derived from the theme's own text/background pair
|
|
6064
|
-
// (ResolvedTheme.colors.neutral), so a warm or cool theme gets warm or
|
|
6065
|
-
// cool grays instead of zinc. One direction only: theme -> CSS.
|
|
6066
|
-
["--oc-text-secondary", n.secondary],
|
|
6067
|
-
["--oc-text-faint", n.faint],
|
|
6068
|
-
["--oc-border", n.border],
|
|
6069
|
-
["--oc-gray-100", n[100]],
|
|
6070
|
-
["--oc-gray-200", n[200]],
|
|
6071
|
-
["--oc-gray-300", n[300]],
|
|
6072
|
-
["--oc-gray-400", n[400]],
|
|
6073
|
-
["--oc-gray-600", n[600]],
|
|
6074
|
-
["--oc-gray-800", n[800]],
|
|
6075
|
-
["--oc-gridline", theme.colors.gridline],
|
|
6076
|
-
// --oc-axis is the hairline the axis line is drawn with, not the ink its
|
|
6077
|
-
// tick labels take (that is --oc-text-muted, above).
|
|
6078
|
-
["--oc-axis", theme.colors.hairline],
|
|
6079
|
-
["--oc-border-radius", `${theme.borderRadius}px`],
|
|
6080
|
-
["--oc-accent", accent],
|
|
6081
|
-
["--oc-accent-strong", adaptForLightLineStroke(accent)],
|
|
6082
|
-
["--oc-positive", theme.colors.positive],
|
|
6083
|
-
["--oc-negative", theme.colors.negative],
|
|
6084
|
-
["--oc-space-2", `${theme.spacing.chromeGap * 2}px`],
|
|
6085
|
-
["--oc-space-4", `${theme.spacing.padding}px`]
|
|
6086
|
-
];
|
|
6087
|
-
for (const [name, value] of props) {
|
|
6088
|
-
el.style.setProperty(name, value);
|
|
6089
|
-
}
|
|
6090
|
-
}
|
|
6091
|
-
|
|
6092
5703
|
// src/mount.ts
|
|
6093
5704
|
var FALLBACK_HEIGHT = 400;
|
|
6094
5705
|
var EDITABLE_HOVER_CSS = `
|
|
6095
5706
|
.oc-editable-hover {
|
|
6096
|
-
outline: 1.5px solid ${
|
|
5707
|
+
outline: 1.5px solid ${cssTokenDefault("--oc-editable-hover", "light")};
|
|
6097
5708
|
outline-offset: 2px;
|
|
6098
5709
|
border-radius: 2px;
|
|
6099
5710
|
}
|
|
@@ -7411,7 +7022,7 @@ function renderBorders(parent, borders) {
|
|
|
7411
7022
|
}
|
|
7412
7023
|
parent.appendChild(g);
|
|
7413
7024
|
}
|
|
7414
|
-
function renderFeatures(parent, features, animation, staggerBudget = 0, focusIds) {
|
|
7025
|
+
function renderFeatures(parent, features, animation, staggerBudget = 0, focusIds, patternMap) {
|
|
7415
7026
|
const g = createSVGElement2("g");
|
|
7416
7027
|
g.setAttribute("class", "oc-map-features");
|
|
7417
7028
|
g.setAttribute("role", "list");
|
|
@@ -7440,13 +7051,17 @@ function renderFeatures(parent, features, animation, staggerBudget = 0, focusIds
|
|
|
7440
7051
|
const path = createSVGElement2("path");
|
|
7441
7052
|
path.setAttribute("class", "oc-map-feature");
|
|
7442
7053
|
path.setAttribute("role", "listitem");
|
|
7054
|
+
const fill = feature.pattern && patternMap ? resolvePatternFill(feature.pattern, patternMap) : feature.fill;
|
|
7443
7055
|
setAttrs2(path, {
|
|
7444
7056
|
d: feature.path,
|
|
7445
|
-
fill
|
|
7057
|
+
fill,
|
|
7446
7058
|
stroke: feature.stroke,
|
|
7447
7059
|
"stroke-width": feature.strokeWidth
|
|
7448
7060
|
});
|
|
7449
7061
|
path.setAttribute("data-feature-id", String(feature.id));
|
|
7062
|
+
if (feature.noData) {
|
|
7063
|
+
path.setAttribute("data-nodata", "true");
|
|
7064
|
+
}
|
|
7450
7065
|
path.setAttribute("data-key", String(feature.id));
|
|
7451
7066
|
if (feature.binIndex !== void 0) {
|
|
7452
7067
|
path.setAttribute("data-bin-index", String(feature.binIndex));
|
|
@@ -7466,7 +7081,7 @@ function renderFeatures(parent, features, animation, staggerBudget = 0, focusIds
|
|
|
7466
7081
|
const idx = feature.animationIndex ?? i;
|
|
7467
7082
|
path.setAttribute("data-animation-index", String(idx));
|
|
7468
7083
|
s.setProperty("--oc-mark-index", String(idx));
|
|
7469
|
-
s.setProperty("--oc-feature-fill",
|
|
7084
|
+
s.setProperty("--oc-feature-fill", fill);
|
|
7470
7085
|
if (dimmed) {
|
|
7471
7086
|
s.setProperty("--oc-feature-target-opacity", String(FOCUS_DIM_OPACITY));
|
|
7472
7087
|
}
|
|
@@ -7539,6 +7154,8 @@ function renderMapSVG(layout, opts) {
|
|
|
7539
7154
|
}
|
|
7540
7155
|
const defs = createSVGElement2("defs");
|
|
7541
7156
|
svg.appendChild(defs);
|
|
7157
|
+
const noDataSwatch = layout.continuousLegend?.noData ?? layout.categoricalLegend?.noData;
|
|
7158
|
+
const patternMap = buildPatternDefs(noDataSwatch ? [...features, noDataSwatch] : features, defs);
|
|
7542
7159
|
const mapGroup = createSVGElement2("g");
|
|
7543
7160
|
mapGroup.setAttribute("class", "oc-map-group");
|
|
7544
7161
|
mapGroup.setAttribute("transform", `translate(${layout.area.x},${layout.area.y})`);
|
|
@@ -7551,7 +7168,8 @@ function renderMapSVG(layout, opts) {
|
|
|
7551
7168
|
features,
|
|
7552
7169
|
animate ? animation : void 0,
|
|
7553
7170
|
mapStaggerBudget,
|
|
7554
|
-
focusIdSet
|
|
7171
|
+
focusIdSet,
|
|
7172
|
+
patternMap
|
|
7555
7173
|
);
|
|
7556
7174
|
renderBorders(cameraGroup, borders);
|
|
7557
7175
|
if (animate && animation?.enter && layout.pointMarks.length > 1) {
|
|
@@ -7564,9 +7182,23 @@ function renderMapSVG(layout, opts) {
|
|
|
7564
7182
|
svg.appendChild(mapGroup);
|
|
7565
7183
|
renderChrome(svg, layout);
|
|
7566
7184
|
if (layout.continuousLegend) {
|
|
7567
|
-
|
|
7185
|
+
const contNoData = layout.continuousLegend.noData;
|
|
7186
|
+
renderLegend(
|
|
7187
|
+
svg,
|
|
7188
|
+
contNoData?.pattern ? {
|
|
7189
|
+
...layout.continuousLegend,
|
|
7190
|
+
noData: { ...contNoData, fill: resolvePatternFill(contNoData.pattern, patternMap) }
|
|
7191
|
+
} : layout.continuousLegend
|
|
7192
|
+
);
|
|
7568
7193
|
} else if (layout.categoricalLegend) {
|
|
7569
|
-
|
|
7194
|
+
const catNoData = layout.categoricalLegend.noData;
|
|
7195
|
+
renderLegend(
|
|
7196
|
+
svg,
|
|
7197
|
+
catNoData?.pattern ? {
|
|
7198
|
+
...layout.categoricalLegend,
|
|
7199
|
+
noData: { ...catNoData, fill: resolvePatternFill(catNoData.pattern, patternMap) }
|
|
7200
|
+
} : layout.categoricalLegend
|
|
7201
|
+
);
|
|
7570
7202
|
}
|
|
7571
7203
|
const ptLegend = layout.pointCategoricalLegend ?? layout.pointContinuousLegend;
|
|
7572
7204
|
if (ptLegend) {
|
|
@@ -8307,21 +7939,10 @@ export {
|
|
|
8307
7939
|
createMeasureText,
|
|
8308
7940
|
resolveFontFamily,
|
|
8309
7941
|
scheduleFontReload,
|
|
8310
|
-
observeResize,
|
|
8311
|
-
resolveDarkMode,
|
|
8312
|
-
createTooltipManager,
|
|
8313
7942
|
VECTOR_EXPORT_MAX_POINTS,
|
|
8314
7943
|
materializeCanvasModeSVG,
|
|
8315
7944
|
applySrOnlyStyles,
|
|
8316
|
-
AnimationScheduler,
|
|
8317
|
-
SpatialIndex,
|
|
8318
|
-
clamp01,
|
|
8319
|
-
lerp,
|
|
8320
|
-
resolveEase,
|
|
8321
|
-
prefersReducedMotion,
|
|
8322
|
-
createTween,
|
|
8323
7945
|
createTextEditOverlay,
|
|
8324
|
-
resolvedSurface,
|
|
8325
7946
|
DEFAULT_UPDATE_MAX_MARKS,
|
|
8326
7947
|
CANVAS_DEFAULT_UPDATE_MAX_MARKS,
|
|
8327
7948
|
canTransitionSpecShape,
|
|
@@ -8329,7 +7950,7 @@ export {
|
|
|
8329
7950
|
createChart,
|
|
8330
7951
|
easingFns,
|
|
8331
7952
|
storyMotion,
|
|
8332
|
-
createTween2,
|
|
7953
|
+
createTween2 as createTween,
|
|
8333
7954
|
FULL_VIEW,
|
|
8334
7955
|
fitTarget,
|
|
8335
7956
|
interpolateCamera,
|
|
@@ -8340,4 +7961,4 @@ export {
|
|
|
8340
7961
|
scrubCamera,
|
|
8341
7962
|
createGeoMap
|
|
8342
7963
|
};
|
|
8343
|
-
//# sourceMappingURL=chunk-
|
|
7964
|
+
//# sourceMappingURL=chunk-5KV3ZBBL.js.map
|