/** * PyramidChart — two series mirrored about a centre line, drawn and animated on * the UI thread. * * ```tsx * * * * * * * * * ``` * * ## The two wings share one scale * * This is the whole contract, and everything else here follows from it. The * domain is derived from the larger of the two series' extents and used by * both, so a bar twice as long as the one facing it means twice as much. * Scaling each side to its own maximum produces a chart whose halves cannot be * compared — which is the only thing a pyramid is for. * * For the same reason the centre is zero and stays there. There is no `yDomain` * that starts anywhere else, because a wing cropped at its base is a length * that lies. * * ## Lengths, not signed values * * Which side a series is on comes from `side`, not from the sign of its * numbers, so a value is a distance outward from the centre. A negative one has * no direction left to grow in and is drawn as nothing; it still appears in the * readout, so a data error shows up as a gap rather than as a bar pointing the * wrong way. * * ## Where the category names go * * `labelPlacement="above"`, the default, gives each row a line of its own over * its pair of bars. That leaves the two wings meeting in the middle with * nothing standing between them, and puts the name where it is read before the * lengths it belongs to rather than beside them. * * `"center"` puts the names in a gutter between the wings instead — taken off * the bars rather than off the edges, so both wings stay equal — and `"start"` * puts them down the left, for a chart with room to spare on that side. * * ## Every series is one path * * A `Bar` draws all its rectangles as subpaths of a single animated path, split * in two so the row under the finger keeps full ink while the rest fade. Thirty * rows is two animated props a frame rather than thirty. */ import { type ReactNode } from 'react'; import { type ViewProps } from 'react-native'; import { type ChartAccessibilityProps } from '../../primitives/chart-accessibility.js'; import { type SeriesColorIndex } from '../../utils/chart.js'; type Layer = 'svg' | 'overlay' | 'header'; export type PyramidChartStatus = 'loading' | 'ready'; /** Which wing a series grows into. */ export type PyramidChartSide = 'start' | 'end'; /** Where the category names sit. */ export type PyramidChartLabelPlacement = 'above' | 'center' | 'start'; export type PyramidChartDatum = Record; /** * The row under the finger, for something rendered *inside* the chart. A * readout in the card's header is outside this provider — use * `onActiveIndexChange` for that. */ export declare function usePyramidChart(): { activeIndex: number; activePoint: PyramidChartDatum | null; xDataKey: string; }; export interface PyramidChartProps extends ViewProps, ChartAccessibilityProps { className?: string; /** The rows. Each one is a band across the chart, with a wing either side. */ data: PyramidChartDatum[]; /** Key holding the category label. Used by the axis and the readout. */ xDataKey?: string; /** * `loading` holds the bars at the centre and grows them out into the real * ones when it turns `ready`. One component throughout, rather than a spinner * swapped for a chart — swapping loses the transition. Add a * `PyramidChart.Skeleton` for something to stand in the plot meanwhile. */ status?: PyramidChartStatus; /** Width ÷ height. `1.2` suits three or four rows in a card. */ aspectRatio?: number; /** Milliseconds for the bars to grow out on mount. */ animationDuration?: number; /** Milliseconds for the scale to settle after the data changes. */ domainDuration?: number; /** * Fix the far end of the shared scale instead of deriving it. The near end is * zero either way — a pyramid measures outward from its centre. */ maxValue?: number; /** * Where the category names sit. `above`, the default, gives each row a line * of its own over its pair of bars, so the two wings meet in the middle with * nothing standing between them. `center` puts the names in a gutter between * the wings instead, and `start` down the left edge. */ labelPlacement?: PyramidChartLabelPlacement; /** * Fraction of each band left empty, `0` to `1`. A fraction rather than a * pixel gap so the proportions hold at any height. */ barGap?: number; /** Fixed bar thickness in points. Derived from the band when omitted. */ barWidth?: number; /** Corner radius on the outward end of a bar. */ cornerRadius?: number; /** * Smallest length a non-zero bar is drawn at, in points. A value that rounds * to nothing still happened, and a bar of zero length says it did not. */ minBarLength?: number; /** Opacity of the rows that are not under the finger. */ fadedOpacity?: number; /** * The row under the finger as it moves, and `-1`/`null` when it lifts. * Fires when the index changes, not per frame. */ onActiveIndexChange?: (index: number, datum: PyramidChartDatum | null) => void; children?: ReactNode; } /** Imperative handle: re-run the grow-out, for a "replay" control. */ export interface PyramidChartHandle { replay: () => void; } export interface PyramidChartGridProps { /** How many lines to draw per wing, not counting the centre. */ columns?: number; color?: string; dashArray?: string; opacity?: number; /** Draw the solid line down the middle the wings are measured from. */ centreLine?: boolean; } /** * Lines up the value axis, mirrored, so a bar can be read against a number * rather than only against the bar facing it. * * The centre line is drawn solid and undashed where the others are dashed: it * is not a tick, it is the zero both wings are measured from. */ declare function PyramidChartGrid({ columns, color, dashArray, opacity, centreLine, }: PyramidChartGridProps): import("react").JSX.Element; declare namespace PyramidChartGrid { var displayName: string; var layer: Layer; } export interface PyramidChartBarProps { /** Column in the data holding this series' values. */ dataKey: string; /** Which wing it grows into. */ side?: PyramidChartSide; /** Explicit colour. Defaults to the `--color-chart-*` token for `colorIndex`. */ color?: string; /** * Which of the five chart tokens to take. Defaults to a different one per * side, so two bars declared with nothing but a `dataKey` and a `side` are * already told apart. */ colorIndex?: SeriesColorIndex; /** Corner radius, overriding the chart's. */ cornerRadius?: number; } /** * One wing. * * Drawn as two paths rather than one rectangle per row: the row under the * finger, and everything else. That is the fewest animated props that can still * dim the rest — one path could not, since a path has one opacity, and a view * per bar would be one animated prop per bar for the same picture. */ declare function PyramidChartBar({ dataKey, side, color, colorIndex, cornerRadius, }: PyramidChartBarProps): import("react").JSX.Element; declare namespace PyramidChartBar { var displayName: string; var layer: Layer; } export interface PyramidChartSkeletonProps { /** * How many placeholder rows to draw. Defaults to one per row of data, and to * five when the data has not arrived — the count is the one thing a loading * chart can be honest about only if it already has the rows. */ rows?: number; /** Milliseconds for one pass of the sweep. */ duration?: number; color?: string; } /** * The loading state: equal stubs either side of the centre, with a highlight * travelling across them. * * Equal on purpose. Placeholder wings of differing lengths are a distribution * the reader has no way to tell from the real one until it changes under them, * so these say only how many rows there will be and where the centre is. */ declare function PyramidChartSkeleton({ rows, duration, color }: PyramidChartSkeletonProps): import("react").JSX.Element | null; declare namespace PyramidChartSkeleton { var displayName: string; var layer: Layer; } export interface PyramidChartXAxisProps { /** How many labels per wing, not counting the zero in the middle. */ ticks?: number; /** Format a value for its label. Defaults to a compact number. */ format?: (value: number) => string; className?: string; } /** * The value labels along the bottom, mirrored either side of a zero in the * middle — the same magnitudes twice, because both wings are read outward from * the centre rather than along one continuous axis. * * Real text rather than SVG text, so the labels follow the theme's font and the * platform's text scaling. SVG text does neither. */ declare function PyramidChartXAxis({ ticks, format, className }: PyramidChartXAxisProps): import("react").JSX.Element | null; declare namespace PyramidChartXAxis { var displayName: string; var layer: Layer; } export interface PyramidChartYAxisProps { /** Turn a row into its label. Defaults to the value at `xDataKey`. */ format?: (datum: PyramidChartDatum, index: number) => string; className?: string; } /** * The category names, one per row. * * `above` puts each name on its own line over the pair of bars it belongs to, * which leaves the two wings meeting in the middle — the name is read first and * the bars are then read outward from a centre nothing is standing in. * * One box per band rather than a spaced column, in every placement: a row owns * a *band*, so names spread evenly would be half a band out at the top and * bottom. */ declare function PyramidChartYAxis({ format, className }: PyramidChartYAxisProps): import("react").JSX.Element | null; declare namespace PyramidChartYAxis { var displayName: string; var layer: Layer; var axis: "y"; } export interface PyramidChartTooltipProps { /** Format one series' value. Defaults to a compact number. */ formatValue?: (value: number, key: string) => string; /** Format the readout's heading from the row. Defaults to the value at xDataKey. */ formatX?: (datum: PyramidChartDatum) => string; className?: string; } /** * The readout, and the gesture that drives it. * * There is no crosshair. A bar is already the thing being pointed at, so * highlighting its row and dimming the rest says the same thing without drawing * a line through the chart. * * The hit area is the whole plot. A readout you have to land on the bar to * summon is a readout nobody finds. */ declare function PyramidChartTooltip({ formatValue, formatX, className, }: PyramidChartTooltipProps): import("react").JSX.Element | null; declare namespace PyramidChartTooltip { var displayName: string; var layer: Layer; } export interface PyramidChartLegendProps extends ViewProps { className?: string; /** Prettier names for the series keys. */ labels?: Record; } /** A swatch and a name per series, in the order the series were declared. */ declare function PyramidChartLegend({ className, labels, ...props }: PyramidChartLegendProps): import("react").JSX.Element | null; declare namespace PyramidChartLegend { var displayName: string; var layer: Layer; } export interface PyramidChartHeaderProps extends ViewProps { className?: string; /** Small line above the value — what the chart is of. */ title?: string; /** The readout. The largest thing on the card, and the first thing read. */ value?: string; /** One muted line under the value — a period, a comparison, a total. */ caption?: string; /** Prettier names for the series keys, as the legend takes. */ labels?: Record; /** * Draw a swatch and a name per series along the trailing edge. Prefer this to * `PyramidChart.Legend` on a chart that has a header: the legend floats over * the plot, where it competes with the bars for the same corner. */ legend?: boolean; /** Trailing slot — a control, a badge, a range picker. Wins over `legend`. */ children?: ReactNode; } /** * The strip above the plot: what the chart is of, what it currently reads, and * what the two colours mean. * * It belongs to the chart rather than to the card around it because it is about * the *plot* — the number changes as a finger moves down the rows, and the * legend is the series list the chart itself is holding. * * The value is not derived here. A readout that follows the finger belongs to * whoever owns the data — take it from `onActiveIndexChange` and pass the * formatted string down. */ declare function PyramidChartHeader({ className, title, value, caption, labels, legend, children, ...props }: PyramidChartHeaderProps): import("react").JSX.Element; declare namespace PyramidChartHeader { var displayName: string; var layer: Layer; } export declare const PyramidChart: import("react").ForwardRefExoticComponent> & { Header: typeof PyramidChartHeader; Grid: typeof PyramidChartGrid; Bar: typeof PyramidChartBar; Skeleton: typeof PyramidChartSkeleton; XAxis: typeof PyramidChartXAxis; YAxis: typeof PyramidChartYAxis; Tooltip: typeof PyramidChartTooltip; Legend: typeof PyramidChartLegend; }; export {}; //# sourceMappingURL=index.d.ts.map