This demonstrates the JavaScript 3D Styling capabilities of SciChart.js v5, including axis label positioning, and control over 3d plane visibility
Select Plane
Visibility Mode
Draw Titles Mode
Draw Labels 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 let selectedAxisTitle: TAxis = "x";
198
199 // update axis title color based on selected axis
200 const updateAxisTitleColor = (axis: TAxis = selectedAxisTitle) => {
201 selectedAxisTitle = axis;
202 const SELECTED_AXIS_COLOR = "#FFFFFF";
203 const UNSELECTED_AXIS_COLOR = "#777777";
204 if (axis === "x") {
205 sciChart3DSurface.xAxis.titleStyle.color = SELECTED_AXIS_COLOR;
206 sciChart3DSurface.xAxis.labelStyle.color = SELECTED_AXIS_COLOR;
207
208 sciChart3DSurface.yAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
209 sciChart3DSurface.zAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
210 sciChart3DSurface.yAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
211 sciChart3DSurface.zAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
212 } else if (axis === "y") {
213 sciChart3DSurface.yAxis.titleStyle.color = SELECTED_AXIS_COLOR;
214 sciChart3DSurface.yAxis.labelStyle.color = SELECTED_AXIS_COLOR;
215
216 sciChart3DSurface.xAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
217 sciChart3DSurface.zAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
218 sciChart3DSurface.xAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
219 sciChart3DSurface.zAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
220 } else {
221 sciChart3DSurface.zAxis.titleStyle.color = SELECTED_AXIS_COLOR;
222 sciChart3DSurface.zAxis.labelStyle.color = SELECTED_AXIS_COLOR;
223
224 sciChart3DSurface.xAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
225 sciChart3DSurface.yAxis.titleStyle.color = UNSELECTED_AXIS_COLOR;
226 sciChart3DSurface.xAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
227 sciChart3DSurface.yAxis.labelStyle.color = UNSELECTED_AXIS_COLOR;
228 }
229 };
230 updateAxisTitleColor("x");
231
232 const enableGridBands = (enable: boolean, axis: TAxis) => {
233 getAxis(axis).drawMajorBands = enable;
234 };
235
236 const enableMajorGridLines = (enable: boolean, axis: TAxis) => {
237 getAxis(axis).drawMajorGridLines = enable;
238 };
239 const enableMinorGridLines = (enable: boolean, axis: TAxis) => {
240 getAxis(axis).drawMinorGridLines = enable;
241 };
242
243 const setLabelOrientationMode = (mode: E3DLabelOrientationMode, axis: TAxis) => {
244 getAxis(axis).labelOrientationMode = mode;
245 };
246
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 break;
257 case EThemeProviderType.Dark:
258 sciChart3DSurface.applyTheme(darkTheme);
259 break;
260 case EThemeProviderType.DarkV2:
261 sciChart3DSurface.applyTheme(darkThemeV2);
262 break;
263 case EThemeProviderType.Navy:
264 default:
265 sciChart3DSurface.applyTheme(navyTheme);
266 break;
267 }
268 updateAxisTitleColor();
269 };
270
271 const setAxisBandsFill = (color: string, axis: TAxis) => {
272 getAxis(axis).axisBandsFill = color;
273 };
274
275 const setMajorGridLineColor = (color: string, axis: TAxis) => {
276 getAxis(axis).majorGridLineStyle = { color };
277 };
278
279 const setMinorGridLineColor = (color: string, axis: TAxis) => {
280 getAxis(axis).minorGridLineStyle = { color };
281 };
282
283 const controls = {
284 setTheme,
285 setTitleOffset,
286 setTickLabelsOffset,
287 enableGridBands,
288 setAxisLabelFontSize,
289 enableMajorGridLines,
290 enableMinorGridLines,
291 setLabelOrientationMode,
292 updateAxisTitleColor,
293 setVisibilityMode,
294 setDrawTitlesMode,
295 setDrawLabelsMode,
296 setIsPlaneVisible,
297 setPlaneBackground,
298 setAxisBandsFill,
299 setMajorGridLineColor,
300 setMinorGridLineColor,
301 };
302
303 return { sciChartSurface: sciChart3DSurface, wasmContext, controls };
304};
305This 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 Scatter 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