解决echarts配置滚动(dataZoom)后导出图片数据不全问题

news2024/10/5 5:24:17

先展现一个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, //是否显示数据阴影 默认auto
                    showDetail: 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()
            // 获取图表的数据 URL
            var 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 = fullData
    newOption.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()
            // 获取图表的数据 URL
            var 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 = null

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, //是否显示数据阴影 默认auto
                    showDetail: 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,  // 是否初始化立即执行一次, 默认是false
        deep: true // 是否是深度监视, 默认是false
    }
)

// 下载echarts
const downloadBtn = (() => {
    // 获取完整的数据
    const fullData = myChart.getOption();
    let newOption = fullData
    newOption.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()
            // 获取图表的数据 URL
            var 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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1085457.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端URL拼接路径参数

前端URL拼接路径参数 一、应用场景二、具体实现1.字符串拼接2.URL对象实现 四、完整代码 一、应用场景 我们有时候会遇到浏览器URL拼接参数的场景&#xff0c;例如页面跳转时&#xff0c;带上一个特定的标识&#xff1a;https://www.baidu.com?fromcsdn 二、具体实现 1.字符…

微软发布2023年10月补丁,修复了103个缺陷,包括2个活跃的漏洞利用

导语 最近&#xff0c;微软发布了2023年10月的补丁更新&#xff0c;共修复了103个缺陷。这些补丁包括两个正在被黑客利用的漏洞。让我们来看看这些补丁的具体内容和影响。 修复103个缺陷 微软此次的补丁更新共修复了103个缺陷&#xff0c;其中13个被评为严重&#xff0c;90个被…

gradle对应jdk版本

官网地址-兼容性矩阵&#xff1a;Compatibility Matrix Gradle运行在所有主要的操作系统上。它需要Java开发工具包&#xff08;JDK&#xff09;版本8或更高版本才能运行。有关详细信息&#xff0c;您可以查看兼容性矩阵。

DailyPractice.2023.10.12

文章目录 1.[1. 两数之和]2.[49. 字母异位词分组]3.[128. 最长连续序列]4.[283. 移动零]5.[11. 盛最多水的容器]6.[15. 三数之和]7.[3. 无重复字符的最长子串]8.[206. 反转链表]9.[141. 环形链表]10.[160. 相交链表] 1.[1. 两数之和] 1. 两数之和 class Solution { public:ve…

单目标优化算法:火鹰优化算法(Fire Hawk Optimizer,FHO)求解23个函数--提供MATLAB代码

一、火鹰优化算法FHO 火鹰优化算法&#xff08;Fire Hawk Optimizer&#xff0c;FHO&#xff09;由Mahdi Azizi等人于2022年提出&#xff0c;该算法性能高效&#xff0c;思路新颖。 单目标优化&#xff1a;火鹰优化算法&#xff08;Fire Hawk Optimizer&#xff0c;FHO&#…

使用Tortoisegit界面拉起master主分支以副分支以及命令行操作

文章目录 1、Gui操作界面2、命令行操作 1、Gui操作界面 "小乌龟"通常指的是Git的图形用户界面&#xff08;GUI&#xff09;工具&#xff0c;其中比较常见的是TortoiseGit。下面是使用TortoiseGit来拉取&#xff08;checkout&#xff09;一个Git分支的步骤&#xff1a…

数字时代的自我呈现:探索个人形象打造的创新工具——FaceChain深度学习模型工具

数字时代的自我呈现&#xff1a;探索个人形象打造的创新工具——FaceChain深度学习模型工具 1.介绍 FaceChain是一个可以用来打造个人数字形象的深度学习模型工具。用户仅需要提供最低一张照片即可获得独属于自己的个人形象数字替身。FaceChain支持在gradio的界面中使用模型训…

机器学习(22)---信息熵、纯度、条件熵、信息增益

文章目录 1、信息熵2、信息增益3、例题分析 1、信息熵 1. 信息熵(information entropy)是度量样本集合纯度最常用的一种指标。信息的混乱程度越大&#xff0c;不确定性越大&#xff0c;信息熵越大&#xff1b;对于纯度&#xff0c;就是信息熵越大&#xff0c;纯度越低。 2. 纯度…

CSI2与CDPHY学习

注意&#xff1a;本文是基于CSI2-V3.0 spec。 其中CPHY为 V2.0 DPHY为V2.5 本文主要在packet级别介绍CSI2与对应的CDPHY&#xff0c;需要注意的是CDPHY的burst数据就是以packet为单位 1.CSI-CPHY 1.1CPHY的多lane分配与合并 csi-cphy规定至少需要一条lane用于传输视频&am…

ubuntu20.04 nerf Instant-ngp (下) 复现,自建数据集,导出mesh

参考链接 Ubuntu20.04复现instant-ngp&#xff0c;自建数据集&#xff0c;导出mesh_XINYU W的博客-CSDN博客 GitHub - NVlabs/instant-ngp: Instant neural graphics primitives: lightning fast NeRF and more youtube上的一个博主自建数据集 https://www.youtube.com/watch…

C++菜鸟日记1

共用体&#xff1a; #include<iostream> using namespace std; int main() {struct widge{char brand[20];int type;union id{long id_num;char id_char[20];}id_val;};widge prize;cout << "Please cin the prize.type mumber:" << endl;cin >…

01Linux基础

附件:day26–linux入门.pdf Linux是 基于Unix 的开源免费的操作系统&#xff0c;由于系统的稳定性和安全性几乎成为程序代码运行的最佳系统环境。 &#xff08;程序基本上在Linux上发布&#xff09; Linux系统的应用非常广泛&#xff0c;不仅可以长时间的运行我们编写的程序代…

【C++14算法】make_unique

文章目录 前言一、make_unique函数1.1 什么是make_unique?1.2 如何使用make_unique?1.3 make_unique的函数原型如下&#xff1a;1.4 示例代码示例1: 创建一个动态分配的整数对象示例2: 创建一个动态分配的自定义类型对象示例3: 创建一个动态分配的数组对象示例4: 创建一个动态…

STM32 CubeMX PWM三种模式(互补,死区互补,普通)(HAL库)

STM32 CubeMX PWM两种模式&#xff08;HAL库&#xff09; STM32 CubeMX STM32 CubeMX PWM两种模式&#xff08;HAL库&#xff09;一、互补对称输出STM32 CubeMX设置代码部分 二、带死区互补模式STM32 CubeMX设置代码 三、普通模式STM32 CubeMX设置代码部分 总结 一、互补对称输…

2023.10.12

#include <iostream>using namespace std; //定义动物类 class Animal { private:string name; public:Animal(){}Animal(string name):name(name){}~Animal(){}//定义虚函数virtual void perform()0;//表演的节目void show(){cout << "Please enjoy the spec…

平衡二叉树(AVL) 的认识与实现

文章目录 1 基本1.1 概念1.2 特点1.3 构建1.4 调整1.4.1 RR1.4.1.1 示例1.4.1.2 多棵树不平衡 1.4.2 LL1.4.2.1 示例 1.4.3 LR1.4.3.1 示例 1.4.4 RL1.4.4.1 示例 1.5 实现1.5.1 示例1.5.2 完善 1 基本 1.1 概念 平衡二叉树是一棵合理的二叉排序树 解释 对于这么一个序列 如…

2023 | github无法访问或速度慢的问题解决方案

github无法访问或速度慢的问题解决方案 前言: 最近经常遇到github无法访问, 或者访问特别慢的问题, 在搜索了一圈解决方案后, 有些不再有效了, 但是其中有几个还特别好用, 总结一下. 首选方案 直接在github.com的域名上加一个fast > githubfast.com, 访问的是与github完全相…

03-RocketMQ高级原理

目录汇总&#xff1a;RocketMQ从入门到精通汇总 上一篇&#xff1a;02-RocketMQ开发模型 前面的部分我们都是为了快速的体验RocketMQ的搭建和使用。这一部分&#xff0c;我们慢下来&#xff0c;总结并学习下RocketMQ底层的一些概念以及原理&#xff0c;为后面的深入学习做准备。…

使用宝塔面板在Linux上搭建网站,并通过内网穿透实现公网访问

文章目录 前言1. 环境安装2. 安装cpolar内网穿透3. 内网穿透4. 固定http地址5. 配置二级子域名6. 创建一个测试页面 前言 宝塔面板作为简单好用的服务器运维管理面板&#xff0c;它支持Linux/Windows系统&#xff0c;我们可用它来一键配置LAMP/LNMP环境、网站、数据库、FTP等&…

4种实现JS深拷贝的方法

浅拷贝与深拷贝 浅拷贝是创建一个新对象&#xff0c;这个对象有着原始对象属性值的拷贝。如果属性是基本类型&#xff0c;拷贝的就是基本类型的值&#xff0c;如果属性是引用类型&#xff0c;拷贝的是内存地址 。 如果不进行深拷贝&#xff0c;其中一个对象改变了对象的值&am…