@vielzeug/prism 26.10.14 → 26.10.16
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/_dev.cjs.map +1 -1
- package/dist/_dev.js +6 -1
- package/dist/_dev.js.map +1 -1
- package/dist/_tappers.cjs.map +1 -1
- package/dist/_tappers.js +25 -1
- package/dist/_tappers.js.map +1 -1
- package/dist/animation/easing.cjs.map +1 -1
- package/dist/animation/easing.js +15 -1
- package/dist/animation/easing.js.map +1 -1
- package/dist/animation/motion.cjs.map +1 -1
- package/dist/animation/motion.js +15 -1
- package/dist/animation/motion.js.map +1 -1
- package/dist/animation/reveal.cjs.map +1 -1
- package/dist/animation/reveal.js +97 -1
- package/dist/animation/reveal.js.map +1 -1
- package/dist/animation/transition.cjs.map +1 -1
- package/dist/animation/transition.js +39 -1
- package/dist/animation/transition.js.map +1 -1
- package/dist/animation/tween.cjs.map +1 -1
- package/dist/animation/tween.js +7 -1
- package/dist/animation/tween.js.map +1 -1
- package/dist/axes/axis.cjs.map +1 -1
- package/dist/axes/axis.js +76 -1
- package/dist/axes/axis.js.map +1 -1
- package/dist/axes/grid.cjs.map +1 -1
- package/dist/axes/grid.js +29 -1
- package/dist/axes/grid.js.map +1 -1
- package/dist/axes/scale-utils.cjs.map +1 -1
- package/dist/axes/scale-utils.js +10 -1
- package/dist/axes/scale-utils.js.map +1 -1
- package/dist/charts/area/area-chart.cjs.map +1 -1
- package/dist/charts/area/area-chart.js +71 -1
- package/dist/charts/area/area-chart.js.map +1 -1
- package/dist/charts/area/area-renderer.cjs.map +1 -1
- package/dist/charts/area/area-renderer.js +128 -1
- package/dist/charts/area/area-renderer.js.map +1 -1
- package/dist/charts/bar/bar-chart.cjs.map +1 -1
- package/dist/charts/bar/bar-chart.js +228 -1
- package/dist/charts/bar/bar-chart.js.map +1 -1
- package/dist/charts/bar/bar-hit-test.cjs.map +1 -1
- package/dist/charts/bar/bar-hit-test.js +25 -1
- package/dist/charts/bar/bar-hit-test.js.map +1 -1
- package/dist/charts/bar/bar-renderer.cjs.map +1 -1
- package/dist/charts/bar/bar-renderer.js +139 -1
- package/dist/charts/bar/bar-renderer.js.map +1 -1
- package/dist/charts/line/line-chart.cjs.map +1 -1
- package/dist/charts/line/line-chart.js +93 -1
- package/dist/charts/line/line-chart.js.map +1 -1
- package/dist/charts/line/line-renderer.cjs.map +1 -1
- package/dist/charts/line/line-renderer.js +143 -1
- package/dist/charts/line/line-renderer.js.map +1 -1
- package/dist/charts/pie/pie-chart.cjs +1 -1
- package/dist/charts/pie/pie-chart.cjs.map +1 -1
- package/dist/charts/pie/pie-chart.js +207 -1
- package/dist/charts/pie/pie-chart.js.map +1 -1
- package/dist/charts/pie/pie-renderer.cjs.map +1 -1
- package/dist/charts/pie/pie-renderer.js +68 -1
- package/dist/charts/pie/pie-renderer.js.map +1 -1
- package/dist/charts/radar/radar-chart.cjs +1 -1
- package/dist/charts/radar/radar-chart.cjs.map +1 -1
- package/dist/charts/radar/radar-chart.js +281 -1
- package/dist/charts/radar/radar-chart.js.map +1 -1
- package/dist/charts/radar/radar-geometry.cjs.map +1 -1
- package/dist/charts/radar/radar-geometry.js +69 -1
- package/dist/charts/radar/radar-geometry.js.map +1 -1
- package/dist/charts/scatter/scatter-chart.cjs.map +1 -1
- package/dist/charts/scatter/scatter-chart.js +69 -1
- package/dist/charts/scatter/scatter-chart.js.map +1 -1
- package/dist/charts/scatter/scatter-renderer.cjs.map +1 -1
- package/dist/charts/scatter/scatter-renderer.js +57 -1
- package/dist/charts/scatter/scatter-renderer.js.map +1 -1
- package/dist/charts/sparkline/sparkline.cjs +1 -1
- package/dist/charts/sparkline/sparkline.cjs.map +1 -1
- package/dist/charts/sparkline/sparkline.js +251 -1
- package/dist/charts/sparkline/sparkline.js.map +1 -1
- package/dist/core/cartesian-model.cjs +1 -1
- package/dist/core/cartesian-model.cjs.map +1 -1
- package/dist/core/cartesian-model.js +26 -1
- package/dist/core/cartesian-model.js.map +1 -1
- package/dist/core/cartesian-scales.cjs.map +1 -1
- package/dist/core/cartesian-scales.js +38 -1
- package/dist/core/cartesian-scales.js.map +1 -1
- package/dist/core/chart-base.cjs.map +1 -1
- package/dist/core/chart-base.js +62 -1
- package/dist/core/chart-base.js.map +1 -1
- package/dist/core/chart-scaffold.cjs.map +1 -1
- package/dist/core/chart-scaffold.js +103 -1
- package/dist/core/chart-scaffold.js.map +1 -1
- package/dist/core/datum-style.cjs +1 -1
- package/dist/core/datum-style.cjs.map +1 -1
- package/dist/core/datum-style.js +22 -1
- package/dist/core/datum-style.js.map +1 -1
- package/dist/core/ids.cjs.map +1 -1
- package/dist/core/ids.js +8 -1
- package/dist/core/ids.js.map +1 -1
- package/dist/core/layout.cjs.map +1 -1
- package/dist/core/layout.js +22 -1
- package/dist/core/layout.js.map +1 -1
- package/dist/core/polar.cjs.map +1 -1
- package/dist/core/polar.js +13 -1
- package/dist/core/polar.js.map +1 -1
- package/dist/core/responsive.cjs.map +1 -1
- package/dist/core/responsive.js +20 -1
- package/dist/core/responsive.js.map +1 -1
- package/dist/core/series-id.cjs.map +1 -1
- package/dist/core/series-id.js +7 -1
- package/dist/core/series-id.js.map +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.js +9 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.js +13 -1
- package/dist/interaction/announcer.cjs.map +1 -1
- package/dist/interaction/announcer.js +25 -1
- package/dist/interaction/announcer.js.map +1 -1
- package/dist/interaction/crosshair.cjs.map +1 -1
- package/dist/interaction/crosshair.js +37 -1
- package/dist/interaction/crosshair.js.map +1 -1
- package/dist/interaction/events.cjs.map +1 -1
- package/dist/interaction/events.js +11 -1
- package/dist/interaction/events.js.map +1 -1
- package/dist/interaction/legend.cjs.map +1 -1
- package/dist/interaction/legend.js +31 -1
- package/dist/interaction/legend.js.map +1 -1
- package/dist/interaction/scatter-interaction.cjs.map +1 -1
- package/dist/interaction/scatter-interaction.js +105 -1
- package/dist/interaction/scatter-interaction.js.map +1 -1
- package/dist/interaction/series-interaction.cjs.map +1 -1
- package/dist/interaction/series-interaction.js +163 -1
- package/dist/interaction/series-interaction.js.map +1 -1
- package/dist/interaction/tooltip.cjs +1 -1
- package/dist/interaction/tooltip.cjs.map +1 -1
- package/dist/interaction/tooltip.js +87 -1
- package/dist/interaction/tooltip.js.map +1 -1
- package/dist/prism.cjs +1 -1
- package/dist/prism.cjs.map +1 -1
- package/dist/prism.iife.js +1 -1
- package/dist/prism.iife.js.map +1 -1
- package/dist/prism.js +2930 -1
- package/dist/prism.js.map +1 -1
- package/dist/scales/band.cjs.map +1 -1
- package/dist/scales/band.js +39 -1
- package/dist/scales/band.js.map +1 -1
- package/dist/scales/linear.cjs.map +1 -1
- package/dist/scales/linear.js +43 -1
- package/dist/scales/linear.js.map +1 -1
- package/dist/scales/time.cjs.map +1 -1
- package/dist/scales/time.js +61 -1
- package/dist/scales/time.js.map +1 -1
- package/dist/svg/element.cjs +1 -1
- package/dist/svg/element.cjs.map +1 -1
- package/dist/svg/element.js +16 -1
- package/dist/svg/element.js.map +1 -1
- package/dist/svg/path.cjs.map +1 -1
- package/dist/svg/path.js +48 -1
- package/dist/svg/path.js.map +1 -1
- package/dist/svg/text.cjs.map +1 -1
- package/dist/svg/text.js +13 -1
- package/dist/svg/text.js.map +1 -1
- package/dist/theme/index.cjs.map +1 -1
- package/dist/theme/index.js +37 -1
- package/dist/theme/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -1,2 +1,208 @@
|
|
|
1
|
-
import{createSvgElement as e,setAttributes as t
|
|
1
|
+
import { createSvgElement as e, setAttributes as t } from "../../svg/element.js";
|
|
2
|
+
import { estimateTextWidth as n } from "../../svg/text.js";
|
|
3
|
+
import { createRadialScaffold as r } from "../../core/chart-scaffold.js";
|
|
4
|
+
import { seriesColor as i } from "../../theme/index.js";
|
|
5
|
+
import { resolveEasing as a } from "../../animation/easing.js";
|
|
6
|
+
import { resolveMotion as o } from "../../animation/motion.js";
|
|
7
|
+
import { tweenNumber as s } from "../../animation/tween.js";
|
|
8
|
+
import { startTween as c } from "../../animation/transition.js";
|
|
9
|
+
import { arcCentroid as l, arcPath as u, computeArcs as d } from "./pie-renderer.js";
|
|
10
|
+
//#region src/charts/pie/pie-chart.ts
|
|
11
|
+
var f = 2 * Math.PI, p = 12;
|
|
12
|
+
function labelFits(e, t) {
|
|
13
|
+
let r = e.outerRadius - e.innerRadius, i = (e.outerRadius + e.innerRadius) / 2, a = (e.endAngle - e.startAngle - 2 * e.padAngle) * i;
|
|
14
|
+
return r >= p * 1.4 && a >= n(t, p) + 8;
|
|
15
|
+
}
|
|
16
|
+
var m = -Math.PI / 2, h = Math.PI / 2;
|
|
17
|
+
function semiAngles(e) {
|
|
18
|
+
return e === "semi" ? {
|
|
19
|
+
end: h,
|
|
20
|
+
start: m
|
|
21
|
+
} : {
|
|
22
|
+
end: f,
|
|
23
|
+
start: 0
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function createPieChart(n, f) {
|
|
27
|
+
let p = f.variant ?? "pie", m = f.padPixels ?? (p === "pie" ? 0 : 8), h = f.cornerRadius ?? (p === "pie" ? 0 : 8), g = f.data, _ = e("circle", {
|
|
28
|
+
class: "prism-pie-bg",
|
|
29
|
+
"pointer-events": "none"
|
|
30
|
+
}), v = e("g", {
|
|
31
|
+
class: "prism-pie-slices",
|
|
32
|
+
"shape-rendering": "geometricPrecision"
|
|
33
|
+
}), y = e("g", {
|
|
34
|
+
class: "prism-pie-labels",
|
|
35
|
+
"pointer-events": "none"
|
|
36
|
+
}), b = [], x = [], S = null;
|
|
37
|
+
function renderLabels(n) {
|
|
38
|
+
y.replaceChildren();
|
|
39
|
+
for (let r = 0; r < b.length; r++) {
|
|
40
|
+
let i = b[r], a = n[r];
|
|
41
|
+
if (!a?.label || !labelFits(i, a.label)) continue;
|
|
42
|
+
let { x: o, y: s } = l(i), c = e("text", { class: "prism-pie-label" });
|
|
43
|
+
t(c, {
|
|
44
|
+
"dominant-baseline": "middle",
|
|
45
|
+
fill: "var(--prism-pie-label-color, #fff)",
|
|
46
|
+
"font-family": "var(--prism-font-family, system-ui)",
|
|
47
|
+
"font-size": "var(--prism-pie-label-size, 12px)",
|
|
48
|
+
"text-anchor": "middle",
|
|
49
|
+
x: o,
|
|
50
|
+
y: s
|
|
51
|
+
}), c.textContent = a.label, y.appendChild(c);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return r(n, {
|
|
55
|
+
a11y: f.a11y,
|
|
56
|
+
legend: f.legend,
|
|
57
|
+
tooltip: f.tooltip
|
|
58
|
+
}, (r) => {
|
|
59
|
+
let { legend: C, svg: w, tooltip: T } = r, E = g.some((e) => e.value > 0);
|
|
60
|
+
C?.update(E ? g.map((e, t) => ({
|
|
61
|
+
color: e.color ?? i(t),
|
|
62
|
+
name: e.label ?? ""
|
|
63
|
+
})) : []), w.contains(_) || (w.appendChild(_), w.appendChild(v), w.appendChild(y));
|
|
64
|
+
let { height: D, width: O } = r.dimensions, k = p === "semi", A = O / 2, j = k ? D * .85 : D / 2, M = k ? Math.min(A, j) - 8 : Math.min(O, D) / 2 - 8, N = p === "pie" ? 0 : Math.round(M * .55), P = f.innerRadius === void 0 ? N : f.innerRadius, F = Math.max(P + 1, M), I = g, { end: L, start: R } = semiAngles(p);
|
|
65
|
+
for (b = d(I, A, j, F, P, R, L, m, h, (e) => i(e), !1), t(_, {
|
|
66
|
+
cx: A,
|
|
67
|
+
cy: j,
|
|
68
|
+
r: P > 0 ? P : 0
|
|
69
|
+
}), _.setAttribute("style", "fill:var(--prism-bg,#fff)"); v.children.length > b.length;) v.removeChild(v.lastChild);
|
|
70
|
+
y.replaceChildren();
|
|
71
|
+
let z = o(f.transition), B = z.duration, V = a(z.easing);
|
|
72
|
+
for (let t = 0; t < b.length; t++) {
|
|
73
|
+
let n = b[t], r = v.children[t];
|
|
74
|
+
r || (r = e("path", { class: "prism-pie-slice" }), v.appendChild(r)), r.setAttribute("fill", n.color), r.setAttribute("stroke", "none"), r.style.cursor = f.onClick || f.onHover ? "pointer" : "";
|
|
75
|
+
}
|
|
76
|
+
S?.();
|
|
77
|
+
let H = x.length === 0, U = x;
|
|
78
|
+
S = c({
|
|
79
|
+
count: 1,
|
|
80
|
+
duration: B,
|
|
81
|
+
easing: V,
|
|
82
|
+
onComplete: () => renderLabels(I),
|
|
83
|
+
onFrame: (e) => {
|
|
84
|
+
let n = e(0);
|
|
85
|
+
if (H) {
|
|
86
|
+
let e = s(R, L, n);
|
|
87
|
+
x = b.map((n, r) => {
|
|
88
|
+
let i = v.children[r];
|
|
89
|
+
if (!i) return n;
|
|
90
|
+
if (e <= n.startAngle) return t(i, { d: "" }), {
|
|
91
|
+
...n,
|
|
92
|
+
endAngle: n.startAngle
|
|
93
|
+
};
|
|
94
|
+
let a = Math.min(n.endAngle, e);
|
|
95
|
+
return t(i, { d: u({
|
|
96
|
+
...n,
|
|
97
|
+
endAngle: a
|
|
98
|
+
}) }), {
|
|
99
|
+
...n,
|
|
100
|
+
endAngle: a
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
} else x = b.map((e, r) => {
|
|
104
|
+
let i = v.children[r], a = U.at(-1), o = U[r] ?? {
|
|
105
|
+
...e,
|
|
106
|
+
endAngle: a?.endAngle ?? R,
|
|
107
|
+
startAngle: a?.endAngle ?? R
|
|
108
|
+
}, c = {
|
|
109
|
+
...e,
|
|
110
|
+
endAngle: s(o.endAngle, e.endAngle, n),
|
|
111
|
+
innerRadius: s(o.innerRadius, e.innerRadius, n),
|
|
112
|
+
outerRadius: s(o.outerRadius, e.outerRadius, n),
|
|
113
|
+
padAngle: s(o.padAngle, e.padAngle, n),
|
|
114
|
+
startAngle: s(o.startAngle, e.startAngle, n)
|
|
115
|
+
};
|
|
116
|
+
return i && t(i, { d: c.endAngle - c.startAngle <= 1e-6 ? "" : u(c) }), c;
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
signal: r.disposalSignal
|
|
120
|
+
}), T?.hide();
|
|
121
|
+
let W = b.reduce((e, t) => e + Math.max(0, t.slice.value), 0), G = -1, describe = (e) => {
|
|
122
|
+
let t = W > 0 ? Math.round(Math.max(0, e.slice.value) / W * 1e3) / 10 : 0;
|
|
123
|
+
return `${e.slice.label ?? `Slice ${e.index + 1}`}: ${e.slice.value} (${t}%)`;
|
|
124
|
+
}, setActive = (e) => {
|
|
125
|
+
G = e, v.classList.toggle("prism-pie-focused", e >= 0);
|
|
126
|
+
for (let [t, n] of [...v.children].entries()) n.classList.toggle("prism-pie-slice--active", t === e);
|
|
127
|
+
}, activate = (e, t) => {
|
|
128
|
+
let i = b[e];
|
|
129
|
+
if (!i) return;
|
|
130
|
+
setActive(e), f.onHover?.({
|
|
131
|
+
index: e,
|
|
132
|
+
originalEvent: t,
|
|
133
|
+
slice: i.slice
|
|
134
|
+
});
|
|
135
|
+
let a = describe(i);
|
|
136
|
+
if (!T) {
|
|
137
|
+
r.announcer.announce(a);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
let { x: o, y: s } = l(i), c = w.getBoundingClientRect(), u = n.getBoundingClientRect();
|
|
141
|
+
T.show(o + (c.left - u.left), s + (c.top - u.top), {
|
|
142
|
+
key: e,
|
|
143
|
+
value: i.slice.value
|
|
144
|
+
}, {
|
|
145
|
+
color: i.color,
|
|
146
|
+
data: [],
|
|
147
|
+
name: i.slice.label ?? ""
|
|
148
|
+
}, a);
|
|
149
|
+
}, deactivate = () => {
|
|
150
|
+
setActive(-1), T?.hide(), r.announcer.clear(), f.onHover?.(null);
|
|
151
|
+
}, hitAt = (e) => {
|
|
152
|
+
let t = w.getBoundingClientRect();
|
|
153
|
+
return hitTestArc(b, e.clientX - t.left, e.clientY - t.top, p);
|
|
154
|
+
}, onMouseMove = (e) => {
|
|
155
|
+
let t = hitAt(e);
|
|
156
|
+
t >= 0 ? t !== G && activate(t, e) : G >= 0 && deactivate();
|
|
157
|
+
}, onClick = (e) => {
|
|
158
|
+
if (!f.onClick) return;
|
|
159
|
+
let t = hitAt(e);
|
|
160
|
+
t >= 0 && f.onClick({
|
|
161
|
+
index: t,
|
|
162
|
+
originalEvent: e,
|
|
163
|
+
slice: b[t].slice
|
|
164
|
+
});
|
|
165
|
+
}, onKeyDown = (e) => {
|
|
166
|
+
let t = b.length;
|
|
167
|
+
if (t === 0) return;
|
|
168
|
+
let n = {
|
|
169
|
+
ArrowDown: 1,
|
|
170
|
+
ArrowLeft: -1,
|
|
171
|
+
ArrowRight: 1,
|
|
172
|
+
ArrowUp: -1
|
|
173
|
+
};
|
|
174
|
+
e.key in n ? (e.preventDefault(), activate(G < 0 ? n[e.key] > 0 ? 0 : t - 1 : (G + n[e.key] + t) % t, e)) : e.key === "Home" || e.key === "End" ? (e.preventDefault(), activate(e.key === "Home" ? 0 : t - 1, e)) : (e.key === "Enter" || e.key === " ") && G >= 0 && f.onClick ? (e.preventDefault(), f.onClick({
|
|
175
|
+
index: G,
|
|
176
|
+
originalEvent: e,
|
|
177
|
+
slice: b[G].slice
|
|
178
|
+
})) : e.key === "Escape" && deactivate();
|
|
179
|
+
};
|
|
180
|
+
return {
|
|
181
|
+
onClick,
|
|
182
|
+
onKeyDown,
|
|
183
|
+
onMouseLeave: deactivate,
|
|
184
|
+
onMouseMove
|
|
185
|
+
};
|
|
186
|
+
}, (e) => {
|
|
187
|
+
g = e;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function hitTestArc(e, t, n, r) {
|
|
191
|
+
for (let i = 0; i < e.length; i++) {
|
|
192
|
+
let a = e[i], o = t - a.centerX, s = n - a.centerY, c = Math.sqrt(o * o + s * s);
|
|
193
|
+
if (c < a.outerRadius && c >= a.innerRadius) {
|
|
194
|
+
let e = Math.atan2(o, -s);
|
|
195
|
+
if (r === "semi") {
|
|
196
|
+
if (e >= a.startAngle - 1e-9 && e <= a.endAngle + 1e-9) return i;
|
|
197
|
+
} else {
|
|
198
|
+
let t = e < 0 ? e + f : e;
|
|
199
|
+
if (t >= a.startAngle - 1e-9 && t <= a.endAngle + 1e-9) return i;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return -1;
|
|
204
|
+
}
|
|
205
|
+
//#endregion
|
|
206
|
+
export { createPieChart };
|
|
207
|
+
|
|
2
208
|
//# sourceMappingURL=pie-chart.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pie-chart.js","names":[],"sources":["../../../src/charts/pie/pie-chart.ts"],"sourcesContent":["import { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { startTween } from '../../animation/transition';\nimport { tweenNumber } from '../../animation/tween';\nimport type { ChartEventHandlers } from '../../core/chart-scaffold';\nimport { createRadialScaffold } from '../../core/chart-scaffold';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { estimateTextWidth } from '../../svg/text';\nimport { seriesColor } from '../../theme';\nimport type { ChartHandle, PieChartConfig, PieSliceConfig } from '../../types';\nimport { type Arc, arcCentroid, arcPath, computeArcs } from './pie-renderer';\n\nconst TWO_PI = 2 * Math.PI;\n/** Default `--prism-pie-label-size` in px, used to decide whether a label fits its slice. */\nconst LABEL_FONT_SIZE = 12;\n\n/** A label fits when its slice is wide enough along the centroid arc and thick enough radially. */\nfunction labelFits(arc: Arc, label: string): boolean {\n const thickness = arc.outerRadius - arc.innerRadius;\n const midRadius = (arc.outerRadius + arc.innerRadius) / 2;\n const arcLength = (arc.endAngle - arc.startAngle - 2 * arc.padAngle) * midRadius;\n\n return thickness >= LABEL_FONT_SIZE * 1.4 && arcLength >= estimateTextWidth(label, LABEL_FONT_SIZE) + 8;\n}\n\nconst SEMI_START = -Math.PI / 2; // -90° = 9-o'clock (left)\nconst SEMI_END = Math.PI / 2; // +90° = 3-o'clock (right) → true 180° half-circle\n\nfunction semiAngles(variant: PieChartConfig['variant']): { end: number; start: number } {\n return variant === 'semi' ? { end: SEMI_END, start: SEMI_START } : { end: TWO_PI, start: 0 };\n}\n\nexport function createPieChart(container: HTMLElement, config: PieChartConfig): ChartHandle<PieSliceConfig[]> {\n const variant = config.variant ?? 'pie';\n const padPixels = config.padPixels ?? (variant === 'pie' ? 0 : 8);\n const cornerRadius = config.cornerRadius ?? (variant === 'pie' ? 0 : 8);\n let data = config.data;\n\n // Pie SVG elements live directly on the SVG (not inside chartArea groups).\n // We create them once and reuse across renders.\n const bgCircle = createSvgElement('circle', { class: 'prism-pie-bg', 'pointer-events': 'none' });\n const pieGroup = createSvgElement('g', {\n class: 'prism-pie-slices',\n 'shape-rendering': 'geometricPrecision',\n });\n const labelGroup = createSvgElement('g', { class: 'prism-pie-labels', 'pointer-events': 'none' });\n\n // Current arcs shared between renderFn and event handlers via closure.\n let currentArcs: Arc[] = [];\n // The geometry actually on screen right now (mid-tween included): the update\n // morph interpolates from this, so interrupting a tween never jumps.\n let drawnArcs: Arc[] = [];\n let activeTween: (() => void) | null = null;\n\n function renderLabels(slices: PieSliceConfig[]): void {\n labelGroup.replaceChildren();\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n const slice = slices[i];\n\n if (!slice?.label || !labelFits(arc, slice.label)) continue;\n\n const { x, y } = arcCentroid(arc);\n const text = createSvgElement('text', { class: 'prism-pie-label' });\n\n setAttributes(text, {\n 'dominant-baseline': 'middle',\n fill: 'var(--prism-pie-label-color, #fff)',\n 'font-family': 'var(--prism-font-family, system-ui)',\n 'font-size': 'var(--prism-pie-label-size, 12px)',\n 'text-anchor': 'middle',\n x,\n y,\n });\n\n text.textContent = slice.label;\n labelGroup.appendChild(text);\n }\n }\n\n return createRadialScaffold(\n container,\n {\n a11y: config.a11y,\n legend: config.legend,\n tooltip: config.tooltip,\n },\n (ctx): ChartEventHandlers => {\n const { legend, svg, tooltip } = ctx;\n const hasSlices = data.some((slice) => slice.value > 0);\n legend?.update(\n hasSlices ? data.map((slice, i) => ({ color: slice.color ?? seriesColor(i), name: slice.label ?? '' })) : [],\n );\n\n // Append pie groups to SVG on first render (idempotent).\n if (!svg.contains(bgCircle)) {\n svg.appendChild(bgCircle);\n svg.appendChild(pieGroup);\n svg.appendChild(labelGroup);\n }\n\n const { height: h, width: w } = ctx.dimensions;\n const isSemi = variant === 'semi';\n const cx = w / 2;\n const cy = isSemi ? h * 0.85 : h / 2;\n const padding = 8;\n const outer = isSemi ? Math.min(cx, cy) - padding : Math.min(w, h) / 2 - padding;\n const defaultInner = variant === 'pie' ? 0 : Math.round(outer * 0.55);\n const inner = config.innerRadius !== undefined ? config.innerRadius : defaultInner;\n const outerR = Math.max(inner + 1, outer);\n\n const slices = data;\n const { end, start } = semiAngles(variant);\n\n currentArcs = computeArcs(\n slices,\n cx,\n cy,\n outerR,\n inner,\n start,\n end,\n padPixels,\n cornerRadius,\n (i) => seriesColor(i),\n false,\n );\n\n setAttributes(bgCircle, { cx, cy, r: inner > 0 ? inner : 0 });\n bgCircle.setAttribute('style', 'fill:var(--prism-bg,#fff)');\n\n while (pieGroup.children.length > currentArcs.length) pieGroup.removeChild(pieGroup.lastChild!);\n\n labelGroup.replaceChildren();\n\n const motion = resolveMotion(config.transition);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n let path = pieGroup.children[i] as SVGPathElement | undefined;\n\n if (!path) {\n path = createSvgElement('path', { class: 'prism-pie-slice' });\n pieGroup.appendChild(path);\n }\n\n path.setAttribute('fill', arc.color);\n path.setAttribute('stroke', 'none');\n path.style.cursor = config.onClick || config.onHover ? 'pointer' : '';\n }\n\n activeTween?.();\n\n // Mount sweeps the ring in once; an update morphs every slice from its\n // drawn angles to the new ones, which reads as the data changing rather\n // than the chart redrawing.\n const isMount = drawnArcs.length === 0;\n const fromArcs = drawnArcs;\n\n activeTween = startTween({\n count: 1,\n duration: dur,\n easing,\n onComplete: () => renderLabels(slices),\n onFrame: (progress) => {\n const e = progress(0);\n\n if (isMount) {\n const revealAngle = tweenNumber(start, end, e);\n\n drawnArcs = currentArcs.map((a, j) => {\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n\n if (!el) return a;\n\n if (revealAngle <= a.startAngle) {\n setAttributes(el, { d: '' });\n\n return { ...a, endAngle: a.startAngle };\n }\n\n const visibleEnd = Math.min(a.endAngle, revealAngle);\n\n setAttributes(el, { d: arcPath({ ...a, endAngle: visibleEnd }) });\n\n return { ...a, endAngle: visibleEnd };\n });\n\n return;\n }\n\n drawnArcs = currentArcs.map((to, j) => {\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n const lastDrawn = fromArcs.at(-1);\n // A slice that was not drawn before grows out of the end of the last drawn one.\n const from: Arc = fromArcs[j] ?? {\n ...to,\n endAngle: lastDrawn?.endAngle ?? start,\n startAngle: lastDrawn?.endAngle ?? start,\n };\n const morphed: Arc = {\n ...to,\n endAngle: tweenNumber(from.endAngle, to.endAngle, e),\n innerRadius: tweenNumber(from.innerRadius, to.innerRadius, e),\n outerRadius: tweenNumber(from.outerRadius, to.outerRadius, e),\n padAngle: tweenNumber(from.padAngle, to.padAngle, e),\n startAngle: tweenNumber(from.startAngle, to.startAngle, e),\n };\n\n if (!el) return morphed;\n\n setAttributes(el, {\n d: morphed.endAngle - morphed.startAngle <= 1e-6 ? '' : arcPath(morphed),\n });\n\n return morphed;\n });\n },\n signal: ctx.disposalSignal,\n });\n\n tooltip?.hide();\n\n const total = currentArcs.reduce((sum, arc) => sum + Math.max(0, arc.slice.value), 0);\n let activeIndex = -1;\n\n const describe = (arc: Arc): string => {\n const percent = total > 0 ? Math.round((Math.max(0, arc.slice.value) / total) * 1000) / 10 : 0;\n\n return `${arc.slice.label ?? `Slice ${arc.index + 1}`}: ${arc.slice.value} (${percent}%)`;\n };\n\n const setActive = (index: number): void => {\n activeIndex = index;\n pieGroup.classList.toggle('prism-pie-focused', index >= 0);\n for (const [i, el] of [...pieGroup.children].entries())\n el.classList.toggle('prism-pie-slice--active', i === index);\n };\n\n const activate = (index: number, originalEvent: Event): void => {\n const arc = currentArcs[index];\n\n if (!arc) return;\n\n setActive(index);\n config.onHover?.({ index, originalEvent, slice: arc.slice });\n\n const text = describe(arc);\n\n if (!tooltip) {\n ctx.announcer.announce(text);\n\n return;\n }\n\n const { x, y } = arcCentroid(arc);\n const svgRect = svg.getBoundingClientRect();\n const contR = container.getBoundingClientRect();\n\n tooltip.show(\n x + (svgRect.left - contR.left),\n y + (svgRect.top - contR.top),\n { key: index, value: arc.slice.value },\n { color: arc.color, data: [], name: arc.slice.label ?? '' },\n text,\n );\n };\n\n const deactivate = (): void => {\n setActive(-1);\n tooltip?.hide();\n ctx.announcer.clear();\n config.onHover?.(null);\n };\n\n const hitAt = (e: MouseEvent): number => {\n const svgRect = svg.getBoundingClientRect();\n\n return hitTestArc(currentArcs, e.clientX - svgRect.left, e.clientY - svgRect.top, variant);\n };\n\n const onMouseMove = (e: MouseEvent): void => {\n const hit = hitAt(e);\n\n if (hit >= 0) {\n if (hit !== activeIndex) activate(hit, e);\n } else if (activeIndex >= 0) {\n deactivate();\n }\n };\n\n const onClick = (e: MouseEvent): void => {\n if (!config.onClick) return;\n\n const hit = hitAt(e);\n\n if (hit >= 0) config.onClick({ index: hit, originalEvent: e, slice: currentArcs[hit].slice });\n };\n\n const onKeyDown = (e: KeyboardEvent): void => {\n const count = currentArcs.length;\n\n if (count === 0) return;\n\n const step: Record<string, number> = { ArrowDown: 1, ArrowLeft: -1, ArrowRight: 1, ArrowUp: -1 };\n\n if (e.key in step) {\n e.preventDefault();\n activate(\n activeIndex < 0 ? (step[e.key] > 0 ? 0 : count - 1) : (activeIndex + step[e.key] + count) % count,\n e,\n );\n } else if (e.key === 'Home' || e.key === 'End') {\n e.preventDefault();\n activate(e.key === 'Home' ? 0 : count - 1, e);\n } else if ((e.key === 'Enter' || e.key === ' ') && activeIndex >= 0 && config.onClick) {\n e.preventDefault();\n config.onClick({ index: activeIndex, originalEvent: e, slice: currentArcs[activeIndex].slice });\n } else if (e.key === 'Escape') {\n deactivate();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: deactivate, onMouseMove };\n },\n (next) => {\n data = next;\n },\n );\n}\n\nfunction hitTestArc(arcs: Arc[], mx: number, my: number, variant: PieChartConfig['variant']): number {\n for (let i = 0; i < arcs.length; i++) {\n const arc = arcs[i];\n const dx = mx - arc.centerX;\n const dy = my - arc.centerY;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < arc.outerRadius && dist >= arc.innerRadius) {\n const rawAngle = Math.atan2(dx, -dy);\n\n if (variant === 'semi') {\n if (rawAngle >= arc.startAngle - 1e-9 && rawAngle <= arc.endAngle + 1e-9) return i;\n } else {\n const angle = rawAngle < 0 ? rawAngle + TWO_PI : rawAngle;\n\n if (angle >= arc.startAngle - 1e-9 && angle <= arc.endAngle + 1e-9) return i;\n }\n }\n }\n\n return -1;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pie-chart.js","names":["TWO_PI","LABEL_FONT_SIZE","thickness","arc","midRadius","arcLength","estimateTextWidth","label","SEMI_START","SEMI_END","variant","config","padPixels","cornerRadius","data","bgCircle","createSvgElement","pieGroup","labelGroup","currentArcs","drawnArcs","activeTween","i","slice","slices","arcCentroid","text","setAttributes","createRadialScaffold","container","ctx","hasSlices","legend","seriesColor","svg","h","w","isSemi","cx","cy","outer","defaultInner","inner","outerR","computeArcs","start","end","motion","resolveMotion","dur","easing","resolveEasing","path","isMount","fromArcs","startTween","e","progress","revealAngle","tweenNumber","el","j","a","visibleEnd","arcPath","lastDrawn","from","to","morphed","tooltip","total","sum","activeIndex","percent","index","svgRect","contR","x","y","hit","count","step","next","arcs","dx","mx","dy","my","dist","rawAngle","angle"],"sources":["../../../src/charts/pie/pie-chart.ts"],"sourcesContent":["import { resolveEasing } from '../../animation/easing';\nimport { resolveMotion } from '../../animation/motion';\nimport { startTween } from '../../animation/transition';\nimport { tweenNumber } from '../../animation/tween';\nimport type { ChartEventHandlers } from '../../core/chart-scaffold';\nimport { createRadialScaffold } from '../../core/chart-scaffold';\nimport { createSvgElement, setAttributes } from '../../svg/element';\nimport { estimateTextWidth } from '../../svg/text';\nimport { seriesColor } from '../../theme';\nimport type { ChartHandle, PieChartConfig, PieSliceConfig } from '../../types';\nimport { type Arc, arcCentroid, arcPath, computeArcs } from './pie-renderer';\n\nconst TWO_PI = 2 * Math.PI;\n/** Default `--prism-pie-label-size` in px, used to decide whether a label fits its slice. */\nconst LABEL_FONT_SIZE = 12;\n\n/** A label fits when its slice is wide enough along the centroid arc and thick enough radially. */\nfunction labelFits(arc: Arc, label: string): boolean {\n const thickness = arc.outerRadius - arc.innerRadius;\n const midRadius = (arc.outerRadius + arc.innerRadius) / 2;\n const arcLength = (arc.endAngle - arc.startAngle - 2 * arc.padAngle) * midRadius;\n\n return thickness >= LABEL_FONT_SIZE * 1.4 && arcLength >= estimateTextWidth(label, LABEL_FONT_SIZE) + 8;\n}\n\nconst SEMI_START = -Math.PI / 2; // -90° = 9-o'clock (left)\nconst SEMI_END = Math.PI / 2; // +90° = 3-o'clock (right) → true 180° half-circle\n\nfunction semiAngles(variant: PieChartConfig['variant']): { end: number; start: number } {\n return variant === 'semi' ? { end: SEMI_END, start: SEMI_START } : { end: TWO_PI, start: 0 };\n}\n\nexport function createPieChart(container: HTMLElement, config: PieChartConfig): ChartHandle<PieSliceConfig[]> {\n const variant = config.variant ?? 'pie';\n const padPixels = config.padPixels ?? (variant === 'pie' ? 0 : 8);\n const cornerRadius = config.cornerRadius ?? (variant === 'pie' ? 0 : 8);\n let data = config.data;\n\n // Pie SVG elements live directly on the SVG (not inside chartArea groups).\n // We create them once and reuse across renders.\n const bgCircle = createSvgElement('circle', { class: 'prism-pie-bg', 'pointer-events': 'none' });\n const pieGroup = createSvgElement('g', {\n class: 'prism-pie-slices',\n 'shape-rendering': 'geometricPrecision',\n });\n const labelGroup = createSvgElement('g', { class: 'prism-pie-labels', 'pointer-events': 'none' });\n\n // Current arcs shared between renderFn and event handlers via closure.\n let currentArcs: Arc[] = [];\n // The geometry actually on screen right now (mid-tween included): the update\n // morph interpolates from this, so interrupting a tween never jumps.\n let drawnArcs: Arc[] = [];\n let activeTween: (() => void) | null = null;\n\n function renderLabels(slices: PieSliceConfig[]): void {\n labelGroup.replaceChildren();\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n const slice = slices[i];\n\n if (!slice?.label || !labelFits(arc, slice.label)) continue;\n\n const { x, y } = arcCentroid(arc);\n const text = createSvgElement('text', { class: 'prism-pie-label' });\n\n setAttributes(text, {\n 'dominant-baseline': 'middle',\n fill: 'var(--prism-pie-label-color, #fff)',\n 'font-family': 'var(--prism-font-family, system-ui)',\n 'font-size': 'var(--prism-pie-label-size, 12px)',\n 'text-anchor': 'middle',\n x,\n y,\n });\n\n text.textContent = slice.label;\n labelGroup.appendChild(text);\n }\n }\n\n return createRadialScaffold(\n container,\n {\n a11y: config.a11y,\n legend: config.legend,\n tooltip: config.tooltip,\n },\n (ctx): ChartEventHandlers => {\n const { legend, svg, tooltip } = ctx;\n const hasSlices = data.some((slice) => slice.value > 0);\n legend?.update(\n hasSlices ? data.map((slice, i) => ({ color: slice.color ?? seriesColor(i), name: slice.label ?? '' })) : [],\n );\n\n // Append pie groups to SVG on first render (idempotent).\n if (!svg.contains(bgCircle)) {\n svg.appendChild(bgCircle);\n svg.appendChild(pieGroup);\n svg.appendChild(labelGroup);\n }\n\n const { height: h, width: w } = ctx.dimensions;\n const isSemi = variant === 'semi';\n const cx = w / 2;\n const cy = isSemi ? h * 0.85 : h / 2;\n const padding = 8;\n const outer = isSemi ? Math.min(cx, cy) - padding : Math.min(w, h) / 2 - padding;\n const defaultInner = variant === 'pie' ? 0 : Math.round(outer * 0.55);\n const inner = config.innerRadius !== undefined ? config.innerRadius : defaultInner;\n const outerR = Math.max(inner + 1, outer);\n\n const slices = data;\n const { end, start } = semiAngles(variant);\n\n currentArcs = computeArcs(\n slices,\n cx,\n cy,\n outerR,\n inner,\n start,\n end,\n padPixels,\n cornerRadius,\n (i) => seriesColor(i),\n false,\n );\n\n setAttributes(bgCircle, { cx, cy, r: inner > 0 ? inner : 0 });\n bgCircle.setAttribute('style', 'fill:var(--prism-bg,#fff)');\n\n while (pieGroup.children.length > currentArcs.length) pieGroup.removeChild(pieGroup.lastChild!);\n\n labelGroup.replaceChildren();\n\n const motion = resolveMotion(config.transition);\n const dur = motion.duration;\n const easing = resolveEasing(motion.easing);\n\n for (let i = 0; i < currentArcs.length; i++) {\n const arc = currentArcs[i];\n let path = pieGroup.children[i] as SVGPathElement | undefined;\n\n if (!path) {\n path = createSvgElement('path', { class: 'prism-pie-slice' });\n pieGroup.appendChild(path);\n }\n\n path.setAttribute('fill', arc.color);\n path.setAttribute('stroke', 'none');\n path.style.cursor = config.onClick || config.onHover ? 'pointer' : '';\n }\n\n activeTween?.();\n\n // Mount sweeps the ring in once; an update morphs every slice from its\n // drawn angles to the new ones, which reads as the data changing rather\n // than the chart redrawing.\n const isMount = drawnArcs.length === 0;\n const fromArcs = drawnArcs;\n\n activeTween = startTween({\n count: 1,\n duration: dur,\n easing,\n onComplete: () => renderLabels(slices),\n onFrame: (progress) => {\n const e = progress(0);\n\n if (isMount) {\n const revealAngle = tweenNumber(start, end, e);\n\n drawnArcs = currentArcs.map((a, j) => {\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n\n if (!el) return a;\n\n if (revealAngle <= a.startAngle) {\n setAttributes(el, { d: '' });\n\n return { ...a, endAngle: a.startAngle };\n }\n\n const visibleEnd = Math.min(a.endAngle, revealAngle);\n\n setAttributes(el, { d: arcPath({ ...a, endAngle: visibleEnd }) });\n\n return { ...a, endAngle: visibleEnd };\n });\n\n return;\n }\n\n drawnArcs = currentArcs.map((to, j) => {\n const el = pieGroup.children[j] as SVGPathElement | undefined;\n const lastDrawn = fromArcs.at(-1);\n // A slice that was not drawn before grows out of the end of the last drawn one.\n const from: Arc = fromArcs[j] ?? {\n ...to,\n endAngle: lastDrawn?.endAngle ?? start,\n startAngle: lastDrawn?.endAngle ?? start,\n };\n const morphed: Arc = {\n ...to,\n endAngle: tweenNumber(from.endAngle, to.endAngle, e),\n innerRadius: tweenNumber(from.innerRadius, to.innerRadius, e),\n outerRadius: tweenNumber(from.outerRadius, to.outerRadius, e),\n padAngle: tweenNumber(from.padAngle, to.padAngle, e),\n startAngle: tweenNumber(from.startAngle, to.startAngle, e),\n };\n\n if (!el) return morphed;\n\n setAttributes(el, {\n d: morphed.endAngle - morphed.startAngle <= 1e-6 ? '' : arcPath(morphed),\n });\n\n return morphed;\n });\n },\n signal: ctx.disposalSignal,\n });\n\n tooltip?.hide();\n\n const total = currentArcs.reduce((sum, arc) => sum + Math.max(0, arc.slice.value), 0);\n let activeIndex = -1;\n\n const describe = (arc: Arc): string => {\n const percent = total > 0 ? Math.round((Math.max(0, arc.slice.value) / total) * 1000) / 10 : 0;\n\n return `${arc.slice.label ?? `Slice ${arc.index + 1}`}: ${arc.slice.value} (${percent}%)`;\n };\n\n const setActive = (index: number): void => {\n activeIndex = index;\n pieGroup.classList.toggle('prism-pie-focused', index >= 0);\n for (const [i, el] of [...pieGroup.children].entries())\n el.classList.toggle('prism-pie-slice--active', i === index);\n };\n\n const activate = (index: number, originalEvent: Event): void => {\n const arc = currentArcs[index];\n\n if (!arc) return;\n\n setActive(index);\n config.onHover?.({ index, originalEvent, slice: arc.slice });\n\n const text = describe(arc);\n\n if (!tooltip) {\n ctx.announcer.announce(text);\n\n return;\n }\n\n const { x, y } = arcCentroid(arc);\n const svgRect = svg.getBoundingClientRect();\n const contR = container.getBoundingClientRect();\n\n tooltip.show(\n x + (svgRect.left - contR.left),\n y + (svgRect.top - contR.top),\n { key: index, value: arc.slice.value },\n { color: arc.color, data: [], name: arc.slice.label ?? '' },\n text,\n );\n };\n\n const deactivate = (): void => {\n setActive(-1);\n tooltip?.hide();\n ctx.announcer.clear();\n config.onHover?.(null);\n };\n\n const hitAt = (e: MouseEvent): number => {\n const svgRect = svg.getBoundingClientRect();\n\n return hitTestArc(currentArcs, e.clientX - svgRect.left, e.clientY - svgRect.top, variant);\n };\n\n const onMouseMove = (e: MouseEvent): void => {\n const hit = hitAt(e);\n\n if (hit >= 0) {\n if (hit !== activeIndex) activate(hit, e);\n } else if (activeIndex >= 0) {\n deactivate();\n }\n };\n\n const onClick = (e: MouseEvent): void => {\n if (!config.onClick) return;\n\n const hit = hitAt(e);\n\n if (hit >= 0) config.onClick({ index: hit, originalEvent: e, slice: currentArcs[hit].slice });\n };\n\n const onKeyDown = (e: KeyboardEvent): void => {\n const count = currentArcs.length;\n\n if (count === 0) return;\n\n const step: Record<string, number> = { ArrowDown: 1, ArrowLeft: -1, ArrowRight: 1, ArrowUp: -1 };\n\n if (e.key in step) {\n e.preventDefault();\n activate(\n activeIndex < 0 ? (step[e.key] > 0 ? 0 : count - 1) : (activeIndex + step[e.key] + count) % count,\n e,\n );\n } else if (e.key === 'Home' || e.key === 'End') {\n e.preventDefault();\n activate(e.key === 'Home' ? 0 : count - 1, e);\n } else if ((e.key === 'Enter' || e.key === ' ') && activeIndex >= 0 && config.onClick) {\n e.preventDefault();\n config.onClick({ index: activeIndex, originalEvent: e, slice: currentArcs[activeIndex].slice });\n } else if (e.key === 'Escape') {\n deactivate();\n }\n };\n\n return { onClick, onKeyDown, onMouseLeave: deactivate, onMouseMove };\n },\n (next) => {\n data = next;\n },\n );\n}\n\nfunction hitTestArc(arcs: Arc[], mx: number, my: number, variant: PieChartConfig['variant']): number {\n for (let i = 0; i < arcs.length; i++) {\n const arc = arcs[i];\n const dx = mx - arc.centerX;\n const dy = my - arc.centerY;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < arc.outerRadius && dist >= arc.innerRadius) {\n const rawAngle = Math.atan2(dx, -dy);\n\n if (variant === 'semi') {\n if (rawAngle >= arc.startAngle - 1e-9 && rawAngle <= arc.endAngle + 1e-9) return i;\n } else {\n const angle = rawAngle < 0 ? rawAngle + TWO_PI : rawAngle;\n\n if (angle >= arc.startAngle - 1e-9 && angle <= arc.endAngle + 1e-9) return i;\n }\n }\n }\n\n return -1;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pie-renderer.cjs","names":[],"sources":["../../../src/charts/pie/pie-renderer.ts"],"sourcesContent":["import { polarPoint as p, polarX as px, polarY as py } from '../../core/polar';\nimport type { PieSliceConfig } from '../../types';\n\nexport interface Arc {\n capEnd: boolean;\n capStart: boolean;\n centerX: number;\n centerY: number;\n color: string;\n cornerRadius: number;\n endAngle: number;\n index: number;\n innerRadius: number;\n outerRadius: number;\n padAngle: number;\n slice: PieSliceConfig;\n startAngle: number;\n}\n\nexport function computeArcs(\n slices: PieSliceConfig[],\n cx: number,\n cy: number,\n outerRadius: number,\n innerRadius: number,\n startAngle: number,\n endAngle: number,\n padPixels: number,\n cornerRadius: number,\n defaultColors: (i: number) => string,\n capEnds = false,\n): Arc[] {\n const total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);\n\n if (total === 0) return [];\n\n const range = endAngle - startAngle;\n const halfGapAngle = outerRadius > 0 ? Math.asin(Math.min(1, padPixels / 2 / outerRadius)) : 0;\n\n let currentAngle = startAngle;\n const n = slices.length;\n\n return slices.map((slice, i) => {\n const fraction = Math.max(0, slice.value) / total;\n const sliceRange = fraction * range;\n const rawStart = currentAngle;\n const rawEnd = currentAngle + sliceRange;\n\n currentAngle += sliceRange;\n\n const padAngle = Math.min(halfGapAngle, sliceRange / 2);\n\n return {\n capEnd: capEnds && i === n - 1,\n capStart: capEnds && i === 0,\n centerX: cx,\n centerY: cy,\n color: slice.color ?? defaultColors(i),\n cornerRadius,\n endAngle: rawEnd,\n index: i,\n innerRadius,\n outerRadius,\n padAngle,\n slice,\n startAngle: rawStart,\n };\n });\n}\n\nexport function arcPath(arc: Arc): string {\n const {\n capEnd,\n capStart,\n centerX: cx,\n centerY: cy,\n cornerRadius: cr,\n endAngle,\n innerRadius,\n outerRadius,\n padAngle,\n startAngle,\n } = arc;\n\n const sweep = endAngle - startAngle;\n\n if (sweep <= 0) return '';\n\n // ── Full circle ─────────────────────────────────────────────────────────────\n if (sweep >= 2 * Math.PI - 1e-6) {\n const mid = startAngle + Math.PI;\n\n if (innerRadius <= 0) {\n return `M${p(cx, cy, outerRadius, startAngle)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, startAngle)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}`,\n `M${p(cx, cy, innerRadius, startAngle)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, mid)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, startAngle)}`,\n 'Z',\n ].join('');\n }\n\n // Cap ends don't get a padAngle inset (no adjacent slice on that side)\n const sa = capStart ? startAngle : startAngle + padAngle;\n const ea = capEnd ? endAngle : endAngle - padAngle;\n\n if (ea <= sa) return '';\n\n const paddedSweep = ea - sa;\n\n // ── No rounding ─────────────────────────────────────────────────────────────\n if (cr <= 0) {\n const large = paddedSweep > Math.PI ? 1 : 0;\n\n if (innerRadius <= 0) {\n return `M${cx},${cy}L${p(cx, cy, outerRadius, sa)}A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, sa)}`,\n `A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}`,\n `L${p(cx, cy, innerRadius, ea)}`,\n `A${innerRadius},${innerRadius},0,${large},0,${p(cx, cy, innerRadius, sa)}`,\n 'Z',\n ].join('');\n }\n\n // ── Rounded corners (or semicircle caps at open ends) ────────────────────────\n // Corner bezier pull amounts\n const outerPull = Math.min(cr / outerRadius, paddedSweep / 2);\n const innerPull = Math.min(cr / innerRadius, paddedSweep / 2);\n const radialPull = Math.min(cr, (outerRadius - innerRadius) / 2);\n const capR = (outerRadius - innerRadius) / 2; // semicircle cap radius\n\n // Shortened arc angles (for corners)\n const oS = sa + (capStart ? 0 : outerPull);\n const oE = ea - (capEnd ? 0 : outerPull);\n const iS = sa + (capStart ? 0 : innerPull);\n const iE = ea - (capEnd ? 0 : innerPull);\n\n const largeO = oE - oS > Math.PI ? 1 : 0;\n const largeI = iE - iS > Math.PI ? 1 : 0;\n\n // Unrounded corner cartesian positions (at full sa/ea, not shortened)\n const cxOs = px(cx, outerRadius, sa);\n const cyOs = py(cy, outerRadius, sa);\n const cxOe = px(cx, outerRadius, ea);\n const cyOe = py(cy, outerRadius, ea);\n const cxIs = px(cx, innerRadius, sa);\n const cyIs = py(cy, innerRadius, sa);\n const cxIe = px(cx, innerRadius, ea);\n const cyIe = py(cy, innerRadius, ea);\n\n const frac = radialPull / (outerRadius - innerRadius);\n const pOsRad = `${cxOs + (cxIs - cxOs) * frac},${cyOs + (cyIs - cyOs) * frac}`;\n const pOeRad = `${cxOe + (cxIe - cxOe) * frac},${cyOe + (cyIe - cyOe) * frac}`;\n const pIsRad = `${cxIs + (cxOs - cxIs) * frac},${cyIs + (cyOs - cyIs) * frac}`;\n const pIeRad = `${cxIe + (cxOe - cxIe) * frac},${cyIe + (cyOe - cyIe) * frac}`;\n\n const segs: string[] = [];\n\n // Start edge\n if (capStart) {\n segs.push(`M${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`M${pOsRad}`);\n segs.push(`Q${cxOs},${cyOs},${p(cx, cy, outerRadius, oS)}`);\n }\n\n // Outer arc\n segs.push(`A${outerRadius},${outerRadius},0,${largeO},1,${p(cx, cy, outerRadius, oE)}`);\n\n // End edge\n if (capEnd) {\n // Semicircle cap from outer-end → inner-end, bulging away from center (CW)\n segs.push(`A${capR},${capR},0,0,1,${p(cx, cy, innerRadius, ea)}`);\n } else {\n segs.push(`Q${cxOe},${cyOe},${pOeRad}`);\n segs.push(`L${pIeRad}`);\n segs.push(`Q${cxIe},${cyIe},${p(cx, cy, innerRadius, iE)}`);\n }\n\n // Inner arc (reversed, CCW)\n segs.push(`A${innerRadius},${innerRadius},0,${largeI},0,${p(cx, cy, innerRadius, iS)}`);\n\n // Start edge close\n if (capStart) {\n // Semicircle cap from inner-start → outer-start, bulging away from center (CCW)\n segs.push(`A${capR},${capR},0,0,0,${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`Q${cxIs},${cyIs},${pIsRad}`);\n }\n\n segs.push('Z');\n\n return segs.join('');\n}\n\nexport function arcCentroid(arc: Arc): { x: number; y: number } {\n const mid = (arc.startAngle + arc.endAngle) / 2;\n const r = (arc.outerRadius + arc.innerRadius) / 2;\n\n return {\n x: arc.centerX + r * Math.sin(mid),\n y: arc.centerY - r * Math.cos(mid),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pie-renderer.cjs","names":["p","px","py","require_polar","total","slices","s","d","range","endAngle","startAngle","halfGapAngle","outerRadius","padPixels","currentAngle","n","sliceRange","slice","rawStart","rawEnd","padAngle","capEnds","i","cx","cy","defaultColors","cr","arc","sweep","mid","innerRadius","sa","capStart","ea","capEnd","paddedSweep","large","outerPull","innerPull","radialPull","capR","oS","oE","iS","iE","largeO","largeI","cxOs","cyOs","cxOe","cyOe","cxIs","cyIs","cxIe","cyIe","frac","pOsRad","pOeRad","pIsRad","pIeRad","segs","r"],"sources":["../../../src/charts/pie/pie-renderer.ts"],"sourcesContent":["import { polarPoint as p, polarX as px, polarY as py } from '../../core/polar';\nimport type { PieSliceConfig } from '../../types';\n\nexport interface Arc {\n capEnd: boolean;\n capStart: boolean;\n centerX: number;\n centerY: number;\n color: string;\n cornerRadius: number;\n endAngle: number;\n index: number;\n innerRadius: number;\n outerRadius: number;\n padAngle: number;\n slice: PieSliceConfig;\n startAngle: number;\n}\n\nexport function computeArcs(\n slices: PieSliceConfig[],\n cx: number,\n cy: number,\n outerRadius: number,\n innerRadius: number,\n startAngle: number,\n endAngle: number,\n padPixels: number,\n cornerRadius: number,\n defaultColors: (i: number) => string,\n capEnds = false,\n): Arc[] {\n const total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);\n\n if (total === 0) return [];\n\n const range = endAngle - startAngle;\n const halfGapAngle = outerRadius > 0 ? Math.asin(Math.min(1, padPixels / 2 / outerRadius)) : 0;\n\n let currentAngle = startAngle;\n const n = slices.length;\n\n return slices.map((slice, i) => {\n const fraction = Math.max(0, slice.value) / total;\n const sliceRange = fraction * range;\n const rawStart = currentAngle;\n const rawEnd = currentAngle + sliceRange;\n\n currentAngle += sliceRange;\n\n const padAngle = Math.min(halfGapAngle, sliceRange / 2);\n\n return {\n capEnd: capEnds && i === n - 1,\n capStart: capEnds && i === 0,\n centerX: cx,\n centerY: cy,\n color: slice.color ?? defaultColors(i),\n cornerRadius,\n endAngle: rawEnd,\n index: i,\n innerRadius,\n outerRadius,\n padAngle,\n slice,\n startAngle: rawStart,\n };\n });\n}\n\nexport function arcPath(arc: Arc): string {\n const {\n capEnd,\n capStart,\n centerX: cx,\n centerY: cy,\n cornerRadius: cr,\n endAngle,\n innerRadius,\n outerRadius,\n padAngle,\n startAngle,\n } = arc;\n\n const sweep = endAngle - startAngle;\n\n if (sweep <= 0) return '';\n\n // ── Full circle ─────────────────────────────────────────────────────────────\n if (sweep >= 2 * Math.PI - 1e-6) {\n const mid = startAngle + Math.PI;\n\n if (innerRadius <= 0) {\n return `M${p(cx, cy, outerRadius, startAngle)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, startAngle)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}`,\n `M${p(cx, cy, innerRadius, startAngle)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, mid)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, startAngle)}`,\n 'Z',\n ].join('');\n }\n\n // Cap ends don't get a padAngle inset (no adjacent slice on that side)\n const sa = capStart ? startAngle : startAngle + padAngle;\n const ea = capEnd ? endAngle : endAngle - padAngle;\n\n if (ea <= sa) return '';\n\n const paddedSweep = ea - sa;\n\n // ── No rounding ─────────────────────────────────────────────────────────────\n if (cr <= 0) {\n const large = paddedSweep > Math.PI ? 1 : 0;\n\n if (innerRadius <= 0) {\n return `M${cx},${cy}L${p(cx, cy, outerRadius, sa)}A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, sa)}`,\n `A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}`,\n `L${p(cx, cy, innerRadius, ea)}`,\n `A${innerRadius},${innerRadius},0,${large},0,${p(cx, cy, innerRadius, sa)}`,\n 'Z',\n ].join('');\n }\n\n // ── Rounded corners (or semicircle caps at open ends) ────────────────────────\n // Corner bezier pull amounts\n const outerPull = Math.min(cr / outerRadius, paddedSweep / 2);\n const innerPull = Math.min(cr / innerRadius, paddedSweep / 2);\n const radialPull = Math.min(cr, (outerRadius - innerRadius) / 2);\n const capR = (outerRadius - innerRadius) / 2; // semicircle cap radius\n\n // Shortened arc angles (for corners)\n const oS = sa + (capStart ? 0 : outerPull);\n const oE = ea - (capEnd ? 0 : outerPull);\n const iS = sa + (capStart ? 0 : innerPull);\n const iE = ea - (capEnd ? 0 : innerPull);\n\n const largeO = oE - oS > Math.PI ? 1 : 0;\n const largeI = iE - iS > Math.PI ? 1 : 0;\n\n // Unrounded corner cartesian positions (at full sa/ea, not shortened)\n const cxOs = px(cx, outerRadius, sa);\n const cyOs = py(cy, outerRadius, sa);\n const cxOe = px(cx, outerRadius, ea);\n const cyOe = py(cy, outerRadius, ea);\n const cxIs = px(cx, innerRadius, sa);\n const cyIs = py(cy, innerRadius, sa);\n const cxIe = px(cx, innerRadius, ea);\n const cyIe = py(cy, innerRadius, ea);\n\n const frac = radialPull / (outerRadius - innerRadius);\n const pOsRad = `${cxOs + (cxIs - cxOs) * frac},${cyOs + (cyIs - cyOs) * frac}`;\n const pOeRad = `${cxOe + (cxIe - cxOe) * frac},${cyOe + (cyIe - cyOe) * frac}`;\n const pIsRad = `${cxIs + (cxOs - cxIs) * frac},${cyIs + (cyOs - cyIs) * frac}`;\n const pIeRad = `${cxIe + (cxOe - cxIe) * frac},${cyIe + (cyOe - cyIe) * frac}`;\n\n const segs: string[] = [];\n\n // Start edge\n if (capStart) {\n segs.push(`M${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`M${pOsRad}`);\n segs.push(`Q${cxOs},${cyOs},${p(cx, cy, outerRadius, oS)}`);\n }\n\n // Outer arc\n segs.push(`A${outerRadius},${outerRadius},0,${largeO},1,${p(cx, cy, outerRadius, oE)}`);\n\n // End edge\n if (capEnd) {\n // Semicircle cap from outer-end → inner-end, bulging away from center (CW)\n segs.push(`A${capR},${capR},0,0,1,${p(cx, cy, innerRadius, ea)}`);\n } else {\n segs.push(`Q${cxOe},${cyOe},${pOeRad}`);\n segs.push(`L${pIeRad}`);\n segs.push(`Q${cxIe},${cyIe},${p(cx, cy, innerRadius, iE)}`);\n }\n\n // Inner arc (reversed, CCW)\n segs.push(`A${innerRadius},${innerRadius},0,${largeI},0,${p(cx, cy, innerRadius, iS)}`);\n\n // Start edge close\n if (capStart) {\n // Semicircle cap from inner-start → outer-start, bulging away from center (CCW)\n segs.push(`A${capR},${capR},0,0,0,${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`Q${cxIs},${cyIs},${pIsRad}`);\n }\n\n segs.push('Z');\n\n return segs.join('');\n}\n\nexport function arcCentroid(arc: Arc): { x: number; y: number } {\n const mid = (arc.startAngle + arc.endAngle) / 2;\n const r = (arc.outerRadius + arc.innerRadius) / 2;\n\n return {\n x: arc.centerX + r * Math.sin(mid),\n y: arc.centerY - r * Math.cos(mid),\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,69 @@
|
|
|
1
|
-
import{polarPoint as e,polarX as t,polarY as n}from"../../core/polar.js";
|
|
1
|
+
import { polarPoint as e, polarX as t, polarY as n } from "../../core/polar.js";
|
|
2
|
+
//#region src/charts/pie/pie-renderer.ts
|
|
3
|
+
function computeArcs(e, t, n, r, i, a, o, s, c, l, u = !1) {
|
|
4
|
+
let d = e.reduce((e, t) => e + Math.max(0, t.value), 0);
|
|
5
|
+
if (d === 0) return [];
|
|
6
|
+
let f = o - a, p = r > 0 ? Math.asin(Math.min(1, s / 2 / r)) : 0, m = a, h = e.length;
|
|
7
|
+
return e.map((e, a) => {
|
|
8
|
+
let o = Math.max(0, e.value) / d * f, s = m, g = m + o;
|
|
9
|
+
m += o;
|
|
10
|
+
let _ = Math.min(p, o / 2);
|
|
11
|
+
return {
|
|
12
|
+
capEnd: u && a === h - 1,
|
|
13
|
+
capStart: u && a === 0,
|
|
14
|
+
centerX: t,
|
|
15
|
+
centerY: n,
|
|
16
|
+
color: e.color ?? l(a),
|
|
17
|
+
cornerRadius: c,
|
|
18
|
+
endAngle: g,
|
|
19
|
+
index: a,
|
|
20
|
+
innerRadius: i,
|
|
21
|
+
outerRadius: r,
|
|
22
|
+
padAngle: _,
|
|
23
|
+
slice: e,
|
|
24
|
+
startAngle: s
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function arcPath(r) {
|
|
29
|
+
let { capEnd: i, capStart: a, centerX: o, centerY: s, cornerRadius: c, endAngle: l, innerRadius: u, outerRadius: d, padAngle: f, startAngle: p } = r, m = l - p;
|
|
30
|
+
if (m <= 0) return "";
|
|
31
|
+
if (m >= 2 * Math.PI - 1e-6) {
|
|
32
|
+
let t = p + Math.PI;
|
|
33
|
+
return u <= 0 ? `M${e(o, s, d, p)}A${d},${d},0,1,1,${e(o, s, d, t)}A${d},${d},0,1,1,${e(o, s, d, p)}Z` : [
|
|
34
|
+
`M${e(o, s, d, p)}`,
|
|
35
|
+
`A${d},${d},0,1,1,${e(o, s, d, t)}`,
|
|
36
|
+
`A${d},${d},0,1,1,${e(o, s, d, p)}`,
|
|
37
|
+
`M${e(o, s, u, p)}`,
|
|
38
|
+
`A${u},${u},0,1,0,${e(o, s, u, t)}`,
|
|
39
|
+
`A${u},${u},0,1,0,${e(o, s, u, p)}`,
|
|
40
|
+
"Z"
|
|
41
|
+
].join("");
|
|
42
|
+
}
|
|
43
|
+
let h = a ? p : p + f, g = i ? l : l - f;
|
|
44
|
+
if (g <= h) return "";
|
|
45
|
+
let _ = g - h;
|
|
46
|
+
if (c <= 0) {
|
|
47
|
+
let t = +(_ > Math.PI);
|
|
48
|
+
return u <= 0 ? `M${o},${s}L${e(o, s, d, h)}A${d},${d},0,${t},1,${e(o, s, d, g)}Z` : [
|
|
49
|
+
`M${e(o, s, d, h)}`,
|
|
50
|
+
`A${d},${d},0,${t},1,${e(o, s, d, g)}`,
|
|
51
|
+
`L${e(o, s, u, g)}`,
|
|
52
|
+
`A${u},${u},0,${t},0,${e(o, s, u, h)}`,
|
|
53
|
+
"Z"
|
|
54
|
+
].join("");
|
|
55
|
+
}
|
|
56
|
+
let v = Math.min(c / d, _ / 2), y = Math.min(c / u, _ / 2), b = Math.min(c, (d - u) / 2), x = (d - u) / 2, S = h + (a ? 0 : v), C = g - (i ? 0 : v), w = h + (a ? 0 : y), T = g - (i ? 0 : y), E = +(C - S > Math.PI), D = +(T - w > Math.PI), O = t(o, d, h), k = n(s, d, h), A = t(o, d, g), j = n(s, d, g), M = t(o, u, h), N = n(s, u, h), P = t(o, u, g), F = n(s, u, g), I = b / (d - u), L = `${O + (M - O) * I},${k + (N - k) * I}`, R = `${A + (P - A) * I},${j + (F - j) * I}`, z = `${M + (O - M) * I},${N + (k - N) * I}`, B = `${P + (A - P) * I},${F + (j - F) * I}`, V = [];
|
|
57
|
+
return a ? V.push(`M${e(o, s, d, h)}`) : (V.push(`M${L}`), V.push(`Q${O},${k},${e(o, s, d, S)}`)), V.push(`A${d},${d},0,${E},1,${e(o, s, d, C)}`), i ? V.push(`A${x},${x},0,0,1,${e(o, s, u, g)}`) : (V.push(`Q${A},${j},${R}`), V.push(`L${B}`), V.push(`Q${P},${F},${e(o, s, u, T)}`)), V.push(`A${u},${u},0,${D},0,${e(o, s, u, w)}`), a ? V.push(`A${x},${x},0,0,0,${e(o, s, d, h)}`) : V.push(`Q${M},${N},${z}`), V.push("Z"), V.join("");
|
|
58
|
+
}
|
|
59
|
+
function arcCentroid(e) {
|
|
60
|
+
let t = (e.startAngle + e.endAngle) / 2, n = (e.outerRadius + e.innerRadius) / 2;
|
|
61
|
+
return {
|
|
62
|
+
x: e.centerX + n * Math.sin(t),
|
|
63
|
+
y: e.centerY - n * Math.cos(t)
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { arcCentroid, arcPath, computeArcs };
|
|
68
|
+
|
|
2
69
|
//# sourceMappingURL=pie-renderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pie-renderer.js","names":[],"sources":["../../../src/charts/pie/pie-renderer.ts"],"sourcesContent":["import { polarPoint as p, polarX as px, polarY as py } from '../../core/polar';\nimport type { PieSliceConfig } from '../../types';\n\nexport interface Arc {\n capEnd: boolean;\n capStart: boolean;\n centerX: number;\n centerY: number;\n color: string;\n cornerRadius: number;\n endAngle: number;\n index: number;\n innerRadius: number;\n outerRadius: number;\n padAngle: number;\n slice: PieSliceConfig;\n startAngle: number;\n}\n\nexport function computeArcs(\n slices: PieSliceConfig[],\n cx: number,\n cy: number,\n outerRadius: number,\n innerRadius: number,\n startAngle: number,\n endAngle: number,\n padPixels: number,\n cornerRadius: number,\n defaultColors: (i: number) => string,\n capEnds = false,\n): Arc[] {\n const total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);\n\n if (total === 0) return [];\n\n const range = endAngle - startAngle;\n const halfGapAngle = outerRadius > 0 ? Math.asin(Math.min(1, padPixels / 2 / outerRadius)) : 0;\n\n let currentAngle = startAngle;\n const n = slices.length;\n\n return slices.map((slice, i) => {\n const fraction = Math.max(0, slice.value) / total;\n const sliceRange = fraction * range;\n const rawStart = currentAngle;\n const rawEnd = currentAngle + sliceRange;\n\n currentAngle += sliceRange;\n\n const padAngle = Math.min(halfGapAngle, sliceRange / 2);\n\n return {\n capEnd: capEnds && i === n - 1,\n capStart: capEnds && i === 0,\n centerX: cx,\n centerY: cy,\n color: slice.color ?? defaultColors(i),\n cornerRadius,\n endAngle: rawEnd,\n index: i,\n innerRadius,\n outerRadius,\n padAngle,\n slice,\n startAngle: rawStart,\n };\n });\n}\n\nexport function arcPath(arc: Arc): string {\n const {\n capEnd,\n capStart,\n centerX: cx,\n centerY: cy,\n cornerRadius: cr,\n endAngle,\n innerRadius,\n outerRadius,\n padAngle,\n startAngle,\n } = arc;\n\n const sweep = endAngle - startAngle;\n\n if (sweep <= 0) return '';\n\n // ── Full circle ─────────────────────────────────────────────────────────────\n if (sweep >= 2 * Math.PI - 1e-6) {\n const mid = startAngle + Math.PI;\n\n if (innerRadius <= 0) {\n return `M${p(cx, cy, outerRadius, startAngle)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, startAngle)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}`,\n `M${p(cx, cy, innerRadius, startAngle)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, mid)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, startAngle)}`,\n 'Z',\n ].join('');\n }\n\n // Cap ends don't get a padAngle inset (no adjacent slice on that side)\n const sa = capStart ? startAngle : startAngle + padAngle;\n const ea = capEnd ? endAngle : endAngle - padAngle;\n\n if (ea <= sa) return '';\n\n const paddedSweep = ea - sa;\n\n // ── No rounding ─────────────────────────────────────────────────────────────\n if (cr <= 0) {\n const large = paddedSweep > Math.PI ? 1 : 0;\n\n if (innerRadius <= 0) {\n return `M${cx},${cy}L${p(cx, cy, outerRadius, sa)}A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, sa)}`,\n `A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}`,\n `L${p(cx, cy, innerRadius, ea)}`,\n `A${innerRadius},${innerRadius},0,${large},0,${p(cx, cy, innerRadius, sa)}`,\n 'Z',\n ].join('');\n }\n\n // ── Rounded corners (or semicircle caps at open ends) ────────────────────────\n // Corner bezier pull amounts\n const outerPull = Math.min(cr / outerRadius, paddedSweep / 2);\n const innerPull = Math.min(cr / innerRadius, paddedSweep / 2);\n const radialPull = Math.min(cr, (outerRadius - innerRadius) / 2);\n const capR = (outerRadius - innerRadius) / 2; // semicircle cap radius\n\n // Shortened arc angles (for corners)\n const oS = sa + (capStart ? 0 : outerPull);\n const oE = ea - (capEnd ? 0 : outerPull);\n const iS = sa + (capStart ? 0 : innerPull);\n const iE = ea - (capEnd ? 0 : innerPull);\n\n const largeO = oE - oS > Math.PI ? 1 : 0;\n const largeI = iE - iS > Math.PI ? 1 : 0;\n\n // Unrounded corner cartesian positions (at full sa/ea, not shortened)\n const cxOs = px(cx, outerRadius, sa);\n const cyOs = py(cy, outerRadius, sa);\n const cxOe = px(cx, outerRadius, ea);\n const cyOe = py(cy, outerRadius, ea);\n const cxIs = px(cx, innerRadius, sa);\n const cyIs = py(cy, innerRadius, sa);\n const cxIe = px(cx, innerRadius, ea);\n const cyIe = py(cy, innerRadius, ea);\n\n const frac = radialPull / (outerRadius - innerRadius);\n const pOsRad = `${cxOs + (cxIs - cxOs) * frac},${cyOs + (cyIs - cyOs) * frac}`;\n const pOeRad = `${cxOe + (cxIe - cxOe) * frac},${cyOe + (cyIe - cyOe) * frac}`;\n const pIsRad = `${cxIs + (cxOs - cxIs) * frac},${cyIs + (cyOs - cyIs) * frac}`;\n const pIeRad = `${cxIe + (cxOe - cxIe) * frac},${cyIe + (cyOe - cyIe) * frac}`;\n\n const segs: string[] = [];\n\n // Start edge\n if (capStart) {\n segs.push(`M${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`M${pOsRad}`);\n segs.push(`Q${cxOs},${cyOs},${p(cx, cy, outerRadius, oS)}`);\n }\n\n // Outer arc\n segs.push(`A${outerRadius},${outerRadius},0,${largeO},1,${p(cx, cy, outerRadius, oE)}`);\n\n // End edge\n if (capEnd) {\n // Semicircle cap from outer-end → inner-end, bulging away from center (CW)\n segs.push(`A${capR},${capR},0,0,1,${p(cx, cy, innerRadius, ea)}`);\n } else {\n segs.push(`Q${cxOe},${cyOe},${pOeRad}`);\n segs.push(`L${pIeRad}`);\n segs.push(`Q${cxIe},${cyIe},${p(cx, cy, innerRadius, iE)}`);\n }\n\n // Inner arc (reversed, CCW)\n segs.push(`A${innerRadius},${innerRadius},0,${largeI},0,${p(cx, cy, innerRadius, iS)}`);\n\n // Start edge close\n if (capStart) {\n // Semicircle cap from inner-start → outer-start, bulging away from center (CCW)\n segs.push(`A${capR},${capR},0,0,0,${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`Q${cxIs},${cyIs},${pIsRad}`);\n }\n\n segs.push('Z');\n\n return segs.join('');\n}\n\nexport function arcCentroid(arc: Arc): { x: number; y: number } {\n const mid = (arc.startAngle + arc.endAngle) / 2;\n const r = (arc.outerRadius + arc.innerRadius) / 2;\n\n return {\n x: arc.centerX + r * Math.sin(mid),\n y: arc.centerY - r * Math.cos(mid),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pie-renderer.js","names":["p","px","py","total","slices","s","d","range","endAngle","startAngle","halfGapAngle","outerRadius","padPixels","currentAngle","n","sliceRange","slice","rawStart","rawEnd","padAngle","capEnds","i","cx","cy","defaultColors","cr","arc","sweep","mid","innerRadius","polarPoint","sa","capStart","ea","capEnd","paddedSweep","large","outerPull","innerPull","radialPull","capR","oS","oE","iS","iE","largeO","largeI","cxOs","polarX","cyOs","polarY","cxOe","cyOe","cxIs","cyIs","cxIe","cyIe","frac","pOsRad","pOeRad","pIsRad","pIeRad","segs","r"],"sources":["../../../src/charts/pie/pie-renderer.ts"],"sourcesContent":["import { polarPoint as p, polarX as px, polarY as py } from '../../core/polar';\nimport type { PieSliceConfig } from '../../types';\n\nexport interface Arc {\n capEnd: boolean;\n capStart: boolean;\n centerX: number;\n centerY: number;\n color: string;\n cornerRadius: number;\n endAngle: number;\n index: number;\n innerRadius: number;\n outerRadius: number;\n padAngle: number;\n slice: PieSliceConfig;\n startAngle: number;\n}\n\nexport function computeArcs(\n slices: PieSliceConfig[],\n cx: number,\n cy: number,\n outerRadius: number,\n innerRadius: number,\n startAngle: number,\n endAngle: number,\n padPixels: number,\n cornerRadius: number,\n defaultColors: (i: number) => string,\n capEnds = false,\n): Arc[] {\n const total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);\n\n if (total === 0) return [];\n\n const range = endAngle - startAngle;\n const halfGapAngle = outerRadius > 0 ? Math.asin(Math.min(1, padPixels / 2 / outerRadius)) : 0;\n\n let currentAngle = startAngle;\n const n = slices.length;\n\n return slices.map((slice, i) => {\n const fraction = Math.max(0, slice.value) / total;\n const sliceRange = fraction * range;\n const rawStart = currentAngle;\n const rawEnd = currentAngle + sliceRange;\n\n currentAngle += sliceRange;\n\n const padAngle = Math.min(halfGapAngle, sliceRange / 2);\n\n return {\n capEnd: capEnds && i === n - 1,\n capStart: capEnds && i === 0,\n centerX: cx,\n centerY: cy,\n color: slice.color ?? defaultColors(i),\n cornerRadius,\n endAngle: rawEnd,\n index: i,\n innerRadius,\n outerRadius,\n padAngle,\n slice,\n startAngle: rawStart,\n };\n });\n}\n\nexport function arcPath(arc: Arc): string {\n const {\n capEnd,\n capStart,\n centerX: cx,\n centerY: cy,\n cornerRadius: cr,\n endAngle,\n innerRadius,\n outerRadius,\n padAngle,\n startAngle,\n } = arc;\n\n const sweep = endAngle - startAngle;\n\n if (sweep <= 0) return '';\n\n // ── Full circle ─────────────────────────────────────────────────────────────\n if (sweep >= 2 * Math.PI - 1e-6) {\n const mid = startAngle + Math.PI;\n\n if (innerRadius <= 0) {\n return `M${p(cx, cy, outerRadius, startAngle)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, startAngle)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, mid)}`,\n `A${outerRadius},${outerRadius},0,1,1,${p(cx, cy, outerRadius, startAngle)}`,\n `M${p(cx, cy, innerRadius, startAngle)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, mid)}`,\n `A${innerRadius},${innerRadius},0,1,0,${p(cx, cy, innerRadius, startAngle)}`,\n 'Z',\n ].join('');\n }\n\n // Cap ends don't get a padAngle inset (no adjacent slice on that side)\n const sa = capStart ? startAngle : startAngle + padAngle;\n const ea = capEnd ? endAngle : endAngle - padAngle;\n\n if (ea <= sa) return '';\n\n const paddedSweep = ea - sa;\n\n // ── No rounding ─────────────────────────────────────────────────────────────\n if (cr <= 0) {\n const large = paddedSweep > Math.PI ? 1 : 0;\n\n if (innerRadius <= 0) {\n return `M${cx},${cy}L${p(cx, cy, outerRadius, sa)}A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}Z`;\n }\n\n return [\n `M${p(cx, cy, outerRadius, sa)}`,\n `A${outerRadius},${outerRadius},0,${large},1,${p(cx, cy, outerRadius, ea)}`,\n `L${p(cx, cy, innerRadius, ea)}`,\n `A${innerRadius},${innerRadius},0,${large},0,${p(cx, cy, innerRadius, sa)}`,\n 'Z',\n ].join('');\n }\n\n // ── Rounded corners (or semicircle caps at open ends) ────────────────────────\n // Corner bezier pull amounts\n const outerPull = Math.min(cr / outerRadius, paddedSweep / 2);\n const innerPull = Math.min(cr / innerRadius, paddedSweep / 2);\n const radialPull = Math.min(cr, (outerRadius - innerRadius) / 2);\n const capR = (outerRadius - innerRadius) / 2; // semicircle cap radius\n\n // Shortened arc angles (for corners)\n const oS = sa + (capStart ? 0 : outerPull);\n const oE = ea - (capEnd ? 0 : outerPull);\n const iS = sa + (capStart ? 0 : innerPull);\n const iE = ea - (capEnd ? 0 : innerPull);\n\n const largeO = oE - oS > Math.PI ? 1 : 0;\n const largeI = iE - iS > Math.PI ? 1 : 0;\n\n // Unrounded corner cartesian positions (at full sa/ea, not shortened)\n const cxOs = px(cx, outerRadius, sa);\n const cyOs = py(cy, outerRadius, sa);\n const cxOe = px(cx, outerRadius, ea);\n const cyOe = py(cy, outerRadius, ea);\n const cxIs = px(cx, innerRadius, sa);\n const cyIs = py(cy, innerRadius, sa);\n const cxIe = px(cx, innerRadius, ea);\n const cyIe = py(cy, innerRadius, ea);\n\n const frac = radialPull / (outerRadius - innerRadius);\n const pOsRad = `${cxOs + (cxIs - cxOs) * frac},${cyOs + (cyIs - cyOs) * frac}`;\n const pOeRad = `${cxOe + (cxIe - cxOe) * frac},${cyOe + (cyIe - cyOe) * frac}`;\n const pIsRad = `${cxIs + (cxOs - cxIs) * frac},${cyIs + (cyOs - cyIs) * frac}`;\n const pIeRad = `${cxIe + (cxOe - cxIe) * frac},${cyIe + (cyOe - cyIe) * frac}`;\n\n const segs: string[] = [];\n\n // Start edge\n if (capStart) {\n segs.push(`M${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`M${pOsRad}`);\n segs.push(`Q${cxOs},${cyOs},${p(cx, cy, outerRadius, oS)}`);\n }\n\n // Outer arc\n segs.push(`A${outerRadius},${outerRadius},0,${largeO},1,${p(cx, cy, outerRadius, oE)}`);\n\n // End edge\n if (capEnd) {\n // Semicircle cap from outer-end → inner-end, bulging away from center (CW)\n segs.push(`A${capR},${capR},0,0,1,${p(cx, cy, innerRadius, ea)}`);\n } else {\n segs.push(`Q${cxOe},${cyOe},${pOeRad}`);\n segs.push(`L${pIeRad}`);\n segs.push(`Q${cxIe},${cyIe},${p(cx, cy, innerRadius, iE)}`);\n }\n\n // Inner arc (reversed, CCW)\n segs.push(`A${innerRadius},${innerRadius},0,${largeI},0,${p(cx, cy, innerRadius, iS)}`);\n\n // Start edge close\n if (capStart) {\n // Semicircle cap from inner-start → outer-start, bulging away from center (CCW)\n segs.push(`A${capR},${capR},0,0,0,${p(cx, cy, outerRadius, sa)}`);\n } else {\n segs.push(`Q${cxIs},${cyIs},${pIsRad}`);\n }\n\n segs.push('Z');\n\n return segs.join('');\n}\n\nexport function arcCentroid(arc: Arc): { x: number; y: number } {\n const mid = (arc.startAngle + arc.endAngle) / 2;\n const r = (arc.outerRadius + arc.innerRadius) / 2;\n\n return {\n x: arc.centerX + r * Math.sin(mid),\n y: arc.centerY - r * Math.cos(mid),\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../../_dev.cjs");const e=require("../../svg/element.cjs"),t=require("../../interaction/announcer.cjs"),n=require("../../interaction/tooltip.cjs"),r=require("../../core/chart-scaffold.cjs"),i=require("../../core/series-id.cjs"),a=require("../../theme/index.cjs"),o=require("../../animation/easing.cjs"),s=require("../../animation/motion.cjs"),c=require("../../animation/tween.cjs"),l=require("../../animation/transition.cjs"),u=require("../../core/ids.cjs"),d=require("../../core/polar.cjs"),f=require("./radar-geometry.cjs");var p=11,m=12,h=10,g={ArrowDown:1,ArrowLeft:-1,ArrowRight:1,ArrowUp:-1};function resolveGrid(e){return e===!1?null:{bands:!0,labels:!1,levels:4,shape:`polygon`,...typeof e==`object`?e:{}}}function createRadarChart(_,v){let{axes:y}=v,b=v.curve??`linear`,x=v.fill??`solid`,S=v.showPoints??!0,C=resolveGrid(v.grid),w=f.toRadians(v.startAngle??0),T=f.axisAngles(y.length,w),E=m+(v.showValues?h:0),D=u.uniqueId(`prism-radar`),O=v.series,k=e.createSvgElement(`g`,{class:`prism-radar`}),A=e.createSvgElement(`defs`),j=e.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-radar-grid`}),M=e.createSvgElement(`g`,{class:`prism-radar-series-group`}),N=e.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-radar-labels`});k.append(A,j,M,N);let P=[],F=null,I=-1,L={cx:0,cy:0,radius:0},datumAt=(e,t)=>e.data.find(e=>e.key===y[t].key),valuesAt=e=>O.map(t=>({datum:datumAt(t,e),series:t})),formatValue=(e,t)=>y[e].format?.(t)??String(t),describe=e=>t.describeValues(y[e].label,valuesAt(e),t=>formatValue(e,t));function draw(t){let{cx:n,cy:r,radius:i}=L;t.forEach((t,a)=>{let o=M.children[a];if(!o)return;let s=f.radarPoints(t,n,r,i,T);o.querySelector(`.prism-radar-area`)?.setAttribute(`d`,f.closedPath(s,b)),o.querySelectorAll(`.prism-radar-point`).forEach((t,n)=>{e.setAttributes(t,{cx:s[n].x,cy:s[n].y})}),o.querySelectorAll(`.prism-radar-value`).forEach((a,o)=>{let s=i*t[o]+h;e.setAttributes(a,{x:d.polarX(n,s,T[o]),y:d.polarY(r,s,T[o])})})})}function renderGrid(t){if(j.replaceChildren(),!C)return;let{cx:n,cy:r,radius:i}=L,a=Math.max(1,Math.round(C.levels)),o=Array.from({length:a},(e,t)=>f.ringPath(C.shape,n,r,i*(t+1)/a,T));if(C.bands)for(let t=a-1;t>=0;t-=2)j.appendChild(e.createSvgElement(`path`,{class:`prism-radar-band`,d:`${o[t]}${o[t-1]??``}`,"fill-rule":`evenodd`}));for(let t of o)j.appendChild(e.createSvgElement(`path`,{class:`prism-radar-ring`,d:t,fill:`none`}));T.forEach((t,a)=>{j.appendChild(e.createSvgElement(`line`,{class:`prism-radar-spoke`,"data-axis":a,x1:n,x2:d.polarX(n,i,t),y1:r,y2:d.polarY(r,i,t)}))});let[s,c]=t[0],l=t.every(([e,t])=>e===s&&t===c);if(!C.labels||!l)return;let u=T[0]+Math.PI/T.length;for(let t=1;t<=a;t++){let o=i*t/a,l=e.createSvgElement(`text`,{class:`prism-radar-level`,"dominant-baseline":`middle`,"text-anchor":`middle`,x:d.polarX(n,o,u),y:d.polarY(r,o,u)});l.textContent=formatValue(0,Math.round((s+(c-s)*t/a)*100)/100),j.appendChild(l)}}function renderLabels(){N.replaceChildren();let{cx:t,cy:n,radius:r}=L;y.forEach((i,a)=>{let{anchor:o,baseline:s}=f.labelPlacement(T[a]),c=e.createSvgElement(`text`,{class:`prism-radar-axis-label`,"dominant-baseline":s,"text-anchor":o,x:d.polarX(t,r+E,T[a]),y:d.polarY(n,r+E,T[a])});c.textContent=i.label,N.appendChild(c)})}function renderSeries(){let{cx:t,cy:n,radius:r}=L;for(A.replaceChildren();M.children.length>O.length;)M.lastChild?.remove();O.forEach((o,s)=>{let c=o.color??a.seriesColor(s),l=M.children[s];l||(l=e.createSvgElement(`g`,{class:`prism-radar-series`}),M.appendChild(l)),l.setAttribute(`data-series-id`,i.seriesDomId(o,s)),l.replaceChildren();let u=e.createSvgElement(`path`,{class:`prism-radar-area prism-radar-area--${x}`,stroke:c,"stroke-linejoin":`round`,"stroke-width":2});if(x===`gradient`){let i=`${D}-fill-${s}`,a=e.createSvgElement(`radialGradient`,{cx:t,cy:n,gradientUnits:`userSpaceOnUse`,id:i,r});for(let[t,n]of[[0,.08],[1,.55]])a.appendChild(e.createSvgElement(`stop`,{offset:t,"stop-color":c,"stop-opacity":n,style:`stop-color:${c}`}));A.appendChild(a),e.setAttributes(u,{fill:`url(#${i})`})}else e.setAttributes(u,{fill:x===`none`?`none`:c,"fill-opacity":.25});l.appendChild(u),S&&y.forEach((t,n)=>{let r=!Number.isFinite(datumAt(o,n)?.value);l.appendChild(e.createSvgElement(`circle`,{class:`prism-radar-point${r?` prism-radar-point--missing`:``}`,"data-axis":n,fill:r?`none`:c,r:3,stroke:c}))}),v.showValues&&y.forEach((t,n)=>{let r=datumAt(o,n),{anchor:i,baseline:a}=f.labelPlacement(T[n]),s=e.createSvgElement(`text`,{"aria-hidden":`true`,class:`prism-radar-value`,"dominant-baseline":a,"text-anchor":i});s.textContent=r&&Number.isFinite(r.value)?formatValue(n,r.value):``,l.appendChild(s)})})}function setActive(e){I=e;for(let t of k.querySelectorAll(`[data-axis]`)){let n=Number(t.getAttribute(`data-axis`))===e;t.classList.toggle(t.tagName===`line`?`prism-radar-spoke--active`:`prism-radar-point--active`,n)}}function animateTo(e,t){F?.();let n=e.map((e,t)=>e.map((e,n)=>P[t]?.[n]??0)),r=s.resolveMotion(v.transition,{defaultDuration:400}),i=o.resolveEasing(r.easing??`ease-out`),a=n.every((t,n)=>t.every((t,r)=>t===e[n][r]));
|
|
1
|
+
require("../../_dev.cjs");const e=require("../../svg/element.cjs"),t=require("../../interaction/announcer.cjs"),n=require("../../interaction/tooltip.cjs"),r=require("../../core/chart-scaffold.cjs"),i=require("../../core/series-id.cjs"),a=require("../../theme/index.cjs"),o=require("../../animation/easing.cjs"),s=require("../../animation/motion.cjs"),c=require("../../animation/tween.cjs"),l=require("../../animation/transition.cjs"),u=require("../../core/ids.cjs"),d=require("../../core/polar.cjs"),f=require("./radar-geometry.cjs");var p=11,m=12,h=10,g={ArrowDown:1,ArrowLeft:-1,ArrowRight:1,ArrowUp:-1};function resolveGrid(e){return e===!1?null:{bands:!0,labels:!1,levels:4,shape:`polygon`,...typeof e==`object`?e:{}}}function createRadarChart(_,v){let{axes:y}=v,b=v.curve??`linear`,x=v.fill??`solid`,S=v.showPoints??!0,C=resolveGrid(v.grid),w=f.toRadians(v.startAngle??0),T=f.axisAngles(y.length,w),E=m+(v.showValues?h:0),D=u.uniqueId(`prism-radar`),O=v.series,k=e.createSvgElement(`g`,{class:`prism-radar`}),A=e.createSvgElement(`defs`),j=e.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-radar-grid`}),M=e.createSvgElement(`g`,{class:`prism-radar-series-group`}),N=e.createSvgElement(`g`,{"aria-hidden":`true`,class:`prism-radar-labels`});k.append(A,j,M,N);let P=[],F=null,I=-1,L={cx:0,cy:0,radius:0},datumAt=(e,t)=>e.data.find(e=>e.key===y[t].key),valuesAt=e=>O.map(t=>({datum:datumAt(t,e),series:t})),formatValue=(e,t)=>y[e].format?.(t)??String(t),describe=e=>t.describeValues(y[e].label,valuesAt(e),t=>formatValue(e,t));function draw(t){let{cx:n,cy:r,radius:i}=L;t.forEach((t,a)=>{let o=M.children[a];if(!o)return;let s=f.radarPoints(t,n,r,i,T);o.querySelector(`.prism-radar-area`)?.setAttribute(`d`,f.closedPath(s,b)),o.querySelectorAll(`.prism-radar-point`).forEach((t,n)=>{e.setAttributes(t,{cx:s[n].x,cy:s[n].y})}),o.querySelectorAll(`.prism-radar-value`).forEach((a,o)=>{let s=i*t[o]+h;e.setAttributes(a,{x:d.polarX(n,s,T[o]),y:d.polarY(r,s,T[o])})})})}function renderGrid(t){if(j.replaceChildren(),!C)return;let{cx:n,cy:r,radius:i}=L,a=Math.max(1,Math.round(C.levels)),o=Array.from({length:a},(e,t)=>f.ringPath(C.shape,n,r,i*(t+1)/a,T));if(C.bands)for(let t=a-1;t>=0;t-=2)j.appendChild(e.createSvgElement(`path`,{class:`prism-radar-band`,d:`${o[t]}${o[t-1]??``}`,"fill-rule":`evenodd`}));for(let t of o)j.appendChild(e.createSvgElement(`path`,{class:`prism-radar-ring`,d:t,fill:`none`}));T.forEach((t,a)=>{j.appendChild(e.createSvgElement(`line`,{class:`prism-radar-spoke`,"data-axis":a,x1:n,x2:d.polarX(n,i,t),y1:r,y2:d.polarY(r,i,t)}))});let[s,c]=t[0],l=t.every(([e,t])=>e===s&&t===c);if(!C.labels||!l)return;let u=T[0]+Math.PI/T.length;for(let t=1;t<=a;t++){let o=i*t/a,l=e.createSvgElement(`text`,{class:`prism-radar-level`,"dominant-baseline":`middle`,"text-anchor":`middle`,x:d.polarX(n,o,u),y:d.polarY(r,o,u)});l.textContent=formatValue(0,Math.round((s+(c-s)*t/a)*100)/100),j.appendChild(l)}}function renderLabels(){N.replaceChildren();let{cx:t,cy:n,radius:r}=L;y.forEach((i,a)=>{let{anchor:o,baseline:s}=f.labelPlacement(T[a]),c=e.createSvgElement(`text`,{class:`prism-radar-axis-label`,"dominant-baseline":s,"text-anchor":o,x:d.polarX(t,r+E,T[a]),y:d.polarY(n,r+E,T[a])});c.textContent=i.label,N.appendChild(c)})}function renderSeries(){let{cx:t,cy:n,radius:r}=L;for(A.replaceChildren();M.children.length>O.length;)M.lastChild?.remove();O.forEach((o,s)=>{let c=o.color??a.seriesColor(s),l=M.children[s];l||(l=e.createSvgElement(`g`,{class:`prism-radar-series`}),M.appendChild(l)),l.setAttribute(`data-series-id`,i.seriesDomId(o,s)),l.replaceChildren();let u=e.createSvgElement(`path`,{class:`prism-radar-area prism-radar-area--${x}`,stroke:c,"stroke-linejoin":`round`,"stroke-width":2});if(x===`gradient`){let i=`${D}-fill-${s}`,a=e.createSvgElement(`radialGradient`,{cx:t,cy:n,gradientUnits:`userSpaceOnUse`,id:i,r});for(let[t,n]of[[0,.08],[1,.55]])a.appendChild(e.createSvgElement(`stop`,{offset:t,"stop-color":c,"stop-opacity":n,style:`stop-color:${c}`}));A.appendChild(a),e.setAttributes(u,{fill:`url(#${i})`})}else e.setAttributes(u,{fill:x===`none`?`none`:c,"fill-opacity":.25});l.appendChild(u),S&&y.forEach((t,n)=>{let r=!Number.isFinite(datumAt(o,n)?.value);l.appendChild(e.createSvgElement(`circle`,{class:`prism-radar-point${r?` prism-radar-point--missing`:``}`,"data-axis":n,fill:r?`none`:c,r:3,stroke:c}))}),v.showValues&&y.forEach((t,n)=>{let r=datumAt(o,n),{anchor:i,baseline:a}=f.labelPlacement(T[n]),s=e.createSvgElement(`text`,{"aria-hidden":`true`,class:`prism-radar-value`,"dominant-baseline":a,"text-anchor":i});s.textContent=r&&Number.isFinite(r.value)?formatValue(n,r.value):``,l.appendChild(s)})})}function setActive(e){I=e;for(let t of k.querySelectorAll(`[data-axis]`)){let n=Number(t.getAttribute(`data-axis`))===e;t.classList.toggle(t.tagName===`line`?`prism-radar-spoke--active`:`prism-radar-point--active`,n)}}function animateTo(e,t){F?.();let n=e.map((e,t)=>e.map((e,n)=>P[t]?.[n]??0)),r=s.resolveMotion(v.transition,{defaultDuration:400}),i=o.resolveEasing(r.easing??`ease-out`),a=n.every((t,n)=>t.every((t,r)=>t===e[n][r]));r.duration===0||a?(P=e,draw(e)):F=l.startTween({count:e.length,duration:r.duration,easing:i,onFrame:t=>{P=e.map((e,r)=>{let i=t(r);return e.map((e,t)=>c.tweenNumber(n[r][t],e,i))}),draw(P)},signal:t,stagger:r.stagger})}return r.createRadialScaffold(_,{a11y:v.a11y,legend:v.legend,tooltip:v.tooltip},e=>{let{legend:t,svg:r,tooltip:i}=e;if(r.contains(k)||r.appendChild(k),i?.hide(),t?.update(O.map((e,t)=>({color:e.color??a.seriesColor(t),name:e.name}))),y.length<3){for(let e of[A,j,M,N])e.replaceChildren();P=[];return}let{height:o,width:s}=e.dimensions,c=f.fitRadius(s,o,y.map(e=>e.label),T,p,E);L={cx:s/2,cy:o/2,radius:c};let l=f.resolveAxisDomains(y,O,v.domain);renderGrid(l),renderLabels(),renderSeries(),animateTo(O.map(e=>y.map((t,n)=>{let r=datumAt(e,n)?.value;return r!==void 0&&Number.isFinite(r)?f.normalize(r,l[n]):0})),e.disposalSignal),setActive(I);let eventFor=(e,t)=>({axis:y[e],index:e,originalEvent:t,values:valuesAt(e)}),activate=(t,o)=>{setActive(t),v.onHover?.(eventFor(t,o));let s=describe(t);if(!i){e.announcer.announce(s);return}let c=Math.max(0,...P.map(e=>e[t]??0)),l=r.getBoundingClientRect(),u=_.getBoundingClientRect(),f=valuesAt(t),p=f.find(e=>e.datum)?.datum,m=f.flatMap(({datum:e,series:n})=>e?[{color:n.color??a.seriesColor(O.indexOf(n)),name:n.name,value:formatValue(t,e.value)}]:[]);i.show(d.polarX(L.cx,L.radius*c,T[t])+(l.left-u.left),d.polarY(L.cy,L.radius*c,T[t])+(l.top-u.top),{key:y[t].key,meta:{axis:y[t],text:s,values:f},value:p?.value??0},{color:O[0]?.color??a.seriesColor(0),data:[],name:y[t].label},n.comparisonContent(r.ownerDocument,y[t].label,m,s))},deactivate=()=>{setActive(-1),v.onHover?.(null),i?.hide(),e.announcer.clear()},hitIndex=e=>{let t=r.getBoundingClientRect(),n=e.clientX-t.left-L.cx,i=e.clientY-t.top-L.cy;return Math.hypot(n,i)>L.radius+E+22?-1:f.nearestAxis(n,i,y.length,w)};return{onClick(e){let t=hitIndex(e);t>=0&&v.onClick?.(eventFor(t,e))},onKeyDown(e){let t=g[e.key];t===void 0?(e.key===`Enter`||e.key===` `)&&I>=0&&v.onClick?(e.preventDefault(),v.onClick(eventFor(I,e))):e.key===`Escape`&&deactivate():(e.preventDefault(),activate(I<0?0:(I+t+y.length)%y.length,e))},onMouseLeave:deactivate,onMouseMove(e){let t=hitIndex(e);t<0?I>=0&&deactivate():t!==I&&activate(t,e)}}},e=>{O=e})}exports.createRadarChart=createRadarChart;
|
|
2
2
|
//# sourceMappingURL=radar-chart.cjs.map
|