Bar values in Chart.js 2.X - dataset.metadata unde

2019-04-01 18:49发布

问题:

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?

回答1:

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



回答2:

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 )



回答3:

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;
    }
  });
}


回答4:

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;
            }
        });
    }