React Trading Drawing Tools

Trading Drawing Tools Demo, which shows how to use Polylines, Extended Lines, Rays, Channels, Pitchforks, Pitchfans, Fibonnaci Retracements, Measure, Stop Loss and Take Profit chart drawing tools for Technical Analysis.

Select Annotation

Fullscreen

Edit

 Edit

Docs

drawExample.ts

index.tsx

tradingAnnotationExampleUtils.ts

Copy to clipboard
Minimise
Fullscreen
1import { buildAnnotations, ERenderLayer, Thickness, IAnnotation } from "scichart";
2import {
3    EAnnotationVisibilityMode,
4    EFibonacciLabelColorMode,
5    EFibonacciLabelPlacement,
6    ETradingAnnotationType,
7    ChannelAnnotation,
8    FibonacciRetracementAnnotation,
9    ExtendedLineAnnotation,
10    MultiPointAnnotationPlacementModifier,
11    TFibonacciLevelLabelFormatParams,
12    FreehandDrawingAnnotation,
13    FreehandDrawingModifier,
14    IMultiPointAnnotationBaseOptions,
15    EMultiPointLabelAnchorMode,
16    EAxisLabelDrawMode,
17} from "scichart-financial-tools";
18import {
19    addDefaultFinancialModifiers,
20    createFinancialChart,
21    createTradingAnnotationOptions,
22    defaultSnapToCandleOptions,
23    FIB_REGION_COLORS,
24    TRADING_ANNOTATION_COLORS,
25} from "../_shared/tradingAnnotationExampleUtils";
26
27type TStartToolOptions = {
28    snapToCandle?: boolean;
29    extendStart?: boolean;
30    extendEnd?: boolean;
31    verticalOnly?: boolean;
32    lockedAspect?: boolean;
33};
34
35const CHANNEL_LABEL_PAIRS = [
36    [0, 1],
37    [2, 3],
38] as const;
39
40const PITCH_LABEL_PAIRS = [[1, 2]] as const;
41
42export const drawExample = async (rootElement: string | HTMLDivElement) => {
43    const ctx = await createFinancialChart(rootElement, {
44        volatility: 0.0028,
45        title: "BTC / USDT - Drawing Tools",
46        startDate: new Date("2024-01-01T00:00:00Z"),
47        dataSeed: 133337,
48    });
49    const { sciChartSurface, candlestickSeries, xAt, yAt } = ctx;
50
51    const placementModifier = new MultiPointAnnotationPlacementModifier({
52        isPlacing: false,
53        keepPlacingAfterComplete: false,
54    });
55    const freehandDrawingModifier = new FreehandDrawingModifier({
56        isDrawing: false,
57        keepDrawingAfterComplete: true,
58        pointSamplingDistancePx: 0.5,
59        simplifyTolerancePx: 1,
60        maxPoints: 5000,
61    });
62
63    addDefaultFinancialModifiers(sciChartSurface);
64    sciChartSurface.chartModifiers.add(freehandDrawingModifier, placementModifier);
65
66    const preparePlacementOptions = <T extends IMultiPointAnnotationBaseOptions>(options: T): T => options;
67
68    const stopActiveTools = () => {
69        console.log('stop active tools');
70        placementModifier.stopPlacement(true);
71        freehandDrawingModifier.stopDrawing(true);
72    };
73
74    const startFreehand = (lockedAspect = false) => {
75        placementModifier.stopPlacement(true);
76        freehandDrawingModifier.startDrawing({
77            isEditable: true,
78            stroke: lockedAspect ? TRADING_ANNOTATION_COLORS.lockedFreehand : TRADING_ANNOTATION_COLORS.freehand,
79            strokeThickness: 2,
80            showBoxOutline: true,
81            showBoxOutlineOnlyWhenSelected: true,
82            boxOutlineStrokeDashArray: [6, 4],
83            keepAspectRatioOnResize: lockedAspect,
84            forcedAspectRatio: lockedAspect ? 1 : undefined,
85            allowMove: true,
86            annotationsGripsRadius: 4,
87            annotationsGripsStroke: lockedAspect
88                ? TRADING_ANNOTATION_COLORS.lockedFreehand
89                : TRADING_ANNOTATION_COLORS.freehand,
90            gripSvgTemplate: (annotation: any, x: number, y: number) => {
91                const ann = annotation as FreehandDrawingAnnotation;
92                return `<circle cx="${x}" cy="${y}" r="${ann.annotationsGripsRadius}" fill="${ann.parentSurface.background}" stroke="${ann.annotationsGripsStroke}" stroke-width="${ann.strokeThickness}" />`;
93            },
94        });
95    };
96
97    const startTool = (tool: ETradingAnnotationType, options: TStartToolOptions = {}) => {
98        stopActiveTools();
99
100        switch (tool) {
101            case ETradingAnnotationType.PolyLineAnnotation: {
102                const color = options.snapToCandle
103                    ? TRADING_ANNOTATION_COLORS.snappedPolyline
104                    : TRADING_ANNOTATION_COLORS.freePolyline;
105
106                placementModifier.startPlacement({
107                    type: ETradingAnnotationType.PolyLineAnnotation,
108                    options: {
109                        ...createTradingAnnotationOptions(options.snapToCandle ? "SNP" : "PLY", 5),
110                        ...(options.snapToCandle ? defaultSnapToCandleOptions(candlestickSeries.id) : {}),
111                        isEditable: true,
112                        stroke: color,
113                        strokeThickness: 2,
114                        fill: `${color}33`,
115                        placementPointCount: 5,
116                    } as any,
117                });
118                return;
119            }
120            case ETradingAnnotationType.ExtendedLineAnnotation: {
121                const extendStart = options.extendStart ?? true;
122                const extendEnd = options.extendEnd ?? true;
123
124                placementModifier.startPlacement({
125                    type: ETradingAnnotationType.ExtendedLineAnnotation,
126                    options: preparePlacementOptions({
127                        ...createTradingAnnotationOptions("RAY", 2),
128                        isEditable: true,
129                        stroke:
130                            extendStart && extendEnd
131                                ? TRADING_ANNOTATION_COLORS.extendedLine
132                                : TRADING_ANNOTATION_COLORS.ray,
133                        strokeThickness: 2,
134                        extendStart,
135                        extendEnd,
136                    }),
137                });
138                return;
139            }
140            case ETradingAnnotationType.ChannelAnnotation:
141                placementModifier.startPlacement({
142                    type: ETradingAnnotationType.ChannelAnnotation,
143                    options: preparePlacementOptions({
144                        ...createTradingAnnotationOptions("CHN", 4, undefined, { includeSegmentLabels: false }),
145                        isEditable: true,
146                        stroke: TRADING_ANNOTATION_COLORS.channel,
147                        fill: `${TRADING_ANNOTATION_COLORS.channel}33`,
148                        strokeThickness: 2,
149                        midLineStrokeDashArray: [4, 3],
150                        showMidLine: true,
151                        showMidPointGrips: true,
152                        
153                    } as any),
154                });
155                console.log('placing channel');
156                return;
157            case ETradingAnnotationType.FlatBottomChannelAnnotation:
158                placementModifier.startPlacement({
159                    type: ETradingAnnotationType.FlatBottomChannelAnnotation,
160                    options: preparePlacementOptions({
161                        ...createTradingAnnotationOptions("FLT", 4, undefined, { segmentPairs: CHANNEL_LABEL_PAIRS }),
162                        isEditable: true,
163                        stroke: TRADING_ANNOTATION_COLORS.flatChannel,
164                        fill: `${TRADING_ANNOTATION_COLORS.flatChannel}33`,
165                        strokeThickness: 2,
166                        midLineStrokeDashArray: [4, 3],
167                        showMidLine: true,
168                        showMidPointGrips: false,
169                    } as any),
170                });
171                return;
172            case ETradingAnnotationType.DisjointChannelAnnotation:
173                placementModifier.startPlacement({
174                    type: ETradingAnnotationType.DisjointChannelAnnotation,
175                    options: preparePlacementOptions({
176                        ...createTradingAnnotationOptions("DSJ", 4, undefined, { segmentPairs: CHANNEL_LABEL_PAIRS }),
177                        isEditable: true,
178                        stroke: TRADING_ANNOTATION_COLORS.disjointChannel,
179                        fill: `${TRADING_ANNOTATION_COLORS.disjointChannel}33`,
180                        strokeThickness: 2,
181                        midLineStrokeDashArray: [4, 3],
182                    } as any),
183                });
184                return;
185            case ETradingAnnotationType.PitchforkAnnotation:
186                placementModifier.startPlacement({
187                    type: ETradingAnnotationType.PitchforkAnnotation,
188                    options: preparePlacementOptions({
189                        ...createTradingAnnotationOptions("PFK", 3, undefined, { segmentPairs: PITCH_LABEL_PAIRS }),
190                        isEditable: true,
191                        stroke: TRADING_ANNOTATION_COLORS.pitchfork,
192                        strokeThickness: 2,
193                        showFullWidthZone: true,
194                        fullWidthZoneFill: `${TRADING_ANNOTATION_COLORS.pitchZone}66`,
195                        fullWidthZoneStroke: TRADING_ANNOTATION_COLORS.pitchZone,
196                        showHalfWidthZone: true,
197                        halfWidthZoneFill: "#33ff3366",
198                        halfWidthZoneStroke: "#33ff33",
199                        renderLayer: ERenderLayer.First,
200                    } as any),
201                });
202                return;
203            case ETradingAnnotationType.PitchfanAnnotation:
204                placementModifier.startPlacement({
205                    type: ETradingAnnotationType.PitchfanAnnotation,
206                    options: preparePlacementOptions({
207                        ...createTradingAnnotationOptions("FAN", 3, undefined, {
208                            segmentPairs: [...PITCH_LABEL_PAIRS, [0, 1]],
209                        }),
210                        isEditable: true,
211                        stroke: TRADING_ANNOTATION_COLORS.pitchfan,
212                        strokeThickness: 2,
213                        showShoulderLine: true,
214                        showFullWidthZone: true,
215                        fullWidthZoneFill: `${TRADING_ANNOTATION_COLORS.pitchZone}66`,
216                        fullWidthZoneStroke: TRADING_ANNOTATION_COLORS.pitchZone,
217                        showHalfWidthZone: true,
218                        halfWidthZoneFill: `${TRADING_ANNOTATION_COLORS.halfPitchZone}66`,
219                        halfWidthZoneStroke: TRADING_ANNOTATION_COLORS.halfPitchZone,
220                    } as any),
221                });
222                return;
223            case ETradingAnnotationType.FibonacciRetracementAnnotation:
224                placementModifier.startPlacement({
225                    type: ETradingAnnotationType.FibonacciRetracementAnnotation,
226                    options: preparePlacementOptions({
227                        ...createTradingAnnotationOptions("FIB", 3, undefined, {
228                            includeSegmentLabels: false,
229                            extraLabels: options.verticalOnly // note that "extraLabels" is not a library prop, these are just additional utils
230                                ? [
231                                    // extra axis labels to show extended Fibonacci using "segmentRatio"
232                                    // for labels at thresholds "-0.618" and "2.618"
233                                    {
234                                        id: `FIB-pt-extended-1`,
235                                        anchorMode: EMultiPointLabelAnchorMode.Axis,
236                                        axisLabelDrawMode: EAxisLabelDrawMode.Y,
237                                        segmentStartIndex: 1,
238                                        segmentEndIndex: 2,
239                                        segmentRatio: 2.618,
240                                    },
241                                    {
242                                        id: `FIB-pt-extended-2`,
243                                        anchorMode: EMultiPointLabelAnchorMode.Axis,
244                                        axisLabelDrawMode: EAxisLabelDrawMode.Y,
245                                        segmentStartIndex: 1,
246                                        segmentEndIndex: 2,
247                                        segmentRatio: -0.618,
248                                    },
249                                ]
250                                : [
251                                    {
252                                        id: `FIB-pt-extended-1`,
253                                        anchorMode: EMultiPointLabelAnchorMode.Axis,
254                                        axisLabelDrawMode: EAxisLabelDrawMode.Y,
255                                        segmentStartIndex: 1,
256                                        segmentEndIndex: 2,
257                                        segmentRatio: 4.236,
258                                    },
259                                ],
260                        }),
261                        isEditable: true,
262                        strokeThickness: 2,
263                        regionColors: options.verticalOnly
264                            ? ["#F85161", "#FB8B62", "#D2E26F", "#70CEA5", "#7FAECE"]
265                            : FIB_REGION_COLORS,
266                        fillOpacity: 0.25,
267                        opacity: 1,
268                        showConnectorLine: true,
269                        connectorLineStrokeDashArray: options.verticalOnly ? [16, 4] : [6, 4],
270                        //thresholds: options.verticalOnly ? [-0.618, -0.236, 0, 0.618, 1, 2.618] : undefined, // use defaults
271                        verticalOnly: options.verticalOnly,
272                        // fibonacciLabelPlacement: EFibonacciLabelPlacement.Top,
273                        // fibonacciLabelColorMode: EFibonacciLabelColorMode.MultiColor,
274                        // formatFibonacciLabel: (params: TFibonacciLevelLabelFormatParams) => {
275                            // const percentage = `${(params.threshold * 100).toFixed(1)}%`;
276                            // return `${percentage}\n${params.valueLabel}`;
277                        // },
278                    } as any),
279                });
280                return;
281            case ETradingAnnotationType.FibonacciExtensionAnnotation:
282                placementModifier.startPlacement({
283                    type: ETradingAnnotationType.FibonacciExtensionAnnotation,
284                    options: preparePlacementOptions({
285                        ...createTradingAnnotationOptions("FBE", 3, undefined, { includeSegmentLabels: false }),
286                        isEditable: true,
287                        strokeThickness: 2,
288                        regionColors: FIB_REGION_COLORS,
289                        fillOpacity: 0.25,
290                        opacity: 1,
291                        showConnectorLine: true,
292                        connectorLineStrokeDashArray: [6, 4],
293                    } as any),
294                });
295                return;
296            case ETradingAnnotationType.FibonacciCirclesAnnotation:
297                placementModifier.startPlacement({
298                    type: ETradingAnnotationType.FibonacciCirclesAnnotation,
299                    options: preparePlacementOptions({
300                        ...createTradingAnnotationOptions("FBC", 2, undefined, { includeSegmentLabels: false }),
301                        isEditable: true,
302                        strokeThickness: 2,
303                        regionColors: FIB_REGION_COLORS,
304                        fillOpacity: 0.2,
305                        opacity: 1,
306                        showConnectorLine: true,
307                        connectorLineStrokeDashArray: [6, 4],
308                    } as any),
309                });
310                return;
311            case ETradingAnnotationType.FibonacciSpeedResistanceArcsAnnotation:
312                placementModifier.startPlacement({
313                    type: ETradingAnnotationType.FibonacciSpeedResistanceArcsAnnotation,
314                    options: preparePlacementOptions({
315                        ...createTradingAnnotationOptions("FSR", 2, undefined, { includeSegmentLabels: false }),
316                        isEditable: true,
317                        strokeThickness: 2,
318                        regionColors: FIB_REGION_COLORS,
319                        fillOpacity: 0.2,
320                        opacity: 1,
321                        showConnectorLine: true,
322                        connectorLineStrokeDashArray: [6, 4],
323                    } as any),
324                });
325                return;
326            case ETradingAnnotationType.FibonacciWedgeAnnotation:
327                placementModifier.startPlacement({
328                    type: ETradingAnnotationType.FibonacciWedgeAnnotation,
329                    options: preparePlacementOptions({
330                        ...createTradingAnnotationOptions("FBW", 3, undefined, { includeSegmentLabels: false }),
331                        isEditable: true,
332                        strokeThickness: 2,
333                        regionColors: FIB_REGION_COLORS,
334                        fillOpacity: 0.2,
335                        opacity: 1,
336                        showConnectorLine: true,
337                        connectorLineStrokeDashArray: [6, 4],
338                    } as any),
339                });
340                return;
341            case ETradingAnnotationType.MeasureAnnotation:
342                placementModifier.startPlacement({
343                    type: ETradingAnnotationType.MeasureAnnotation,
344                    options: preparePlacementOptions({
345                        ...createTradingAnnotationOptions("MSR", 2, undefined, { includeSegmentLabels: false }),
346                        ...defaultSnapToCandleOptions(candlestickSeries.id),
347                        isEditable: true,
348                        strokeThickness: 2,
349                        growingColor: TRADING_ANNOTATION_COLORS.measureUp,
350                        decliningColor: TRADING_ANNOTATION_COLORS.measureDown,
351                        fillOpacity: 0.15,
352                        labelCornerRadius: 6,
353                        labelOffset: 6,
354                        labelPadding: new Thickness(4, 8, 4, 8),
355                        yValueScaleFactor: 100,
356                    }),
357                });
358                return;
359            case ETradingAnnotationType.StopLossTakeProfitAnnotation:
360                placementModifier.startPlacement({
361                    type: ETradingAnnotationType.StopLossTakeProfitAnnotation,
362                    options: preparePlacementOptions({
363                        ...createTradingAnnotationOptions("RISK", 2),
364                        isEditable: true,
365                        strokeThickness: 2,
366                        strokeDashArray: [6, 3],
367                        takeProfitColor: "#16A34A",
368                        stopLossColor: TRADING_ANNOTATION_COLORS.measureDown,
369                        fillOpacity: 0.18,
370                        axisSpanFillOpacity: 0.2,
371                        axisLabelVisibility: EAnnotationVisibilityMode.Always,
372                        axisLabelStroke: "#FFFFFF",
373                        annotationsGripsRadius: 4,
374                        annotationsGripsStroke: TRADING_ANNOTATION_COLORS.foreground,
375                    } as any),
376                });
377                return;
378            case ETradingAnnotationType.FreehandDrawingAnnotation:
379                startFreehand(options.lockedAspect);
380                return;
381        }
382    };
383
384    const addSeedAnnotations = () => {
385        sciChartSurface.annotations.clear(true);
386        sciChartSurface.annotations.add(
387            new ChannelAnnotation({
388                ...createTradingAnnotationOptions("", 4, undefined, { includeSegmentLabels: false }),
389                isEditable: true,
390                stroke: TRADING_ANNOTATION_COLORS.channel,
391                fill: `${TRADING_ANNOTATION_COLORS.channel}26`,
392                strokeThickness: 2,
393                midLineStrokeDashArray: [4, 3],
394                showMidLine: true,
395                showMidPointGrips: true,
396                points: [
397                    { x: 1705049596, y: 62895 },
398                    { x: 1705259865, y: 64864 },
399                    { x: 1705049596, y: 61731 },
400                    { x: 1705259865, y: 63699 },
401                ],
402            } as any),
403            new FibonacciRetracementAnnotation({
404                ...createTradingAnnotationOptions("Fib", 3, undefined, {
405                    includeSegmentLabels: false,
406                    extraLabels: [
407                        {
408                            id: "Fib-extended-1",
409                            anchorMode: EMultiPointLabelAnchorMode.Axis,
410                            axisLabelDrawMode: EAxisLabelDrawMode.Y,
411                            segmentStartIndex: 1,
412                            segmentEndIndex: 2,
413                            segmentRatio: 2.618,
414                        },
415                        {
416                            id: "Fib-extended-2",
417                            anchorMode: EMultiPointLabelAnchorMode.Axis,
418                            axisLabelDrawMode: EAxisLabelDrawMode.Y,
419                            segmentStartIndex: 1,
420                            segmentEndIndex: 2,
421                            segmentRatio: -0.618,
422                        },
423                    ],
424                }),
425                isEditable: true,
426                strokeThickness: 2,
427                regionColors: ["#F85161", "#FB8B62", "#D2E26F", "#70CEA5", "#7FAECE"],
428                fillOpacity: 0.25,
429                opacity: 1,
430                fibonacciLabelPlacement: EFibonacciLabelPlacement.Top,
431                fibonacciLabelColorMode: EFibonacciLabelColorMode.MultiColor,
432                showConnectorLine: true,
433                connectorLineStrokeDashArray: [16, 4],
434                // thresholds: [-0.618, -0.236, 0, 0.618, 1, 2.618],
435                verticalOnly: true,
436                formatFibonacciLabel: (params: TFibonacciLevelLabelFormatParams) => {
437                    const percentage = `${(params.threshold * 100).toFixed(1)}%`;
438                    return `${percentage}\n${params.valueLabel}`;
439                },
440                points: [
441                    {x: 1705587439, y: 63110},
442                    {x: 1705822618, y: 65283}
443                ],
444            }),
445            new ExtendedLineAnnotation({
446                ...createTradingAnnotationOptions("", 2, undefined),
447                isEditable: true,
448                strokeThickness: 2,
449                stroke: TRADING_ANNOTATION_COLORS.ray,
450                points: [
451                    {x: 1705291231, y: 62131},
452                    {x: 1705459018, y: 63495}
453                ],
454            })
455        );
456    };
457
458    const removeSelectedAnnotations = () => {
459        sciChartSurface.annotations
460            .asArray()
461            .filter((annotation: IAnnotation) => annotation.isSelected)
462            .forEach((annotation: IAnnotation) => sciChartSurface.annotations.remove(annotation, true));
463    };
464
465    const duplicateSelectedAnnotation = () => {
466        const selectedAnnotation = sciChartSurface.annotations
467            .asArray()
468            .find((annotation: IAnnotation) => annotation.isSelected);
469        if (!selectedAnnotation) return;
470
471        const json = JSON.parse(JSON.stringify(selectedAnnotation.toJSON()));
472        json.options.isSelected = true;
473        delete json.options.id;
474        if (Array.isArray(json.options.points)) {
475            json.options.points = json.options.points.map((point: { x: number; y: number }) => ({
476                x: point.x + 8 * 60 * 60,
477                y: point.y + 350,
478            }));
479        }
480        const [duplicate] = buildAnnotations(json);
481        if (duplicate) {
482            selectedAnnotation.isSelected = false;
483            sciChartSurface.annotations.add(duplicate);
484        }
485    };
486    addSeedAnnotations();
487
488    const disposeKeyboard = addKeyboardShortcuts(removeSelectedAnnotations, duplicateSelectedAnnotation);
489
490    const deleteAllAnnotations = () => {
491        sciChartSurface.annotations.clear(true);
492    };
493
494    return {
495        sciChartSurface,
496        startTool,
497        stopActiveTools,
498        resetAnnotations: addSeedAnnotations,
499        deleteAllAnnotations,
500        removeSelectedAnnotations,
501        duplicateSelectedAnnotation,
502        setKeepPlacingAfterComplete: (enabled: boolean) => {
503            (placementModifier as any).keepPlacingAfterCompleteProperty = enabled;
504            (freehandDrawingModifier as any).keepDrawingAfterCompleteProperty = enabled;
505        },
506        dispose: disposeKeyboard,
507    };
508};
509
510const addKeyboardShortcuts = (removeSelected: () => void, duplicateSelected: () => void) => {
511    const isTypingTarget = (target: EventTarget | null) => {
512        if (!(target instanceof HTMLElement)) return false;
513        return target.isContentEditable || ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName);
514    };
515
516    const onKeyDown = (event: KeyboardEvent) => {
517        if (isTypingTarget(event.target)) return;
518        if (event.key === "Backspace" || event.key === "Delete") {
519            removeSelected();
520            event.preventDefault();
521        }
522        if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "d") {
523            duplicateSelected();
524            event.preventDefault();
525        }
526    };
527
528    document.addEventListener("keydown", onKeyDown);
529    return () => document.removeEventListener("keydown", onKeyDown);
530};
531

React Trading Drawing Tools

This example demonstrates a full drawing toolbar for financial and trading charts. It uses scichart-financial-tools for Polylines, Extended Lines, Channels, Rays, Pitchforks, Pitchfans, Fibonacci Retracements, Measure Tools and Stop-loss/Take-profit regions, with MultiPointAnnotationPlacementModifier for click-to-place workflows.

react Chart Examples & Demos

See Also: Financial Charts (11 Demos)

React Candlestick Chart | Online JavaScript Chart Examples

React Candlestick Chart

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

React OHLC Chart | React Charts | SciChart.js Demo

React OHLC Chart

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

React Realtime Ticking Stock Chart | SciChart.js Demo

React Realtime Ticking Stock Charts

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.

NEW!
React Orderbook Heatmap | React Charts | SciChart.js Demo

Order Book Heatmap

Create a React heatmap chart showing historical orderbook levels, using the high performance SciChart.js chart library. Get free demo now.

React Multi-Pane Stock Chart using Subcharts | View JavaScript Charts

React Multi-Pane Stock Charts using Subcharts

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

Tenor Curves Demo | React Charts | SciChart.js Demo

Tenor Curves Demo

Demonstrating the capability of SciChart.js to create a composite 2D &amp; 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.

React Multi-Pane Stock Chart | View JavaScript Charts

React Multi-Pane Stock Charts using Sync Multi-Chart

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

React Market Depth Chart | React Charts | SciChart.js Demo

React Market Depth Chart

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

React Chart Hoverable Buy Sell Marker Annotations | SciChart

React Chart Hoverable Buy Sell Marker Annotations

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

React User Annotated Stock Chart | React Charts | SciChart.js

React User Annotated Stock Chart

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.

NEW!
React Freehand Drawing Tools | React Charts | SciChart.js

React Freehand Drawing Tools

An example of using React FreehandDrawingModifier for arbitrary drawing on trading and financial charts. Can be used for drawing trends, arrow, markers, text, etc.

SciChart Ltd, 16 Beaufort Court, Admirals Way, Docklands, London, E14 9XL.