JavaScript Spline Band Chart

Demonstrates how to create a JavaScript Spline Band Chart or High-Low Fill using SciChart.js, our High Performance JavaScript Chart Software

Fullscreen

Edit

 Edit

Docs

src/drawExample.ts
import {
    AxisMarkerAnnotation,
    EAxisAlignment,
    ECoordinateMode,
    EDragMode,
    EHorizontalAnchorPoint,
    ELegendOrientation,
    ELegendPlacement,
    EllipsePointMarker,
    LegendModifier,
    MouseWheelZoomModifier,
    NativeTextAnnotation,
    NumberRange,
    NumericAxis,
    ScaleAnimation,
    SciChartSurface,
    SplineBandRenderableSeries,
    XyyBezierRenderDataTransform,
    XyyDataSeries,
    YAxisDragModifier,
} from "scichart";
// import { XyyBezierRenderDataTransform } from "scichart/Charting/Visuals/RenderableSeries/RenderDataTransforms/BezierRenderDataTransform";
import { ExampleDataProvider } from "./ExampleDataProvider";
import { appTheme } from "./appTheme";
//import { xValues } from "../StackedMountainChart/data/stackedMountainChartData";

export const drawExample = async (rootElement: string | HTMLDivElement) => {

    // Create a SciChartSurface
    const { wasmContext, sciChartSurface } = await SciChartSurface.create(rootElement, {
        theme: appTheme.SciChartJsTheme,
    });

    // Add an XAxis, YAxis
    sciChartSurface.xAxes.add(new NumericAxis(wasmContext, { axisAlignment: EAxisAlignment.Top }));
    sciChartSurface.yAxes.add(
        new NumericAxis(wasmContext, {
            axisAlignment: EAxisAlignment.Left,
            visibleRange: new NumberRange(-1.75, 0.75),
            backgroundColor: appTheme.VividSkyBlue + "33",
            labelStyle: { color: appTheme.VividOrange },
            majorTickLineStyle: { color: appTheme.VividOrange },
        })
    );
    sciChartSurface.yAxes.add(
        new NumericAxis(wasmContext, {
            axisAlignment: EAxisAlignment.Right,
            id: "y2",
            visibleRange: new NumberRange(-0.9, 1.6),
            backgroundColor: appTheme.VividPurple + "33",
            labelStyle: { color: appTheme.VividRed },
            majorTickLineStyle: { color: appTheme.VividRed },
        })
    );

    // The spline bandseries requires a special dataseries type called XyyDataSeries
    // This stores X, Y1, Y2 point data for the two lines in the band
    const yData = ExampleDataProvider.getDampedSinewave(0, 0.9, 0, 0.002, 1000, 17);
    const y1Data = ExampleDataProvider.getDampedSinewave(0, 0.9, 0, 0.002, 1000, 16);

    const xValues: number[] = [];
    const yValues: number[] = [];
    const y1Values: number[] = [];

    for (let i = 0; i < 20; i++) {
        const index = i * 50;
        xValues.push(yData.xValues[index]);
        yValues.push(yData.yValues[index]);
        y1Values.push(y1Data.yValues[index]);
    }

    // Create the band series and add to the chart
    const rendSeries = new SplineBandRenderableSeries(wasmContext, {
        dataSeries: new XyyDataSeries(wasmContext, { xValues, yValues, y1Values, dataSeriesName: "Default Spline" }),
        strokeThickness: 3,
        fill: appTheme.VividOrange + "33",
        fillY1: appTheme.VividSkyBlue + "33",
        stroke: appTheme.VividOrange,
        strokeY1: appTheme.VividSkyBlue,
        interpolationPoints: 20, // Choose the number of points to interpolate for smoothing
        pointMarker: new EllipsePointMarker(wasmContext, {
            width: 7,
            height: 7,
            fill: appTheme.PaleSkyBlue,
            stroke: appTheme.VividSkyBlue,
        }),
        animation: new ScaleAnimation({ duration: 800, zeroLine: 0, fadeEffect: true }),
    });

    sciChartSurface.renderableSeries.add(rendSeries);

    const bezierSeries = new SplineBandRenderableSeries(wasmContext, {
        dataSeries: new XyyDataSeries(wasmContext, {
            xValues,
            yValues,
            y1Values,
            dataSeriesName: "XyyBezier (Range Restricted)",
        }),
        stroke: appTheme.VividPurple,
        strokeY1: appTheme.VividRed,
        fill: appTheme.VividPurple + "33",
        fillY1: appTheme.VividRed + "33",
        pointMarker: new EllipsePointMarker(wasmContext, {
            width: 7,
            height: 7,
            fill: appTheme.PaleSkyBlue,
            stroke: appTheme.VividSkyBlue,
        }),
        yAxisId: "y2",
        strokeThickness: 3,
        interpolationPoints: 20, // Choose the number of points to interpolate for smoothing
        animation: new ScaleAnimation({ duration: 800, zeroLine: 0, fadeEffect: true }),
    });
    const bezierTransform = new XyyBezierRenderDataTransform(
        bezierSeries,
        wasmContext,
        [bezierSeries.drawingProviders[0]],
        { interpolationPoints: 20, curvature: 0.5 }
    );
    bezierSeries.renderDataTransform = bezierTransform;
    sciChartSurface.renderableSeries.add(bezierSeries);

    const curvatureAnnotation = new AxisMarkerAnnotation({
        yCoordinateMode: ECoordinateMode.Relative,
        y1: 0.5,
        yAxisId: "y2",
        formattedValue: "Bezier Curvature 0.5",
        backgroundColor: appTheme.VividPurple,
        isEditable: true,
        onDrag: (args) => {
            bezierTransform.curvature = curvatureAnnotation.y1;
            curvatureAnnotation.formattedValue = "Bezier Curvature " + curvatureAnnotation.y1.toFixed(2);
        },
    });
    sciChartSurface.annotations.add(curvatureAnnotation);

    sciChartSurface.annotations.add(
        new NativeTextAnnotation({
            xCoordinateMode: ECoordinateMode.Relative,
            yCoordinateMode: ECoordinateMode.Relative,
            x1: 0.9,
            y1: 0.9,
            horizontalAnchorPoint: EHorizontalAnchorPoint.Right,
            text: "Drag the left or right y axis to overlay and compare the series",
            fontSize: 16,
        })
    );

    // Optional: Add some interactivity modifiers
    sciChartSurface.chartModifiers.add(
        new YAxisDragModifier({ dragMode: EDragMode.Panning }),
        new MouseWheelZoomModifier(),
        new LegendModifier({
            orientation: ELegendOrientation.Vertical,
            placement: ELegendPlacement.TopRight,
            showCheckboxes: true,
        })
    );

    return { wasmContext, sciChartSurface };
};

Spline Band Series Chart Example in JavaScript

Overview

This example demonstrates how to create a Spline Band Series Chart using SciChart.js in a JavaScript environment. The implementation visualizes two spline band series with high-low fills, utilizing dual Y axes for comparing different data ranges. It leverages custom styling, smooth interpolation, and interactive annotations to deliver an engaging charting experience.

Technical Implementation

The chart is initialized asynchronously using the SciChartSurface.create() method as described in the Getting Started with SciChart JS documentation. Two NumericAxis are configured for distinct visual zones with custom styles, as detailed in the Numeric Axis Documentation. Data for the spline band is managed by the XyyDataSeries which stores dual-line datasets, and is rendered using the SplineBandRenderableSeries. Smooth spline curves are achieved by setting interpolation points and applying the XyyBezierRenderDataTransform with customizable curvature.

Features and Capabilities

Key features include real-time update capabilities via an interactive AxisMarkerAnnotation that allows dynamic adjustment of the Bezier transform curvature. The series incorporate smooth animations using the ScaleAnimation for a refined rendering effect. Advanced spline interpolation is enabled by specifying interpolation points, ensuring that the chart curves are rendered with high visual fidelity, as explained in The Spline (Smoothed) Band Series Type. Interactive modifiers, such as the YAxisDragModifier and MouseWheelZoomModifier, further enhance the user experience by providing intuitive controls for data navigation and zooming.

Integration and Best Practices

This example follows best practices for asynchronous initialization and proper disposal in a JavaScript context. After creation, the chart instance is disposed using the sciChartSurface.delete() method to manage resources effectively, as recommended in the Memory Best Practices guide. Developers are encouraged to explore the use of custom data series (such as XyyDataSeries), configurable animations, and interactive annotations to build high-performance and responsive charting applications in JavaScript. The approach demonstrated here provides a clear model for integrating SciChart.js into non-framework-specific environments, ensuring optimal performance and ease of customization.