This demonstrates the JavaScript 3D Styling capabilities of SciChart.js v5, including axis label positioning, and control over 3d plane visibility
Select Plane
Visability Mode
Draw Titles Mode
Draw Lables Mode
Is Visible
drawExample.ts
index.html
vanilla.ts
theme.ts
1import {
2 CubePointMarker3D,
3 CylinderPointMarker3D,
4 EAxisPlaneDrawLabelsMode,
5 EAxisPlaneVisibilityMode,
6 EllipsePointMarker3D,
7 EThemeProviderType,
8 MouseWheelZoomModifier3D,
9 NumberRange,
10 NumericAxis3D,
11 OrbitModifier3D,
12 PixelPointMarker3D,
13 PyramidPointMarker3D,
14 QuadPointMarker,
15 ResetCamera3DModifier,
16 ScatterRenderableSeries3D,
17 SciChart3DSurface,
18 SciChartJSDarkTheme,
19 SciChartJSDarkv2Theme,
20 SciChartJSLightTheme,
21 SciChartJsNavyTheme,
22 SpherePointMarker3D,
23 TrianglePointMarker3D,
24 Vector3,
25 XyzDataSeries3D,
26} from "scichart";
27
28import { appTheme } from "../../../theme";
29import { E3DLabelOrientationMode } from "scichart/types/TextStyle3D";
30
31export type TAxis = "x" | "y" | "z";
32export type TSelectedAxisPlane = "xy" | "zy" | "zx" | "none";
33
34export const drawExample = async (rootElement: string | HTMLDivElement) => {
35 const { sciChart3DSurface, wasmContext } = await SciChart3DSurface.create(rootElement, {
36 theme: appTheme.SciChartJsTheme,
37 worldDimensions: new Vector3(300, 200, 300),
38 });
39 sciChart3DSurface.camera.position = new Vector3(-190.48, 272.08, -429.63);
40 sciChart3DSurface.camera.target = new Vector3(0, 60, 0);
41
42 sciChart3DSurface.chartModifiers.add(
43 new MouseWheelZoomModifier3D(),
44 new OrbitModifier3D(),
45 new ResetCamera3DModifier()
46 );
47
48 sciChart3DSurface.xAxis = new NumericAxis3D(wasmContext, {
49 axisTitle: "X Axis",
50 visibleRange: new NumberRange(25, 110),
51 labelPrecision: 0,
52 drawMajorGridLines: false,
53 drawMinorGridLines: false,
54 axisBandsFill: appTheme.DarkIndigo + "44",
55 tickLabelsOffset: 10,
56 majorGridLineStyle: { color: "#5588AA" },
57 minorGridLineStyle: { color: "#225588" },
58 labelOrientationMode: E3DLabelOrientationMode.Auto,
59 });
60 sciChart3DSurface.yAxis = new NumericAxis3D(wasmContext, {
61 axisTitle: "Y Axis",
62 visibleRange: new NumberRange(0, 50000),
63 labelPrecision: 0,
64 drawMajorGridLines: false,
65 drawMinorGridLines: false,
66 axisBandsFill: appTheme.DarkIndigo + "44",
67 tickLabelsOffset: 10,
68 majorGridLineStyle: { color: "#5588AA" },
69 minorGridLineStyle: { color: "#225588" },
70 });
71 sciChart3DSurface.zAxis = new NumericAxis3D(wasmContext, {
72 axisTitle: "Z Axis",
73 visibleRange: new NumberRange(1965, 2010),
74 labelPrecision: 0,
75 drawMajorGridLines: false,
76 drawMinorGridLines: false,
77 axisBandsFill: appTheme.DarkIndigo + "44",
78 tickLabelsOffset: 10,
79 majorGridLineStyle: { color: "#5588AA" },
80 minorGridLineStyle: { color: "#225588" },
81 });
82
83 // Utils to get/set axis settings
84 const getPlane = (plane: TSelectedAxisPlane) => {
85 switch (plane) {
86 case "xy":
87 return sciChart3DSurface.xyAxisPlane;
88 case "zy":
89 return sciChart3DSurface.zyAxisPlane;
90 case "zx":
91 return sciChart3DSurface.zxAxisPlane;
92 default:
93 return null;
94 }
95 };
96
97 const setPlaneBackground = (plane: TSelectedAxisPlane) => {
98 sciChart3DSurface.xAxis.axisPlaneBackgroundFill = "transparent";
99 sciChart3DSurface.yAxis.axisPlaneBackgroundFill = "transparent";
100 sciChart3DSurface.zAxis.axisPlaneBackgroundFill = "transparent";
101 const unselectedPlaneColor = "#44444466";
102 if (plane === "xy") {
103 sciChart3DSurface.zAxis.axisPlaneBackgroundFill = unselectedPlaneColor;
104 } else if (plane === "zy") {
105 sciChart3DSurface.xAxis.axisPlaneBackgroundFill = unselectedPlaneColor;
106 } else if (plane === "zx") {
107 sciChart3DSurface.yAxis.axisPlaneBackgroundFill = unselectedPlaneColor;
108 }
109 };
110 setPlaneBackground("none"); // init - does nothing with "none" but it's kept for clarity
111
112 const setIsPlaneVisible = (plane: TSelectedAxisPlane, mode: string) => {
113 getPlane(plane).isVisible = mode === "true";
114 };
115
116 const setDrawLabelsMode = (plane: TSelectedAxisPlane, mode: EAxisPlaneDrawLabelsMode) => {
117 getPlane(plane).drawLabelsMode = mode;
118 };
119
120 const setDrawTitlesMode = (plane: TSelectedAxisPlane, mode: EAxisPlaneDrawLabelsMode) => {
121 getPlane(plane).drawTitlesMode = mode;
122 };
123
124 const setVisibilityMode = (plane: TSelectedAxisPlane, mode: string) => {
125 if (mode === "auto") {
126 getPlane(plane).visibilityMode = EAxisPlaneVisibilityMode.Auto;
127 }
128 if (mode === "negativeSide") {
129 getPlane(plane).visibilityMode = EAxisPlaneVisibilityMode.NegativeSide;
130 }
131 if (mode === "positiveSide") {
132 getPlane(plane).visibilityMode = EAxisPlaneVisibilityMode.PositiveSide;
133 }
134 };
135
136 const getAxis = (axis: TAxis) => {
137 if (axis === "x") return sciChart3DSurface.xAxis;
138 if (axis === "y") return sciChart3DSurface.yAxis;
139 return sciChart3DSurface.zAxis;
140 };
141
142 const setTitleOffset = (offset: number, axis: TAxis) => {
143 getAxis(axis).titleOffset = offset;
144 };
145
146 const setTickLabelsOffset = (offset: number, axis: TAxis) => {
147 getAxis(axis).tickLabelsOffset = offset;
148 };
149
150 const setAxisLabelFontSize = (value: number, axis: TAxis) => {
151 getAxis(axis).labelStyle.fontSize = value;
152 };
153
154 // Create different point markers for each data point
155 const pointMarkers = [
156 new EllipsePointMarker3D(wasmContext, { size: 10 }),
157 new TrianglePointMarker3D(wasmContext, { size: 10 }),
158 new PixelPointMarker3D(wasmContext, { size: 10 }),
159 new QuadPointMarker(wasmContext, { size: 10 }),
160 new SpherePointMarker3D(wasmContext, { size: 10 }),
161 new CubePointMarker3D(wasmContext, { size: 10 }),
162 new CylinderPointMarker3D(wasmContext, { size: 10 }),
163 new PyramidPointMarker3D(wasmContext, { size: 10 }),
164 ];
165
166 const lifeExpectancy = [30, 40, 50, 60, 70, 80, 90, 100];
167 const gdpPerCapita = [5000, 10_000, 15_000, 20_000, 25_000, 30_000, 35_000, 40_000];
168 const year = [1972, 1977, 1982, 1987, 1992, 1997, 2002, 2007];
169
170 const metadata = [
171 { markerType: "EllipsePointMarker3D", pointScale: 1, vertexColor: 4284988847, color: "#67BDAF" },
172 { markerType: "TrianglePointMarker3D", pointScale: 1, vertexColor: 4292639081, color: "#DC7969" },
173 { markerType: "PixelPointMarker3D", pointScale: 1, vertexColor: 4278255615, color: "#FF6B35" },
174 { markerType: "QuadPointMarker", pointScale: 1, vertexColor: 4294934352, color: "#F7931E" },
175 { markerType: "SpherePointMarker3D", pointScale: 2, vertexColor: 4294967040, color: "#FFD23F" },
176 { markerType: "CubePointMarker3D", pointScale: 2, vertexColor: 4278255360, color: "#6BCF7F" },
177 { markerType: "CylinderPointMarker3D", pointScale: 2, vertexColor: 4278190335, color: "#4D96FF" },
178 { markerType: "PyramidPointMarker3D", pointScale: 2, vertexColor: 4286578816, color: "#9B59B6" },
179 ];
180
181 // Create individual series for each data point with different markers
182 for (let i = 0; i < lifeExpectancy.length; i++) {
183 const renderableSeries = new ScatterRenderableSeries3D(wasmContext, {
184 opacity: 0.9,
185 dataSeries: new XyzDataSeries3D(wasmContext, {
186 xValues: [lifeExpectancy[i]],
187 yValues: [gdpPerCapita[i]],
188 zValues: [year[i]],
189 metadata: [metadata[i]],
190 }),
191 pointMarker: pointMarkers[i % pointMarkers.length],
192 });
193
194 sciChart3DSurface.renderableSeries.add(renderableSeries);
195 }
196
197 // update axis title color based on selected axis
198 const updateAxisTitleColor = (axis?: TAxis) => {
199 const SELECTED_AXIS_COLOR = currentTheme === EThemeProviderType.Light ? "#000000" : "#FFFFFF";
200 const UNSELECTED_AXIS_COLOR = "#777777";
201 if (axis === "x" || !axis) {
202 sciChart3DSurface.xAxis.titleStyle.color = SELECTED_AXIS_COLOR;
203 sciChart3DSurface.xAxis.labelStyle.color = SELECTED_AXIS_COLOR;
204
205 sciChart3DSurface.yAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
206 sciChart3DSurface.zAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
207 sciChart3DSurface.yAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
208 sciChart3DSurface.zAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
209 }
210 if (axis === "y" || !axis) {
211 sciChart3DSurface.yAxis.titleStyle.color = SELECTED_AXIS_COLOR;
212 sciChart3DSurface.yAxis.labelStyle.color = SELECTED_AXIS_COLOR;
213
214 sciChart3DSurface.xAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
215 sciChart3DSurface.zAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
216 sciChart3DSurface.xAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
217 sciChart3DSurface.zAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
218 }
219 if (axis === "z" || !axis) {
220 sciChart3DSurface.zAxis.titleStyle.color = SELECTED_AXIS_COLOR;
221 sciChart3DSurface.zAxis.labelStyle.color = SELECTED_AXIS_COLOR;
222
223 sciChart3DSurface.xAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
224 sciChart3DSurface.yAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
225 sciChart3DSurface.xAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
226 sciChart3DSurface.yAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
227 }
228 };
229 updateAxisTitleColor("x");
230
231 const enableGridBands = (enable: boolean, axis: TAxis) => {
232 getAxis(axis).drawMajorBands = enable;
233 };
234
235 const enableMajorGridLines = (enable: boolean, axis: TAxis) => {
236 getAxis(axis).drawMajorGridLines = enable;
237 };
238 const enableMinorGridLines = (enable: boolean, axis: TAxis) => {
239 getAxis(axis).drawMinorGridLines = enable;
240 };
241
242 const setLabelOrientationMode = (mode: E3DLabelOrientationMode, axis: TAxis) => {
243 getAxis(axis).labelOrientationMode = mode;
244 };
245
246 let currentTheme: EThemeProviderType = EThemeProviderType.Navy;
247 const lightTheme = new SciChartJSLightTheme();
248 const darkTheme = new SciChartJSDarkTheme();
249 const darkThemeV2 = new SciChartJSDarkv2Theme();
250 const navyTheme = new SciChartJsNavyTheme();
251
252 const setTheme = (themeName: EThemeProviderType) => {
253 switch (themeName) {
254 case EThemeProviderType.Light:
255 sciChart3DSurface.applyTheme(lightTheme);
256 currentTheme = EThemeProviderType.Light;
257 break;
258 case EThemeProviderType.Dark:
259 sciChart3DSurface.applyTheme(darkTheme);
260 currentTheme = EThemeProviderType.Dark;
261 break;
262 case EThemeProviderType.DarkV2:
263 sciChart3DSurface.applyTheme(darkThemeV2);
264 currentTheme = EThemeProviderType.DarkV2;
265 break;
266 case EThemeProviderType.Navy:
267 default:
268 sciChart3DSurface.applyTheme(navyTheme);
269 currentTheme = EThemeProviderType.Navy;
270 break;
271 }
272 updateAxisTitleColor();
273 };
274
275 const setAxisBandsFill = (color: string, axis: TAxis) => {
276 getAxis(axis).axisBandsFill = color;
277 };
278
279 const setMajorGridLineColor = (color: string, axis: TAxis) => {
280 getAxis(axis).majorGridLineStyle = { color };
281 };
282
283 const setMinorGridLineColor = (color: string, axis: TAxis) => {
284 getAxis(axis).minorGridLineStyle = { color };
285 };
286
287 const controls = {
288 setTheme,
289 setTitleOffset,
290 setTickLabelsOffset,
291 enableGridBands,
292 setAxisLabelFontSize,
293 enableMajorGridLines,
294 enableMinorGridLines,
295 setLabelOrientationMode,
296 updateAxisTitleColor,
297 setVisibilityMode,
298 setDrawTitlesMode,
299 setDrawLabelsMode,
300 setIsPlaneVisible,
301 setPlaneBackground,
302 setAxisBandsFill,
303 setMajorGridLineColor,
304 setMinorGridLineColor,
305 };
306
307 return { sciChartSurface: sciChart3DSurface, wasmContext, controls };
308};
309This example demonstrates advanced 3D chart styling capabilities built with SciChart.js using JavaScript. It showcases a comprehensive styling demo featuring multiple point marker types, axis styling controls, and interactive styling features. The example illustrates how to create visually rich 3D charts with extensive customization options without relying on frameworks such as Angular or React.
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 for optimal viewing. 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. The chart features eight different 3D Point Markers including EllipsePointMarker3D, TrianglePointMarker3D, SpherePointMarker3D, CubePointMarker3D, and more, each with unique styling and metadata. Axis selection is shown by the label font color and plane selection uses axisPlaneBackgroundFill.
Key features include multiple point marker types with individual styling, comprehensive axis styling controls, and interactive plane visibility management. The example demonstrates how to customize axis planes with different visibility modes, label drawing modes, and title positioning. Advanced styling options include grid bands, major grid lines, label orientation modes, and dynamic color theming. Each data point is rendered with unique metadata including custom colors and scaling factors.
This implementation serves as a comprehensive template for integrating advanced 3D chart styling into applications using only JavaScript. Best practices demonstrated here include modular styling control functions, and organized axis configuration. The example shows how to create reusable styling functions for different chart elements and how to manage complex 3D chart interactions. Developers can use these techniques along with detailed SciChart.js documentation to create highly customized and visually appealing 3D charts.

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

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.

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

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 JavaScript 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 JavaScript 3D Column Chart using SciChart's 5-star rated JavaScript chart library. Supports large datasets