Dev.to AI 🤖 Ai 👁 0 📖 20 min read

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

In this tutorial, we'll walk through creating a fully interactive, dynamic dashboard in React with SciChart.js in 20 minutes, coding almost entirely with AI. The dashboard features five chart types: a React Line Chart, R

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

In this tutorial, we'll walk through creating a fully interactive, dynamic dashboard in React with SciChart.js in 20 minutes, coding almost entirely with AI. The dashboard features five chart types: a 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 in a consistent layout. By the end, you'll have a fully functional React dashboard you can customise for data visualisation in any domain.

Introduction

Data visualisation is a critical part of modern web applications, helping users understand complex data at a glance. With a powerful React chart library like SciChart.js, developers can create stunning, high-performance visualisations with ease. Combined with React, a popular JavaScript library for building user interfaces and interactive dashboards, the possibilities are endless.

In this tutorial, we'll build a dynamic dashboard that showcases five chart types in a single view. The dashboard is interactive, with tooltips, legends, and zooming and panning so you can inspect data on the fly. We'll also apply SciChart.js's Navy theme for a sleek, professional look.

We'll show the power of generative AI for building this React dashboard layout using Deepseek R1, an open-source competitor to ChatGPT, including the prompts we used and the changes needed to get the dashboard working. The whole tutorial is coded in CodeSandbox.

Key Takeaways

  • How to integrate SciChart.js into a React application
  • Creating and customising five 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
  • Adding legends, zooming, panning and tooltips
  • The limitations, pros and cons of using AI such as ChatGPT or Deepseek to create React dashboards, and where this technology could go next

Who Is This For?

  • Frontend developers looking to improve their data visualisation skills
  • React developers interested in integrating advanced charting libraries
  • Data enthusiasts who want to build interactive dashboards for data analysis

Getting Started

Creating the Input Prompt

We start by using Deepseek, an open-source competitor to ChatGPT that scores highly in coding benchmarks and runs at a fraction of the cost of OpenAI's solutions.

Here's 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'

The first prompt entered into Deepseek

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

Deepseek's output for the first prompt

The first output from Deepseek was good, but slightly incorrect. We'll correct it later. Here's 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 move this into an IDE. For this tutorial we'll use CodeSandbox, which provides a ready-made in-browser IDE with full npm, JavaScript and React support.

On the CodeSandbox homepage, click Create to create a new sandbox.

Creating a new sandbox in CodeSandbox

Choose React (TS) as the template. This creates a new React project with npm and TypeScript or JavaScript support.

Choosing the React TS template in CodeSandbox

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

Adding scichart and scichart-react dependencies in CodeSandbox

Next, create a file called dashboard.jsx and paste in the code from the prompt above. Note that the code is incorrect, as AI isn'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 not quite working yet. In the next section we'll work through the errors to get a working React dashboard.

The first dashboard attempt showing errors in CodeSandbox

Getting the Dashboard Working

Let's work through the errors.

Error #1: Check types are correct

AI tools such as ChatGPT or Deepseek often make subtle syntax errors. They're trained on the whole internet but may not have specific knowledge of a particular library like SciChart. These are easily fixed with a little knowledge of the library and the SciChart.js documentation.

For example, in dashboard.jsx, FastScatterRenderableSeries is incorrect and should be XyScatterRenderableSeries. Check for other badly imported types or type errors. CodeSandbox highlights syntax errors and offers autocomplete (IntelliSense) for types 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 the wasm and data files or load them from a CDN. You can find out how in the documentation on deploying Wasm and data files.

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

Deepseek got this one completely wrong, but no worries. We can find the real syntax for creating a pie chart in the SciChart JavaScript Pie Chart demo.

Here's the incorrect code from the 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 relates to scichart-react, which expects an initialisation function <SciChartReact initChart={function}/> that returns { sciChartSurface }.

Here's the incorrect code the AI generated for each chart:

// 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 improve it in the next sections.

The first working React dashboard

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. SciChartJsNavyTheme contains a set of predefined series colours that look good against the chart background. However, some series default to an unimaginative grey when no colours are set.

Let's use Deepseek again 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.

Deepseek's output for the styling prompt

Because we gave the AI working code, it modifies it straight away without errors. Here's the output dashboard.jsx with styles and colours:

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!

The styled React dashboard with pastel colours

Adding a Legend and Tooltips

The AI chat history should now contain working code. If it doesn't, fix the code and include it in your prompt.

Next, we'll add a legend and tooltips to the charts. This is actually pretty easy to do by hand, but it's a good way to show the power of generative AI tools like ChatGPT or Deepseek for modifying 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 gets straight to work and outputs some new code:

Deepseek's output adding legends, tooltips and zoom modifiers

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

Final dashboard.jsx version #4 (with tooltips, legends and 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 with legends, tooltips and zooming interactions:

React dashboard with legends and tooltips

Final Tweaks to the Dashboard

There's a little tweaking left, but the code works. If you hover over the charts, you'll notice some tooltips are very bright with white text that can't be read.

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

You can change this with the RenderableSeries.rolloverModifierProps property, which lets you set tooltip styles per series.

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 a React line chart, scatter chart, stacked column chart, mountain chart and pie chart:

The final interactive React dashboard

And here's the CodeSandbox. To edit it in your browser, click Open Sandbox and create your own fork.

Conclusion

How the Final React Dashboard Works

The code in this tutorial creates a dashboard with multiple SciChart visualisations using React. Here's how it breaks down:

  1. Imports & setup
    • Imports the necessary SciChart components (chart types, axes, series, modifiers)
    • Defines colour palettes for consistent styling
    • Uses the SciChartReact wrapper component for React integration and correct component lifecycle
  2. Chart initialisation functions. Each chart type has its own initialisation 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: a simple line graph with FastLineRenderableSeries
    • Scatter plot: uses XyScatterRenderableSeries with circular markers
    • Stacked columns: multiple column series combined in a StackedColumnCollection
    • Mountain chart: an area chart using FastMountainRenderableSeries
    • Pie chart: created with SciChartPieSurface and PieSegment
  4. Interactive features (via chart modifiers)
    • LegendModifier: shows the data series legend
    • RolloverModifier: tooltips on hover
    • MouseWheelZoomModifier: zoom with the scroll wheel
    • ZoomPanModifier: drag to pan
    • ZoomExtentsModifier: double-click to reset zoom
  5. Dashboard layout
    • Uses flexbox for a responsive grid layout
    • The first row has 2 charts (line and scatter)
    • The second row has 3 charts (stacked columns, mountain and pie)
    • Each chart is wrapped in a SciChartReact component with its initialisation function
  6. Key React-SciChart integration
    • SciChartReact handles the component lifecycle (mount/unmount)
    • The initChart prop passes in the initialisation function
    • The WASM library is loaded once from CDN using loadWasmFromCDN()
  7. Styling
    • A consistent navy theme across all charts
    • A pastel colour palette defined at the top
    • Responsive sizing using percentage-based dimensions
    • A dark background container for the dashboard

The result is a responsive dashboard with five chart types, interactive features (zoom, tooltips, panning), consistent theming and styling, and efficient React integration with SciChart's WebAssembly rendering.

From here, you can modify the data series values and format, adjust styling through the colour arrays and chart properties, rearrange the layout, add or remove chart modifiers, or create new chart types using different renderable series.

Remember that SciChart requires WebAssembly (WASM), which is why we use async initialisation 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 working through the SciChart documentation:

  1. Experiment with hover behaviours and on-select drilldowns using the SeriesSelectionModifier
  2. Add grid splitters between the charts and enable dynamic, responsive dashboards for mobile as well as web
  3. Experiment with dynamic data and real-time updates, an area where SciChart excels

Final Comments on Deepseek and Generative AI

Generative AI has come a long way since ChatGPT first launched in late 2022. It's now a competent coder that understands complex concepts and can develop dashboards rapidly with libraries like SciChart.js and scichart-react.

While the code it produces isn't perfect and does contain errors, a competent developer combined with SciChart's solid documentation and examples can write code quickly and make rapid progress on applications.

Where to Learn More

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.