echarts柱状图带滚动条时,实现截图

需求:

需要用柱状图展示每个部门的数据,以部门作为横轴,数据作为纵轴。如果部门超过一定数量,为了不让柱状图上每个部门被压缩得太小,柱状图使用滚动条更清楚地展示每个部门的数据。并且页面上有个导出按钮,能够下载柱状图为图片格式到本地。(vue框架内使用)

一般实现echarts截图办法:

常用的两种截取echarts图的方法

1、echarts图本身自带的截图,能够在柱状图上显示一个下载的图标,点击图标实现下载图片到本地。

用法:直接在echarts的options中配置

 toolbox: { show: true, feature: { saveAsImage: {} } }, 

2、通过canvas的方式,创建canvas画布,将前端需要截取的dom绘制到canvas里,再使用canvas自带函数将其转换为base64格式,再调用函数将base64格式文件转换为file格式,最后调用接口将file格式文件传给后端,后端处理后,将图片下载到本地。(将base64转换为file格式这步,具体看后端需要什么格式)(代码在最后面)

两种方式比较

第一种,相对简单,且不需要调用接口。但是echarts自带的下载图标不好调整,要是有比较严格的样式要求就不行。

第二种,能自定义下载点击触发事件的样式,但是效率比较低,图片下载起来相对比较慢。

但是至此需求还没有实现

上面两种解决方式都可以实现截图,但是当echarts图带上滚动条后就会产生问题。

如果是在echarts的options配置里面通过dataZoom来设置滚动条,大概会达到下面的效果,滚动条在柱状图上。通过设置当数据大于某个数值时柱状图上的滚动条出现。 

这样的图是非常动态的,滑动滚动条时纵坐标和横坐标都会变化。这就说明,滚动条以外,未展示的区域还没有生成,所以不论是使用第一种或者是第二种方式进行截图,只要滚动条在柱状图上,就只能截取当前展示的部分,无法实现完整截图。

改进思路:

1、生成echarts图时就全部生成,柱状图不再改变。

2、为了适应页面宽度,echarts图区域宽度为100%,外侧父容器宽度动态变化。再外层容器宽度固定。

具体代码

<div style='width:1613px'>
    <div class="column-container" style="overflow-x: auto" id="export-region">
        <div
          ref="countRedBlack"
          class="echarts-box"
          style="height: 400px; background-color: #fff"
          :style="{ width: echartsDomWidth }"
        ></div>
     </div>
</div>
 data() {
    return {
      echartsData: null,//柱状图的数据
      barChart: null,
      echartsDom: null,//获得生成柱状图的dom区域
      echartsDomWidth: ""//柱状图dom区域的宽度 动态变化
    };
  },

watch: {
//监听 柱状图dom区域的宽度 的变化,宽度随着数据量的改变而变化,数据量改变-->重新绘图 and 宽度变化
    echartsDomWidth() {
      this.$nextTick(() => {
        this.disposeCharts();//销毁原来柱状图的函数
        this.initEcharts();//重新生成柱状图的函数
      });
    }
  },
methods(){
    //销毁柱状图
    disposeCharts() {
          echarts.dispose(this.barChart);
        },

    //销毁柱状图
    initEcharts(){
    //根据具体需求生成柱状图
    //需要注意的是 不能设置dataZoom,在柱状图上展示滚动条
    
    //关键代码
    //获取柱状图数据
      this.echartsData = await this.getEchartsData();

      //柱状图区域宽度动态变化  此处我设置的是 当数据量大于8时柱状图区域宽度增加,因为内部宽度超过了外部容器宽度,区域内就会出现浏览器自带滚动条
      if (
        this.echartsData.length > 8 &&
        parseInt(this.echartsDomWidth) < 1613
      ) {
        this.echartsDomWidth =
          this.echartsDom.offsetWidth +
          (this.echartsData.length - 8) * 200 +
          "px";
      }
        }
    
    //截图
handleExport() {
      //生成url
      const canvas = document.createElement("canvas"); //生成canvas标签
      const canvasBox = document.getElementById("export-region"); //得到柱状图的dom
      const scrollWidth = canvasBox.scrollWidth; //柱状图区域包括滚动区域在内的宽度
      const offsetHeight = canvasBox.offsetHeight;
      canvasBox.setAttribute(
        "style",
        `width:${scrollWidth};height:${offsetHeight}`
      ); //把柱状图区域的宽高赋值给dom 因为canvas需要宽改一致才能实现截图
      canvas.width = scrollWidth;
      canvas.height = offsetHeight;
      const options = {
        backgroundColor: null,
        canvas: canvas,
        useCORS: true,
        allowTaint: true,
        tainTest: false
      };
      html2canvas(canvasBox, options).then(canvas => {
        let imgUrl = canvas.toDataURL("image/png");
        //将base64文件转换为file
        let file = dataURLFile(imgUrl, "plusMinus.png");
        //组织参数
        let formData = new FormData();
        formData.append("redblackGraphFile", file, "截图.png");
        //调用接口导出图片
        exportEcharts(formData).then(res => {
          let resBlob = new Blob([res.data], { type: "application/x-xlsx" });
          let fileUrl = window.URL.createObjectURL(resBlob);
          let link = document.createElement("a");
          link.href = fileUrl;
          link.setAttribute(
            "download",
            "带滚动条柱状图导出_" + formatDate(+new Date(), "YYYY_MM_DD") + ".xlsx"
          );
          //防止导出一遍后柱状图上的滚动条消失
          canvasBox.setAttribute("style", `overflow-x:auto`);
          link.click();
        });
      });
    },
    }

此方法对柱状图自带的saveAsImage同样有用,能完整的截出柱状图。最重要的思路就是,让柱状图一开始就完全生成,滚动条使用浏览器自带的滚动条,而不是echarts的滚动条。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值