Chart.js堆积条形图文本位于堆积条形上方

问题描述 投票:0回答:1

我在div元素中有Chart.js图表​​。到目前为止,我得到的方法看起来不错,这是我所需要的,但是它缺少很大一部分,它是一种动态文本,必须聚合图表数据并显示摘要。不是逐个栏,而是两个栏的摘要。这是我到目前为止所到之处:

var chart;
var opts = {
  layout: {
    padding: {
      left: 0,
      right: 0,
      top: 0,
      bottom: 0
    }
  },
  responsive: true,
  maintainAspectRatio: false,
  legend: {
    display: false,
  },
  tooltips: {
    enabled: false,
  },
  scales: {
    xAxes: [{
      stacked: true,
      display: false,
      ticks: {
        fontColor: "#fff",
      }
    }, ],
    yAxes: [{
      stacked: true,
      display: false,
      ticks: {
        fontColor: "#fcafe4",
        mirror: true
      }
    }]
  }
};

var datasets = [{
    label: "My Label",
    backgroundColor: ["#FF3A2F"],
    data: [],
  },
  {
    label: "Your Label",
    backgroundColor: ["#0CB04A"],
    data: [],
  }
];

var labels = ['Label 1'];

var ctx = document.getElementById('chart-canvas');

chart = new Chart(ctx, {
  type: "horizontalBar",
  data: {
    labels: labels,
    datasets: datasets
  },
  options: opts
});

function refresh() {

  chart.data.datasets[0].data[0] = Math.floor(Math.random() * 1000) + 1;
  chart.data.datasets[1].data[0] = Math.floor(Math.random() * 1000) + 1;
  chart.config.options.scales.xAxes[0].ticks.max = chart.data.datasets[0].data[0] + chart.data.datasets[1].data[0];
  chart.update();
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<div class="row">
  <div class="col-lg-5 small">My Stacked Chart</div>
  <div class="col-lg-6">
    <div class="chart-container">
      <canvas id="chart-canvas"></canvas>
    </div>
  </div>
  <div class="col-lg-1 my-auto">
    <div class="btn-group">
      <button type="button" class="btn btn-primary btn-md btn-sm" onClick="refresh()">
                            Refresh
                        </button>
    </div>
  </div>
</div>

我想知道是否有一种方法可以添加将在画布中间并显示图表中数据的文本。例如XXXX of Total,并且每次单击刷新按钮时都会更新。像这样:enter image description here

谢谢!朱利安

javascript chart.js
1个回答
0
投票

Plugin Core API提供了一系列可用于执行自定义代码的挂钩。您可以使用afterDraw钩子使用canvasCanvasRenderingContext2D.fillText()上直接绘制文本。

CanvasRenderingContext2D.fillText()

请在下面查看您的修改后的代码。

chart = new Chart(ctx, {
  type: "horizontalBar",
  plugins: [{
    afterDraw: chart => {      
      var ctx = chart.chart.ctx; 
      var value =  chart.config.data.datasets[0].data[0];
      var total = chart.config.data.datasets.reduce((t, ds) => t + ds.data[0], 0);
      var percent = Math.round(1000 / total * value) / 10;
      var xAxis = chart.scales['x-axis-0'];   
      var yAxis = chart.scales['y-axis-0'];   
      ctx.save();
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.font = "24px Arial";
      ctx.fillText(value + ' (' + percent + '%) of ' + total, xAxis.right / 2, (yAxis.bottom + yAxis.top) / 2);
      ctx.restore();
    }
  }],
  ... 
var chart;
var opts = {
  layout: {
    padding: {
      left: 0,
      right: 0,
      top: 0,
      bottom: 0
    }
  },
  responsive: true,
  maintainAspectRatio: false,
  legend: {
    display: false,
  },
  tooltips: {
    enabled: false,
  },
  scales: {
    xAxes: [{
      stacked: true,
      display: false,
      ticks: {
        fontColor: "#fff",
      }
    }, ],
    yAxes: [{
      stacked: true,
      display: false,
      ticks: {
        fontColor: "#fcafe4",
        mirror: true
      }
    }]
  }
};

var datasets = [{
    label: "My Label",
    backgroundColor: ["#FF3A2F"],
    data: [],
  },
  {
    label: "Your Label",
    backgroundColor: ["#0CB04A"],
    data: [],
  }
];

var labels = ['Label 1'];

var ctx = document.getElementById('chart-canvas');

chart = new Chart(ctx, {
  type: "horizontalBar",
  plugins: [{
    afterDraw: chart => {      
      var ctx = chart.chart.ctx; 
      var value =  chart.config.data.datasets[0].data[0];
      var total = chart.config.data.datasets.reduce((t, ds) => t + ds.data[0], 0);
      var percent = Math.round(1000 / total * value) / 10;
      var xAxis = chart.scales['x-axis-0'];   
      var yAxis = chart.scales['y-axis-0'];   
      ctx.save();
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.font = "24px Arial";
      ctx.fillText(value + ' (' + percent + '%) of ' + total, xAxis.right / 2, (yAxis.bottom + yAxis.top) / 2);
      ctx.restore();
    }
  }],
  data: {
    labels: labels,
    datasets: datasets
  },
  options: opts
});
refresh();

function refresh() {
  chart.data.datasets[0].data[0] = Math.floor(Math.random() * 1000) + 1;
  chart.data.datasets[1].data[0] = Math.floor(Math.random() * 1000) + 1;
  chart.config.options.scales.xAxes[0].ticks.max = chart.data.datasets[0].data[0] + chart.data.datasets[1].data[0];
  chart.update();
}
© www.soinside.com 2019 - 2024. All rights reserved.