JavaScript Point Line 3D Chart

Our team demonstrates how to create a JavaScript 3D Point Line Chart using SciChart.js, capable of creating detailed 3D JavaScript Charts.

Fullscreen

Edit

 Edit

Docs

drawExample.ts

index.html

vanilla.ts

Radix2FFT.ts

theme.ts

Copy to clipboard
Minimise
Fullscreen
1import { Radix2FFT } from "../../../FeaturedApps/ScientificCharts/AudioAnalyzer/Radix2FFT";
2import {
3    CameraController,
4    HeatmapLegend,
5    MouseWheelZoomModifier3D,
6    NumericAxis3D,
7    OrbitModifier3D,
8    parseColorToUIntArgb,
9    PointLineRenderableSeries3D,
10    ResetCamera3DModifier,
11    SciChart3DSurface,
12    TGradientStop,
13    Vector3,
14    XyzDataSeries3D,
15} from "scichart";
16import { appTheme } from "../../../theme";
17
18type TMetadata = {
19    vertexColor: number;
20    pointScale: number;
21};
22
23// This function generates some spectral data for the waterfall chart
24const createSpectralData = (n: number) => {
25    const spectraSize = 1024;
26    const timeData = new Array(spectraSize);
27
28    // Generate some random data with spectral components
29    for (let i = 0; i < spectraSize; i++) {
30        timeData[i] =
31            4.0 * Math.sin((2 * Math.PI * i) / (20 + n * 0.2)) +
32            10 * Math.sin((2 * Math.PI * i) / (10 + n * 0.01)) +
33            20 * Math.sin((2 * Math.PI * i) / (5 + n * -0.002)) +
34            3.0 * Math.random();
35    }
36
37    // Do a fourier-transform on the data to get the frequency domain
38    const transform = new Radix2FFT(spectraSize);
39    const yValues = transform.run(timeData);
40    // .slice(0, 300); // We only want the first N points just to make the example cleaner
41
42    // This is just setting a floor to make the data cleaner for the example
43    for (let i = 0; i < yValues.length; i++) {
44        yValues[i] =
45            yValues[i] < -30 || yValues[i] > -5 ? (yValues[i] < -30 ? -30 : Math.random() * 9 - 6) : yValues[i];
46    }
47    yValues[0] = -30;
48
49    // we need x-values (sequential numbers) for the frequency data
50    const xValues = yValues.map((value, index) => index);
51
52    return { xValues, yValues };
53};
54
55// SCICHART CODE
56export const drawExample = async (rootElement: string | HTMLDivElement) => {
57    const { sciChart3DSurface, wasmContext } = await SciChart3DSurface.create(rootElement, {
58        theme: appTheme.SciChartJsTheme,
59    });
60    sciChart3DSurface.worldDimensions = new Vector3(300, 100, 300);
61    sciChart3DSurface.camera = new CameraController(wasmContext, {
62        position: new Vector3(-141.6, 310.29, 393.32),
63        target: new Vector3(0, 50, 0),
64    });
65
66    sciChart3DSurface.chartModifiers.add(new MouseWheelZoomModifier3D());
67    sciChart3DSurface.chartModifiers.add(new OrbitModifier3D());
68    sciChart3DSurface.chartModifiers.add(new ResetCamera3DModifier());
69
70    sciChart3DSurface.xAxis = new NumericAxis3D(wasmContext, {
71        axisTitle: "Frequency (Hz)",
72        drawMinorGridLines: false,
73        drawMajorGridLines: false,
74        tickLabelsOffset: 20,
75    });
76    sciChart3DSurface.yAxis = new NumericAxis3D(wasmContext, {
77        axisTitle: "Power (dB)",
78        drawMinorGridLines: false,
79        drawMajorGridLines: false,
80        tickLabelsOffset: 20,
81    });
82    sciChart3DSurface.zAxis = new NumericAxis3D(wasmContext, {
83        axisTitle: "Time (s)",
84        drawMinorGridLines: false,
85        drawMajorGridLines: false,
86        tickLabelsOffset: 20,
87    });
88
89    for (let i = 0; i < 50; i++) {
90        // Create some data for the example
91        // xValues are frequency values (Hz)
92        // yValues are heights or magnitude
93        const { xValues, yValues } = createSpectralData(i);
94        // zValues are the 3rd dimension where we will spread out our series in time
95        const zValues = Array.from({ length: xValues.length }).map((_) => i * 2);
96
97        // Metadata in scichart.js 3D controls color 3D line series. It can also hold additional optional properties
98        // Below we format the data for yValues into metadata colour coded and scaled depending on the value
99        const metadata = formatMetadata(yValues, [
100            { offset: 1, color: appTheme.VividPink },
101            { offset: 0.9, color: appTheme.VividOrange },
102            { offset: 0.7, color: appTheme.MutedRed },
103            { offset: 0.5, color: appTheme.VividGreen },
104            { offset: 0.3, color: appTheme.VividSkyBlue },
105            { offset: 0.2, color: appTheme.Indigo },
106            { offset: 0, color: appTheme.DarkIndigo },
107        ]);
108
109        // Add a 3D Point-Line chart
110        sciChart3DSurface.renderableSeries.add(
111            new PointLineRenderableSeries3D(wasmContext, {
112                dataSeries: new XyzDataSeries3D(wasmContext, {
113                    xValues,
114                    yValues,
115                    zValues,
116                    metadata,
117                }),
118                strokeThickness: 3,
119                opacity: 0.5,
120            })
121        );
122    }
123
124    return { sciChartSurface: sciChart3DSurface, wasmContext };
125};
126
127function formatMetadata(valuesArray: number[], gradientStops: TGradientStop[]): TMetadata[] {
128    const low = Math.min(...valuesArray);
129    const high = Math.max(...valuesArray);
130
131    const sGradientStops = gradientStops.sort((a, b) => (a.offset > b.offset ? 1 : -1));
132    // Compute a scaling factor from 0...1 where values in valuesArray at the lower end correspond to 0 and
133    // values at the higher end correspond to 1
134    return valuesArray.map((x) => {
135        // scale from 0..1 for the values
136        const valueScale = (x - low) / (high - low);
137        // Find the nearest gradient stop index
138        const index = sGradientStops.findIndex((gs) => gs.offset >= valueScale);
139        // const nextIndex = Math.min(index + 1, sGradientStops.length - 1);
140        // work out the colour of this point
141        const color1 = parseColorToUIntArgb(sGradientStops[index].color);
142        // const color2 = parseColorToUIntArgb(sGradientStops[nextIndex].color);
143        // const ratio = (valueScale - sGradientStops[index].offset) / (sGradientStops[nextIndex].offset - sGradientStops[index].offset)
144        // const colorScale = uintArgbColorLerp(color1, color2, ratio)
145        // console.log(`valueScale ${valueScale} low ${sGradientStops[index].offset} high ${sGradientStops[nextIndex].offset} ratio ${ratio}`);
146        return { pointScale: 0.1 + valueScale, vertexColor: color1 };
147    });
148}
149
150export const drawHeatmapLegend = async (rootElement: string | HTMLDivElement) => {
151    const { heatmapLegend, wasmContext } = await HeatmapLegend.create(rootElement, {
152        theme: {
153            ...appTheme.SciChartJsTheme,
154            sciChartBackground: appTheme.DarkIndigo + "BB",
155            loadingAnimationBackground: appTheme.DarkIndigo + "BB",
156        },
157        yAxisOptions: {
158            isInnerAxis: true,
159            labelStyle: {
160                fontSize: 12,
161                color: appTheme.ForegroundColor,
162            },
163            axisBorder: {
164                borderRight: 1,
165                color: appTheme.ForegroundColor + "77",
166            },
167            majorTickLineStyle: {
168                color: appTheme.ForegroundColor,
169                tickSize: 6,
170                strokeThickness: 1,
171            },
172            minorTickLineStyle: {
173                color: appTheme.ForegroundColor,
174                tickSize: 3,
175                strokeThickness: 1,
176            },
177        },
178        colorMap: {
179            minimum: -30,
180            maximum: 0,
181            gradientStops: [
182                { offset: 1, color: appTheme.VividPink },
183                { offset: 0.9, color: appTheme.VividOrange },
184                { offset: 0.7, color: appTheme.MutedRed },
185                { offset: 0.5, color: appTheme.VividGreen },
186                { offset: 0.3, color: appTheme.VividSkyBlue },
187                { offset: 0.15, color: appTheme.Indigo },
188                { offset: 0, color: appTheme.DarkIndigo },
189            ],
190        },
191    });
192
193    heatmapLegend.innerSciChartSurface.sciChartSurface.title = "Power (dB)";
194    heatmapLegend.innerSciChartSurface.sciChartSurface.padding.top = 0;
195    heatmapLegend.innerSciChartSurface.sciChartSurface.titleStyle = { fontSize: 12, color: appTheme.ForegroundColor };
196
197    return { sciChartSurface: heatmapLegend.innerSciChartSurface.sciChartSurface };
198};
199

Point Line 3D Chart with JavaScript

Overview

This example demonstrates a sophisticated 3D point-line chart built with SciChart.js using JavaScript. It visualizes spectral data generated via a Fourier Transform (using the Radix2FFT algorithm) and displays the frequency domain in a dynamic 3D scene. The example illustrates how to integrate complex data processing and 3D rendering without relying on frameworks such as Angular or React.

Technical Implementation

The core of the implementation is the creation of a SciChart 3D surface using the Creating your first SciChartSurface3D guide. The example sets up a custom 3D world with defined dimensions and configures the camera using the CameraController. Interaction is enhanced by modifiers such as the MouseWheelZoomModifier3D, OrbitModifier3D (see OrbitModifier3D for details), and ResetCamera3DModifier which enable intuitive zooming, panning, and orbiting around the data. Additionally, three 3D NumericAxes are configured using the NumericAxis3D API. Data points are enriched with custom metadata that maps spectral intensities to color gradients. This metadata formatting leverages a gradient-stop approach and a utility function to convert CSS color strings into UInt ARGB values, ensuring accurate per-point styling. The renderable series is then created using the Point Line 3D Chart Type for a smooth visual output.

Features and Capabilities

Key features include the generation of dynamic spectral data, efficient FFT-based signal processing, and advanced 3D rendering. The example further demonstrates how to customize chart appearance through adjustable stroke thickness, opacity, and per-point metadata coloring. A separate heatmap legend, created via the HeatmapLegend API, provides a visual mapping of data values to color scales, enhancing interpretability.

Integration and Best Practices

This implementation serves as a template for integrating high-performance 3D charts into applications using only JavaScript. Best practices demonstrated here include organizing the code into clear asynchronous initialization steps, optimizing performance by limiting the number of rendered points, and applying efficient color parsing routines. Developers can use these techniques along with detailed SciChart.js documentation to customize and extend the chart’s functionality as needed.

javascript Chart Examples & Demos

See Also: JavaScript 3D Chart Types (8 Demos)

JavaScript 3D Bubble Chart | 3D JavaScript Charts | View Now

JavaScript 3D Bubble Chart

Create detailed JavaScript 3D Bubble Chart using SciChart's 5-star rated JavaScript chart library. Supports large datasets. Get your free demo now.

JavaScript 3D Surface Mesh Chart | View 3D JavaScript Charts

JavaScript Surface Mesh 3D Chart

Design a JavaScript 3D Surface Mesh Chart with SciChart.js - feature-rich JavaScript chart library. Represent 2D data in a 3D map. Get your free demo.

LiDAR 3D Point Cloud of Geospatial Data | SciChart.js

LiDAR 3D Point Cloud of Geospatial Data

Demonstrating the capability of SciChart.js to create JavaScript 3D Point Cloud charts and visualize LiDAR data from the UK Defra Survey.

Tenor Curves Demo | Javascript 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.

JavaScript Realtime 3D Surface Mesh Chart | View 3D JavaScript Charts

JavaScript Realtime Surface Mesh 3D Chart

Design a JavaScript 3D Surface Mesh Chart with SciChart.js - feature-rich JavaScript chart library. Represent 2D data in a 3D map. Get your free demo.

JavaScript 3D Column Chart | View 3D JavaScript Charts

JavaScript Column 3D Chart

Create detailed JavaScript 3D Column Chart using SciChart's 5-star rated JavaScript chart library. Supports large datasets

JavaScript 3D Styling Demo Chart | Advanced 3D Chart Styling

JavaScript 3D Styling Demo Chart

Create advanced JavaScript 3D Styling Demo using SciChart's 5-star rated JavaScript chart library. Explore axis styling, plane visibility and multiple point markers.

NEW!
JavaScript 3D Log-Log Scatter Chart | 3D JavaScript Charts | View Now

JavaScript 3D Log-Log Scatter Chart

Create a JavaScript 3D Log-Log Scatter Chart using SciChart's high-performance WebGL chart library. Features LogarithmicAxis3D on X and Y axes. Get your free demo now.

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