/**
* 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