From this question I'm looking to turn into a multiple range highlight
But there 1 annoying bug I didn't succeed to solve
Here my work so far: https://jsfiddle.net/742zut83/588/
Why the custom draw function executed for each dataset? Once highlights done originalLineDraw
is returned
draw : function() {
var chart = this.chart;
// Get the object that determines the region to highlight.
var yHighlightRanges = chart.config.data.yHighlightRanges;
let ctx = chart.chart.ctx;
yHighlightRanges.forEach(function(Range) {
var yRangeBegin = Range.begin;
var yRangeEnd = Range.end;
var xaxis = chart.scales['x-axis-0'];
var yaxis = chart.scales['y-axis-0'];
var yRangeBeginPixel = yaxis.getPixelForValue(yRangeBegin);
var yRangeEndPixel = yaxis.getPixelForValue(yRangeEnd);
ctx.save();
// The fill style of the rectangle we are about to fill.
ctx.fillStyle = Range.rgb;
// Fill the rectangle that represents the highlight region. The parameters are the closest-to-starting-point pixel's x-coordinate,
// the closest-to-starting-point pixel's y-coordinate, the width of the rectangle in pixels, and the height of the rectangle in pixels, respectively.
ctx.fillRect(xaxis.left, Math.min(yRangeBeginPixel, yRangeEndPixel), xaxis.right - xaxis.left, Math.max(yRangeBeginPixel, yRangeEndPixel) - Math.min(yRangeBeginPixel, yRangeEndPixel));
ctx.restore();
});
// Apply the original draw function for the line chart.
originalLineDraw.apply(this, arguments);
}
var ctx = document.getElementById("myChart");
// The original draw function for the line chart. This will be applied after we have drawn our highlight range (as a rectangle behind the line chart).
var originalLineDraw = Chart.controllers.line.prototype.draw;
// Extend the line chart, in order to override the draw function.
Chart.helpers.extend(Chart.controllers.line.prototype, {
draw : function() {
var chart = this.chart;
// Get the object that determines the region to highlight.
var yHighlightRanges = chart.config.data.yHighlightRanges;
let ctx = chart.chart.ctx;
yHighlightRanges.forEach(function(Range) {
var yRangeBegin = Range.begin;
var yRangeEnd = Range.end;
var xaxis = chart.scales['x-axis-0'];
var yaxis = chart.scales['y-axis-0'];
var yRangeBeginPixel = yaxis.getPixelForValue(yRangeBegin);
var yRangeEndPixel = yaxis.getPixelForValue(yRangeEnd);
ctx.save();
// The fill style of the rectangle we are about to fill.
ctx.fillStyle = Range.rgb;
// Fill the rectangle that represents the highlight region. The parameters are the closest-to-starting-point pixel's x-coordinate,
// the closest-to-starting-point pixel's y-coordinate, the width of the rectangle in pixels, and the height of the rectangle in pixels, respectively.
ctx.fillRect(xaxis.left, Math.min(yRangeBeginPixel, yRangeEndPixel), xaxis.right - xaxis.left, Math.max(yRangeBeginPixel, yRangeEndPixel) - Math.min(yRangeBeginPixel, yRangeEndPixel));
ctx.restore();
});
// Apply the original draw function for the line chart.
originalLineDraw.apply(this, arguments);
}
});
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: 'Season 1',
data: [12, 17, 3, 5, 9, 3],
fill: false,
borderColor: 'rgba(0, 200, 0, 1)'
},
{
label: 'Season 2',
data: [5, 14, 3, 15, 9, 13],
fill: false,
borderColor: 'rgba(200, 0, 0, 1)'
}
],
// This, if it exists at all, defines the highlight region.
yHighlightRanges : [
{
begin: 0,
end: 6,
rgb: 'rgba(100, 100, 100, 0.2)'
},
{
begin: 6,
end: 12,
rgb: 'rgba(200, 100, 200, 0.2)'
},
{
begin: 12,
end: 18,
rgb: 'rgba(0, 100, 200, 0.2)'
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>
Why not using simply the annotation plugin?
Here is your example with annotation plugin, using Box annotations:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: 'Season 1',
data: [12, 17, 3, 5, 9, 3],
fill: false,
borderColor: 'rgba(0, 200, 0, 1)'
},
{
label: 'Season 2',
data: [5, 14, 3, 15, 9, 13],
fill: false,
borderColor: 'rgba(200, 0, 0, 1)'
}
]
},
options: {
scales: {
yAxes: [{
id: 'y-axis-1',
ticks: {
beginAtZero:true
}
}]
},
annotation: {
drawTime: "afterDraw",
annotations: [{
id: 'box1',
type: 'box',
yScaleID: 'y-axis-1',
yMin: 0,
yMax: 6,
backgroundColor: 'rgba(100, 100, 100, 0.2)',
borderColor: 'rgba(100, 100, 100, 0.2)',
},{
id: 'box2',
type: 'box',
yScaleID: 'y-axis-1',
yMin: 6,
yMax: 12,
backgroundColor: 'rgba(200, 100, 200, 0.2)',
borderColor: 'rgba(200, 100, 200, 0.2)',
},{
id: 'box3',
type: 'box',
yScaleID: 'y-axis-1',
yMin: 12,
yMax: 18,
backgroundColor: 'rgba(0, 100, 200, 0.2)',
borderColor: 'rgba(0, 100, 200, 0.2)',
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/0.5.7/chartjs-plugin-annotation.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>
And this is your fiddle updated: https://jsfiddle.net/beaver71/50L21shp/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With