I’m having some trouble trying to change the backgroundColor of a specific chart area between two yAxis ticks.This is what I have so far:
And this is what I wanted:
I’ve seen some similar posts about that and people recommend using Annotation to do this. I tried using it on my chart and it didn’t work. This is my first time building a chart with chart.js so I’m still learning. Here’s my code:
var profileChart = new Chart(ctx1, { type: "line", data: { labels: ["", "D", "I", "S", "C", ""], datasets:[{ data: [], borderWidth: 1, pointBackgroundColor: "black", backgroundColor: "black", borderColor: "black", fill: false, lineTension: 0, yAxisID: 'first-y-axis' }, { yAxisID: 'third-y-axis' }], }, options: { title: { display: true, text: 'Gráfico do Perfil DISC', fontSize: 20, }, scales: { yAxes: [{ id: 'first-y-axis', type: 'linear', gridLines: { drawOnChartArea: false }, scaleLabel: { display: true, padding: '15px', labelString: 'Intensity' }, ticks: { max: 28, min: 1, stepSize: 1 } }, { id: 'second-y-axis', type: 'linear', position: 'left', gridLines: { drawOnChartArea: true }, ticks: { display: false, min: 1, max: 8, stepSize: 1 } }, { id: 'third-y-axis', position: 'right', type: 'linear', gridLines: { drawOnChartArea: false }, scaleLabel: { display: true, padding: '10px', labelString: 'Segment' }, ticks: { max: 7.5, min: 0.5, stepSize: 1 }, afterTickToLabelConversion: function(scaleInstance) { scaleInstance.ticks[0] = null; scaleInstance.ticks[scaleInstance.ticks.length - 1] = null; scaleInstance.ticksAsNumbers[0] = null; scaleInstance.ticksAsNumbers[scaleInstance.ticksAsNumbers.length - 1] = null; }, }] }, legend: { display: false }, tooltips: { callbacks: { label: function(tooltipItem) { return tooltipItem.yLabel; } } } }, annotation: { drawTime: "afterDraw", annotations: [{ id: 'box1', type: 'box', yScaleID: 'second-y-axis', yMin: 12.5, yMax: 16.5, backgroundColor: 'grey', }] } });
Advertisement
Answer
You can draw the rectangle directly on the canvas using the Plugin Core API. The API offers a range of hooks that may be used for performing custom code.
In your amended code below, I use the beforeDraw
hook to draw the rectangle through CanvasRenderingContext2D.fillRect()
.
var profileChart = new Chart('canvas', { type: "line", plugins: [{ beforeDraw: chart => { var ctx = chart.chart.ctx; var xAxis = chart.scales['x-axis-0']; var yAxis = chart.scales['first-y-axis']; ctx.save(); ctx.fillStyle = 'lightgray'; ctx.beginPath(); var yTop = yAxis.getPixelForValue(16.5); var yBottom = yAxis.getPixelForValue(12.5); ctx.fillRect(xAxis.left, yTop, xAxis.right - xAxis.left, yBottom - yTop); ctx.stroke(); ctx.restore(); } }], data: { labels: ["", "D", "I", "S", "C", ""], datasets: [{ data: [,25.5, 8, 7.5, 11], borderWidth: 1, pointBackgroundColor: "black", backgroundColor: "black", borderColor: "black", fill: false, lineTension: 0, yAxisID: 'first-y-axis' }, { yAxisID: 'third-y-axis' } ], }, options: { title: { display: true, text: 'Gráfico do Perfil DISC', fontSize: 20, }, scales: { yAxes: [{ id: 'first-y-axis', type: 'linear', gridLines: { drawOnChartArea: false }, scaleLabel: { display: true, padding: '15px', labelString: 'Intensity' }, ticks: { max: 28, min: 1, stepSize: 1 } }, { id: 'second-y-axis', type: 'linear', position: 'left', gridLines: { drawOnChartArea: true }, ticks: { display: false, min: 1, max: 8, stepSize: 1 } }, { id: 'third-y-axis', position: 'right', type: 'linear', gridLines: { drawOnChartArea: false }, scaleLabel: { display: true, padding: '10px', labelString: 'Segment' }, ticks: { max: 7.5, min: 0.5, stepSize: 1 }, afterTickToLabelConversion: function(scaleInstance) { scaleInstance.ticks[0] = null; scaleInstance.ticks[scaleInstance.ticks.length - 1] = null; scaleInstance.ticksAsNumbers[0] = null; scaleInstance.ticksAsNumbers[scaleInstance.ticksAsNumbers.length - 1] = null; }, } ] }, legend: { display: false }, tooltips: { callbacks: { label: function(tooltipItem) { return tooltipItem.yLabel; } } } } });
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js"></script> <canvas id="canvas" height="200">