Pre loader

Creating a React Dashboard with SciChart.js, SciChart-React and Deepseek AI

Creating a React Dashboard with SciChart.js, SciChart-React and Deepseek AI

In this blog, we’ll walk through the process of creating a fully interactive and dynamic dashboard in React and SciChart.js in 20 minutes, coding almost entirely using AI. The dashboard features five different types of charts: React Line Chart, React Scatter Chart, React Stacked Column Chart, React Mountain Chart, and React Pie Chart, arranged in a grid layout. We’ll cover how to integrate SciChart.js into a React dashboard, using scichart-react, apply a custom theme, and position the charts to maintain a consistent layout. By the end of this tutorial, you’ll have a fully functional React dashboard that can be customized for data visualization in any domain.

Introduction

Data visualization is a critical aspect of modern web applications, enabling users to understand complex data at a glance. With the rise of powerful React chart libraries like SciChart.js, developers can now create stunning, high-performance visualizations with ease. When combined with React, a popular JavaScript library for building user interfaces with interactive dashboards, the possibilities are endless.

In this blog, we’ll explore how to build a dynamic dashboard that showcases five different chart types, all seamlessly integrated into a single view. The dashboard is designed to be interactive, with tooltips, legends and zooming and panning behaviours to allow you to inspect data on the fly. We’ll also apply the Navy theme from SciChart.js to give the dashboard a sleek, professional look.

We’ll show the power of generative AI tools in creating this React Dashboard layout by using Deepseek R1, an open source competitor to Chat GPT and show the prompts used and what changes were required to get the dashboard working. We’ll code the entire tutorial in codesandbox.

Key Takeaways

  • How to integrate SciChart.js into a React application.
  • Creating and customizing five different chart types: React Line Chart, React Scatter Chart, React Stacked Column Chart, React Mountain Chart, and React Pie Chart.
  • Applying a custom theme (Navy theme) to all charts for a cohesive look.
  • Applying legends, zooming and panning and tooltip behaviours.
  • Concluding on the limitations and pros/cons of using AI such as Chat GPT or Deepseek for creating react dashboards and where this technology could go next.

Who is this for?

  • Frontend Developers looking to enhance their data visualization skills.
  • React Developers interested in integrating advanced charting libraries.
  • Data Enthusiasts who want to create interactive dashboards for data analysis.

Getting Started

Creating the Input Prompt

We begin the tutorial by using Deepseek, an open source competitor to Chat GPT which scores highly in coding benchmarks, and operates at a fraction of the cost of Open AIs solutions.

We’ll start with our first prompt.

Create a dashboard in react with 5 charts using SciChart.js and scichart-react. Each chart should be hosted in a `<SciChartReact/>` component. `initChart` should not be inline but be a separate function.

The charts should be arranged in two rows. The first row should have two charts: a line chart (top left) and a scatter chart (top right).

The second row should have three charts: A stacked column chart (bottom left), a Mountain chart (bottom middle) and a pie chart (bottom right). Create some dummy data to upload to the charts and create the dashboard.

Choose the theme `SciChartJsNavyTheme` to apply to each chart. Do not set any Series Colors or Fill/Stroke on the chart series, as these will be applied automatically by the theme.

Ensure all SciChart type imports are “import { A, B, C } from ‘scichart'”

Deepseek gets straight to work on the output, recommending correctly to `npm install scichart scichart-react`. It then provides JSX output to include in your application.

The first output from DeepSeek provided good, but slightly incorrect code. We’re going to modify and correct it later. Here it is the initial draft of dashboard.jsx in full:

dashboard.jsx version #1 with errors

import React from "react";
import {
  SciChartSurface,
  NumericAxis,
  FastLineRenderableSeries,
  XyDataSeries,
  EllipsePointMarker,
  FastScatterRenderableSeries,
  StackedColumnCollection,
  StackedColumnRenderableSeries,
  FastMountainRenderableSeries,
  PieChart,
  PieSegment,
  SciChartJsNavyTheme,
} from "scichart";
import { SciChartReact } from "scichart-react";

// Initialize the line chart
const initLineChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, 
  {
    theme: new SciChartJsNavyTheme(),
  });
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const lineSeries = new FastLineRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [2, 4, 6, 8, 10],
    }),
  });
  sciChartSurface.renderableSeries.add(lineSeries);
  return sciChartSurface;
};

// Initialize the scatter chart
const initScatterChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement,
  {
    theme: new SciChartJsNavyTheme(),
  });
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const scatterSeries = new FastScatterRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [3, 5, 7, 9, 11],
    }),
    pointMarker: new EllipsePointMarker(wasmContext, { width: 10, height: 10 }),
  });
  sciChartSurface.renderableSeries.add(scatterSeries);
  return sciChartSurface;
};

// Initialize the stacked column chart
const initStackedColumnChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, 
  {
    theme: new SciChartJsNavyTheme(),
  });
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const stackedColumnCollection = new StackedColumnCollection(wasmContext);
  const series1 = new StackedColumnRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [2, 3, 4, 5, 6],
    }),
  });
  const series2 = new StackedColumnRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [1, 2, 3, 4, 5],
    }),
  });
  stackedColumnCollection.add(series1, series2);
  sciChartSurface.renderableSeries.add(stackedColumnCollection);
  return sciChartSurface;
};

// Initialize the mountain chart
const initMountainChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, 
  {
    theme: new SciChartJsNavyTheme(),
  });
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const mountainSeries = new FastMountainRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [5, 4, 3, 2, 1],
    }),
  });
  sciChartSurface.renderableSeries.add(mountainSeries);
  return sciChartSurface;
};

// Initialize the pie chart
const initPieChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, 
  {
    theme: new SciChartJsNavyTheme(),
  });
  const pieChart = new PieChart(wasmContext, {
    segments: [
      new PieSegment({ value: 30, title: "Segment 1" }),
      new PieSegment({ value: 20, title: "Segment 2" }),
      new PieSegment({ value: 50, title: "Segment 3" }),
    ],
  });
  sciChartSurface.renderableSeries.add(pieChart);
  return sciChartSurface;
};

// Dashboard component
const Dashboard = () => {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "20px" }}>
      {/* First row */}
      <div style={{ display: "flex", gap: "20px" }}>
        <div style={{ flex: 1 }}>
          <SciChartReact initChart={initLineChart} 
                 style={{ width: "100%", height: "400px" }} />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact initChart={initScatterChart} 
                 style={{ width: "100%", height: "400px" }} />
        </div>
      </div>

      {/* Second row */}
      <div style={{ display: "flex", gap: "20px" }}>
        <div style={{ flex: 1 }}>
          <SciChartReact initChart={initStackedColumnChart} 
                 style={{ width: "100%", height: "400px" }} />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact initChart={initMountainChart} 
                 style={{ width: "100%", height: "400px" }} />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact initChart={initPieChart} 
                 style={{ width: "100%", height: "400px" }} />
        </div>
      </div>
    </div>
  );
};

export default Dashboard;

Creating a Project in CodeSandbox

Let’s export this into an IDE. For the purpose of this tutorial we’ll use codesandbox which provides a ready-made IDE in browser with full npm, JavaScript and react support.

On the homepage of codesandbox, click ‘Create’ to create a new sandbox.

Choose React(TS) as a template. This will create a new react project with npm and TypeScript or JavaScript support.

In the dependencies section, add scichart and scichart-react. This is equivalent to npm install scichart scichart-react in your IDE. Package.json should update as follows:

Next, create a file called dashboard.jsx. Paste in the code outputted by the above prompt. NOTE the code is incorrect, as AI’s aren’t perfect yet, but we’ll make some minor changes to get it compiling.

Now, modify the default App.tsx to contain a <Dashboard/> component:

import "./styles.css";
import Dashboard from "./dashboard";

export default function App() {
  return (
    <div className="App">
      <Dashboard />
    </div>
  );
}

You should see something like this. Promising, but it isn’t quite working. In the next section we’ll work through the errors to get a working React Dashboard.

Getting the Dashboard Working

Let’s start working through the errors.

Error #1: Check types are correct

AIs such as ChatGPT or Deepseek often make subtle errors in syntax. This is because they are trained on the whole internet but may not have specific knowledge about a particular library like SciChart. These can be easily fixed with a little knowledge of the library and the scichart.js documentation.

For example, in dashboard.jsx, FastScatterRenderableSeries is incorrect – this should be XyScatterRenderableSeries. Check for other badly imported types or type errors. Codesandbox will point out syntax errors as well as have autocomplete (intellisense) for type information found in the SciChart library.

Error #2: Could not load SciChart WebAssembly module

Could not load SciChart WebAssembly module. Check your build process and ensure that your scichart2d.wasm, scichart2d.data and scichart2d.js files are from the same version

This error occurs because you need to either package wasm & data files or load them from CDN. You can find out how to do this here.

Add a call to SciChartSurface.loadWasmFromCDN() at the start of your Dashboard react component.

// Dashboard component
const Dashboard = () => {

  SciChartSurface.loadWasmFromCDN(); // Add this call
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "20px" }}>
      {/* First row */}
      <div style={{ display: "flex", gap: "20px" }}>
        <div style={{ flex: 1 }}>
        ...

Error #3: _scichart.PieChart is not a constructor

OK so DeepSeek has totally messed this one up, but no worry, we can find out the real syntax for creating a pie chart from the SciChart JavaScript Pie Chart demo.

Here’s the incorrect code outputted by AI:

// Initialize the pie chart
const initPieChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(
    rootElement,
    {
      theme: new SciChartJsNavyTheme(),
    }
  );
  const pieChart = new PieChart(wasmContext, {
    segments: [
      new PieSegment({ value: 30, title: "Segment 1" }),
      new PieSegment({ value: 20, title: "Segment 2" }),
      new PieSegment({ value: 50, title: "Segment 3" }),
    ],
  });
  sciChartSurface.renderableSeries.add(pieChart);
  return sciChartSurface;
};

And here’s the correct code.

const initPieChart = async (rootElement) => {
  const sciChartSurface = await SciChartPieSurface.create(rootElement, {
    theme: new SciChartJsNavyTheme(),
  });
  const pieChartData = [
    { value: 40, text: "Segment 1" },
    { value: 30, text: "Segment 2" },
    { value: 20, text: "Segment 3" },
    { value: 10, text: "Segment 4" },
  ];

  pieChartData.forEach((segment) =>
    sciChartSurface.pieSegments.add(new PieSegment(segment))
  );
  return sciChartSurface;
};

Error #4: “initChart” function should resolve to an object with “sciChartSurface” property ({ sciChartSurface })

This error is related to the use of scichart-react, which expects an initialization function <SciChartReact initChart={function}/> with a return value of { sciChartSurface }

Here’s the incorrect code for each of the charts that are initialized by AI:

// Initialize the line chart
const initLineChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
      theme: new SciChartJsNavyTheme(),
  });
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const lineSeries = new FastLineRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [2, 4, 6, 8, 10],
    }),
  });
  sciChartSurface.renderableSeries.add(lineSeries);
  return sciChartSurface; // this line is incorrect, 
  // modify to return { sciChartSurface }
};

And here’s how to correct it:

// Initialize the line chart
const initLineChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
      theme: new SciChartJsNavyTheme(),
  });
  // ... 
  return { sciChartSurface }; // This is the correct return value
};

Do this for each of the charts.

The complete React Dashboard

Hurrah! You should now have a working dashboard. It looks a bit bland but we’ll modify it in the next sections.

Here’s the working code for dashboard.jsx:

dashboard.jsx version #2 working dashboard

import React from "react";
import {
  SciChartSurface,
  NumericAxis,
  FastLineRenderableSeries,
  XyDataSeries,
  EllipsePointMarker,
  XyScatterRenderableSeries,
  StackedColumnCollection,
  StackedColumnRenderableSeries,
  FastMountainRenderableSeries,
  SciChartPieSurface,
  PieSegment,
  SciChartJsNavyTheme,
} from "scichart";
import { SciChartReact } from "scichart-react";

// Initialize the line chart
const initLineChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(
    rootElement,
    {
      theme: new SciChartJsNavyTheme(),
    }
  );
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const lineSeries = new FastLineRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [2, 4, 6, 8, 10],
    }),
  });
  sciChartSurface.renderableSeries.add(lineSeries);
  return { sciChartSurface };
};

// Initialize the scatter chart
const initScatterChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(
    rootElement,
    {
      theme: new SciChartJsNavyTheme(),
    }
  );
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const scatterSeries = new XyScatterRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [3, 5, 7, 9, 11],
    }),
    pointMarker: new EllipsePointMarker(wasmContext, { width: 10, height: 10 }),
  });
  sciChartSurface.renderableSeries.add(scatterSeries);
  return { sciChartSurface };
};

// Initialize the stacked column chart
const initStackedColumnChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(
    rootElement,
    {
      theme: new SciChartJsNavyTheme(),
    }
  );
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const stackedColumnCollection = new StackedColumnCollection(wasmContext);
  const series1 = new StackedColumnRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [2, 3, 4, 5, 6],
    }),
  });
  const series2 = new StackedColumnRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [1, 2, 3, 4, 5],
    }),
  });
  stackedColumnCollection.add(series1, series2);
  sciChartSurface.renderableSeries.add(stackedColumnCollection);
  return { sciChartSurface };
};

// Initialize the mountain chart
const initMountainChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(
    rootElement,
    {
      theme: new SciChartJsNavyTheme(),
    }
  );
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const mountainSeries = new FastMountainRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [5, 4, 3, 2, 1],
    }),
  });
  sciChartSurface.renderableSeries.add(mountainSeries);
  return { sciChartSurface };
};

// Initialize the pie chart
const initPieChart = async (rootElement) => {
  const sciChartSurface = await SciChartPieSurface.create(rootElement, {
    theme: new SciChartJsNavyTheme(),
  });
  const pieChartData = [
    { value: 40, text: "Segment 1" },
    { value: 30, text: "Segment 2" },
    { value: 20, text: "Segment 3" },
    { value: 10, text: "Segment 4" },
  ];

  pieChartData.forEach((segment) =>
    sciChartSurface.pieSegments.add(new PieSegment(segment))
  );
  return { sciChartSurface };
};

// Dashboard component
const Dashboard = () => {
  SciChartSurface.loadWasmFromCDN();
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "20px" }}>
      {/* First row */}
      <div style={{ display: "flex", gap: "20px" }}>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initLineChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initScatterChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
      </div>

      {/* Second row */}
      <div style={{ display: "flex", gap: "20px" }}>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initStackedColumnChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initMountainChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initPieChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
      </div>
    </div>
  );
};

export default Dashboard;

Adding Styles to the React Dashboard

SciChart themes are pretty powerful. The SciChartJsNavyTheme contains a set of predefined series colors which look good with the background color of the chart. However, for some series you’ll get an unimaginative grey when not setting series colors.

Let’s leverage Deepseek again to modify the code with a new prompt passing in the working code and requesting the changes.

I’ve modified the code you created to correct some errors. Namely, FastScatterRenderableSeries should be XyScatterRenderableSeries. initChart functions should return { sciChartSurface }. Pie charts should be created using ‘SciChartPieSurface.create’.

Here is my working code which renders a dashboard without errors

`
// PASTE THE WORKING DASHBOARD.JSX CODE IN HERE
`

I would like you to modify this code using pleasing pastel colors which work with the background color which is #22365B.

Choose stroke colors from the list #274b92, #47bde6, #ae418d, #e97064, #68bcae

Choose fill colors from the list #274b9288, #47bde688, #ae418d88, #e9706488, #68bcae88

Apply these to the following properties: FastLineRenderableSeries.stroke, FastMountainRenderableSeries.fill, StackedColumnRenderableSeries.stroke and fill, EllipsePointMarker.stroke and fill, PieSegment pass color to the object in the constructor.

Set the background to the body equal a darker shade which matches #22365B.

Because we’ve given the AI working code, it should modify it straight away without errors. Here’s the output dashboard.jsx with styles and colors.

dashboard.jsx version #3 with styles

import React from "react";
import {
  SciChartSurface,
  NumericAxis,
  FastLineRenderableSeries,
  XyDataSeries,
  EllipsePointMarker,
  XyScatterRenderableSeries,
  StackedColumnCollection,
  StackedColumnRenderableSeries,
  FastMountainRenderableSeries,
  SciChartPieSurface,
  PieSegment,
  SciChartJsNavyTheme,
} from "scichart";
import { SciChartReact } from "scichart-react";

// Define pastel colors
const strokeColors = ["#274b92", "#47bde6", "#ae418d", "#e97064", "#68bcae"];
const fillColors = ["#274b9288", "#47bde688", "#ae418d88", "#e9706488", "#68bcae88"];

// Initialize the line chart
const initLineChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, 
  {
    theme: new SciChartJsNavyTheme(),
  });
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const lineSeries = new FastLineRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [2, 4, 6, 8, 10],
    }),
    stroke: strokeColors[0], // Apply stroke color
  });
  sciChartSurface.renderableSeries.add(lineSeries);
  return { sciChartSurface };
};

// Initialize the scatter chart
const initScatterChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, 
  {
    theme: new SciChartJsNavyTheme(),
  });
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const scatterSeries = new XyScatterRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [3, 5, 7, 9, 11],
    }),
    pointMarker: new EllipsePointMarker(wasmContext, {
      width: 10,
      height: 10,
      stroke: strokeColors[1], // Apply stroke color
      fill: fillColors[1], // Apply fill color
    }),
  });
  sciChartSurface.renderableSeries.add(scatterSeries);
  return { sciChartSurface };
};

// Initialize the stacked column chart
const initStackedColumnChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, 
  {
    theme: new SciChartJsNavyTheme(),
  });
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const stackedColumnCollection = new StackedColumnCollection(wasmContext);
  const series1 = new StackedColumnRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [2, 3, 4, 5, 6],
    }),
    stroke: strokeColors[2], // Apply stroke color
    fill: fillColors[2], // Apply fill color
  });
  const series2 = new StackedColumnRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [1, 2, 3, 4, 5],
    }),
    stroke: strokeColors[3], // Apply stroke color
    fill: fillColors[3], // Apply fill color
  });
  stackedColumnCollection.add(series1, series2);
  sciChartSurface.renderableSeries.add(stackedColumnCollection);
  return { sciChartSurface };
};

// Initialize the mountain chart
const initMountainChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, 
  {
    theme: new SciChartJsNavyTheme(),
  });
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const mountainSeries = new FastMountainRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [5, 4, 3, 2, 1],
    }),
    fill: fillColors[4], // Apply fill color
  });
  sciChartSurface.renderableSeries.add(mountainSeries);
  return { sciChartSurface };
};

// Initialize the pie chart
const initPieChart = async (rootElement) => {
  const sciChartSurface = await SciChartPieSurface.create(rootElement, {
    theme: new SciChartJsNavyTheme(),
  });
  const pieChartData = [
    { value: 40, text: "Segment 1", color: strokeColors[0] },
    { value: 30, text: "Segment 2", color: strokeColors[1] },
    { value: 20, text: "Segment 3", color: strokeColors[2] },
    { value: 10, text: "Segment 4", color: strokeColors[3] },
  ];

  pieChartData.forEach((segment) =>
    sciChartSurface.pieSegments.add(new PieSegment(segment))
  );
  return { sciChartSurface };
};

// Dashboard component
const Dashboard = () => {
  SciChartSurface.loadWasmFromCDN();
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "20px", 
               backgroundColor: "#1a2a4a", padding: "20px" }}>
      {/* First row */}
      <div style={{ display: "flex", gap: "20px" }}>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initLineChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initScatterChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
      </div>

      {/* Second row */}
      <div style={{ display: "flex", gap: "20px" }}>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initStackedColumnChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initMountainChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initPieChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
      </div>
    </div>
  );
};

export default Dashboard;

This is looking a lot better!

Adding a Legend and Tooltips

The AI chat history should now have a working piece of code in it. If it doesn’t, fix the code and include it in your prompt.

Now we’re going to add a legend and tooltips to the chart. It’s actually pretty easy to do this but I want to show the power of using generating AI tools like Chat GPT or Deepseek to modify the code.

Start a new prompt:

Here is my current working code which renders a dashboard without errors:

`
// PASTE YOUR CURRENT WORKING CODE HERE
`

Modify this code as follows.

    1. For each SciChartSurface which is not a SciChartPieSurface, add a Legend using the LegendModifier
    2. For each XyDataSeries, set the dataSeriesName property to a dummy string.
    3. For each SciChartSurface which is not a SciChartPieSurface, add a Tooltip using the RolloverModifier. set showRolloverLine: true and showTooltip: true
    4. For each SciChartSurface which is not a SciChartPieSurface, add mouse wheel, zoompan and zoom extents modifiers

Deepseek AI gets straight to work and outputs some new code:

Let’s update dashboard.jsx with the new code:

Final dashboard.jsx version #4 with tooltips, legends, zooming

import React from "react";
import {
  SciChartSurface,
  NumericAxis,
  FastLineRenderableSeries,
  XyDataSeries,
  EllipsePointMarker,
  XyScatterRenderableSeries,
  StackedColumnCollection,
  StackedColumnRenderableSeries,
  FastMountainRenderableSeries,
  SciChartPieSurface,
  PieSegment,
  SciChartJsNavyTheme,
  LegendModifier,
  RolloverModifier,
  MouseWheelZoomModifier,
  ZoomPanModifier,
  ZoomExtentsModifier,
} from "scichart";
import { SciChartReact } from "scichart-react";

// Define pastel colors
const strokeColors = ["#274b92", "#47bde6", "#ae418d", "#e97064", "#68bcae"];
const fillColors = [
  "#274b9288",
  "#47bde688",
  "#ae418d88",
  "#e9706488",
  "#68bcae88",
];

// Initialize the line chart
const initLineChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(
    rootElement,
    {
      theme: new SciChartJsNavyTheme(),
    }
  );
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const lineSeries = new FastLineRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [2, 4, 6, 8, 10],
      dataSeriesName: "Line Series", // Set dataSeriesName
    }),
    stroke: strokeColors[0], // Apply stroke color
  });
  sciChartSurface.renderableSeries.add(lineSeries);

  // Add modifiers
  sciChartSurface.chartModifiers.add(new LegendModifier());
  sciChartSurface.chartModifiers.add(
    new RolloverModifier({ showRolloverLine: true, showTooltip: true })
  );
  sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
  sciChartSurface.chartModifiers.add(new ZoomPanModifier());
  sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());

  return { sciChartSurface };
};

// Initialize the scatter chart
const initScatterChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(
    rootElement,
    {
      theme: new SciChartJsNavyTheme(),
    }
  );
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const scatterSeries = new XyScatterRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [3, 5, 7, 9, 11],
      dataSeriesName: "Scatter Series", // Set dataSeriesName
    }),
    pointMarker: new EllipsePointMarker(wasmContext, {
      width: 10,
      height: 10,
      stroke: strokeColors[1], // Apply stroke color
      fill: fillColors[1], // Apply fill color
    }),
  });
  sciChartSurface.renderableSeries.add(scatterSeries);

  // Add modifiers
  sciChartSurface.chartModifiers.add(new LegendModifier());
  sciChartSurface.chartModifiers.add(
    new RolloverModifier({ showRolloverLine: true, showTooltip: true })
  );
  sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
  sciChartSurface.chartModifiers.add(new ZoomPanModifier());
  sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());

  return { sciChartSurface };
};

// Initialize the stacked column chart
const initStackedColumnChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(
    rootElement,
    {
      theme: new SciChartJsNavyTheme(),
    }
  );
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const stackedColumnCollection = new StackedColumnCollection(wasmContext);
  const series1 = new StackedColumnRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [2, 3, 4, 5, 6],
      dataSeriesName: "Stacked Column Series 1", // Set dataSeriesName
    }),
    stroke: strokeColors[2], // Apply stroke color
    fill: fillColors[2], // Apply fill color
  });
  const series2 = new StackedColumnRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [1, 2, 3, 4, 5],
      dataSeriesName: "Stacked Column Series 2", // Set dataSeriesName
    }),
    stroke: strokeColors[3], // Apply stroke color
    fill: fillColors[3], // Apply fill color
  });
  stackedColumnCollection.add(series1, series2);
  sciChartSurface.renderableSeries.add(stackedColumnCollection);

  // Add modifiers
  sciChartSurface.chartModifiers.add(new LegendModifier());
  sciChartSurface.chartModifiers.add(
    new RolloverModifier({ showRolloverLine: true, showTooltip: true })
  );
  sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
  sciChartSurface.chartModifiers.add(new ZoomPanModifier());
  sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());

  return { sciChartSurface };
};

// Initialize the mountain chart
const initMountainChart = async (rootElement) => {
  const { sciChartSurface, wasmContext } = await SciChartSurface.create(
    rootElement,
    {
      theme: new SciChartJsNavyTheme(),
    }
  );
  const xAxis = new NumericAxis(wasmContext);
  const yAxis = new NumericAxis(wasmContext);
  sciChartSurface.xAxes.add(xAxis);
  sciChartSurface.yAxes.add(yAxis);

  const mountainSeries = new FastMountainRenderableSeries(wasmContext, {
    dataSeries: new XyDataSeries(wasmContext, {
      xValues: [1, 2, 3, 4, 5],
      yValues: [5, 4, 3, 2, 1],
      dataSeriesName: "Mountain Series", // Set dataSeriesName
    }),
    fill: fillColors[4], // Apply fill color
  });
  sciChartSurface.renderableSeries.add(mountainSeries);

  // Add modifiers
  sciChartSurface.chartModifiers.add(new LegendModifier());
  sciChartSurface.chartModifiers.add(
    new RolloverModifier({ showRolloverLine: true, showTooltip: true })
  );
  sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
  sciChartSurface.chartModifiers.add(new ZoomPanModifier());
  sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());

  return { sciChartSurface };
};

// Initialize the pie chart
const initPieChart = async (rootElement) => {
  const sciChartSurface = await SciChartPieSurface.create(rootElement, {
    theme: new SciChartJsNavyTheme(),
  });
  const pieChartData = [
    { value: 40, text: "Segment 1", color: strokeColors[0] },
    { value: 30, text: "Segment 2", color: strokeColors[1] },
    { value: 20, text: "Segment 3", color: strokeColors[2] },
    { value: 10, text: "Segment 4", color: strokeColors[3] },
  ];

  pieChartData.forEach((segment) =>
    sciChartSurface.pieSegments.add(new PieSegment(segment))
  );

  return { sciChartSurface };
};

// Dashboard component
const Dashboard = () => {
  SciChartSurface.loadWasmFromCDN();
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: "20px",
        backgroundColor: "#1a2a4a",
        padding: "20px",
      }}
    >
      {/* First row */}
      <div style={{ display: "flex", gap: "20px" }}>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initLineChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initScatterChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
      </div>

      {/* Second row */}
      <div style={{ display: "flex", gap: "20px" }}>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initStackedColumnChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initMountainChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
        <div style={{ flex: 1 }}>
          <SciChartReact
            initChart={initPieChart}
            style={{ width: "100%", height: "400px" }}
          />
        </div>
      </div>
    </div>
  );
};

export default Dashboard;

Here’s the (almost final) dashboard result with legend, tooltip and zooming interactions.

Final Tweaking to the Dashboard Example

There’s a little bit of tweaking we need to do here, but the code functionally works. Namely if you hover the chart you’ll see some tooltips are very bright with white text and can’t be read.

This is because the RolloverModifier by default uses the RenderableSeries.stroke as a tooltip container colour, and the foreground of the container is always white.

You can change this using the RenderableSeries.rolloverModifierProps property which allows setting of tooltip styles on a per-series basis.

Adjust the code one last time:

// Initialize the scatter chart
const initScatterChart = async (rootElement) => {
  // ... 
  // after the declaration of scatterSeries, set rollover props

  scatterSeries.rolloverModifierProps.tooltipTextColor = "#333";
  // ...
}


// Initialize the mountain chart
const initMountainChart = async (rootElement) => {
  // ... 
  // after the declaration of mountainSeries, set rollover props

  mountainSeries.rolloverModifierProps.tooltipTextColor = "#333";
  // ...
}

That should be it! Here’s the final working dashboard with React Line Chart, React Scatter Chart, React Stacked Column Chart and React Pie Chart below:

And here’s the Codesandbox. If you want to edit this in browser, click ‘Open Sandbox’ and create your own fork of this example.

Conclusion

How the final React Dashboard Works

The code in this tutorial creates a dashboard with multiple SciChart visualizations using React. Let’s break it down step by step:

  1. Imports & Setup:
    • Imports necessary SciChart components (chart types, axes, series, modifiers)
    • Defines color palettes for consistent styling
    • Uses SciChartReact wrapper component for React integration, for correct react component lifecycle
  2. Chart Initialization Functions:
    Each chart type has its own initialization function that:

    • Creates a SciChartSurface with a dark theme
    • Adds X/Y axes
    • Configures data series and visual styling
    • Adds interactive features (zoom, pan, legend, tooltips)
    • Returns the chart surface for React to manage
  3. Chart Types Demonstrated:
    • Line Chart: Simple line graph with FastLineRenderableSeries
    • Scatter Plot: Uses XyScatterRenderableSeries with circular markers
    • Stacked Columns: Multiple column series combined in StackedColumnCollection
    • Mountain Chart: Area chart using FastMountainRenderableSeries
    • Pie Chart: Created with SciChartPieSurface and PieSegment
  4. Interactive Features (via Chart Modifiers):
    • LegendModifier: Shows data series legend
    • RolloverModifier: Tooltips on hover
    • MouseWheelZoomModifier: Zoom with scroll wheel
    • ZoomPanModifier: Drag to pan
    • ZoomExtentsModifier: Double-click to reset zoom
  5. Dashboard Layout:
    • Uses flexbox for responsive grid layout
    • First row has 2 charts (line + scatter)
    • Second row has 3 charts (stacked columns + mountain + pie)
    • Each chart is wrapped in SciChartReact component with initialization function
  6. Key React-SciChart Integration:
    • SciChartReact handles component lifecycle (mount/unmount)
    • initChart prop passes the initialization function
    • WASM library loaded once from CDN using loadWasmFromCDN()
  7. Styling:
    • Consistent navy theme across all charts
    • Pastel color palette defined at top
    • Responsive sizing using percentage-based dimensions
    • Dark background container for the dashboard

This code achieves a responsive dashboard with 5 different chart types, interactive visualization features (zoom, tooltips, panning), consistent theming and styling, efficient React integration with SciChart’s WebAssembly rendering and demonstrates multiple chart types working together.

As an user, you can now modify the data series values/format, adjust styling through color arrays and chart properties, rearrange the dashboard layout, add/remove chart modifiers or create new chart types using different renderable series.

Remember that SciChart requires WebAssembly (WASM), which is why we use async initialization and the loadWasmFromCDN() call.

Further Work

What else could you do with this?

Here are some ideas to explore both with generative-AI and by going through the SciChart documentation.

  1. Experiment with adding hover behaviours and triggering on-selected drilldowns using the SeriesSelectionModifier
  2. Adding grid splitters between the charts and enabling dynamic responsive dashboards for mobile as well as web views.
  3. Experimenting with dynamic data and real-time updates as SciChart excels in this area.

Final Comments about Deepseek and Generative AI

Generative AI has come a long way since the original version of Chat GPT two years ago. It is now quite a competent coder and able to understand complex concepts, capable of developing dashboards rapidly using libraries like SciChart.js and scichart-react.

While the code it produces isn’t perfect, and does contain errors, a competent developer combined with the solid documentation & examples that SciChart has to offer can create code quickly and make rapid progress in applications.

Where to learn more

 

By Andrew Burnett-Thompson | Jan 25, 2025
CEO / Founder of SciChart. Masters (MEng) and PhD in Electronics & Signal Processing.Follow me on LinkedIn for more SciChart content, or twitter at @drandrewbt.

Leave a Reply