/**
* RingChart — progress towards several targets, as concentric arcs.
*
* ```tsx
*
*
*
*
*
*
* ```
*
* ## What it is not
*
* It is not a pie or a donut, and the difference matters. A pie divides one
* whole between its slices, so its parts are only meaningful against each
* other and the angles must add to a full turn. A ring here is a value against
* *its own* target — three rings can all be at ninety percent of three
* unrelated numbers, and that is the reading. Nothing is normalised across
* rings, and nothing has to add up.
*
* That is also why each ring gets a track. An arc drawn on nothing shows how
* far something went; an arc drawn on a full circle shows how far it went *of
* what it was aiming at*, which is the entire question.
*
* ## Drawing
*
* Each ring is two arcs — a track and the progress over it — with only the
* progress animated, through `strokeDasharray`. Sweeping the arc by rebuilding
* its path would work, but a dash offset is two numbers moving on an unchanged
* path, and it keeps the rounded cap pinned to the moving end for free.
*
* The same dash pattern is what makes the other two shapes possible without any
* more geometry. An open gauge is the pattern cut short of the circumference
* and the whole circle turned to put the gap where it is wanted; a segmented
* ring is the pattern repeated, one pair per tick. Both stay one `Circle`.
*
* Touch, not hover: a ring 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';
import { type SeriesColorIndex } from '../../utils/chart.js';
/** One ring per datum, and the datum is the whole of its contract. */
export interface RingDatum {
/** Name for the legend and the centre readout. */
label: string;
/** Where this ring has got to. */
value: number;
/** What it is aiming at. The ring is full when `value` reaches it. */
maxValue: number;
/** Explicit colour, overriding the `--color-chart-*` token. */
color?: string;
}
/** The selected ring, for something rendered inside the chart. */
export declare function useRingChart(): {
activeIndex: number;
activeRing: RingDatum | null;
};
export interface RingChartProps extends ViewProps {
className?: string;
/** One entry per ring, outermost first. */
data: RingDatum[];
/** Fixed diameter in points. Measured from the container when omitted. */
size?: number;
/** Thickness of each ring. */
strokeWidth?: number;
/** Gap between one ring and the next. */
ringGap?: number;
/**
* Where the arcs begin, in degrees clockwise from twelve o'clock. `0` is the
* top, `90` the right-hand side.
*/
startAngle?: number;
/**
* Where they end, on the same clock. Leaving a turn's worth between the two
* gives a closed ring; anything less leaves a gap and reads as a gauge —
* `startAngle={-90} endAngle={90}` is the half circle over the top.
*/
endAngle?: number;
/** Milliseconds for the arcs to sweep in. */
animationDuration?: number;
/** Selected ring. Leave unset to let the chart track it. */
activeIndex?: number;
/** Fires with the selected ring, or `-1` when the selection is cleared. */
onActiveIndexChange?: (index: number) => void;
children?: ReactNode;
}
/** Imperative handle: re-run the sweep, for a "replay" control. */
export interface RingChartHandle {
replay: () => void;
}
export interface RingChartRingProps {
/** Which entry in `data` this ring draws. */
index: number;
/** Explicit colour, overriding the datum's and the token. */
color?: string;
/** Which of the five chart tokens to take, when the datum names no colour. */
colorIndex?: SeriesColorIndex;
/**
* Rounded ends, or square ones. Defaults to round, and to square when the
* ring is segmented — a rounded cap on a tick as long as it is wide draws a
* lozenge rather than a tick.
*/
lineCap?: 'round' | 'butt';
/** Opacity of the track behind the arc. */
trackOpacity?: number;
/**
* Break the ring into this many ticks, lit one at a time as the value
* climbs. For a target made of countable things — eight of twelve sessions
* reads off ticks you can count, and off a smooth arc only as "about two
* thirds".
*/
segments?: number;
/** Gap between one tick and the next, in points. */
segmentGap?: number;
}
/**
* One ring: a full-circle track, and the arc showing how far along it the
* value has got.
*
* The arc is swept with `strokeDasharray` rather than by rebuilding its path.
* Both work, but a dash offset moves two numbers on a path that never changes
* — and it keeps the rounded cap pinned to the moving end without any extra
* geometry.
*/
declare function RingChartRing({ index, color, colorIndex, lineCap, trackOpacity, segments, segmentGap, }: RingChartRingProps): import("react").JSX.Element | null;
declare namespace RingChartRing {
var displayName: string;
var slot: "ring";
}
export interface RingChartCenterProps {
/**
* Heading shown when no ring is selected. Defaults to the outermost ring's
* own name, which is what the centre shows when nothing has been picked.
*/
defaultLabel?: string;
/** Format the number under the label. Defaults to a compact number. */
formatValue?: (value: number, ring: RingDatum | null) => string;
/**
* Draw the middle yourself. Given the selected ring, or `null` when nothing
* is selected.
*/
children?: (ring: RingDatum | null) => ReactNode;
className?: string;
}
/**
* The readout in the hole.
*
* With nothing selected it shows the outermost ring — the one the eye lands on
* first. Not a total: the rings measure different things against different
* targets, so their values do not add up and their percentages do not average,
* and a total here would be a confident number about nothing. Selecting a ring
* swaps it for that ring's own figures.
*/
declare function RingChartCenter({ defaultLabel, formatValue, children, className, }: RingChartCenterProps): import("react").JSX.Element;
declare namespace RingChartCenter {
var displayName: string;
var slot: "overlay";
}
export interface RingChartLegendProps extends ViewProps {
className?: string;
/** Show each ring's percentage of its own target beside its name. */
showValue?: boolean;
}
/**
* A swatch and a name per ring, pressable in the same way the rings are — the
* legend is usually the easier target of the two, and on a small chart it is
* the only comfortable one.
*/
declare function RingChartLegend({ className, showValue, ...props }: RingChartLegendProps): import("react").JSX.Element | null;
declare namespace RingChartLegend {
var displayName: string;
var slot: "overlay";
}
export interface RingChartHeaderProps 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 target. */
caption?: string;
/** Prettier names for the rings, keyed by their `label`. */
labels?: Record;
/**
* Draw a swatch and a name per ring along the trailing edge. Prefer this to
* `RingChart.Legend` on a chart that has a header: that legend hangs off the
* bottom of the square, where it overlaps whatever is under the chart.
*/
legend?: boolean;
/** Trailing slot — a control, a badge, a range picker. Wins over `legend`. */
children?: ReactNode;
}
/**
* The strip above the rings: 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 *rings* — 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. There is no total to derive: the rings measure
* different things against different targets. Take it from `onActiveIndexChange`
* and pass the formatted string down, so one header can show the headline figure
* when nothing is selected and a ring's own when something is.
*/
declare function RingChartHeader({ className, title, value, caption, labels, legend, children, ...props }: RingChartHeaderProps): import("react").JSX.Element;
declare namespace RingChartHeader {
var displayName: string;
var slot: "header";
}
export declare const RingChart: import("react").ForwardRefExoticComponent> & {
Header: typeof RingChartHeader;
Ring: typeof RingChartRing;
Center: typeof RingChartCenter;
Legend: typeof RingChartLegend;
};
export {};
//# sourceMappingURL=index.d.ts.map