echarts导出图片
一、echarts内置导出
众所周知,echarts是有专门的工具栏可以帮助我们导出图片的,就是我们的toolBox
工具栏配置项,其内置导出图片,数据视图,动态类型切换,数据区域缩放,重置五个工具。
既然ehcarts都提供了这么丰富的工具栏,那俺为啥还要大费周章呢(摸鱼它不香嘛)🤔
导出图片的样式不能自定义,虽然它支持更改图标以及更改颜色,但却不符合咱项目的UI设计/(ㄒoㄒ)/~~。
产品要求导出图片时图片能大一点,不要跟页面的布局一样小小的。
当出现dataZoom数据缩放的滚动条时,用户滚动后再点击导出图片,是只能看到当前的缩放后的echarts图片滴。
toolBox - saveAsImage配置项中有一个
excludeComponents
的属性,可以忽略导出图片的组件(看到这个真给我高兴坏了😍),结果一设置才知道,确实是忽略掉了dataZoom滚动条,但导出时还是滚动缩放后的echarts图片😅。
SO!!基于上述条件,咱不得不开始水(bushi)这篇文章了。
二、初步探索
first of all,居然echarts有导出图片的功能,那会不会有对应导出图片的API ?!
事不宜迟,马上度娘->echarts->文档->API
果然echarts实例化后提供一个
getDataURL()
的方法,里面可自定义导出格式,导出分辨率,导出图片背景色,以及可以选择导出时忽略echarts组件的图片。
(opts: {
// 导出的格式,可选 png, jpg, svg
// 注意:png, jpg 只有在 canvas 渲染器的时候可使用,svg 只有在使用 svg 渲染器的时候可用
type?: string,
// 导出的图片分辨率比例,默认为 1。
pixelRatio?: number,
// 导出的图片背景色,默认使用 option 里的 backgroundColor
backgroundColor?: string,
// 忽略组件的列表,例如要忽略 toolbox 就是 ['toolbox']
excludeComponents?: Array.<string>
}) => string
second,解决用户拖拉滚动条,导致导出图片数据不全的问题。
这个easy,直接新创建一个画布,再拿到当前echarts的配置项,创建一个echarts对象,再通过
getDataURL()
这个方法不就美滋滋的解决了嘛。顺便还将导出图片大小的问题解决了,唔~~~
三、代码实现初实现
俗话说的好,don‘bb show me your code
export async function exportEchartsImg(chart, imgOption = {}) {
// 创建画布元素
let canvas = document.createElement("canvas");
canvas.width = imgOption.chartWidth || chart.getWidth();
canvas.height = imgOption.chartHeight || chart.getHeight();
// 创建 ECharts 实例并绑定到容器
let myChart = echarts.init(canvas);
let option = JSON.parse(JSON.stringify(chart.getOption()));
// 修改图表配置项,
option.dataZoom = [];
myChart.setOption(option);
// echarts的API方法:getDataURL() 获取图片
let imageData = await myChart.getDataURL({
type: "png",
pixelRatio: 1,
excludeComponents: ["toolbox", "dataZoom"],
});
// 创建链接元素并下载图片
let link = document.createElement("a");
link.href = imageData
link.download = imgOption.imgName || "chart.png";
link.click();
// 释放资源
canvas.remove();
link.remove();
},
我直接一个导出
我图呢!?!?我柱子呢!?
四、问题解决
GPT启动!! 百度启动!!
在我不断尝试gpt输出的答案之后,我看到了这一幕
根据我实习‘两年半’的经验,我发现既然柱状图的label属性和数据都已经渲染上去了,那不应该柱子没有啊,难道是因为这个动画的原因,导致我的柱子并没有出现?!
说时迟那时快,通过我不断的‘走访调查’后发现,ECharts 是默认使用动画效果来进行图表的异步渲染的,这就可能会导致当我init完echarts之后,直接调用
getDataURL()
柱状图的动画效果并没有渲染完毕。
1. 解决方法
我直接一个
animation:false
取消掉动画的渐变渲染过程,让其返璞归真,展示它最纯真的一面。调用echarts API中的
finished
方法:渲染完成事件,当渲染完毕后再调用getDataURL()
的方法获取图片。
五、最终代码
export async function exportEchartsImg(chart, imgOption = {}) {
// 创建画布元素
let canvas = document.createElement("canvas");
canvas.width = imgOption.chartWidth || chart.getWidth();
canvas.height = imgOption.chartHeight || chart.getHeight();
// 创建 ECharts 实例并绑定到容器
let myChart = echarts.init(canvas);
let option = JSON.parse(JSON.stringify(chart.getOption()));
// 修改图表配置项,
this.modifyChartOption(option); //自己定义个方法,对option进行一些操作,展示出你想要的导出图片的样子
myChart.setOption(option);
// echarts的API方法:getDataURL() 获取图片
let imageData = await myChart.getDataURL({
type: "png",
pixelRatio: 1,
excludeComponents: ["toolbox", "dataZoom"],
});
// 创建链接元素并下载图片
let link = document.createElement("a");
link.href = imageData
link.download = imgOption.imgName || "chart.png";
link.click();
// 释放资源
canvas.remove();
link.remove();
},
modifyChartOption(option){
option.dataZoom = [];
// 将图表配置series中的animation去掉,防止导出图片时动画没开始 数据没渲染
option.series.forEach((element) => {
element["animation"] = false;
element.label["color"] = "#000";
});
option.xAxis.forEach((item) => {
item.axisLabel["color"] = "#494949";
});
option.yAxis.forEach((item) => {
item.axisLabel["color"] = "#494949";
});
}
六、ending
望你我都能在茫茫人海中找到那属于自己的星光,用坚定的步伐走向理想的彼岸,不负韶华的光阴。✨