/**
* RadarChart — several measures of one thing, on one shape.
*
* A radar answers a question a bar chart cannot: not "which of these is
* biggest" but "what shape is this". Five scores read as five bars are five
* facts; read as a polygon they are a profile, and two profiles laid over each
* other are comparable at a glance in a way two groups of bars never are.
*
* ```tsx
*
*
*
*
*
*
*
* ```
*
* That is also the shape's limit, and worth saying out loud: the order of the
* axes changes the outline, and the outline is what people read. Two datasets
* are only comparable on one radar if the axes are in the same order, and a
* radar is the wrong chart for data whose axes have no natural order at all.
*
* The reveal grows the polygons out of the centre rather than sweeping across
* them, because a polar chart has no left-hand edge for a sweep to start at.
* Everything below the root is drawn on the UI thread.
*/
import { type ReactNode } from 'react';
import { type ViewProps } from 'react-native';
import { type SharedValue } from 'react-native-reanimated';
import { type ChartAccessibilityProps } from '../../primitives/chart-accessibility.js';
import { type SeriesColorIndex } from '../../utils/chart.js';
export type RadarChartStatus = 'loading' | 'ready';
/** One row is one axis: its label, and one value per series. */
export type RadarChartDatum = Record;
interface RadarChartContextValue {
data: RadarChartDatum[];
axisKey: string;
/** Centre of the rings, in view coordinates. */
cx: number;
cy: number;
/** Radius of the outermost ring. */
radius: number;
/** The drawing box, so a label can be kept inside it rather than clipped. */
width: number;
height: number;
status: RadarChartStatus;
/** The value the outermost ring stands for, tweened. */
domainMax: SharedValue;
/** …and the innermost, which is usually but not always zero. */
domainMin: SharedValue;
reveal: SharedValue;
series: [string, string][];
registerSeries: (key: string, color: string) => void;
unregisterSeries: (key: string) => void;
}
/** The chart's geometry and data, for a part or a readout beside one. */
export declare function useRadarChart(): RadarChartContextValue;
export interface RadarChartProps extends Omit {
className?: string;
/** One row per axis, in the order they go round. */
data: RadarChartDatum[];
/** Key holding each row's axis label. */
axisKey?: string;
/**
* `loading` holds the shape at the centre until the data arrives, then grows
* it — one component throughout rather than a spinner swapped for a chart,
* because swapping loses the transition.
*/
status?: RadarChartStatus;
/**
* Diameter of the outermost ring, in points. The view is that plus the room
* the axis labels need around it, and centres itself.
*
* The ring rather than the box, because the ring is the thing being sized —
* a box measurement would mean "bigger" also meant "labels further from the
* shape", and the chart would grow without the drawing growing with it.
*
* Pass `size={undefined}` with an `aspectRatio` to fill the container the
* way the other charts do.
*/
size?: number;
/**
* Width ÷ height when `size` is not given. `1` is the square a radar wants;
* the rings stay circular whatever it is set to.
*/
aspectRatio?: number;
/**
* Fix the scale instead of deriving it from the data. A radar almost always
* wants this: the shape only means something against a known maximum, and a
* scale that moves with the data makes two charts incomparable.
*/
domain?: [number, number];
/** Milliseconds for the reveal on mount. */
animationDuration?: number;
/** Drop the room reserved for axis labels, for a radar with none. */
compact?: boolean;
children?: ReactNode;
/** Accessible data labels and optional activation for each axis row. */
accessibilityLabelForDatum?: ChartAccessibilityProps['accessibilityLabelForDatum'];
onAccessibilityDatumPress?: ChartAccessibilityProps['onAccessibilityDatumPress'];
}
/** Imperative handle: re-run the reveal on demand, for a "replay" control. */
export interface RadarChartHandle {
replay: () => void;
}
export interface RadarChartGridProps {
/** How many rings, including the outermost. */
rings?: number;
/** Overrides the themed hairline colour. */
color?: string;
/** Draw the rings as circles rather than as polygons through the spokes. */
circular?: boolean;
/** Draw a line from the centre out to each axis. */
spokes?: boolean;
}
/**
* The scale, drawn as rings.
*
* Polygonal by default rather than circular, because the rings are read
* against the shape laid over them — a round ring behind an angular polygon
* gives every axis a different apparent distance to the edge, and the whole
* point of the rings is to say how far out something is.
*/
declare function RadarChartGrid({ rings, color, circular, spokes, }: RadarChartGridProps): import("react").JSX.Element | null;
declare namespace RadarChartGrid {
var displayName: string;
}
export interface RadarChartAxisProps {
/** Overrides the themed label colour. */
color?: string;
/** Label size in points. */
fontSize?: number;
/** How far outside the rings the labels sit. */
offset?: number;
/** Rewrites a label — to shorten it, or to add a unit. */
formatLabel?: (label: string, index: number) => string;
}
/**
* The axis names, placed around the rings.
*
* Each label is anchored by which side of the circle it is on rather than
* centred on its point: a label centred at three o'clock overlaps the shape it
* belongs to, and one centred at nine o'clock overlaps the view's edge.
*/
declare function RadarChartAxis({ color, fontSize, offset, formatLabel }: RadarChartAxisProps): import("react").JSX.Element | null;
declare namespace RadarChartAxis {
var displayName: string;
}
export interface RadarChartSeriesProps {
/** Key holding this series' value on each row. */
dataKey: string;
/** Name for the legend. Defaults to `dataKey`. */
name?: string;
/**
* Stroke colour. Defaults to the `--color-chart-*` token at `colorIndex`, so
* a series follows the theme without the call site naming a colour.
*/
color?: string;
/** Which `--color-chart-*` token to take when `color` is not given. */
colorIndex?: SeriesColorIndex;
strokeWidth?: number;
/**
* Opacity of the fill. Two filled polygons over each other make a third
* colour that means nothing, so drop it towards `0` — or to `0` — on the
* second and subsequent series.
*/
fillOpacity?: number;
/** A dot at each vertex. Worth it on a radar with few axes. */
showDots?: boolean;
}
/** One profile. */
declare function RadarChartSeries({ dataKey, name, color, colorIndex, strokeWidth, fillOpacity, showDots, }: RadarChartSeriesProps): import("react").JSX.Element;
declare namespace RadarChartSeries {
var displayName: string;
}
export interface RadarChartHeaderProps {
className?: string;
/** Small caption above the value. */
title?: string;
/** The headline figure, if there is one. */
value?: string;
/** A line under the value. */
caption?: string;
/** Draw the series legend on the trailing end of the strip. */
legend?: boolean;
children?: ReactNode;
}
/** The strip above the rings. */
declare function RadarChartHeader({ className, title, value, caption, legend, children, }: RadarChartHeaderProps): import("react").JSX.Element;
declare namespace RadarChartHeader {
var displayName: string;
}
export interface RadarChartLegendProps {
className?: string;
/** Rewrites a series' name — the key is rarely what a reader should see. */
formatName?: (key: string) => string;
}
/**
* The series, named and coloured.
*
* In the bottom-left of the plot rather than under it, which on a radar costs
* nothing: the shape is a circle in a square box, so the corners are empty by
* construction. Move it with `className`.
*/
declare function RadarChartLegend({ className, formatName }: RadarChartLegendProps): import("react").JSX.Element | null;
declare namespace RadarChartLegend {
var displayName: string;
}
export declare const RadarChart: import("react").ForwardRefExoticComponent> & {
Header: typeof RadarChartHeader;
Grid: typeof RadarChartGrid;
Axis: typeof RadarChartAxis;
Series: typeof RadarChartSeries;
Legend: typeof RadarChartLegend;
};
export {};
//# sourceMappingURL=index.d.ts.map