Currently, when the data points lie within the box region demarcated by the Lower Specification Limit (LSL) and Lower Control Limit (LCL), they are overlapping with the yellow shaded area that represents this region, despite the fact that I've used the "z" attribute for layer ordering and set the position to relative. This behavior is contrary to my intention of having these data points appear above the region's shading.
To resolve this issue, I'm seeking effective debugging strategies and potential solutions that can help rectify this layering problem. Any insights or advice on the matter would be greatly appreciated. "chart.js": "^4.2.1", "chartjs-adapter-date-fns": "^3.0.0", "chartjs-plugin-annotation": "^2.2.1", "chartjs-plugin-zoom": "^2.0.1", enter image description here
import React, { useState, useEffect } from 'react';
import { Line } from 'react-chartjs-2';
import annotationPlugin from 'chartjs-plugin-annotation';
import { format } from 'date-fns';
import 'chartjs-adapter-date-fns';
import Grid from '@mui/material/Grid';
import Modal from '@mui/material/Modal';
import Backdrop from '@mui/material/Backdrop';
import Fade from '@mui/material/Fade';
import {
Chart as ChartJS,
TimeScale,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
} from 'chart.js';
import zoomPlugin from 'chartjs-plugin-zoom';
ChartJS.register(
TimeScale,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
annotationPlugin,
zoomPlugin
);
const SMMSChart = ({ className, chartDataArray }) => {
const [data, setData] = useState([]);
const [open, setOpen] = useState(false);
const [selectedChart, setSelectedChart] = useState(null);
const handleOpen = (chart) => {
setSelectedChart(chart);
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
useEffect(() => {
console.log('chartDataArray:', chartDataArray);
const chartData = chartDataArray.flat().map((chartData) => {
console.log('chartData:', chartData);
const dataset = {
label: `${chartData.LineLane} - ${chartData.Title}`,
data: chartData.Yvalue.map((value, index) => ({
x: new Date(chartData.Xvalue[index]),
y: value,
})),
position: 'relative',
zIndex: 2,
// borderColor: 'rgb(54, 162, 235)',
borderColor: 'black',
// backgroundColor: 'red',
// fill: false,
// position: 'absolute',
// borderWidth: 5,
// zIndex: '999999 !important',
};
const dateArray = chartData.Xvalue.map((value) => new Date(value));
const xMin = new Date(Math.min(...dateArray));
const xMax = new Date(Math.max(...dateArray));
const annotations = [
{
type: 'box',
xScaleID: 'x',
yScaleID: 'y',
xMin: xMin,
xMax: xMax,
position: 'relative',
zIndex: -1,
yMin: chartData.UCL,
yMax: chartData.USL,
backgroundColor: 'rgba(255, 143, 0, 0.7)', // yellow color
borderWidth: 0,
},
{
type: 'box',
xScaleID: 'x',
yScaleID: 'y',
xMin: xMin,
xMax: xMax,
position: 'relative',
zIndex: -1,
yMin: chartData.LSL,
yMax: chartData.LCL,
backgroundColor: 'rgba(255, 143, 0, 0.7)', // yellow color
borderWidth: 0,
},
{
type: 'box',
xScaleID: 'x',
yScaleID: 'y',
xMin: xMin,
xMax: xMax,
yMin: chartData.LCL,
yMax: chartData.LSL,
backgroundColor: 'transparent',
zIndex: -1, // lower z index than other annotations
borderWidth: 0,
},
{
type: 'line',
mode: 'horizontal',
scaleID: 'y',
value: 0,
position: 'relative',
borderColor: 'black',
backgroundColor: 'red',
borderWidth: 2,
borderDash: [10, 5],
label: {
backgroundColor: 'black',
display: true,
position: 'start',
},
},
{
type: 'line',
mode: 'horizontal',
scaleID: 'y',
value: chartData.UCL,
borderColor: 'red',
borderWidth: 2,
borderDash: [10, 5],
label: {
backgroundColor: 'red',
content: 'UCL',
display: true,
position: 'start',
yAdjust: -10,
},
},
{
type: 'line',
mode: 'horizontal',
scaleID: 'y',
value: chartData.LCL,
borderColor: 'red',
borderWidth: 2,
borderDash: [10, 5],
label: {
backgroundColor: 'red',
content: 'LCL',
display: true,
position: 'start',
},
},
{
type: 'line',
mode: 'horizontal',
scaleID: 'y',
value: chartData.USL,
borderColor: 'green',
borderWidth: 2,
borderDash: [10, 5],
label: {
backgroundColor: 'green',
content: 'USL',
display: true,
position: 'start',
},
},
{
type: 'line',
mode: 'horizontal',
scaleID: 'y',
value: chartData.LSL,
borderColor: 'green',
borderWidth: 2,
borderDash: [10, 5],
label: {
backgroundColor: 'green',
content: 'LSL',
display: true,
position: 'start',
},
},
];
// Add point annotations for exceeding values
for (let i = 0; i < chartData.Yvalue.length; i++) {
if (
chartData.Yvalue[i] >= chartData.USL ||
chartData.Yvalue[i] >= chartData.UCL ||
chartData.Yvalue[i] <= chartData.LSL ||
chartData.Yvalue[i] <= chartData.LCL
) {
annotations.push({
type: 'point',
backgroundColor: 'red',
borderColor: 'red',
borderWidth: 1,
scaleID: 'y',
radius: 7,
xValue: new Date(chartData.Xvalue[i]),
yValue: chartData.Yvalue[i],
position: 'relative',
zIndex: 1000,
});
}
}
return { dataset, annotations };
});
console.log('Processed chartData:', chartData);
setData(chartData);
}, [chartDataArray]);
if (!chartDataArray || chartDataArray.length === 0) {
return <p>Loading chart...</p>;
}
const options = {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
type: 'time',
time: {
parser: 'dd/MM/yy HH:mm',
tooltipFormat: 'dd/MM/yy HH:mm',
},
ticks: {
autoSkip: true,
maxTicksLimit: 20,
callback: function (value, index, values) {
return format(new Date(value), 'dd/MM/yy HH:mm');
},
maxRotation: 90,
minRotation: 90,
},
grid: {
drawBorder: true,
drawOnChartArea: false,
},
},
y: {
grid: {
drawBorder: true,
drawOnChartArea: false,
},
},
},
plugins: {
legend: {
display: false,
position: 'top',
},
title: {
display: false,
},
// annotation: {
// annotations: [],
// },
annotation: {
annotations: [{
type: 'line',
mode: 'horizontal',
scaleID: 'y',
value: 22, // The y-value where you want the line to be drawn
borderColor: 'red',
borderWidth: 2,
label: {
backgroundColor: 'black',
content: 'Line over Box',
enabled: true,
},
z: 999 // Set a high value to bring the line above the data
}]
}
},
elements: {
line: {
borderWidth: 1,
},
},
};
return (
<Grid container>
<Grid item xs={12}>
<div className={className}>
{data.map((d, index) => (
<div key={index} style={{ height: '100%', width: '100%' }}>
<Line
data={{
datasets: [d.dataset],
}}
options={{
...options,
plugins: {
...options.plugins,
title: {
display: true,
text: d.dataset.label,
},
annotation: {
annotations: d.annotations,
},
},
}}
onClick={() => handleOpen(d)}
/>
</div>
))}
</div>
</Grid>
<Modal
open={open}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={open}>
<div
style={{
height: '80%',
width: '80%',
margin: 'auto',
position: 'fixed',
top: '10%',
left: '10%',
background: '#fff',
border: '2px solid #000',
overflow: 'auto',
borderRadius: '10px',
}}
>
{selectedChart && (
<Line
data={{
datasets: [selectedChart.dataset],
}}
options={{
...options,
plugins: {
...options.plugins,
title: {
display: true,
text: selectedChart.dataset.label,
},
annotation: {
annotations: selectedChart.annotations,
},
},
maintainAspectRatio: false,
}}
style={{ height: '100%', width: '100%' }}
/>
)}
</div>
</Fade>
</Modal>
</Grid>
);
};
export default SMMSChart;