0

I know just a little React but have been tasked with displaying json using highcharts. The json is returned via a fetch api call and looks like below. I currently use the code at bottom and it works fine. However, it is hard-coded and I would like to refactor/improve it, maybe looping over the keys object. Research shows I could potentially use .entries or .map, but examples I find call those functions in the render section, but with the way my code it, I need to do it in getConfig() and componentDidMount().

Suggestions?

JSON to be displayed using highcharts

[
    {
        "reason": "reason-1", 
        "fq_counts": {"FQ1": 35, "FQ4": 92, "FQ3": 91, "FQ2": 49}
    }, 
    {
        "reason": "reason-2", 
        "fq_counts": {"FQ1": 53, "FQ4": 32, "FQ3": 82, "FQ2": 16}
    }, 
    // etc...
]

Metrics.jsx

import HighCharts from "highcharts"
import HighchartsReact from "highcharts-react-official";
// other imports...

const getConfig = ( metricsData ) => ({
    chart: {
        type: 'column'
    },
    title: {
        text: 'my title'
    },
    
    // other highcharts objects...
    
    series: [
        {
            name: metricsData["reason0"],
            data: [
                metricsData["data0Label0"], 
                metricsData["data0Label1"], 
                metricsData["data0Label2"], 
                metricsData["data0Label3"], 
            ]
        },{
            name: metricsData["reason1"],
            data: [
                metricsData["data1Label0"], 
                metricsData["data1Label1"], 
                metricsData["data1Label2"], 
                metricsData["data1Label3"], 
            ]
        },
        // more objects...
    ]
});


class Metrics extends Component {

    constructor() {
      super();
      this.state = {
          metricsData: {},
        }
    }
    
    componentDidMount() {
        fetch(process.env.MY_ENDPOINT + '/metrics', {credentials: 'include'})
        .then(res => res.json())
        .then(data => {
            const keys = Object.keys(data[0].fq_counts);
            this.setState({
                metricsData: {
                
                    "reason0":data[0].reason,
                    "data0Label0":data[0].fq_counts[keys[0]],
                    "data0Label1":data[0].fq_counts[keys[1]],
                    "data0Label2":data[0].fq_counts[keys[2]],
                    "data0Label3":data[0].fq_counts[keys[3]],
                    
                    "reason1":data[1].reason,
                    "data1Label0":data[1].fq_counts[keys[0]],
                    "data1Label1":data[1].fq_counts[keys[1]],
                    "data1Label2":data[1].fq_counts[keys[2]],
                    "data1Label3":data[1].fq_counts[keys[3]],
                    
                    // more data...
                   
                }
            });
        });
    }  
  
    render() {
      const { metricsData } = this.state;
      const chartConfig = getConfig(metricsData);
        return (
            <Paper sx={{width: 1}}>
                <Box
                    sx={{
                    display: 'flex',
                    flexDirection: 'column',
                        alignItems: 'flex-start',
                    p: 1,
                    m: 1,
                    bgcolor: 'background.paper',
                    borderRadius: 1,
                    }}
                    <Typography variant="h4" gutterBottom>
                        <b>Quarterly Metrics</b>
                    </Typography>
                            <Divider />
                    <Typography variant="p" gutterBottom>Totals</Typography>
                    <HighchartsReact highcharts={HighCharts} options={chartConfig}/>
                </Box>
            </Paper>
        );
    }
}
export default Metrics;

1 Answer 1

1

You can relatively easily convert your data to the Highcharts series structure. The below concept will be the same for React and pure JS:

const keys = Object.keys(responseData[0].fq_counts);
const series = [];

responseData.forEach((dataEl, index) => {
    series.push({ name: dataEl.reason, data: [] });
    keys.forEach(key => {
        series[index].data.push([key, dataEl.fq_counts[key]]);
    });
});

Live demo: http://jsfiddle.net/BlackLabel/deskutc4/

API Reference: https://api.highcharts.com/highcharts/series.column.data

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.