Skip to main content

LineChart

A gap-aware line through one numeric column. The default draw layer for a continuous series — over time, or over a value axis.

src/examples/first-chart.tsx
import {
ChartContainer,
ChartRow,
Layers,
LineChart,
YAxis,
LineCursor,
} from '@pond-ts/charts';
import { useSiteChartTheme } from '@site/src/theme/useSiteChartTheme';
import { singleHostSeries } from './lib/server-metrics';

export default function FirstChart() {
const theme = useSiteChartTheme();
const series = singleHostSeries();

return (
<ChartContainer range={series.timeRange()} width={560} theme={theme}>
<LineCursor />
<ChartRow height={220}>
<Layers>
<LineChart series={series} column="cpu" axis="pct" />
</Layers>
<YAxis id="pct" side="right" format=".0%" />
</ChartRow>
</ChartContainer>
);
}

Data contract​

Takes a TimeSeries or ValueSeries and one numeric column (the y value); x comes from the series key (time) or axis (value). A NaN run is a gap — how it renders is the gaps prop. For non-pond data the same view builds by hand via fromTimeSeries(series, column).

Props​

PropTypeDefaultPurpose
seriesTimeSeries | ValueSeries— (req)The source series.
columnstring— (req)Numeric column to plot as y.
readoutstring—Second column reported at the cursor (see below).
asstring'default'Style role → theme.line[as].
axisstringrow defaultWhich <YAxis id> to scale against.
curveCurve'linear'Path interpolation (see variants).
gapsGapMode'empty'How a NaN run renders.
sessionBreaksbooleanfalseBreak the line at trading-axis session discontinuities.
xOffsetnumber | duration0Draw each row this long after its key (time series only).

Variants​

  • curve — 'linear' (default), 'monotone', 'natural', 'basis', 'step'. A view concern only; denoise the data with pond's smooth(), not the curve.
  • gaps — 'empty' (default: break at the gap), 'none' (bridge across), 'dashed' / 'step' / 'fade' (faint connectors over the break). A NaN in the column is the gap; the mode is how it draws — see Missing data & gaps.
  • sessionBreaks — a scale break (at session boundaries on a trading-time axis), orthogonal to gaps (a data break); set both independently.
  • xOffset — draws each row a fixed time after its key: milliseconds or a duration string ('1m', '-30s'). For a value stamped at one instant that belongs at another — a 1-minute bar is keyed at its open, but its close is the price at the bar's end, so xOffset="1m" puts the close line where it happened and the session's last close on the close. The series is not changed (a <Candlestick> from the same series still draws at the key); the layer moves its own key, value columns shared. Everything the layer reports — tracker dot, auto-fit extent, sessionBreaks, a sweep's span — is in drawn time. To move the data itself, use pond's series.offsetTime(by). On a trading axis, keep the offset within the bar: a negative offset on bars keyed at their open moves each session's first bar into closed time.

Interaction & theming​

  • Cursor: participates in every readout mode (line/point/inline/flag/ crosshair) — the dot rides the line at the cursor, no readout past the data span.
  • readout (a second column): the tracker sample carries readout from another column while value stays the plotted number, so an off-chart readout can show a source value behind a derived plot (a smoothed / log / normalized line reading its raw sample). The in-chart dot and chips keep showing the plotted value — the dot has to sit on the line — so an off-chart consumer is the one that renders readout ?? value. A mistyped column name throws on both axis kinds.
  • Selection: not selectable (no id); it's a display + readout layer.
  • Theming: the theme.line slot (LineStyle = { color, width, dash? }). A dashed line for a modeled series comes from the theme role's dash, not a prop.

Cautions​

  • No per-component colour/width — style is the as role only, by design (style and scale are separate channels).
  • curve smooths the drawing, not the data — for denoised values use smooth() upstream so the readout matches the line.

See also​