I want to fill color to the chart (SPC Chart)
With the easy data, it can fill normally. However, with this sample data it fills not well, the range color fill looks quite stupid :((((
Please, refer to the link and review it. Can anybody help me to fill same as expected picture.
The expected layout that draw with AmChart
function generateData() {
const data = [
"12.466",
"12.739",
"13.491",
"13.936",
"14.339",
"14.955",
"15.375",
"15.842",
"16.163",
"16.864",
"17.541",
"17.763",
"17.755",
"17.755",
"17.602",
"17.815",
"17.086",
"17.561",
"17.422",
"17.487",
"17.499",
"17.611",
"17.866",
"17.451",
"17.37",
"17.766",
"17.529",
"17.158",
"17.28",
"17.626",
"17.625",
"17.594",
"17.376",
"17.712",
"17.879",
"17.073",
"17.202",
"17.534",
"17.374",
"17.822"
];
const timestamps = [
"2024-09-10 18:06:55",
"2024-09-10 18:06:56",
"2024-09-10 18:06:57",
"2024-09-10 18:06:58",
"2024-09-10 18:06:59",
"2024-09-10 18:07:00",
"2024-09-10 18:07:01",
"2024-09-10 18:07:02",
"2024-09-10 18:07:03",
"2024-09-10 18:07:04",
"2024-09-10 18:07:05",
"2024-09-10 18:07:06",
"2024-09-10 18:07:07",
"2024-09-10 18:07:08",
"2024-09-10 18:07:09",
"2024-09-10 18:07:10",
"2024-09-10 18:07:11",
"2024-09-10 18:07:12",
"2024-09-10 18:07:14",
"2024-09-10 18:07:15",
"2024-09-10 18:07:16",
"2024-09-10 18:07:17",
"2024-09-10 18:07:18",
"2024-09-10 18:07:19",
"2024-09-10 18:07:20",
"2024-09-10 18:07:21",
"2024-09-10 18:07:22",
"2024-09-10 18:07:23",
"2024-09-10 18:07:24",
"2024-09-10 18:07:25",
"2024-09-10 18:07:26",
"2024-09-10 18:07:27",
"2024-09-10 18:07:28",
"2024-09-10 18:07:29",
"2024-09-10 18:07:30",
"2024-09-10 18:07:31",
"2024-09-10 18:07:32",
"2024-09-10 18:07:33",
"2024-09-10 18:07:34",
"2024-09-10 18:07:36"
];
const usl = [
"",
"13",
"13",
"13",
"13",
"13",
"13",
"13",
"13",
"13",
"",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1",
"18.1"
];
const ucl = [
"",
"12.5",
"12",
"12",
"12",
"12",
"12",
"12",
"12",
"12",
"",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9",
"17.9"
];
const lcl = [
"",
"11.5",
"10",
"10",
"10",
"10",
"10",
"10",
"10",
"10",
"",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5",
"16.5"
];
const lsl = [
"",
"10.5",
"9",
"9",
"9",
"9",
"9",
"9",
"9",
"9",
"",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1"
];
return {
timestamps,
data,
usl,
ucl,
lcl,
lsl
};
}
const { timestamps, data, usl, ucl, lcl, lsl } = generateData();
function createFillBetweenTraces(xData, ucl, lcl, usl, lsl) {
const traces = [];
let x = [];
let yUsl = [];
let yLsl = [];
for (let i = 0; i < xData.length; i++) {
if (usl[i] !== null && lsl[i] !== null) {
x.push(xData[i]);
yUsl.push(usl[i]);
yLsl.push(lsl[i]);
} else if (x.length > 0) {
traces.push({
x: x.slice(),
y: yLsl.slice(),
mode: "lines",
line: {
color: "transparent"
},
showlegend: false
});
traces.push({
x: x.slice(),
y: yUsl.slice(),
fill: "tonexty",
fillcolor: "rgba(255, 255, 0, 1.0)",
line: {
color: "transparent"
},
showlegend: false
});
x = [];
yUsl = [];
yLsl = [];
}
}
if (x.length > 0) {
traces.push({
x: x,
y: yLsl,
mode: "lines",
line: {
color: "transparent"
},
showlegend: false
});
traces.push({
x: x,
y: yUsl,
fill: "tonexty",
fillcolor: "rgba(255, 255, 0, 1.0)",
line: {
color: "transparent"
},
showlegend: false
});
}
x = [];
let yUcl = [];
let yLcl = [];
for (let i = 0; i < xData.length; i++) {
if (ucl[i] !== null && lcl[i] !== null) {
x.push(xData[i]);
yUcl.push(ucl[i]);
yLcl.push(lcl[i]);
} else if (x.length > 0) {
traces.push({
x: x.slice(),
y: yLcl.slice(),
mode: "lines",
line: {
color: "transparent"
},
showlegend: false
});
traces.push({
x: x.slice(),
y: yUcl.slice(),
mode: "lines",
fill: "tonexty",
fillcolor: "rgba(0, 255, 0, 0.8)",
line: {
color: "transparent"
},
showlegend: false
});
x = [];
yUcl = [];
yLcl = [];
}
}
if (x.length > 0) {
traces.push({
x: x,
y: yLcl,
mode: "lines",
line: {
color: "transparent"
},
showlegend: false
});
traces.push({
x: x,
y: yUcl,
mode: "lines",
fill: "tonexty",
fillcolor: "rgba(0, 255, 0, 0.8)",
line: {
color: "transparent"
},
showlegend: false
});
}
return traces;
}
let fillBetweenTraces = [];
function createPlot(xData, xAxisType) {
fillBetweenTraces = createFillBetweenTraces(xData, ucl, lcl, usl, lsl);
const trace1 = {
x: xData,
y: data,
mode: "lines+markers",
name: "Value",
marker: {
color: "blue"
},
line: {
color: "blue"
}
};
const trace2 = {
x: xData,
y: usl,
mode: "lines",
name: "USL",
line: {
dash: "dash",
color: "red"
}
};
const trace3 = {
x: xData,
y: ucl,
mode: "lines",
name: "UCL",
line: {
dash: "dot",
color: "orange"
}
};
const trace4 = {
x: xData,
y: lcl,
mode: "lines",
name: "LCL",
line: {
dash: "dot",
color: "orange"
}
};
const trace5 = {
x: xData,
y: lsl,
mode: "lines",
name: "LSL",
line: {
dash: "dash",
color: "red"
}
};
const dataToPlot = [
...fillBetweenTraces,
trace1,
trace2,
trace3,
trace4,
trace5
];
/* const dataToPlot = [trace1, trace2, trace3, trace4, trace5] */ const layout = {
title: "Scatter Plot with Control and Specification Limits",
xaxis: {
type: "date",
tickformat: "%Y-%m-%d<br>%H:%M:%S"
}
};
Plotly.newPlot("myDiv", dataToPlot, layout);
}
createPlot(timestamps, "timestamp");
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scatter Plot with Plotly</title>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.9/xlsx.full.min.js"></script>
</head>
<div id="myDiv"></div>
</html>
I implemented the createFillBetweenTraces function. Worked as expected
function createFillBetweenTraces(xData, ucl, lcl, usl, lsl) {
let x = [];
const traces = [];
// USL LSL
x = [];
let yUsl = [],
yLsl = [];
xData.forEach((e, i) => {
if (usl[i] !== "" && lsl[i] !== "") {
x.push(xData[i]);
yUsl.push(usl[i]);
yLsl.push(lsl[i]);
} else if (x.length > 0) {
traces.push({
x: x,
y: yLsl,
mode: 'lines',
line: {
color: 'transparent'
},
showlegend: false,
hoverinfo: "none"
});
traces.push({
x: x,
y: yUsl,
fill: 'tonexty',
fillcolor: 'rgba(255, 255, 0, 0.3)',
line: {
color: 'transparent'
},
showlegend: false,
hoverinfo: "none"
});
xData.slice(i);
x = [];
yUsl = [];
yLsl = [];
}
})
if (x.length > 0) {
traces.push({
x: x,
y: yLsl,
mode: 'lines',
line: {
color: 'transparent'
},
showlegend: false,
hoverinfo: "none"
});
traces.push({
x: x,
y: yUsl,
mode: 'lines',
fill: 'tonexty',
fillcolor: 'rgba(255, 255, 0, 0.3)',
line: {
color: 'transparent'
},
showlegend: false,
hoverinfo: "none"
});
}
x = [];
let yUcl = [],
yLcl = [];
xData.forEach((e, i) => {
if (ucl[i] !== "" && lcl[i] !== "") {
x.push(xData[i]);
yUcl.push(ucl[i]);
yLcl.push(lcl[i]);
} else if (x.length > 0) {
traces.push({
x: x,
y: yLcl,
mode: 'lines',
line: {
color: 'transparent'
},
showlegend: false,
hoverinfo: "none"
});
traces.push({
x: x,
y: yUcl,
fill: 'tonexty',
fillcolor: 'rgba(0, 255, 0, 0.3)',
line: {
color: 'transparent'
},
showlegend: false,
hoverinfo: "none"
});
xData.slice(i);
x = [];
yUcl = [];
yLcl = [];
}
})
if (x.length > 0) {
traces.push({
x: x,
y: yLcl,
mode: 'lines',
line: {
color: 'transparent'
},
showlegend: false,
hoverinfo: "none"
});
traces.push({
x: x,
y: yUcl,
mode: 'lines',
fill: 'tonexty',
fillcolor: 'rgba(0, 255, 0, 0.3)',
line: {
color: 'transparent'
},
showlegend: false,
hoverinfo: "none"
});
}
return traces;
}