Plotting System
QFChart's plotting system is designed to render technical indicators with flexible styling options. Each indicator consists of one or more plots, where each plot is a time-series of values with associated visual styling.
Core Concepts
Data Structure
An indicator is composed of:
- Indicator: A collection of plots that represent a single technical indicator (e.g., MACD contains three plots: MACD line, signal line, and histogram)
- Plot: A single visual series with a specific style (line, histogram, shape, etc.)
- Point: An individual data point in a plot with a timestamp and value
TypeScript Interfaces
interface IndicatorPoint {
time: number; // Unix timestamp in milliseconds
value: number | null; // Numeric value or null to skip rendering
options?: {
// Optional per-point styling overrides
color?: string;
offset?: number;
// ... style-specific options
};
}
interface IndicatorPlot {
data: IndicatorPoint[];
options: IndicatorOptions; // Global styling for this plot
}
interface Indicator {
id: string; // Unique identifier
plots: { [name: string]: IndicatorPlot };
paneIndex: number; // 0 = main chart, >0 = separate pane
height?: number; // Pane height in percentage (for separate panes)
collapsed?: boolean;
}
Adding Indicators
const plots = {
SMA: {
data: [
{ time: 1620000000000, value: 50200 },
{ time: 1620086400000, value: 50300 },
// ...
],
options: {
style: 'line',
color: '#ff9900',
linewidth: 2,
},
},
};
// Add as overlay on main chart
chart.addIndicator('SMA_14', plots, { overlay: true });
// Or add as separate pane
chart.addIndicator('RSI_14', plots, { overlay: false, height: 15 });
Plot Styles
QFChart uses a unified plot structure where all plots have a style property. This differs from Pine Script, which uses separate functions (plot(), plotshape(), plotchar(), plotcandle(), plotbar(), barcolor()). In PineTS and QFChart:
plot()maps to styles like'line','histogram','columns','step','circles','cross','background'plotshape()always creates plots withstyle: 'shape'plotchar()always creates plots withstyle: 'char'plotcandle()always creates plots withstyle: 'candle'plotbar()always creates plots withstyle: 'bar'barcolor()always creates plots withstyle: 'barcolor'fill()creates plots withstyle: 'fill'(fills area between two plots)
This unified approach simplifies plot management and provides a consistent API across all visualization types.
1. Line (style: 'line')
Renders data as a continuous line chart.
Options:
color: Line color (hex, rgb, or named color)linewidth: Line thickness in pixels (default: 1)smooth: Enable smooth curve interpolation (default: false)offset: Horizontal offset in bars (positive = right, negative = left)
Per-Point Options:
color: Override color for a specific point (breaks line if'na'ornull)
Example:
const smaPlot = {
data: [
{ time: 1620000000000, value: 50200 },
{ time: 1620086400000, value: 50300, options: { color: 'red' } }, // Override color
{ time: 1620172800000, value: null }, // Break line
{ time: 1620259200000, value: 50400 },
],
options: {
style: 'line',
color: '#ff9900',
linewidth: 2,
smooth: true,
},
};
Behavior:
- Setting
value: nullcreates a gap in the line - Setting
color: 'na'(ornull) also breaks the line - Smooth curves use spline interpolation
2. Step (style: 'step')
Renders data as a step line (staircase pattern).
Options:
Same as line, but renders with horizontal + vertical segments instead of diagonal lines.
Example:
const stepPlot = {
data: [
{ time: 1620000000000, value: 1 },
{ time: 1620086400000, value: 1 },
{ time: 1620172800000, value: 2 },
{ time: 1620259200000, value: 2 },
],
options: {
style: 'step',
color: '#00bcd4',
linewidth: 1,
},
};
3. Columns / Histogram (style: 'columns' or style: 'histogram')
Renders data as vertical bars.
Options:
color: Default bar coloroffset: Horizontal offset in bars
Per-Point Options:
color: Override color for individual bars
Example:
const volumePlot = {
data: [
{ time: 1620000000000, value: 1000, options: { color: 'green' } },
{ time: 1620086400000, value: 1500, options: { color: 'red' } },
{ time: 1620172800000, value: 1200, options: { color: 'green' } },
],
options: {
style: 'histogram',
color: '#888888',
},
};
Behavior:
- Bars are centered on their timestamp
nullvalues are not rendered (no bar)- Commonly used for volume or histogram-based indicators like MACD histogram
4. Circles (style: 'circles')
Renders data as circular markers at each data point.
Options:
color: Marker coloroffset: Horizontal offset in bars
Per-Point Options:
color: Override color for individual circles
Example:
const pivotPlot = {
data: [
{ time: 1620000000000, value: 50200 },
{ time: 1620259200000, value: 50400, options: { color: 'red' } },
],
options: {
style: 'circles',
color: '#00ff00',
},
};
Behavior:
- Fixed size (6px diameter)
- Only renders at data points (not interpolated)
5. Cross (style: 'cross')
Renders data as cross ('+') markers at each data point.
Options:
color: Marker coloroffset: Horizontal offset in bars
Per-Point Options:
color: Override color for individual crosses
Example:
const signalPlot = {
data: [
{ time: 1620000000000, value: 50200 },
{ time: 1620259200000, value: 50400, options: { color: 'red' } },
],
options: {
style: 'cross',
color: '#ffff00',
},
};
Behavior:
- Fixed size (16px)
- Useful for marking specific events or signals
6. Background (style: 'background')
Fills the vertical space with a colored background for specific bars.
Options:
color: Default background coloroffset: Horizontal offset in bars
Per-Point Options:
color: Override color for individual bars
Example:
const trendPlot = {
data: [
{ time: 1620000000000, value: 1, options: { color: 'rgba(0, 255, 0, 0.1)' } },
{ time: 1620086400000, value: 1, options: { color: 'rgba(0, 255, 0, 0.1)' } },
{ time: 1620172800000, value: 1, options: { color: 'rgba(255, 0, 0, 0.1)' } },
],
options: {
style: 'background',
color: 'rgba(128, 128, 128, 0.1)',
},
};
Behavior:
- Fills entire vertical space of the pane/chart
valuemust be truthy (non-zero, non-null) for the background to render- Commonly used for trend zones or market regimes
- Use semi-transparent colors (
rgba) to avoid obscuring data
7. Char (style: 'char')
Displays data values only in the tooltip/sidebar without any visual representation on the chart. This is useful for displaying auxiliary calculations, debug values, or statistics that don't need visual representation but should be accessible when hovering over the chart.
Pine Script Equivalent:
- This style is automatically used when calling
plotchar()in Pine Script indicators - When using PineTS,
plotchar()will always force the plot style to'char', regardless of other parameters - In manual plot definitions, you can explicitly set
style: 'char'to achieve the same behavior - Note: Pine Script's
plot()function does not acceptstyle={{ }}- you must use the dedicatedplotchar()function
Options:
color: Not used for rendering (invisible), but available for consistencyoffset: Horizontal offset in bars
Per-Point Options:
color: Not used for rendering
Example:
const volumeRatio = {
data: [
{ time: 1620000000000, value: 1.25 },
{ time: 1620086400000, value: 0.85 },
{ time: 1620172800000, value: 1.42 },
{ time: 1620259200000, value: 0.93 },
],
options: {
style: 'char',
color: '#888888', // Not rendered, but required
},
};
Behavior:
- No visual elements are rendered on the chart
- Values appear in the tooltip when hovering over the corresponding bar
- Useful for displaying calculations like volume ratios, percentages, or other derived metrics
- Does not affect chart scaling or layout
- Perfect for debugging or displaying reference data
Use Cases:
- Volume ratio (current volume / average volume)
- Price change percentage
- Volatility metrics
- Custom calculations that complement visual indicators
- Debug values during indicator development
8. Bar (style: 'bar')
Renders OHLC (Open, High, Low, Close) data as traditional bar charts with horizontal ticks. Each bar consists of a vertical line from low to high, with a left tick for open and a right tick for close.
Pine Script Equivalent:
- This style is automatically used when calling
plotbar()in Pine Script indicators - When using PineTS,
plotbar()will always force the plot style to'bar', regardless of other parameters - In manual plot definitions, you can explicitly set
style: 'bar'to achieve the same behavior - Note: Pine Script's
plot()function does not acceptstyle={{ }}- you must use the dedicatedplotbar()function
Data Format:
For bar/candle styles, each data point's value must be an array of 4 numbers: [open, high, low, close]
Options:
color: Bar color (applied to the entire bar)wickcolor: Optional separate color for the vertical line (defaults tocolorif not specified)offset: Horizontal offset in bars
Per-Point Options:
color: Override bar color for a specific barwickcolor: Override wick color for a specific bar
Example:
const heikinAshiBars = {
data: [
{ time: 1620000000000, value: [50000, 51000, 49500, 50500] }, // [O, H, L, C]
{ time: 1620086400000, value: [50500, 51500, 50000, 51000] },
{ time: 1620172800000, value: [51000, 51200, 50200, 50300], options: { color: 'red' } },
{ time: 1620259200000, value: [50300, 50800, 49800, 50600], options: { color: 'green' } },
],
options: {
style: 'bar',
color: '#888888',
wickcolor: '#666666',
},
};
Behavior:
- Each bar shows the full OHLC range for a time period
- Open tick extends to the left of the vertical line
- Close tick extends to the right of the vertical line
- Useful for Heikin Ashi, Renko, or other modified candlestick indicators
9. Candle (style: 'candle')
Renders OHLC data as traditional candlesticks with filled bodies and wicks. This is identical to the main chart's candlestick rendering but can be used for overlay indicators like Heikin Ashi candles.
Pine Script Equivalent:
- This style is automatically used when calling
plotcandle()in Pine Script indicators - When using PineTS,
plotcandle()will always force the plot style to'candle', regardless of other parameters - In manual plot definitions, you can explicitly set
style: 'candle'to achieve the same behavior - Note: Pine Script's
plot()function does not acceptstyle={{ }}- you must use the dedicatedplotcandle()function
Data Format:
For bar/candle styles, each data point's value must be an array of 4 numbers: [open, high, low, close]
Options:
color: Candle body fill colorwickcolor: Optional separate color for the wicks (high/low lines). Defaults tocolorif not specifiedbordercolor: Optional separate color for the candle body border. Defaults towickcolorif not specifiedoffset: Horizontal offset in bars
Per-Point Options:
color: Override body fill color for a specific candlewickcolor: Override wick color for a specific candlebordercolor: Override body border color for a specific candle
Example:
const heikinAshiCandles = {
data: [
{ time: 1620000000000, value: [50000, 51000, 49500, 50500] }, // [O, H, L, C]
{
time: 1620086400000,
value: [50500, 51500, 50000, 51000],
options: { color: 'green', wickcolor: 'darkgreen', bordercolor: 'lime' },
},
{
time: 1620172800000,
value: [51000, 51200, 50200, 50300],
options: { color: 'red', wickcolor: 'darkred', bordercolor: 'orange' },
},
],
options: {
style: 'candle',
color: '#888888',
wickcolor: '#666666',
bordercolor: '#444444', // Optional: separate body border color
},
};
Behavior:
- Each candle consists of a rectangular body (open to close) and wicks (high/low lines)
- Body is filled with the specified
color - Body border uses
bordercolorif specified, otherwise falls back towickcolororcolor - Wicks extend from the body to the high and low prices and use
wickcolor - If open equals close (doji), a thin line is drawn
- Perfect for displaying modified candlestick data like Heikin Ashi
Use Cases:
- Heikin Ashi candles overlaid on regular candlesticks
- Renko charts
- Modified OHLC visualizations
- Custom smoothed candlestick indicators
10. BarColor (style: 'barcolor')
Applies colors to the main chart candlesticks without creating a visual series. This is a special plot type that modifies the appearance of existing candlesticks based on indicator conditions.
Pine Script Equivalent:
- This style is automatically used when calling
barcolor()in Pine Script indicators - When using PineTS,
barcolor()will always force the plot style to'barcolor', regardless of other parameters - In manual plot definitions, you can explicitly set
style: 'barcolor'to achieve the same behavior - Note: Pine Script's
plot()function does not acceptstyle={{ }}- you must use the dedicatedbarcolor()function
Behavior:
- Does not create a visual series on the chart
- Colors the main chart candlesticks (body, wicks, and borders)
- Works regardless of whether the indicator is an overlay (
overlay: true/false) - Honors the
offsetparameter to shift colors forward/backward in time - Only applies color when the value is truthy (non-zero, not null/false)
- Color
'na'ornullmeans no color change for that bar
Options:
color: Color to apply to candlesticksoffset: Horizontal offset in bars (positive = shift right, negative = shift left)
Per-Point Options:
color: Override color for a specific bar
Example:
const trendColor = {
data: [
{ time: 1620000000000, value: 1, options: { color: 'green' } }, // Bullish - color candle green
{ time: 1620086400000, value: 1, options: { color: 'green' } },
{ time: 1620172800000, value: 0 }, // Neutral - no color change
{ time: 1620259200000, value: 1, options: { color: 'red' } }, // Bearish - color candle red
{ time: 1620345600000, value: 1, options: { color: 'red' } },
],
options: {
style: 'barcolor',
color: '#888888', // Default color
},
};
chart.addIndicator(
'Trend Color',
{ trendColor },
{ overlay: false } // Works even when not overlay
);
Use Cases:
- Color candles based on trend direction (bullish/bearish)
- Highlight specific market conditions (volume spikes, momentum shifts)
- Visualize custom indicators without cluttering the chart with additional plots
- Create color-coded trading signals directly on candles
- Combine with other indicators for multi-dimensional analysis
Technical Notes:
- Multiple
barcolorindicators can be used, but later ones will override earlier ones for the same bar - The color is applied to all parts of the candlestick: body fill, body border, and wicks
- If no color is specified (value is falsy or color is
'na'), the candle retains its default color
11. Shape (style: 'shape')
Renders custom shapes at data points with extensive customization options. This is the most flexible plot style, supporting various shapes, sizes, text labels, and positioning modes.
Pine Script Equivalent:
- This style is automatically used when calling
plotshape()in Pine Script indicators - When using PineTS,
plotshape()will always force the plot style to'shape', regardless of other parameters - In manual plot definitions, you can explicitly set
style: 'shape'to achieve the same behavior - Note: Pine Script's
plot()function does not acceptstyle={{ }}- you must use the dedicatedplotshape()function
Options:
color: Shape color (default: 'blue')shape: Shape type (default: 'circle')size: Shape size preset (default: 'normal')text: Text label to display near the shapetextcolor: Text color (default: 'white')location: Positioning mode (default: 'absolute')offset: Horizontal offset in barswidth: Custom width in pixels (overridessize)height: Custom height in pixels (overridessize)
Per-Point Options:
All global options can be overridden per-point:
color: Override shape colorshape: Override shape typesize: Override size presettext: Override label texttextcolor: Override text colorlocation: Override positioning modeoffset: Override horizontal offsetwidth: Override widthheight: Override height
Shape Types
| Shape | Description | Direction |
|---|---|---|
circle | Circular marker | None |
square | Square marker | None |
diamond | Diamond (rotated square) | None |
triangleup | Triangle pointing upward | Up |
triangledown | Triangle pointing downward | Down |
arrowup | Arrow pointing upward | Up |
arrowdown | Arrow pointing downward | Down |
flag | Flag marker | None |
cross | Cross ('+') marker | None |
xcross | X-shaped cross | None |
labelup | Rounded rectangle with upward pointer (for text) | Up |
labeldown | Rounded rectangle with downward pointer (for text) | Down |
Size Presets
| Size | Pixels | Use Case |
|---|---|---|
tiny | 8px | Subtle markers |
small | 12px | Compact charts |
normal | 16px | Default (balanced) |
large | 24px | Emphasis |
huge | 32px | Maximum visibility |
auto | 16px | Alias for normal |
Custom Dimensions:
- If both
widthandheightare specified, they are used directly:[width, height] - If only
widthis specified, aspect ratio is preserved:[width, width] - If only
heightis specified, aspect ratio is preserved:[height, height] - If neither is specified, falls back to the
sizepreset
Location Modes
The location parameter determines where shapes are positioned relative to the chart:
| Location | Behavior | Value Condition |
|---|---|---|
absolute | Position at the exact value (Y-coordinate) | Always renders |
abovebar | Position above the candle's high | Only if value is truthy |
belowbar | Position below the candle's low | Only if value is truthy |
top | Position at the top of the chart (not implemented for dynamic axis yet - uses value) | Only if value is truthy |
bottom | Position at the bottom of the chart (not implemented for dynamic axis yet - uses value) | Only if value is truthy |
Key Point:
- For
abovebarandbelowbar, the shape only renders whenvalueis truthy (non-zero, not null/false) - For
absolute, the shape renders whenever avalueis provided - This behavior makes shapes ideal for conditional signals and event markers
Text Label Positioning
Text labels are positioned relative to the shape based on the location parameter:
| Location | Text Position | Description |
|---|---|---|
abovebar | top | Text appears above the shape |
belowbar | bottom | Text appears below the shape |
top | bottom | Text appears below the shape (at chart top) |
bottom | top | Text appears above the shape (at chart bottom) |
absolute | top or inside | inside for label shapes, top for others |
Shape Examples
Basic Buy/Sell Signals:
const buySignals = {
data: [
{ time: 1620000000000, value: 1 }, // Show shape
{ time: 1620086400000, value: 0 }, // Hide shape
{ time: 1620172800000, value: 1 }, // Show shape
],
options: {
style: 'shape',
shape: 'triangleup',
color: 'green',
size: 'small',
location: 'belowbar', // Below the candle
},
};
const sellSignals = {
data: [
{ time: 1620086400000, value: 1 },
{ time: 1620259200000, value: 1 },
],
options: {
style: 'shape',
shape: 'triangledown',
color: 'red',
size: 'small',
location: 'abovebar', // Above the candle
},
};
With Text Labels:
const entrySignals = {
data: [
{
time: 1620000000000,
value: 1,
options: {
text: 'BUY',
textcolor: 'white',
},
},
{
time: 1620259200000,
value: 1,
options: {
text: 'SELL',
textcolor: 'yellow',
},
},
],
options: {
style: 'shape',
shape: 'labelup',
color: 'green',
size: 'large',
location: 'belowbar',
},
};
Per-Point Shape Overrides:
const dynamicSignals = {
data: [
{
time: 1620000000000,
value: 1,
options: {
shape: 'arrowup',
color: 'lime',
size: 'huge',
text: 'Strong Buy',
},
},
{
time: 1620086400000,
value: 1,
options: {
shape: 'triangleup',
color: 'green',
size: 'small',
text: 'Buy',
},
},
{
time: 1620172800000,
value: 1,
options: {
shape: 'arrowdown',
color: 'red',
size: 'huge',
text: 'Strong Sell',
},
},
],
options: {
style: 'shape',
shape: 'circle',
color: 'blue',
size: 'normal',
location: 'absolute',
text: 'Signal',
textcolor: 'white',
},
};
Custom Dimensions:
const customShapes = {
data: [
{
time: 1620000000000,
value: 50200,
options: {
width: 40, // 40px wide
height: 20, // 20px tall (non-uniform)
},
},
{
time: 1620086400000,
value: 50300,
options: {
height: 60, // 60px tall (will be 60x60 square)
},
},
],
options: {
style: 'shape',
shape: 'square',
color: 'purple',
size: 'normal', // Fallback if width/height not specified
location: 'absolute',
},
};
12. Fill (style: 'fill')
Fills the area between two existing plots with a color. This is commonly used for Bollinger Bands, Keltner Channels, or any indicator with upper/lower bounds.
Special Structure:
Unlike other plot styles, fill plots do not have a data array. Instead, they reference two existing plots using plot1 and plot2:
{
plot1: 'upperPlotId', // Reference to first plot
plot2: 'lowerPlotId', // Reference to second plot
options: {
style: 'fill',
color: 'rgba(33, 150, 243, 0.2)'
}
}
Options:
color: Fill color (supports hex, named colors, or rgba with transparency)plot1: ID of the first plot to fill from (required)plot2: ID of the second plot to fill to (required)
Example: Bollinger Bands with Fill
const bbPlots = {
upper: {
data: [
{ time: 1620000000000, value: 50500 },
{ time: 1620086400000, value: 50700 },
{ time: 1620172800000, value: 50900 },
],
options: {
style: 'line',
color: '#2196F3',
linewidth: 1,
},
},
basis: {
data: [
{ time: 1620000000000, value: 50000 },
{ time: 1620086400000, value: 50200 },
{ time: 1620172800000, value: 50400 },
],
options: {
style: 'line',
color: '#FFC107',
linewidth: 2,
},
},
lower: {
data: [
{ time: 1620000000000, value: 49500 },
{ time: 1620086400000, value: 49700 },
{ time: 1620172800000, value: 49900 },
],
options: {
style: 'line',
color: '#2196F3',
linewidth: 1,
},
},
// Fill between upper and lower bands
fill: {
plot1: 'upper',
plot2: 'lower',
options: {
style: 'fill',
color: 'rgba(33, 150, 243, 0.2)', // Semi-transparent blue
},
},
};
chart.addIndicator('BB_20', bbPlots, { overlay: true });
Color Formats:
All of the following are valid:
// RGBA with custom transparency (recommended for fills)
color: 'rgba(255, 87, 34, 0.3)' // 30% opacity
// Hex color (defaults to 30% opacity)
color: '#FF5722'
// Named color (defaults to 30% opacity)
color: 'green'
// RGB without alpha (defaults to 30% opacity)
color: 'rgb(255, 87, 34)'
Opacity Handling:
- When using
rgba()format, the alpha channel value is extracted and used as the fill opacity - For hex colors, named colors, or
rgb()format, a default opacity of0.3(30%) is applied - Example:
rgba(33, 150, 243, 0.95)renders with 95% opacity - Example:
#2196F3renders with 30% opacity (default)
Requirements:
- Both
plot1andplot2must reference existing plot IDs within the same indicator - Referenced plots are processed first, then fill plots are created
- Both plots must be on the same pane (overlay or separate)
- If either plot has
nullat any point, the fill is skipped for that segment
Behavior:
- Fill renders at
z: -5(behind lines, above background) - Creates smooth, continuous area fill between lines (like TradingView's Bollinger Bands)
- Each segment is rendered as a polygon connecting consecutive points for smooth transitions
- Automatically handles gaps in data - no fill is rendered where data is missing
- Supports any combination of plot styles (line, step, etc.)
Example: Keltner Channels
const kcPlots = {
upper: {
data: upperData,
options: { style: 'line', color: '#4CAF50', linewidth: 1 },
},
middle: {
data: middleData,
options: { style: 'line', color: '#FFC107', linewidth: 2 },
},
lower: {
data: lowerData,
options: { style: 'line', color: '#F44336', linewidth: 1 },
},
fill1: {
plot1: 'middle',
plot2: 'upper',
options: { style: 'fill', color: 'rgba(76, 175, 80, 0.15)' },
},
fill2: {
plot1: 'middle',
plot2: 'lower',
options: { style: 'fill', color: 'rgba(244, 67, 54, 0.15)' },
},
};
chart.addIndicator('KC_20', kcPlots, { overlay: true });
Per-Point Overrides
All plot styles support per-point styling through the options field in each IndicatorPoint. This allows dynamic coloring and styling based on conditions (e.g., green for bullish, red for bearish).
Color Overrides
const macdHistogram = {
data: [
{ time: 1620000000000, value: 10, options: { color: 'green' } },
{ time: 1620086400000, value: 15, options: { color: 'green' } },
{ time: 1620172800000, value: -5, options: { color: 'red' } },
{ time: 1620259200000, value: -10, options: { color: 'red' } },
],
options: {
style: 'histogram',
color: '#888888', // Fallback color
},
};
Offset Overrides
const displacedMA = {
data: [
{ time: 1620000000000, value: 50200, options: { offset: 5 } }, // Shift 5 bars right
{ time: 1620086400000, value: 50300, options: { offset: 5 } },
],
options: {
style: 'line',
color: '#ff9900',
offset: 0, // Default offset
},
};
Breaking Lines
To create gaps in line plots (e.g., for missing data or conditional rendering):
const conditionalLine = {
data: [
{ time: 1620000000000, value: 50200 },
{ time: 1620086400000, value: 50300, options: { color: 'na' } }, // Break line
{ time: 1620172800000, value: null }, // Also breaks line
{ time: 1620259200000, value: 50400 },
],
options: {
style: 'line',
color: '#00bcd4',
},
};
Multi-Plot Indicators
Many technical indicators consist of multiple plots. For example, MACD has three components:
const macdPlots = {
macd: {
data: [
{ time: 1620000000000, value: 5.2 },
{ time: 1620086400000, value: 6.1 },
// ...
],
options: {
style: 'line',
color: '#2196F3',
linewidth: 2,
},
},
signal: {
data: [
{ time: 1620000000000, value: 4.8 },
{ time: 1620086400000, value: 5.5 },
// ...
],
options: {
style: 'line',
color: '#FF9800',
linewidth: 2,
},
},
histogram: {
data: [
{ time: 1620000000000, value: 0.4, options: { color: 'green' } },
{ time: 1620086400000, value: 0.6, options: { color: 'green' } },
// ...
],
options: {
style: 'histogram',
color: '#888888',
},
},
};
chart.addIndicator('MACD_12_26_9', macdPlots, { overlay: false, height: 20 });
Real-Time Updates
To update plot data incrementally (e.g., for WebSocket feeds), use the updateData() method:
// Initial setup
const indicator = chart.addIndicator('RSI_14', rsiPlots, { overlay: false });
// Later: update with new data
function onNewBar(bar, indicators) {
// Update indicator first
indicator.updateData(indicators.rsiPlots);
// Then update chart
chart.updateData([bar]);
}
Key Points:
- Always update indicators before calling
chart.updateData() updateData()merges data by timestamp (updates existing or appends new)- Much more efficient than
setMarketData()for incremental updates
Best Practices
-
Use
nullvalues to skip rendering for specific points instead of removing them from the data array (maintains time alignment) -
Color consistency: Use a consistent color scheme across related plots (e.g., green for bullish, red for bearish)
-
Per-point overrides: Use sparingly for conditional styling; avoid overriding every point (defeats the purpose of global options)
-
Shape locations: For signal-based shapes (
abovebar,belowbar), usevalue: 1to show andvalue: 0to hide -
Text labels: Keep text short (2-5 characters) for clarity; use
labelup/labeldownshapes for better text visibility -
Custom dimensions: Use
widthandheightfor non-uniform shapes (e.g., wide rectangles); omit both to use standard size presets -
Overlay vs. Separate Pane:
- Use
overlay: truefor indicators that share the same scale as price (e.g., moving averages, Bollinger Bands) - Use
overlay: falsefor oscillators with different ranges (e.g., RSI, MACD, Stochastic) - Plot-level override: Individual plots can override the indicator's overlay setting using
plot.options.overlay
// MACD indicator with histogram in separate pane but signal lines as overlay
chart.addIndicator(
'MACD',
{
histogram: {
data: histogramData,
options: { style: 'histogram', color: '#888', overlay: false }, // Stays in separate pane
},
macdLine: {
data: macdData,
options: { style: 'line', color: '#2962FF', overlay: true }, // Overrides to main chart
},
signalLine: {
data: signalData,
options: { style: 'line', color: '#FF6D00', overlay: true }, // Overrides to main chart
},
},
{ overlay: false, height: 15 }
); // Indicator default is separate pane - Use
-
Performance: For high-frequency updates, minimize the number of separate indicators; combine plots into a single indicator when possible
See Also
- API Reference - Detailed method documentation
- Layout & Customization - Pane sizing and layout options
- Plugins - Interactive tools and extensions
