
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.
- 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 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:
- 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
- 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
- Creates a
- 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
andPieSegment
- Line Chart: Simple line graph with
- Interactive Features (via Chart Modifiers):
LegendModifier
: Shows data series legendRolloverModifier
: Tooltips on hoverMouseWheelZoomModifier
: Zoom with scroll wheelZoomPanModifier
: Drag to panZoomExtentsModifier
: Double-click to reset zoom
- 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
- Key React-SciChart Integration:
SciChartReact
handles component lifecycle (mount/unmount)initChart
prop passes the initialization function- WASM library loaded once from CDN using
loadWasmFromCDN()
- 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.
- Experiment with adding hover behaviours and triggering on-selected drilldowns using the
SeriesSelectionModifier
- Adding grid splitters between the charts and enabling dynamic responsive dashboards for mobile as well as web views.
- 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
- Deepseek official page
- Deepseek vs Chat GPT: a comprehensive comparison
- SciChart-react: An open source React Component wrapper for SciChart.js
- SciChart.js: an overview of features and capabilities for high performance datavisualization
- The SciChart.js documentation, including tutorials and more
Recent Blogs