/**
* LiveLineChart — a reading that keeps arriving, against a window that keeps
* moving.
*
* ```tsx
*
*
*
*
*
*
*
* ```
*
* ## What it is, against the line chart beside it
*
* `LineChart` places a point by its position in the list, which is right for a
* series of twelve months whatever the gaps between the dates behind them. Here
* a point is placed at the time it carries, against a domain that runs from
* `window` seconds ago to now — so the gaps are the subject, and a reading that
* arrived late sits where it arrived rather than one slot along.
*
* ## The clock, and what it costs
*
* This is the only thing in the library that animates without an interaction or
* a change of data. The window is tied to the wall clock, so the line drifts
* left whether or not anything is arriving, and a feed that stalls shows as a
* flat run reaching back from the tip rather than as a chart that has frozen.
* Those two look identical if the window only moves when a point lands, and
* they mean opposite things.
*
* The cost is a frame callback for as long as the chart is mounted. It is
* stopped by `paused`, by `status="loading"`, while the app is backgrounded
* and on unmount, and it is never started when the platform asks for reduced
* motion — in that case the window advances as each point arrives instead,
* which is the same picture sampled less often.
*
* Screen readers receive one image-role snapshot: its name, current or
* selected value, direction, time window and paused state. It changes when the
* React data changes, never on the UI-thread clock frame, and requests no live
* announcement. The visual axes, badges and tooltip repeat that snapshot and
* stay out of the accessibility tree; controls placed in Header remain normal
* controls.
*
* ## Colour follows the recent direction
*
* With `momentumColors` set, the line, the fill and the tip take their colour
* from where the reading has been going rather than from a fixed hue. It is the
* one thing on the chart readable without looking at the axis, which is what a
* number being watched out of the corner of an eye needs.
*/
import { type ReactNode } from 'react';
import { type ViewProps } from 'react-native';
import { type ChartCurve } from '../../utils/chart.js';
/** Which layer a part belongs to. Read off the component itself. */
type Layer = 'svg' | 'overlay' | 'header';
/** Whether the chart is showing data or waiting for it. */
export type LiveLineChartStatus = 'loading' | 'ready';
/** Where the reading has been going, over the last few points. */
export type LiveLineMomentum = 'up' | 'down' | 'flat';
/** A colour per direction, for a chart that is read by its colour. */
export interface LiveLineMomentumColors {
up?: string;
down?: string;
flat?: string;
}
/** One reading. `time` is a timestamp in milliseconds, as `Date.now()` gives. */
export interface LiveLinePoint {
time: number;
value: number;
}
/** The reading under the crosshair, for something rendered inside the chart. */
export declare function useLiveLineChart(): {
activePoint: LiveLinePoint | null;
latest: LiveLinePoint | null;
momentum: LiveLineMomentum;
color: string;
};
export interface LiveLineChartProps extends ViewProps {
className?: string;
/**
* Names the chart's single screen-reader snapshot. Falls back to the Header
* title, then to "Live line chart".
*/
accessibilityLabel?: string;
/** Additional guidance after the snapshot. No gesture is invented for it. */
accessibilityHint?: string;
/** The readings so far. Invalid values are dropped and timestamps are ordered. */
data: LiveLinePoint[];
/** How much time the plot spans, in seconds. Invalid values use 30. */
window?: number;
/** Freeze the window where it is. The readings still arrive; the clock stops. */
paused?: boolean;
/** Fix the y-axis instead of deriving it from what is visible. */
yDomain?: [number, number];
/** Milliseconds for the y-axis to settle after the range changes. */
domainDuration?: number;
/** `monotone` never overshoots between readings; `linear` joins them straight. */
curve?: ChartCurve;
/**
* The most readings kept. Older ones are dropped, since they are off the
* window and cannot come back — an unbounded feed otherwise grows an array
* for as long as the screen is open. Must be positive and finite.
*/
maxPoints?: number;
/** Width ÷ height of the plot. */
aspectRatio?: number;
/** `loading` draws a flat placeholder and holds the clock. */
status?: LiveLineChartStatus;
/** Colour per direction. Left out, the chart draws in one hue throughout. */
momentumColors?: LiveLineMomentumColors;
/** Overrides the `--color-chart-1` token. Ignored when `momentumColors` is set. */
color?: string;
/** The reading under the crosshair as it moves, and `null` when the finger lifts. */
onActivePointChange?: (point: LiveLinePoint | null) => void;
children?: ReactNode;
}
export interface LiveLineChartHandle {
/** Jump the window to the current moment — after a pause, or a background. */
sync: () => void;
}
export interface LiveLineChartGridProps {
/** How many bands the plot is divided into. */
rows?: number;
color?: string;
dashArray?: string;
}
/** The horizontal rules the readings are judged against. */
declare function LiveLineChartGrid({ rows, color, dashArray }: LiveLineChartGridProps): import("react").JSX.Element;
declare namespace LiveLineChartGrid {
var displayName: string;
var layer: Layer;
}
export interface LiveLineChartLineProps {
strokeWidth?: number;
/** Overrides the chart's colour, momentum included. */
color?: string;
}
/** The line itself, rebuilt on the UI thread every frame the window moves. */
declare function LiveLineChartLine({ strokeWidth, color }: LiveLineChartLineProps): import("react").JSX.Element | null;
declare namespace LiveLineChartLine {
var displayName: string;
var layer: Layer;
}
export interface LiveLineChartAreaProps {
/** Opacity at the top of the fill, fading to nothing at the baseline. */
opacity?: number;
/** Overrides the chart's colour, momentum included. */
color?: string;
}
/**
* The fill under the line.
*
* Its own part rather than a flag on the line, so a chart that wants the shape
* without the weight of a filled band simply does not have one.
*/
declare function LiveLineChartArea({ opacity, color }: LiveLineChartAreaProps): import("react").JSX.Element | null;
declare namespace LiveLineChartArea {
var displayName: string;
var layer: Layer;
}
export interface LiveLineChartTipProps {
/**
* Show the current reading in a badge beside the dot.
*
* Off by default. The badge is a floating card, which is the shape a reader
* has learnt means "you touched something" — sitting there unasked it reads
* as a tooltip nobody opened. Turn it on where the chart has no header to put
* the reading in, and it becomes the only place the number is written.
*/
badge?: boolean;
/** Ring the dot with a repeating pulse. */
pulse?: boolean;
/** Format the badge. Defaults to a compact number. */
formatValue?: (value: number) => string;
className?: string;
}
/**
* The dot at the leading end, and what it currently reads.
*
* It rides the newest reading rather than the right-hand edge, so a feed that
* stops is a dot drifting left with the rest of the line. Pinning it to the
* edge would hold it still and steady, which is the picture of a feed that is
* working.
*
* A view rather than an SVG node: it carries text and a pulse, and SVG text
* ignores the platform's text scaling and the theme's font.
*/
declare function LiveLineChartTip({ badge, pulse, formatValue, className, }: LiveLineChartTipProps): import("react").JSX.Element | null;
declare namespace LiveLineChartTip {
var displayName: string;
var layer: Layer;
}
export interface LiveLineChartXAxisProps {
/** How many labels along the bottom. */
ticks?: number;
/** Rewrites a label. Given how many seconds back the tick is. */
formatTick?: (secondsAgo: number) => string;
className?: string;
}
/**
* How far back the plot reaches, labelled along the bottom.
*
* The labels are offsets from now — `-30s`, `-15s`, `now` — rather than clock
* times, and they never change. A moving window labelled with wall-clock times
* would rewrite every one of them on every frame, which is a row of digits
* churning under a chart that is trying to be read.
*/
declare function LiveLineChartXAxis({ ticks, formatTick, className }: LiveLineChartXAxisProps): import("react").JSX.Element | null;
declare namespace LiveLineChartXAxis {
var displayName: string;
var layer: Layer;
}
export interface LiveLineChartYAxisProps {
/** How many labels up the side. */
ticks?: number;
/** Format a value. Defaults to a compact number. */
formatValue?: (value: number) => string;
className?: string;
}
/**
* The scale up the left-hand side.
*
* Declaring one widens the left gutter, which the root reads off the children
* before anything is laid out — an axis given no room is drawn over the line,
* which loses both the numbers and the shape they were there to explain.
*
* The labels follow the domain the tween is heading for rather than the tween
* itself. A number re-rendered on every frame of a settle is thirty renders
* landing on the string it started on.
*/
declare function LiveLineChartYAxis({ ticks, formatValue, className }: LiveLineChartYAxisProps): import("react").JSX.Element | null;
declare namespace LiveLineChartYAxis {
var displayName: string;
var layer: Layer;
var axis: "y";
}
export interface LiveLineChartTooltipProps {
/** Format the value. Defaults to a compact number. */
formatValue?: (value: number) => string;
className?: string;
}
/**
* Drag back through the window to read a reading that has already gone past.
*
* The crosshair is pinned to the *moment* it was put on rather than to the
* place on screen, so it travels left with the reading it named instead of
* sitting still while the line slides out from under it.
*/
declare function LiveLineChartTooltip({ formatValue, className }: LiveLineChartTooltipProps): import("react").JSX.Element | null;
declare namespace LiveLineChartTooltip {
var displayName: string;
var layer: Layer;
}
export interface LiveLineChartSkeletonProps {
color?: string;
}
/**
* The waiting state: a flat line down the middle of the plot.
*
* The shape the real line grows out of once readings arrive, rather than a
* placeholder series — an invented run of readings is indistinguishable from a
* real one until it changes under the reader.
*/
declare function LiveLineChartSkeleton({ color }: LiveLineChartSkeletonProps): import("react").JSX.Element | null;
declare namespace LiveLineChartSkeleton {
var displayName: string;
var layer: Layer;
}
export interface LiveLineChartHeaderProps extends ViewProps {
className?: string;
/** Small line above the value — what is being watched. */
title?: string;
/** The readout. Left out, it shows the current reading. */
value?: string;
/** One muted line under the value. */
caption?: string;
/** Format the derived value. Defaults to a compact number. */
formatValue?: (value: number) => string;
/** Trailing slot — a pause control, a badge, a unit. */
children?: ReactNode;
}
/**
* The strip above the plot: what is being watched and what it currently reads.
*
* The value falls back to the reading under the crosshair, then to the latest
* one, so a drag back through the window reads out here without the caller
* wiring anything up.
*/
declare function LiveLineChartHeader({ className, title, value, caption, formatValue, children, ...props }: LiveLineChartHeaderProps): import("react").JSX.Element;
declare namespace LiveLineChartHeader {
var displayName: string;
var layer: Layer;
}
export declare const LiveLineChart: import("react").ForwardRefExoticComponent> & {
Header: typeof LiveLineChartHeader;
Grid: typeof LiveLineChartGrid;
Area: typeof LiveLineChartArea;
Line: typeof LiveLineChartLine;
Tip: typeof LiveLineChartTip;
XAxis: typeof LiveLineChartXAxis;
YAxis: typeof LiveLineChartYAxis;
Tooltip: typeof LiveLineChartTooltip;
Skeleton: typeof LiveLineChartSkeleton;
};
export {};
//# sourceMappingURL=index.d.ts.map