/** * BarChart — categories compared by length, drawn and animated on the UI thread. * * Composed the same way `LineChart` is: the grid, each series, the axes and the * readout are separate children, so a chart that wants no grid simply does not * have one. * * ```tsx * * * * * * * ``` * * ## What is different from a line * * **The baseline is zero, and not negotiable.** A line's job is to show change, * so it may crop its axis to the range the data actually occupies. A bar's job * is to compare *lengths*, and a bar cropped at the bottom is a length that * lies — twice as tall no longer means twice as much. So the domain always * reaches zero unless `yDomain` says otherwise, and saying otherwise is opting * into a chart that misreads. * * **Bands, not points.** A line has a point at each x; a bar owns a slice of * width around it. `barGap` is the fraction of that slice left empty, so bars * stay proportional at any width instead of needing a pixel gap that is wrong * on half of them. * * **Every series is one path.** A `Bar` draws all its rectangles as subpaths of * a single animated path, split in two so the band under the finger keeps full * ink while the rest fade. Fifty bars is two animated props a frame rather * than fifty, and the corners are drawn as a path because a bar is rounded on * the end it grows towards and square on the end it grows from — which `rx` * cannot express, since it rounds all four corners or none. */ 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 BarChartStatus = 'loading' | 'ready'; export type BarChartOrientation = 'vertical' | 'horizontal'; export type BarChartDatum = Record; /** * The band 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 useBarChart(): { activeIndex: number; activePoint: BarChartDatum | null; xDataKey: string; }; export interface BarChartProps extends ViewProps, ChartAccessibilityProps { className?: string; /** The rows. Each one is a band along the category axis. */ data: BarChartDatum[]; /** Key holding the category label. Used by the axis and the readout. */ xDataKey?: string; /** * `loading` holds the bars at the baseline and grows them 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 * `BarChart.Skeleton` for something to stand in the plot meanwhile. */ status?: BarChartStatus; /** Width ÷ height. `2` is the wide card shape. */ aspectRatio?: number; /** Milliseconds for the bars to grow in on mount. */ animationDuration?: number; /** Milliseconds for the value axis to settle after the data changes. */ domainDuration?: number; /** * Fix the value axis instead of deriving it. Note that the derived domain * always includes zero, and a domain that does not is a bar chart whose * lengths cannot be compared — pass this only when you mean it. */ yDomain?: [number, number]; /** `vertical` grows the bars upward; `horizontal` grows them rightward. */ orientation?: BarChartOrientation; /** Stack the series on each other instead of standing them side by side. */ stacked?: boolean; /** * Fraction of each band left empty, `0` to `1`. A fraction rather than a * pixel gap so the proportions hold at any width. */ barGap?: number; /** Fixed bar thickness in points. Derived from the band when omitted. */ barWidth?: number; /** Points between the segments of a stack. */ stackGap?: number; /** Corner radius on the growing 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 height says it did not. */ minBarLength?: number; /** Opacity of the bars that are not under the finger. */ fadedOpacity?: number; /** * The band under the finger as it moves, and `-1`/`null` when it lifts. * Fires when the index changes, not per frame. */ onActiveIndexChange?: (index: number, datum: BarChartDatum | null) => void; /** Drop the axis padding, for a bar sparkline with no axis or readout. */ compact?: boolean; children?: ReactNode; } /** Imperative handle: re-run the grow-in, for a "replay" control. */ export interface BarChartHandle { replay: () => void; } export interface BarChartGridProps { /** How many lines to draw across the value axis. */ rows?: number; color?: string; dashArray?: string; opacity?: number; } /** * Lines across the value axis, so a bar can be read against a number rather * than only against the bar beside it. */ declare function BarChartGrid({ rows, color, dashArray, opacity }: BarChartGridProps): import("react").JSX.Element; declare namespace BarChartGrid { var displayName: string; var layer: Layer; } export interface BarChartBarProps { /** Column in the data holding this series' values. */ dataKey: string; /** Explicit colour. Defaults to the `--color-chart-*` token for `colorIndex`. */ color?: string; /** Which of the five chart tokens to take. */ colorIndex?: SeriesColorIndex; /** Corner radius, overriding the chart's. */ cornerRadius?: number; } /** * One series of bars. * * Drawn as two paths rather than one rectangle per band: the band 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 BarChartBar({ dataKey, color, colorIndex, cornerRadius }: BarChartBarProps): import("react").JSX.Element; declare namespace BarChartBar { var displayName: string; var layer: Layer; } export interface BarChartSkeletonProps { /** * How many placeholder bars to draw. Defaults to one per row, and to seven * 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. */ bars?: number; /** Milliseconds for one pass of the sweep. */ duration?: number; color?: string; } /** * The loading state: a row of short, equal stubs on the baseline, with a * highlight travelling across them. * * Equal on purpose. Placeholder bars of differing heights 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 bars there will be and where the baseline is. * * The sweep is the part that carries the meaning. Without it a chart waiting * for data and a chart whose values are all zero draw the same picture, and * the reader is left to guess which one they are looking at. */ declare function BarChartSkeleton({ bars, duration, color }: BarChartSkeletonProps): import("react").JSX.Element | null; declare namespace BarChartSkeleton { var displayName: string; var layer: Layer; } export interface BarChartXAxisProps { /** * How many labels to show. Every category by default, thinned only when the * bands get too narrow to read — pass a number to force it lower. */ ticks?: number; /** Turn a row into its label. Defaults to the value at `xDataKey`. */ format?: (datum: BarChartDatum, index: number) => string; className?: string; } /** * The category labels, one under each band it has room for. Real text rather * than SVG text, so they follow the theme's font and the platform's text * scaling — SVG text does neither. */ declare function BarChartXAxis({ ticks, format, className }: BarChartXAxisProps): import("react").JSX.Element | null; declare namespace BarChartXAxis { var displayName: string; var layer: Layer; } export interface BarChartYAxisProps { /** How many labels to show along the value axis. */ ticks?: number; /** Format a value for its label. Defaults to a compact number. */ format?: (value: number) => string; className?: string; } /** Value labels down the side, aligned to the grid lines. */ declare function BarChartYAxis({ ticks, format, className }: BarChartYAxisProps): import("react").JSX.Element; declare namespace BarChartYAxis { var displayName: string; var layer: Layer; var axis: "y"; } export interface BarChartTooltipProps { /** 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: BarChartDatum) => string; className?: string; } /** * The readout, and the gesture that drives it. * * There is no crosshair. A line needs one because a point on a line has no * width of its own to point at; a bar is already the thing being pointed at, * so highlighting it 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 — and the thinner the bars, the truer that * gets. */ declare function BarChartTooltip({ formatValue, formatX, className }: BarChartTooltipProps): import("react").JSX.Element | null; declare namespace BarChartTooltip { var displayName: string; var layer: Layer; } export interface BarChartLegendProps 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 BarChartLegend({ className, labels, ...props }: BarChartLegendProps): import("react").JSX.Element | null; declare namespace BarChartLegend { var displayName: string; var layer: Layer; } export interface BarChartHeaderProps 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 * `BarChart.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 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 along the bars, and the * legend is the series list the chart itself is holding. The card's header is a * caption on the tray the chart sits in; this is the chart introducing itself. * * 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, so one header can show a total when nothing is pressed * and a band's value when something is. */ declare function BarChartHeader({ className, title, value, caption, labels, legend, children, ...props }: BarChartHeaderProps): import("react").JSX.Element; declare namespace BarChartHeader { var displayName: string; var layer: Layer; } export declare const BarChart: import("react").ForwardRefExoticComponent> & { Header: typeof BarChartHeader; Grid: typeof BarChartGrid; Bar: typeof BarChartBar; Skeleton: typeof BarChartSkeleton; XAxis: typeof BarChartXAxis; YAxis: typeof BarChartYAxis; Tooltip: typeof BarChartTooltip; Legend: typeof BarChartLegend; }; export {}; //# sourceMappingURL=index.d.ts.map