/**
* PieChart — one whole, divided between its parts.
*
* ```tsx
*
*
*
*
*
* ```
*
* ## What it is, against the ring beside it
*
* A ring chart draws a value against *its own* target, so three rings can all
* sit at ninety percent of three unrelated numbers and nothing has to add up.
* A pie is the opposite claim: every slice is a share of one total, the angles
* must come to a full turn, and a slice only means anything next to the others.
* That is why nothing here takes a `maxValue` and why every value is normalised
* against the sum — the sum *is* the subject.
*
* It follows that a pie is the wrong shape for a great many things. Two numbers
* that do not belong to one whole, a series over time, anything a reader has to
* compare precisely: all of those are a bar chart, because an angle is the
* hardest quantity to read off a page and the fifth-largest slice of eleven is
* not a fact anybody is going to extract. Use it for a handful of parts of one
* obvious total, and put the number in the middle.
*
* ## Drawing
*
* Each slice is a filled path rather than a stroked arc, because a slice is a
* *region* — two arcs and two radial edges — and a stroke is a band of even
* thickness with no ends of its own. `wedgePath` builds it, and rebuilds it on
* the UI thread on every frame of the reveal.
*
* That is what makes the reveal an unroll rather than a fade: one angle sweeps
* clockwise from the start and each slice is drawn only as far as it has got
* to. The pie fills the way it would be drawn by hand, and the slices arrive in
* the order they are listed rather than all at once.
*
* Touch, not hover: a slice is selected by pressing it, and pressing the same
* one again clears the selection. There is no equivalent of a pointer resting
* somewhere without committing, so a chart that only revealed its numbers on
* hover would never reveal them at all.
*/
import { type ReactNode } from 'react';
import { type ViewProps } from 'react-native';
/** Whether the chart is showing data or waiting for it. */
export type PieChartStatus = 'loading' | 'ready';
/** One slice. Its share is worked out from the others, so there is no maximum. */
export interface PieDatum {
/** Name for the legend, the centre readout and the accessibility label. */
label: string;
/** How much of the whole this slice is. Negatives are treated as zero. */
value: number;
/** Explicit colour, overriding the `--color-chart-*` token. */
color?: string;
}
/** The selected slice and its share, for something rendered inside the chart. */
export declare function usePieChart(): {
activeIndex: number;
activeSlice: PieDatum | null;
/** The selected slice's share of the whole, 0 to 1. */
activeFraction: number;
};
export interface PieChartProps extends ViewProps {
className?: string;
/** One entry per slice, in the order they are drawn clockwise. */
data: PieDatum[];
/** Fixed diameter in points. Measured from the container when omitted. */
size?: number;
/**
* The hole, as a share of the radius. `0` is a pie; anything above it is a
* donut, and `0.55`–`0.65` is the range that leaves room for a readout in the
* middle without the band getting thin enough to be hard to hit.
*
* Given as a share rather than in points so a chart keeps its proportions at
* whatever size it is measured at.
*/
innerRadius?: number;
/** Where the first slice begins, in degrees clockwise from twelve o'clock. */
startAngle?: number;
/**
* Where the last one ends, on the same clock. Leaving a turn's worth between
* the two gives a closed pie; anything less leaves a gap and reads as a dial.
*/
endAngle?: number;
/** Gap between one slice and the next, in degrees. */
padAngle?: number;
/**
* The smallest angle any non-zero slice is drawn at, in degrees.
*
* A slice worth a fifth of a percent is a hairline nobody can see and nobody
* can press, so it reads as missing rather than as small — and "missing" is a
* different claim from "nearly none". The angle it borrows comes off the
* others in proportion, so the turn still closes.
*/
minAngle?: number;
/** Milliseconds for the pie to unroll. */
animationDuration?: number;
/** `loading` draws a plain muted ring until the data arrives. */
status?: PieChartStatus;
/** Selected slice. Leave unset to let the chart track it. */
activeIndex?: number;
/** Fires with the selected slice, or `-1` when the selection is cleared. */
onActiveIndexChange?: (index: number) => void;
children?: ReactNode;
}
/** Imperative handle: re-run the unroll, for a "replay" control. */
export interface PieChartHandle {
replay: () => void;
}
export interface PieChartSlicesProps {
/** Rounds the four turns of each slice, in points. */
cornerRadius?: number;
/** How far a selected slice lifts out of the pie, in points. */
popOut?: number;
/** Opacity of the slices that are not selected, once one is. */
dimOpacity?: number;
}
/**
* Every slice, drawn in the order the data lists them.
*
* One part rather than one per datum, unlike the rings next door. A ring is
* configured on its own — its own thickness, its own cap, its own segment count
* — because it is its own measurement. Slices of a pie are not: they share a
* radius, a hole and a dial by definition, and a chart where one of them could
* be given a different radius would be a chart drawing a lie.
*/
declare function PieChartSlices({ cornerRadius, popOut, dimOpacity, }: PieChartSlicesProps): import("react").JSX.Element | null;
declare namespace PieChartSlices {
var displayName: string;
var slot: "svg";
}
export interface PieChartSkeletonProps {
color?: string;
}
/**
* The loading state: the dial as one plain band, with nothing divided up yet.
*
* Deliberately undivided. Placeholder slices would be a made-up split, and a
* reader has no way to tell an invented one from a real one until it changes
* under them — which is worse than showing nothing, because it is showing
* something wrong.
*/
declare function PieChartSkeleton({ color }: PieChartSkeletonProps): import("react").JSX.Element | null;
declare namespace PieChartSkeleton {
var displayName: string;
var slot: "svg";
}
export interface PieChartCenterProps {
/** Heading shown when no slice is selected. */
defaultLabel?: string;
/** Format the number under the label. Defaults to a compact number. */
formatValue?: (value: number, slice: PieDatum | null) => string;
/**
* Draw the middle yourself. Given the selected slice, or `null` when nothing
* is selected.
*/
children?: (slice: PieDatum | null) => ReactNode;
className?: string;
}
/**
* The hole's readout: the total, and the selected slice's own figures once one
* is picked.
*
* Unlike the ring chart's centre, the default here *is* an aggregate, and it is
* the honest one — the whole point of a pie is that its parts belong to a total,
* so the total is the number the chart is about. Selecting a slice swaps it for
* that slice's value and its share.
*/
declare function PieChartCenter({ defaultLabel, formatValue, children, className, }: PieChartCenterProps): import("react").JSX.Element | null;
declare namespace PieChartCenter {
var displayName: string;
var slot: "overlay";
}
export interface PieChartLegendProps extends ViewProps {
className?: string;
/** Show each slice's share of the whole beside its name. */
showValue?: boolean;
}
/**
* A swatch, a name and a share per slice, under the chart and across the width
* of it. Pressable in the same way the slices are — the legend is usually the
* easier target of the two, and a slice worth a couple of percent is not a
* target at all.
*
* It wraps rather than stacking, so five or six entries take two lines instead
* of six. A key is a lookup table, and a lookup table read down a column of one
* word each is a column the eye has to walk.
*/
declare function PieChartLegend({ className, showValue, ...props }: PieChartLegendProps): import("react").JSX.Element | null;
declare namespace PieChartLegend {
var displayName: string;
var slot: "footer";
}
export interface PieChartHeaderProps 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 caveat. */
caption?: string;
/** Prettier names for the slices, keyed by their `label`. */
labels?: Record;
/**
* Draw a swatch and a name per slice along the trailing edge.
*
* For two or three short names. Past that use `PieChart.Legend`, which runs
* under the chart across the full width: a key of five long names crammed
* into the trailing corner of a header wraps to a column and leaves the title
* beside it a few points wide.
*/
legend?: boolean;
/** Trailing slot — a control, a badge, a range picker. Wins over `legend`. */
children?: ReactNode;
}
/**
* The strip above the pie: what the chart is of, what it reads, and what the
* colours mean.
*
* It belongs to the chart rather than to the card around it because it is about
* the *slices* — the number changes as one is selected, and the legend is the
* 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 even though there is a total to derive it from,
* because the formatting is not the chart's to guess: a total of 18420 is a
* count, a currency or a percentage depending on what was counted, and only the
* caller knows which.
*/
declare function PieChartHeader({ className, title, value, caption, labels, legend, children, ...props }: PieChartHeaderProps): import("react").JSX.Element;
declare namespace PieChartHeader {
var displayName: string;
var slot: "header";
}
export declare const PieChart: import("react").ForwardRefExoticComponent> & {
Header: typeof PieChartHeader;
Slices: typeof PieChartSlices;
Center: typeof PieChartCenter;
Legend: typeof PieChartLegend;
Skeleton: typeof PieChartSkeleton;
};
export {};
//# sourceMappingURL=index.d.ts.map