I am generating a chart.js canvas bar chart. What I am trying to do is, inside of the labels array, add images that go with each label, as opposed to just the text label itself. Here is the code for the chart: The json object that I am getting data from has an image url that I want to use to display the picture:
$.ajax({
method: "get",
url: "http://localhost:3000/admin/stats/show",
dataType: "json",
error: function() {
console.log("Sorry, something went wrong");
},
success: function(response) {
console.log(response)
var objectToUse = response.top_dogs
var updateLabels = [];
var updateData = [];
for (var i = 0; i < objectToUse.length; i+=1) {
updateData.push(objectToUse[i].win_percentage * 100);
updateLabels.push(objectToUse[i].title);
}
var data = {
labels: updateLabels,
datasets: [
{
label: "Top Winners Overall",
fillColor: get_random_color(),
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: get_random_color(),
highlightStroke: "rgba(220,220,220,1)",
data: updateData
}
]
};
var options = {
//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
scaleBeginAtZero : true,
//Boolean - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - If there is a stroke on each bar
barShowStroke : true,
//Number - Pixel width of the bar stroke
barStrokeWidth : 2,
//Number - Spacing between each of the X value sets
barValueSpacing : 5,
//Number - Spacing between data sets within X values
barDatasetSpacing : 2,
};
var loadNewChart = new Chart(barChart).Bar(data, options);
}
});
If anyone has a solution it would be greatly appreciated!
I'm aware that this is an old post but since it has been viewed so many times, I'll describe a solution that works with the current Chart.js version 2.9.3.
The Plugin Core API offers a range of hooks that may be used for performing custom code. You can use the afterDraw
hook to draw images (icons) directly on the canvas using CanvasRenderingContext2D
.
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 image = new Image();
image.src = images[index],
ctx.drawImage(image, x - 12, yAxis.bottom + 10);
});
}
}],
The position of the labels will have to be defined through the xAxes.ticks.padding
as follows:
xAxes: [{
ticks: {
padding: 30
}
}],
Please have a look at the following runnable code snippet.
const labels = ['Red Vans', 'Blue Vans', 'Green Vans', 'Gray Vans'];
const images = ['https://i.stack.imgur.com/2RAv2.png', 'https://i.stack.imgur.com/Tq5DA.png', 'https://i.stack.imgur.com/3KRtW.png', 'https://i.stack.imgur.com/iLyVi.png'];
const values = [48, 56, 33, 44];
new Chart(document.getElementById("myChart"), {
type: "bar",
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 image = new Image();
image.src = images[index],
ctx.drawImage(image, x - 12, yAxis.bottom + 10);
});
}
}],
data: {
labels: labels,
datasets: [{
label: 'My Dataset',
data: values,
backgroundColor: ['red', 'blue', 'green', 'lightgray']
}]
},
options: {
responsive: true,
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}],
xAxes: [{
ticks: {
padding: 30
}
}],
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="90"></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