解决echarts配置滚动(dataZoom)后导出图片数据不全问题
先展现一个echarts,并配置dataZoom,每页最多10条数据,超出滚动
<div class="echartsBox" id="echartsBox"></div>
onMounted(() => {nextTick(() => {var chartDom = document.getElementById('echartsBox');myChart = echarts.init(chartDom);option = {grid: {left: '0px', // 图表左边距right: '50px', // 图表右边距top: '50px', // 图表上边距bottom: '0px', // 图表下边距containLabel: true // 包含坐标轴标签在内},graphic: [{type: 'text',left: '15', // 根据需要调整位置top: '20', // 根据需要调整位置z: 100, // 设置 z 轴数值较高,确保文本显示在最前面style: {text: '课程内容', // 指定要显示的文本fill: '#666666', // 文本颜色fontSize: '14px',}}],yAxis: {// name: '课程内容',type: 'category',data: ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10', 'A11', 'A12', 'A13', 'A14', 'A15', 'A16', 'A17', 'A18', 'A19', 'A20', 'A21', 'A22', 'A23', 'A24', 'A25'],inverse: true,},xAxis: {name: '得分',type: 'value',min: 5,max: 0,axisLabel: {formatter: function (value: any) {return Math.floor(value); // 取整数部分}},},dataZoom: [{type: "slider",realtime: true, // 拖动时,是否实时更新系列的视图// show:false, // 是否展示滚动条根据数据判断startValue: 0,endValue: 9, // 最多10条 超出滚动width: 5,height: "75%",top: "12.5%",right: 0,brushSelect: false,yAxisIndex: [0, 1], // 控制y轴滚动fillerColor: "#0093ff", // 滚动条颜色borderColor: "rgba(17, 100, 210, 0.12)",backgroundColor: "#cfcfcf", //两边未选中的滑动条区域的颜色handleSize: 0, // 两边手柄尺寸showDataShadow: false, //是否显示数据阴影 默认autoshowDetail: false, // 拖拽时是否展示滚动条两侧的文字zoomLock: true,moveHandleStyle: {opacity: 0,},},{type: "inside",startValue: 0,endValue: 10,minValueSpan: 10,yAxisIndex: [0],zoomOnMouseWheel: false, // 关闭滚轮缩放moveOnMouseWheel: true, // 开启滚轮平移moveOnMouseMove: true, // 鼠标移动能触发数据窗口平移},],series: [{data: [5, 0, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1],type: 'bar',label: {show: true,position: 'right',formatter: '{c}分', // 显示数值textStyle: {color: '#333',fontSize: 14}},itemStyle: {color: function (params: any) {// 根据数据值取整后选择颜色var value = Math.round(params.data);var colors = ['#A6A6A6', '#FF7F2D', '#FCC946', '#A2C081', '#619C8A', '#016B25'];return colors[value];}},}]};option && myChart.setOption(option);})
})
效果:
调用echarts中getDataURL获取图表的数据 URL
// 下载echarts
const downloadBtn = (() => {nextTick(() => {const loading = ElLoading.service({lock: true,text: '图表生成中',background: 'rgba(0, 0, 0, 0.7)',})// 需要3s左右生成setTimeout(() => {loading.close()// 获取图表的数据 URLvar dataURL = myChart.getDataURL({type: 'png', // 可以根据需要修改为其他格式,如 'jpeg'pixelRatio: 2, // 图片分辨率,根据需要进行调整backgroundColor: '#fff' // 图片背景色,根据需要进行调整});// 创建一个虚拟的下载链接并模拟点击下载var link = document.createElement('a');link.href = dataURL;link.download = 'echarts_image.png'; // 下载的文件名,可以根据需要修改link.style.display = 'none';document.body.appendChild(link);link.click();document.body.removeChild(link);}, 3000)})
})
问题来了:如数据不分页则可以下载全数据,如数据分页了则只能下载出可视区内容,如何解决?

解决思路:echarts最终生成了canvas,canvas的宽高就是当前可视区的宽高,那么是否可以动态计算高度???
解决:
新增一个容器,这个容器为动态计算高度后导出使用
<!-- 导出echarts使用 --><div id="newEchartsBox" style="display:none;"></div>
// 下载echarts
const downloadBtn = (() => {// 获取完整的数据const fullData = myChart.getOption();let newOption = fullDatanewOption.dataZoom = []// var chartDom: any = document.getElementById('newEchartsBox');chartDom.style.width = '600px'chartDom.style.height = 50 * fullData.series[0].data.length + 'px'// newMyChart = echarts.init(chartDom);// newOption && newMyChart.setOption(newOption);// nextTick(() => {const loading = ElLoading.service({lock: true,text: '图表生成中',background: 'rgba(0, 0, 0, 0.7)',})// 需要3s左右生成setTimeout(() => {loading.close()// 获取图表的数据 URLvar dataURL = newMyChart.getDataURL({type: 'png', // 可以根据需要修改为其他格式,如 'jpeg'pixelRatio: 2, // 图片分辨率,根据需要进行调整backgroundColor: '#fff' // 图片背景色,根据需要进行调整});// 创建一个虚拟的下载链接并模拟点击下载var link = document.createElement('a');link.href = dataURL;link.download = 'echarts_image.png'; // 下载的文件名,可以根据需要修改link.style.display = 'none';document.body.appendChild(link);link.click();document.body.removeChild(link);}, 3000)})
});
通过getOption获取echarts数据,根据数据长度动态设置新容器的高度,并赋值,赋值时把dataZoom清空,这里就不需要分页了,因为不做回显。
然后通过新容器调用echarts导出图片,问题完美解决。

源码如下:
<template><div class="kcnrzt"><div class="left"><div class="l">已选<br />课程内容</div><div class="r"><el-scrollbar><div class="list"><div class="item">11111111111111111111111111111111111111111111111111111111111111111</div><div class="item">11111111111111111111111111111111111111111111111111111111111111111</div><div class="item">11111111111111111111111111111111111111111111111111111111111111111</div><div class="item">11111111111111111111111111111111111111111111111111111111111111111</div><div class="item">11111111111111111111111111111111111111111111111111111111111111111</div><div class="item">11111111111111111111111111111111111111111111111111111111111111111</div></div></el-scrollbar></div></div><div class="right"><div class="exportBtn" @click="downloadBtn">导出报告</div><div class="echartsBox" id="echartsBox"></div></div></div><!-- 导出echarts使用 --><div id="newEchartsBox" style="display:none;"></div>
</template><script setup lang="ts">
import { ElLoading } from 'element-plus'
import { watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { dataStore } from '@/store'
let store = dataStore()
import * as echarts from 'echarts';//
var myChart: any = null
var option: any = null
// 导出专用
var newMyChart: any = nullonMounted(() => {nextTick(() => {var chartDom = document.getElementById('echartsBox');myChart = echarts.init(chartDom);option = {grid: {left: '0px', // 图表左边距right: '50px', // 图表右边距top: '50px', // 图表上边距bottom: '0px', // 图表下边距containLabel: true // 包含坐标轴标签在内},graphic: [{type: 'text',left: '15', // 根据需要调整位置top: '20', // 根据需要调整位置z: 100, // 设置 z 轴数值较高,确保文本显示在最前面style: {text: '课程内容', // 指定要显示的文本fill: '#666666', // 文本颜色fontSize: '14px',}}],yAxis: {// name: '课程内容',type: 'category',data: ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10', 'A11', 'A12', 'A13', 'A14', 'A15', 'A16', 'A17', 'A18', 'A19', 'A20', 'A21', 'A22', 'A23', 'A24', 'A25'],inverse: true,},xAxis: {name: '得分',type: 'value',min: 5,max: 0,axisLabel: {formatter: function (value: any) {return Math.floor(value); // 取整数部分}},},dataZoom: [{type: "slider",realtime: true, // 拖动时,是否实时更新系列的视图// show:false, // 是否展示滚动条根据数据判断startValue: 0,endValue: 9, // 最多10条 超出滚动width: 5,height: "75%",top: "12.5%",right: 0,brushSelect: false,yAxisIndex: [0, 1], // 控制y轴滚动fillerColor: "#0093ff", // 滚动条颜色borderColor: "rgba(17, 100, 210, 0.12)",backgroundColor: "#cfcfcf", //两边未选中的滑动条区域的颜色handleSize: 0, // 两边手柄尺寸showDataShadow: false, //是否显示数据阴影 默认autoshowDetail: false, // 拖拽时是否展示滚动条两侧的文字zoomLock: true,moveHandleStyle: {opacity: 0,},},{type: "inside",startValue: 0,endValue: 10,minValueSpan: 10,yAxisIndex: [0],zoomOnMouseWheel: false, // 关闭滚轮缩放moveOnMouseWheel: true, // 开启滚轮平移moveOnMouseMove: true, // 鼠标移动能触发数据窗口平移},],series: [{data: [5, 0, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1],type: 'bar',label: {show: true,position: 'right',formatter: '{c}分', // 显示数值textStyle: {color: '#333',fontSize: 14}},itemStyle: {color: function (params: any) {// 根据数据值取整后选择颜色var value = Math.round(params.data);var colors = ['#A6A6A6', '#FF7F2D', '#FCC946', '#A2C081', '#619C8A', '#016B25'];return colors[value];}},}]};option && myChart.setOption(option);})// window.addEventListener('resize', updateEcharts);
})
//
onBeforeUnmount(() => {myChart.dispose();// window.removeEventListener('resize', updateEcharts);
})
//
const updateEcharts = (() => {nextTick(() => {myChart.resize();})
})
//
watch(() => store.isCollapse,() => {setTimeout(() => { updateEcharts() }, 300);},{immediate: false, // 是否初始化立即执行一次, 默认是falsedeep: true // 是否是深度监视, 默认是false}
)// 下载echarts
const downloadBtn = (() => {// 获取完整的数据const fullData = myChart.getOption();let newOption = fullDatanewOption.dataZoom = []// var chartDom: any = document.getElementById('newEchartsBox');chartDom.style.width = '600px'chartDom.style.height = 50 * fullData.series[0].data.length + 'px'// newMyChart = echarts.init(chartDom);// newOption && newMyChart.setOption(newOption);// nextTick(() => {const loading = ElLoading.service({lock: true,text: '图表生成中',background: 'rgba(0, 0, 0, 0.7)',})// 需要3s左右生成setTimeout(() => {loading.close()// 获取图表的数据 URLvar dataURL = newMyChart.getDataURL({type: 'png', // 可以根据需要修改为其他格式,如 'jpeg'pixelRatio: 2, // 图片分辨率,根据需要进行调整backgroundColor: '#fff' // 图片背景色,根据需要进行调整});// 创建一个虚拟的下载链接并模拟点击下载var link = document.createElement('a');link.href = dataURL;link.download = 'echarts_image.png'; // 下载的文件名,可以根据需要修改link.style.display = 'none';document.body.appendChild(link);link.click();document.body.removeChild(link);}, 3000)})
});
</script><style scoped lang="scss">
.kcnrzt {flex: 1;display: flex;justify-content: space-between;overflow: hidden;margin: 20px 15px;.left {width: 50%;height: 100%;border: 1px solid #DEDEDE;display: flex;overflow: hidden;margin-right: 20px;.l {width: 87px;border-right: 1px solid #DEDEDE;display: flex;align-items: center;justify-content: center;text-align: center;overflow: hidden;}.r {flex: 1;overflow: hidden;.list {.item {padding: 10px;font-size: 14px;font-family: Microsoft YaHei;font-weight: 400;color: #333333;line-height: 22px;border-bottom: 1px solid #DEDEDE;}}}}.right {width: 50%;height: 100%;position: relative;margin-left: 20px;.exportBtn {width: 81px;height: 30px;background: #FFB100;border-radius: 6px;font-size: 14px;font-family: Microsoft YaHei;font-weight: 400;color: #FFFFFF;line-height: 30px;text-align: center;cursor: pointer;position: absolute;top: 0;right: 0;z-index: 999;}.echartsBox {width: 100%;height: 100%;}}
}
</style>
相关文章:
解决echarts配置滚动(dataZoom)后导出图片数据不全问题
先展现一个echarts,并配置dataZoom,每页最多10条数据,超出滚动 <div class"echartsBox" id"echartsBox"></div>onMounted(() > {nextTick(() > {var chartDom document.getElementById(echartsBox);…...
【vue3+ts】项目初始化
1、winr呼出cmd,输入构建命令 //用vite构建 npm init vitelatest//用cli脚手架构建 npm init vurlatest2、设置vscode插件 搜索volar,安装前面两个 如果安装了vue2的插件vetur,要禁用掉,否则插件会冲突...
c++视觉图像----扩充边界
图像扩充边界 #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp>int main() {// 读取图像cv::Mat image cv::imread("1.jpg", cv::IMREAD_COLOR);if (image.empty()) {std::cerr << "Could not open or find the imag…...
邮政编码,格式校验:@ZipCode(自定义注解)
目标 自定义一个用于校验邮政编码格式的注解ZipCode,能够和现有的 Validation 兼容,使用方式和其他校验注解保持一致(使用 Valid 注解接口参数)。 校验逻辑 有效格式 不能包含空格;应为6位数字; 不校验…...
Appium自动化测试框架:关键字驱动+数据驱动
1. 关键字驱动框架简介 原理及特点 关键字驱动测试是数据驱动测试的一种改进类型,它也被称为表格驱动测试或者基于动作字的测试。主要关键字包括三类:被操作对象(Item)、操作行为(Operation)和操作值&…...
简单多状态dp【动态规划】
目录 一、按摩师 二、打家劫舍 三、删除并获得点数 四、粉刷房子 五、买卖股票的最佳时机 六、买卖股票的最佳时机(含手续费) 七、买卖股票的最佳时机III 八、买卖股票的最佳时机IV 一、按摩师 class Solution { public:int massage(vector<int>…...
OpenCV中initUndistortRectifyMap ()函数与十四讲中去畸变公式的区别探究
文章目录 1.十四讲中的去畸变公式2. OpenCV中的去畸变公式3. 4个参数和8个参数之间的区别4.initUndistortRectifyMap()函数源码 最近在使用OpenCV对鱼眼相机图像去畸变时发现一个问题,基于针孔模型去畸变时所使用的参数和之前十四讲以及视觉SLAM中的畸变系数有一点不…...
【C++】C++11——智能指针、内存泄漏、智能指针的使用和原理、RAII、auto_ptr、unique_ptr、shared_ptr、weak_ptr
文章目录 C117.智能指针7.1内存泄漏7.2智能指针的概念7.3智能指针的使用7.3.1 auto_ptr7.3.2 unique_ptr7.3.3 shared_ptr7.3.4 weak_ptr C11 7.智能指针 7.1内存泄漏 什么是内存泄漏: 内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏…...
EDUSRC-记某擎未授权与sql注入
目录 360天擎 - 未授权与sql注入 信息收集 FOFA语法 鹰图搜索 360天擎未授权访问 - 数据库信息泄露 漏洞复现 修复方案 360天擎终端安全管理系统ccid处SQL注入 漏洞复现 手动测试方法 修复方案 360天擎 - 未授权与sql注入 通常访问的页面如下,存在登录框…...
1688拍立淘API接口分享
拍立淘接口,顾名思义,就是通过图片搜索到相关商品列表。通过此接口,可以实现图片搜索爆款商品等功能。 接口地址:1688.item_search_img 公共参数 名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中&…...
昇腾910使用记录
一. 压缩文件和解压文件 1. 压缩文件 tar -czvf UNITE-main.tar.gz ./UNITE-main/2. 解压文件 tar -xvf ./UNITE-main/二. CUDA更改为NPU data[label] data[label].cuda() data[instance] data[instance].cuda() data[image] data[image].cuda()更改为 data[label] da…...
从一部iPhone手机看芯片的分类
目录 问题 iPhone X 手机处理器:A11 iPhone X 的两大存储芯片 数字 IC CPU:计算设备的运算核心和控制核心 GPU:图形处理器 ASIC:为解决特定应用问题而定制设计的集成电路 存储芯片:DRAM 和 NAND Flash iPhone…...
arm day 7
完成字符串收发函数的封装并且验证现象,一个字符串发送接受后会有‘\n’ \r src/uart.c #include"uart.h"void uart4_init() {//设置UART4的RCc时钟使能//RCC_MP_APB1ENSETR[16]->1RCC->MP_APB1ENSETR | (0x1<<16);//设置GPIOB和GPIOG的时钟…...
Java基础面试-面向对象
什么是面向对象? 对比面向过程,是两种不同的处理问题角度 面向过程更注重事情的每一个步骤及顺序,面向对象更注重事情有哪些参与者(对象),及各自需要做什么 比如洗衣机洗衣服 面向过程会将任务拆解成一系…...
GCC vs. G++:C 与 C++ 编译器的差异和比较
本文将介绍 GCC(GNU Compiler Collection)和 G 编译器的区别,并对它们在 C 和 C 程序开发中的特性和用法进行比较和总结。 引言 在 C 和 C 程序开发中,选择合适的编译器是至关重要的。GCC(GNU Compiler Collection&a…...
MAC m系列docker login报错
错误:ERROR: failed to solve: XXX error getting credentials - err: exit status 1, out: 解决: vi ~/.docker/config.jsonzsxzsx [15时55分55秒] [~] { {"auths": {"harbor-g42c.corp.matrx.team": {"auth": "…...
Redis通用指令和五大基本数据类型常用指令总结
通用指令 keys parttern 查询key (parttern即通配符,不是正则表达式,例如 keys a? 匹配以a开头的长度为2的key) del key 删除key exists key 获取key是否存在 type key 获取key的类型 expire key seconds 为指定key设置有效期,单位秒 …...
uCharts常用图表组件demo
带渐变阴影的曲线图 <view class"charts-box"><qiun-data-charts type"area" :opts"opts" :chartData"chartData" :ontouch"true":background"rgba(256,256,256,0)" /> </view>data(){return{…...
VNC:Timed out waiting for a response from the computer
VNC的服务端使用的是TigerVNC,客户端使用的是RealVNC TigerVNC按其他博客配好后,防火墙ip什么的都配了,vnc客户端怎么连都是超时。 这里建议大家可以尝试一下重启服务器。我的是CentOS的 shutdown -r now 配了2天,最后服务器重启…...
Kotlin 协程 知识点
Android 上的 Kotlin 协程 | Android Developers (google.cn) 官方网址 1.什么是协程? 我觉得协程就是kotlin中一种优雅的实现异步请求 协程(Coroutines)是一种轻量级的并发编程概念,旨在简化异步编程和并发任务的处理。它是…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
