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
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.initChartshould 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
SciChartJsNavyThemeto 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, correctly recommending npm install scichart scichart-react. It then provides JSX output to include in your application.
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.
Choose React (TS) as the template. This creates a new React project with npm and TypeScript or JavaScript support.
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:
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.
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.
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 HEREI 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 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!
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 HEREModify this code as follows.
- For each SciChartSurface which is not a SciChartPieSurface, add a Legend using the LegendModifier
- For each XyDataSeries, set the dataSeriesName property to a dummy string.
- For each SciChartSurface which is not a SciChartPieSurface, add a Tooltip using the RolloverModifier. set showRolloverLine: true and showTooltip: true
- 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:
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:
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:
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:
-
Imports & setup
- Imports the necessary SciChart components (chart types, axes, series, modifiers)
- Defines colour palettes for consistent styling
- Uses the
SciChartReactwrapper component for React integration and correct component lifecycle
-
Chart initialisation functions. Each chart type has its own initialisation function that:
- Creates a
SciChartSurfacewith 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
- Creates a
-
Chart types demonstrated
-
Line chart: a simple line graph with
FastLineRenderableSeries -
Scatter plot: uses
XyScatterRenderableSerieswith circular markers -
Stacked columns: multiple column series combined in a
StackedColumnCollection -
Mountain chart: an area chart using
FastMountainRenderableSeries -
Pie chart: created with
SciChartPieSurfaceandPieSegment
-
Line chart: a simple line graph with
-
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
-
-
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
SciChartReactcomponent with its initialisation function
-
Key React-SciChart integration
-
SciChartReacthandles the component lifecycle (mount/unmount) - The
initChartprop passes in the initialisation function - The WASM library is loaded once from CDN using
loadWasmFromCDN()
-
-
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:
- Experiment with hover behaviours and on-select drilldowns using the
SeriesSelectionModifier - Add grid splitters between the charts and enable dynamic, responsive dashboards for mobile as well as web
- 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
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.










