cforcomputer
cforcomputer

Reputation: 199

Implementing a choropleth chart using chartjs-chart-geo plugin with react-chartjs-2

I am trying to create a choropleth chart of the United States with functionality similar to - if not the same as this example from chartjs-chart-geo using react-chartjs-2 wrapper for chartjs.

The problem that I ran into is how to use chartjs-chart-geo with react-chartjs-2. I was able to get plugins working that modify existing chart types, but I'm not sure how to get it working with a plugin that adds new chart types.

Here is my code so far:

import React, { useState, useEffect} from "react";
import { Line } from "react-chartjs-2";
import 'chartjs-chart-geo';
import stateUnemployment from "../march-state-unemployment.json"


const JSON_IMPORT = stateUnemployment;

const transformData = obj => {
    let stateNames = [];
    let dataMonth = new Date().getMonth();
    let dataValue = [];

    console.log(obj.length);
    console.log(obj[1].state);
    // Code for parsing json data goes here
    for (let i = 0; i < obj.length; i++) {
        stateNames[i] = obj[i].state;
        dataValue[i] = obj[i].unemploymentPercent;
    }

    return {
        stateNames,
        dataMonth,
        dataValue,
    };
};

const USPageMap = () => {
    const [data, setData] = useState(null);

    useEffect(() => {
        const {dataLabel, dataValue} = transformData(JSON_IMPORT);
        setData({
            labels: dataLabel,
            datasets: [
                {
                    // code for configuring choropleth data goes here?
                    label: "States",
                    data: dataValue,
                }
            ]
        });
    }, []);

    return (
        <div>
            <h2>National Unemployment</h2>
            // Swapping line for Choropleth doesn't seem to work?
            <Line
                data={data}
                options={{
                    maintainAspectRatio: true,
                    legend: {
                        display: false
               },
                plugins: {
                    // setting plugin options usually goes here
                    scale: {
                        projection: 'albersUsa'
                    },
                    geo: {
                        colorScale: {
                            display: true,
                            position: 'bottom',
                            quantize: 5,
                            legend: {
                                position: 'bottom-right',
                            },
                        },
                    },
                }
            }}
        />
        </div>
     );
  };

export default USPageMap;

Here is an example of the JSON being used:

[
  {
    "state": "Alabama",
    "totalUnemployed": "77,988",
    "unemploymentPercent": 3.5
  },
  {
    "state": "Alaska",
    "totalUnemployed": "19,426",
    "unemploymentPercent": 5.6
  },
  {
    "state": "Arizona",
    "totalUnemployed": "196,793",
    "unemploymentPercent": 5.5
  }
]

If there is a simpler alternative than react-chartjs-2 I am open to changing my approach. I've also been looking at potential alternatives such as react-geo-charts and react-simple-maps. Thanks!

Upvotes: 2

Views: 6391

Answers (1)

Juha Kangas
Juha Kangas

Reputation: 788

I got the example working with React by using the following imports. I used the canvas element with the useEffect. Canvas isn't ready when the page is initially loaded so we must check if canvas exist before we can create the chart.

import { Chart } from 'react-chartjs-2'
import * as ChartGeo from 'chartjs-chart-geo'

    const USPageMap = () =>{
    
        useEffect(()=>{
    
            let canvas = document.getElementById("canvas")
            if(!canvas) return
    
            fetch('https://unpkg.com/us-atlas/states-10m.json').then((r) => r.json()).then((us) => {
    
                const nation = ChartGeo.topojson.feature(us, us.objects.nation).features[0];
                const states = ChartGeo.topojson.feature(us, us.objects.states).features;
              
                const chart = new Chart(canvas.getContext("2d"), {
                  type: 'choropleth',
                  data: {
                    labels: states.map((d) => d.properties.name),
                    datasets: [{
                      label: 'States',
                      outline: nation,
                      data: states.map((d) => ({feature: d, value: Math.random() * 10})),
                    }]
                  },
                  options: {
                    legend: {
                      display: false
                    },
                    scale: {
                      projection: 'albersUsa'
                    },
                    geo: {
                      colorScale: {
                        display: true,
                        position: 'bottom',
                        quantize: 5,
                        legend: {
                          position: 'bottom-right',
                        },
                      },
                    },
                  }
                });
              });
        })
        
        return(
            <div>
                <canvas id='canvas'></canvas>
            </div>
        )
    }

Upvotes: 2

Related Questions