在图表顶部绘制图像不适用于 ChartJS

Drawing images on top of graph doesn't work with ChartJS

我正在尝试用我用 drawImage() 函数绘制的图标来标记饼图,但它不起作用。这是我的代码:

var config = {
  type: 'pie',
  data: {
    datasets: [{
      data: [
        "1",
        "2"
      ]
    }],
    labels: [
      "1",
      "2"
    ]
  }
};
var ctx = document.getElementById('Chart1').getContext('2d');
var myChart = new Chart(ctx, config);

var image = new Image();
image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAA1BMVEX/AAAZ4gk3AAAASElEQVR4nO3BgQAAAADDoPlTX+AIVQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwDcaiAAFXD1ujAAAAAElFTkSuQmCC';
image.onload = () => {
  ctx.drawImage(image, 0, 0, 100, 100)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="Chart1"></canvas>

我想让它在图表顶部绘制图像,但它不起作用,有什么想法吗?

问题是 chartJs 通过清除它并重新渲染整个东西来不断更新 canvas,比如在悬停和鼠标移动时添加标签和做一些动画,所以你添加到canvas会丢失

自 github 讨论以来 github discussion regarding the same issue is the way to go. You just need to create a new chart type extending the existing chart type you want to use where you can override the draw method of the new chart type to do the extra stuff you want, the syntax for extending the charts has changed 中的解决方法,因此我们将使用新的解决方法:

Chart.defaults.pieWithExtraStuff = Chart.defaults.pie;                // the name of the new chart type is "pieWithExtraStuff"

Chart.controllers.pieWithExtraStuff = Chart.controllers.pie.extend({  // creating the controller for our "pieWithExtraStuff" chart by extending from the default pie chart controller
  draw: function(ease) {                                              // override the draw method to add the extra stuff
    Chart.controllers.pie.prototype.draw.call(this, ease);            // call the parent draw method (inheritance in javascript, whatcha gonna do?)

    var ctx = this.chart.ctx;                                         // get the context
    if (this.labelIconImage) {                                        // if the image is loaded
      ctx.drawImage(this.labelIconImage, 0, 0, 100, 100);             // draw it
    }
  },
  initialize: function(chart, datasetIndex) {                         // override initialize too to preload the image, the image doesn't need to be outside as it is only used by this chart
    Chart.controllers.pie.prototype.initialize.call(this, chart, datasetIndex);

    var image = new Image();
    image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAA1BMVEX/AAAZ4gk3AAAASElEQVR4nO3BgQAAAADDoPlTX+AIVQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwDcaiAAFXD1ujAAAAAElFTkSuQmCC';
    image.onload = () => {                                            // when the image loads
      this.labelIconImage = image;                                    // save it as a property so it can be accessed from the draw method
      chart.render();                                                 // and force re-render to include it
    };
  }
});



var config = {
  type: "pieWithExtraStuff",                                          // use our own chart type, otherwise what's the point?
  data: { /* ... */ }
};

var ctx = document.getElementById('Chart1').getContext('2d');
var myChart = new Chart(ctx, config);

现在,每当 pieWithExtraStuff 图表重新呈现时,它也会绘制图像。

演示:

Chart.defaults.pieWithExtraStuff = Chart.defaults.pie;

Chart.controllers.pieWithExtraStuff = Chart.controllers.pie.extend({
  draw: function(ease) {
    Chart.controllers.pie.prototype.draw.call(this, ease);

    var ctx = this.chart.ctx;
    if (this.labelIconImage) {
      ctx.drawImage(this.labelIconImage, 0, 0, 100, 100);
    }
  },
  initialize: function(chart, datasetIndex) {
    Chart.controllers.pie.prototype.initialize.call(this, chart, datasetIndex);

    var image = new Image();
    image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAAAA1BMVEX/AAAZ4gk3AAAASElEQVR4nO3BgQAAAADDoPlTX+AIVQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwDcaiAAFXD1ujAAAAAElFTkSuQmCC';
    image.onload = () => {
      this.labelIconImage = image;
      chart.render();
    };
  }
});



var config = {
  type: "pieWithExtraStuff",
  data: {
    datasets: [{
      data: [
        "1",
        "2"
      ]
    }],
    labels: [
      "1",
      "2"
    ]
  }
};

var ctx = document.getElementById('Chart1').getContext('2d');
var myChart = new Chart(ctx, config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="Chart1"></canvas>