@motionscript/charts 0.1.1-alpha.1 → 0.1.1-alpha.2
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 +15 -0
- package/README.md +19 -8
- package/dist/bar-chart/bar-chart.d.ts +97 -65
- package/dist/bar-chart/bar-chart.d.ts.map +1 -1
- package/dist/bar-chart/bar-chart.js +9 -5
- package/dist/bar-chart/bar-chart.js.map +1 -1
- package/dist/bar-chart/chart-bars.d.ts +29 -5
- package/dist/bar-chart/chart-bars.d.ts.map +1 -1
- package/dist/bar-chart/chart-bars.js +33 -8
- package/dist/bar-chart/chart-bars.js.map +1 -1
- package/dist/bar-chart/shared.d.ts +9 -4
- package/dist/bar-chart/shared.d.ts.map +1 -1
- package/dist/bar-chart/shared.js +10 -5
- package/dist/bar-chart/shared.js.map +1 -1
- package/dist/browser/chunks/chunk-7XCRX6GE.js +2 -0
- package/dist/browser/chunks/chunk-7XCRX6GE.js.map +7 -0
- package/dist/browser/index.js +1 -1
- package/dist/browser/index.js.map +3 -3
- package/dist/browser/kit.js +1 -1
- package/dist/browser/manifest.json +1 -1
- package/dist/kit/cartesian.d.ts +6 -4
- package/dist/kit/cartesian.d.ts.map +1 -1
- package/dist/kit/cartesian.js +5 -3
- package/dist/kit/cartesian.js.map +1 -1
- package/dist/kit/style.d.ts +339 -76
- package/dist/kit/style.d.ts.map +1 -1
- package/dist/kit/style.js +196 -101
- package/dist/kit/style.js.map +1 -1
- package/dist/line-chart/line-chart.d.ts +81 -57
- package/dist/line-chart/line-chart.d.ts.map +1 -1
- package/dist/line-chart/line-chart.js +9 -7
- package/dist/line-chart/line-chart.js.map +1 -1
- package/dist/pie-chart/pie-chart.d.ts +43 -43
- package/dist/pie-chart/pie-chart.d.ts.map +1 -1
- package/dist/pie-chart/pie-chart.js +2 -1
- package/dist/pie-chart/pie-chart.js.map +1 -1
- package/dist/pie-chart/shared.d.ts +15 -8
- package/dist/pie-chart/shared.d.ts.map +1 -1
- package/dist/pie-chart/shared.js +21 -20
- package/dist/pie-chart/shared.js.map +1 -1
- package/dist/radar-chart/index.d.ts +1 -1
- package/dist/radar-chart/index.d.ts.map +1 -1
- package/dist/radar-chart/index.js +1 -1
- package/dist/radar-chart/index.js.map +1 -1
- package/dist/radar-chart/radar-chart.d.ts +37 -43
- package/dist/radar-chart/radar-chart.d.ts.map +1 -1
- package/dist/radar-chart/radar-chart.js +12 -12
- package/dist/radar-chart/radar-chart.js.map +1 -1
- package/dist/radar-chart/radar-grid.d.ts +7 -1
- package/dist/radar-chart/radar-grid.d.ts.map +1 -1
- package/dist/radar-chart/radar-grid.js +17 -15
- package/dist/radar-chart/radar-grid.js.map +1 -1
- package/dist/radar-chart/shared.d.ts +7 -2
- package/dist/radar-chart/shared.d.ts.map +1 -1
- package/dist/radar-chart/shared.js +6 -0
- package/dist/radar-chart/shared.js.map +1 -1
- package/dist/radial-chart/radial-chart.d.ts +37 -43
- package/dist/radial-chart/radial-chart.d.ts.map +1 -1
- package/dist/radial-chart/radial-chart.js +2 -1
- package/dist/radial-chart/radial-chart.js.map +1 -1
- package/dist/radial-chart/shared.d.ts +13 -9
- package/dist/radial-chart/shared.d.ts.map +1 -1
- package/dist/radial-chart/shared.js +15 -16
- package/dist/radial-chart/shared.js.map +1 -1
- package/package.json +4 -4
- package/src/bar-chart/bar-chart.ts +17 -6
- package/src/bar-chart/chart-bars.ts +48 -9
- package/src/bar-chart/shared.ts +20 -5
- package/src/kit/cartesian.ts +10 -7
- package/src/kit/style.ts +214 -118
- package/src/line-chart/line-chart.ts +14 -8
- package/src/pie-chart/pie-chart.ts +3 -1
- package/src/pie-chart/shared.ts +30 -22
- package/src/radar-chart/index.ts +1 -1
- package/src/radar-chart/radar-chart.ts +16 -13
- package/src/radar-chart/radar-grid.ts +18 -13
- package/src/radar-chart/shared.ts +9 -2
- package/src/radial-chart/radial-chart.ts +3 -1
- package/src/radial-chart/shared.ts +30 -18
- package/dist/browser/chunks/chunk-R3Q5EE6E.js +0 -2
- package/dist/browser/chunks/chunk-R3Q5EE6E.js.map +0 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Graphics2D, Types, clamp, component2d, strokeOps, } from "@motionscript/sdk";
|
|
1
|
+
import { Graphics2D, Types, clamp, component2d, fillOps, strokeOps, } from "@motionscript/sdk";
|
|
2
2
|
import { loadPaints } from "../kit/paints.js";
|
|
3
3
|
import { spokeDirection } from "./shared.js";
|
|
4
4
|
/**
|
|
@@ -13,6 +13,8 @@ export const RadarGrid = component2d({
|
|
|
13
13
|
/** The rim, in px. */
|
|
14
14
|
radius: 0,
|
|
15
15
|
levels: 4,
|
|
16
|
+
/** Inside the outer ring, under the rings and spokes; empty paints nothing. */
|
|
17
|
+
fill: Types.custom([], { resolve: fillOps.resolve, lerp: fillOps.lerp }),
|
|
16
18
|
shape: Types.custom("polygon"),
|
|
17
19
|
stroke: Types.custom([], { resolve: strokeOps.resolve, lerp: strokeOps.lerp }),
|
|
18
20
|
/** The line out to each category; empty draws none. */
|
|
@@ -21,7 +23,7 @@ export const RadarGrid = component2d({
|
|
|
21
23
|
reveal: 1,
|
|
22
24
|
},
|
|
23
25
|
defaults: { width: "fill", height: "fill" },
|
|
24
|
-
load: (loader, state) => loadPaints(loader, { strokes: [state.stroke, state.spokeStroke] }),
|
|
26
|
+
load: (loader, state) => loadPaints(loader, { fills: [state.fill], strokes: [state.stroke, state.spokeStroke] }),
|
|
25
27
|
render: (ctx, state) => {
|
|
26
28
|
const grow = clamp(state.reveal, 0, 1);
|
|
27
29
|
const rim = state.radius * grow;
|
|
@@ -30,22 +32,22 @@ export const RadarGrid = component2d({
|
|
|
30
32
|
const count = Math.max(0, Math.round(state.count));
|
|
31
33
|
const levels = Math.max(1, Math.round(state.levels));
|
|
32
34
|
const round = state.shape === "circle" || count < 3;
|
|
35
|
+
const outline = (g, r) => {
|
|
36
|
+
if (round)
|
|
37
|
+
return g.ellipse({ width: r * 2, height: r * 2 });
|
|
38
|
+
const points = [];
|
|
39
|
+
for (let i = 0; i < count; i++) {
|
|
40
|
+
const d = spokeDirection(i, count);
|
|
41
|
+
points.push({ x: d.x * r, y: d.y * r });
|
|
42
|
+
}
|
|
43
|
+
return g.line({ points, closed: true });
|
|
44
|
+
};
|
|
45
|
+
if (state.fill.length > 0)
|
|
46
|
+
ctx.draw(outline(new Graphics2D(), rim).fill(state.fill).opacity(grow));
|
|
33
47
|
// One draw per ring: rings chained into one surface would stroke only their union's outline.
|
|
34
48
|
for (let level = 1; state.stroke.length > 0 && level <= levels; level++) {
|
|
35
49
|
const r = (rim * level) / levels;
|
|
36
|
-
|
|
37
|
-
if (round) {
|
|
38
|
-
ring.ellipse({ width: r * 2, height: r * 2 });
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
const points = [];
|
|
42
|
-
for (let i = 0; i < count; i++) {
|
|
43
|
-
const d = spokeDirection(i, count);
|
|
44
|
-
points.push({ x: d.x * r, y: d.y * r });
|
|
45
|
-
}
|
|
46
|
-
ring.line({ points, closed: true });
|
|
47
|
-
}
|
|
48
|
-
ctx.draw(ring.stroke(state.stroke).opacity(grow));
|
|
50
|
+
ctx.draw(outline(new Graphics2D(), r).stroke(state.stroke).opacity(grow));
|
|
49
51
|
}
|
|
50
52
|
if (state.spokeStroke.length === 0)
|
|
51
53
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radar-grid.js","sourceRoot":"","sources":["../../src/radar-chart/radar-grid.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,KAAK,EACL,KAAK,EACL,WAAW,EACX,SAAS,
|
|
1
|
+
{"version":3,"file":"radar-grid.js","sourceRoot":"","sources":["../../src/radar-chart/radar-grid.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Graphics2D,\n Types,\n clamp,\n component2d,\n fillOps,\n strokeOps,\n type Fill,\n type FillResolved,\n type NodeOf,\n // Named so this component's emitted type reaches `Node2D` and its props through the sdk, not core.\n type Node2D as _Node2D,\n type Node2DProps as _Node2DProps,\n type Stroke,\n type StrokeResolved,\n type Vector2,\n} from \"@motionscript/sdk\"\n\nimport { loadPaints } from \"../kit/paints\"\nimport { spokeDirection, type GridShape } from \"./shared\"\n\n/**\n * The web of a {@link RadarChart}: `levels` rings and, if asked, a spoke to each\n * of `count` categories, drawn from the node's centre out to `radius`. `reveal`\n * grows the web from nothing.\n */\nexport const RadarGrid = component2d({\n key: \"radarGrid\",\n state: {\n count: 0,\n /** The rim, in px. */\n radius: 0,\n levels: 4,\n /** Inside the outer ring, under the rings and spokes; empty paints nothing. */\n fill: Types.custom<Fill, FillResolved[]>([], { resolve: fillOps.resolve, lerp: fillOps.lerp }),\n shape: Types.custom<GridShape>(\"polygon\"),\n stroke: Types.custom<Stroke, StrokeResolved[]>([], { resolve: strokeOps.resolve, lerp: strokeOps.lerp }),\n /** The line out to each category; empty draws none. */\n spokeStroke: Types.custom<Stroke, StrokeResolved[]>([], { resolve: strokeOps.resolve, lerp: strokeOps.lerp }),\n /** How far the web has grown out, `0`-`1`. Rests at 1 so a paused canvas paints it. */\n reveal: 1,\n },\n defaults: { width: \"fill\", height: \"fill\" },\n load: (loader, state) => loadPaints(loader, { fills: [state.fill], strokes: [state.stroke, state.spokeStroke] }),\n render: (ctx, state) => {\n const grow = clamp(state.reveal, 0, 1)\n const rim = state.radius * grow\n if (rim <= 0 || grow <= 0) return\n const count = Math.max(0, Math.round(state.count))\n const levels = Math.max(1, Math.round(state.levels))\n const round = state.shape === \"circle\" || count < 3\n const outline = (g: Graphics2D, r: number): Graphics2D => {\n if (round) return g.ellipse({ width: r * 2, height: r * 2 })\n const points: Vector2[] = []\n for (let i = 0; i < count; i++) {\n const d = spokeDirection(i, count)\n points.push({ x: d.x * r, y: d.y * r })\n }\n return g.line({ points, closed: true })\n }\n\n if (state.fill.length > 0) ctx.draw(outline(new Graphics2D(), rim).fill(state.fill).opacity(grow))\n\n // One draw per ring: rings chained into one surface would stroke only their union's outline.\n for (let level = 1; state.stroke.length > 0 && level <= levels; level++) {\n const r = (rim * level) / levels\n ctx.draw(outline(new Graphics2D(), r).stroke(state.stroke).opacity(grow))\n }\n\n if (state.spokeStroke.length === 0) return\n for (let i = 0; i < count; i++) {\n const d = spokeDirection(i, count)\n ctx.draw(\n new Graphics2D()\n .line({ points: [{ x: 0, y: 0 }, { x: d.x * rim, y: d.y * rim }] })\n .stroke(state.spokeStroke)\n .opacity(grow)\n )\n }\n },\n})\n\nexport type RadarGrid = NodeOf<typeof RadarGrid>\n"]}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import { type DataRecord, type Size2D, type StrokeResolved, type Stroke as _Stroke, type Vector2 } from "@motionscript/sdk";
|
|
1
|
+
import { type TextStyle, type DataRecord, type Size2D, type StrokeResolved, type Stroke as _Stroke, type Vector2 } from "@motionscript/sdk";
|
|
2
2
|
import { type ChartSeries } from "../kit/shared.js";
|
|
3
|
+
/** The radar chart's text: the category names around the rim, and the legend. */
|
|
4
|
+
export declare const RADAR_TEXT: {
|
|
5
|
+
legendText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
|
|
6
|
+
spokeText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
|
|
7
|
+
};
|
|
3
8
|
export type GridShape = "polygon" | "circle";
|
|
4
9
|
/** The radar chart's own grid group: the web the polygons are drawn over. */
|
|
5
10
|
export declare const RADAR_GRID: {
|
|
@@ -34,7 +39,7 @@ export interface RadarStyle {
|
|
|
34
39
|
readonly areaOpacity: number;
|
|
35
40
|
readonly dots: boolean;
|
|
36
41
|
readonly dotSize: number;
|
|
37
|
-
readonly
|
|
42
|
+
readonly spokeText: TextStyle;
|
|
38
43
|
}
|
|
39
44
|
/** Spoke `index` of `count`, as a unit direction: 12 o'clock first, clockwise on screen, y up. */
|
|
40
45
|
export declare function spokeDirection(index: number, count: number): Vector2;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/radar-chart/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,UAAU,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,KAAK,MAAM,IAAI,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/radar-chart/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { Types } from "@motionscript/sdk";
|
|
2
2
|
import { num, text } from "../kit/shared.js";
|
|
3
|
+
import { CHART_MUTED, LEGEND_TEXT } from "../kit/style.js";
|
|
4
|
+
/** The radar chart's text: the category names around the rim, and the legend. */
|
|
5
|
+
export const RADAR_TEXT = {
|
|
6
|
+
spokeText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),
|
|
7
|
+
...LEGEND_TEXT,
|
|
8
|
+
};
|
|
3
9
|
/** The radar chart's own grid group: the web the polygons are drawn over. */
|
|
4
10
|
export const RADAR_GRID = {
|
|
5
11
|
/** Whether the rings are straight-edged (a polygon through the spokes) or round. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/radar-chart/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { Types, type DataRecord, type Size2D, type StrokeResolved, type Stroke as _Stroke, type Vector2 } from \"@motionscript/sdk\"\n\nimport { num, text, type ChartSeries } from \"../kit/shared\"\n\nexport type GridShape = \"polygon\" | \"circle\"\n\n/** The radar chart's own grid group: the web the polygons are drawn over. */\nexport const RADAR_GRID = {\n /** Whether the rings are straight-edged (a polygon through the spokes) or round. */\n gridShape: Types.oneOf([\"polygon\", \"circle\"] as const),\n /** How many rings, outermost at the scale's maximum. */\n gridLevels: Types.number(4, { min: 1, max: 10, step: 1 }),\n /** The rings; empty draws none. */\n gridStroke: Types.stroke({ weight: 2, fill: \"white/15\" }),\n /** The line from the centre out to each category; empty draws none. */\n spokeStroke: Types.stroke({ weight: 2, fill: \"white/15\" }),\n /** Read as the chart is built: whether the category names stand around the rim. */\n spokeLabels: Types.boolean(true, { animatable: false }),\n}\n\nexport const RADAR_MARKS = {\n /** Outline weight of each series' polygon. */\n strokeWidth: Types.number(4, { min: 0, max: 24, step: 1, unit: \"px\" }),\n /** How strongly each polygon is filled in its series colour; 0 leaves an outline. */\n areaOpacity: Types.number(0.25, { min: 0, max: 1, step: 0.05 }),\n /** Whether a dot marks each value on its spoke. */\n dots: Types.boolean(true),\n dotSize: Types.number(10, { min: 2, max: 40, step: 1, unit: \"px\" }),\n}\n\n/** The grid and marks fields the parts read, whichever way the chart's style is spelled. */\nexport interface RadarStyle {\n readonly gridShape: GridShape\n readonly gridLevels: number\n readonly gridStroke: StrokeResolved[]\n readonly spokeStroke: StrokeResolved[]\n readonly spokeLabels: boolean\n readonly strokeWidth: number\n readonly areaOpacity: number\n readonly dots: boolean\n readonly dotSize: number\n readonly fontSize: number\n}\n\n/** Fraction of the label's font size between the rim and the label. */\nconst LABEL_PAD = 0.55\n/** Glyph width as a fraction of the font size, for fitting labels. */\nconst GLYPH = 0.58\n/** Room kept clear around the web when nothing else claims it, in px. */\nconst MARGIN = 10\n/** Below this a spoke counts as vertical, and its label centres over it. */\nconst SIDE = 0.35\n\n/** Spoke `index` of `count`, as a unit direction: 12 o'clock first, clockwise on screen, y up. */\nexport function spokeDirection(index: number, count: number): Vector2 {\n const angle = (index / Math.max(1, count)) * Math.PI * 2\n return { x: Math.sin(angle), y: Math.cos(angle) }\n}\n\n/** One category per data row. */\nexport function categoriesOf(data: readonly DataRecord[], field: string): string[] {\n return data.map((row) => text(row, field))\n}\n\n/** One list of values per series, a value per row. */\nexport function valuesOf(data: readonly DataRecord[], series: readonly ChartSeries[]): number[][] {\n return series.map((s) => data.map((row) => num(row, s.field)))\n}\n\nconst MANTISSAS = [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10]\n\n/** `value` rounded up to a tidy 1, 1.5, 2, 2.5, 3, 4, 5, 6, 8 times a power of ten. */\nexport function niceCeil(value: number): number {\n if (!(value > 0)) return 1\n const power = 10 ** Math.floor(Math.log10(value))\n const mantissa = value / power\n const pick = MANTISSAS.find((m) => m >= mantissa - 1e-9) ?? 10\n return pick * power\n}\n\n/**\n * The scale the web is drawn to: `min` (default 0) to `max`, which when unset\n * (or not above `min`) is the largest value rounded up tidily.\n */\nexport function scaleOf(values: readonly (readonly number[])[], min: number, max: number): { min: number; max: number } {\n if (max > min) return { min, max }\n let top = min\n for (const list of values) for (const v of list) top = Math.max(top, v)\n const span = niceCeil(top - min)\n return { min, max: min + span }\n}\n\n/** Where `value` stands between the scale's ends, `0`-`1`. */\nexport function fractionOf(value: number, scale: { min: number; max: number }): number {\n const span = scale.max - scale.min\n if (span <= 0) return 0\n return Math.min(1, Math.max(0, (value - scale.min) / span))\n}\n\nexport type LabelAnchor = \"centerLeft\" | \"centerRight\" | \"bottomCenter\" | \"topCenter\"\n\n/** Which corner of a category's label touches the point beside its spoke's end. */\nexport function labelAnchor(index: number, count: number): LabelAnchor {\n const { x, y } = spokeDirection(index, count)\n if (x > SIDE) return \"centerLeft\"\n if (x < -SIDE) return \"centerRight\"\n return y >= 0 ? \"bottomCenter\" : \"topCenter\"\n}\n\nexport function labelPad(fontSize: number): number {\n return fontSize * LABEL_PAD\n}\n\n/** Rough size of a label, since the web is fitted before any text is measured. */\nexport function labelSize(caption: string, fontSize: number): Size2D {\n return { width: caption.length * fontSize * GLYPH, height: fontSize * 1.25 }\n}\n\n/**\n * The rim's radius for a box: the largest the web can be with every label\n * (when there are labels) still inside it.\n */\nexport function fitRadius(box: Size2D, categories: readonly string[], fontSize: number, labelled: boolean): number {\n let radius = Math.min(box.width, box.height) / 2 - MARGIN\n if (!labelled) return Math.max(0, radius)\n const pad = labelPad(fontSize)\n const count = categories.length\n categories.forEach((caption, i) => {\n const { x, y } = spokeDirection(i, count)\n const size = labelSize(caption, fontSize)\n const side = labelAnchor(i, count)\n // How much of the label hangs past its anchor point on each axis.\n const reachX = side === \"centerLeft\" || side === \"centerRight\" ? size.width : size.width / 2\n const reachY = side === \"bottomCenter\" || side === \"topCenter\" ? size.height : size.height / 2\n if (Math.abs(x) > 1e-6) radius = Math.min(radius, (box.width / 2 - reachX - MARGIN / 2) / Math.abs(x) - pad)\n if (Math.abs(y) > 1e-6) radius = Math.min(radius, (box.height / 2 - reachY - MARGIN / 2) / Math.abs(y) - pad)\n })\n return Math.max(0, radius)\n}\n\n/** Where spoke `index`'s label is pinned: just past the rim, centre-relative, y up. */\nexport function labelPoint(index: number, count: number, radius: number, fontSize: number): Vector2 {\n const { x, y } = spokeDirection(index, count)\n const r = radius + labelPad(fontSize)\n return { x: x * r, y: y * r }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/radar-chart/shared.ts"],"names":[],"mappings":"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","sourcesContent":["import { Types, type TextStyle, type DataRecord, type Size2D, type StrokeResolved, type Stroke as _Stroke, type Vector2 } from \"@motionscript/sdk\"\n\nimport { num, text, type ChartSeries } from \"../kit/shared\"\nimport { CHART_MUTED, LEGEND_TEXT } from \"../kit/style\"\n\n/** The radar chart's text: the category names around the rim, and the legend. */\nexport const RADAR_TEXT = {\n spokeText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),\n ...LEGEND_TEXT,\n}\n\nexport type GridShape = \"polygon\" | \"circle\"\n\n/** The radar chart's own grid group: the web the polygons are drawn over. */\nexport const RADAR_GRID = {\n /** Whether the rings are straight-edged (a polygon through the spokes) or round. */\n gridShape: Types.oneOf([\"polygon\", \"circle\"] as const),\n /** How many rings, outermost at the scale's maximum. */\n gridLevels: Types.number(4, { min: 1, max: 10, step: 1 }),\n /** The rings; empty draws none. */\n gridStroke: Types.stroke({ weight: 2, fill: \"white/15\" }),\n /** The line from the centre out to each category; empty draws none. */\n spokeStroke: Types.stroke({ weight: 2, fill: \"white/15\" }),\n /** Read as the chart is built: whether the category names stand around the rim. */\n spokeLabels: Types.boolean(true, { animatable: false }),\n}\n\nexport const RADAR_MARKS = {\n /** Outline weight of each series' polygon. */\n strokeWidth: Types.number(4, { min: 0, max: 24, step: 1, unit: \"px\" }),\n /** How strongly each polygon is filled in its series colour; 0 leaves an outline. */\n areaOpacity: Types.number(0.25, { min: 0, max: 1, step: 0.05 }),\n /** Whether a dot marks each value on its spoke. */\n dots: Types.boolean(true),\n dotSize: Types.number(10, { min: 2, max: 40, step: 1, unit: \"px\" }),\n}\n\n/** The grid and marks fields the parts read, whichever way the chart's style is spelled. */\nexport interface RadarStyle {\n readonly gridShape: GridShape\n readonly gridLevels: number\n readonly gridStroke: StrokeResolved[]\n readonly spokeStroke: StrokeResolved[]\n readonly spokeLabels: boolean\n readonly strokeWidth: number\n readonly areaOpacity: number\n readonly dots: boolean\n readonly dotSize: number\n readonly spokeText: TextStyle\n}\n\n/** Fraction of the label's font size between the rim and the label. */\nconst LABEL_PAD = 0.55\n/** Glyph width as a fraction of the font size, for fitting labels. */\nconst GLYPH = 0.58\n/** Room kept clear around the web when nothing else claims it, in px. */\nconst MARGIN = 10\n/** Below this a spoke counts as vertical, and its label centres over it. */\nconst SIDE = 0.35\n\n/** Spoke `index` of `count`, as a unit direction: 12 o'clock first, clockwise on screen, y up. */\nexport function spokeDirection(index: number, count: number): Vector2 {\n const angle = (index / Math.max(1, count)) * Math.PI * 2\n return { x: Math.sin(angle), y: Math.cos(angle) }\n}\n\n/** One category per data row. */\nexport function categoriesOf(data: readonly DataRecord[], field: string): string[] {\n return data.map((row) => text(row, field))\n}\n\n/** One list of values per series, a value per row. */\nexport function valuesOf(data: readonly DataRecord[], series: readonly ChartSeries[]): number[][] {\n return series.map((s) => data.map((row) => num(row, s.field)))\n}\n\nconst MANTISSAS = [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10]\n\n/** `value` rounded up to a tidy 1, 1.5, 2, 2.5, 3, 4, 5, 6, 8 times a power of ten. */\nexport function niceCeil(value: number): number {\n if (!(value > 0)) return 1\n const power = 10 ** Math.floor(Math.log10(value))\n const mantissa = value / power\n const pick = MANTISSAS.find((m) => m >= mantissa - 1e-9) ?? 10\n return pick * power\n}\n\n/**\n * The scale the web is drawn to: `min` (default 0) to `max`, which when unset\n * (or not above `min`) is the largest value rounded up tidily.\n */\nexport function scaleOf(values: readonly (readonly number[])[], min: number, max: number): { min: number; max: number } {\n if (max > min) return { min, max }\n let top = min\n for (const list of values) for (const v of list) top = Math.max(top, v)\n const span = niceCeil(top - min)\n return { min, max: min + span }\n}\n\n/** Where `value` stands between the scale's ends, `0`-`1`. */\nexport function fractionOf(value: number, scale: { min: number; max: number }): number {\n const span = scale.max - scale.min\n if (span <= 0) return 0\n return Math.min(1, Math.max(0, (value - scale.min) / span))\n}\n\nexport type LabelAnchor = \"centerLeft\" | \"centerRight\" | \"bottomCenter\" | \"topCenter\"\n\n/** Which corner of a category's label touches the point beside its spoke's end. */\nexport function labelAnchor(index: number, count: number): LabelAnchor {\n const { x, y } = spokeDirection(index, count)\n if (x > SIDE) return \"centerLeft\"\n if (x < -SIDE) return \"centerRight\"\n return y >= 0 ? \"bottomCenter\" : \"topCenter\"\n}\n\nexport function labelPad(fontSize: number): number {\n return fontSize * LABEL_PAD\n}\n\n/** Rough size of a label, since the web is fitted before any text is measured. */\nexport function labelSize(caption: string, fontSize: number): Size2D {\n return { width: caption.length * fontSize * GLYPH, height: fontSize * 1.25 }\n}\n\n/**\n * The rim's radius for a box: the largest the web can be with every label\n * (when there are labels) still inside it.\n */\nexport function fitRadius(box: Size2D, categories: readonly string[], fontSize: number, labelled: boolean): number {\n let radius = Math.min(box.width, box.height) / 2 - MARGIN\n if (!labelled) return Math.max(0, radius)\n const pad = labelPad(fontSize)\n const count = categories.length\n categories.forEach((caption, i) => {\n const { x, y } = spokeDirection(i, count)\n const size = labelSize(caption, fontSize)\n const side = labelAnchor(i, count)\n // How much of the label hangs past its anchor point on each axis.\n const reachX = side === \"centerLeft\" || side === \"centerRight\" ? size.width : size.width / 2\n const reachY = side === \"bottomCenter\" || side === \"topCenter\" ? size.height : size.height / 2\n if (Math.abs(x) > 1e-6) radius = Math.min(radius, (box.width / 2 - reachX - MARGIN / 2) / Math.abs(x) - pad)\n if (Math.abs(y) > 1e-6) radius = Math.min(radius, (box.height / 2 - reachY - MARGIN / 2) / Math.abs(y) - pad)\n })\n return Math.max(0, radius)\n}\n\n/** Where spoke `index`'s label is pinned: just past the rim, centre-relative, y up. */\nexport function labelPoint(index: number, count: number, radius: number, fontSize: number): Vector2 {\n const { x, y } = spokeDirection(index, count)\n const r = radius + labelPad(fontSize)\n return { x: x * r, y: y * r }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DataRecord, type NodeOf, type Node2D, type Node2DProps as _Node2DProps, type Fill as _Fill, type FillResolved as _FillResolved } from "@motionscript/sdk";
|
|
1
|
+
import { type DataRecord, type NodeOf, type Node2D, type Node2DProps as _Node2DProps, type TextStyle as _TextStyle, type Fill as _Fill, type FillResolved as _FillResolved } from "@motionscript/sdk";
|
|
2
2
|
import { type RadialStyle } from "./shared.js";
|
|
3
3
|
export interface RadialChartValues {
|
|
4
4
|
readonly data: DataRecord[];
|
|
@@ -23,17 +23,16 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
|
|
|
23
23
|
/** The value a full sweep stands for. 0 lets the largest value fill its ring. */
|
|
24
24
|
readonly max: import("@motionscript/sdk").Type<number, number, false>;
|
|
25
25
|
readonly style: import("@motionscript/sdk").Type<import("@motionscript/sdk").StyleInput<{
|
|
26
|
+
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
27
|
+
} & {
|
|
26
28
|
legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
|
|
27
29
|
swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
|
|
28
30
|
} & {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
32
|
+
labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
33
|
+
centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
32
34
|
} & {
|
|
33
|
-
|
|
34
|
-
foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
35
|
-
muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
36
|
-
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
35
|
+
seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
|
|
37
36
|
} & {
|
|
38
37
|
innerRadius: import("@motionscript/sdk").Type<number, number, false>;
|
|
39
38
|
ringGap: import("@motionscript/sdk").Type<number, number, false>;
|
|
@@ -44,17 +43,16 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
|
|
|
44
43
|
} & {
|
|
45
44
|
ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
|
|
46
45
|
}>, import("@motionscript/sdk").StyleValues<{
|
|
46
|
+
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
47
|
+
} & {
|
|
47
48
|
legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
|
|
48
49
|
swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
|
|
49
50
|
} & {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
52
|
+
labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
53
|
+
centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
53
54
|
} & {
|
|
54
|
-
|
|
55
|
-
foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
56
|
-
muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
57
|
-
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
55
|
+
seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
|
|
58
56
|
} & {
|
|
59
57
|
innerRadius: import("@motionscript/sdk").Type<number, number, false>;
|
|
60
58
|
ringGap: import("@motionscript/sdk").Type<number, number, false>;
|
|
@@ -91,17 +89,16 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
|
|
|
91
89
|
/** The value a full sweep stands for. 0 lets the largest value fill its ring. */
|
|
92
90
|
readonly max: import("@motionscript/sdk").Type<number, number, false>;
|
|
93
91
|
readonly style: import("@motionscript/sdk").Type<import("@motionscript/sdk").StyleInput<{
|
|
92
|
+
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
93
|
+
} & {
|
|
94
94
|
legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
|
|
95
95
|
swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
|
|
96
96
|
} & {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
98
|
+
labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
99
|
+
centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
100
100
|
} & {
|
|
101
|
-
|
|
102
|
-
foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
103
|
-
muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
104
|
-
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
101
|
+
seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
|
|
105
102
|
} & {
|
|
106
103
|
innerRadius: import("@motionscript/sdk").Type<number, number, false>;
|
|
107
104
|
ringGap: import("@motionscript/sdk").Type<number, number, false>;
|
|
@@ -112,17 +109,16 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
|
|
|
112
109
|
} & {
|
|
113
110
|
ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
|
|
114
111
|
}>, import("@motionscript/sdk").StyleValues<{
|
|
112
|
+
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
113
|
+
} & {
|
|
115
114
|
legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
|
|
116
115
|
swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
|
|
117
116
|
} & {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
118
|
+
labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
119
|
+
centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
121
120
|
} & {
|
|
122
|
-
|
|
123
|
-
foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
124
|
-
muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
125
|
-
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
121
|
+
seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
|
|
126
122
|
} & {
|
|
127
123
|
innerRadius: import("@motionscript/sdk").Type<number, number, false>;
|
|
128
124
|
ringGap: import("@motionscript/sdk").Type<number, number, false>;
|
|
@@ -152,17 +148,16 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
|
|
|
152
148
|
/** The value a full sweep stands for. 0 lets the largest value fill its ring. */
|
|
153
149
|
readonly max: import("@motionscript/sdk").Type<number, number, false>;
|
|
154
150
|
readonly style: import("@motionscript/sdk").Type<import("@motionscript/sdk").StyleInput<{
|
|
151
|
+
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
152
|
+
} & {
|
|
155
153
|
legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
|
|
156
154
|
swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
|
|
157
155
|
} & {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
156
|
+
legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
157
|
+
labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
158
|
+
centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
161
159
|
} & {
|
|
162
|
-
|
|
163
|
-
foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
164
|
-
muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
165
|
-
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
160
|
+
seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
|
|
166
161
|
} & {
|
|
167
162
|
innerRadius: import("@motionscript/sdk").Type<number, number, false>;
|
|
168
163
|
ringGap: import("@motionscript/sdk").Type<number, number, false>;
|
|
@@ -173,17 +168,16 @@ export declare const RadialChart: import("@motionscript/sdk").Component<"radialC
|
|
|
173
168
|
} & {
|
|
174
169
|
ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
|
|
175
170
|
}>, import("@motionscript/sdk").StyleValues<{
|
|
171
|
+
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
172
|
+
} & {
|
|
176
173
|
legend: import("@motionscript/sdk").Type<"right" | "top" | "bottom" | "none", "right" | "top" | "bottom" | "none", false>;
|
|
177
174
|
swatch: import("@motionscript/sdk").Type<"square" | "circle" | "line", "square" | "circle" | "line", false>;
|
|
178
175
|
} & {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
176
|
+
legendText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
177
|
+
labelText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
178
|
+
centerText: import("@motionscript/sdk").Type<_TextStyle, _TextStyle, false>;
|
|
182
179
|
} & {
|
|
183
|
-
|
|
184
|
-
foreground: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
185
|
-
muted: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
186
|
-
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
180
|
+
seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
|
|
187
181
|
} & {
|
|
188
182
|
innerRadius: import("@motionscript/sdk").Type<number, number, false>;
|
|
189
183
|
ringGap: import("@motionscript/sdk").Type<number, number, false>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radial-chart.d.ts","sourceRoot":"","sources":["../../src/radial-chart/radial-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,UAAU,EACf,KAAK,MAAM,EAEX,KAAK,MAAM,EACX,KAAK,WAAW,IAAI,YAAY,EAChC,KAAK,IAAI,IAAI,KAAK,EAClB,KAAK,YAAY,IAAI,aAAa,EACnC,MAAM,mBAAmB,CAAA;AAQ1B,OAAO,EAQL,KAAK,WAAW,EACjB,MAAM,UAAU,CAAA;AAEjB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CACxB;AAwCD;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;IAIpB,4DAA4D;;IAE5D,yDAAyD;;IAEzD,iFAAiF
|
|
1
|
+
{"version":3,"file":"radial-chart.d.ts","sourceRoot":"","sources":["../../src/radial-chart/radial-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,UAAU,EACf,KAAK,MAAM,EAEX,KAAK,MAAM,EACX,KAAK,WAAW,IAAI,YAAY,EAChC,KAAK,SAAS,IAAI,UAAU,EAC5B,KAAK,IAAI,IAAI,KAAK,EAClB,KAAK,YAAY,IAAI,aAAa,EACnC,MAAM,mBAAmB,CAAA;AAQ1B,OAAO,EAQL,KAAK,WAAW,EACjB,MAAM,UAAU,CAAA;AAEjB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CACxB;AAwCD;;;;;GAKG;AACH,eAAO,MAAM,WAAW;;IAIpB,4DAA4D;;IAE5D,yDAAyD;;IAEzD,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGjF,mDAAmD;;IAEnD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,8GAA8G;;IAE9G,yJAAyJ;;;;;;;;;;;IAfzJ,4DAA4D;;IAE5D,yDAAyD;;IAEzD,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGjF,mDAAmD;;IAEnD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,8GAA8G;;IAE9G,yJAAyJ;;;;IAfzJ,4DAA4D;;IAE5D,yDAAyD;;IAEzD,iFAAiF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGjF,mDAAmD;;IAEnD,mCAAmC;;IAEnC,+CAA+C;;IAE/C,8GAA8G;;IAE9G,yJAAyJ;;;;;;;;;0BAuG3J,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Rect, Types, clamp, component2d, easeOut, } from "@motionscript/sdk";
|
|
2
2
|
import { SERIES_ARG, asParts, fresh } from "../kit/entries.js";
|
|
3
3
|
import { beats } from "../kit/motion.js";
|
|
4
|
-
import { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS } from "../kit/style.js";
|
|
4
|
+
import { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS, migrateChartStyle } from "../kit/style.js";
|
|
5
5
|
import { PieLegend } from "../kit/pie-legend.js";
|
|
6
6
|
import { PIE_SPOTLIGHT_DIM, selectionFade } from "../kit/polar.js";
|
|
7
7
|
import { RadialRings } from "./radial-rings.js";
|
|
@@ -73,6 +73,7 @@ export const RadialChart = component2d({
|
|
|
73
73
|
height: "fill",
|
|
74
74
|
pops: (state) => state.data.map(() => 0),
|
|
75
75
|
},
|
|
76
|
+
migrate: { style: migrateChartStyle("radial") },
|
|
76
77
|
allowedChildren: [],
|
|
77
78
|
children: (state) => {
|
|
78
79
|
const style = () => state.style;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radial-chart.js","sourceRoot":"","sources":["../../src/radial-chart/radial-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Rect,\n Types,\n clamp,\n component2d,\n easeOut,\n type ChildView,\n type DataRecord,\n type NodeOf,\n // Named so this component's emitted type reaches `Node2D` and its props through the sdk, not core.\n type Node2D,\n type Node2DProps as _Node2DProps,\n type Fill as _Fill,\n type FillResolved as _FillResolved,\n} from \"@motionscript/sdk\"\n\nimport { SERIES_ARG, asParts, fresh } from \"../kit/entries\"\nimport { beats, type AnyTimeline, type Beat } from \"../kit/motion\"\nimport { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS } from \"../kit/style\"\nimport { PieLegend } from \"../kit/pie-legend\"\nimport { PIE_SPOTLIGHT_DIM, selectionFade } from \"../kit/polar\"\nimport { RadialRings } from \"./radial-rings\"\nimport {\n RADIAL_STYLE_GROUPS,\n centerOf,\n legendOf,\n marksOf,\n resolveRadialRows,\n ringLabelOf,\n type RadialRow,\n type RadialStyle,\n} from \"./shared\"\n\nexport interface RadialChartValues {\n readonly data: DataRecord[]\n readonly categoryField: string\n readonly valueField: string\n readonly max: number\n readonly style: RadialStyle\n readonly pops: number[]\n}\n\n/** How `enter` divides its duration: rings sweeping in, then captions and legend together. Sums to 1. */\nconst SWEEP_SHARE = 0.7\nconst LABEL_SHARE = 0.3\n\nfunction rowsOf(s: RadialChartValues): RadialRow[] {\n return resolveRadialRows(s.data, s.categoryField, s.valueField, s.style)\n}\n\nfunction popAt(s: RadialChartValues, index: number): number {\n return clamp(s.pops[index] ?? 0, 0, 1)\n}\n\n/** Per-row opacity for the legend: 1 while nothing is selected and for the selected ring, falling toward the dim for the rest. */\nfunction ringDims(s: RadialChartValues): number[] {\n let focus = 0\n for (let i = 0; i < s.data.length; i++) focus = Math.max(focus, popAt(s, i))\n return s.data.map((_, i) => selectionFade(focus, RING_DIM, popAt(s, i)))\n}\n\nconst RING_DIM = Math.max(PIE_SPOTLIGHT_DIM, 0.25)\n\nfunction popping(timeline: AnyTimeline, s: RadialChartValues, pop: (index: number) => number) {\n const from = s.data.map((_, i) => popAt(s, i))\n const targets = s.data.map((_, i) => clamp(pop(i), 0, 1))\n if (from.every((value, i) => value === targets[i])) return timeline.wait(timeline.duration)\n return timeline.animate((t) => ({ pops: from.map((value, i) => value + (targets[i] - value) * t) }))\n}\n\n/** The rings and legend among the children; the last row is the one the chart built. */\nfunction partsOf(children: readonly ChildView[]) {\n for (let i = children.length - 1; i >= 0; i--) {\n const row = children[i]\n const rings = Rect.is(row) ? row.children.find(RadialRings.is) : undefined\n if (rings) return { rings, legend: row.children.find(PieLegend.is) ?? null }\n }\n return null\n}\n\n/**\n * A radial bar chart: one concentric ring per row, the first row outermost,\n * each an arc from `startAngle` sweeping `value / max` of `sweep` degrees.\n * Rows are the marks and none can be hidden; `selectRing` thickens a ring and\n * dims the rest.\n */\nexport const RadialChart = component2d({\n key: \"radialChart\",\n state: {\n data: fresh<DataRecord[]>(() => [], { kind: \"dataset\" }),\n /** Ring caption, used on the ring labels and the legend. */\n categoryField: \"\",\n /** Ring magnitude: the arc's share of the full sweep. */\n valueField: \"\",\n /** The value a full sweep stands for. 0 lets the largest value fill its ring. */\n max: Types.number(0, { min: 0, step: 1 }),\n style: Types.style(CHART_STYLE_FAMILY, RADIAL_STYLE_GROUPS, { presets: CHART_STYLE_PRESETS }),\n /** Gap between the rings and the legend, in px. */\n gap: 40,\n /** Text set in the centre hole. */\n centerLabel: \"\",\n /** Smaller second line under `centerLabel`. */\n centerCaption: \"\",\n /** How far each ring is emphasised, `0`-`1` per index. Here because the rings and the legend both read it. */\n pops: fresh<number[]>(() => []),\n /** Read as the chart is built: whether the centre summary is drawn at rest. A scene that wants it to land later sets `false` and runs `revealCenter`. */\n showCenter: Types.boolean(true, { animatable: false }),\n },\n defaults: {\n width: \"fill\",\n height: \"fill\",\n pops: (state) => state.data.map(() => 0),\n },\n allowedChildren: [],\n children: (state) => {\n const style = () => state.style\n const rows = () => rowsOf(state)\n const parts: Node2D[] = [\n new RadialRings({\n width: \"fill\",\n height: \"fill\",\n rows,\n max: () => state.max,\n marks: () => marksOf(style()),\n label: () => ringLabelOf(style()),\n centerStyle: () => centerOf(style()),\n trackFill: () => style().track,\n ringLabels: () => style().ringLabels,\n pops: () => state.pops,\n dimOpacity: RING_DIM,\n centerLabel: state.centerLabel,\n centerCaption: state.centerCaption,\n centerReveal: state.showCenter === false ? 0 : 1,\n }) as unknown as Node2D,\n ]\n const position = state.style.legend\n if (position !== \"none\") {\n const side = position === \"right\"\n const config = legendOf(state.style)\n const legend = new PieLegend({\n slices: rows,\n legend: () => legendOf(style()),\n dims: () => ringDims(state),\n flow: side ? \"vertical\" : \"horizontal\",\n align: \"center\",\n gap: side ? config.itemGap / 3 : config.itemGap,\n padding: 0,\n }) as unknown as Node2D\n if (position === \"top\") parts.unshift(legend)\n else parts.push(legend)\n }\n const row = new Rect({\n flow: position === \"right\" || position === \"none\" ? \"horizontal\" : \"vertical\",\n width: \"fill\",\n height: \"fill\",\n gap: state.gap,\n padding: 24,\n align: \"center\",\n fill: () => state.style.background,\n children: parts,\n })\n return asParts([row as unknown as Node2D])\n },\n commands: {\n /** Rings sweep in from `startAngle`, outer ring first, then captions fade up and the legend staggers in. `duration` is the whole entrance; the centre summary keeps its own signal. */\n enter: {\n args: {},\n entrance: true,\n easing: easeOut(),\n run: (timeline, _state, children) => {\n const parts = partsOf(children)\n if (!parts) return timeline.wait(timeline.duration)\n const { rings, legend } = parts\n const sweep = timeline.duration * SWEEP_SHARE\n const labels = timeline.duration * LABEL_SHARE\n const at0 = (piece: Beat[\"piece\"]): Beat => ({ at: 0, duration: 0, piece })\n return beats(timeline, [\n at0(rings.to({ growth: 0, labelReveal: 0 })),\n ...(legend ? [at0(legend.run(\"arm\"))] : []),\n { at: 0, duration: sweep, piece: rings.run(\"sweep\") },\n { at: sweep, duration: labels, piece: rings.run(\"revealLabels\") },\n ...(legend ? [{ at: sweep, duration: labels, piece: legend.run(\"enter\") }] : []),\n ])\n },\n },\n /** Fade the centre summary up. Not part of `enter`: it is usually the conclusion, which a scene lands on its own beat. */\n revealCenter: {\n args: {},\n easing: easeOut(),\n run: (timeline, _state, children) => partsOf(children)?.rings.run(\"revealCenter\") ?? timeline.wait(timeline.duration),\n },\n /** Thicken ring `ringIndex` and dim the rest, leaving any other selected ring where it is. */\n selectRing: {\n args: { ringIndex: SERIES_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const index = timeline.args.ringIndex\n return popping(timeline, state, (i) => (i === index ? 1 : popAt(state, i)))\n },\n },\n /** Settle every ring and bring the whole chart back to full. */\n clearSelection: {\n args: {},\n easing: easeOut(),\n run: (timeline, state) => popping(timeline, state, () => 0),\n },\n },\n})\n\nexport type RadialChart = NodeOf<typeof RadialChart>\n"]}
|
|
1
|
+
{"version":3,"file":"radial-chart.js","sourceRoot":"","sources":["../../src/radial-chart/radial-chart.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Rect,\n Types,\n clamp,\n component2d,\n easeOut,\n type ChildView,\n type DataRecord,\n type NodeOf,\n // Named so this component's emitted type reaches `Node2D` and its props through the sdk, not core.\n type Node2D,\n type Node2DProps as _Node2DProps,\n type TextStyle as _TextStyle,\n type Fill as _Fill,\n type FillResolved as _FillResolved,\n} from \"@motionscript/sdk\"\n\nimport { SERIES_ARG, asParts, fresh } from \"../kit/entries\"\nimport { beats, type AnyTimeline, type Beat } from \"../kit/motion\"\nimport { CHART_STYLE_FAMILY, CHART_STYLE_PRESETS, migrateChartStyle } from \"../kit/style\"\nimport { PieLegend } from \"../kit/pie-legend\"\nimport { PIE_SPOTLIGHT_DIM, selectionFade } from \"../kit/polar\"\nimport { RadialRings } from \"./radial-rings\"\nimport {\n RADIAL_STYLE_GROUPS,\n centerOf,\n legendOf,\n marksOf,\n resolveRadialRows,\n ringLabelOf,\n type RadialRow,\n type RadialStyle,\n} from \"./shared\"\n\nexport interface RadialChartValues {\n readonly data: DataRecord[]\n readonly categoryField: string\n readonly valueField: string\n readonly max: number\n readonly style: RadialStyle\n readonly pops: number[]\n}\n\n/** How `enter` divides its duration: rings sweeping in, then captions and legend together. Sums to 1. */\nconst SWEEP_SHARE = 0.7\nconst LABEL_SHARE = 0.3\n\nfunction rowsOf(s: RadialChartValues): RadialRow[] {\n return resolveRadialRows(s.data, s.categoryField, s.valueField, s.style)\n}\n\nfunction popAt(s: RadialChartValues, index: number): number {\n return clamp(s.pops[index] ?? 0, 0, 1)\n}\n\n/** Per-row opacity for the legend: 1 while nothing is selected and for the selected ring, falling toward the dim for the rest. */\nfunction ringDims(s: RadialChartValues): number[] {\n let focus = 0\n for (let i = 0; i < s.data.length; i++) focus = Math.max(focus, popAt(s, i))\n return s.data.map((_, i) => selectionFade(focus, RING_DIM, popAt(s, i)))\n}\n\nconst RING_DIM = Math.max(PIE_SPOTLIGHT_DIM, 0.25)\n\nfunction popping(timeline: AnyTimeline, s: RadialChartValues, pop: (index: number) => number) {\n const from = s.data.map((_, i) => popAt(s, i))\n const targets = s.data.map((_, i) => clamp(pop(i), 0, 1))\n if (from.every((value, i) => value === targets[i])) return timeline.wait(timeline.duration)\n return timeline.animate((t) => ({ pops: from.map((value, i) => value + (targets[i] - value) * t) }))\n}\n\n/** The rings and legend among the children; the last row is the one the chart built. */\nfunction partsOf(children: readonly ChildView[]) {\n for (let i = children.length - 1; i >= 0; i--) {\n const row = children[i]\n const rings = Rect.is(row) ? row.children.find(RadialRings.is) : undefined\n if (rings) return { rings, legend: row.children.find(PieLegend.is) ?? null }\n }\n return null\n}\n\n/**\n * A radial bar chart: one concentric ring per row, the first row outermost,\n * each an arc from `startAngle` sweeping `value / max` of `sweep` degrees.\n * Rows are the marks and none can be hidden; `selectRing` thickens a ring and\n * dims the rest.\n */\nexport const RadialChart = component2d({\n key: \"radialChart\",\n state: {\n data: fresh<DataRecord[]>(() => [], { kind: \"dataset\" }),\n /** Ring caption, used on the ring labels and the legend. */\n categoryField: \"\",\n /** Ring magnitude: the arc's share of the full sweep. */\n valueField: \"\",\n /** The value a full sweep stands for. 0 lets the largest value fill its ring. */\n max: Types.number(0, { min: 0, step: 1 }),\n style: Types.style(CHART_STYLE_FAMILY, RADIAL_STYLE_GROUPS, { presets: CHART_STYLE_PRESETS }),\n /** Gap between the rings and the legend, in px. */\n gap: 40,\n /** Text set in the centre hole. */\n centerLabel: \"\",\n /** Smaller second line under `centerLabel`. */\n centerCaption: \"\",\n /** How far each ring is emphasised, `0`-`1` per index. Here because the rings and the legend both read it. */\n pops: fresh<number[]>(() => []),\n /** Read as the chart is built: whether the centre summary is drawn at rest. A scene that wants it to land later sets `false` and runs `revealCenter`. */\n showCenter: Types.boolean(true, { animatable: false }),\n },\n defaults: {\n width: \"fill\",\n height: \"fill\",\n pops: (state) => state.data.map(() => 0),\n },\n migrate: { style: migrateChartStyle(\"radial\") },\n allowedChildren: [],\n children: (state) => {\n const style = () => state.style\n const rows = () => rowsOf(state)\n const parts: Node2D[] = [\n new RadialRings({\n width: \"fill\",\n height: \"fill\",\n rows,\n max: () => state.max,\n marks: () => marksOf(style()),\n label: () => ringLabelOf(style()),\n centerStyle: () => centerOf(style()),\n trackFill: () => style().track,\n ringLabels: () => style().ringLabels,\n pops: () => state.pops,\n dimOpacity: RING_DIM,\n centerLabel: state.centerLabel,\n centerCaption: state.centerCaption,\n centerReveal: state.showCenter === false ? 0 : 1,\n }) as unknown as Node2D,\n ]\n const position = state.style.legend\n if (position !== \"none\") {\n const side = position === \"right\"\n const config = legendOf(state.style)\n const legend = new PieLegend({\n slices: rows,\n legend: () => legendOf(style()),\n dims: () => ringDims(state),\n flow: side ? \"vertical\" : \"horizontal\",\n align: \"center\",\n gap: side ? config.itemGap / 3 : config.itemGap,\n padding: 0,\n }) as unknown as Node2D\n if (position === \"top\") parts.unshift(legend)\n else parts.push(legend)\n }\n const row = new Rect({\n flow: position === \"right\" || position === \"none\" ? \"horizontal\" : \"vertical\",\n width: \"fill\",\n height: \"fill\",\n gap: state.gap,\n padding: 24,\n align: \"center\",\n fill: () => state.style.background,\n children: parts,\n })\n return asParts([row as unknown as Node2D])\n },\n commands: {\n /** Rings sweep in from `startAngle`, outer ring first, then captions fade up and the legend staggers in. `duration` is the whole entrance; the centre summary keeps its own signal. */\n enter: {\n args: {},\n entrance: true,\n easing: easeOut(),\n run: (timeline, _state, children) => {\n const parts = partsOf(children)\n if (!parts) return timeline.wait(timeline.duration)\n const { rings, legend } = parts\n const sweep = timeline.duration * SWEEP_SHARE\n const labels = timeline.duration * LABEL_SHARE\n const at0 = (piece: Beat[\"piece\"]): Beat => ({ at: 0, duration: 0, piece })\n return beats(timeline, [\n at0(rings.to({ growth: 0, labelReveal: 0 })),\n ...(legend ? [at0(legend.run(\"arm\"))] : []),\n { at: 0, duration: sweep, piece: rings.run(\"sweep\") },\n { at: sweep, duration: labels, piece: rings.run(\"revealLabels\") },\n ...(legend ? [{ at: sweep, duration: labels, piece: legend.run(\"enter\") }] : []),\n ])\n },\n },\n /** Fade the centre summary up. Not part of `enter`: it is usually the conclusion, which a scene lands on its own beat. */\n revealCenter: {\n args: {},\n easing: easeOut(),\n run: (timeline, _state, children) => partsOf(children)?.rings.run(\"revealCenter\") ?? timeline.wait(timeline.duration),\n },\n /** Thicken ring `ringIndex` and dim the rest, leaving any other selected ring where it is. */\n selectRing: {\n args: { ringIndex: SERIES_ARG },\n easing: easeOut(),\n run: (timeline, state) => {\n const index = timeline.args.ringIndex\n return popping(timeline, state, (i) => (i === index ? 1 : popAt(state, i)))\n },\n },\n /** Settle every ring and bring the whole chart back to full. */\n clearSelection: {\n args: {},\n easing: easeOut(),\n run: (timeline, state) => popping(timeline, state, () => 0),\n },\n },\n})\n\nexport type RadialChart = NodeOf<typeof RadialChart>\n"]}
|
|
@@ -4,7 +4,7 @@ import type { LegendConfig } from "../kit/shared.js";
|
|
|
4
4
|
import type { CenterConfig, PieSlice } from "../kit/polar.js";
|
|
5
5
|
/** One ring: a row's caption, magnitude and paint. The same shape as a pie's slice, so the legend is shared. */
|
|
6
6
|
export type RadialRow = PieSlice;
|
|
7
|
-
export declare function resolveRadialRows(data: readonly DataRecord[], category: string, value: string, style: Pick<ChartStyleBase, "
|
|
7
|
+
export declare function resolveRadialRows(data: readonly DataRecord[], category: string, value: string, style: Pick<ChartStyleBase, "seriesFills">): RadialRow[];
|
|
8
8
|
/** A row's plotted value: negatives and non-finite values count as 0. */
|
|
9
9
|
export declare function rowValue(row: RadialRow): number;
|
|
10
10
|
/** What a full sweep stands for: `max` when it is positive, else the largest value (1 when every value is 0). */
|
|
@@ -30,18 +30,22 @@ export interface RadialStyle extends ChartStyleBase {
|
|
|
30
30
|
readonly track: _FillResolved[];
|
|
31
31
|
readonly roundCaps: boolean;
|
|
32
32
|
readonly ringLabels: boolean;
|
|
33
|
+
readonly labelText: TextStyle;
|
|
34
|
+
readonly centerText: TextStyle;
|
|
33
35
|
}
|
|
34
36
|
export declare const RADIAL_STYLE_GROUPS: {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
series: {
|
|
38
|
+
seriesFills: import("@motionscript/sdk").Type<_Fill[], _FillResolved[][], false>;
|
|
39
|
+
};
|
|
40
|
+
background: {
|
|
39
41
|
background: import("@motionscript/sdk").Type<_Fill, _FillResolved[], false>;
|
|
40
42
|
};
|
|
41
43
|
text: {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
legendText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
|
|
45
|
+
/** The category at each ring's start, and the caption under the centre. */
|
|
46
|
+
labelText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
|
|
47
|
+
/** The summary in the middle. */
|
|
48
|
+
centerText: import("@motionscript/sdk").Type<TextStyle, TextStyle, false>;
|
|
45
49
|
};
|
|
46
50
|
marks: {
|
|
47
51
|
/** Where the innermost ring starts, as a fraction of the outer radius. */
|
|
@@ -58,7 +62,7 @@ export declare const RADIAL_STYLE_GROUPS: {
|
|
|
58
62
|
roundCaps: import("@motionscript/sdk").Type<boolean, boolean, false>;
|
|
59
63
|
};
|
|
60
64
|
labels: {
|
|
61
|
-
/** The category written at each ring's start, in the
|
|
65
|
+
/** The category written at each ring's start, set in the label text. */
|
|
62
66
|
ringLabels: import("@motionscript/sdk").Type<boolean, boolean, false>;
|
|
63
67
|
};
|
|
64
68
|
legend: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/radial-chart/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,IAAI,KAAK,EAAE,KAAK,YAAY,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEzI,OAAO,
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/radial-chart/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,IAAI,KAAK,EAAE,KAAK,YAAY,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEzI,OAAO,EAWL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAA;AACrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAE1D,gHAAgH;AAChH,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAA;AAEhC,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,GAAG,SAAS,EAAE,CAEvJ;AAED,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAE/C;AAED,iHAAiH;AACjH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKzE;AAED,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAGjF;AAED,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,EAAE,CAAA;IAC/B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAA;CAC/B;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;QAI5B,2EAA2E;;QAE3E,iCAAiC;;;;QAKjC,0EAA0E;;QAE1E,4CAA4C;;QAE5C,2EAA2E;;QAE3E,iEAAiE;;QAEjE,sDAAsD;;QAEtD,6CAA6C;;;;QAI7C,wEAAwE;;;;;;;CAI3E,CAAA;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CASvD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAEzD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAEzD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAMzD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Types, clamp } from "@motionscript/sdk";
|
|
2
|
-
import {
|
|
2
|
+
import { CHART_BACKGROUND, CHART_FOREGROUND, CHART_LEGEND, CHART_MUTED, CHART_SERIES, LEGEND_TEXT, legendConfigOf, paletteFill, placedText, sizeOf, } from "../kit/style.js";
|
|
3
3
|
import { num, text } from "../kit/shared.js";
|
|
4
4
|
export function resolveRadialRows(data, category, value, style) {
|
|
5
5
|
return data.map((row, i) => ({ category: text(row, category), value: num(row, value), fill: paletteFill(style, i) }));
|
|
@@ -23,8 +23,15 @@ export function radialFractions(rows, max) {
|
|
|
23
23
|
return rows.map((row) => clamp(rowValue(row) / top, 0, 1));
|
|
24
24
|
}
|
|
25
25
|
export const RADIAL_STYLE_GROUPS = {
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
series: CHART_SERIES,
|
|
27
|
+
background: CHART_BACKGROUND,
|
|
28
|
+
text: {
|
|
29
|
+
/** The category at each ring's start, and the caption under the centre. */
|
|
30
|
+
labelText: Types.typography({ fontSize: 28, fontWeight: 500, fill: CHART_MUTED }),
|
|
31
|
+
/** The summary in the middle. */
|
|
32
|
+
centerText: Types.typography({ fontSize: 50, fontWeight: 800, fill: CHART_FOREGROUND }),
|
|
33
|
+
...LEGEND_TEXT,
|
|
34
|
+
},
|
|
28
35
|
marks: {
|
|
29
36
|
/** Where the innermost ring starts, as a fraction of the outer radius. */
|
|
30
37
|
innerRadius: Types.number(0.3, { min: 0, max: 0.9, step: 0.05 }),
|
|
@@ -40,7 +47,7 @@ export const RADIAL_STYLE_GROUPS = {
|
|
|
40
47
|
roundCaps: Types.boolean(true),
|
|
41
48
|
},
|
|
42
49
|
labels: {
|
|
43
|
-
/** The category written at each ring's start, in the
|
|
50
|
+
/** The category written at each ring's start, set in the label text. */
|
|
44
51
|
ringLabels: Types.boolean(false),
|
|
45
52
|
},
|
|
46
53
|
legend: CHART_LEGEND,
|
|
@@ -58,22 +65,14 @@ export function marksOf(style) {
|
|
|
58
65
|
export function legendOf(style) {
|
|
59
66
|
return legendConfigOf(style);
|
|
60
67
|
}
|
|
61
|
-
function face(style) {
|
|
62
|
-
return style.fontFamily ? { fontFamily: style.fontFamily } : {};
|
|
63
|
-
}
|
|
64
68
|
export function ringLabelOf(style) {
|
|
65
|
-
return
|
|
69
|
+
return placedText(style.labelText);
|
|
66
70
|
}
|
|
67
71
|
export function centerOf(style) {
|
|
72
|
+
const size = sizeOf(style.centerText, 50);
|
|
68
73
|
return {
|
|
69
|
-
labelStyle:
|
|
70
|
-
|
|
71
|
-
fontSize: Math.round(style.fontSize * 1.8),
|
|
72
|
-
fontWeight: Math.min(900, style.fontWeight + 300),
|
|
73
|
-
textAlign: "center",
|
|
74
|
-
fill: style.foreground,
|
|
75
|
-
},
|
|
76
|
-
captionStyle: { ...face(style), fontSize: Math.round(style.fontSize * 0.8), fontWeight: style.fontWeight, textAlign: "center", fill: style.muted },
|
|
74
|
+
labelStyle: placedText(style.centerText),
|
|
75
|
+
captionStyle: placedText(style.labelText, "center", { fontSize: Math.round(size * 0.45) }),
|
|
77
76
|
};
|
|
78
77
|
}
|
|
79
78
|
//# sourceMappingURL=shared.js.map
|