Creates a JavaScript Vector Field using our FastLineSegmentRenderableSeries paired with a custom PaletteProvider and optional arrow heads made with FastTriangleRenderableSeries
drawExample.ts
index.html
vanilla.ts
theme.ts
1import {
2 NumberRange,
3 SciChartSurface,
4 NumericAxis,
5 CentralAxesLayoutManager,
6 FastLineSegmentRenderableSeries,
7 IStrokePaletteProvider,
8 EStrokePaletteMode,
9 parseColorToUIntArgb,
10 IRenderableSeries,
11 TPaletteProviderDefinition,
12 EPaletteProviderType,
13 XyDataSeries,
14 ZoomPanModifier,
15 ZoomExtentsModifier,
16 MouseWheelZoomModifier,
17 FastTriangleRenderableSeries,
18 ETriangleSeriesDrawMode,
19 CursorModifier,
20 TCursorTooltipDataTemplate,
21 SeriesInfo,
22 XySeriesInfo,
23} from "scichart";
24
25import { appTheme } from "../../../theme";
26
27const lineStartColor = appTheme.VividBlue; //"red";
28const lineEndColor = appTheme.VividOrange; //"blue";
29
30class LineSegmentPaletteProvider implements IStrokePaletteProvider {
31 public readonly strokePaletteMode = EStrokePaletteMode.GRADIENT;
32 private readonly palettedStart = parseColorToUIntArgb(lineStartColor);
33 private readonly palettedEnd = parseColorToUIntArgb(lineEndColor);
34
35 public onAttached(parentSeries: IRenderableSeries): void {}
36
37 public onDetached(): void {}
38
39 public overrideStrokeArgb(xValue: number, yValue: number, index: number): number {
40 return index % 2 === 0 ? this.palettedStart : this.palettedEnd;
41 }
42
43 public toJSON(): TPaletteProviderDefinition {
44 return { type: EPaletteProviderType.Custom, customType: "MyPaletteProvider" };
45 }
46}
47
48// Tooltip Data Template
49const tooltipDataTemplate: TCursorTooltipDataTemplate = (seriesInfos: SeriesInfo[]) => {
50 const valuesWithLabels: string[] = [];
51 seriesInfos.forEach((si) => {
52 const xySI = si as XySeriesInfo;
53 if (xySI.isWithinDataBounds) {
54 if (!isNaN(xySI.yValue) && xySI.isHit) {
55 valuesWithLabels.push(
56 `start (${xySI.xValue},${xySI.yValue}) end (${xySI.point2xValue},${xySI.point2yValue})`
57 );
58 }
59 }
60 });
61 return valuesWithLabels;
62};
63
64function addArrowheads(xValues: number[], yValues: number[], arrowLength = 0.2, arrowAngle = Math.PI / 12) {
65 function distance(x1: number, y1: number, x2: number, y2: number) {
66 return Math.hypot(x2 - x1, y2 - y1);
67 }
68
69 const arrows = [];
70 for (let i = 0; i < xValues.length; i += 2) {
71 // Line start and end
72 const x1 = xValues[i];
73 const y1 = yValues[i];
74 const x2 = xValues[i + 1];
75 const y2 = yValues[i + 1];
76
77 // Direction of the line
78 const dx = x2 - x1;
79 const dy = y2 - y1;
80 const lineAngle = Math.atan2(dy, dx);
81
82 // Arrowhead points
83 const angle1 = lineAngle + Math.PI - arrowAngle;
84 const angle2 = lineAngle + Math.PI + arrowAngle;
85
86 const arrowPoint1 = [x2 + arrowLength * Math.cos(angle1), y2 + arrowLength * Math.sin(angle1)];
87 const arrowPoint2 = [x2 + arrowLength * Math.cos(angle2), y2 + arrowLength * Math.sin(angle2)];
88
89 // Arrowhead: [tip, base1, base2]
90 arrows.push([
91 [x2, y2], // Tip of the arrow
92 arrowPoint1, // First base point
93 arrowPoint2, // Second base point
94 ]);
95 }
96 return arrows;
97}
98
99export const drawExample = async (rootElement: string | HTMLDivElement) => {
100 // Create a SciChartSurface
101 const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
102 theme: appTheme.SciChartJsTheme,
103 });
104
105 // configure central axes
106 const layoutManager = new CentralAxesLayoutManager();
107
108 sciChartSurface.layoutManager = layoutManager;
109
110 const xMin = -15;
111 const xMax = 15;
112 const yMin = -10;
113 const yMax = 10;
114
115 const growBy = new NumberRange(0.1, 0.1);
116
117 const xAxis = new NumericAxis(wasmContext, {
118 axisBorder: { color: "white", borderBottom: 1 },
119 drawMajorBands: false,
120 drawMajorGridLines: false,
121 drawMinorGridLines: false,
122 growBy,
123 });
124 sciChartSurface.xAxes.add(xAxis);
125
126 const yAxis = new NumericAxis(wasmContext, {
127 axisBorder: { color: "white", borderRight: 1 },
128 drawMajorBands: false,
129 drawMajorGridLines: false,
130 drawMinorGridLines: false,
131 growBy,
132 });
133 sciChartSurface.yAxes.add(yAxis);
134
135 const multiplier = 0.01;
136
137 const linesXValues: number[] = [];
138 const linesYValues: number[] = [];
139
140 for (let x = xMin; x <= xMax; x++) {
141 for (let y = yMin; y <= yMax; y++) {
142 // start point
143 // dataSeries.append(x, y);
144 linesXValues.push(x);
145 linesYValues.push(y);
146 // end point
147 const xEnd = x + (x * x - y * y - 4) * multiplier;
148 const yEnd = y + 2 * x * y * multiplier;
149
150 linesXValues.push(xEnd);
151 linesYValues.push(yEnd);
152 }
153 }
154
155 const lineSegmentSeries = new FastLineSegmentRenderableSeries(wasmContext, {
156 dataSeries: new XyDataSeries(wasmContext, {
157 xValues: linesXValues,
158 yValues: linesYValues,
159 }),
160 strokeThickness: 2,
161 paletteProvider: new LineSegmentPaletteProvider(),
162 });
163
164 const arrowheads = addArrowheads(linesXValues, linesYValues);
165
166 //console.log(arrowheads.flat());
167
168 const arrowheadsXvalues = arrowheads.flat().map((d) => d[0]);
169 const arrowheadsYvalues = arrowheads.flat().map((d) => d[1]);
170
171 const polygonSeries = new FastTriangleRenderableSeries(wasmContext, {
172 dataSeries: new XyDataSeries(wasmContext, {
173 xValues: arrowheadsXvalues,
174 yValues: arrowheadsYvalues,
175 }),
176 isDigitalLine: false,
177 opacity: 1,
178 fill: lineEndColor,
179 drawMode: ETriangleSeriesDrawMode.List, // Polygon / List / Strip
180 });
181
182 sciChartSurface.renderableSeries.add(lineSegmentSeries);
183
184 sciChartSurface.renderableSeries.add(polygonSeries);
185
186 sciChartSurface.chartModifiers.add(new ZoomPanModifier());
187 sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());
188 sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
189 sciChartSurface.chartModifiers.add(new CursorModifier({ showTooltip: true, tooltipDataTemplate }));
190
191 return { sciChartSurface, wasmContext };
192};
193This example demonstrates a Vector Field Chart implementation using SciChart.js in vanilla JavaScript. It visualizes mathematical vector fields with directional arrows, combining FastLineSegmentRenderableSeries for vector lines and FastTriangleRenderableSeries for arrowheads.
The chart uses a CentralAxesLayoutManager to center axes and calculates vector endpoints using polynomial transformations. A custom LineSegmentPaletteProvider applies gradient colors to line segments, while the addArrowheads utility generates directional markers.
Key features include dynamic vector field generation, color-coded line segments, and interactive modifiers like ZoomPanModifier and CursorModifier with custom tooltips. The implementation showcases WebGL-accelerated rendering of hundreds of vectors.
The example follows best practices for WASM initialization and resource cleanup. Developers can extend this pattern for scientific visualization by modifying the vector calculation logic in the drawExample function.

Create a JavaScript Histogram Chart with custom texture fills and patterns. Try the SciChart.js library for seamless integration today.

Build a JavaScript Gantt Chart with SciChart. View the demo for horizontal bars, rounded corners and data labels to show project timelines and task completion.

Create a JavaScript Choropleth map, a type of thematic map where areas are shaded or patterned in proportion to the value of a variable being represented.

Create a JavaScript Multi-Layer Map Example, using FastTriangleRenderableSeries with GeoJSON data-points using a constrained delaunay triangulation algorithm.

Bring annual comparison data to life with the JavaScript Animated Bar Chart example from SciChart. This demo showcases top 10 tennis players from 1990 to 2024.

Build a JavaScript Waterfall Chart with dynamic coloring, multi-line data labels and responsive design. Try SciChart.js for seamless integration today.

Try the JavaScript Box-Plot Chart examples with developer-friendly chart lifecycle management, dynamic sub-surface positioning, and custom styling.

Create JavaScript Triangle Meshes with the Triangle Series from SciChart. This demo supports strip mode, list mode and the drawing of polygons. View the example.

Create a JavaScript Treemap Chart to define rectangle positions based on total value. Use SciChart FastRectangleRenderableSeries and d3-hierarchy.js layouts.

Design a highly dynamic JavaScript Map Chart with Heatmap overlay with SciChart's feature-rich JavaScript Chart Library. Get your free demo today.

Demonstrating the capability of SciChart.js to create a JavaScript Audio Analyzer Bars and visualize the Fourier-Transform of an audio waveform in realtime.

View the JavaScript Linear Gauge Chart example to combine rectangles & annotations. Create a linear gauge dashboard with animated indicators and custom scales.

The JavaScript Order of Rendering example gives you full control of the draw order of series and annotations for charts. Try SciChart's advanced customizations.

Build Responsive JavaScript HTML Annotations with SciChart. Use the advanced CSS container queries for responsive text layout and custom design. View demo now.

JavaScript HTML Chart Control example demonstrates advanced HTML annotation integration and how to render HTML components within charts. Try the SciChart demo.

Explore SciChart's Polar Interactivity Modifiers including zooming, panning, and cursor tracking. Try the demo to trial the Polar Chart Behavior Modifiers.