html2canvas Chart.js 图表未呈现

Posted

技术标签:

【中文标题】html2canvas Chart.js 图表未呈现【英文标题】:html2canvas Chart.js chart not rendered 【发布时间】:2018-02-09 07:22:09 【问题描述】:

我正在尝试将包含 Chart.js 图表的 div 导出为 Iamge。所有元素都显示得非常好,但是 Chart.js 画布没有被渲染。

我在图表中 onAnimationComplete 选项的回调中调用我的导出函数,因此在图表完全构建之前无法进行导出。

这是我的 html2canvas 和下载功能的外观:

download() 
        this.dl.download = this.fileName;
        this.dl.click();


loadDataUrl($node) 
    this.hideUnwantedElements();
    html2canvas($node, 
        background: '#ffffff',
        scale: 4,
        proxy: 'proxy-for-cors-images',
        onrendered: (canvas) => 
            this.showElements();
            this.dl.href = canvas.toDataURL('image/jpeg');
        );

谁能告诉我是否可以使用 html2canvas 导出 Chart.js 图表,如果可以,怎么做? 我还在图表画布上尝试了 toDataURL() 函数,但它只返回透明 png 的数据 URL。

【问题讨论】:

【参考方案1】:

是的!可以使用html2canvas导出(另存为图像)图表(使用ChartJS创建)

方法如下:

var isChartRendered = false;

var chart = new Chart(ctx, 
   type: 'line',
   data: 
      labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
      datasets: [
         label: 'LINE',
         data: [3, 1, 4, 2, 5],
         backgroundColor: 'rgba(0, 119, 290, 0.2)',
         borderColor: 'rgba(0, 119, 290, 0.6)',
         fill: false
      ]
   ,
   options: 
      // setting following option is mandatory
      animation: 
         onComplete: function() 
            isChartRendered = true
         
      
   
);

function download() 
   if (!isChartRendered) return; // return if chart not rendered
   html2canvas(document.getElementById('chart-container'), 
      onrendered: function(canvas) 
         var link = document.createElement('a');
         link.href = canvas.toDataURL('image/jpeg');
         link.download = 'myChart.jpeg';
         link.click();
      
   )
#chart-container  background: white 
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<button onclick="download()">save chart as...</button>
<div id="chart-container">
   <canvas id="ctx"></canvas>
</div>

PS:不用说,但很明显,这只是一个例子,您需要在您的项目中相应地采用它。

【讨论】:

非常感谢我尝试在我的项目中使用它的那个例子,但它仍然不能渲染画布。我还在 onComplete callack 中创建了一个 console.log,它在动画完成之前出现在控制台中。这正常吗? 不,不是。你用的是哪个版本的chartjs?确保使用最新的 - 2.6.0 Chart.js 版本 2.6.0 那么,也许您没有正确创建图表。在动画完成之前,onComplete 函数无法运行。也许,仔细检查一切...... 我现在设法通过在 onComplete 回调中添加 setTimeout 来重新绘制画布。但是,这绝不是解决我的问题的好方法,我无法真正理解为什么我的 onComplete 过早触发..【参考方案2】:

以防万一其他人在 Chart.js 中过早触发 onComplete 回调时遇到同样的问题,以下是我能够在不添加 setTimeout 的情况下修复它的方法:

这是动画完成后加载我的导出数据的正确方法

animation: 
   onComplete: () => 
   this.loadExportElements();
   

我的第一种方法看起来像这样,但没有奏效:

animation: 
                onComplete: this.loadExportElements()

【讨论】:

【参考方案3】:

onRendered 现已弃用

//我们正在针对图例并等待承诺完成,如果您不希望图例出现,您可以跳过这部分

html2canvas($("#yourChartID").find("ul")[0]).then(grid1Legend => 

   var pdf = new jsPDF('l', 'pt', 'a3');
  var chart1 = $("#yourChartID").get(0).toDataURL("image/png", 1.0);
  var grid1LegendtoUrl = grid1Legend.toDataURL("image/jpeg", 1.0);
  pdf.text(675, 275,"my chart");
  pdf.addImage(chart1, 'JPEG', 590, 325);
  pdf.addImage(grid1LegendtoUrl, 'JPEG', 465, 475);
  pdf.save("state_summary.pdf");



);

基本上 html2canvas 不会保存您的画布,您可以做的是使用 get(0) 将 htmltocanvas 指向画布图表(chart.js),这将捕获图表然后手动添加图例和标题,如上所示并设置正确的坐标。

【讨论】:

以上是关于html2canvas Chart.js 图表未呈现的主要内容,如果未能解决你的问题,请参考以下文章

chart.js轻量级图表插件使用

在函数内部创建图表时,销毁 chart.js 不起作用 - chart.destroy() 不是函数

Chart js 更新多个图表

使用Vue.js 和Chart.js制作绚丽多彩的图表

在 Chart.js 中设置图表高度

vue.js 图表chart.js使用