ChartJS 2.7.0更新并导出为png

时间:2017-11-03 09:35:00

标签: jquery chart.js

所以我有一个ChartJS图表,我正在尝试更新此图表的标题,到目前为止我已经使它工作并显示新标题! (哇噢)。

然而,当我尝试导出其新标题显示的图表时,我的问题出现了。

我正在转换为base64 png。创建一个a-tag,以编程方式单击a-tag,然后删除a-tag,最后将标题更改回旧标题。

直到我试图用新标题保存图表作为base64 png一切正常。然后新标题不在导出的.png

function downloadImage($id) {
console.log("");
console.log("*///// SAVING /////*");

//get the charts variable name (stored as a data-attribute on the canvas element called chart-var)
var chart_variable_name = $("#" + $id).data('chart-var');
//convert this to a usable variable instead of a string
var chart_variable = eval(chart_variable_name);

console.log("");
console.log("Get Chart Variable");
console.log(chart_variable);

//get canvas element using id passed in
var ctx = $("#" + $id);
//get data-export-title attribute (multiline title with Title, Date, Source)
var exportTitle = $(ctx).data('export-title');

console.log("");
console.log("Get Chart");
console.log(ctx);

console.log("");
console.log("Get Chart Export Title");
console.log(exportTitle);

//get the old title from the ChartJS Object (ready to use for going back to old title)
var old_title = chart_variable.options.title.text;

console.log("");
console.log("Get Chart Old Title");
console.log(old_title);

// get the exportTitle as an array, this will allow for MultiLine titles on export
arr = exportTitle.split(',');

console.log("");
console.log("Get Chart New Title");
console.log(arr);

//push String "Title" + old_title variable so we have the title added at the end of the array
arr.push("Title: " + old_title);

//set the charts title text to the new Multiline export title.
chart_variable.options.title.text = arr;

//run the update on the chart
chart_variable.update();

chart_variable = eval(chart_variable_name);

console.log("");
console.log("Get Chart Current Options");
console.log(chart_variable.options);

//convert the chart to a base64 link PNG
var newBase64 = chart_variable.toBase64Image();

//insert an <a> tag which is hidden, before the save button - irrelevant where it goes as it wont be seen but for consistency
$("<a id='" + $id + "-button-temp' style='display:none;' class='button-style' href='" + newBase64 + "' download='" + $id + ".png' >Download</a>").insertAfter($('#' + $id + '-button'));

    //programmatically find and click the <a> tag to initiate the download of the image
   ($(document).find("#" + $id + "-button-temp")[0]).click();

   //programmatically remove the <a> tag so we dont clutter the page with unecessary HTML that are hidden
   ($(document).find("#" + $id + "-button-temp")[0]).remove();

   //set chart title back to previous title
  //chart_variable.options.title.text = old_title;
}

有没有人知道为什么会发生这种情况......?

1 个答案:

答案 0 :(得分:4)

这种情况正在发生,因为当您通过调用update()方法更新图表(更改标题后)时,它会使用动画重新呈现整个图表,需要一些时间(约1000毫秒)才能完成,使图表更新过程延迟,并且由于此过程是异步发生的,因此即使在图表完全更新之前,图像保存代码也会执行,这使得新标题不会出现在导出的图像上。

基本上,你需要的是在更改图表标题后更新图表而不用动画(同步),这可以通过以下两种方式之一完成:

1。使用 config update对象(参数)传递给duration方法>属性设置为 0

chart_variable.update({
   duration: 0
});

2。仅将 0 作为参数传递给update方法(请参阅preventing animations

chart_variable.update(0);

ᴡᴏʀᴋɪɴɢ ᴅᴇᴍᴏ

var chart_variable = new Chart(ctx, {
   type: 'line',
   data: {
      labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
      datasets: [{
         label: 'My First Dataset',
         data: [3, 1, 4, 2, 5],
         backgroundColor: 'rgba(0, 119, 290, 0.2)',
         borderColor: 'rgba(0, 119, 290, 0.6)'
      }]
   },
   options: {
      title: {
         display: true,
         text: 'Chart Title'
      },
      scales: {
         yAxes: [{
            ticks: {
               beginAtZero: true,
               stepSize: 1
            }
         }]
      }
   }
});

function downloadImage() {
   /* set new title */
   chart_variable.options.title.text = 'New Chart Title';
   chart_variable.update({
      duration: 0
   });
   // or, use
   // chart_variable.update(0);

   /* save as image */
   var link = document.createElement('a');
   link.href = chart_variable.toBase64Image();
   link.download = 'myImage.png';
   link.click();

   /* rollback to old title */
   chart_variable.options.title.text = 'Chart Title';
   chart_variable.update({
      duration: 0
   });
   // or, use
   // chart_variable.update(0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>

<button onclick="downloadImage();">save as image</button>
<canvas id="ctx"></canvas>