Skip to content

Candlestick

Creates a candlestick (or OHLC bar) chart of financial periods, from rows with a date and open, high, low, and close values. Each row’s date is read by x (default "date"): a Date, a timestamp, or a date string.

Each row is one period with a date, open, high, low, and close (the default keys). The wick runs from the high to the low and the body from the open to the close. Periods that closed at or above their open are drawn as green outlines, and periods that fell are filled red, so direction reads from the fill as well as the color. Hover anywhere over the plot to see the nearest period’s values and its change from open to close.

How each period draws: "candlestick" (default), a wick from the high to the low around a body from the open to the close; or "ohlc", a line from the high to the low with the open ticked to the left and the close ticked to the right.

Draws rising candles as outlines and falling candles filled (default true), so direction reads without relying on color; false fills both. OHLC bars are never filled. An unfilled candle or bar takes no shapeConfig.texture or shapeConfig.backgroundImage; filled ones take both, with a texture's lines a shade darker than the body unless the texture sets its own stroke.

The color of periods that closed at or above their open: a color string, or an accessor of the row. Defaults to green.

The color of periods that closed below their open: a color string, or an accessor of the row. Defaults to red.

The share of each period's room the candle body (or OHLC ticks) spans, from 0 to 1. Defaults to 0.7.

variant: "ohlc" draws each period as an OHLC bar: a line from the high to the low, with the open ticked to the left and the close ticked to the right.

How each period draws: "candlestick" (default), a wick from the high to the low around a body from the open to the close; or "ohlc", a line from the high to the low with the open ticked to the left and the close ticked to the right.

The share of each period's room the candle body (or OHLC ticks) spans, from 0 to 1. Defaults to 0.7.

Point x, open, high, low, and close at your own keys (or accessor functions). hollow: false fills every candle, and upColor/downColor swap the palette, here for a blue/orange pair that stays distinct for red-green color blindness. A yConfig.tickFormat formats the prices in the tooltip as well as on the axis.

Accessor (or data key) for each period's opening value. Defaults to "open"; a row without one opens at its close. Rows that share a series and a period merge into one candle, taking the first row's open (in data order, so sort rows oldest first). Override with an aggs entry on the data key, or, for a function accessor, on "open".

Accessor (or data key) for each period's highest value. Defaults to "high"; the high always reaches the open and close. Merged rows take the highest high; aggs overrides it as it does for open.

Accessor (or data key) for each period's lowest value. Defaults to "low"; the low always reaches the open and close. Merged rows take the lowest low; aggs overrides it as it does for open.

Accessor (or data key) for each period's closing value. Defaults to "close". The close is the chart's y: setting y sets it, rows without one are skipped, and hover snaps to it. Merged rows take the last row's close; aggs overrides it as it does for open.

Draws rising candles as outlines and falling candles filled (default true), so direction reads without relying on color; false fills both. OHLC bars are never filled. An unfilled candle or bar takes no shapeConfig.texture or shapeConfig.backgroundImage; filled ones take both, with a texture's lines a shade darker than the body unless the texture sets its own stroke.

The color of periods that closed at or above their open: a color string, or an accessor of the row. Defaults to green.

The color of periods that closed below their open: a color string, or an accessor of the row. Defaults to red.

volume draws a strip of volume bars under the candles, one per candle in its up or down color, on its own small axis with abbreviated ticks (e.g. 1.2M). The price axis shrinks to make room, the x axis sits under the strip, and the tooltip adds a Volume row. Bars stay filled when candles are hollow, so short bars remain easy to read. volumeConfig sets the strip’s height (a share of the plot, default 0.2), the gap above it, and axisConfig/shapeConfig for its axis and bars. When rows merge, volumes add up; aggs overrides it.

Accessor (or data key) for each period's traded volume. Off by default; when set, a strip under the candles draws one bar per candle, as tall as its volume on the strip's own axis (ticks abbreviated, e.g. "1.2M"), in its candle's up or down color, and the tooltip adds a Volume row. Bars are always filled, hollow candles included, and take shapeConfig.texture and shapeConfig.backgroundImage like filled candles; they hover with their candle. The price axis shrinks to make room, and the x axis sits under the strip. Merged rows add their volumes; an aggs entry overrides it as it does for open. Set false to turn it off.

How each period draws: "candlestick" (default), a wick from the high to the low around a body from the open to the close; or "ohlc", a line from the high to the low with the open ticked to the left and the close ticked to the right.

Draws rising candles as outlines and falling candles filled (default true), so direction reads without relying on color; false fills both. OHLC bars are never filled. An unfilled candle or bar takes no shapeConfig.texture or shapeConfig.backgroundImage; filled ones take both, with a texture's lines a shade darker than the body unless the texture sets its own stroke.

Rows that share a series and a period merge into one candle: the first row’s open, the highest high, the lowest low, and the last row’s close. Rows merge in data order, so sort them oldest first. Here seven hourly rows a day, with x pointed at their day, roll up to daily candles. An aggs entry overrides any of the four, keyed by the data key (or, for a function accessor, by the field name: aggs: {close: (rows, value) => ...}).

const config = {
  data: (() => {
    let seed = 7;
    const random = () => (seed = (seed * 16807) % 2147483647) / 2147483647;
    const round = v => Math.round(v * 100) / 100;
    const rows = [];
    const day = new Date(2024, 0, 1);
    let price = 120,
      n = 0;
    while (n < 30) {
      if (day.getDay() % 6) {
        const date = [day.getFullYear(), day.getMonth() + 1, day.getDate()]
          .map(v => String(v).padStart(2, "0"))
          .join("-");
        for (let hour = 10; hour <= 16; hour++) {
          const open = price;
          price = open * (1 + (random() - 0.49) * 0.012);
          rows.push({
            symbol: "ACME",
            day: date,
            time: date + "T" + hour + ":00",
            open: round(open),
            high: round(Math.max(open, price) * (1 + random() * 0.004)),
            low: round(Math.min(open, price) * (1 - random() * 0.004)),
            close: round(price),
          });
        }
        n++;
      }
      day.setDate(day.getDate() + 1);
    }
    return rows;
  })(),
  groupBy: "symbol",
  x: "day",
};

By default periods are spaced evenly in date order, so weekends and holidays leave no gaps, and the axis ticks the first period of each week, month, quarter, or year. skipGaps: false places each period at its date on a continuous time axis instead, which shows the gaps.

Places periods one slot apart in date order (default true), so days without data (weekends, holidays) leave no gap; false places each period at its date on a continuous time axis, where xConfig.rangeBreaks can hide weekends, holidays, or off-hours.

Two years of daily candles. The Canvas renderer draws dense charts quickly while keeping the snapped tooltip; candles narrow to fit, down to a single pixel.

renderer

Selects which @d3plus/render backend paints the visible output. "svg" = SvgRenderer (default), "canvas" = CanvasRenderer. Boolean arguments both normalize to "svg".

Places periods one slot apart in date order (default true), so days without data (weekends, holidays) leave no gap; false places each period at its date on a continuous time axis, where xConfig.rangeBreaks can hide weekends, holidays, or off-hours.

The share of each period's room the candle body (or OHLC ticks) spans, from 0 to 1. Defaults to 0.7.

facet draws one panel per ticker. With facetConfig.scales: "independent", each panel’s value axis fits its own price range.

Splits the chart into small multiples: a grid of equally sized panels, one per distinct value of this data key or accessor, each drawing the chart for that value's rows. The panels share one legend, color scale, title, and timeline, color each series the same way, and hover, tooltips, and legend clicks apply across all of them. Pass false to draw a single chart. See facetConfig for the grid's layout and shared scales.

Configuration

import {Candlestick} from "@d3plus/core";

Extends Plot → Viz.

activefalse | function

The active callback function for highlighting shapes.

annotationsunknownDefault unknown

Allows drawing custom shapes to be used as annotations in the provided x/y plot. This method accepts custom config objects for the Shape class, either a single config object or an array of config objects. Each config object requires an additional parameter, the "shape", which denotes which Shape sub-class to use (Rect, Line, etc).

Additionally, each config object can also contain an optional "layer" key, which defines whether the annotations will be displayed in "front" or in "back" of the primary visualization shapes. This value defaults to "back" if not present ("front" for callouts).

Three more kinds draw chart notes: "Callout" anchors wrapped text in a box at each data row's x/y (in data units, or plot-area fractions with xRef/yRef: "plot"), offset by dx/dy pixels and joined to its anchor by a connector ending in an arrowhead or dot (see CalloutAnnotation); "ReferenceLine" and "ReferenceBand" draw what referenceLines and referenceBands entries expand into. All annotations follow zoom and never respond to the pointer or keyboard.

axisPersistbooleanDefault unknown

Determines whether the x and y axes should have their scales persist while users filter the data, the timeline being the prime example (set this to true to make the axes stay consistent when the timeline changes).

backgroundConfigrecordDefault {duration: 0, fill: transparent}

A d3plus-shape configuration Object used for styling the background rectangle of the inner x/y plot (behind all of the shapes and gridlines).

bodyWidthnumberDefault 0.7

The share of each period's room the candle body (or OHLC ticks) spans, from 0 to 1. Defaults to 0.7.

bufferboolean | recordDefault assign({}, defaultBuffers, {Bar: false, Line: false})

Determines whether or not to add additional padding at the ends of x or y scales. The most commone use for this is in Scatter Plots, so that the shapes do not appear directly on the axis itself. The value provided can either be true or false to toggle the behavior for all shape types, or a keyed Object for each shape type (ie. {Bar: false, Circle: true, Line: false}).

classNamestring | array.&lt;string&gt; | undefined

CSS classes added to the outermost element this chart or component draws into, next to its fixed d3plus classes, so page CSS can target it: a chart's root <svg class="d3plus-viz"> (its <canvas> with the Canvas renderer) and a standalone component's <svg>. Takes a space-separated string or an array. A new value replaces the classes the previous one added; unset adds none. Tooltips take their own tooltipConfig.className.

closestring | functionDefault "close"

Accessor (or data key) for each period's closing value. Defaults to "close". The close is the chart's y: setting y sets it, rows without one are skipped, and hover snaps to it. Merged rows take the last row's close; aggs overrides it as it does for open.

colorDefaultscolordefaultsconfig

Overrides the default colors used when assigning fills from data and choosing legible text colors: dark and light (the text colors picked for contrast against a background), missing (null/undefined values), on/off (true/false values), sequential (the anchor hue for magnitude ramps), and scale (the categorical palette, given as a d3 ordinal scale or an array of colors). Keys are merged into the current defaults, and a Viz passes its overrides down to the shapes and components it draws.

configd3plusconfig

Methods that correspond to the key/value pairs and returns this class.

crosshairConfigrecordDefault
function
{stroke: () => themed(this._theme, (t) => t.textMuted, colorGray.500), strokeDasharray: 4 3, strokeWidth: 1}

Paint for the shared tooltip's crosshair guide line (stroke, strokeWidth, strokeDasharray, strokeOpacity, …). Merged into the current config.

datastring | array.&lt;datapoint&gt; | object

The primary data array used to draw the visualization. The value passed should be an Array of objects or a String representing a filepath or URL to be loaded. The following filetypes are supported: csv, tsv, txt, and json.

If your data URL needs specific headers to be set, an Object with a "url" and "headers" (or any other fetch request option) may also be passed. An Object with any other key is a data row, not a request.

Additionally, a custom formatting function can be passed as a second argument to this method. This custom function will be passed the data that has been loaded, as long as there are no errors. This function should return the final array of obejcts to be used as the primary data array. For example, some JSON APIs return the headers split from the data values to save bandwidth. These would need be joined using a custom formatter.

If you would like to specify certain configuration options based on the yet-to-be-loaded data, you can also return a full config object from the data formatter (including the new data array as a key in the object).

To re-fetch a URL on an interval and redraw when its data changes, set dataPollingInterval; each poll runs the same formatter.

Defaults to an empty array ([]).

downColorstring | functionDefault "#e03131"

The color of periods that closed below their open: a color string, or an accessor of the row. Defaults to red.

facetstring | false | function

Splits the chart into small multiples: a grid of equally sized panels, one per distinct value of this data key or accessor, each drawing the chart for that value's rows. The panels share one legend, color scale, title, and timeline, color each series the same way, and hover, tooltips, and legend clicks apply across all of them. Pass false to draw a single chart. See facetConfig for the grid's layout and shared scales.

facetConfigfacetconfig

Configuration for small multiples (see facet), merged into the current config: - columns / rows: the grid's shape. Chosen by default to make the panels as large as the chart's shape allows. - padding: the space between panels, in pixels (default 20). - sort: panel order — "ascending" (default), "descending", "data" (first appearance), a comparator over facet values, or an Array of values. - scales: "shared" (default) gives every panel of a chart with axes the same x/y domains; "independent" fits each panel to its own rows. Funnel defaults to "independent" (each panel sized to its own widest stage); "shared" sizes every panel against the widest stage across all panels. PolarArea and RadialBar default to "independent" (each panel's rings and ticks fit its own values); "shared" gives every panel the same value domain. - axes: with shared scales, "outer" (default) labels the axes only along the grid's left and bottom edges; "all" labels every panel. An object sets each axis on its own, as in {x: "all", y: "outer"}: every panel labels its x axis, only the left column labels its y axis, and the panels' plot areas line up. BumpChart defaults to "all", and Marimekko labels its categories on every panel and its 0–100% share axis only along the outer edge, even with independent scales. - title: a (value, data) => string function for each panel's title, or false to hide panel titles. - titleConfig: TextBox config for the panel titles (fontSize, fontWeight, fontColor, textAnchor, padding, …).

fontFamilystring | array.&lt;string&gt;

The font family used throughout the visualization.

groupBystring | function | array.&lt;string | function&gt;

Defines the mapping between data and shape. The value can be a String matching a key in each data point (default is "id"), or an accessor Function that returns a unique value for each data point. Additionally, an Array of these values may be provided if the visualization supports nested hierarchies.

highstring | functionDefault "high"

Accessor (or data key) for each period's highest value. Defaults to "high"; the high always reaches the open and close. Merged rows take the highest high; aggs overrides it as it does for open.

highlightfalse | function

Persistently emphasizes the data points matching the given predicate: the matching marks keep their color while every other mark is de-emphasized to a neutral gray (the "emphasis" form — highlight one series, gray the rest). Unlike hover/active (transient, opacity-based), highlight is a standing state that survives pointer movement. Pass false to clear it.

hollowbooleanDefault true

Draws rising candles as outlines and falling candles filled (default true), so direction reads without relying on color; false fills both. OHLC bars are never filled. An unfilled candle or bar takes no shapeConfig.texture or shapeConfig.backgroundImage; filled ones take both, with a texture's lines a shade darker than the body unless the texture sets its own stroke.

hoverfalse | function

The hover callback function for highlighting shapes on mouseover.

legendboolean | functionDefault false

Whether to display the legend. By default, the legend shows when it has more than one entry and each entry stands for a single group (or two groups at most), or when the entries are colored by a category that isn't a groupBy level (see color), in which case each entry is labelled by its category. Pass false to hide it, true to always show it, or a (config, data) => boolean function to decide.

localestring | object

The locale used for all text and number formatting. Supports the locales defined in d3plus-format. The locale can be a complex Object, a locale code (like "en-US"), or a 2-digit language code (like "en"). If a 2-digit code is provided, the "findLocale" function is used to identify the most approximate locale.

lowstring | functionDefault "low"

Accessor (or data key) for each period's lowest value. Defaults to "low"; the low always reaches the open and close. Merged rows take the lowest low; aggs overrides it as it does for open.

onstring

Event listener for the specified event typenames. Mirrors the core d3-selection behavior.

openstring | functionDefault "open"

Accessor (or data key) for each period's opening value. Defaults to "open"; a row without one opens at its close. Rows that share a series and a period merge into one candle, taking the first row's open (in data order, so sort rows oldest first). Override with an aggs entry on the data key, or, for a function accessor, on "open".

parentunknown

Parent config used by the wrapper.

renderfunction

Draws the visualization given the specified configuration.

rendererboolean | "svg" | "canvas"

Selects which @d3plus/render backend paints the visible output. "svg" = SvgRenderer (default), "canvas" = CanvasRenderer. Boolean arguments both normalize to "svg".

selectstring | htmlelement

The SVG container element as a d3 selector or DOM element. Defaults to undefined.

shapeConfigd3plusconfig

Configuration object with key/value pairs applied as method calls on each shape.

skipGapsbooleanDefault true

Places periods one slot apart in date order (default true), so days without data (weekends, holidays) leave no gap; false places each period at its date on a continuous time axis, where xConfig.rangeBreaks can hide weekends, holidays, or off-hours.

thresholdnumber | function

The threshold value for bucketing small data points together, as a share of the total. On a stacked Plot, the series whose summed value across every position is under that share of the whole chart's total merge into one series, stacked on top. A bucket needs at least two items, and its tooltips list them. Off (0) by default on Plot charts.

thresholdKeystring | function

Accessor for the value used in the threshold algorithm. A stacked Plot defaults to its stacked value.

timestring | false | function

Accessor function or string key for the time dimension of each data point.

timelinebooleanDefault false

Whether to show the timeline component.

timelineDefaultstring | date | array.&lt;string | date&gt;

The starting time or range for the timeline. Can be a single Date/String, or an Array of 2 values representing the min and max.

tooltipConfigtooltipconfigDefault {tbody: (d: DataPoint, i: number) => candleTooltipRows(viz, d, i)}

Configuration for the tooltip component.

totalstring | boolean | function

Accessor function or string key for the total value displayed in the visualization.

translatefunction

Defines how informational text strings should be displayed. By default, this function will try to find the string in question (which is the first argument provided to this function) inside of an internally managed translation Object. If you'd like to override to use custom text, simply pass this method your own custom formatting function.

upColorstring | functionDefault "#2f9e44"

The color of periods that closed at or above their open: a color string, or an accessor of the row. Defaults to green.

variant"candlestick" | "ohlc"Default "candlestick"

How each period draws: "candlestick" (default), a wick from the high to the low around a body from the open to the close; or "ohlc", a line from the high to the low with the open ticked to the left and the close ticked to the right.

volumestring | false | function

Accessor (or data key) for each period's traded volume. Off by default; when set, a strip under the candles draws one bar per candle, as tall as its volume on the strip's own axis (ticks abbreviated, e.g. "1.2M"), in its candle's up or down color, and the tooltip adds a Volume row. Bars are always filled, hollow candles included, and take shapeConfig.texture and shapeConfig.backgroundImage like filled candles; they hover with their candle. The price axis shrinks to make room, and the x axis sits under the strip. Merged rows add their volumes; an aggs entry overrides it as it does for open. Set false to turn it off.

volumeConfigobjectDefault VOLUME_DEFAULTS

The volume strip's layout and styling: height, its height as a share of the plot's (default 0.2; pixels when above 1; at most half the plot); gap, the pixels between the candles and the strip (default 16); axisConfig, Axis config for the strip's value axis; and shapeConfig, Path config for the bars (default {fillOpacity: 0.5}).

xplotaccessorargDefault
function
d => d["x"]

Accessor function or string key for the x-axis value of each data point.

x2plotaccessorargDefault
function
d => d["x2"]

Accessor function or string key for the secondary x-axis value of each data point.

x2ConfigrecordDefault {}

A pass-through to the underlying Axis config used for the secondary x-axis. Includes additional functionality where passing "auto" as the value for the scale method will determine if the scale should be "linear" or "log" based on the provided data.

xConfigrecordDefault
function
{gridConfig: {stroke: (d) => {
  if (this.schema.discrete?.charAt(0) === "x" || this._swarm?.cross === "x") return "transparent";
  const range = this._xAxis.range();
  const position = this._xAxis._getPosition.bind(this._xAxis)(d.id);
  if (range[0] === position) return "transparent";
  return chartGridline(this);
}}}

A pass-through to the underlying Axis config used for the x-axis. Includes additional functionality where passing "auto" as the value for the scale method will determine if the scale should be "linear" or "log" based on the provided data.

yplotaccessorargDefault
function
d => d["y"]

Accessor function or string key for the y-axis value of each data point.

y2plotaccessorargDefault
function
d => d["y2"]

Accessor function or string key for the secondary y-axis value of each data point.

y2ConfigrecordDefault {}

A pass-through to the underlying Axis config used for the secondary y-axis. Includes additional functionality where passing "auto" as the value for the scale method will determine if the scale should be "linear" or "log" based on the provided data.

yConfigrecordDefault
function
{gridConfig: {stroke: (d) => {
  if (this.schema.discrete?.charAt(0) === "y" || this._swarm?.cross === "y") return "transparent";
  const range = this._yAxis.range();
  const position = this._yAxis._getPosition.bind(this._yAxis)(d.id);
  if (range[range.length - 1] === position) return "transparent";
  return chartGridline(this);
}}}

A pass-through to the underlying Axis config used for the y-axis. Includes additional functionality where passing "auto" as the value for the scale method will determine if the scale should be "linear" or "log" based on the provided data.

Note: If a "domain" array is passed to the y-axis config, it will be reversed.