简体   繁体   中英

ChartJS horizontal chart display legend on each bar

I'm pretty new in ChartJS and I'm having a horizontal bar chart:

HTML

<canvas id="mybarChart"></canvas>

JavaScript:

var ctx = document.getElementById("mybarChart");

    ctx.height = 300;

    var mybarChart = new Chart(ctx, {
        type: 'horizontalBar',
        responsive: true,
        data: data,
        options: {
            legend: {
                display: false
            },
            scales: {
                yAxes: [{
                    display: false,
                    ticks: {
                        beginAtZero: true
                    },
                    gridLines: {
                        color: "rgba(0, 0, 0, 0)",
                    }
                }],
                xAxes: [{
                    display: false,
                    gridLines: {
                        color: "rgba(0, 0, 0, 0)",
                    },
                    barPercentage: 0.5,
                    categoryPercentage: 0.5
                }]
            }
        }
    });

for which I'm trying to add the legend on each bar like 这个 but right now it looks like 这个

I've tried adding

onAnimationComplete: function () {

            var ctx = this.chart.ctx;
            ctx.font = this.scale.font;
            ctx.fillStyle = this.scale.textColor
            ctx.textAlign = "center";
            ctx.textBaseline = "bottom";

            this.datasets.forEach(function (dataset) {
                dataset.points.forEach(function (points) {
                    ctx.fillText(points.value, points.x, points.y - 10);
                });
            })
        }

but still the same result. What am I doing wrong? I found something here but the labels displayed on each bar are the ticks for Y axes. Is possible to add the legend on each bar and also keep the tooltip?

Thanks in advance!

There are actually several ways that you can achieve this. For simplicity, I will just modify the example that you provided.

Keep in mind that this puts the label inside the bar. You can easily modify this to place it outside, but you will have to add logic to make sure you don't overflow on the top of the chart or into other bars (not very simple logic).

Also, this approach requires that you have configured a label for each dataset (which is needed to drive the regular legend anyway).

Just put this in your animation.onComplete property.

function() {
  var ctx = this.chart.ctx;
  ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
  ctx.textAlign = 'left';
  ctx.textBaseline = 'bottom';

  this.data.datasets.forEach(function(dataset) {
    for (var i = 0; i < dataset.data.length; i++) {
      var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
          scale_max = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._yScale.maxHeight;
      left = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._xScale.left;
      offset = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._xScale.longestLabelWidth;
      ctx.fillStyle = '#444';
      var y_pos = model.y - 5;
      var label = model.label;
      // Make sure data value does not get overflown and hidden
      // when the bar's value is too close to max value of scale
      // Note: The y value is reverse, it counts from top down
      if ((scale_max - model.y) / scale_max >= 0.93)
        y_pos = model.y + 20;
      // ctx.fillText(dataset.data[i], model.x, y_pos);

      if (dataset.data[i] > 0) {
        ctx.fillText(dataset.label, left + 10, model.y + 8);
      }
    }
  });
}

Here is a jsfiddle example (forked from the example you provided).

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