I have a chart i need to draw that, in addition to the data points, i want an icon permanently above (some) data points with a custom text string.
I don't need the default value popover as i can make do with a custom legend, but i need to add an icon above one or two points, and on hover of the icon, display a popover. i need to build the popover text string from non-chart related data.
The custom data labels don't appear to be flexible enough to allow different icons/popovers on different data points, i may be wrong though.
Another possibility is chartjs-plugin-datalabels, but I'm not sure about that.
In case your chart (canvas) is of fixed size, you can easily solve this problem by adding an additional dataset
that specifies nothing but the icons to be shown in the chart.
{
data: data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null),
fill: false,
pointStyle: icon,
pointRadius: 22,
pointHoverRadius: 22
}
Given the data array data2
and the array imageIndexes
, the data
of the icons dataset
can be built using Array.map
. Note that the values - where any - are derived from corresponding values in data2
but slightly increased to make the images appear on top of them.
data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null)
Further you'll need to define a tooltips
object inside the chart options
in order to style the popup and to make sure, tooltips are only displayed when the mouse hovers over the icons.
tooltips: {
filter: tooltipItem => tooltipItem.datasetIndex == 2,
titleFontSize: 16,
titleAlign: 'center',
callbacks: {
title: (tooltipItem) => tooltipItem.length == 0 ? null : tooltipText,
label: () => null
}
},
Please have a look at the runnable code snipped below.
const labels = ['A', 'B', 'C', 'D', 'E', 'F'];
const alerts = ['B', 'D'];
const data1 = [0, 2, 1, 3, 2, 1];
const data2 = [1, 3, 3, 4, 3, 2];
const imageIndexes = [1, 3];
const tooltipText = 'Efficiency of Standard Curve\nnot opimal';
var icon = new Image();
icon.src = 'https://i.stack.imgur.com/YvlWY.png';
const chart = new Chart(document.getElementById("myChart"), {
type: "line",
data: {
labels: labels,
datasets: [{
data: data1,
fill: false,
backgroundColor: 'blue',
borderColor: 'blue',
lineTension: 0,
pointRadius: 5,
pointHoverRadius: 5,
pointBorderWidth: 3,
pointHoverBorderWidth: 3,
pointBorderColor: 'white',
pointHoverBorderColor: 'white'
},
{
data: data2,
fill: false,
showLine: false,
backgroundColor: 'orange',
pointRadius: 4,
pointHoverRadius: 4
},
{
data: data2.map((v, i) => imageIndexes.includes(i) ? v + 1.2 : null),
fill: false,
pointStyle: icon,
pointRadius: 22,
pointHoverRadius: 22
}
]
},
options: {
responsive: false,
title: {
display: false
},
legend: {
display: false
},
tooltips: {
filter: tooltipItem => tooltipItem.datasetIndex == 2,
titleFontSize: 16,
titleAlign: 'center',
callbacks: {
title: (tooltipItem) => tooltipItem.length == 0 ? null : tooltipText,
label: () => null
}
},
scales: {
yAxes: [{
ticks: {
min: 0,
max: 6,
stepSize: 1
}
}],
xAxes: [{
gridLines: {
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" style="width: 500px; height: 200px"></canvas>
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