Demonstrates interaction by dragging vertical and horizontal line thresholds on a mountain chart. As the thresholds move, the chart colour updates. The vertical mountain fill is done using a separate renderableSeries and a dataFilter which reshapes the data to draw only the portion above the threshold.
drawExample.ts
angular.ts
ExampleDataProvider.ts
theme.ts
1import {
2 BaseDataSeries,
3 ECoordinateMode,
4 EFillPaletteMode,
5 EHorizontalAnchorPoint,
6 ELabelPlacement,
7 EStrokePaletteMode,
8 EVerticalAnchorPoint,
9 FastMountainRenderableSeries,
10 GradientParams,
11 HorizontalLineAnnotation,
12 IFillPaletteProvider,
13 IRenderableSeries,
14 IStrokePaletteProvider,
15 MouseWheelZoomModifier,
16 NumberRange,
17 NumericAxis,
18 parseColorToUIntArgb,
19 Point,
20 SciChartSurface,
21 TextAnnotation,
22 VerticalLineAnnotation,
23 XyDataSeries,
24 XyFilterBase,
25 XyyFilterBase,
26 ZoomExtentsModifier,
27 ZoomPanModifier,
28} from "scichart";
29import { ExampleDataProvider } from "../../../ExampleData/ExampleDataProvider";
30import { appTheme } from "../../../theme";
31
32// tslint:disable:no-empty
33// tslint:disable:max-line-length
34
35class ThresholdFilter extends XyFilterBase {
36 private thresholdProperty = 1;
37
38 constructor(originalSeries: BaseDataSeries, threshold: number, dataSeriesName: string) {
39 super(originalSeries, { dataSeriesName });
40 this.thresholdProperty = threshold;
41 this.filterAll();
42 }
43
44 public get threshold() {
45 return this.thresholdProperty;
46 }
47
48 public set threshold(value: number) {
49 this.thresholdProperty = value;
50 this.filterAll();
51 }
52
53 protected filterAll() {
54 this.clear();
55 this.filter(0, this.getOriginalCount());
56 }
57
58 protected filterOnAppend(count: number): void {
59 // Overriding this so we do not have to reprocess the entire series on append
60 this.filter(this.getOriginalCount() - count, count);
61 }
62
63 protected filter(start: number, count: number): void {
64 const xValues: number[] = [];
65 const yValues: number[] = [];
66 for (let i = start; i < start + count; i++) {
67 xValues.push(this.getOriginalXValues().get(i));
68 const y = this.getOriginalYValues().get(i);
69 if (this.threshold > 0 && y < this.threshold) {
70 yValues.push(NaN);
71 } else if (y < 0) {
72 yValues.push(Math.max(y, this.threshold));
73 } else {
74 yValues.push(y);
75 }
76 }
77 this.appendRange(xValues, yValues);
78 }
79
80 protected onClear() {
81 this.clear();
82 }
83}
84
85export const drawExample = async (rootElement: string | HTMLDivElement) => {
86 const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
87 theme: appTheme.SciChartJsTheme,
88 });
89
90 // Add an XAxis, YAxis
91 sciChartSurface.xAxes.add(new NumericAxis(wasmContext));
92 sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { growBy: new NumberRange(0.1, 0.1) }));
93
94 // Create a paletteprovider to colour the series depending on a threshold value
95 const thresholdPalette = new XThresholdPaletteProvider(8, appTheme.VividTeal);
96
97 // Add a Column series with some values to the chart
98 const { xValues, yValues } = ExampleDataProvider.getDampedSinewave(0, 10, 0, 0.001, 3000, 10);
99 const dataSeries = new XyDataSeries(wasmContext, {
100 xValues,
101 yValues,
102 });
103 sciChartSurface.renderableSeries.add(
104 new FastMountainRenderableSeries(wasmContext, {
105 stroke: appTheme.PaleSkyBlue,
106 strokeThickness: 5,
107 zeroLineY: 0.0,
108 dataSeries,
109 fillLinearGradient: new GradientParams(new Point(0, 0), new Point(0, 1), [
110 { color: appTheme.VividSkyBlue, offset: 0 },
111 { color: appTheme.VividSkyBlue + "77", offset: 1 },
112 ]),
113 paletteProvider: thresholdPalette,
114 })
115 );
116
117 const thresholdFilter = new ThresholdFilter(dataSeries, 4.0, "TopFill");
118 const topFill = new FastMountainRenderableSeries(wasmContext, {
119 stroke: appTheme.PaleSkyBlue,
120 strokeThickness: 5,
121 zeroLineY: 4.0,
122 dataSeries: thresholdFilter,
123 fill: appTheme.MutedOrange,
124 paletteProvider: thresholdPalette,
125 });
126 sciChartSurface.renderableSeries.add(topFill);
127
128 // Add a label to tell user what to do
129 const textAnnotation = new TextAnnotation({
130 verticalAnchorPoint: EVerticalAnchorPoint.Bottom,
131 xCoordinateMode: ECoordinateMode.Relative,
132 x1: 0.5,
133 y1: 4.2,
134 fontSize: 22,
135 text: "Drag the lines!",
136 textColor: "White",
137 });
138 // Add a horizontal threshold at Y=5
139 const horizontalLine = new HorizontalLineAnnotation({
140 y1: 4.0,
141 isEditable: true,
142 showLabel: true,
143 stroke: appTheme.VividOrange,
144 strokeThickness: 3,
145 axisLabelFill: appTheme.VividOrange,
146 axisLabelStroke: appTheme.ForegroundColor,
147 labelPlacement: ELabelPlacement.Axis,
148 onDrag: (args) => {
149 // When the horizontal line is dragged, update the
150 // threshold palette and redraw the SciChartSurface
151 topFill.zeroLineY = Math.max(0, horizontalLine.y1);
152 thresholdFilter.threshold = horizontalLine.y1;
153 textAnnotation.y1 = horizontalLine.y1 + 0.2;
154 sciChartSurface.invalidateElement();
155 },
156 });
157 sciChartSurface.annotations.add(horizontalLine);
158 sciChartSurface.annotations.add(textAnnotation);
159
160 // Add a vertical line
161 const verticalLine = new VerticalLineAnnotation({
162 x1: 8,
163 strokeThickness: 3,
164 isEditable: true,
165 showLabel: true,
166 stroke: appTheme.VividTeal,
167 axisLabelFill: appTheme.VividTeal,
168 axisLabelStroke: appTheme.ForegroundColor,
169 labelPlacement: ELabelPlacement.Axis,
170 onDrag: (args) => {
171 // When the vertical line is dragged, update the
172 // threshold palette and redraw the SciChartSurface
173 thresholdPalette.xThresholdValue = verticalLine.x1;
174 sciChartSurface.invalidateElement();
175 },
176 });
177 sciChartSurface.annotations.add(verticalLine);
178
179 // Add instructions
180 sciChartSurface.annotations.add(
181 new TextAnnotation({
182 x1: 0,
183 y1: 0,
184 xAxisId: "history",
185 xCoordinateMode: ECoordinateMode.Relative,
186 yCoordinateMode: ECoordinateMode.Relative,
187 horizontalAnchorPoint: EHorizontalAnchorPoint.Left,
188 verticalAnchorPoint: EVerticalAnchorPoint.Top,
189 text: "SciChart.js supports editable, draggable annotations and dynamic color/fill rules. Drag a threshold line!",
190 textColor: appTheme.ForegroundColor + "77",
191 })
192 );
193
194 // Optional: Add some interactivity modifiers
195 sciChartSurface.chartModifiers.add(new ZoomPanModifier({ enableZoom: true }));
196 sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());
197 sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
198
199 return { sciChartSurface, wasmContext };
200};
201
202/**
203 * A paletteprovider which colours a series if X value over a threshold, else use default colour
204 */
205export class XThresholdPaletteProvider implements IFillPaletteProvider {
206 public readonly fillPaletteMode: EFillPaletteMode = EFillPaletteMode.GRADIENT;
207 public readonly strokePaletteMode: EStrokePaletteMode = EStrokePaletteMode.GRADIENT;
208 public xThresholdValue: number;
209 private readonly xColor: number;
210
211 constructor(xThresholdValue: number, xColor: string) {
212 this.xThresholdValue = xThresholdValue;
213 this.xColor = parseColorToUIntArgb(xColor);
214 }
215
216 onAttached(parentSeries: IRenderableSeries): void {}
217
218 onDetached(): void {}
219
220 overrideFillArgb(xValue: number, yValue: number, index: number, opacity?: number): number {
221 // When the x-value of the series is greater than the x threshold
222 // fill with the xColor
223 if (xValue > this.xThresholdValue) {
224 return this.xColor;
225 }
226 // Undefined means use default color
227 return undefined;
228 }
229}
230
Demonstrates how to place Annotations (lines, arrows, markers, text) over a Angular Chart using SciChart.js Annotations API
Demonstrates per-point coloring in JavaScript chart types with SciChart.js PaletteProvider API
Demonstrates how to place Buy/Sell arrow markers on a Angular Stock Chart using SciChart.js - Annotations API
Demonstrates how to edit Annotations (shapes, boxes, lines, text, horizontal and vertical line) over a Angular Chart using SciChart.js Annotations API
Demonstrates how to color areas of the chart surface using background Annotations using SciChart.js Annotations API
Demonstrates how layering works a Angular Chart using SciChart.js Annotations API