I am trying to create a pie chart, to display data. When I edit the file and save to see the result, the pie chart suddenly loads onscreen(displaying the data correctly). If I refresh the page though, I only have the logo on screen loaded, no pie. Can anyone point me to what I am doing wrong?
Component:
import React, { useLayoutEffect, useRef } from "react";
import * as am4core from "@amcharts/amcharts4/core";
import * as am4charts from "@amcharts/amcharts4/charts";
import am4themes_animated from "@amcharts/amcharts4/themes/animated";
am4core.useTheme(am4themes_animated);
const Pie = (props) => {
const chart = useRef(null);
useLayoutEffect(() => {
let pie = am4core.create("chartdiv", am4charts.PieChart3D);
let pieData = [];
props.data.map((item) => {
let obj = {};
obj = { name: item.prod_name, quantity: item.prod_quantity };
pieData.push(obj);
});
// ...
pie.data = pieData;
let pieSeries = pie.series.push(new am4charts.PieSeries3D());
pieSeries.slices.template.strokeOpacity = 1;
pie.radius = am4core.percent(70);
pieSeries.dataFields.value = "quantity";
pieSeries.dataFields.category = "name";
pieSeries.hiddenState.properties.opacity = 1;
pieSeries.hiddenState.properties.endAngle = -90;
pieSeries.hiddenState.properties.startAngle = -90;
pie.hiddenState.properties.radius = am4core.percent(60);
pie.innerRadius = am4core.percent(40);
chart.current = pie;
return () => {
pie.dispose();
};
}, []);
return <div id="chartdiv" className="pie"></div>;
};
export default Pie;
Update: Component Statistics:
import Pie from "./Charts/Pie";
const Statistics = () => {
const [data, setData] = useState([]);
useEffect(() => {
axios
.get("http://localhost:3001/statistics")
.then((res) => setData(res.data.data.orders));
}, []);
return (
<section className="statistics">
<Pie data={data} />
</section>
);
};
export default Statistics;
Also, the css for the className='pie' :
.pie {
height: 500px;
}
So since you are using useEffect
with empty dependency array, your component Pie
will only run the pie chart creation code inside useEffect
on component mount.
Now since you are fetching the data using axios asynchronously, the data will be passed to the Pie
component after it is already mounted. So now data changes will not be reflected in Pie chart.
adding the props.data
in the dependency array will run the useEffect
whenever new data is passed to the Pie component. (i.e. on props update).
useEffect(() => {
// your code for rendering pie chart
return () => {
pie.dispose();
};
}, [props.data])
https://codesandbox.io/s/blissful-fast-djuxm?file=/src/Pie.jsx