如何在vue项目中导出Hcharts图表
功能需求
今天小白同学想和大家分享一下如何在vue项目中导出Hcharts图表(正好我现在的产品中有这么一个需求)
需求分析以及资料查询
我现在的产品中,有大量图表需求,所使用的插件为Hcharts,所有的图表都需要支持下载,当我看到这个需求的时候,我第一时间去查询了Hcharts的官方API,发现了这个:
很好,但是我不想要Hcharts自带的这个导航菜单怎么办呢,没关系,继续往下看:
看到这里如果您不是在vue项目中使用,那么就可以停止前进了,官方API文档已经可以实现导出图片了,但是我想在vue项目中使用,一时摸不着头脑,因为需要引入如下文件:
<script src="http://cdn.hcharts.cn/highcharts/highcharts.js"></script>
<!-- 需要保存导出功能模块文件是在 highcharts.js 之后引入 -->
<script src="http://cdn.hcharts.cn/highcharts/modules/exporting.js"></script>
<!-- 客户端导出功能模块为可选选项 -->
<script src="http://cdn.hcharts.cn/highcharts/modules/offline-exporting.js"></script>
但是我们import进项目之后,插件包内的js文件我们可能并不能直接调用,于是再继续Google,但是相关文档真的很少,找到寥寥几篇也很不详细,终于我看到了一个看上去好像能解决这个问题的:
看样子是需要引入一个叫vue-highcharts的包,然后再进行一些相关API的调用,但是怎么调用呢?文档到了引入之后又没有了。我卡了有一两个小时,一时不知道怎么搞,在洗了把脸之后,我决定更换思路。
解决
我决定不使用Hcharts的官方js文件以及官方API,自己实现这个图表导出功能。
我的思路如下:
利用html2canvas实现html转canvas→canvas转base64→获取base64赋值给img标签→代码实现下载
看上去很烦是不是,但其实很快,我从想到这个思路到最后实现下载也不过只用了20分钟,下面我将把代码贴上。
第一步:下载html2canvas,命令行如下:npm install html2canvas --s
第二步:在你的图表组件中引入:import html2canvas from 'html2canvas’
第三步:在你的methods里面或者common.js内加上如下两个方法(canvas转图片以及模拟a标签图片点击下载):
// canvas转图片 参数canvas为DOM canvas
convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
},
// 模拟a标签图片下载 data为base64字符串 filename为你自定义的下载图片名
saveFile(data, filename) {
const save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
save_link.href = data;
save_link.download = filename;
const event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
save_link.dispatchEvent(event);
}
第四步:在你的按钮点击事件方法内加入这段代码(图表组件内):
//document.getElementsByClassName("chartView")[0])为你自定义的包含图表的父级div的类名
let that = this;
html2canvas(document.getElementsByClassName("chartView")[0]).then(function(canvas) {
document.body.appendChild(canvas);
let canvasDom = document.getElementsByTagName("canvas")[0]
canvasDom.style.display = "none";
that.ad.saveFile(that.ad.convertCanvasToImage(canvasDom).src,"canvasImg");
document.body.removeChild(canvasDom);
});
OJ8K,到这里下载已经完成。下面我想对第四段代码段做一些注释:
html2canvas(document.getElementsByClassName("chartView")[0]).then(function(canvas) {}
这是html2canvas的API,所需要自定义的是这个:document.getElementsByClassName(“chartView”)[0],这个是你图表的父级div,html2canvas插件会获取你传入的dom,然后把整段HTML代码段内的内容全部转成canvas,并动态地添加在body中,我在方法内让这个canvas“display:none”了,如果你想查看效果可以把这段代码注释。
that.ad.saveFile(that.ad.convertCanvasToImage(canvasDom).src,"canvasImg");
这段代码的saveFile以及convertCanvasToImage方法就是我第三步中的两个方法,为什么会有this.ad呢,这里是我把这两个方法放在了我的common.js中了,而我又把我的common.js挂载到了vue上同时命名为ad,所以我在这里用this.ad.saveFile调用,如果你放在了你的当前组件内,那么直接用this.saveFile就可以调用了。
最后,当导出完成的时候千万不要忘了把这个动态生成的canvas给删掉哦:
document.body.removeChild(canvasDom);
下面我们来看下效果:
写在最后
当你卡在某个地方过久的时候,不妨换个思路,或许很快就能解决哦。希望这边文档能给您带来一些帮助,感谢阅读。