Skip to content

Smooth line

Show trends with a smooth curve through each value.

Chart ID: smoothLine. Independent import: @revolist/charts/smooth-line.

Loading chart…

Follow ordered trends with curved connections between observations. The curve is a visual interpolation, not additional measured data.

Use one category per row and one or more numeric series. Values are finite numbers or explicit nulls; the row mapper does not group or aggregate repeated keys.

The roles below describe the chart's data contract. Generic category/value roles resolve from the dataset; explicitly bind specialized numeric roles as shown in the complete example.

Data roleField count
category1 or more
value1 or more
series1 or more

Download the complete sample data and settings (JSON). See Data & Configuration for mapping, null values, updates and lifecycle rules.

Install the package using the installation guide, give the host an explicit height, and call createSmoothLineChart after the host mounts. This factory fixes the chart type to smoothLine.

<div id="chart" style="width: 100%; height: 450px;"></div>
Complete runnable TypeScript example with sample data
import { createSmoothLineChart } from '@revolist/charts/smooth-line';
const container = document.getElementById('chart')!;
const chart = await createSmoothLineChart({
container,
"dataset": {
"revision": 0,
"source": "client",
"categories": [
{
"id": "preview-category-0",
"label": "Jan",
"path": [
"Jan"
],
"labels": [
"Jan"
],
"depth": 1,
"kind": "leaf"
},
{
"id": "preview-category-1",
"label": "Feb",
"path": [
"Feb"
],
"labels": [
"Feb"
],
"depth": 1,
"kind": "leaf"
},
{
"id": "preview-category-2",
"label": "Mar",
"path": [
"Mar"
],
"labels": [
"Mar"
],
"depth": 1,
"kind": "leaf"
},
{
"id": "preview-category-3",
"label": "Apr",
"path": [
"Apr"
],
"labels": [
"Apr"
],
"depth": 1,
"kind": "leaf"
}
],
"series": [
{
"id": "preview-series-0",
"label": "Current",
"columnPath": [
"Current"
],
"labels": [
"Current"
],
"kind": "leaf",
"prop": "preview-0"
},
{
"id": "preview-series-1",
"label": "Previous",
"columnPath": [
"Previous"
],
"labels": [
"Previous"
],
"kind": "leaf",
"prop": "preview-1"
}
],
"values": [
[
18,
29
],
[
44,
27
],
[
31,
45
],
[
62,
50
]
],
"analyticalFrame": {
"fields": [
{
"id": "pivot:category",
"label": "pivot:category",
"role": "dimension",
"semanticType": "category"
},
{
"id": "pivot:series",
"label": "pivot:series",
"role": "dimension",
"semanticType": "category"
},
{
"id": "preview-series-0",
"label": "Current",
"role": "measure",
"semanticType": "number",
"sourceField": "preview-0"
},
{
"id": "preview-series-1",
"label": "Previous",
"role": "measure",
"semanticType": "number",
"sourceField": "preview-1"
}
],
"observations": [
{
"id": "[\"preview-category-0\",\"preview-series-0\"]",
"dimensions": {
"pivot:category": {
"value": "Jan",
"label": "Jan",
"path": [
"Jan"
],
"labels": [
"Jan"
]
},
"pivot:series": {
"value": "Current",
"label": "Current",
"path": [
"Current"
],
"labels": [
"Current"
]
}
},
"measures": {
"preview-series-0": 18
}
},
{
"id": "[\"preview-category-0\",\"preview-series-1\"]",
"dimensions": {
"pivot:category": {
"value": "Jan",
"label": "Jan",
"path": [
"Jan"
],
"labels": [
"Jan"
]
},
"pivot:series": {
"value": "Previous",
"label": "Previous",
"path": [
"Previous"
],
"labels": [
"Previous"
]
}
},
"measures": {
"preview-series-1": 29
}
},
{
"id": "[\"preview-category-1\",\"preview-series-0\"]",
"dimensions": {
"pivot:category": {
"value": "Feb",
"label": "Feb",
"path": [
"Feb"
],
"labels": [
"Feb"
]
},
"pivot:series": {
"value": "Current",
"label": "Current",
"path": [
"Current"
],
"labels": [
"Current"
]
}
},
"measures": {
"preview-series-0": 44
}
},
{
"id": "[\"preview-category-1\",\"preview-series-1\"]",
"dimensions": {
"pivot:category": {
"value": "Feb",
"label": "Feb",
"path": [
"Feb"
],
"labels": [
"Feb"
]
},
"pivot:series": {
"value": "Previous",
"label": "Previous",
"path": [
"Previous"
],
"labels": [
"Previous"
]
}
},
"measures": {
"preview-series-1": 27
}
},
{
"id": "[\"preview-category-2\",\"preview-series-0\"]",
"dimensions": {
"pivot:category": {
"value": "Mar",
"label": "Mar",
"path": [
"Mar"
],
"labels": [
"Mar"
]
},
"pivot:series": {
"value": "Current",
"label": "Current",
"path": [
"Current"
],
"labels": [
"Current"
]
}
},
"measures": {
"preview-series-0": 31
}
},
{
"id": "[\"preview-category-2\",\"preview-series-1\"]",
"dimensions": {
"pivot:category": {
"value": "Mar",
"label": "Mar",
"path": [
"Mar"
],
"labels": [
"Mar"
]
},
"pivot:series": {
"value": "Previous",
"label": "Previous",
"path": [
"Previous"
],
"labels": [
"Previous"
]
}
},
"measures": {
"preview-series-1": 45
}
},
{
"id": "[\"preview-category-3\",\"preview-series-0\"]",
"dimensions": {
"pivot:category": {
"value": "Apr",
"label": "Apr",
"path": [
"Apr"
],
"labels": [
"Apr"
]
},
"pivot:series": {
"value": "Current",
"label": "Current",
"path": [
"Current"
],
"labels": [
"Current"
]
}
},
"measures": {
"preview-series-0": 62
}
},
{
"id": "[\"preview-category-3\",\"preview-series-1\"]",
"dimensions": {
"pivot:category": {
"value": "Apr",
"label": "Apr",
"path": [
"Apr"
],
"labels": [
"Apr"
]
},
"pivot:series": {
"value": "Previous",
"label": "Previous",
"path": [
"Previous"
],
"labels": [
"Previous"
]
}
},
"measures": {
"preview-series-1": 50
}
}
],
"matrixCells": [
{
"categoryId": "preview-category-0",
"seriesId": "preview-series-0",
"observationId": "[\"preview-category-0\",\"preview-series-0\"]",
"measureFieldId": "preview-series-0"
},
{
"categoryId": "preview-category-0",
"seriesId": "preview-series-1",
"observationId": "[\"preview-category-0\",\"preview-series-1\"]",
"measureFieldId": "preview-series-1"
},
{
"categoryId": "preview-category-1",
"seriesId": "preview-series-0",
"observationId": "[\"preview-category-1\",\"preview-series-0\"]",
"measureFieldId": "preview-series-0"
},
{
"categoryId": "preview-category-1",
"seriesId": "preview-series-1",
"observationId": "[\"preview-category-1\",\"preview-series-1\"]",
"measureFieldId": "preview-series-1"
},
{
"categoryId": "preview-category-2",
"seriesId": "preview-series-0",
"observationId": "[\"preview-category-2\",\"preview-series-0\"]",
"measureFieldId": "preview-series-0"
},
{
"categoryId": "preview-category-2",
"seriesId": "preview-series-1",
"observationId": "[\"preview-category-2\",\"preview-series-1\"]",
"measureFieldId": "preview-series-1"
},
{
"categoryId": "preview-category-3",
"seriesId": "preview-series-0",
"observationId": "[\"preview-category-3\",\"preview-series-0\"]",
"measureFieldId": "preview-series-0"
},
{
"categoryId": "preview-category-3",
"seriesId": "preview-series-1",
"observationId": "[\"preview-category-3\",\"preview-series-1\"]",
"measureFieldId": "preview-series-1"
}
]
}
},
"bindings": {},
"presentation": {
"dataLabels": false
}
});
// When the host unmounts:
// chart.destroy();

Await updates before reading a snapshot or exporting. Call chart.destroy() when the host unmounts. See the live catalog to interact with this type.

Set these fields in chartOptions. The option schema validates supported keys, ranges and choices; updating chartOptions replaces that authored object.

OptionDefaultAccepted values
showGridLinestruetrue or false
markOpacity10.2 to 1; step 0.05
sparklinefalsetrue or false
strokeWidth21 to 6; step 0.5
samplingautoauto, none, m4, minmax, lttb
disableLineItemHighlightfalsetrue or false
stackOrdernonenone, reverse, ascending, descending, appearance
stackOffsetdivergingdiverging, none, expand

Titles, legends, theme and labels belong to presentation or the corresponding top-level setting. Axis, color, navigation and interaction support depends on the selected chart; see Data & Configuration.

  • Line — Show change and trends across an ordered axis.
  • Stepped line — Show values that remain constant between categories.
  • Small multiples — Compare measures in aligned panels with independent scales.
  • Annotated time series — Highlight notable points along an ordered time trend.

Charts overview · Installation · Data & Configuration

Use seriesOverrides[id].interpolation to choose linear, legacy smooth, directional/midpoint steps, monotone X/Y, natural, Catmull–Rom or bump X/Y curves. Combination charts accept this on line/area layers. See all curve choices, defaults and Pivot controls.

Set seriesOverrides[id].connectNulls: true to join finite path endpoints across null values. It defaults to false and preserves explicit calendar gaps. See null connections, viewport behavior and Pivot controls.

Use seriesOverrides[id].markers: true | false | 'start' | 'end' for all, hidden or accepted-frame endpoint glyphs. Marker shapes include cross, star and wye alongside the four existing choices. See marker modes, sampling and Pivot controls.

Application code can refine those modes with rendererOptions.markers.isVisible(context). See runtime source predicates and sampling.

chartOptions.sampling accepts 'auto' (default), 'none', 'm4', 'minmax', and 'lttb'. See path sampling for budgets, stacked-edge alignment, viewport behavior, and marker handling.

seriesOverrides[id].strictStepCurve defaults to false. Stepped paths expand across categorical bands; true retains exact observation endpoints. Default native point layouts and numeric/time axes keep their existing geometry. Explicit category band placement enables expansion for native line/area paths. See step endpoint policy for combination bands, null runs, sampling, areas, and Pivot controls.

axes.x.categoryPlacement and axes.xAxes[id].categoryPlacement accept 'point' or 'band' for categorical X axes. Omitted settings keep native line/area point positions and combination band centers. Band placement enables expanded native steps; point placement retains exact stepped endpoints. See category point and band placement for singletons, column margins, grouped labels, selection, preview, save/SSR and Pivot controls.

chartOptions.disableLineItemHighlight and seriesOverrides[id].disableHighlight default to false. Highlights inspect source observations independently of regular marker visibility/predicates and can temporarily replace saved endpoint glyphs. See transient source-point highlights for nearest-source policy, tooltip/focus/activation limits, snapshots and Pivot controls.

Line/area observations omitted by marker settings, runtime predicates or sampling remain reachable through the chart’s single inspection Tab stop. Arrow keys wrap; Home/End select the first/last item and Enter/Space use raw source activation. Null, hidden and clipped observations are excluded. See source-point keyboard traversal for ordering, focus rings, updates and inspection-only derived values.

Use seriesOverrides[id].stackGroup for independent groups, with shared stackOrder and stackOffset policies. Regular paths without a group remain raw; dedicated stacked/normalized areas retain an implicit default stack. See normalization, defaults, source identity and Pivot controls.

Use seriesOverrides[id].encoding for saved per-datum styling, gradients and patterns. Supported line/area paths also accept directed segment rules; bars accept datum rules without segment/marker fields. Runtime datumStyle callbacks are reattached after restore. Rules follow canonical category IDs through sorting, hiding and navigation; source values and raw activation remain intact. See the complete styling capability matrix, precedence and callback contract.