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;
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