What are React highcharts and why are they used?
React Highcharts simply started as a charting tool that was used for monitoring snow depth near the owner’s house in Norway. The tool quickly became one of the most famous visualization libraries. It provides the user with a lot of great built-in interactive features and is easy to use.
In this document, we are going to learn how to build a simple e-commerce dashboard with cube.js and react highcharts. We will be using the main Highcharts library, as well as Maps, stock, and Solid Gauge modules.
It is important to keep in mind that react highchart libraries are available under different licenses, depending on whether it is intended for commercial/government use, or for personal or non-profit projects. Make sure to check its license page.
Prerequisites to build the dashboard:
1) Database with sample data
2) Cube.js backend in order to handle communications between our database and the frontend
3) The frontend application
4) Create react app build
Analytics Backend-
We are going to use a PostgreSQL database and an example of an e-commerce dataset.
Use the code given below to download and import the example dataset.
$ curl http://cube.dev/downloads/ecom-dump.sql > ecom-dump.sql
$ createdb ecom
$ psql –dbname ecom -f ecom-dump.sql
The next step is to install the Cube.js CLI and create a new project
$ npm -g install cubejs-cli
$ cubejs create highcharts -d postgres
The cube.js uses environment variables inside the.env file for configuration. Update the contents of the .env file with your own database credentials.
CUBEJS_DB_NAME=ecom
CUBEJS_DB_TYPE=postgres
CUBEJS_API_SECRET=SECRET
Now let us begin with the Cube.js backend.
$ npm run dev
At this step, you can fine the Cube.js playground on the link http://localhost:4000.
Here we can see all the tables from our database, and we can choose any of them to generate the schema.
The Cube.js Data Schema concept is based on multidimensional analysis and should look familiar to those with experience in OLAP cubes.
The two main entities are measures and dimensions. Dimensions are the “as is” properties that we get from our database, but measures are results of aggregation operation like count, sum, average, and others.
In this example, we need an orders and users table. Check this and click on “Generate Schema”. Cube.js will then generate Orders.js and Users.js files inside the schema folder.
Cube.js data schema is javascript code and can be easily edited. You can also dynamically generate schema, if needed.
Let’s update the schema/Users.js file.
We will only keep the state, id dimensions and count measure because we will need to use them in our example.
cube(`Users`, {
sql: `SELECT * FROM public.users`,
dimensions: {
state: {
sql: `state`,
type: `string`
},
id: {
sql: `id`,
type: `number`,
primaryKey: true
}
}
});
That’s it for our backend. We have configured the database and created the Cube.js. backend.
After this, we are ready to start working on our frontend application.
Frontend Dashboard with React Highcharts
Let us generate our app with Cube.js templates. Navigate to the Dashboard App tab and select “Create custom application” with React and Ant Design.
Creating the dashboard app and installing dependencies will take some time. Once it is finished, the dashboard-app folder should be visible inside the project folder.
Next, let us install the dependencies we will need. Run the following commands in the dashboard-app folder.
$ cd dashboard-app
$ npm install –save highcharts highcharts-react-official @highcharts/map-collection
The above-mentioned command installs the following dependencies:
– Highcharts
– Highcharts React wrapper
– Highcharts map collection for our map chart wrapper.
You can feel free to remove all the files inside the src folder and the page folder, as well as update the dashboard/index.js file with the following content.
import React from ‘react’;
import ReactDOM from ‘react-dom’;
import ‘./index.css’;
import App from ‘./App’;
import * as serviceWorker from ‘./serviceWorker’;
ReactDOM.render(
<React.StrictMode>
<App></App>
</React.StrictMode>,
document.getElementById(‘root’)
);
serviceWorker.unregister();
The application we build will have the following structure:
– App as the main app component
– A Dashboard component that stores data and manages the app state
– Map, Line, Stock and other chart components that manage chart render according to applications data and state.
Let us create the <Dashboard/> component in the dashboard-app/src/components/Dashboards.js file with the following content.
We will create the <Map/> component later.
import React from ‘react’;
import { Layout } from ‘antd’;
import { useCubeQuery } from ‘@cubejs-client/react’;
import Map from ‘./Map’;
const Dashboard = () => {
const { resultSet } = useCubeQuery({
measures: [‘Orders.count’],
dimensions: [‘Users.state’],
timeDimensions: [
{
dimension: ‘Orders.createdAt’,
dateRange: ‘last year’,
},
],
});
if (!resultSet) {
return “Loading…”;
}
const data = regions.tablePivot().map(item => [item[‘Users.state’], parseInt(item[‘Orders.count’])])
return (
<Layout>
<Map data={data} />
</Layout>
);
};
export default Dashboard;
In the above snippet, we performed multiple steps. We imported the useCubeQuery React hook first.
import { useCubeQuery } from “@cubejs-client/react”;
The next step is to render the amount of orders in each state. To do this, we need to change the data into Highcharts’ format, where the first element is the state key and the second element is the value.
[
[“us-ca”,967],
[“us-ny”,283],
[“us-wa”,239],
[“us-il”,205],
[“us-tx”,190]
]
We are using resultSet.tablePivot() to access data returned from the backend and to prepare it for rendering.
const data = regions.tablePivot().map(item => [item[‘Users.state’], parseInt(item[‘Orders.count’])])
Now, we are ready to padd our data to the Map chart.
Let us create a new dashboard-app/src/components/Maps.js file with the following content.
import React, { useState, useEffect } from ‘react’;
import Highcharts from ‘highcharts’;
import HighchartsReact from ‘highcharts-react-official’;
import highchartsMap from ‘highcharts/modules/map’;
import mapDataIE from ‘@highcharts/map-collection/countries/us/us-all.geo.json’;
highchartsMap(Highcharts);
const staticOptions = {
chart: {
styledMode: true,
},
credits: {
enabled: false,
},
title: {
text: ‘Orders by region<small>Highcharts Map API</small>’,
useHTML: true,
},
colorAxis: {
min: 0,
},
tooltip: {
headerFormat: ”,
pointFormat: `
<b>{point.name}</b>: {point.value}`,
},
colorAxis: {
minColor: ‘#FFEAE4’,
maxColor: ‘#FF6492’,
},
series: [
{
name: ‘Basemap’,
mapData: mapDataIE,
borderColor: ‘#FFC3BA’,
borderWidth: 0.5,
nullColor: ‘#FFEAE4’,
showInLegend: false,
allowPointSelect: true,
dataLabels: {
enabled: true,
format: ‘{point.name}’,
color: ‘#000’,
},
states: {
select: {
borderColor: ‘#B5ACFF’,
color: ‘#7A77FF’,
},
},
},
],
};
export default ({ data }) => {
const [options, setOptions] = useState({});
useEffect(() => {
setOptions({
…staticOptions,
series: [
{
…staticOptions.series[0],
data: data,
},
],
});
}, [data]);
return (
<HighchartsReact
highcharts={Highcharts}
constructorType={‘mapChart’}
options={options}
/>
);
};
Inside the Map.js file, we imported useState, useEffect hooks and a bunch of Highcharts components. Then, we defined chart options based on Highcharts Map API specs.
In the staticOptions, we can set map styling, source, data, event handlers and other options.
Highcharts has a wide selection of SVG maps to use.
Lastly, we merged our staticOptions and props.data and then passed it to the Highcharts component.
That’s all for our <Map/> component.
Now, we just need to update the ‘dashboard-app/App.js’ to include the <Dashboard/> component:
+ import Dashboard from ‘./components/Dashboard’;
– <Header />
– <Layout.Content>{children}</Layout.Content>
+ <Dashboard />
After this, we are ready to see our first chart!
Visit the site http://localhost:3000 in your browser, and the map chart that we just built should be visible there.