Demonstrates how to load a 3D model in React and show it in a SciChart3DSurface. The engine can load any 3D model, not just the car shown here.

drawExample.ts
index.tsx
theme.ts
modelLoadProgress.ts
1import {
2 BaseSceneEntity3D,
3 EMainLightMode,
4 ESceneEntityType,
5 MouseWheelZoomModifier3D,
6 NumericAxis3D,
7 OrbitModifier3D,
8 ResetCamera3DModifier,
9 SciChart3DSurface,
10 TSciChart3D,
11 Vector3,
12} from "scichart";
13import { appTheme } from "../../../theme";
14
15/**
16 * The model to load, named by its path inside the asset package. Nothing here is specific to a car -
17 * the SciChart 3D engine loads any model you cook into a package (glTF, OBJ, STL, STEP and more).
18 */
19const modelFileName = "AstonMartin/aston.glb.twi";
20
21/**
22 * The asset package holding the model. The engine appends ".web.pkg" and fetches the result, so this
23 * may be a bare name served from your site root, or an absolute URL as it is here.
24 */
25const modelPackage = "https://stagingdemo.scichart.com/fileshare/F1CarAssets";
26
27/**
28 * A thin {@link BaseSceneEntity3D} wrapper around the native model entity, so the loaded model can be
29 * added to the 3D scene via sciChart3DSurface.rootEntity.children.
30 */
31class ModelSceneEntity extends BaseSceneEntity3D<any> {
32 public readonly type = ESceneEntityType.SCRTSceneEntity;
33
34 constructor(webAssemblyContext: TSciChart3D) {
35 super(webAssemblyContext);
36 const nativeEntity = new webAssemblyContext.SCRTCADModelSceneEntity(modelFileName, modelPackage);
37 // Sizes the model to the 3D world. The package is downloaded in the background and the scene
38 // redraws itself once the model is ready.
39 nativeEntity.SetModelScale(0.1);
40 this.setNativeEntity(nativeEntity);
41 }
42
43 /**
44 * True once the package has been downloaded and the model is in the scene. The native entity only
45 * reports a node hierarchy once it has a model, so an empty hierarchy means "still loading".
46 */
47 public get isModelLoaded(): boolean {
48 try {
49 const hierarchyJson = this.nativeEntity.GetNodeHierarchyJson();
50 return hierarchyJson ? JSON.parse(hierarchyJson).nodes?.length > 0 : false;
51 } catch {
52 return false;
53 }
54 }
55}
56
57export const drawExample = async (rootElement: string | HTMLDivElement) => {
58 const { sciChart3DSurface, wasmContext } = await SciChart3DSurface.create(rootElement, {
59 theme: appTheme.SciChartJsTheme,
60 lighting: {
61 ambientLight: 0.25,
62 lightMode: EMainLightMode.GlobalSpace,
63 lightDirection: new Vector3(-1, -1, -1),
64 },
65 // Framed so the whole model is in view on startup. Double-click returns the camera here.
66 cameraOptions: {
67 position: new Vector3(24, 12, 24),
68 target: new Vector3(0, 1, 0),
69 },
70 // Leave only the floor plane, so the model is not boxed in by the axis cube
71 xyAxisPlane: { isVisible: false },
72 zyAxisPlane: { isVisible: false },
73 });
74
75 sciChart3DSurface.xAxis = new NumericAxis3D(wasmContext);
76 sciChart3DSurface.yAxis = new NumericAxis3D(wasmContext);
77 sciChart3DSurface.zAxis = new NumericAxis3D(wasmContext);
78
79 // A model is not a renderable series - it is a scene entity added to the root entity
80 const model = new ModelSceneEntity(wasmContext);
81 sciChart3DSurface.rootEntity.children.add(model);
82
83 // A large model can take a while to arrive, so the example shows a loader until it does. The entity
84 // has no load event, so poll it. The returned function stops waiting when the chart goes away.
85 const waitForModel = (onModelLoaded: () => void) => {
86 const intervalId = setInterval(() => {
87 if (!model.isModelLoaded) return;
88 clearInterval(intervalId);
89 // A cached package can arrive before the first render pass, so ask for a redraw once the
90 // model is in the scene. Without this the scene stays empty until something else redraws it.
91 sciChart3DSurface.invalidateElement();
92 onModelLoaded();
93 }, 200);
94 return () => clearInterval(intervalId);
95 };
96
97 sciChart3DSurface.chartModifiers.add(
98 new MouseWheelZoomModifier3D(),
99 new OrbitModifier3D(),
100 new ResetCamera3DModifier()
101 );
102
103 return { sciChartSurface: sciChart3DSurface, wasmContext, waitForModel };
104};
105This example loads a 3D model into a SciChart3DSurface. The model shown here is a racing car, but nothing in the code is specific to it: the SciChart 3D engine can load any 3D model, so the same few lines will show a CAD assembly, a scanned part, a machine, a building or a character.
BaseSceneEntity3D wrapper holds the native model entity and is added to sciChart3DSurface.rootEntity.children..web.pkg to the package name and fetches the result, so the package may be a bare name served from your site root, or an absolute URL as it is here.invalidateElement() at that point. A cached package can arrive before the first render pass, and without a redraw the scene would stay empty.SetModelScale() sizes the model to the 3D world, and the camera is placed so the whole model is in view when the example opens.Orbit with the left mouse button, zoom with the mouse wheel and double-click to reset the camera.

Create a high performance React Parallel Coordinate Plot with SciChart.js. Visualise multivariate data with one axis per dimension, reorder axes, highlight ranges and select records, with up to 100,000 records on screen.

Draw custom lit 3D geometry in React with SciChart.js using ImmediateLitMeshContext. Emit per-vertex positions, normals, texture coordinates and colours from a custom 3D scene entity.