Profit Loss Chart
Series split at zero. Default and Motion variants.
Examples
Installation
Default is a ready-made wrapper from the registry. Motion is the composable engine at @cronus-ui/ui/charts (peer visx + motion).
npx cronus-ui add profit-loss-chart
import { ProfitLossChart } from "@cronus-ui/ui";
Usage
Motion is a LineChart child, not a root. The series is split at zero into positive/negative path segments.
import { LineChart, ProfitLossLine, ProfitLossLegend, Grid, XAxis, ChartTooltip } from "@cronus-ui/ui/charts";<LineChart data={data}><Grid highlightRowValues={[0]} horizontal /><ProfitLossLine dataKey="pnl" /><XAxis /><ChartTooltip /></LineChart><ProfitLossLegend />
Components
Motion API — compose these under the chart root. Default wrapper props are in Default API below.
ProfitLossLine
Sign-colored segments on a LineChart.
| Prop | Type | Default | Description |
|---|---|---|---|
dataKey* | string | — | Value key. |
positiveColor | string | var(--color-emerald-500) | Stroke when value ≥ 0. |
negativeColor | string | var(--color-red-500) | Stroke when value < 0. |
curve | CurveFactory | curveLinear | d3 curve. |
fadeEdges | boolean | "left" | "right" | false | Fade at chart edges. |
ProfitLossLegend
Profit / Loss swatches. Share hoveredIndex to dim the opposite sign.
| Prop | Type | Default | Description |
|---|---|---|---|
hoveredIndex | number | null | — | 0 = profit, 1 = loss. |
align | "start" | "center" | "end" | "start" | Horizontal alignment. |
Grid
Plot-area grid lines. Horizontal by default; optional shimmer while loading.
| Prop | Type | Default | Description |
|---|---|---|---|
horizontal | boolean | true | Show horizontal lines. |
vertical | boolean | false | Show vertical lines. |
numTicksRows | number | 5 | Horizontal line count. |
numTicksColumns | number | 10 | Vertical line count. |
stroke | string | var(--chart-grid) | Line color while ready. |
strokeDasharray | string | "4,4" | Dash pattern. |
shimmer | boolean | false | Animate a band across horizontal lines. |
highlightRowValues | number[] | — | Rows drawn with alternate styling (e.g. zero). |
XAxis
Time-axis labels that fade when the crosshair passes.
| Prop | Type | Default | Description |
|---|---|---|---|
numTicks | number | 5 | Tick labels to show, including first and last. |
tickerHalfWidth | number | 50 | Fade radius around the date pill. |
tickMode | "data" | "domain" | "data" | `data` snaps labels to rows (crosshair-aligned). `domain` spaces ticks evenly. |
ChartTooltip
Motion tooltip: crosshair, series dots, floating panel, optional date pill. This is not the recharts ChartTooltip from `@cronus-ui/ui`.
| Prop | Type | Default | Description |
|---|---|---|---|
showDatePill | boolean | true | Animated date ticker on the x-axis. |
showCrosshair | boolean | true | Vertical crosshair. |
showDots | boolean | true | Dots on series at the hovered x. |
dotVariant | "dot" | "ring" | "dot" | Filled circle or ring. |
indicatorColor | string | (point) => string | — | Crosshair and dot color. |
indicatorDasharray | string | — | Dash pattern for the crosshair. |
indicatorFadeEdges | "both" | "top" | "bottom" | "none" | "both" | Vertical crosshair fade. |
matchCrosshair | boolean | false | Panel uses the crosshair spring when true. |
damping | number | 20 | Panel follow when matchCrosshair is false. 0 = instant. |
content | (props) => ReactNode | — | Custom tooltip renderer. |
rows | (point) => TooltipRow[] | — | Custom row generator. |
Zero line
Highlight the baseline with Grid highlightRowValues={[0]}.
<Grid highlightRowValues={[0]} horizontal />
Data format
const data = [{ date: new Date("2026-01-01"), pnl: 420 },{ date: new Date("2026-01-02"), pnl: -180 },];
Theming
Motion charts read `--chart-*` aliases that map onto Cronus semantic tokens (`--cronus-chart-1`…`--cronus-chart-5`, `--cronus-border`, `--cronus-fg`, surfaces). Override the aliases or the tokens — never palette scales (`bg-zinc-900`). Default wrappers use `ChartConfig` with `var(--cronus-chart-*)` / `var(--cronus-primary)`. Sign colors default to emerald/red. Pass positiveColor / negativeColor with `var(--cronus-success)` / `var(--cronus-danger)` to stay on semantic tokens.
Full token reference: Theming.
Dependencies
Default needs the recharts peer. Motion needs visx (and sometimes d3) as optional peers — install only what this chart uses.
bun add recharts
bun add @visx/curve @visx/responsive @visx/scale @visx/shape motion react-use-measure
Default API
Generated from the Default wrapper's exported types. Motion subcomponents are documented above.
ProfitLossChartProps
Extends HTMLAttributes<HTMLDivElement>
| Prop | Type | Default | Description |
|---|---|---|---|
data* | ProfitLossPoint[] | — | — |