Reputation: 23
I am quite new at Chart.js 2, so any help will be appreciated.
I'm trying to show values for each bar in the chart. As suggested in Display values in Pareto chart using Chart.js 2.0.2 and other users I'm using this solution. However, this part throws an exception TypeError: dataset.metaData is undefined
:
dataset.metaData.forEach(function(p) {
ctx.fillText(p._chart.config.data.datasets[p._datasetIndex].data[p._index], p._model.x, p._model.y + 20);
});
I just want to show the value over the bar. Any help?
Upvotes: 2
Views: 9654
Reputation: 33
I have adapted it a little bit for horizontal Bars to show the sum of values instead of the stacked values. maybe someone can beautify the code a little bit but it works this way:
onComplete: function() {
var ctx = this.chart.ctx;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
var chart = this;
var datasets = this.config.data.datasets;
var sum=new Array();
datasets.forEach(function (dataset, i) {
ctx.font = "10px Arial";
switch ( chart.getDatasetMeta(i).type ) {
case "line":
ctx.fillStyle = "Black";
chart.getDatasetMeta(i).data.forEach(function (p, j) {
ctx.fillText(datasets[i].data[j], p._model.x, p._model.y - 20);
});
break;
case "bar":
ctx.fillStyle = "White";
chart.getDatasetMeta(i).data.forEach(function (p, j) {
ctx.fillText(datasets[i].data[j], p._model.x, p._model.y + 20);
});
break;
case "horizontalBar":
ctx.fillStyle = "Black";
chart.getDatasetMeta(i).data.forEach(function (p, j) {
if (sum[j]== null) { sum[j] = 0; }
sum[j]=sum[j]+parseFloat(datasets[i].data[j]);
if (i==datasets.length-1) {ctx.fillText(sum[j], p._model.x+10, p._model.y);}
});
break;
}
});
}
Upvotes: 0
Reputation: 1125
Works for me! chart.js 2.5.0
In addition to potatopeelings's and slashpm answers.
To handle horizontalBar you can add this case (change the padding "offsetY" to "offsetX")
case "horizontalBar":
ctx.fillStyle = "Black";
chart.getDatasetMeta(i).data.forEach(function (p, j) {
ctx.fillText(datasets[i].data[j], p._model.x + 20, p._model.y);
});
break;
Here is the full function
function chartValuesShow() { // show max values of the chart
var ctx = this.chart.ctx;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
var chart = this;
var datasets = this.config.data.datasets;
datasets.forEach(function (dataset, i) {
ctx.fontSize = "10px";
switch (chart.getDatasetMeta(i).type) {
case "line":
ctx.fillStyle = "Black";
chart.getDatasetMeta(i).data.forEach(function (p, j) {
ctx.fillText(datasets[i].data[j], p._model.x, p._model.y - 20);
});
break;
case "bar":
ctx.fillStyle = "Black";
chart.getDatasetMeta(i).data.forEach(function (p, j) {
ctx.fillText(datasets[i].data[j], p._model.x, p._model.y + 20);
});
break;
case "horizontalBar":
ctx.fillStyle = "Black";
chart.getDatasetMeta(i).data.forEach(function (p, j) {
ctx.fillText(datasets[i].data[j], p._model.x + 20, p._model.y);
});
break;
}
});
}
Upvotes: 1
Reputation: 214
In addition to potatopeelings's answer, using Chart.js v2.5, I had to adjust the following:
switch (dataset.type)
to switch ( chart.getDatasetMeta(i).type )
Upvotes: 1
Reputation: 41075
With the below updated onComplete
, your code should work with Chart.js v2.1
...
var options = {
animation: {
onComplete: function() {
var ctx = this.chart.ctx;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
var chart = this;
var datasets = this.config.data.datasets;
datasets.forEach(function (dataset, i) {
ctx.font = "20px Arial";
switch (dataset.type) {
case "line":
ctx.fillStyle = "Black";
chart.getDatasetMeta(i).data.forEach(function (p, j) {
ctx.fillText(datasets[i].data[j], p._model.x, p._model.y - 20);
});
break;
case "bar":
ctx.fillStyle = "White";
chart.getDatasetMeta(i).data.forEach(function (p, j) {
ctx.fillText(datasets[i].data[j], p._model.x, p._model.y + 20);
});
break;
}
});
}
},
...
Fiddle - http://jsfiddle.net/0j4g7kxy/
I've assumed you needed only the bar, but I have retained the code for line in the onComplete
, so it should work for lines too. If you don't need either, just remove the related case
from the onComplete
code
Upvotes: 6