@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
package/dist/browser/kit.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{$,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,_,a,aa,b,ba,c,ca,d,da,e,ea,f,fa,g,ga,h,ha,i,ia,j,ja,k,ka,l,la,m,ma,n,na,o,oa,p,q,r,s,t,u,v,w,x,y,z}from"./chunks/chunk-
|
|
1
|
+
import{$,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,_,a,aa,b,ba,c,ca,d,da,e,ea,f,fa,g,ga,h,ha,i,ia,j,ja,k,ka,l,la,m,ma,n,na,o,oa,p,pa,q,qa,r,ra,s,sa,t,ta,u,ua,v,va,w,x,y,z}from"./chunks/chunk-7XCRX6GE.js";export{j as CARTESIAN_GRID,i as CARTESIAN_TEXT,f as CHART_BACKGROUND,c as CHART_FOREGROUND,k as CHART_LEGEND,d as CHART_MUTED,b as CHART_PALETTE_DEFAULT,e as CHART_SERIES,a as CHART_STYLE_FAMILY,l as CHART_STYLE_PRESETS,J as ChartCanvas,ja as ChartLegend,ca as DEFAULT_LEGEND,M as DEFAULT_MARKERS,aa as DEFAULT_X_AXIS,ba as DEFAULT_Y_AXIS,qa as DEG,N as ENTER_SHARE,g as GRID_BACKGROUND,oa as HorizontalAxis,K as LEGEND_SLIDE,h as LEGEND_TEXT,ta as PIE_SPOTLIGHT_DIM,pa as PieLegend,G as SERIES_ARG,Y as SPOTLIGHT_DIM,na as VerticalAxis,S as armed,T as arrival,R as arrivalOf,Q as arrivalsEntry,F as asParts,s as axisConfigOf,la as axisPads,P as beats,B as boundText,ma as captionColumn,y as cartesianFrame,z as chartViews,C as columnGhost,D as fade,da as formatMarker,fa as formatPercent,O as frameEase,v as frameGap,E as fresh,w as headroom,A as laidOutSize,L as legendAway,t as legendConfigOf,V as lerpAxisDomain,W as lerpAxisEntry,H as loadPaints,ka as markerCaption,ea as markerStep,q as markerText,ga as markerValues,u as migrateChartStyle,ha as niceRange,ia as niceTicks,Z as num,$ as numericFields,x as overhang,m as paletteFill,p as placedText,U as resolveAxisDomain,ua as resolvedFill,va as ringFills,sa as ringPoint,I as rule,ra as selectionFade,n as seriesFill,X as settleAxisDomain,o as sizeOf,_ as text,r as valueText};
|
|
2
2
|
//# sourceMappingURL=kit.js.map
|
package/dist/kit/cartesian.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { type ChildView, type Fill, type Insets, type Node2D, type Size2D, type TextStyle } from "@motionscript/sdk";
|
|
2
|
-
import type
|
|
2
|
+
import { type CartesianStyle, type LegendPosition } from "./style.js";
|
|
3
3
|
/** Space between the frame's rows and columns: the plot and the legend, the axes and the legend. */
|
|
4
|
-
export declare function frameGap(style: Pick<CartesianStyle, "
|
|
4
|
+
export declare function frameGap(style: Pick<CartesianStyle, "legendText">): number;
|
|
5
5
|
/** Room above the plot for the top value marker, which is centred on the top grid line. */
|
|
6
|
-
export declare function headroom(style: Pick<CartesianStyle, "
|
|
6
|
+
export declare function headroom(style: Pick<CartesianStyle, "yLabelText">): number;
|
|
7
7
|
/** How far an end marker of a horizontal value axis may hang past the plot: half a short caption. */
|
|
8
|
-
export declare function overhang(style: Pick<CartesianStyle, "
|
|
8
|
+
export declare function overhang(style: Pick<CartesianStyle, "xLabelText">): number;
|
|
9
9
|
interface CartesianParts {
|
|
10
|
+
/** Behind the whole chart, axes and legend included. */
|
|
11
|
+
readonly background?: () => Fill;
|
|
10
12
|
/** The axis beside the plot, on its left. */
|
|
11
13
|
readonly left?: Node2D;
|
|
12
14
|
/** An invisible twin of `left` under the plot, so the row there starts at the plot's left edge. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cartesian.d.ts","sourceRoot":"","sources":["../../src/kit/cartesian.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,IAAI,EAET,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAA;AAE1B,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"cartesian.d.ts","sourceRoot":"","sources":["../../src/kit/cartesian.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,IAAI,EAET,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,SAAS,EACf,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAU,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,SAAS,CAAA;AAE1E,oGAAoG;AACpG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,GAAG,MAAM,CAE1E;AAED,2FAA2F;AAC3F,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,GAAG,MAAM,CAE1E;AAED,qGAAqG;AACrG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,GAAG,MAAM,CAE1E;AAED,UAAU,cAAc;IACtB,wDAAwD;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IAChC,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,mGAAmG;IACnG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAA;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CA8B5D;AAED,qIAAqI;AACrI,wBAAgB,UAAU,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,CAUtE;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG5D;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKxE;AAED,UAAU,SAAS;IACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,SAAS,MAAM,EAAE,CAAA;IAC1C,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,SAAS,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,SAAS,CAAA;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,MAAM,CAAA;CAChC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAQnD;AAED,uDAAuD;AACvD,wBAAgB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAGhD"}
|
package/dist/kit/cartesian.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Rect, RotatedBox, Text, textOps, } from "@motionscript/sdk";
|
|
2
|
+
import { sizeOf } from "./style.js";
|
|
2
3
|
/** Space between the frame's rows and columns: the plot and the legend, the axes and the legend. */
|
|
3
4
|
export function frameGap(style) {
|
|
4
|
-
return Math.round(style.
|
|
5
|
+
return Math.round(sizeOf(style.legendText) * 0.9);
|
|
5
6
|
}
|
|
6
7
|
/** Room above the plot for the top value marker, which is centred on the top grid line. */
|
|
7
8
|
export function headroom(style) {
|
|
8
|
-
return Math.ceil(style.
|
|
9
|
+
return Math.ceil(sizeOf(style.yLabelText) * 0.7);
|
|
9
10
|
}
|
|
10
11
|
/** How far an end marker of a horizontal value axis may hang past the plot: half a short caption. */
|
|
11
12
|
export function overhang(style) {
|
|
12
|
-
return Math.ceil(style.
|
|
13
|
+
return Math.ceil(sizeOf(style.xLabelText) * 1.1);
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
16
|
* The frame the line and bar charts share. A legend above or below is centred
|
|
@@ -39,6 +40,7 @@ export function cartesianFrame(parts) {
|
|
|
39
40
|
height: "fill",
|
|
40
41
|
gap: parts.gap,
|
|
41
42
|
padding: parts.padding,
|
|
43
|
+
...(parts.background ? { fill: parts.background } : {}),
|
|
42
44
|
children: [
|
|
43
45
|
...(legend && parts.legendAt === "top" ? [across(legend)] : []),
|
|
44
46
|
main,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cartesian.js","sourceRoot":"","sources":["../../src/kit/cartesian.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Rect,\n RotatedBox,\n Text,\n textOps,\n type ChildView,\n type Fill,\n type FillResolved,\n type Insets,\n type Node2D,\n type Size2D,\n type TextStyle,\n} from \"@motionscript/sdk\"\n\nimport type { CartesianStyle, LegendPosition } from \"./style\"\n\n/** Space between the frame's rows and columns: the plot and the legend, the axes and the legend. */\nexport function frameGap(style: Pick<CartesianStyle, \"fontSize\">): number {\n return Math.round(style.fontSize * 0.9)\n}\n\n/** Room above the plot for the top value marker, which is centred on the top grid line. */\nexport function headroom(style: Pick<CartesianStyle, \"fontSize\">): number {\n return Math.ceil(style.fontSize * 0.7)\n}\n\n/** How far an end marker of a horizontal value axis may hang past the plot: half a short caption. */\nexport function overhang(style: Pick<CartesianStyle, \"fontSize\">): number {\n return Math.ceil(style.fontSize * 1.1)\n}\n\ninterface CartesianParts {\n /** The axis beside the plot, on its left. */\n readonly left?: Node2D\n /** An invisible twin of `left` under the plot, so the row there starts at the plot's left edge. */\n readonly ghost?: Node2D\n /** The box the grid and the marks share. */\n readonly plot: Node2D\n /** The axis under the plot. */\n readonly bottom?: Node2D\n readonly legend?: Node2D\n readonly legendAt: LegendPosition\n readonly gap: () => number\n readonly padding: () => Insets\n}\n\n/**\n * The frame the line and bar charts share. A legend above or below is centred\n * on the whole chart; one on the right is a column beside the plot. An axis the\n * style turns off is simply not here, and the plot takes its room.\n */\nexport function cartesianFrame(parts: CartesianParts): Node2D {\n const top = new Rect({ flow: \"horizontal\", width: \"fill\", height: \"fill\", children: [...(parts.left ? [parts.left] : []), parts.plot] })\n const rows: Node2D[] = [top as unknown as Node2D]\n if (parts.bottom) {\n rows.push(new Rect({ flow: \"horizontal\", width: \"fill\", height: \"hug\", children: [...(parts.ghost ? [parts.ghost] : []), parts.bottom] }) as unknown as Node2D)\n }\n const body = new Rect({ flow: \"vertical\", width: \"fill\", height: \"fill\", children: rows })\n const legend = parts.legend && parts.legendAt !== \"none\" ? parts.legend : undefined\n const main = new Rect({\n flow: \"horizontal\",\n width: \"fill\",\n height: \"fill\",\n align: \"center\",\n gap: parts.gap,\n children: [body, ...(legend && parts.legendAt === \"right\" ? [legend] : [])],\n })\n const across = (node: Node2D) => new Rect({ flow: \"horizontal\", width: \"fill\", height: \"hug\", align: \"center\", children: [node] })\n return new Rect({\n flow: \"vertical\",\n width: \"fill\",\n height: \"fill\",\n gap: parts.gap,\n padding: parts.padding,\n children: [\n ...(legend && parts.legendAt === \"top\" ? [across(legend)] : []),\n main,\n ...(legend && parts.legendAt === \"bottom\" ? [across(legend)] : []),\n ],\n }) as unknown as Node2D\n}\n\n/** Every view under `children`, depth first in build order: the axis beside the plot comes before its twin, which holds no parts. */\nexport function chartViews(children: readonly ChildView[]): ChildView[] {\n const out: ChildView[] = []\n const walk = (views: readonly ChildView[]) => {\n for (const view of views) {\n out.push(view)\n walk(view.children)\n }\n }\n walk(children)\n return out\n}\n\n/** A part's laid-out size; zero before it is built or laid out. */\nexport function laidOutSize(node: Node2D | undefined): Size2D {\n const bounds = node?.layoutBounds\n return { width: bounds?.width ?? 0, height: bounds?.height ?? 0 }\n}\n\n/**\n * A text style as props bound to `read`, so a style tween reaches text built\n * once. Only the keys set at build are bound: an unset family stays unset, so\n * the host's default face still applies.\n */\nexport function boundText(read: () => TextStyle): Record<string, unknown> {\n const keys = Object.keys(textOps.styleProps(read())) as (keyof TextStyle)[]\n const props: Record<string, unknown> = {}\n for (const key of keys) props[key] = () => read()[key]\n return props\n}\n\ninterface GhostSpec {\n readonly captions: () => readonly string[]\n /** How many captions the real axis built. */\n readonly count: number\n readonly text: () => TextStyle\n readonly title: string\n readonly titleText: () => TextStyle\n readonly tickPad: () => number\n readonly titlePad: () => number\n}\n\n/**\n * An invisible column as wide as a vertical axis built from the same captions:\n * the widest caption plus the tick padding, and the rotated title before it. A\n * plain tree, so a command looking for the axis never finds this instead.\n */\nexport function columnGhost(spec: GhostSpec): Node2D {\n const captions = Array.from({ length: spec.count }, (_, i) => new Text({ ...boundText(spec.text), text: () => spec.captions()[i] ?? \"\" }))\n const children: Node2D[] = []\n if (spec.title !== \"\") {\n children.push(new RotatedBox({ angle: -90, width: \"hug\", height: \"hug\", children: new Text({ ...boundText(spec.titleText), text: spec.title }) }) as unknown as Node2D)\n }\n children.push(new Rect({ flow: \"vertical\", width: \"hug\", height: \"hug\", padding: () => ({ right: spec.tickPad() }), children: captions }) as unknown as Node2D)\n return new Rect({ opacity: 0, flow: \"horizontal\", gap: spec.titlePad, width: \"hug\", height: 0, children }) as unknown as Node2D\n}\n\n/** `fill` with every layer's opacity scaled by `k`. */\nexport function fade(fill: Fill, k: number): Fill {\n const layers = (Array.isArray(fill) ? fill : [fill]) as FillResolved[]\n return layers.map((layer) => (typeof layer === \"object\" && layer !== null ? { ...layer, opacity: ((layer as { opacity?: number }).opacity ?? 1) * k } : layer)) as Fill\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cartesian.js","sourceRoot":"","sources":["../../src/kit/cartesian.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Rect,\n RotatedBox,\n Text,\n textOps,\n type ChildView,\n type Fill,\n type FillResolved,\n type Insets,\n type Node2D,\n type Size2D,\n type TextStyle,\n} from \"@motionscript/sdk\"\n\nimport { sizeOf, type CartesianStyle, type LegendPosition } from \"./style\"\n\n/** Space between the frame's rows and columns: the plot and the legend, the axes and the legend. */\nexport function frameGap(style: Pick<CartesianStyle, \"legendText\">): number {\n return Math.round(sizeOf(style.legendText) * 0.9)\n}\n\n/** Room above the plot for the top value marker, which is centred on the top grid line. */\nexport function headroom(style: Pick<CartesianStyle, \"yLabelText\">): number {\n return Math.ceil(sizeOf(style.yLabelText) * 0.7)\n}\n\n/** How far an end marker of a horizontal value axis may hang past the plot: half a short caption. */\nexport function overhang(style: Pick<CartesianStyle, \"xLabelText\">): number {\n return Math.ceil(sizeOf(style.xLabelText) * 1.1)\n}\n\ninterface CartesianParts {\n /** Behind the whole chart, axes and legend included. */\n readonly background?: () => Fill\n /** The axis beside the plot, on its left. */\n readonly left?: Node2D\n /** An invisible twin of `left` under the plot, so the row there starts at the plot's left edge. */\n readonly ghost?: Node2D\n /** The box the grid and the marks share. */\n readonly plot: Node2D\n /** The axis under the plot. */\n readonly bottom?: Node2D\n readonly legend?: Node2D\n readonly legendAt: LegendPosition\n readonly gap: () => number\n readonly padding: () => Insets\n}\n\n/**\n * The frame the line and bar charts share. A legend above or below is centred\n * on the whole chart; one on the right is a column beside the plot. An axis the\n * style turns off is simply not here, and the plot takes its room.\n */\nexport function cartesianFrame(parts: CartesianParts): Node2D {\n const top = new Rect({ flow: \"horizontal\", width: \"fill\", height: \"fill\", children: [...(parts.left ? [parts.left] : []), parts.plot] })\n const rows: Node2D[] = [top as unknown as Node2D]\n if (parts.bottom) {\n rows.push(new Rect({ flow: \"horizontal\", width: \"fill\", height: \"hug\", children: [...(parts.ghost ? [parts.ghost] : []), parts.bottom] }) as unknown as Node2D)\n }\n const body = new Rect({ flow: \"vertical\", width: \"fill\", height: \"fill\", children: rows })\n const legend = parts.legend && parts.legendAt !== \"none\" ? parts.legend : undefined\n const main = new Rect({\n flow: \"horizontal\",\n width: \"fill\",\n height: \"fill\",\n align: \"center\",\n gap: parts.gap,\n children: [body, ...(legend && parts.legendAt === \"right\" ? [legend] : [])],\n })\n const across = (node: Node2D) => new Rect({ flow: \"horizontal\", width: \"fill\", height: \"hug\", align: \"center\", children: [node] })\n return new Rect({\n flow: \"vertical\",\n width: \"fill\",\n height: \"fill\",\n gap: parts.gap,\n padding: parts.padding,\n ...(parts.background ? { fill: parts.background } : {}),\n children: [\n ...(legend && parts.legendAt === \"top\" ? [across(legend)] : []),\n main,\n ...(legend && parts.legendAt === \"bottom\" ? [across(legend)] : []),\n ],\n }) as unknown as Node2D\n}\n\n/** Every view under `children`, depth first in build order: the axis beside the plot comes before its twin, which holds no parts. */\nexport function chartViews(children: readonly ChildView[]): ChildView[] {\n const out: ChildView[] = []\n const walk = (views: readonly ChildView[]) => {\n for (const view of views) {\n out.push(view)\n walk(view.children)\n }\n }\n walk(children)\n return out\n}\n\n/** A part's laid-out size; zero before it is built or laid out. */\nexport function laidOutSize(node: Node2D | undefined): Size2D {\n const bounds = node?.layoutBounds\n return { width: bounds?.width ?? 0, height: bounds?.height ?? 0 }\n}\n\n/**\n * A text style as props bound to `read`, so a style tween reaches text built\n * once. Only the keys set at build are bound: an unset family stays unset, so\n * the host's default face still applies.\n */\nexport function boundText(read: () => TextStyle): Record<string, unknown> {\n const keys = Object.keys(textOps.styleProps(read())) as (keyof TextStyle)[]\n const props: Record<string, unknown> = {}\n for (const key of keys) props[key] = () => read()[key]\n return props\n}\n\ninterface GhostSpec {\n readonly captions: () => readonly string[]\n /** How many captions the real axis built. */\n readonly count: number\n readonly text: () => TextStyle\n readonly title: string\n readonly titleText: () => TextStyle\n readonly tickPad: () => number\n readonly titlePad: () => number\n}\n\n/**\n * An invisible column as wide as a vertical axis built from the same captions:\n * the widest caption plus the tick padding, and the rotated title before it. A\n * plain tree, so a command looking for the axis never finds this instead.\n */\nexport function columnGhost(spec: GhostSpec): Node2D {\n const captions = Array.from({ length: spec.count }, (_, i) => new Text({ ...boundText(spec.text), text: () => spec.captions()[i] ?? \"\" }))\n const children: Node2D[] = []\n if (spec.title !== \"\") {\n children.push(new RotatedBox({ angle: -90, width: \"hug\", height: \"hug\", children: new Text({ ...boundText(spec.titleText), text: spec.title }) }) as unknown as Node2D)\n }\n children.push(new Rect({ flow: \"vertical\", width: \"hug\", height: \"hug\", padding: () => ({ right: spec.tickPad() }), children: captions }) as unknown as Node2D)\n return new Rect({ opacity: 0, flow: \"horizontal\", gap: spec.titlePad, width: \"hug\", height: 0, children }) as unknown as Node2D\n}\n\n/** `fill` with every layer's opacity scaled by `k`. */\nexport function fade(fill: Fill, k: number): Fill {\n const layers = (Array.isArray(fill) ? fill : [fill]) as FillResolved[]\n return layers.map((layer) => (typeof layer === \"object\" && layer !== null ? { ...layer, opacity: ((layer as { opacity?: number }).opacity ?? 1) * k } : layer)) as Fill\n}\n"]}
|