Getting Started
Build your first chart step-by-step, learning the core concepts and gradually adding complexity.
Step 1 · Basic Chart with ChartCanvas, Chart & Series
Start by understanding the three foundational components that work together:
• ChartCanvas is the top-level container that orchestrates the entire charting system. It manages data processing, scales, interactions, and provides the foundation for all chart elements. It requires data, scale provider, accessors, and extents to define the plotting domain.
• Chart represents an individual chart panel within the ChartCanvas. Multiple Chart components can be stacked vertically to create multi-panel layouts. Each Chart has its own Y-scale and manages a specific vertical area. Chart components need an id, yExtents (for Y-domain calculation), and optional height/origin positioning.
• Series components (like LineSeries) render the actual data visualization. LineSeries connects data points with a line. All series need a yAccessor to extract the Y values from your data. Series components go inside Chart panels and need yAccessor functions to map data to visual coordinates.
"use client";
import * as React from "react";
import { ChartCanvas, Chart } from "@reincharts/core";
import { discontinuousTimeScaleProviderBuilder } from "@reincharts/scales";
import { LineSeries } from "@reincharts/series";
import { withOHLCData } from "@/data";
import { withSize, withDeviceRatio } from "@reincharts/utils";
interface ChartProps {
readonly data: any[];
readonly height: number;
readonly width: number;
readonly ratio: number;
}
class Step1_BasicChart extends React.Component<ChartProps> {
private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder().inputDateAccessor((d: any) => d.date);
public render() {
const { data: initialData, height, width, ratio } = this.props;
const { data, xScale, xAccessor, displayXAccessor } = this.xScaleProvider(initialData);
const max = xAccessor(data[data.length - 1]);
const min = xAccessor(data[Math.max(0, data.length - 100)]);
const xExtents = [min, max];
return (
<ChartCanvas
height={height}
width={width}
ratio={ratio}
margin={{ left: 50, right: 50, top: 10, bottom: 30 }}
data={data}
seriesName="MSFT"
xScale={xScale}
xAccessor={xAccessor}
displayXAccessor={displayXAccessor}
xExtents={xExtents}
>
<Chart id={1} yExtents={(d: any) => d.close}>
<LineSeries yAccessor={(d: any) => d.close} strokeStyle="#4f46e5" strokeWidth={2} />
</Chart>
</ChartCanvas>
);
}
}
export default withOHLCData()(withSize({ style: { minHeight: 300 } })(withDeviceRatio()(Step1_BasicChart)));
This example shows how ChartCanvas, Chart, and LineSeries work together to create a basic functioning chart. A snippet of the data being used in this chart can be found here.
Step 2 · Add Axes
Axes provide reference scales and labels for your data. XAxis shows time/date labels, YAxis shows value labels. They can be positioned at different sides and configured with ticks and grid lines.
"use client";
import * as React from "react";
import { ChartCanvas, Chart } from "@reincharts/core";
import { discontinuousTimeScaleProviderBuilder } from "@reincharts/scales";
import { LineSeries } from "@reincharts/series";
import { XAxis, YAxis } from "@reincharts/axes";
import { withOHLCData } from "@/data";
import { withSize, withDeviceRatio } from "@reincharts/utils";
interface ChartProps {
readonly data: any[];
readonly height: number;
readonly width: number;
readonly ratio: number;
}
class Step2_AddAxes extends React.Component<ChartProps> {
private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder().inputDateAccessor((d: any) => d.date);
public render() {
const { data: initialData, height, width, ratio } = this.props;
const { data, xScale, xAccessor, displayXAccessor } = this.xScaleProvider(initialData);
const max = xAccessor(data[data.length - 1]);
const min = xAccessor(data[Math.max(0, data.length - 100)]);
const xExtents = [min, max];
return (
<ChartCanvas
height={height}
width={width}
ratio={ratio}
margin={{ left: 50, right: 50, top: 10, bottom: 30 }}
data={data}
seriesName="MSFT"
xScale={xScale}
xAccessor={xAccessor}
displayXAccessor={displayXAccessor}
xExtents={xExtents}
>
<Chart id={1} yExtents={(d: any) => d.close}>
<LineSeries yAccessor={(d: any) => d.close} strokeStyle="#4f46e5" strokeWidth={2} />
<XAxis axisAt="bottom" orient="bottom" ticks={6} />
<YAxis axisAt="right" orient="right" ticks={5} />
</Chart>
</ChartCanvas>
);
}
}
export default withOHLCData()(withSize({ style: { minHeight: 300 } })(withDeviceRatio()(Step2_AddAxes)));
Axes are positioned with axisAt and orient props. They automatically scale based on the chart's domains. A snippet of the data being used in this chart can be found here.
Step 3 · Add Coordinates & Crosshair
Coordinates provide interactive feedback showing exact values under the mouse cursor. CrossHairCursor draws crosshair lines, while MouseCoordinate components show formatted values.
"use client";
import * as React from "react";
import { ChartCanvas, Chart } from "@reincharts/core";
import { discontinuousTimeScaleProviderBuilder } from "@reincharts/scales";
import { LineSeries } from "@reincharts/series";
import { XAxis, YAxis } from "@reincharts/axes";
import { CrossHairCursor, MouseCoordinateX, MouseCoordinateY } from "@reincharts/coordinates";
import { format } from "d3-format";
import { timeFormat } from "d3-time-format";
import { withOHLCData } from "@/data";
import { withSize, withDeviceRatio } from "@reincharts/utils";
interface ChartProps {
readonly data: any[];
readonly height: number;
readonly width: number;
readonly ratio: number;
}
class Step3_AddCoordinates extends React.Component<ChartProps> {
private readonly margin = { left: 50, right: 50, top: 10, bottom: 30 };
private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder().inputDateAccessor((d: any) => d.date);
public render() {
const { data: initialData, height, width, ratio } = this.props;
const { data, xScale, xAccessor, displayXAccessor } = this.xScaleProvider(initialData);
const max = xAccessor(data[data.length - 1]);
const min = xAccessor(data[Math.max(0, data.length - 100)]);
const xExtents = [min, max];
return (
<ChartCanvas
height={height}
width={width}
ratio={ratio}
margin={this.margin}
data={data}
seriesName="MSFT"
xScale={xScale}
xAccessor={xAccessor}
displayXAccessor={displayXAccessor}
xExtents={xExtents}
>
<Chart id={1} yExtents={(d: any) => d.close}>
<LineSeries yAccessor={(d: any) => d.close} strokeStyle="#4f46e5" strokeWidth={2} />
<XAxis axisAt="bottom" orient="bottom" ticks={6} />
<YAxis axisAt="right" orient="right" ticks={5} />
<MouseCoordinateX displayFormat={timeFormat("%Y-%m-%d")} />
<MouseCoordinateY rectWidth={this.margin.right} displayFormat={format(".2f")} />
</Chart>
<CrossHairCursor />
</ChartCanvas>
);
}
}
export default withOHLCData()(withSize({ style: { minHeight: 300 } })(withDeviceRatio()(Step3_AddCoordinates)));
Use displayFormat to control how values are shown. A snippet of the data being used in this chart can be found here.
Step 4 · Add Tooltips
Tooltips display data values in a fixed position as you move the mouse. Different tooltip types exist for different data formats (OHLC, single values, multiple indicators).
"use client";
import * as React from "react";
import { ChartCanvas, Chart } from "@reincharts/core";
import { discontinuousTimeScaleProviderBuilder } from "@reincharts/scales";
import { LineSeries } from "@reincharts/series";
import { XAxis, YAxis } from "@reincharts/axes";
import { CrossHairCursor, MouseCoordinateX, MouseCoordinateY } from "@reincharts/coordinates";
import { SingleValueTooltip } from "@reincharts/tooltip";
import { format } from "d3-format";
import { timeFormat } from "d3-time-format";
import { withOHLCData } from "@/data";
import { withSize, withDeviceRatio } from "@reincharts/utils";
interface ChartProps {
readonly data: any[];
readonly height: number;
readonly width: number;
readonly ratio: number;
}
class Step4_AddTooltip extends React.Component<ChartProps> {
private readonly margin = { left: 50, right: 50, top: 10, bottom: 30 };
private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder().inputDateAccessor((d: any) => d.date);
public render() {
const { data: initialData, height, width, ratio } = this.props;
const { data, xScale, xAccessor, displayXAccessor } = this.xScaleProvider(initialData);
const max = xAccessor(data[data.length - 1]);
const min = xAccessor(data[Math.max(0, data.length - 100)]);
const xExtents = [min, max];
return (
<ChartCanvas
height={height}
width={width}
ratio={ratio}
margin={this.margin}
data={data}
seriesName="MSFT"
xScale={xScale}
xAccessor={xAccessor}
displayXAccessor={displayXAccessor}
xExtents={xExtents}
>
<Chart id={1} yExtents={(d: any) => d.close}>
<LineSeries yAccessor={(d: any) => d.close} strokeStyle="#4f46e5" strokeWidth={2} />
<XAxis axisAt="bottom" orient="bottom" ticks={6} />
<YAxis axisAt="right" orient="right" ticks={5} />
<MouseCoordinateX displayFormat={timeFormat("%Y-%m-%d")} />
<MouseCoordinateY rectWidth={this.margin.right} displayFormat={format(".2f")} />
<SingleValueTooltip
yAccessor={(d: any) => d.close}
yLabel="Close"
yDisplayFormat={format(".2f")}
origin={[8, 16]}
/>
</Chart>
<CrossHairCursor />
</ChartCanvas>
);
}
}
export default withOHLCData()(withSize({ style: { minHeight: 300 } })(withDeviceRatio()(Step4_AddTooltip)));
Tooltips go inside Chart panels and use the same yAccessor pattern as series. Position them with the origin prop. A snippet of the data being used in this chart can be found here.
Step 5 · Candlestick Series
CandlestickSeries is essential for financial data, showing open, high, low, and close values. It automatically uses OHLC properties from your data and provides standard candlestick styling.
"use client";
import * as React from "react";
import { ChartCanvas, Chart } from "@reincharts/core";
import { discontinuousTimeScaleProviderBuilder } from "@reincharts/scales";
import { CandlestickSeries } from "@reincharts/series";
import { XAxis, YAxis } from "@reincharts/axes";
import { CrossHairCursor, MouseCoordinateX, MouseCoordinateY } from "@reincharts/coordinates";
import { OHLCTooltip } from "@reincharts/tooltip";
import { format } from "d3-format";
import { timeFormat } from "d3-time-format";
import { withOHLCData } from "@/data";
import { withSize, withDeviceRatio } from "@reincharts/utils";
interface ChartProps {
readonly data: any[];
readonly height: number;
readonly width: number;
readonly ratio: number;
}
class Step5_CandlestickSeries extends React.Component<ChartProps> {
private readonly margin = { left: 50, right: 50, top: 10, bottom: 30 };
private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder().inputDateAccessor((d: any) => d.date);
public render() {
const { data: initialData, height, width, ratio } = this.props;
const { data, xScale, xAccessor, displayXAccessor } = this.xScaleProvider(initialData);
const max = xAccessor(data[data.length - 1]);
const min = xAccessor(data[Math.max(0, data.length - 100)]);
const xExtents = [min, max];
return (
<ChartCanvas
height={height}
width={width}
ratio={ratio}
margin={this.margin}
data={data}
seriesName="MSFT"
xScale={xScale}
xAccessor={xAccessor}
displayXAccessor={displayXAccessor}
xExtents={xExtents}
>
<Chart id={1} yExtents={(d: any) => [d.high, d.low]}>
<CandlestickSeries />
<XAxis axisAt="bottom" orient="bottom" ticks={6} />
<YAxis axisAt="right" orient="right" ticks={5} />
<MouseCoordinateX displayFormat={timeFormat("%Y-%m-%d")} />
<MouseCoordinateY rectWidth={this.margin.right} displayFormat={format(".2f")} />
<OHLCTooltip origin={[8, 16]} />
</Chart>
<CrossHairCursor />
</ChartCanvas>
);
}
}
export default withOHLCData()(withSize({ style: { minHeight: 300 } })(withDeviceRatio()(Step5_CandlestickSeries)));
Candlestick series expect data with high, low, open, close properties. YExtents should include both high and low for proper scaling. A snippet of the data being used in this chart can be found here.
Step 6 · Multi-Panel Layout
Multiple Chart panels let you create complex layouts with different data views. Common patterns include price + volume, or price + indicators. Each panel has independent Y-scaling.
"use client";
import * as React from "react";
import { ChartCanvas, Chart } from "@reincharts/core";
import { discontinuousTimeScaleProviderBuilder } from "@reincharts/scales";
import { CandlestickSeries, BarSeries } from "@reincharts/series";
import { XAxis, YAxis } from "@reincharts/axes";
import { CrossHairCursor, MouseCoordinateX, MouseCoordinateY } from "@reincharts/coordinates";
import { OHLCTooltip } from "@reincharts/tooltip";
import { format } from "d3-format";
import { timeFormat } from "d3-time-format";
import { withOHLCData } from "@/data";
import { withSize, withDeviceRatio } from "@reincharts/utils";
interface ChartProps {
readonly data: any[];
readonly height: number;
readonly width: number;
readonly ratio: number;
}
class Step6_MultiPanel extends React.Component<ChartProps> {
private readonly margin = { left: 25, right: 75, top: 10, bottom: 30 };
private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder().inputDateAccessor((d: any) => d.date);
public render() {
const { data: initialData, height, width, ratio } = this.props;
const { data, xScale, xAccessor, displayXAccessor } = this.xScaleProvider(initialData);
const max = xAccessor(data[data.length - 1]);
const min = xAccessor(data[Math.max(0, data.length - 100)]);
const xExtents = [min, max];
const priceChartHeight = 300;
const volumeChartHeight = 100;
return (
<ChartCanvas
height={height}
width={width}
ratio={ratio}
margin={this.margin}
data={data}
seriesName="MSFT"
xScale={xScale}
xAccessor={xAccessor}
displayXAccessor={displayXAccessor}
xExtents={xExtents}
>
{/* Price Chart */}
<Chart id={1} height={priceChartHeight} origin={[0, 0]} yExtents={(d: any) => [d.high, d.low]}>
<CandlestickSeries />
<XAxis axisAt="bottom" orient="bottom" showTicks={false} outerTickSize={0} />
<YAxis axisAt="right" orient="right" ticks={5} />
<MouseCoordinateX displayFormat={timeFormat("%Y-%m-%d")} />
<MouseCoordinateY rectWidth={this.margin.right} displayFormat={format(".2f")} />
<OHLCTooltip origin={[8, 16]} />
</Chart>
{/* Volume Chart */}
<Chart
id={2}
height={volumeChartHeight}
origin={[0, priceChartHeight + 10]}
yExtents={(d: any) => d.volume}
>
<BarSeries
yAccessor={(d: any) => d.volume}
fillStyle={(d: any) => (d.close > d.open ? "#26a69a" : "#ef5350")}
/>
<XAxis axisAt="bottom" orient="bottom" ticks={6} />
<YAxis axisAt="right" orient="right" ticks={3} />
</Chart>
<CrossHairCursor />
</ChartCanvas>
);
}
}
export default withOHLCData()(withSize({ style: { minHeight: 450 } })(withDeviceRatio()(Step6_MultiPanel)));
Use height and origin props to position panels. A snippet of the data being used in this chart can be found here.
Step 7 · Technical Indicators
Indicators calculate derived data from your raw OHLC data. EMAs, moving averages, RSI, MACD and others are available. Indicators process data and merge results back into your dataset.
"use client";
import * as React from "react";
import { ChartCanvas, Chart } from "@reincharts/core";
import { discontinuousTimeScaleProviderBuilder } from "@reincharts/scales";
import { CandlestickSeries, BarSeries, LineSeries } from "@reincharts/series";
import { XAxis, YAxis } from "@reincharts/axes";
import { CrossHairCursor, MouseCoordinateX, MouseCoordinateY } from "@reincharts/coordinates";
import { OHLCTooltip, MovingAverageTooltip } from "@reincharts/tooltip";
import { ema } from "@reincharts/indicators";
import { format } from "d3-format";
import { timeFormat } from "d3-time-format";
import { withOHLCData } from "@/data";
import { withSize, withDeviceRatio } from "@reincharts/utils";
interface ChartProps {
readonly data: any[];
readonly height: number;
readonly width: number;
readonly ratio: number;
}
class Step7_MovingAverages extends React.Component<ChartProps> {
private readonly margin = { left: 25, right: 75, top: 10, bottom: 30 };
private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder().inputDateAccessor((d: any) => d.date);
public render() {
const { data: initialData, height, width, ratio } = this.props;
// Calculate moving averages
const ema12 = ema()
.id(1)
.options({ windowSize: 12 })
.merge((d: any, c: any) => {
d.ema12 = c;
})
.accessor((d: any) => d.ema12);
const ema26 = ema()
.id(2)
.options({ windowSize: 26 })
.merge((d: any, c: any) => {
d.ema26 = c;
})
.accessor((d: any) => d.ema26);
const calculatedData = ema26(ema12(initialData));
const { data, xScale, xAccessor, displayXAccessor } = this.xScaleProvider(calculatedData);
const max = xAccessor(data[data.length - 1]);
const min = xAccessor(data[Math.max(0, data.length - 100)]);
const xExtents = [min, max];
const priceChartHeight = 300;
const volumeChartHeight = 100;
return (
<ChartCanvas
height={height}
width={width}
ratio={ratio}
margin={this.margin}
data={data}
seriesName="MSFT"
xScale={xScale}
xAccessor={xAccessor}
displayXAccessor={displayXAccessor}
xExtents={xExtents}
>
{/* Price Chart */}
<Chart id={1} height={priceChartHeight} origin={[0, 0]} yExtents={(d: any) => [d.high, d.low]}>
<CandlestickSeries />
<LineSeries yAccessor={ema12.accessor()} strokeStyle="#1f77b4" strokeWidth={1} />
<LineSeries yAccessor={ema26.accessor()} strokeStyle="#ff7f0e" strokeWidth={1} />
<XAxis axisAt="bottom" orient="bottom" showTicks={false} outerTickSize={0} />
<YAxis axisAt="right" orient="right" ticks={5} />
<MouseCoordinateX displayFormat={timeFormat("%Y-%m-%d")} />
<MouseCoordinateY rectWidth={this.margin.right} displayFormat={format(".2f")} />
<OHLCTooltip origin={[8, 16]} />
<MovingAverageTooltip
origin={[8, 48]}
options={[
{
yAccessor: ema12.accessor(),
type: "EMA",
stroke: "#1f77b4",
windowSize: ema12.options().windowSize,
},
{
yAccessor: ema26.accessor(),
type: "EMA",
stroke: "#ff7f0e",
windowSize: ema26.options().windowSize,
},
]}
/>
</Chart>
{/* Volume Chart */}
<Chart
id={2}
height={volumeChartHeight}
origin={[0, priceChartHeight + 10]}
yExtents={(d: any) => d.volume}
>
<BarSeries
yAccessor={(d: any) => d.volume}
fillStyle={(d: any) => (d.close > d.open ? "#26a69a" : "#ef5350")}
/>
<XAxis axisAt="bottom" orient="bottom" ticks={6} />
<YAxis axisAt="right" orient="right" ticks={3} />
</Chart>
<CrossHairCursor />
</ChartCanvas>
);
}
}
export default withOHLCData()(withSize({ style: { minHeight: 450 } })(withDeviceRatio()(Step7_MovingAverages)));
Indicators are calculated before creating the chart, then rendered as LineSeries. Use specialized tooltips to display indicator values. A snippet of the data being used in this chart can be found here.
Step 8 · Complete Chart
Final result with all features enabled: responsive sizing, grid lines, proper margins, and production-ready styling. This represents a typical financial chart implementation.
"use client";
import * as React from "react";
import { ChartCanvas, Chart } from "@reincharts/core";
import { discontinuousTimeScaleProviderBuilder } from "@reincharts/scales";
import { CandlestickSeries, BarSeries, LineSeries } from "@reincharts/series";
import { XAxis, YAxis } from "@reincharts/axes";
import { CrossHairCursor, MouseCoordinateX, MouseCoordinateY } from "@reincharts/coordinates";
import { OHLCTooltip, MovingAverageTooltip } from "@reincharts/tooltip";
import { ema } from "@reincharts/indicators";
import { format } from "d3-format";
import { timeFormat } from "d3-time-format";
import { withOHLCData } from "@/data";
import { withSize, withDeviceRatio } from "@reincharts/utils";
interface ChartProps {
readonly data: any[];
readonly height: number;
readonly width: number;
readonly ratio: number;
}
class Step8_CompleteChart extends React.Component<ChartProps> {
private readonly margin = { left: 25, right: 75, top: 10, bottom: 30 };
private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder().inputDateAccessor((d: any) => d.date);
public render() {
const { data: initialData, height, width, ratio } = this.props;
// Calculate moving averages
const ema12 = ema()
.id(1)
.options({ windowSize: 12 })
.merge((d: any, c: any) => {
d.ema12 = c;
})
.accessor((d: any) => d.ema12);
const ema26 = ema()
.id(2)
.options({ windowSize: 26 })
.merge((d: any, c: any) => {
d.ema26 = c;
})
.accessor((d: any) => d.ema26);
const calculatedData = ema26(ema12(initialData));
const { data, xScale, xAccessor, displayXAccessor } = this.xScaleProvider(calculatedData);
const max = xAccessor(data[data.length - 1]);
const min = xAccessor(data[Math.max(0, data.length - 100)]);
const xExtents = [min, max];
const priceChartHeight = 300;
const volumeChartHeight = 100;
return (
<ChartCanvas
height={height}
width={width}
ratio={ratio}
margin={this.margin}
data={data}
seriesName="MSFT"
xScale={xScale}
xAccessor={xAccessor}
displayXAccessor={displayXAccessor}
xExtents={xExtents}
>
{/* Price Chart */}
<Chart id={1} height={priceChartHeight} origin={[0, 0]} yExtents={(d: any) => [d.high, d.low]}>
<CandlestickSeries />
<LineSeries yAccessor={ema12.accessor()} strokeStyle="#1f77b4" strokeWidth={1} />
<LineSeries yAccessor={ema26.accessor()} strokeStyle="#ff7f0e" strokeWidth={1} />
<XAxis axisAt="bottom" orient="bottom" showTicks={false} outerTickSize={0} showGridLines />
<YAxis axisAt="right" orient="right" ticks={5} showGridLines />
<MouseCoordinateX displayFormat={timeFormat("%Y-%m-%d")} />
<MouseCoordinateY rectWidth={this.margin.right} displayFormat={format(".2f")} />
<OHLCTooltip origin={[8, 16]} />
<MovingAverageTooltip
origin={[8, 48]}
options={[
{
yAccessor: ema12.accessor(),
type: "EMA",
stroke: "#1f77b4",
windowSize: ema12.options().windowSize,
},
{
yAccessor: ema26.accessor(),
type: "EMA",
stroke: "#ff7f0e",
windowSize: ema26.options().windowSize,
},
]}
/>
</Chart>
{/* Volume Chart */}
<Chart
id={2}
height={volumeChartHeight}
origin={[0, priceChartHeight + 10]}
yExtents={(d: any) => d.volume}
>
<BarSeries
yAccessor={(d: any) => d.volume}
fillStyle={(d: any) => (d.close > d.open ? "#26a69a" : "#ef5350")}
/>
<XAxis axisAt="bottom" orient="bottom" ticks={6} showGridLines />
<YAxis axisAt="right" orient="right" ticks={3} />
</Chart>
<CrossHairCursor />
</ChartCanvas>
);
}
}
export default withOHLCData()(withSize({ style: { minHeight: 450 } })(withDeviceRatio()(Step8_CompleteChart)));
Use withSize and withDeviceRatio HOCs for responsive charts. Add grid lines and proper margins for professional appearance. A snippet of the data being used in this chart can be found here.
Data
This is a snippet of the data that is used in the examples above.
[
{
"date": "2010-01-04T00:00:00.000Z",
"open": 25.436282332605284,
"high": 25.835021381744056,
"low": 25.411360259406774,
"close": 25.710416,
"volume": 38409100,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-05T00:00:00.000Z",
"open": 25.627344939513726,
"high": 25.83502196495549,
"low": 25.452895407434543,
"close": 25.718722,
"volume": 49749600,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-06T00:00:00.000Z",
"open": 25.65226505944465,
"high": 25.81840750861228,
"low": 25.353210976925574,
"close": 25.560888,
"volume": 58182400,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-07T00:00:00.000Z",
"open": 25.444587793771767,
"high": 25.502739021094353,
"low": 25.079077898061875,
"close": 25.295062,
"volume": 50559700,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-08T00:00:00.000Z",
"open": 25.153841756996414,
"high": 25.6522649488092,
"low": 25.120612602739726,
"close": 25.46951,
"volume": 51197400,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-11T00:00:00.000Z",
"open": 25.511044730573705,
"high": 25.55258096597291,
"low": 25.02092861663475,
"close": 25.145534,
"volume": 68754700,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-12T00:00:00.000Z",
"open": 25.045848646491518,
"high": 25.253525666777517,
"low": 24.84647870701696,
"close": 24.979392,
"volume": 65912100,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-13T00:00:00.000Z",
"open": 25.13722727051071,
"high": 25.353211377924218,
"low": 24.929550244151567,
"close": 25.211991,
"volume": 51863500,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-14T00:00:00.000Z",
"open": 25.178761733851413,
"high": 25.83502196495549,
"low": 25.137227159471163,
"close": 25.718722,
"volume": 63228100,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-15T00:00:00.000Z",
"open": 25.818406945612217,
"high": 25.95132023748152,
"low": 25.51104412745638,
"close": 25.635652,
"volume": 79913200,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-19T00:00:00.000Z",
"open": 25.544274163987136,
"high": 25.95132113440514,
"low": 25.486124596784563,
"close": 25.835022,
"volume": 46575700,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-20T00:00:00.000Z",
"open": 25.59411494568944,
"high": 25.702108656795026,
"low": 25.17876090842236,
"close": 25.41136,
"volume": 54849500,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-21T00:00:00.000Z",
"open": 25.427975689088637,
"high": 25.51935191837554,
"low": 24.92124291902699,
"close": 24.92955,
"volume": 73086700,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-22T00:00:00.000Z",
"open": 24.921242227943445,
"high": 25.087384673504477,
"low": 23.9576208617963,
"close": 24.057305,
"volume": 102004600,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
},
{
"date": "2010-01-25T00:00:00.000Z",
"open": 24.289904353342425,
"high": 24.63880174829468,
"low": 24.17360522169168,
"close": 24.356361,
"volume": 63373000,
"split": 0,
"dividend": 0,
"absoluteChange": 0,
"percentChange": 0
}
]
Architecture Summary
Component Hierarchy
<ChartCanvas> // Top-level container, manages data & interactions
<Chart id={1}> // Individual chart panel with Y-scale
<_Series/> // Visual data representation
<_Axis/> // Axis labels and ticks
<MouseCoordinate_/> // X-coordinate display
<_Tooltip/> // Data tooltips
</Chart>
<_Cursor/> // Custom cursor
</ChartCanvas>
Key Concepts
• ChartCanvas: Foundation layer handling data, scales, events, and canvas management
• Chart: Individual panels with independent Y-scales for different data views
• Series: Visual representations of data (lines, candlesticks, bars, etc.)
• Axes: Reference scales and labels positioned around chart panels
• Coordinates: Interactive feedback showing cursor position and values
• Tooltips: Fixed-position data displays that update with mouse movement
• Indicators: Calculated data transformations (moving averages, RSI, etc.)
Next Steps
You've learned the core concepts. Next, explore interactive components or explore other chart features.