Shows one seeded OHLC data set toggled between no filter, Heikin-Ashi, Renko, and Point & Figure views.
drawExample.ts
index.tsx
1import {
2 EllipsePointMarker,
3 FastCandlestickRenderableSeries,
4 MouseWheelZoomModifier,
5 NumberRange,
6 NumericAxis,
7 OhlcDataSeries,
8 RolloverModifier,
9 SciChartJsNavyTheme,
10 SciChartSurface,
11 XPointMarker,
12 XyDataSeries,
13 XyScatterRenderableSeries,
14 ZoomExtentsModifier,
15 ZoomPanModifier,
16} from "scichart";
17import { OhlcHeikinAshiFilter, OhlcRenkoFilter, PointAndFigureFilter } from "scichart-financial-tools";
18
19export type TFilterMode = "source" | "heikinAshi" | "renko" | "pointAndFigure";
20
21const SOURCE_POINT_COUNT = 90;
22const RENKO_BRICK_SIZE = 1.4;
23const RENKO_REVERSAL_AMOUNT = 2;
24const PNF_BOX_SIZE = 1.2;
25const PNF_REVERSAL_AMOUNT = 2;
26
27const createSeededRandom = (seed: number) => {
28 let state = seed >>> 0;
29 return () => {
30 state = (1664525 * state + 1013904223) >>> 0;
31 return state / 0x100000000;
32 };
33};
34
35const createSeededOhlcData = (count: number) => {
36 const random = createSeededRandom(20260514);
37 const xValues: number[] = [];
38 const openValues: number[] = [];
39 const highValues: number[] = [];
40 const lowValues: number[] = [];
41 const closeValues: number[] = [];
42
43 let close = 116;
44 for (let i = 0; i < count; i++) {
45 const trend = Math.sin(i / 9) * 0.9 + Math.cos(i / 18) * 0.45;
46 const noise = (random() - 0.5) * 1.9;
47 const open = close + (random() - 0.5) * 1.2;
48 close = Math.max(78, open + trend + noise);
49 const high = Math.max(open, close) + 0.5 + random() * 1.6;
50 const low = Math.min(open, close) - 0.5 - random() * 1.5;
51
52 xValues.push(i);
53 openValues.push(Number(open.toFixed(2)));
54 highValues.push(Number(high.toFixed(2)));
55 lowValues.push(Number(low.toFixed(2)));
56 closeValues.push(Number(close.toFixed(2)));
57 }
58
59 return { xValues, openValues, highValues, lowValues, closeValues };
60};
61
62export const drawExample = async (rootElement: string | HTMLDivElement) => {
63 const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
64 theme: new SciChartJsNavyTheme(),
65 });
66
67 const xAxis = new NumericAxis(wasmContext, {
68 axisTitle: "Source Index",
69 growBy: new NumberRange(0.01, 0.01),
70 labelPrecision: 0,
71 });
72 const yAxis = new NumericAxis(wasmContext, {
73 axisTitle: "Price",
74 growBy: new NumberRange(0.08, 0.18),
75 labelPrecision: 2,
76 });
77 sciChartSurface.xAxes.add(xAxis);
78 sciChartSurface.yAxes.add(yAxis);
79
80 const sourceData = createSeededOhlcData(SOURCE_POINT_COUNT);
81 const sourceSeries = new OhlcDataSeries(wasmContext, {
82 ...sourceData,
83 dataSeriesName: "Source OHLC",
84 });
85 const heikinAshiFilter = new OhlcHeikinAshiFilter(sourceSeries, {
86 dataSeriesName: "Heikin-Ashi",
87 });
88 const renkoFilter = new OhlcRenkoFilter(sourceSeries, {
89 dataSeriesName: "Renko",
90 brickSize: RENKO_BRICK_SIZE,
91 reversalAmount: RENKO_REVERSAL_AMOUNT,
92 });
93 const pointAndFigureFilter = new PointAndFigureFilter(sourceSeries, {
94 dataSeriesName: "Point & Figure",
95 boxSize: PNF_BOX_SIZE,
96 reversalAmount: PNF_REVERSAL_AMOUNT,
97 });
98
99 const candleSeries = new FastCandlestickRenderableSeries(wasmContext, {
100 dataSeries: sourceSeries,
101 dataPointWidth: 0.62,
102 strokeThickness: 1,
103 });
104
105 const xMarksData = new XyDataSeries(wasmContext, { dataSeriesName: "Rising X" });
106 const oMarksData = new XyDataSeries(wasmContext, { dataSeriesName: "Falling O" });
107 const xMarks = new XyScatterRenderableSeries(wasmContext, {
108 dataSeries: xMarksData,
109 pointMarker: new XPointMarker(wasmContext, {
110 width: 16,
111 height: 16,
112 stroke: "#41D6A4",
113 strokeThickness: 3,
114 }),
115 });
116 const oMarks = new XyScatterRenderableSeries(wasmContext, {
117 dataSeries: oMarksData,
118 pointMarker: new EllipsePointMarker(wasmContext, {
119 width: 15,
120 height: 15,
121 stroke: "#FF6B6B",
122 fill: "transparent",
123 strokeThickness: 3,
124 }),
125 });
126
127 sciChartSurface.renderableSeries.add(candleSeries, xMarks, oMarks);
128 sciChartSurface.chartModifiers.add(
129 new ZoomPanModifier(),
130 new ZoomExtentsModifier(),
131 new MouseWheelZoomModifier(),
132 new RolloverModifier()
133 );
134
135 const syncPointAndFigureData = () => {
136 const result = pointAndFigureFilter.lastResult;
137 xMarksData.clear();
138 oMarksData.clear();
139 xMarksData.appendRange(
140 result.xMarks.map((mark) => mark.columnIndex),
141 result.xMarks.map((mark) => mark.price)
142 );
143 oMarksData.appendRange(
144 result.oMarks.map((mark) => mark.columnIndex),
145 result.oMarks.map((mark) => mark.price)
146 );
147 return result;
148 };
149
150 const setFilterMode = (mode: TFilterMode) => {
151 candleSeries.isVisible = mode !== "pointAndFigure";
152 xMarks.isVisible = mode === "pointAndFigure";
153 oMarks.isVisible = mode === "pointAndFigure";
154 xAxis.axisTitle = mode === "pointAndFigure" ? "P&F Column" : "Source Index";
155
156 if (mode === "source") {
157 candleSeries.dataSeries = sourceSeries;
158 } else if (mode === "heikinAshi") {
159 candleSeries.dataSeries = heikinAshiFilter;
160 } else if (mode === "renko") {
161 candleSeries.dataSeries = renkoFilter;
162 } else {
163 syncPointAndFigureData();
164 }
165
166 sciChartSurface.zoomExtents(300);
167 };
168
169 setFilterMode("source");
170
171 return { sciChartSurface, setFilterMode };
172};
173The React wrapper keeps the selected filter mode in state and forwards it to a chart API returned by drawExample. The filters are created once during chart initialization.

Discover how to create a React Candlestick Chart or Stock Chart using SciChart.js. For high Performance JavaScript Charts, get your free demo now.

Easily create React OHLC Chart or Stock Chart using feature-rich SciChart.js chart library. Supports custom colors. Get your free trial now.

Create a React Realtime Ticking Candlestick / Stock Chart with live ticking and updating, using the high performance SciChart.js chart library. Get free demo now.

Render a real-time React BTC order book heatmap with ease. Optimize your crypto exchange with a fast heatmap order book. Give the SciChart demo a try.

Create a React Multi-Pane Candlestick / Stock Chart with indicator panels, synchronized zooming, panning and cursors. Get your free trial of SciChart.js now.

Demonstrating the capability of SciChart.js to create a composite 2D & 3D Chart application. An example like this could be used to visualize Tenor curves in a financial setting, or other 2D/3D data combined on a single screen.

Create a React Multi-Pane Candlestick / Stock Chart with indicator panels, synchronized zooming, panning and cursors. Get your free trial of SciChart.js now.

Create a React Depth Chart, using the high performance SciChart.js chart library. Get free demo now.

Demonstrates how to place Buy/Sell arrow markers on a React Stock Chart using SciChart.js - Annotations API

This demo shows you how to create a <strong>{frameworkName} User Annotated Stock Chart</strong> using SciChart.js. Custom modifiers allow you to add lines and markers, then use the built in serialisation functions to save and reload the chart, including the data and all your custom annotations.

Build high-performance financial apps with React trading drawing tools. Try SciChart’s demo to see the advanced drawing tools for trading apps in action.

Create a custom React stock chart annotation by extending SciChart.js PolyLineAnnotation with paired dashed connectors.

Deploy the ultimate React freehand drawing tool in your app. Render complex freehand drawing tools with a smooth UI experience. Try the SciChart demo today.