Выровняйте метку данных по правому краю. Горизонтальная гистограмма Vue JS - PullRequest
0 голосов
/ 18 июня 2020

Я попытался выровнять метку данных по правому краю холста. Есть ли способ переместить метки вправо? Вот как я настраиваю ярлыки

plugins: {
      datalabels: {
        formatter: (value, ctx) => {
          let sum = 0;
          let dataArr = ctx.chart.data.datasets[0].data;
          dataArr.map(data => {
            sum += data;
          });
          let percentage = ((value * 100) / sum).toFixed(2) + "%";
          return percentage;
        },
        color: "#000",
        align: "right",
        anchor: "end",
        offset: "70"
      },
      drawBorder: true
    },

Horizontal Bar chart

1 Ответ

0 голосов
/ 20 июня 2020

Plugin Core API предлагает ряд хуков, которые могут использоваться для выполнения пользовательского кода. Вы можете использовать хук afterDraw, чтобы рисовать текст прямо на холсте, используя CanvasRenderingContext2D.fillText() следующим образом:

plugins: [{
  afterDraw: chart => {
    var ctx = chart.chart.ctx;
    ctx.save();
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    ctx.font = "12px Arial";
    let sum = chart.config.data.datasets[0].data.reduce((v, s) => v + s, 0);
    var xAxis = chart.scales['x-axis-0'];
    var yAxis = chart.scales["y-axis-0"];
    yAxis.ticks.forEach((v, i) => {
      var label = chart.data.labels[i];
      var value = chart.data.datasets[0].data[i];
      var x = xAxis.getPixelForValue(value) + 5;
      var y = yAxis.getPixelForTick(i);
      let percent = (value * 100 / sum).toFixed(2);
      ctx.fillText(label + ' (' + percent + '%)', x, y);
    });
    ctx.restore();
  }
}],

Возможно, вам также придется определить некоторые padding справа от диаграмм, чтобы убедиться, что все метки отображаются на canvas.

options: {
  layout: {
    padding: {
      right: 110
    }
  },

Обратите внимание на приведенный ниже фрагмент исполняемого кода.

const chart = new Chart(document.getElementById('myChart'), {
  type: 'horizontalBar',
  plugins: [{
    afterDraw: chart => {
      var ctx = chart.chart.ctx;
      ctx.save();
      ctx.textAlign = 'left';
      ctx.textBaseline = 'middle';
      ctx.font = "12px Arial";
      let sum =  chart.config.data.datasets[0].data.reduce((v, s) => v + s, 0);
      var xAxis = chart.scales['x-axis-0'];
      var yAxis = chart.scales["y-axis-0"];
      yAxis.ticks.forEach((v, i) => {
        var label = chart.data.labels[i];
        var value = chart.data.datasets[0].data[i];
        var x = xAxis.getPixelForValue(value) + 5;
        var y = yAxis.getPixelForTick(i);             
        let percent = (value * 100 / sum).toFixed(2);
        ctx.fillText(label + ' (' + percent + '%)', x, y);
      });
      ctx.restore();
    }
  }],
  data: {
    labels: ['Traffic source 1', 'Traffic source 2', 'Traffic source 3', 'Traffic source 4'],
    datasets: [{
      label: 'By Dataset',
      data: [15, 8, 12, 6],
      backgroundColor: ['red', 'lightblue', 'green', 'orange'],
      barPercentage: 1,
      categoryPercentage: 1
    }]
  },
  options: {
    layout: {
      padding: {
        right: 110
      }
    },
    legend: {
      display: false
    },
    scales: {
      yAxes: [{
        ticks: {
          display: false
        },
        gridLines: {
          drawTicks: false
        }
      }],
      xAxes: [{
        ticks: {
          beginAtZero: true
        },
        gridLines: {
          display: false
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="80"></canvas>
...