繁体   English   中英

无法使用 toDataURL() 转换带有图表和图像的 Canvas

[英]Not able to convert Canvas with chart and images using toDataURL()

我有一个带有标签作为图像的条形图(使用chart.js),当我尝试将画布导出为图像时,它仅导出图表部分而不是图像(标签),而是在我右键单击并另存为图像时导出相同的画布能够正确导出(图表和标签图像)。

有人可以帮我解决这个问题。

我的js文件:

var config = {
    type: 'horizontalBar',
  data: {
    labels:['a', 'b', 'c', 'd', 'e', 'f'],
    datasets: [
      {
        data: [ "20", "10", "2", "5", "1", "22" ],
        backgroundColor: [ '#f1f33a', '#99d695', "#cc8e50", '#ec9089', '#8e7bd4', '#eef5ce' ]   
      }]
  },
  options: {
    animation: {
      duration: 1,
      onComplete: function(charttt) {
        var chartInstance = charttt.chart,
        ctx = chartInstance.ctx;

        ctx.textAlign = 'right';
        ctx.textBaseline = 'bottom';

        this.data.datasets.forEach(function (dataset) {
            var meta = chartInstance.controller.getDatasetMeta(i);
            meta.data.forEach(function (bar, index) {
                var img = new Image();
                img.src = 'https://i.imgur.com/yDYW1I7.png';
                var data = dataset.data[index];

                ctx.fillStyle = 'red';
                ctx.fillText(data, bar._model.x - 20, bar._model.y - 10);
                img.onload = function() {
                  ctx.drawImage(img, bar._model.x, bar._model.y, 10, 10);
                }
            });
        });
        var url = document.getElementById('barChart').toDataURL('image/png');
        document.getElementById("testimg").src = url;
        }
    },
    legend: {
      "display": false
    },
    responsive:false,
    chartArea: {
        backgroundColor: 'blue'
    }
  }
};

var ctx = document.getElementById("barChart").getContext("2d");
var chartt = new Chart(ctx, config);

我想你的问题是在这里...

    this.data.datasets.forEach(function (dataset) {
        var meta = chartInstance.controller.getDatasetMeta(i);

您正在尝试获取数据集i的元数据
i没有定义

需要将参数添加到forEach函数中

    this.data.datasets.forEach(function (dataset, i) {  // <-- here
        var meta = chartInstance.controller.getDatasetMeta(i);

请参阅以下工作片段...

 $(document).ready(function() { var config = { type: 'horizontalBar', data: { labels:['a', 'b', 'c', 'd', 'e', 'f'], datasets: [ { data: [ "20", "10", "2", "5", "1", "22" ], backgroundColor: [ '#f1f33a', '#99d695', "#cc8e50", '#ec9089', '#8e7bd4', '#eef5ce' ] }] }, options: { animation: { duration: 1, onComplete: function(charttt) { var chartInstance = charttt.chart, ctx = chartInstance.ctx; ctx.textAlign = 'right'; ctx.textBaseline = 'bottom'; this.data.datasets.forEach(function (dataset, i) { var meta = chartInstance.controller.getDatasetMeta(i); meta.data.forEach(function (bar, index) { var img = new Image(); img.src = 'https://i.imgur.com/yDYW1I7.png'; var data = dataset.data[index]; ctx.fillStyle = 'red'; ctx.fillText(data, bar._model.x - 20, bar._model.y - 10); img.onload = function() { ctx.drawImage(img, bar._model.x, bar._model.y, 10, 10); } }); }); var url = document.getElementById('barChart').toDataURL('image/png'); document.getElementById("testimg").src = url; } }, legend: { "display": false }, responsive:false, chartArea: { backgroundColor: 'blue' } } }; var ctx = document.getElementById("barChart").getContext("2d"); var chartt = new Chart(ctx, config); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script> <canvas id="barChart"></canvas> <img id="testimg"/>


编辑

有两个问题导致图像没有出现在导出中。

首先,添加来自另一个域的图像会污染画布。
之后,安全错误将阻止画布导出。
解决方法是将crossorigin属性添加到要添加到图表的图像。

img.setAttribute('crossorigin', 'anonymous');

接下来,在导出图表之前,
我们必须等待所有图像加载完毕,
img.onload事件中。

请参阅以下工作片段...

 $(document).ready(function() { var config = { type: 'horizontalBar', data: { labels:['a', 'b', 'c', 'd', 'e', 'f'], datasets: [ { data: [ "20", "10", "2", "5", "1", "22" ], backgroundColor: [ '#f1f33a', '#99d695', "#cc8e50", '#ec9089', '#8e7bd4', '#eef5ce' ] }] }, options: { animation: { duration: 1, onComplete: function(charttt) { var chartInstance = charttt.chart, ctx = chartInstance.ctx; ctx.textAlign = 'right'; ctx.textBaseline = 'bottom'; var countDatasets = this.data.datasets.length; this.data.datasets.forEach(function (dataset, i) { var meta = chartInstance.controller.getDatasetMeta(i); var countMeta = meta.data.length; meta.data.forEach(function (bar, index) { var img = new Image(); img.setAttribute('crossorigin', 'anonymous'); img.src = 'https://i.imgur.com/yDYW1I7.png'; var data = dataset.data[index]; ctx.fillStyle = 'red'; ctx.fillText(data, bar._model.x - 20, bar._model.y - 10); img.onload = function() { ctx.drawImage(img, bar._model.x, bar._model.y, 10, 10); countMeta--; if (countMeta === 0) { countDatasets--; } if ((countDatasets === 0) && (countMeta === 0)) { var url = document.getElementById('barChart').toDataURL('image/png'); document.getElementById("testimg").src = url; } } }); }); } }, legend: { "display": false }, responsive:false, chartArea: { backgroundColor: 'blue' } } }; var ctx = document.getElementById("barChart").getContext("2d"); var chartt = new Chart(ctx, config); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script> <canvas id="barChart"></canvas> <img id="testimg"/>

暂无
暂无

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

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