0👍
✅
In the chart options, I defined an onClick
event handler that records the index of the selected data point (selIndex
) and updates the chart. It also overwrites the label at the selected index with an empty string since we’re going to draw that label ourselves using a specific style.
onClick: event => {
var element = lineChart.getElementAtEvent(event);
if (element.length > 0) {
selIndex = element[0]._index;
lineChart.data.labels = labels.map((l, i) => i == selIndex ? '' : l),
lineChart.update(data);
}
},
The recorded selIndex
is used inside the Plugin Core API afterDraw
hook to draw a circle around the selected data point and draw text for the value and the label.
if (index == selIndex) {
// draw circle
ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle = "#53b300";
ctx.arc(x, yTop, 8, 0, 2 * Math.PI);
ctx.stroke();
// draw text for value and label
ctx.textAlign = 'center';
ctx.font = "18px Arial";
ctx.fillStyle = "#53b300";
ctx.fillText(data[index] + 'k', x, yTop - 15);
ctx.fillText(labels[index], x, yAxis.bottom + 22);
}
Please run your amended code below and click on individual data points to see how it works. I made one data point pre-selected. If no data point should be selected at start, simply make the following change to the code: let selIndex = -1
;.
const labels = ["January", "February", "March", "April", "May", "June", "July"];
const data = [65, 0, 80, 81, 56, 85, 40];
let selIndex = 2;
const lineChart = new Chart(document.getElementById('myChart'), {
type: 'line',
plugins: [{
afterDraw: chart => {
var ctx = chart.chart.ctx;
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
xAxis.ticks.forEach((value, index) => {
var x = xAxis.getPixelForTick(index);
var yTop = yAxis.getPixelForValue(data[index]);
ctx.save();
ctx.strokeStyle = '#aaaaaa';
ctx.beginPath();
ctx.moveTo(x, yAxis.bottom);
ctx.lineTo(x, yTop);
ctx.stroke();
if (index == selIndex) {
// draw circle
ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle = "#53b300";
ctx.arc(x, yTop, 8, 0, 2 * Math.PI);
ctx.stroke();
// draw text for value and label
ctx.textAlign = 'center';
ctx.font = "18px Arial";
ctx.fillStyle = "#53b300";
ctx.fillText(data[index] + 'k', x, yTop - 15);
ctx.fillText(labels[index], x, yAxis.bottom + 22);
}
ctx.restore();
});
}
}],
data: {
labels: labels.map((l, i) => i == selIndex ? '' : l),
datasets: [{
label: "My First dataset",
data: data,
fill: false
}]
},
options: {
layout: {
padding: {
top: 25,
right: 25
}
},
legend: {
display: false
},
tooltips: {
enabled: false
},
onClick: event => {
var element = lineChart.getElementAtEvent(event);
if (element.length > 0) {
selIndex = element[0]._index;
lineChart.data.labels = labels.map((l, i) => i == selIndex ? '' : l),
lineChart.update(data);
}
},
scales: {
yAxes: [{
gridLines: {
display: false
}
}],
xAxes: [{
gridLines: {
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<div style="width: 75%">
<canvas id="myChart" height="120"></canvas>
</div>
Source:stackexchange.com