Chart JS — Conditional horizontal row background colours - javascript

I'm a bit stuck on adding conditional background colours to a row in ChartJS, based on numbers on the vertical axis.
Eg.
If the vertical axis is between 0 - 6, background colour for those rows is green.
If the vertical axis is between 6 - 12 background colour for those rows is grey
If the vertical axis is > 12 background colour for those rows is red
Has anyone done something like this before?
I've attached a picture that roughly describes the functionality.
Cheers!

There is no option to do this with chartjs. However you can write your own plugin and draw the background by yourself in the beforeDraw hook for example.
var chart = new Chart(ctx, {
plugins: [{
beforeDraw: function(chart) {
//..
}
}]
});
You can get all the information to calculate the height of an y-axis-segment from the chart parameter.
I've included a snippet below how this could be implemented. Note however that this is more a proof of concept than a proper implementation:
var canvas = document.getElementById('myChart');
window.chartColors = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(51, 204, 51)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
};
var myLineChart = new Chart(canvas,
{
type: 'line',
data: {
labels: ['1', '2', '3', '4', '5'],
datasets: [
{
label: '# of Votes',
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [2, 5, 12.5, 9, 6.3]
}
]
},
options: {
responsive: true,
title: {
display: true,
text: 'Conditional Background'
},
backgroundRules: [{
backgroundColor: window.chartColors.green,
yAxisSegement: 6
}, {
backgroundColor: window.chartColors.grey,
yAxisSegement: 12
}, {
backgroundColor: window.chartColors.red,
yAxisSegement: Infinity
}],
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 1
}
}]
}
},
plugins: [{
beforeDraw: function (chart) {
var ctx = chart.chart.ctx;
var ruleIndex = 0;
var rules = chart.chart.options.backgroundRules;
var yaxis = chart.chart.scales["y-axis-0"];
var xaxis = chart.chart.scales["x-axis-0"];
var partPercentage = 1 / (yaxis.ticksAsNumbers.length - 1);
for (var i = yaxis.ticksAsNumbers.length - 1; i > 0; i--) {
if (yaxis.ticksAsNumbers[i] < rules[ruleIndex].yAxisSegement) {
ctx.fillStyle = rules[ruleIndex].backgroundColor;
ctx.fillRect(xaxis.left, yaxis.top + ((i - 1) * (yaxis.height * partPercentage)), xaxis.width, yaxis.height * partPercentage);
} else {
ruleIndex++;
i++;
}
}
}
}]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<canvas id="myChart" width="400" height="250"></canvas>

Shiffty's answer is right on point, however it only works if the background values are present on the yAxis, which is not always the case... depends on what fits. A more generic solution is to calculate the actual values:
var canvas = document.getElementById('myChart');
window.chartColors = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(51, 204, 51)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
};
var myLineChart = new Chart(canvas,
{
type: 'line',
data: {
labels: ['1', '2', '3', '4', '5'],
datasets: [
{
label: '# of Votes',
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [2, 5, 12.5, 9, 6.3]
}
]
},
options: {
responsive: true,
title: {
display: true,
text: 'Conditional Background'
},
backgroundRules: [{
backgroundColor: window.chartColors.green,
yAxisSegement: 6
}, {
backgroundColor: window.chartColors.grey,
yAxisSegement: 12
}, {
backgroundColor: window.chartColors.red,
yAxisSegement: 999999
}],
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 1
}
}]
}
},
plugins: [{
beforeDraw: function (chart) {
var rules = chart.chart.options.backgroundRules;
var ctx = chart.chart.ctx;
var yAxis = chart.chart.scales["y-axis-0"];
var xaxis = chart.chart.scales["x-axis-0"];
for (var i = 0; i < rules.length; ++i) {
var yAxisSegement = (rules[i].yAxisSegement > yAxis.ticksAsNumbers[0] ? yAxis.ticksAsNumbers[0] : rules[i].yAxisSegement);
var yAxisPosStart = yAxis.height - ((yAxisSegement * yAxis.height) / yAxis.ticksAsNumbers[0]) + chart.chart.controller.chartArea.top;
var yAxisPosEnd = (i === 0 ? yAxis.height : yAxis.height - ((rules[i - 1].yAxisSegement * yAxis.height) / yAxis.ticksAsNumbers[0]));
ctx.fillStyle = rules[i].backgroundColor;
ctx.fillRect(xaxis.left, yAxisPosStart, xaxis.width, yAxisPosEnd - yAxisPosStart + chart.chart.controller.chartArea.top);
}
}
}]
});

Related

How add the sizes of the slices in the pie chart (at the top) in Chart.js?

I am starting to learn the chart.js library.
I drew a pie chart (like "pie"). When you hover over the slices of the diagram, a number appears in the pop-up window that sets the size of the sector.
new chart(
document.getElementById('diagram_1').getContext('2d'), {
type: 'pie',
data: {
labels: [
'Завершенная задача',
'Новая задача',
'Ошибка выполнения'
],
datasets: [{
label: '# of Votes',
data: [#successful_tasks, #new_tasks, #error_tasks],
backgroundColor: [
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(255, 99, 132, 0.2)'
],
borderColor: [
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(255, 99, 132, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
},
responsive: false
}
}
)
How can you make this number still displayed at the top, where the sectors are listed (I marked this place with a red circle in the picture)?
I can add the required number to the labels array
...
data: {
labels: [
'Завершенная задача: ' + #successful_tasks,
'Новая задача: ' + #new_tasks,
'Ошибка выполнения: ' + #error_tasks
],
...
But then this number will appear twice in the tooltip
You can use the plugin system for this:
var options = {
type: 'pie',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"]
}]
},
options: {
plugins: {
customNumber: {
textColor: 'red',
xOffset: 10,
yOffset: 0,
font: '24px Comic Sans MS'
}
}
},
plugins: [{
id: 'customNumber',
afterDraw: (chart, args, opts) => {
const hoveredSlice = chart._active[0];
const {
ctx,
chartArea: {
right
}
} = chart;
if (!hoveredSlice) {
return;
}
ctx.font = opts.font || '24px verdana, sans-serif'
ctx.fillStyle = opts.textColor || 'black'
const val = chart.data.datasets[hoveredSlice.datasetIndex].data[hoveredSlice.index];
const meassures = ctx.measureText(val);
const height = ctx.measureText('M').width;
ctx.fillText(val, (right - meassures.width - (opts.xOffset || 0)), height + (opts.yOffset || 0))
}
}]
}
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.6.0/chart.js"></script>
</body>
I found the answer. My project is written in CoffeeScript, but I think it would be more useful for the StackOverflow community to post the code in JS.
options: {
legend: {
labels: {
generateLabels: function(chart) {
var data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
var meta = chart.getDatasetMeta(0);
var ds = data.datasets[0];
var arc = meta.data[i];
var custom = arc && arc.custom || {};
var getValueAtIndexOrDefault = Chart.helpers.getValueAtIndexOrDefault;
var arcOpts = chart.options.elements.arc;
var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
var value = chart.config.data.datasets[arc._datasetIndex].data[arc._index];
return {
text: label + ": " + value,
fillStyle: fill,
strokeStyle: stroke,
lineWidth: bw,
hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
index: i
};
});
} else {
return [];
}
}
}
}
}

How to remove the extra Y axis from a bar chart in chart.js

I am trying to make a bar chart in chart.js I found some ready-made example and I am trying to adapt it for my requirements.
I don't know how to remove the double Y axis.
var densityCanvas = document.getElementById("densityChart");
Chart.defaults.global.defaultFontFamily = "Lato";
Chart.defaults.global.defaultFontSize = 18;
var densityData = {
label: 'Density of Planet (kg/m3)',
data: [5427, 5243, 5514, 3933, 1326, 687, 1271, 1638],
backgroundColor: 'rgba(0, 99, 132, 0.6)',
borderWidth: 0,
yAxisID: "y-axis-density"
};
var gravityData = {
label: 'Gravity of Planet (m/s2)',
data: [5427, 5243, 5514, 3933, 1326, 687, 1271, 1638],
backgroundColor: 'rgba(99, 132, 0, 0.6)',
borderWidth: 0,
yAxisID: "y-axis-gravity"
};
var planetData = {
labels: ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"],
datasets: [densityData, gravityData]
};
var chartOptions = {
scales: {
xAxes: [{
barPercentage: 1,
categoryPercentage: 0.6
}],
yAxes: [{
id: "y-axis-density"
}, {
id: "y-axis-gravity"
}]
}
};
var barChart = new Chart(densityCanvas, {
type: 'bar',
data: planetData,
options: chartOptions
});
The code above provides this result.
checkout this example [JSFIDDLE](http://jsfiddle.net/p3g07d09/)

Chart.js: Some sectors not showing if difference is too big

I'm passing the following config to Chart.js:
{
type: 'doughnut',
data: {
labels: ['a', 'b', 'c'],
datasets: [{
data: [878, 19020, 100412286],
backgroundColor: [
'rgb(255, 99, 132)',
'rgb(54, 162, 235)',
'rgb(255, 205, 86)'
],
hoverOffset: 4
}]
}
}
But because of the huge difference between all three (given how much bigger c is), c ends up "overlapping" everything else and I just get a doughnut with only one color, showing only c.
If I try a smaller value for c all three sectors show up fine.
But I don't understand, Chart.js should've been able to show all pieces (set a minimum size for the smallest sector etc.)
Is there some parameter I can pass to the config to fix this ?
You can use a logarithmic scale but only for lines. A donut is not a good choice for your use case
https://www.chartjs.org/docs/latest/samples/scales/log.html
Config:
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - Logarithmic'
}
},
scales: {
x: {
display: true,
},
y: {
display: true,
type: 'logarithmic',
}
}
},
};
Setup:
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: logNumbers(DATA_COUNT),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.CHART_COLORS.red,
fill: false,
},
]
};
Action
const logNumbers = (num) => {
const data = [];
for (let i = 0; i < num; ++i) {
data.push(Math.ceil(Math.random() * 10.0) * Math.pow(10, Math.ceil(Math.random() * 5)));
}
return data;
};
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = logNumbers(chart.data.labels.length);
});
chart.update();
}
},
];
One alternative is using 3 datasets, one for each data.
labels: ['a', 'b', 'c'],
datasets: [
{
label: "My First Dataset",
data: [878,0,0],
backgroundColor: [
"rgb(255, 205, 86)",
"rgb(255, 99, 132)",
"rgb(54, 162, 235)",
],
offset:0,
hoverOffset: 0,
},
{
label: "My First Dataset2",
data: [0,19020,0],
backgroundColor: [
"rgb(255, 205, 86)",
"rgb(255, 99, 132)",
"rgb(54, 162, 235)",
],
offset:0,
hoverOffset: 0,
},
{
label: "My First Dataset2",
data: [0,0,100412286],
backgroundColor: [
"rgb(255, 205, 86)",
"rgb(255, 99, 132)",
"rgb(54, 162, 235)",
],
offset:0,
hoverOffset: 0,
},
],
I hope this help.

Chartjs Line Color Between Two Points

Is there any way to set line color of specific sections in between two points in chart.js?
I would like to color the section 00-07 gray, 07-15 red, and 15-23 blue.
Here is what I am passing as the data attribute in the options object to initialize the chart:
var chartData = {
labels: [/* a single dimensional array of strings */],
datasets: [
{
label: '',
data: [/* a single dimensional array of totals */],
fill: false,
backgroundColor: '#e7eaeb',
borderColor: red
}
]
};
I think this is where I need to add the graph section points and colors, but I do not know how.
HI Michael Hurley I think you should use:
interpolation:
https://www.chartjs.org/docs/latest/samples/line/interpolation.html
or
Multi-axis: https://www.chartjs.org/docs/latest/samples/line/multi-axis.html
My idea is we have 3 datasets with multi-color,
End of dataset1 is first of dataset2.
Here my Example:
window.chartColors = { red: 'rgb(255, 99, 132)', orange: 'rgb(255, 159, 64)', yellow: 'rgb(255, 205, 86)', green: 'rgb(75, 192, 192)', blue: 'rgb(54, 162, 235)', purple: 'rgb(153, 102, 255)', grey: 'rgb(201, 203, 207)' };
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var config = {
type: 'line',
data: {
labels: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
datasets: [{
label: 'Cubic interpolation (monotone)',
data: [0, 20, 20, 60, 60, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN],
borderColor: window.chartColors.red,
backgroundColor: 'rgba(0, 0, 0, 0)',
fill: false,
cubicInterpolationMode: 'monotone'
}, {
label: 'Cubic interpolation (default)',
data: [NaN, NaN, NaN, NaN, 60, 120, 140, 180, 120, NaN, NaN, NaN, NaN],
borderColor: window.chartColors.blue,
backgroundColor: 'rgba(0, 0, 0, 0)',
fill: false,
}, {
label: 'Linear interpolation',
data: [NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, 120, 125, 105, 110, 170],
borderColor: window.chartColors.green,
backgroundColor: 'rgba(0, 0, 0, 0)',
fill: false,
lineTension: 0
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Line Chart - Cubic interpolation mode'
},
tooltips: {
mode: 'index'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
},
ticks: {
suggestedMin: -10,
suggestedMax: 200,
}
}]
}
}
};
var ctx = document.getElementById('canvas').getContext('2d');
window.myLine = new Chart(ctx, config);
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
Latest versions of ChartJS allow you to customize line segments individually, which can be used to change the color and also the style (dashed etc) of a specific segment.
const config = {
type: 'line',
data: {
labels: Utils.months({count: 7}),
datasets: [{
label: 'My First Dataset',
data: [65, 59, NaN, 48, 56, 57, 40],
borderColor: 'rgb(75, 192, 192)',
segment: {
borderColor: ctx => skipped(ctx, 'rgb(0,0,0,0.2)') || down(ctx, 'rgb(192,75,75)'),
borderDash: ctx => skipped(ctx, [6, 6]),
}
}]
},
options: genericOptions
};
See https://www.chartjs.org/docs/master/samples/line/segments.html for more info.
The Plugin Core API offers a range of hooks that may be used for performing custom code. You can use the afterLayout hook to create a linear gradient through CanvasRenderingContext2D.createLinearGradient().
In the following example, the linear gradient is created from the colors defined in data.dataset.colors.
new Chart('myChart', {
type: 'line',
plugins: [{
afterLayout: chart => {
var ctx = chart.chart.ctx;
var xAxis = chart.scales['x-axis-0'];
var gradientStroke = ctx.createLinearGradient(xAxis.left, 0, xAxis.right, 0);
var dataset = chart.data.datasets[0];
dataset.colors.forEach((c, i) => {
var stop = 1 / (dataset.colors.length - 1) * i;
gradientStroke.addColorStop(stop, dataset.colors[i]);
});
dataset.backgroundColor = gradientStroke;
dataset.borderColor = gradientStroke;
dataset.pointBorderColor = gradientStroke;
dataset.pointBackgroundColor = gradientStroke;
dataset.pointHoverBorderColor = gradientStroke;
dataset.pointHoverBackgroundColor = gradientStroke;
}
}],
data: {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
datasets: [{
label: 'My Dataset',
data: [101, 122, 103, 115, 95, 94, 100, 108, 112, 115, 119, 120, 109, 108, 105, 116, 117, 108, 109, 114],
fill: false,
colors: ['gray', 'gray', 'gray', 'gray','gray', 'gray', 'red', 'red', 'red', 'red', 'red', 'red', 'red', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue']
}]
},
options: {
scales: {
yAxes: [{
ticks: {
min: 0
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="myChart" height="70"></canvas>
In V3 you can make use of the segment option in the dataset to style specific line parts:
new Chart('myChart', {
type: 'line',
data: {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
datasets: [{
label: 'My Dataset',
data: [101, 122, 103, 115, 95, 94, 100, 108, 112, 115, 119, 120, 109, 108, 105, 116, 117, 108, 109, 114],
segment: {
borderColor: (ctx) => {
const xVal = ctx.p1.parsed.x;
if (xVal <= 7) {
return 'gray';
} else if (xVal <= 15) {
return 'red'
} else {
return 'blue'
}
},
},
}]
},
options: {}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
<canvas id="myChart" height="70"></canvas>
I've been wanting to let everyone know a way for react chart.
import React from "react";
import { LineController } from 'chart.js';
import Chart from 'chart.js/auto';
class MultiLineController extends LineController {
draw() {
const ctx = this.chart.ctx;
const meta = this.getMeta();
const points = meta.data || [];
const colors = this.getDataset().colors || [];
const area = this.chart.chartArea;
colors.forEach((color, idx) => {
meta.dataset.options.borderColor = color;
meta.dataset.draw(ctx, area, idx, 2);
});
meta.dataset.draw(ctx, area, colors.length, points.length - colors.length);
}
}
MultiLineController.id = "multicolorLine";
MultiLineController.defaults = LineController.defaults;
Chart.register(MultiLineController);
export default function App() {
React.useEffect(() => {
const ctx = document.getElementById("line-chart").getContext("2d");
window.lineChart = new Chart(ctx, {
type: 'multicolorLine',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: 'rgb(255, 99, 132)',
data: [0, 10, 5, 2, 20, 30, 45],
colors: ['red', 'green', 'blue', 'yellow']
}]
},
options: {}
});
return () => window.lineChart.destroy();
}, []);
return (
<div style={{width: '100%', height: 300}}>
<canvas id="line-chart" />
</div>
);
}
Here is screenshot of this chart.
React Chart Component implemented by chart.js

Multiple Range Highlighting of Background in Chart.js

From this question I'm looking to turn into a multiple range highlight
But there 1 annoying bug I didn't succeed to solve
background is superposing, if you uncheck a dataset on the top, background alpha change
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/

Categories

Resources