I am working on project that requires me to design a chart as the following diagram:

I am using chart.js and react to make the distribution plot. But I am not able to figure out how to add fill color of the area chart between a particular range of values of the x-variable. So far, I am able to achieve this:

I have used the following code to make the area chart as a react component:
const data = {
labels: {DataLabel},
datasets: [
{
label: 'Blood Sugar Measure',
data: {Data},
fill: true,
backgroundColor: ["#E5E5E5", "#E5E5E5", "#B4EDB3", "#B4EDB3", "#E5E5E5"],
pointBorderColor: "#8884d8",
pointBorderWidth: 2,
pointRadius: 3,
tension: 0.4
},
],
};
const options = {
plugins: { legend: { display: false } },
layout: { padding: { bottom: 0.1 } },
scales: {
y: {
display : false,
beginAtZero: true,
grid: {
display: false
},
ticks: {
color: "#000000",
font: {
size: 18
}
}
},
x: {
beginAtZero: true,
grid: {
display: false
},
ticks: {
color: "#000000",
font: {
size: 10
},
min: 0
}
}
},
};
export const DistChart = () => {
return (<div className="App">
<Line data={data} options={options} />
</div>);
};
I would need some help to apply the conditional fill color based on the x-axis variable.
You can use multiple datasets with object data so you can specify starting and end points. After this you can manipulate the legend so it looks like its only a single dataset:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: 'Blood Sugar Measure extra',
data: [{
x: "Red",
y: 5
}, {
x: "Blue",
y: 8
}],
backgroundColor: 'lightGray',
fill: true
},
{
label: 'Blood Sugar Measure',
data: [{
x: "Blue",
y: 8
}, {
x: "Yellow",
y: 12
}, {
x: "Green",
y: 10
}],
backgroundColor: 'pink',
fill: true
},
{
label: 'Blood Sugar Measure extra',
data: [{
x: "Green",
y: 10
}, {
x: "Purple",
y: 12
}, {
x: "Orange",
y: 10
}],
backgroundColor: 'lightGray',
fill: true
}
]
},
options: {
plugins: {
legend: {
onClick: (e, legendItem, legend) => {
const ci = legend.chart;
const currentlyHidden = ci.getDatasetMeta(0).hidden;
for (let i = 0; i < ci.data.datasets.length; i++) {
ci.setDatasetVisibility(i, currentlyHidden)
}
ci.update();
},
labels: {
filter: (e) => (!e.text.includes('extra'))
}
}
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>
I was able to make some progress on the design that I wanted, so thought of sharing my answer to benefit others. I was able to fill based on x-axis data values and get the following chart:

I had to use the segment property inside data configs to achieve this, with the help of a function. This is the modified code:
const highlightRegion = (ctx, value) => {
if (ctx.p0DataIndex > boundary_val1 && ctx.p0DataIndex < boundary_val2) {
return "#B4EDB3";
}
return "#E5E5E5";
};
const bgColor = ctx => highlightRegion(ctx, "#B4EDB3");
const data = {
labels: x_values,
datasets: [
{
label: 'Count',
data: [0, 20, 40, 80, 150, 80, 30, 0],
pointRadius: 0,
fill: true,
tension: 0.4,
segment: {
backgroundColor: bgColor,
borderColor: bgColor,
},
},
],
};
Special thanks goes to this youtube series from where I was able to find my answer: https://www.youtube.com/watch?v=st2O-pvhWM4.
I will keep this post open, in case if there is a better solution as I think my solution is not absolutely correct.