3D Waterfall / Point-Line Chart
The 3D Waterfall Chart renders spectral or time-series data as stacked line slices in a 3D world, giving a sense of depth and evolution over time. Each slice is a PointLineRenderableSeries3Dš whose points share the same Z value, spreading the series along the Z axis to form the waterfall stack.
The JavaScript 3D Point-Line Chart Example can be found in the SciChart.JS Examples Suite on GitHub, or in the live demo at scichart.com/demo.
Create a 3D Waterfall Chartā
The waterfall depth effect is achieved by assigning every point in a slice the same Z value while incrementing that value for each successive slice. The X axis represents frequency (or whatever dimension varies within a slice) and the Y axis represents magnitude.
- TS
- HTML
- CSS
// Demonstrates how to create a 3D Waterfall Chart using PointLineRenderableSeries3D.
// Each "slice" is a PointLineRenderableSeries3D whose zValues are all set to the same
// value, spreading slices along the Z axis to produce the waterfall depth effect.
const { wasmContext, sciChart3DSurface } = await SciChart3DSurface.create(divElementId, {
theme: new SciChartJsNavyTheme(),
worldDimensions: new Vector3(300, 100, 300),
cameraOptions: {
position: new Vector3(-142, 310, 393),
target: new Vector3(0, 50, 0),
},
});
sciChart3DSurface.xAxis = new NumericAxis3D(wasmContext, {
axisTitle: "Frequency (Hz)",
drawMinorGridLines: false,
});
sciChart3DSurface.yAxis = new NumericAxis3D(wasmContext, {
axisTitle: "Power (dB)",
drawMinorGridLines: false,
visibleRange: new NumberRange(-30, 10),
});
sciChart3DSurface.zAxis = new NumericAxis3D(wasmContext, {
axisTitle: "Time",
drawMinorGridLines: false,
});
const sliceCount = 20;
const spectraSize = 200;
for (let i = 0; i < sliceCount; i++) {
const { xValues, yValues, zValues } = generateSpectralSlice(i, spectraSize);
// Color each point by its Y (power) value using a heat gradient
const low = Math.min(...yValues);
const high = Math.max(...yValues);
const metadata = yValues.map((y) => ({
vertexColor: valueToColor(y, low, high),
pointScale: 1,
}));
sciChart3DSurface.renderableSeries.add(
new PointLineRenderableSeries3D(wasmContext, {
dataSeries: new XyzDataSeries3D(wasmContext, { xValues, yValues, zValues, metadata }),
strokeThickness: 2,
opacity: 0.7,
})
);
}
sciChart3DSurface.chartModifiers.add(
new MouseWheelZoomModifier3D(),
new OrbitModifier3D(),
new ResetCamera3DModifier()
);
<div class="wrapper">
<div id="scichart-root"></div>
<div class="titleWrapper">
<p class="title">SciChart.js 3D Waterfall Chart</p>
<p class="subtitle">Spectral data stacked along the Z axis using PointLineRenderableSeries3D.</p>
<p class="subTitle">Drag to orbit • Scroll to zoom • Double-click to reset camera</p>
</div>
</div>
body {
margin: 0;
font-family: Arial;
}
.wrapper {
width: 100%;
height: 100vh;
position: relative;
}
#scichart-root {
width: 100%;
height: 100%;
position: relative;
}
.titleWrapper {
position: absolute;
width: 100%;
top: 35%;
text-align: center;
pointer-events: none;
color: #ffffffaa;
}
.title {
font-size: 20px;
}
.subTitle {
font-size: 16px;
}
In the code above:
SciChart3DSurface.create()creates a 3D chart surface.worldDimensionssets the physical size of the 3D world in X, Y, Z units;cameraOptionspositions the viewpoint.sciChart3DSurface.xAxis / yAxis / zAxisā 3D charts use single-axis assignment (not.add()) for each of the three axes.zValues.push(sliceIndex * 6)ā all points in one slice share the same Z, and successive slices are spaced 6 units apart along Z, stacking them into the waterfall.PointLineRenderableSeries3Dwith anXyzDataSeries3Drenders each slice as a colored line in 3D space.metadata[i].vertexColorā per-point color in UInt ARGB format, mapped from the Y (power) value through a heat gradient viauintArgbColorLerp.OrbitModifier3D/MouseWheelZoomModifier3D/ResetCamera3DModifierā 3D-specific modifiers for orbit rotation, zoom, and camera reset.
The 3D API vs the 2D APIā
| Concept | 2D | 3D |
|---|---|---|
| Surface | SciChartSurface | SciChart3DSurface |
| Axis | NumericAxis added via .xAxes.add() | NumericAxis3D assigned to .xAxis / .yAxis / .zAxis |
| Data series | XyDataSeries | XyzDataSeries3D |
| Renderable series | FastLineRenderableSeries | PointLineRenderableSeries3D |
| Zoom/pan | ZoomPanModifier, MouseWheelZoomModifier | OrbitModifier3D, MouseWheelZoomModifier3D |
| Per-point color | PaletteProvider | metadata[i].vertexColor (UInt ARGB) |
Point Markersā
PointLineRenderableSeries3D supports optional 3D point markers at each data point. Choose from:
| Marker type | Class |
|---|---|
| Sphere | SpherePointMarker3Dš |
| Cube | CubePointMarker3Dš |
| Pyramid | PyramidPointMarker3Dš |
| Cylinder | CylinderPointMarker3Dš |
| Ellipse (flat, camera-facing) | EllipsePointMarker3Dš |
| Pixel | PixelPointMarker3Dš |
Pass a marker instance to the pointMarker constructor option:
new PointLineRenderableSeries3D(wasmContext, {
dataSeries: ...,
strokeThickness: 2,
pointMarker: new EllipsePointMarker3D(wasmContext, { size: 3 }),
})
Per-Point Coloring with Metadataā
Color each point individually by supplying a metadata array on XyzDataSeries3D. The vertexColor property controls the point color as a UInt ARGB value. Use parseColorToUIntArgb() and uintArgbColorLerp() to map values to a gradient:
const metadata = yValues.map((y) => ({
vertexColor: valueToColor(y, low, high), // UInt ARGB
pointScale: 1,
}));
new XyzDataSeries3D(wasmContext, { xValues, yValues, zValues, metadata })
Colors must be in UInt ARGB format where 0xFFFF0000 is opaque red. Use parseColorToUIntArgbš to convert from CSS hex strings, and uintArgbColorLerpš to blend between two colors.
See Alsoā
- The Lines 3D Chart Type ā full reference for
PointLineRenderableSeries3Dincluding all marker types and per-segment coloring - The Waterfall Chart Type ā 2D financial waterfall built with Rectangle Series
- Interactive Waterfall (Spectral) Chart ā 2D stacked spectral waterfall using offset axes