Charts & widgets
Dashboard pages are assembled from the components on this page: charts that plot series and distributions, cards that headline a single value or a ranking, and a period selector that drives one date range across every widget bound to it. Each is a builder like any other component — declare it as a static field on a page and feed it a backend route — then arrange the result in a grid (Layout & containers). For the authoring loop and route wiring, see Pages & components.
Charts render on the frontend with ApexCharts (via vue3-apexcharts); the builder options below map onto ApexCharts concepts (series, stacking, axis types, opacity, candlestick/heatmap, radial bar). You never touch ApexCharts directly — the backend emits a serializable description and the shared Nuxt frontend renders it.
Shared options
The charts and the three cards are data-driven and share these options; the per-component tables below list only what's distinctive. PeriodSelector is the control that drives them — it takes none of these options (see its own table).
| Option | Type | Purpose |
|---|---|---|
title | string | Heading / component meta name. Required on the three cards, optional on charts. |
description | string | Sub-heading text. |
fetchUrl | string | Route returning the component's payload. |
fetchUrlMethod | HttpMethod | HTTP method for the fetch (defaults to GET). |
periodScope | string | id of a PeriodSelector to bind to; refetches when its range/comparison changes. |
The three cards additionally share valueFormat (number / currency / percent / compact), currencyCode (ISO code when valueFormat is currency), and showDelta (the change-vs-comparison badge). Where a component supports fixtures instead of a route, pass its static* option.
Charts
Each low-level chart builder maps to one chart type. Each renders a single titled chart and is most often dropped inside a ChartCard, but works standalone too.
What it renders. A chart canvas sized by height / width, with an optional title/description above it, an optional legend and hover tooltips, and (for XY types) a grid and configurable axes. XY charts plot one or more named series; circular charts (donut/pie/radial) plot a list of label/value records; heatmap and candlestick take their own series shapes.
Import
import {
ChartLine,
ChartArea,
ChartRangeArea,
ChartBar,
ChartColumn,
ChartScatter,
ChartMixed,
ChartRadar,
ChartCandlestick,
ChartDonut,
ChartPie,
ChartRadialBar,
ChartHeatmap,
} from "@antelopejs-private/cms/interfaces/cms-base/chart";
Each builder is pinned to a ChartType. Pass options without a type field — the builder injects it.
| Builder | ChartType | Family | Notable extra options |
|---|---|---|---|
ChartLine | LINE | XY | strokeWidth |
ChartArea | AREA | XY | fillOpacity, stacked |
ChartRangeArea | RANGE_AREA | XY | fillOpacity; points carry y: [low, high] |
ChartBar | BAR | XY | stacked, barWidth, roundedCorners, orientation |
ChartColumn | COLUMN | XY | stacked, columnWidth, roundedCorners |
ChartScatter | SCATTER | XY | pointSize, showLabels |
ChartMixed | MIXED | XY | seriesDefs (per-series line/area/column + color) |
ChartRadar | RADAR | XY | fillOpacity |
ChartCandlestick | CANDLESTICK | XY | OHLC data (y: [open, high, low, close]) |
ChartDonut | DONUT | Circular | centralLabel, centralSubLabel, arcWidth |
ChartPie | PIE | Circular | — |
ChartRadialBar | RADIAL_BAR | Circular | hollowSize, showTotal |
ChartHeatmap | HEATMAP | — | shadeIntensity, distributed |
Options — common to all charts (BaseChartProps, plus the shared options)
| Option | Type | Purpose |
|---|---|---|
color | ChartColor | One color name/hex/rgb/hsl, or an array for multi-series. |
height | string | CSS height, e.g. "320px". |
width | number | Explicit width. |
showTooltip | boolean | Hover tooltips. |
showLegend | boolean | Series legend. |
realtimeTopic | string | string[] | Realtime topic(s); the chart refetches when published over SSE. |
rawOptions | KeyValuePair[] | Escape hatch — raw key/value passthrough to the chart library. |
Options — XY charts (XYChartProps, adds to the above)
| Option | Type | Purpose |
|---|---|---|
showGrid | boolean | Background grid lines. |
staticDataset | ChartSeries[] | Inline series instead of fetchUrl. |
yRange | { min: number; max: number } | Clamp the Y axis so small variations read larger. |
comparisonStyle | "dashed" | "solid" | "dimmed" | How a comparison series is drawn against the primary. |
smooth | boolean | Smooth (curved) lines/areas. |
curve | "smooth" | "straight" | "stepline" | Line interpolation; wins over smooth when both are set. |
annotations | ChartAnnotation[] | Y-axis reference lines or shaded bands. |
syncGroup | string | Share the crosshair and tooltip with the charts of that group. |
xaxisType | "category" | "datetime" | "numeric" | X-axis interpretation; use "datetime" for time series. |
Circular charts (CircularChartProps) instead take a staticDataset of DonutRecords — a label and a value — plus their per-type extras listed in the builder table.
Bands, reference lines and synced crosshairs
The three options a metrics screen leans on, and what they expect from the payload.
ChartRangeArea plots a filled band per series instead of a curve: each point is { x, y: [low, high] }. Percentile bands read as one distribution when you send adjacent ranges — p50 – p95 then p95 – p99 — rather than three separate lines. rangeArea is also a valid seriesDefs type on ChartMixed, so a band can carry a plain line on top.
annotations draws horizontal reference lines through the plot:
| Field | Type | Purpose |
|---|---|---|
y | number | Where the line sits on the value axis. Required. |
y2 | number | Turns the line into a shaded band between y and y2. |
label | string | Caption drawn at the right end, in the annotation's own color. |
color | ChartColorValue | Theme color name or literal; defaults to the chart primary. |
dashed | boolean | Dashed by default; pass false for a solid rule. |
ChartLine({
title: "Replicas",
fetchUrl: "/metrics/replicas",
curve: "stepline",
annotations: [{ y: 4, label: "max bound", color: "warning" }],
});
syncGroup gives every chart naming the same group a shared crosshair: hovering one moves the tooltip of all of them to the same x position, which is what makes a grid of stacked metrics readable. Each chart keeps its own axes, colors and annotations — the group only ties the pointer.
Features
- Multi-series and stacking for area/bar/column;
coloraccepts an array to color each series. staticDatasetfor fixtures vs.fetchUrlfor live data;ChartSeries.dataaccepts{ x, y, label }points, candlestick OHLC tuples, or bare numbers.realtimeTopicwires the chart to SSE so it refetches when the backend publishes.- Charts emit click events other components can watch (the
ChartEventsconstants):SEGMENT_CLICKon circular charts,POINT_CLICKon XY charts — see Actions & reactivity. The payload carriesvaluefor scalar points; on the types whose points hold a tuple (rangeArea,candlestick)valueisnulland the tuple arrives invalues. rawOptionsis the escape hatch when a needed ApexCharts knob isn't surfaced as a typed option.
ChartCard
A framed card that wraps one chart and surfaces a headline metric, delta, and comparison legend around it — the dashboard-ready version of a bare chart.
What it renders. A bordered card with a title (and optional icon/description), a large formatted headline value with an up/down delta badge versus the comparison period, an optional primary/comparison legend, and the nested chart filling the body.
Import
import { ChartCard } from "@antelopejs-private/cms/interfaces/cms-base/chart-card";
Options (ChartCardBuilderOptions, plus the shared options)
| Option | Type | Default | Purpose |
|---|---|---|---|
chart | Component | — | The nested chart builder (e.g. ChartArea({...})). Required. |
icon | string | i-ph-chart-line | Iconify name shown on the card. |
showLegend | boolean | — | Show the primary/comparison legend. |
primaryLabel | string | — | Legend label for the primary series. |
comparisonLabel | string | — | Legend label for the comparison series. |
Features
- The card owns the
fetchUrl/periodScope; the nestedchartis configured for presentation (smooth,comparisonStyle,xaxisType,height). - Payload carries
value,delta,previousValue, andseries(plus optionalcomparisonSeries).
KpiCard
A single-metric stat card: a big formatted number with a delta and optional sparkline.
What it renders. A compact card with a title, an optional icon, a large formatted value, a colored up/down delta badge with a "compare" caption, and an optional inline sparkline. The "stat" variant is the tighter DMS look — mono uppercase label and a bare icon.
Import
import { KpiCard } from "@antelopejs-private/cms/interfaces/cms-base/kpi-card";
Options (KpiCardProps, plus the shared options)
| Option | Type | Default | Purpose |
|---|---|---|---|
variant | "default" | "stat" | default | stat = compact DMS look (mono uppercase label, bare icon). |
icon | string | i-ph-trend-up | Iconify name. |
showSparkline | boolean | — | Render an inline sparkline. |
sparklineAccent | ChartColorValue | "auto" | — | Sparkline color; auto follows the delta direction. |
invert | boolean | — | Treat a negative delta as good (e.g. errors, churn). |
compareLabel | string | — | Caption next to the delta, e.g. "vs previous period". |
staticValue | number | — | Fixture value instead of fetchUrl. |
staticDelta | number | — | Fixture delta. |
staticSparkline | number[] | — | Fixture sparkline points. |
Features
fetchUrlpayload returnsvalue,delta,previousValue,sparkline; for static demos passstaticValue/staticDelta/staticSparkline.invertflips the good/bad coloring so a decrease can read as positive.
TopListCard
A ranked leaderboard card — a vertical list of items each with a value, delta, and optional sparkline.
What it renders. A titled card listing rows in rank order, each with an optional rank badge, an icon or avatar, a title and description, a formatted value, an optional delta, and an optional row sparkline. The top N rows can be highlighted, rows can link elsewhere via to, and an empty list shows emptyLabel.
Import
import { TopListCard } from "@antelopejs-private/cms/interfaces/cms-base/top-list-card";
Options (TopListCardProps, plus the shared options)
| Option | Type | Purpose |
|---|---|---|
showRank | boolean | Show numeric rank badges. |
highlightTopN | number | Emphasize the first N rows. |
rankColor | ChartColorValue | Color of the rank badges. |
showSparkline | boolean | Show per-row sparklines. |
sparklineAccent | ChartColorValue | "auto" | Sparkline color; auto follows the delta. |
invert | boolean | Treat negative deltas as good. |
badgeColor | ChartColorValue | Color of value/delta badges. |
maxHeight | string | Cap the list height (scrolls beyond). |
staticItems | TopListItem[] | Fixture items instead of fetchUrl. |
emptyLabel | string | Text shown when there are no items. |
fetchUrl returns { items: TopListItem[] }. Each TopListItem carries an id, a title, and a value, plus optional description, delta, sparkline, icon, avatar (src, optional alt), and to (link target).
Features
- Rank chrome (
showRank,highlightTopN,rankColor) and per-row deltas/sparklines are independently toggleable. toturns a row into a link;avatar/icongive each row a leading visual.
PeriodSelector
PeriodSelector to widgets by a scope id (behind the periodScope option) is documented in Period filtering.A date-range control that scopes every widget bound to its id. Place one on the page; charts, KPI cards, and lists referencing it via periodScope refetch when the range or comparison changes.
What it renders. A compact preset dropdown (Today, Last 7 days, This month, YTD, …) with an optional custom range, a comparison selector (none / previous period / previous year / custom), and — when showRangeLabel — the resolved date range as text. align positions it within its row.
Import
import { PeriodSelector } from "@antelopejs-private/cms/interfaces/cms-base/period-selector";
Options (PeriodSelectorProps)
| Option | Type | Purpose |
|---|---|---|
id | string | Scope id widgets reference via periodScope. Required. |
defaultPreset | PeriodPreset | Initial range preset. |
defaultComparison | PeriodComparison | Initial comparison mode. |
presets | PeriodPreset[] | Restrict the offered presets. |
comparisons | PeriodComparison[] | Restrict the offered comparison modes. |
presetLabels | Partial<Record<PeriodPreset, string>> | Override preset display labels. |
comparisonLabels | Partial<Record<PeriodComparison, string>> | Override comparison display labels. |
align | "left" | "center" | "right" | Horizontal alignment within the row. |
size | "xs" | "sm" | "md" | "lg" | "xl" | Control size, honoured by both variants. |
showRangeLabel | boolean | Show the resolved date range as text. |
variant | "default" | "segmented" | Render the presets as a dropdown or as inline pills. |
PeriodPreset is one of last-hour, last-24h, today, yesterday, last-7-days, last-30-days, last-90-days, this-month, last-month, this-quarter, last-quarter, ytd, last-year, custom. PeriodComparison is none, previous-period, previous-year, or custom.
Features
- Linking by
id. Any widget withperiodScope: "<id>"is driven by the matching selector. On change it appendspreset,from/to, andcomparisonto each scoped widget's request and triggers a refetch. - Multiple independent scopes on one page: give each selector a distinct
idand point disjoint widget groups at each. presets/comparisonsnarrow the menus;presetLabels/comparisonLabelsrelabel them (e.g. for i18n).variant: "segmented"turns a short preset list into inline pills — one click per range instead of open-then-pick, which is the gesture a metrics page repeats all day. Keep the list to a handful; anything longer belongs in the dropdown. The custom range stays in its popover calendar either way, and the pills implement the radiogroup keyboard pattern (arrows, Home/End).
PeriodSelector at the top, then a Grid of GridRows holding KpiCards, a ChartCard, and a TopListCard — all sharing the same periodScope.