JavaScript Bubble Chart

Demonstrates how to create a JavaScript Bubble Chart This is a JavaScript Chart type which draws point-markers (Ellipse, Square, Triangle, Circle) at X,Y locations

Fullscreen

Edit

 Edit

Docs

src/drawExample.ts
import {
    XyDataSeries,
    XyzDataSeries,
    NumericAxis,
    FastBubbleRenderableSeries,
    SciChartSurface,
    NumberRange,
    EllipsePointMarker,
    EFillPaletteMode,
    EStrokePaletteMode,
    IPointMarkerPaletteProvider,
    TPointMarkerArgb,
    IRenderableSeries,
    IPointMetadata,
    MouseWheelZoomModifier,
    ZoomExtentsModifier,
    ZoomPanModifier,
    parseColorToUIntArgb,
    SplineLineRenderableSeries,
    SweepAnimation,
} from "scichart";

import { appTheme } from "./appTheme";

export const drawExample = async (rootElement: string | HTMLDivElement) => {
    // Create a SciChartSurface with X,Y Axis
    const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
        theme: appTheme.SciChartJsTheme,
    });
    sciChartSurface.xAxes.add(new NumericAxis(wasmContext));
    sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { growBy: new NumberRange(0.05, 0.05) }));

    // Create some data
    const xValues = [];
    const yValues = [];
    const zValues = [];
    let prevYValue = 0;
    for (let i = 0; i < 20; i++) {
        const curYValue = Math.sin(i) * 10 + 5;
        const size = Math.sin(i) * 60 + 3;

        xValues.push(i);
        yValues.push(prevYValue + curYValue);
        zValues.push(size);

        prevYValue += curYValue;
    }

    // Create and add a line series to the chart
    sciChartSurface.renderableSeries.add(
        new SplineLineRenderableSeries(wasmContext, {
            dataSeries: new XyDataSeries(wasmContext, { xValues, yValues }),
            stroke: appTheme.PaleSkyBlue,
            strokeThickness: 3,
            animation: new SweepAnimation({ duration: 500 }),
        })
    );

    // Create and add a Bubble series to the chart
    // The Bubble series requires a special dataseries type called XyzDataSeries with X,Y and Z (size) values
    sciChartSurface.renderableSeries.add(
        new FastBubbleRenderableSeries(wasmContext, {
            dataSeries: new XyzDataSeries(wasmContext, { xValues, yValues, zValues }),
            // Pointmarker defines the marker shown per-bubble point. This will be scaled according to z-value
            pointMarker: new EllipsePointMarker(wasmContext, {
                width: 64,
                height: 64,
                strokeThickness: 0,
                fill: appTheme.VividSkyBlue + "77",
            }),
            // Optional: Allows per-point colouring of bubble stroke
            paletteProvider: new BubblePaletteProvider(appTheme.VividOrange),
            animation: new SweepAnimation({ delay: 200, duration: 500, fadeEffect: true }),
        })
    );

    // Add some zooming and panning behaviour
    sciChartSurface.chartModifiers.add(new ZoomPanModifier({ enableZoom: true }));
    sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());
    sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());

    sciChartSurface.zoomExtents();
    return { sciChartSurface, wasmContext };
};

/**
 * Optional: An example PaletteProvider which implements IPointMarkerPaletteProvider
 * This can be attached to Scatter or Bubble series to change the stroke or fill
 * of the series point-markers conditionally
 */
class BubblePaletteProvider implements IPointMarkerPaletteProvider {
    public readonly fillPaletteMode = EFillPaletteMode.SOLID;
    public readonly strokePaletteMode: EStrokePaletteMode = EStrokePaletteMode.SOLID;
    private readonly fillArgb: number;

    constructor(fillHexString: string) {
        this.fillArgb = parseColorToUIntArgb(fillHexString);
    }

    public onAttached(parentSeries: IRenderableSeries): void {}

    public onDetached(): void {}

    public overridePointMarkerArgb(
        xValue: number,
        yValue: number,
        index: number,
        opacity?: number,
        metadata?: IPointMetadata
    ): TPointMarkerArgb {
        return xValue >= 8 && xValue <= 12 ? { fill: this.fillArgb, stroke: this.fillArgb } : undefined;
    }
}

Bubble Chart with JavaScript

Overview

This example demonstrates how to create a high-performance Bubble Chart using JavaScript and SciChart.js. It combines a smooth spline line series with a dynamic bubble series where each bubble’s size is determined by a third data value. The implementation leverages asynchronous chart initialization and WebAssembly for optimal rendering performance.

Technical Implementation

The chart is initialized asynchronously using SciChartSurface.create, which loads the WebAssembly context for efficient GPU-accelerated rendering. Data for the chart is managed using an XyDataSeries for the spline line and an XyzDataSeries for the bubble series, a design choice that allows the bubble sizes to be scaled automatically based on the Z-values. Smooth visual transitions are applied using SweepAnimation, and each bubble is rendered with an EllipsePointMarker for a consistent appearance. Additionally, a custom palette provider is implemented following the PaletteProvider API guidelines to conditionally style bubbles based on their data values. Interactive capabilities are enhanced through modifiers such as ZoomPanModifier, MouseWheelZoomModifier, and ZoomExtentsModifier, details of which can be found in the Interactive Zooming and Panning documentation.

Features and Capabilities

Key features of this implementation include real-time data visualization, dynamic bubble sizing, and smooth startup animations. The chart offers advanced interactivity with zooming and panning tools, providing users the ability to explore detailed datasets easily. The custom palette provider further enhances the chart by enabling per-point color customization based on specific data conditions, adding an extra layer of data insight.

Integration and Best Practices

This example adheres to best practices for modular chart initialization in plain JavaScript by isolating the rendering logic in a dedicated function. Its asynchronous setup ensures that the heavy lifting, such as WebAssembly loading, does not block the main thread, promoting a responsive user interface. Developers looking to optimize performance and maintainability in their web applications can benefit from the techniques demonstrated here, as detailed in the Performance Tips for JavaScript Charts documentation.