简体   繁体   English

如何使用 vue-chartjs 将图像添加到图表标签?

[英]How to add images to chart labels with vue-chartjs?

I want to add flag icons under the country code labels but am completely stuck.我想在国家代码标签下添加国旗图标,但完全卡住了。

Image of the chart with my current code带有我当前代码的图表图像

The images are named BR.svg, FR.svg and MX.svg and are located under @/assets/icons/flags/这些图像名为BR.svg, FR.svg and MX.svg ,位于@/assets/icons/flags/

I am using vue@2.6.12 and vue-chartjs@3.5.1 in my project.我在我的项目中使用vue@2.6.12vue-chartjs@3.5.1 This is my Chart.vue component :这是我的Chart.vue 组件

<script>
import { Bar } from 'vue-chartjs'

export default {
  extends: Bar,
  data: () => ({
    chartdata: {
      labels: ['BR', 'FR', 'MX'],
      datasets: [
        {
          label: 'Lorem ipsum',
          backgroundColor: '#AF78D2',
          data: [39, 30, 30],
        }
      ]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      legend: {
        display: false,
      },
      tooltips: {
        "enabled": false
      },
      scales : {
        xAxes : [ {
            gridLines : {
                display : false
            }
        } ],
        yAxes: [{
          ticks: {
            beginAtZero: true,
            suggestedMin: 0,
            suggestedMax: 40,
            stepSize: 5,
          }
        }]
      },
      "hover": {
        "animationDuration": 0
      },
      "animation": {
        "duration": 1,
        "onComplete": function() {
          var chartInstance = this.chart,
          ctx = chartInstance.ctx;

          ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
          ctx.textAlign = 'center';
          ctx.textBaseline = 'bottom';

          this.data.datasets.forEach(function(dataset, i) {
            var meta = chartInstance.controller.getDatasetMeta(i);
            meta.data.forEach(function(bar, index) {
              var data = dataset.data[index] + '%';
              ctx.fillText(data, bar._model.x, bar._model.y - 5);
            });
          });
        }
      },
    }
  }),
  mounted () {
    this.renderChart(this.chartdata, this.options)
  }
}
</script>

This runnable code below is the closest to a solution I have come by hours of searching.下面的可运行代码是我经过数小时的搜索得出的最接近解决方案的代码。 But it still won't do the trick because I don't know how to integrate it with what I have.但它仍然无法解决问题,因为我不知道如何将它与我所拥有的相结合。

 const labels = ['Red Vans', 'Blue Vans', 'Green Vans', 'Gray Vans']; const images = ['https://i.stack.imgur.com/2RAv2.png', 'https://i.stack.imgur.com/Tq5DA.png', 'https://i.stack.imgur.com/3KRtW.png', 'https://i.stack.imgur.com/iLyVi.png']; const values = [48, 56, 33, 44]; new Chart(document.getElementById("myChart"), { type: "bar", plugins: [{ afterDraw: chart => { var ctx = chart.chart.ctx; var xAxis = chart.scales['x-axis-0']; var yAxis = chart.scales['y-axis-0']; xAxis.ticks.forEach((value, index) => { var x = xAxis.getPixelForTick(index); var image = new Image(); image.src = images[index], ctx.drawImage(image, x - 12, yAxis.bottom + 10); }); } }], data: { labels: labels, datasets: [{ label: 'My Dataset', data: values, backgroundColor: ['red', 'blue', 'green', 'lightgray'] }] }, options: { responsive: true, legend: { display: false }, scales: { yAxes: [{ ticks: { beginAtZero: true } }], xAxes: [{ ticks: { padding: 30 } }], } } });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script> <canvas id="myChart" height="90"></canvas>

When I have added the plugin code into my own code I get an error message saying 'plugins' is already defined in props, but I can't manage to use it somehow.当我将插件代码添加到我自己的代码中时,我收到一条错误消息,提示“插件”已在道具中定义,但我无法设法以某种方式使用它。

Anyone who knows how to implement this afterDraw plugin into my code?谁知道如何在我的代码中实现这个 afterDraw 插件? I appreciate any input.我感谢任何意见。

Thanks a lot in advance: :)非常感谢::)

In the mounted of your vue component you can call the addPlugin (has to be done before the renderChart method) like this:在你的 vue 组件的挂载中,你可以像这样调用 addPlugin (必须在 renderChart 方法之前完成):

this.addPlugin({
  id: 'image-label',
  afterDraw: (chart) => {      
      var ctx = chart.chart.ctx; 
      var xAxis = chart.scales['x-axis-0'];
      var yAxis = chart.scales['y-axis-0'];
      xAxis.ticks.forEach((value, index) => {  
        var x = xAxis.getPixelForTick(index);      
        var image = new Image();
        image.src = images[index],
        ctx.drawImage(image, x - 12, yAxis.bottom + 10);
      });      
    }
})

Documentation: https://vue-chartjs.org/api/#addplugin文档: https://vue-chartjs.org/api/#addplugin

It works in ChartJS version 4.0.1.它适用于 ChartJS 版本 4.0.1。 data needs to return 'plugins':数据需要返回“插件”:

data() {
    return {
        plugins: [{
            afterDraw: chart => {
                    const ctx = chart.ctx;
                    const xAxis = chart.scales['x'];
                    const yAxis = chart.scales['y'];
                    xAxis.ticks.forEach((value, index) => {
                        let x = xAxis.getPixelForTick(index);
                        ctx.drawImage(images[index], x - 12, yAxis.bottom + 10)
                    });
                }
        }],
        data: {...

Please note that ctx should be chart.ctx and NOT chart.chart.ctx.. Similarly, it should be chart.scales['x'] and NOT chart.scales['x-axis-0'].请注意 ctx 应该是 chart.ctx 而不是 chart.chart.ctx.. 同样,它应该是 chart.scales['x'] 而不是 chart.scales['x-axis-0']。

After you return plugins, this needs to be referenced in your Bar component like so..返回插件后,需要像这样在 Bar 组件中引用它。

<Bar :data="data" :options="options" :plugins="plugins"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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