This demo shows you how to create a Angular User Annotated Stock Chart 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.
drawExample.ts
angular.ts
binanceRestClient.ts
ExampleDataProvider.ts
theme.ts
CreateLineAnnotationModifier.ts
CreateTradeMarkerModifier.ts
RulerModifier.ts
1// SCICHART EXAMPLE
2import {
3 AnnotationClickEventArgs,
4 buildDataSeries,
5 CategoryAxis,
6 chartReviver,
7 configure2DSurface,
8 CursorModifier,
9 CursorTooltipSvgAnnotation,
10 CustomAnnotation,
11 DateTimeNumericAxis,
12 EAutoRange,
13 EBaseType,
14 ECoordinateMode,
15 EDataSeriesType,
16 EExecuteOn,
17 EFillPaletteMode,
18 EHorizontalAnchorPoint,
19 EMultiLineAlignment,
20 ENumericFormat,
21 ESeriesType,
22 EVerticalAnchorPoint,
23 FastCandlestickRenderableSeries,
24 FastColumnRenderableSeries,
25 FastLineRenderableSeries,
26 FastMountainRenderableSeries,
27 FastOhlcRenderableSeries,
28 GradientParams,
29 IFillPaletteProvider,
30 IPointMetadata,
31 IRenderableSeries,
32 MouseWheelZoomModifier,
33 NativeTextAnnotation,
34 NumberRange,
35 NumericAxis,
36 OhlcDataSeries,
37 OhlcSeriesInfo,
38 parseColorToUIntArgb,
39 Point,
40 registerFunction,
41 SciChartOverview,
42 SciChartSurface,
43 SeriesInfo,
44 SmartDateLabelProvider,
45 TOhlcSeriesData,
46 XyDataSeries,
47 XyMovingAverageFilter,
48 ZoomExtentsModifier,
49 ZoomPanModifier,
50} from "scichart";
51import { appTheme } from "../../../theme";
52import { CreateTradeMarkerModifier } from "./CreateTradeMarkerModifier";
53import { CreateLineAnnotationModifier } from "./CreateLineAnnotationModifier";
54import { VerticalYRulerModifier } from "./RulerModifier";
55import { simpleBinanceRestClient } from "../../../ExampleData/binanceRestClient";
56import { ExampleDataProvider } from "../../../ExampleData/ExampleDataProvider";
57
58const deleteOnClick = (args: AnnotationClickEventArgs) => {
59 if (args.sender.isSelected && args.mouseArgs.ctrlKey) {
60 args.sender.parentSurface.annotations.remove(args.sender, true);
61 }
62};
63
64registerFunction(EBaseType.OptionFunction, "deleteOnClick", deleteOnClick);
65
66export const drawExample = async (divElementId: string | HTMLDivElement) => {
67 // Create a SciChartSurface
68 const { sciChartSurface, wasmContext } = await SciChartSurface.create(divElementId, {
69 theme: appTheme.SciChartJsTheme,
70 });
71
72 const xAxis = new CategoryAxis(wasmContext, {
73 // autoRange.never as we're setting visibleRange explicitly below. If you dont do this, leave this flag default
74 autoRange: EAutoRange.Never,
75 labelProvider: new SmartDateLabelProvider(),
76 });
77 sciChartSurface.xAxes.add(xAxis);
78
79 // Create a NumericAxis on the YAxis with 2 Decimal Places
80 sciChartSurface.yAxes.add(
81 new NumericAxis(wasmContext, {
82 growBy: new NumberRange(0.1, 0.1),
83 labelFormat: ENumericFormat.Decimal,
84 labelPrecision: 2,
85 labelPrefix: "$",
86 autoRange: EAutoRange.Always,
87 })
88 );
89
90 const day = 24 * 60 * 60;
91 const startDate = new Date(Date.now() - 300 * day);
92 const { xValues, openValues, highValues, lowValues, closeValues } = ExampleDataProvider.getRandomOHLCVData(
93 300,
94 1.5,
95 startDate,
96 day
97 );
98
99 // Create and add the Candlestick series
100 // The Candlestick Series requires a special dataseries type called OhlcDataSeries with o,h,l,c and date values
101 const candleDataSeries = new OhlcDataSeries(wasmContext, {
102 xValues,
103 openValues,
104 highValues,
105 lowValues,
106 closeValues,
107 dataSeriesName: "BTC/USDT",
108 });
109 const candlestickSeries = new FastCandlestickRenderableSeries(wasmContext, {
110 id: "Candles",
111 dataSeries: candleDataSeries,
112 stroke: appTheme.ForegroundColor, // used by cursorModifier below
113 strokeThickness: 1,
114 brushUp: appTheme.VividGreen + "77",
115 brushDown: appTheme.MutedRed + "77",
116 strokeUp: appTheme.VividGreen,
117 strokeDown: appTheme.MutedRed,
118 });
119 sciChartSurface.renderableSeries.add(candlestickSeries);
120
121 // Add some moving averages using SciChart's filters/transforms API
122 // when candleDataSeries updates, XyMovingAverageFilter automatically recomputes
123 sciChartSurface.renderableSeries.add(
124 new FastLineRenderableSeries(wasmContext, {
125 dataSeries: new XyMovingAverageFilter(candleDataSeries, {
126 dataSeriesName: "Moving Average (20)",
127 length: 20,
128 }),
129 stroke: appTheme.VividSkyBlue,
130 })
131 );
132
133 sciChartSurface.renderableSeries.add(
134 new FastLineRenderableSeries(wasmContext, {
135 dataSeries: new XyMovingAverageFilter(candleDataSeries, {
136 dataSeriesName: "Moving Average (50)",
137 length: 50,
138 }),
139 stroke: appTheme.VividPink,
140 })
141 );
142
143 // Optional: Add some interactivity modifiers
144 sciChartSurface.chartModifiers.add(
145 new ZoomExtentsModifier(),
146 new MouseWheelZoomModifier(),
147 new ZoomPanModifier({ id: "pan" }),
148 new CreateTradeMarkerModifier({ id: "marker" }),
149 new CreateLineAnnotationModifier({ id: "line" })
150 );
151 sciChartSurface.chartModifiers.getById("marker").isEnabled = false;
152 sciChartSurface.chartModifiers.getById("line").isEnabled = false;
153
154 const helpAnnotation = new NativeTextAnnotation({
155 x1: 20,
156 y1: 20,
157 xCoordinateMode: ECoordinateMode.Pixel,
158 yCoordinateMode: ECoordinateMode.Pixel,
159 verticalAnchorPoint: EVerticalAnchorPoint.Top,
160 multiLineAlignment: EMultiLineAlignment.Left,
161 textColor: appTheme.ForegroundColor,
162 });
163 // Add this to modifierAnnotations so it is not saved/loaded
164 sciChartSurface.modifierAnnotations.add(helpAnnotation);
165
166 const getDefinition = () => {
167 return {
168 visibleRange: xAxis.visibleRange,
169 annotations: sciChartSurface.annotations.asArray().map((annotation) => annotation.toJSON()),
170 data: candleDataSeries.toJSON(),
171 };
172 };
173 const applyDefinition = (definition: any) => {
174 if (definition) {
175 configure2DSurface({ annotations: definition.annotations }, sciChartSurface, wasmContext);
176 xAxis.visibleRange = definition.visibleRange;
177 const newData = definition.data.options as TOhlcSeriesData;
178 candleDataSeries.clear();
179 candleDataSeries.appendRange(
180 newData.xValues,
181 newData.openValues,
182 newData.highValues,
183 newData.lowValues,
184 newData.closeValues
185 );
186 }
187 };
188
189 const setChartMode = (mode: string) => {
190 if (mode === "pan") {
191 sciChartSurface.chartModifiers.getById("marker").isEnabled = false;
192 sciChartSurface.chartModifiers.getById("line").isEnabled = false;
193 sciChartSurface.chartModifiers.getById("pan").isEnabled = true;
194 helpAnnotation.text = `Click and drag to pan the chart`;
195 } else if (mode === "line") {
196 sciChartSurface.chartModifiers.getById("marker").isEnabled = false;
197 sciChartSurface.chartModifiers.getById("line").isEnabled = true;
198 sciChartSurface.chartModifiers.getById("pan").isEnabled = false;
199 helpAnnotation.text = `Click and drag to draw a line.
200Ctrl + click a line to delete it`;
201 } else if (mode === "marker") {
202 sciChartSurface.chartModifiers.getById("marker").isEnabled = true;
203 sciChartSurface.chartModifiers.getById("line").isEnabled = false;
204 sciChartSurface.chartModifiers.getById("pan").isEnabled = false;
205 helpAnnotation.text = `Left click to place a buy marker.
206Right click to place a sell marker
207Ctrl + Click to delete a marker`;
208 }
209 };
210
211 const resetChart = () => {
212 sciChartSurface.annotations.clear(true);
213 // Zoom to the latest 100 candles
214 xAxis.visibleRange = new NumberRange(xValues.length - 100, xValues.length - 1);
215 };
216
217 resetChart();
218 setChartMode("line");
219
220 return {
221 sciChartSurface,
222 controls: { getDefinition, applyDefinition, resetChart, setChartMode },
223 };
224};
225
Discover how to create a Angular Candlestick Chart or Stock Chart using SciChart.js. For high Performance JavaScript Charts, get your free demo now.
Easily create Angular OHLC Chart or Stock Chart using feature-rich SciChart.js chart library. Supports custom colors. Get your free trial now.
Create a Angular Realtime Ticking Candlestick / Stock Chart with live ticking and updating, using the high performance SciChart.js chart library. Get free demo now.
Create a Angular 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 Angular Multi-Pane Candlestick / Stock Chart with indicator panels, synchronized zooming, panning and cursors. Get your free trial of SciChart.js now.
Create a Angular Depth Chart, using the high performance SciChart.js chart library. Get free demo now.
Demonstrates how to place Buy/Sell arrow markers on a Angular Stock Chart using SciChart.js - Annotations API