【问题标题】:Chart.js stacked bar chart text on top of the stacked barsChart.js 堆积条形图顶部的堆积条形图文本
【发布时间】:2020-09-14 06:09:12
【问题描述】:

我在 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,每次单击刷新按钮时都会更新。像这样的东西:

提前致谢! 朱利安

【问题讨论】:

    标签: javascript chart.js


    【解决方案1】:

    Plugin Core API 提供了一系列可用于执行自定义代码的挂钩。您可以使用afterDraw 钩子直接在canvas 上使用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();
    }
    <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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 2018-05-04
      • 2014-02-09
      • 2014-06-05
      • 2022-08-19
      • 2017-10-14
      相关资源
      最近更新 更多