简体   繁体   中英

Data label over stacked bar chart

https://github.com/chartjs/Chart.js/blob/master/samples/data_label_combo-bar-line.html shows how to add data labels over simple bar charts, which display the number the bar is representing. How can this be done with stacked bar charts in charts.js?

This can be done using the following options:

animation:
{
  onComplete: function()
  {
    var chartInstance = this.chart;
    var horizontal = chartInstance.config.type.lastIndexOf("horizontal", 0) === 0; //if type of graph starts with horizontal

    var ctx = chartInstance.ctx;
    ctx.textAlign = (horizontal) ? "left" : "center";
    ctx.textBaseline = (horizontal) ? "middle" : "bottom";
    ctx.font = '16px "Helvetica Neue", Helvetica, Arial, sans-serif';
    ctx.fillStyle = "#000";

    var dataLabels = {}; //key = x or y coordinate (depends on grouping), value = Array[0] other coordinate , Array[1] = value to print
    var equationForGrouping = (horizontal) ? Math.max : Math.min; //equation to use for grouping

    //get values from chart, fill them in dataLabels (as seen in https://github.com/chartjs/Chart.js/blob/master/samples/data_label_combo-bar-line.html )
    Chart.helpers.each(this.data.datasets.forEach(function(dataset, i)
    {
      var meta = chartInstance.controller.getDatasetMeta(i);
      Chart.helpers.each(meta.data.forEach(function(bar, index)
      { //for each part of each stacked bar
        if(meta.hidden != true) //if data is not hidden (by clicking on it in the legend)
        {
          var groupByCoordinate = (horizontal) ? bar._model.y : bar._model.x;
          var otherCoordinate = (horizontal) ? bar._model.x : bar._model.y;

          if(dataLabels[groupByCoordinate])
          {
            dataLabels[groupByCoordinate][0] = equationForGrouping(otherCoordinate, dataLabels[groupByCoordinate][0]);
            dataLabels[groupByCoordinate][1] += dataset.data[index];
          }
          else
            dataLabels[groupByCoordinate] = [otherCoordinate, dataset.data[index]];
          }
        }), this)
      }), this);

      //draw values onto graph
      for(var key in dataLabels)
      {
        if(dataLabels[key][1] >= 1000000) //million
          dataLabels[key][1] = Math.round(dataLabels[key][1] / 1000000) + "m";
        else if(dataLabels[key][1] >= 1000) //thousand
          dataLabels[key][1] = Math.round(dataLabels[key][1] / 1000) + "k";

        if(horizontal) //if grouped by y values
          ctx.fillText(dataLabels[key][1], dataLabels[key][0], key);
        else
          ctx.fillText(dataLabels[key][1], key, dataLabels[key][0]);
      }
    }
  }
};

See this example: https://jsfiddle.net/s4r2rj8h/1

例

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM