React Highcharts example

React Highcharts example

In this post I show a React Highcharts example to demostrate how I’m using Highcharts with React in my data visualization projects. Assuming you are starting from scratch I’ll go from start to end. If you already have an app created then you can skip the set up section.

The entire project can be cloned and run from the Github repo.

Set up a new React app

The first step is to create a new React app by running the Create React App command. There are a number of different ways to create a new React app, but for simplicity we will use CRA here.

npx create-react-app react-highcharts-example

Once that’s complete, move into the app directory and install the Highchart dependencies. The below script installs the latest version of the Highcharts library as well as the official Highcharts React wrapper package. I’ve also included Bootstrap in this project to help with the display.

npm install highcharts highcharts-react-official bootstrap react-bootstrap

Now run npm start and you should have a working minimal React site running on http://localhost:3000/

Create the chart component

Start by creating a new component called Chart.js inside the src folder. All the work for this example is done in the Chart.js component. This work can be broken down into multiple sub-components and services, but for the example it is easier to show in a single component.

The component renders a dataset that displays the average temperature in Minneapolis for each month of the year from the year 2021. I’m getting this data from the Regional Climate Center web services (RCC ACIS). You’re most likely rendering data from an API, so I’ve include a fetch method as well as a template for how to wait for the fetch method to complete in the code below.

When the component renders for the first time we make a call to the RCC ACIS web service to get the average temperatures for each month of 2021. Using JavaScript async/await the app waits until the API promise resolves before continuing on. You can have multiple series rendered within a single chart, so the Series property of the Highcharts Options object expects an array of arrays where each series is it’s own array. The data that’s returned from the API is not in a state to automatically apply as a series so I do some manipulation to get the data in the right format for Highcharts to consume.

This is the entire component code below, I’ve commented the important parts of the code in more detail to describe each part’s purpose.

import React, { useEffect, useState } from "react";
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';

///
//Import necessary Highcharts dependencies
///
import Highcharts from 'highcharts'
import HighchartsReact from 'highcharts-react-official'
import HighchartsMore from 'highcharts/highcharts-more';
import HC_exporting from 'highcharts/modules/exporting'

HighchartsMore(Highcharts);
HC_exporting(Highcharts);

function Chart() {
    
    ///
    ///Create and set up two state variables. Options holds the options for the Highcharts
    ///component and isLoading keeps that state of the fetch request
    const [options, setOptions] = useState(null);
    const [isLoading, setIsLoading] = useState(true);
    const url = "https://data.rcc-acis.org/StnData";

    useEffect(() => {
        setIsLoading(true);
        
        ///
        /// Create a variable for the fetchRecords method so that we can use async/await
        /// The query parts are specific to the RCC endpoint
        const fetchRecords = async () => {
            const query = {
                elems: [
                    {
                        interval: "mly",
                        duration: 1,
                        name: "avgt",
                        reduce: { "reduce": "mean" },
                        prec: 3
                    }],
                sid: "MSPthr 9",
                sDate: "2021-01-01",
                eDate: "2021-12-31",
                meta: ["name", "state", "sids"]
            }

            const response = await fetch(url, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                redirect: 'follow',
                body: JSON.stringify(query)
            });

            const responseData = await response.json();

            ///
            /// After the retch request returns go through the each item in the array to assign
            /// categories and create an array to be used as the series data source
            ///
            const categories = [];
            const seriesData = [];
            responseData.data.map((item) => {
                categories.push(item[0]);
                seriesData.push(parseInt(item[1]));
            });

            ///
            /// Setting the Highcharts options variable with the options object right from Highcharts
            /// Here we set things like the title and other plot options.
            /// Notice that the Series and Categories are also set here
            ///
            setOptions({
                title: {
                    text: `2021 Average temperatures in Minneapolis`
                },
                xAxis: {
                    categories: categories
                },
                yAxis: {
                    title: {
                        text: "Temperature (°F)"
                    }
                },
                tooltip: {
                    crosshairs: true,
                    shared: true,
                    valueSuffix: '°F'
                },
                plotOptions: {
                    line: {
                        dataLabels: {
                            enabled: true
                        },
                    }
                },
                series: [
                    {
                        name: 'Average Temperature',
                        color: "#7393B3",
                        data: seriesData,
                        zIndex: 1,

                    }
                ]
            });

            setIsLoading(false);
        }

        fetchRecords();

    }, []);

    return (
        <Row>
            <Col xs={12}>
                <div>
                    <h1>React Highcharts example</h1>
                    <Row>
                        <Col s={12}>
                            {isLoading &&
                                <div>Loading data...</div>
                            }
                            {!isLoading && options &&
                                <HighchartsReact
                                    highcharts={Highcharts}
                                    options={options}
                                />
                            }
                        </Col>
                    </Row>
                </div>
            </Col>
        </Row>
    );
}

export default Chart;

Update App component

Remove everything inside the root div from the App.js component and replace that code with a reference to the new Chart.js component. The App.js component should now look like this:

import Chart from "./Chart.js";
import './App.css';

function App() {
  return (
    <div className="App">
      <Chart />
    </div>
  );
}

export default App;

Conclusion

There you have it. If you have not already run the start command, run npm start to see the updated chart rendering twelve months of average temperatures.

Using the Chart.js component above you can integrate Highcharts easily into your React app. The source code for the entire React project can be found in the Github repo. There is also a working copy of the app running on an instance of the repo’s Github pages.