Reputation: 305
I'm migrating some plots from Plot.ly to Chart.js v2.9, and I'm trying to add background colors to my new Chart.js plots to match their predecessor:
But when I add the appropriate plugin to my Chart.js config, instead I get this:
Here is my plugin code:
[{
beforeDraw: function (chart, easing) {
let config: DragenChartConfiguration = chart.config;
if (chart.ctx) {
if (config.dragen?.hBars) {
var ctx = chart.ctx;
var chartArea = chart.chartArea;
for (const hBar of config.dragen.hBars) {
ctx.save();
ctx.fillStyle = hBar.color;
ctx.fillRect(chartArea.left, hBar.from, chartArea.right - chartArea.left, hBar.to - hBar.from);
ctx.restore();
}
}
}
}
}]
Where each "Hbar" object simply defines a color and a Y-axis range I want to color:
hBars: Array(3)
0: {from: 28, to: 100, color: "rgb(195, 230, 195)"}
1: {from: 20, to: 28, color: "rgb(230, 220, 195)"}
2: {from: 0, to: 20, color: "rgb(230, 195, 195)"}
length: 3
What am I missing here?
Upvotes: 0
Views: 243
Reputation: 31439
You are taking raw values instead of getting the pixels for those values, if you do that it will work:
Plugin V3:
{
id: 'backgrounds',
beforeDraw: (chart, args, options) => {
const { ctx, chartArea, scales: {y} } = chart;
options.hbars.forEach((hBar) => {
ctx.save();
ctx.fillStyle = hBar.color;
ctx.fillRect(chartArea.left, y.getPixelForValue(hBar.from), chartArea.right - chartArea.left, y.getPixelForValue(hBar.to) - y.getPixelForValue(hBar.from));
ctx.restore();
})
}
}
Plugin V2:
{
id: 'backgrounds',
beforeDraw: (chart, x, options) => {
const { ctx, chartArea, scales } = chart;
const y = scales['y-axis-0']
options.hbars.forEach((hBar) => {
ctx.save();
ctx.fillStyle = hBar.color;
ctx.fillRect(chartArea.left, y.getPixelForValue(hBar.from), chartArea.right - chartArea.left, y.getPixelForValue(hBar.to) - y.getPixelForValue(hBar.from));
ctx.restore();
})
}
Working example V3:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [100, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
plugins: {
backgrounds: {
hbars: [{
from: 28,
to: 100,
color: "rgb(195, 230, 195)"
},
{
from: 20,
to: 28,
color: "rgb(230, 220, 195)"
},
{
from: 0,
to: 20,
color: "rgb(230, 195, 195)"
}
]
}
}
},
plugins: [{
id: 'backgrounds',
beforeDraw: (chart, args, options) => {
const {
ctx,
chartArea,
scales: {
y
}
} = chart;
options.hbars.forEach((hBar) => {
ctx.save();
ctx.fillStyle = hBar.color;
ctx.fillRect(chartArea.left, y.getPixelForValue(hBar.from), chartArea.right - chartArea.left, y.getPixelForValue(hBar.to) - y.getPixelForValue(hBar.from));
ctx.restore();
})
}
}]
}
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.2.0/chart.js"></script>
</body>
Working example V2:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [100, 19, 3, 5, 2, 3],
borderWidth: 1
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1
}
]
},
options: {
plugins: {
backgrounds: {
hbars: [{
from: 28,
to: 100,
color: "rgb(195, 230, 195)"
},
{
from: 20,
to: 28,
color: "rgb(230, 220, 195)"
},
{
from: 0,
to: 20,
color: "rgb(230, 195, 195)"
}
]
}
}
},
plugins: [{
id: 'backgrounds',
beforeDraw: (chart, x, options) => {
const {
ctx,
chartArea,
scales
} = chart;
const y = scales['y-axis-0']
options.hbars.forEach((hBar) => {
ctx.save();
ctx.fillStyle = hBar.color;
ctx.fillRect(chartArea.left, y.getPixelForValue(hBar.from), chartArea.right - chartArea.left, y.getPixelForValue(hBar.to) - y.getPixelForValue(hBar.from));
ctx.restore();
})
}
}]
}
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/2.9.4/Chart.js"></script>
</body>
Fiddle V3: https://jsfiddle.net/Leelenaleee/6s8upz10/15/
Fiddle V2: https://jsfiddle.net/Leelenaleee/tj71gLa2/10/
Upvotes: 1