Series & styling
The series API
addSeries returns a handle you keep for the life of the series:
const series = chart.addSeries('candlestick', { paneIndex: 0, style: { /* ... */ } });
series.setData(bars); // replace all data
series.prependData(older); // merge older bars (history paging), viewport kept
series.update(bar); // mutate the last bar or append a new one
const bars = series.getData(); // current bars, sorted old -> new
const markers = series.createMarkers(); // a markers layer bound to this series
// mutate a live series (no re-create needed):
series.applyOptions({ color: '#f00' }); // merge a partial style + repaint
series.applyOptions({ visible: false }); // hide it (also excluded from autoscale)
const scale = series.priceScale(); // the PriceScale this series maps to
series.remove(); // detach from the pane + free its dataaddSeries also accepts priceScaleId ('right' / 'left' / '' overlay) and
priceFormat — see Scales & panes.
applyOptions / remove make dynamic charts (add, restyle, hide, and remove series at
runtime) straightforward without recreating the chart.
setData, prependData, and update accept three item shapes (normalized to
bars internally, so getData always returns Bar[]):
{ time, open, high, low, close, volume? } // an OHLC bar
{ time, value } // a value point (line / area / baseline)
{ time } // a whitespace gap: breaks the line, draws nothingUse isWhitespace(item) to test for a gap, or toBar(item) to normalize one
yourself. A value point sets open=high=low=close=value; a whitespace item becomes
a NaN bar that the line renderer skips.
Per-series style
Every chart type has a typed style. Per-series style always wins over the theme, so you
can mix a themed chart with a custom-colored overlay:
const chart = lib.createChart(el);
const bars = lib.generateBars(1700000000, 140, 3600);
chart.addSeries('candlestick', {
style: { upColor: '#16a34a', downColor: '#dc2626', wickUpColor: '#16a34a', wickDownColor: '#dc2626' }
}).setData(bars);
// a second overlay series in the same pane, custom-colored
chart.addSeries('line', { style: { color: '#a855f7', lineWidth: 2 } })
.setData(lib.emaSeries(bars, 9));
chart.timeScale.fitContent(140);
return chart;Dynamic series & dashed lines
Series are mutable at runtime — restyle, hide, or remove without recreating the chart.
lineStyle: 'dashed' renders a reference line dashed:
const chart = lib.createChart(el);
const bars = lib.generateBars(1700000000, 140, 3600);
chart.addSeries('line', { style: { color: '#2962ff' } })
.setData(bars.map(b => ({ time: b.time, value: b.close, close: b.close })));
// a dashed EMA(20) reference overlay
const ema = chart.addSeries('line', { style: { color: '#e0b020', lineStyle: 'dashed', lineWidth: 2 } });
ema.setData(lib.emaSeries(bars, 20));
// recolor it live via applyOptions (no re-create)
ema.applyOptions({ color: '#16a34a' });
chart.fitContent();
return chart;Common style fields
| Field | Applies to | Notes |
|---|---|---|
upColor / downColor | candle, bar, volume-candle | bullish / bearish body |
wickUpColor / wickDownColor | candle | wick color |
color | line, area, baseline, column | primary stroke |
lineWidth | line, area, baseline | pixels |
lineStyle | line, step, area, HLC | 'solid' (default), 'dashed', 'dotted' |
visible | all | false hides the series and drops it from autoscale |
priceLineVisible | price series | false hides the dashed last-price line (default on) |
lastValueVisible | price series | false hides the last-value tag on the axis (default on) |
title | all | label carried with the series for host-drawn legends |
areaTopColor / areaBottomColor | area | vertical gradient stops |
baseValue | baseline | the reference level |
priceLineVisible | all price series | the dashed last-price line |
Whitespace (gaps)
To break a line without interpolating, emit a whitespace item - a point with a time but no
value. The renderer leaves a gap and skips markers there. This is how indicator warmup
periods render (they emit NaN, which is treated as whitespace).