@motionscript/charts 0.1.1-alpha.0 → 0.1.1-alpha.1
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/CHANGELOG.md +19 -0
- package/README.md +98 -28
- package/dist/bar-chart/bar-chart.d.ts +233 -39
- package/dist/bar-chart/bar-chart.d.ts.map +1 -1
- package/dist/bar-chart/bar-chart.js +215 -171
- package/dist/bar-chart/bar-chart.js.map +1 -1
- package/dist/bar-chart/category-axis.d.ts +12 -7
- package/dist/bar-chart/category-axis.d.ts.map +1 -1
- package/dist/bar-chart/category-axis.js +56 -42
- package/dist/bar-chart/category-axis.js.map +1 -1
- package/dist/bar-chart/chart-bars.d.ts +52 -52
- package/dist/bar-chart/chart-bars.d.ts.map +1 -1
- package/dist/bar-chart/chart-bars.js +80 -89
- package/dist/bar-chart/chart-bars.js.map +1 -1
- package/dist/bar-chart/index.d.ts +4 -4
- package/dist/bar-chart/index.d.ts.map +1 -1
- package/dist/bar-chart/index.js +2 -2
- package/dist/bar-chart/index.js.map +1 -1
- package/dist/bar-chart/shared.d.ts +36 -65
- package/dist/bar-chart/shared.d.ts.map +1 -1
- package/dist/bar-chart/shared.js +68 -117
- package/dist/bar-chart/shared.js.map +1 -1
- package/dist/browser/chunks/chunk-R3Q5EE6E.js +2 -0
- package/dist/browser/chunks/chunk-R3Q5EE6E.js.map +7 -0
- package/dist/browser/index.js +1 -1
- package/dist/browser/index.js.map +4 -4
- package/dist/browser/kit.js +1 -1
- package/dist/browser/manifest.json +1 -1
- package/dist/engine.d.ts +5 -2
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +5 -2
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/kit/cartesian.d.ts +49 -15
- package/dist/kit/cartesian.d.ts.map +1 -1
- package/dist/kit/cartesian.js +79 -29
- package/dist/kit/cartesian.js.map +1 -1
- package/dist/kit/chart-canvas.d.ts +32 -24
- package/dist/kit/chart-canvas.d.ts.map +1 -1
- package/dist/kit/chart-canvas.js +52 -46
- package/dist/kit/chart-canvas.js.map +1 -1
- package/dist/kit/chart-legend.d.ts +8 -4
- package/dist/kit/chart-legend.d.ts.map +1 -1
- package/dist/kit/chart-legend.js +30 -20
- package/dist/kit/chart-legend.js.map +1 -1
- package/dist/{line-chart → kit}/horizontal-axis.d.ts +31 -6
- package/dist/kit/horizontal-axis.d.ts.map +1 -0
- package/dist/{line-chart → kit}/horizontal-axis.js +23 -24
- package/dist/kit/horizontal-axis.js.map +1 -0
- package/dist/kit/motion.d.ts +5 -0
- package/dist/kit/motion.d.ts.map +1 -1
- package/dist/kit/motion.js +8 -0
- package/dist/kit/motion.js.map +1 -1
- package/dist/{pie-chart → kit}/pie-legend.d.ts +3 -3
- package/dist/kit/pie-legend.d.ts.map +1 -0
- package/dist/{pie-chart → kit}/pie-legend.js +11 -10
- package/dist/kit/pie-legend.js.map +1 -0
- package/dist/kit/polar.d.ts +31 -0
- package/dist/kit/polar.d.ts.map +1 -0
- package/dist/kit/polar.js +33 -0
- package/dist/kit/polar.js.map +1 -0
- package/dist/kit/shared.d.ts +11 -50
- package/dist/kit/shared.d.ts.map +1 -1
- package/dist/kit/shared.js +58 -141
- package/dist/kit/shared.js.map +1 -1
- package/dist/kit/style.d.ts +254 -0
- package/dist/kit/style.d.ts.map +1 -0
- package/dist/kit/style.js +197 -0
- package/dist/kit/style.js.map +1 -0
- package/dist/kit/vertical-axis.d.ts +22 -2
- package/dist/kit/vertical-axis.d.ts.map +1 -1
- package/dist/kit/vertical-axis.js +56 -43
- package/dist/kit/vertical-axis.js.map +1 -1
- package/dist/line-chart/chart-line.d.ts +95 -3
- package/dist/line-chart/chart-line.d.ts.map +1 -1
- package/dist/line-chart/chart-line.js +165 -53
- package/dist/line-chart/chart-line.js.map +1 -1
- package/dist/line-chart/chart-region.d.ts +1 -1
- package/dist/line-chart/chart-region.d.ts.map +1 -1
- package/dist/line-chart/chart-region.js +7 -8
- package/dist/line-chart/chart-region.js.map +1 -1
- package/dist/line-chart/index.d.ts +5 -6
- package/dist/line-chart/index.d.ts.map +1 -1
- package/dist/line-chart/index.js +3 -4
- package/dist/line-chart/index.js.map +1 -1
- package/dist/line-chart/line-chart.d.ts +257 -18
- package/dist/line-chart/line-chart.d.ts.map +1 -1
- package/dist/line-chart/line-chart.js +282 -134
- package/dist/line-chart/line-chart.js.map +1 -1
- package/dist/line-chart/shared.d.ts +51 -34
- package/dist/line-chart/shared.d.ts.map +1 -1
- package/dist/line-chart/shared.js +175 -83
- package/dist/line-chart/shared.js.map +1 -1
- package/dist/line-chart/x-scale.d.ts +2 -0
- package/dist/line-chart/x-scale.d.ts.map +1 -1
- package/dist/line-chart/x-scale.js +15 -0
- package/dist/line-chart/x-scale.js.map +1 -1
- package/dist/nodes.d.ts +3 -1
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +9 -1
- package/dist/nodes.js.map +1 -1
- package/dist/pie-chart/index.d.ts +2 -3
- package/dist/pie-chart/index.d.ts.map +1 -1
- package/dist/pie-chart/index.js +1 -2
- package/dist/pie-chart/index.js.map +1 -1
- package/dist/pie-chart/pie-chart.d.ts +114 -18
- package/dist/pie-chart/pie-chart.d.ts.map +1 -1
- package/dist/pie-chart/pie-chart.js +37 -24
- package/dist/pie-chart/pie-chart.js.map +1 -1
- package/dist/pie-chart/pie-ring.d.ts +16 -5
- package/dist/pie-chart/pie-ring.d.ts.map +1 -1
- package/dist/pie-chart/pie-ring.js +89 -55
- package/dist/pie-chart/pie-ring.js.map +1 -1
- package/dist/pie-chart/shared.d.ts +53 -61
- package/dist/pie-chart/shared.d.ts.map +1 -1
- package/dist/pie-chart/shared.js +41 -121
- package/dist/pie-chart/shared.js.map +1 -1
- package/dist/radar-chart/index.d.ts +5 -0
- package/dist/radar-chart/index.d.ts.map +1 -0
- package/dist/radar-chart/index.js +5 -0
- package/dist/radar-chart/index.js.map +1 -0
- package/dist/radar-chart/radar-chart.d.ts +218 -0
- package/dist/radar-chart/radar-chart.d.ts.map +1 -0
- package/dist/radar-chart/radar-chart.js +224 -0
- package/dist/radar-chart/radar-chart.js.map +1 -0
- package/dist/radar-chart/radar-grid.d.ts +43 -0
- package/dist/radar-chart/radar-grid.d.ts.map +1 -0
- package/dist/radar-chart/radar-grid.js +61 -0
- package/dist/radar-chart/radar-grid.js.map +1 -0
- package/dist/radar-chart/radar-series.d.ts +59 -0
- package/dist/radar-chart/radar-series.d.ts.map +1 -0
- package/dist/radar-chart/radar-series.js +71 -0
- package/dist/radar-chart/radar-series.js.map +1 -0
- package/dist/radar-chart/shared.d.ts +73 -0
- package/dist/radar-chart/shared.d.ts.map +1 -0
- package/dist/radar-chart/shared.js +123 -0
- package/dist/radar-chart/shared.js.map +1 -0
- package/dist/radial-chart/index.d.ts +6 -0
- package/dist/radial-chart/index.d.ts.map +1 -0
- package/dist/radial-chart/index.js +4 -0
- package/dist/radial-chart/index.js.map +1 -0
- package/dist/radial-chart/radial-chart.d.ts +216 -0
- package/dist/radial-chart/radial-chart.d.ts.map +1 -0
- package/dist/radial-chart/radial-chart.js +174 -0
- package/dist/radial-chart/radial-chart.js.map +1 -0
- package/dist/radial-chart/radial-rings.d.ts +121 -0
- package/dist/radial-chart/radial-rings.d.ts.map +1 -0
- package/dist/radial-chart/radial-rings.js +273 -0
- package/dist/radial-chart/radial-rings.js.map +1 -0
- package/dist/radial-chart/shared.d.ts +73 -0
- package/dist/radial-chart/shared.d.ts.map +1 -0
- package/dist/radial-chart/shared.js +79 -0
- package/dist/radial-chart/shared.js.map +1 -0
- package/package.json +4 -4
- package/registry.json +21 -6
- package/src/bar-chart/bar-chart.ts +252 -179
- package/src/bar-chart/category-axis.ts +46 -40
- package/src/bar-chart/chart-bars.ts +97 -117
- package/src/bar-chart/index.ts +7 -10
- package/src/bar-chart/shared.ts +78 -238
- package/src/engine.ts +5 -2
- package/src/index.ts +2 -0
- package/src/kit/cartesian.ts +118 -40
- package/src/kit/chart-canvas.ts +49 -54
- package/src/kit/chart-legend.ts +28 -20
- package/src/kit/horizontal-axis.ts +114 -0
- package/src/kit/motion.ts +7 -0
- package/src/{pie-chart → kit}/pie-legend.ts +12 -11
- package/src/kit/polar.ts +54 -0
- package/src/kit/shared.ts +55 -277
- package/src/kit/style.ts +257 -0
- package/src/kit/vertical-axis.ts +67 -48
- package/src/line-chart/chart-line.ts +176 -54
- package/src/line-chart/chart-region.ts +6 -10
- package/src/line-chart/index.ts +14 -10
- package/src/line-chart/line-chart.ts +347 -151
- package/src/line-chart/shared.ts +193 -174
- package/src/line-chart/x-scale.ts +13 -0
- package/src/nodes.ts +9 -1
- package/src/pie-chart/index.ts +2 -23
- package/src/pie-chart/pie-chart.ts +52 -35
- package/src/pie-chart/pie-ring.ts +92 -71
- package/src/pie-chart/shared.ts +68 -266
- package/src/radar-chart/index.ts +4 -0
- package/src/radar-chart/radar-chart.ts +287 -0
- package/src/radar-chart/radar-grid.ts +78 -0
- package/src/radar-chart/radar-series.ts +88 -0
- package/src/radar-chart/shared.ts +146 -0
- package/src/radial-chart/index.ts +5 -0
- package/src/radial-chart/radial-chart.ts +210 -0
- package/src/radial-chart/radial-rings.ts +328 -0
- package/src/radial-chart/shared.ts +114 -0
- package/dist/browser/chunks/chunk-4SMRCU24.js +0 -2
- package/dist/browser/chunks/chunk-4SMRCU24.js.map +0 -7
- package/dist/kit/chart-border.d.ts +0 -18
- package/dist/kit/chart-border.d.ts.map +0 -1
- package/dist/kit/chart-border.js +0 -23
- package/dist/kit/chart-border.js.map +0 -1
- package/dist/line-chart/horizontal-axis.d.ts.map +0 -1
- package/dist/line-chart/horizontal-axis.js.map +0 -1
- package/dist/pie-chart/pie-legend.d.ts.map +0 -1
- package/dist/pie-chart/pie-legend.js.map +0 -1
- package/src/kit/chart-border.ts +0 -36
- package/src/line-chart/horizontal-axis.ts +0 -122
|
@@ -6,12 +6,9 @@ import {
|
|
|
6
6
|
Types,
|
|
7
7
|
clamp,
|
|
8
8
|
component2d,
|
|
9
|
-
fillOps,
|
|
10
|
-
shadowOps,
|
|
11
9
|
strokeOps,
|
|
12
10
|
textOps,
|
|
13
11
|
type Fill,
|
|
14
|
-
type FillResolved,
|
|
15
12
|
type NodeOf,
|
|
16
13
|
// Named so this component's emitted type reaches `Node2D` and its props through the sdk, not core.
|
|
17
14
|
type Node2D,
|
|
@@ -23,9 +20,11 @@ import {
|
|
|
23
20
|
import { asParts, fresh } from "../kit/entries"
|
|
24
21
|
import { frameEase } from "../kit/motion"
|
|
25
22
|
import { loadPaints } from "../kit/paints"
|
|
23
|
+
import { resolvedFill, ringFills } from "../kit/polar"
|
|
26
24
|
import { formatPercent } from "../kit/shared"
|
|
25
|
+
|
|
27
26
|
import {
|
|
28
|
-
|
|
27
|
+
PIE_SPOTLIGHT_DIM,
|
|
29
28
|
pieArcs,
|
|
30
29
|
relaxLabels,
|
|
31
30
|
ringPoint,
|
|
@@ -39,6 +38,27 @@ import {
|
|
|
39
38
|
type RingConfig,
|
|
40
39
|
} from "./shared"
|
|
41
40
|
|
|
41
|
+
const DEFAULT_RING: RingConfig = { gap: 3, holeRadius: 0, startAngle: 0, selectedGrow: 1.08, cornerRadius: 4 }
|
|
42
|
+
const DEFAULT_LABEL: LabelConfig = {
|
|
43
|
+
textStyle: { fontSize: 28, fontWeight: 500, textAlign: "center", fill: "#a1a1aa" },
|
|
44
|
+
percentStyle: { fontSize: 28, fontWeight: 700, textAlign: "center", fill: "#f4f4f5" },
|
|
45
|
+
insideStyle: { fontSize: 52, fontWeight: 700, textAlign: "center", fill: "#111113" },
|
|
46
|
+
leaderStroke: { weight: 2, fill: "#a1a1aa" },
|
|
47
|
+
}
|
|
48
|
+
const DEFAULT_CENTER: CenterConfig = {
|
|
49
|
+
labelStyle: { fontSize: 50, fontWeight: 800, textAlign: "center", fill: "#f4f4f5" },
|
|
50
|
+
captionStyle: { fontSize: 22, fontWeight: 500, textAlign: "center", fill: "#a1a1aa" },
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Black or white, whichever reads better on a solid `fill`; black for any other paint. */
|
|
54
|
+
export function onFill(fill: Fill): string {
|
|
55
|
+
const layers = resolvedFill(fill)
|
|
56
|
+
const solid = layers.find((layer) => layer.type === "solid") as { color: [number, number, number, number] } | undefined
|
|
57
|
+
if (!solid) return "#111113"
|
|
58
|
+
const [r, g, b] = solid.color
|
|
59
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b > 0.45 ? "#111113" : "#ffffff"
|
|
60
|
+
}
|
|
61
|
+
|
|
42
62
|
const LABEL_GAP = 12
|
|
43
63
|
const LABEL_PAD = 14
|
|
44
64
|
/** Rough glyph width as a fraction of the font size, for gutter sizing. */
|
|
@@ -79,57 +99,72 @@ interface LabelPlacement {
|
|
|
79
99
|
|
|
80
100
|
/**
|
|
81
101
|
* A wedge over `a0`..`a1` (radians clockwise from 12 o'clock) from `rInner` to
|
|
82
|
-
* `rOuter`, centred on `cx`; with `rInner <= 0` it closes
|
|
83
|
-
* `halfGap` is half the px gap to the neighbour,
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* rather than turning inside out.
|
|
102
|
+
* `rOuter`, centred on `cx`; with `rInner <= 0` it closes at an apex pulled
|
|
103
|
+
* off the centre by the gap. `halfGap` is half the px gap to the neighbour,
|
|
104
|
+
* converted to an angle per radius so the channel keeps one width across the
|
|
105
|
+
* band; the inset is capped at the wedge's half-span so a sliver narrows to
|
|
106
|
+
* nothing rather than turning inside out. Corners are rounded by `corner` px
|
|
107
|
+
* (clamped to what the wedge can hold), except a pie's apex.
|
|
87
108
|
*/
|
|
88
|
-
function wedgePath(
|
|
89
|
-
a0: number,
|
|
90
|
-
a1: number,
|
|
91
|
-
rInner: number,
|
|
92
|
-
rOuter: number,
|
|
93
|
-
halfGap: number,
|
|
94
|
-
cx: number
|
|
95
|
-
): PathBuilder {
|
|
109
|
+
export function wedgePath(a0: number, a1: number, rInner: number, rOuter: number, halfGap: number, corner: number, cx: number): PathBuilder {
|
|
96
110
|
const path = new PathBuilder()
|
|
97
111
|
const span = a1 - a0
|
|
98
|
-
const steps = Math.max(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
const steps = Math.max(2, Math.ceil((Math.abs(span) / (Math.PI * 2)) * ARC_STEPS))
|
|
113
|
+
const insetAt = (r: number): number => (r <= 0 ? 0 : Math.min(halfGap / r, span / 2.2))
|
|
114
|
+
const at = (r: number, a: number): Vector2 => {
|
|
115
|
+
const p = ringPoint(r, a)
|
|
116
|
+
return { x: p.x + cx, y: p.y }
|
|
117
|
+
}
|
|
118
|
+
const hasHole = rInner > 0
|
|
119
|
+
const oa0 = a0 + insetAt(rOuter)
|
|
120
|
+
const oa1 = a1 - insetAt(rOuter)
|
|
121
|
+
const ia0 = a0 + insetAt(rInner)
|
|
122
|
+
const ia1 = a1 - insetAt(rInner)
|
|
123
|
+
const O0 = at(rOuter, oa0)
|
|
124
|
+
const O1 = at(rOuter, oa1)
|
|
125
|
+
const half = Math.max(1e-3, Math.min(span / 2, Math.PI / 2))
|
|
126
|
+
const apex = at(halfGap > 0 ? Math.min(halfGap / Math.sin(half), rOuter * 0.8) : 0, (a0 + a1) / 2)
|
|
127
|
+
const I0 = hasHole ? at(rInner, ia0) : apex
|
|
128
|
+
const I1 = hasHole ? at(rInner, ia1) : apex
|
|
129
|
+
|
|
130
|
+
const band = hasHole ? rOuter - rInner : rOuter
|
|
131
|
+
const rho = Math.max(0, Math.min(corner, band / 2.2, ((oa1 - oa0) * rOuter) / 2.2, hasHole ? ((ia1 - ia0) * rInner) / 2.2 : Infinity))
|
|
132
|
+
const rounded = rho >= 0.5
|
|
133
|
+
const toward = (from: Vector2, to: Vector2, d: number): Vector2 => {
|
|
134
|
+
const len = Math.hypot(to.x - from.x, to.y - from.y) || 1
|
|
135
|
+
const k = Math.min(0.5, d / len)
|
|
136
|
+
return { x: from.x + (to.x - from.x) * k, y: from.y + (to.y - from.y) * k }
|
|
137
|
+
}
|
|
138
|
+
const dOuter = rounded ? rho / Math.max(1, rOuter) : 0
|
|
139
|
+
const dInner = rounded && hasHole ? rho / rInner : 0
|
|
140
|
+
|
|
141
|
+
const arc = (r: number, from: number, to: number) => {
|
|
115
142
|
for (let i = 0; i <= steps; i++) {
|
|
116
|
-
const p =
|
|
143
|
+
const p = at(r, from + ((to - from) * i) / steps)
|
|
117
144
|
path.lineTo(p.x, p.y)
|
|
118
145
|
}
|
|
119
|
-
path.close()
|
|
120
|
-
return path
|
|
121
146
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (i === 0) path.moveTo(p.x, p.y)
|
|
126
|
-
else path.lineTo(p.x, p.y)
|
|
147
|
+
const round = (corner: Vector2, next: Vector2) => {
|
|
148
|
+
if (rounded) path.quadraticCurveTo(corner.x, corner.y, next.x, next.y)
|
|
149
|
+
else path.lineTo(corner.x, corner.y)
|
|
127
150
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
151
|
+
|
|
152
|
+
const first = at(rOuter, oa0 + dOuter)
|
|
153
|
+
path.moveTo(first.x, first.y)
|
|
154
|
+
arc(rOuter, oa0 + dOuter, oa1 - dOuter)
|
|
155
|
+
round(O1, toward(O1, I1, rho))
|
|
156
|
+
if (hasHole) {
|
|
157
|
+
const beforeI1 = toward(I1, O1, rho)
|
|
158
|
+
path.lineTo(beforeI1.x, beforeI1.y)
|
|
159
|
+
round(I1, at(rInner, ia1 - dInner))
|
|
160
|
+
arc(rInner, ia1 - dInner, ia0 + dInner)
|
|
161
|
+
round(I0, toward(I0, O0, rho))
|
|
162
|
+
} else {
|
|
163
|
+
path.lineTo(apex.x, apex.y)
|
|
132
164
|
}
|
|
165
|
+
const beforeO0 = toward(O0, I0, rounded ? rho : 0)
|
|
166
|
+
path.lineTo(beforeO0.x, beforeO0.y)
|
|
167
|
+
round(O0, first)
|
|
133
168
|
path.close()
|
|
134
169
|
return path
|
|
135
170
|
}
|
|
@@ -161,7 +196,7 @@ export class RingGeometry {
|
|
|
161
196
|
|
|
162
197
|
/** Leader labels are the only thing that costs a gutter. */
|
|
163
198
|
get hasLeaderLabels(): boolean {
|
|
164
|
-
return this.s.labelPlacement === "
|
|
199
|
+
return this.s.labelPlacement === "outside" && this.s.labelMode !== "none" && this.arcs.length > 0
|
|
165
200
|
}
|
|
166
201
|
|
|
167
202
|
/**
|
|
@@ -382,19 +417,6 @@ function sideOf(mid: number): 1 | -1 {
|
|
|
382
417
|
const NO_BOX = { width: 0, height: 0 }
|
|
383
418
|
|
|
384
419
|
/** Fills resolved once per paint, not per frame: a theme tween hands over new paint, but a frame that moves nothing must not re-resolve. Keyed by the paint, so it needs no node. */
|
|
385
|
-
const resolvedFills = new WeakMap<object, FillResolved[]>()
|
|
386
|
-
|
|
387
|
-
function resolvedFill(fill: Fill): FillResolved[] {
|
|
388
|
-
if (typeof fill !== "object" || fill === null) return fillOps.resolve(fill)
|
|
389
|
-
let resolved = resolvedFills.get(fill)
|
|
390
|
-
if (resolved === undefined) resolvedFills.set(fill, resolved = fillOps.resolve(fill))
|
|
391
|
-
return resolved
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
export function ringFills(slices: readonly PieSlice[]): FillResolved[][] {
|
|
395
|
-
return slices.map((slice) => resolvedFill(slice.fill))
|
|
396
|
-
}
|
|
397
|
-
|
|
398
420
|
/** One label per drawn slice (a zero-valued slice has no wedge), then the hole's summary. Only the choice of form is settled here; the pinned points stay reactive. */
|
|
399
421
|
function ringLabels(s: RingState & { readonly labelReveal: number; readonly centerReveal: number }) {
|
|
400
422
|
const blocks: Node2D[] = []
|
|
@@ -413,6 +435,7 @@ function ringLabels(s: RingState & { readonly labelReveal: number; readonly cent
|
|
|
413
435
|
inside.push(new Text({
|
|
414
436
|
...textOps.styleProps(s.label.insideStyle),
|
|
415
437
|
text: () => geometry().percentText(arc.index),
|
|
438
|
+
fill: () => onFill(s.slices[arc.index]?.fill ?? "white"),
|
|
416
439
|
fontSize: () => geometry().insideFont,
|
|
417
440
|
}))
|
|
418
441
|
}
|
|
@@ -420,6 +443,7 @@ function ringLabels(s: RingState & { readonly labelReveal: number; readonly cent
|
|
|
420
443
|
inside.push(new Text({
|
|
421
444
|
...textOps.styleProps(s.label.insideStyle),
|
|
422
445
|
text: () => s.slices[arc.index]?.category ?? "",
|
|
446
|
+
fill: () => onFill(s.slices[arc.index]?.fill ?? "white"),
|
|
423
447
|
fontSize: () => (s.labelMode === "category" ? geometry().insideFont : geometry().insideFont * INSIDE_CAPTION_RATIO),
|
|
424
448
|
}))
|
|
425
449
|
}
|
|
@@ -493,7 +517,7 @@ function ringLabels(s: RingState & { readonly labelReveal: number; readonly cent
|
|
|
493
517
|
height: "hug",
|
|
494
518
|
gap: 2,
|
|
495
519
|
align: "center",
|
|
496
|
-
opacity: () => clamp(s.centerReveal, 0, 1),
|
|
520
|
+
opacity: () => clamp(s.centerReveal, 0, 1) * clamp(geometry().holeRadius / 20, 0, 1),
|
|
497
521
|
center: () => ({ x: geometry().centerX, y: 0 }),
|
|
498
522
|
children,
|
|
499
523
|
}))
|
|
@@ -513,12 +537,12 @@ export const PieRing = component2d({
|
|
|
513
537
|
key: "pieRing",
|
|
514
538
|
state: {
|
|
515
539
|
slices: fresh<PieSlice[]>(() => []),
|
|
516
|
-
ring: Types.custom<RingConfig>(
|
|
517
|
-
label: Types.custom<LabelConfig>(
|
|
540
|
+
ring: Types.custom<RingConfig>(DEFAULT_RING),
|
|
541
|
+
label: Types.custom<LabelConfig>(DEFAULT_LABEL),
|
|
518
542
|
// Not `center`: every node already has one, the anchor its position is measured from.
|
|
519
|
-
centerStyle: Types.custom<CenterConfig>(
|
|
543
|
+
centerStyle: Types.custom<CenterConfig>(DEFAULT_CENTER),
|
|
520
544
|
labelMode: Types.custom<PieLabelMode>("percent"),
|
|
521
|
-
labelPlacement: Types.custom<PieLabelPlacement>("
|
|
545
|
+
labelPlacement: Types.custom<PieLabelPlacement>("outside"),
|
|
522
546
|
/** Sweep `[0, 1]`: the wedges grow clockwise from `startAngle` as it rises. */
|
|
523
547
|
growth: 1,
|
|
524
548
|
/** Fade of leaders and labels, separate from `growth` so they arrive after the sweep. */
|
|
@@ -526,7 +550,7 @@ export const PieRing = component2d({
|
|
|
526
550
|
/** Per-slice pop `[0, 1]`, owned by the chart so the ring and legend read one signal. */
|
|
527
551
|
pops: fresh<number[]>(() => []),
|
|
528
552
|
/** Opacity everything unselected falls back to while any slice is selected. */
|
|
529
|
-
dimOpacity:
|
|
553
|
+
dimOpacity: PIE_SPOTLIGHT_DIM,
|
|
530
554
|
/** Empty leaves the hole clear; ignored when there is no hole. */
|
|
531
555
|
centerLabel: "",
|
|
532
556
|
centerCaption: "",
|
|
@@ -540,8 +564,7 @@ export const PieRing = component2d({
|
|
|
540
564
|
load: (loader, state) =>
|
|
541
565
|
loadPaints(loader, {
|
|
542
566
|
fills: ringFills(state.slices),
|
|
543
|
-
|
|
544
|
-
strokes: [strokeOps.resolve(state.ring.stroke), strokeOps.resolve(state.label.leaderStroke)],
|
|
567
|
+
strokes: [strokeOps.resolve(state.label.leaderStroke)],
|
|
545
568
|
}),
|
|
546
569
|
commands: {
|
|
547
570
|
/** Wipe the wedges in around the ring (`growth` 0 to 1). */
|
|
@@ -591,11 +614,9 @@ export const PieRing = component2d({
|
|
|
591
614
|
const a1 = Math.min(arc.a1, revealEnd)
|
|
592
615
|
if (a1 <= arc.a0) continue
|
|
593
616
|
|
|
594
|
-
const path = wedgePath(arc.a0, a1, hole, g.anchorRadius(arc.index), halfGap, cx)
|
|
617
|
+
const path = wedgePath(arc.a0, a1, hole, g.anchorRadius(arc.index), halfGap, Math.max(0, state.ring.cornerRadius), cx)
|
|
595
618
|
const wedge = new Graphics2D().path(path.toPathState({ centerBounds, width: span, height: span }))
|
|
596
|
-
wedge.shadow(state.ring.shadow)
|
|
597
619
|
wedge.fill(fills[arc.index] ?? [])
|
|
598
|
-
wedge.stroke(state.ring.stroke)
|
|
599
620
|
ctx.draw(wedge.opacity(g.sliceOpacity(arc.index)))
|
|
600
621
|
}
|
|
601
622
|
|