Our team demonstrates how to create a React 3D Point Line Chart using SciChart.js, capable of creating detailed 3D JavaScript Charts.
drawExample.ts
index.tsx
ChartGroupLoader.tsx
Radix2FFT.ts
theme.ts
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
Create detailed React 3D Bubble Chart using SciChart's 5-star rated JavaScript chart library. Supports large datasets. Get your free demo now.
Design a React 3D Surface Mesh Chart with SciChart.js - feature-rich JavaScript chart library. Represent 2D data in a 3D map. Get your free demo.
Demonstrating the capability of SciChart.js to create JavaScript 3D Point Cloud charts and visualize LiDAR data from the UK Defra Survey.
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.
Design a React 3D Surface Mesh Chart with SciChart.js - feature-rich JavaScript chart library. Represent 2D data in a 3D map. Get your free demo.
Create detailed React 3D Column Chart using SciChart's 5-star rated JavaScript chart library. Supports large datasets