Open
Description
I am using ApexCharts with React in a Next.js project to create multiple area plot sparklines. When the statsData states changes, all charts should update with new data. However, all charts end up displaying the same data as the last chart. I've ensured that my state is updating correctly and that each chart has unique keys.
I suspect the issue is related to how I'm updating the chart options. According to the ApexCharts documentation, I should update the outermost property of the options object.
Here’s a simplified version of my component:
import dynamic from 'next/dynamic';
import { useEffect, useState } from 'react';
const Chart = dynamic(() => import('react-apexcharts'), { ssr: false });
const Apdex = ({ data, startTime, endTime, theme, selectedTimeRange }) => {
const [statsData, setStatsData] = useState([]);
useEffect(() => {
if (data.length === 0) return;
const startTimeEpoch = parseInt(startTime);
const endTimeEpoch = parseInt(endTime);
const {
binTotalRequests,
binAvgResponseTimes,
binFailureRates,
binFailedRequests,
overallTotalRequests,
overallAvgResponseTime,
overallFailureRate,
overallFailedRequests,
} = computeMetrics(data, selectedTimeRange, startTimeEpoch, endTimeEpoch);
const updatedStats = [
{ title: 'Total Requests', data: binTotalRequests, overall: overallTotalRequests },
{ title: 'Avg Response Time', data: binAvgResponseTimes, overall: overallAvgResponseTime },
{ title: 'Failure Rate', data: binFailureRates, overall: overallFailureRate },
{ title: 'Failed Requests', data: binFailedRequests, overall: overallFailedRequests },
];
setStatsData(updatedStats);
}, [data, startTime, endTime]);
const createChartOptions = (id, title, data, overall) => ({
chart: {
id,
group: 'sparks',
type: 'area',
grid: { padding: { left: 0, right: 0 } },
sparkline: { enabled: true },
dropShadow: { enabled: true, top: 1, left: 1, blur: 2, opacity: 0.2 },
},
series: [{ data }],
stroke: { curve: 'smooth', width: 0.5 },
markers: { size: 0 },
colors: ['#fff'],
tooltip: { x: { show: false }, y: { title: { formatter: () => '' } } },
title: { text: overall, offsetX: 20, style: { fontSize: '15px', color: '#fff' } },
subtitle: { text: title, offsetX: 20, offsetY: 20, style: { fontSize: '10px', color: '#fff' } },
});
return (
<div className="w-full flex flex-col h-full">
<div className="flex-grow" style={{ flexBasis: '60%' }}>
<div className="grid h-full grid-cols-1 sm:grid-cols-2">
{statsData.length === 0
? [...Array(4)].map((_, index) => (
<div key={index} className={`${theme} bg-white rounded-lg m-1 pt-1 shadow flex flex-col justify-center items-center animate-pulse`}>
<div className="text-lg text-gray-500">Loading...</div>
</div>
))
: statsData.map((stat, index) => (
<div key={`chart-container-${index}`} className={`${theme} bg-white rounded-lg m-1 pt-1 shadow flex flex-col justify-center items-center`}>
<Chart
options={createChartOptions(`chart-${index}`, stat.title, stat.data, stat.overall)}
series={[{ data: stat.data }]}
type="area"
height="55%"
width="100%"
key={`chart-${index}`}
/>
</div>
))}
</div>
</div>
</div>
);
};
export default Apdex;
I have confirmed that the statsData is correct, and the issue seems to be with the chart rendering. How can I ensure each chart updates correctly with its respective data?
charts after states gets updated