vue左右div结构手动拉伸并且echarts图表根据拉伸宽高自适应

news2024/12/23 20:50:27

需求:

  1. 左右结构的div,可以根据数据抬起按下进行拉伸修改容器宽度的操作
  2. 给左右结构某一图表设置拉伸自适应
  3. 左右结构都设置个最小宽度,只能到一定区域内拉伸
  4. 解决echarts的bug(重复加载chart实例):[ECharts] There is a chart instance already initialized on the dom.
  5. 解决浏览器兼容性报错问题

       5.解决echarts在flex布局下宽高不显示问题

1.效果

 2.左右结构布局

左右布局给定一个基础的宽度,并且给最小宽度,min-width,如果不给最小宽度,那么拉伸的时候会拉到底,到时候其他元素挤压或者是隐藏了就不太好

<template>
    <div class="content-box">
        <div class="container">
            <div class="container_box">
                <div class="left" :style="{ width: leftWidth + 'px' }">左侧内容区</div>
                <div class="center"></div>
                <div class="right" :style="{ width: rightWidth + 'px' }">
                    <div class="right_top">右上内容区</div>
                    <!-- echarts图标区 -->
                    <div id="echartsWarp">
                        <div id="myChat" :style="{ width: '100%', height: '100%' }"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            isResizing: false,
            containerWidth: 600,
            leftWidth: 300,
            rightWidth: 400
        };
    },
    mounted() {},
    methods: {}
};
</script>

<style lang="scss" scoped>
.container_box {
    display: flex;
    height: 500px;
    width: 100%;
    .left {
        min-width: 300px;
        background-color: #ddd;
    }
    .center {
        min-width: 10px;
        height: 100%;
        background-color: #c7adad;
        cursor: col-resize;
    }
    .right {
        background-color: #d3e2d1;
        flex: 1;
        min-width: 500px;
        display: flex;
        flex-direction: column;
        .right_top {
            height: 60px;
        }
        #echartsWarp {
            height: calc(100vh - 300px);
        }
    }
}
</style>

效果如下:

 3.拉伸效果实现

  1. 首先下载echarts,不用多说,下载最新版就行
npm install echarts -S

     2.局部导入和全局导入,根据自己的需求来

局部导入:在需要用到的页面导入即可,为了各位看的更明白我用的是局部导入的方式

import * as echarts from 'echarts';

全局导入:在main.js文件导入挂载

import echarts from 'echarts';
Vue.prototype.$echarts = echarts;

全局导入后在页面使用:

this.$echarts.方法名

        3.在中间灰色区域添加个鼠标按下事件

<template>
    <div class="content-box">
        <div class="container">
            <div class="container_box">
                <div class="left" :style="{ width: leftWidth + 'px' }">左侧内容区</div>
                <div class="center" @mousedown="onMouseDown"></div>
                <div class="right" :style="{ width: rightWidth + 'px' }">
                    <div class="right_top">右上内容区</div>
                    <!-- echarts图标区 -->
                    <div id="echartsWarp">
                        <div id="myChat" :style="{ width: '100%', height: '100%' }"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            isResizing: false,
            containerWidth: 600,
            leftWidth: 200,
            rightWidth: 400
        };
    },
    mounted() {},
    methods: {
        onMouseDown() {
            // 鼠标按下时开始拖动
            this.isResizing = true;

            // 监听鼠标移动事件
            document.addEventListener('mousemove', this.onMouseMove);
            // 监听鼠标松开事件
            document.addEventListener('mouseup', this.onMouseUp);
        },
        onMouseMove(event) {
            if (this.isResizing) {
                // 计算鼠标在容器中的位置
                const containerRect = this.$el.getBoundingClientRect();
                const mouseX = event.clientX - containerRect.left;

                // 更新左侧和右侧容器的宽度
                this.leftWidth = mouseX;
                this.rightWidth = this.containerWidth - mouseX;
            }
        },
        onMouseUp() {
            // 鼠标松开时停止拖动
            this.isResizing = false;

            // 移除监听鼠标移动和松开事件
            document.removeEventListener('mousemove', this.onMouseMove);
            document.removeEventListener('mouseup', this.onMouseUp);
        }
    }
};
</script>

<style lang="scss" scoped>
.container_box {
    display: flex;
    height: 500px;
    width: 100%;
    .left {
        min-width: 300px;
        background-color: #ddd;
    }
    .center {
        min-width: 10px;
        height: 100%;
        background-color: #c7adad;
        cursor: col-resize;
    }
    .right {
        background-color: #d3e2d1;
        flex: 1;
        min-width: 500px;
        display: flex;
        flex-direction: column;
        .right_top {
            height: 60px;
        }
        #echartsWarp {
            height: calc(100vh - 300px);
        }
    }
}
</style>

效果:

 3.添加echarts图表

如果是按照以前的办法,不能实现自适应的哈,只能说把图标显示出来了,但是在拉伸的时候折线图不能自适应。

解决echarts的bug(重复加载chart实例)关键代码如下:

  if (
                    //判断是否存在echarts实例化对象,如果存在则销毁
                    this.chartsDom != null &&
                    this.chartsDom != '' &&
                    this.chartsDom != undefined
                ) {
                    this.chartsDom.dispose();
                }
<template>
    <div class="content-box">
        <div class="container">
            <div class="container_box">
                <div class="left" :style="{ width: leftWidth + 'px' }">左侧内容区</div>
                <div class="center" @mousedown="onMouseDown"></div>
                <div class="right" :style="{ width: rightWidth + 'px' }">
                    <div class="right_top">右上内容区</div>
                    <!-- echarts图标区 -->
                    <div id="echartsWarp">
                        <div id="myChat" :style="{ width: '100%', height: '100%' }"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import * as echarts from 'echarts';
export default {
    data() {
        return {
            isResizing: false,
            containerWidth: 600,
            leftWidth: 200,
            rightWidth: 400
        };
    },
    mounted() {
        this.echartsDom();
    },
    methods: {
        echartsDom() {
            // 基于准备好的dom,初始化echarts实例
            this.$nextTick(_ => {
                if (
                    //判断是否存在echarts实例化对象,如果存在则销毁
                    this.chartsDom != null &&
                    this.chartsDom != '' &&
                    this.chartsDom != undefined
                ) {
                    this.chartsDom.dispose();
                }
                const dom = document.getElementById('myChat');
                dom.style.width = dom.parentNode.parentNode.clientWidth + 'px';
                this.chartsDom = echarts.init(dom); //创建echarts实例化对象
                this.chartsDom.clear(); //清空画布数据
                //设置对应的参数,标题,x轴,y轴坐标,以及显示的数据
                let options = {
                    xAxis: {
                        type: 'category',
                        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                    },
                    yAxis: {
                        type: 'value'
                    },
                    series: [
                        {
                            data: [820, 932, 901, 934, 1290, 1330, 1320],
                            type: 'line',
                            smooth: true
                        }
                    ]
                };
                this.chartsDom.setOption(options);
                this.chartsDom.resize();
                setTimeout(function() {
                    window.addEventListener('resize', () => {
                        this.chartsDom.resize();
                    });
                }, 200);
            });
        },
        onMouseDown() {
            // 鼠标按下时开始拖动
            this.isResizing = true;

            // 监听鼠标移动事件
            document.addEventListener('mousemove', this.onMouseMove);
            // 监听鼠标松开事件
            document.addEventListener('mouseup', this.onMouseUp);
        },
        onMouseMove(event) {
            if (this.isResizing) {
                // 计算鼠标在容器中的位置
                const containerRect = this.$el.getBoundingClientRect();
                const mouseX = event.clientX - containerRect.left;

                // 更新左侧和右侧容器的宽度
                this.leftWidth = mouseX;
                this.rightWidth = this.containerWidth - mouseX;
            }
        },
        onMouseUp() {
            // 鼠标松开时停止拖动
            this.isResizing = false;

            // 移除监听鼠标移动和松开事件
            document.removeEventListener('mousemove', this.onMouseMove);
            document.removeEventListener('mouseup', this.onMouseUp);
        }
    }
};
</script>

<style lang="scss" scoped>
.container_box {
    display: flex;
    height: 500px;
    width: 100%;
    .left {
        min-width: 300px;
        background-color: #ddd;
    }
    .center {
        min-width: 10px;
        height: 100%;
        background-color: #c7adad;
        cursor: col-resize;
    }
    .right {
        background-color: #d3e2d1;
        flex: 1;
        min-width: 500px;
        display: flex;
        flex-direction: column;
        .right_top {
            height: 60px;
        }
        #echartsWarp {
            height: calc(100vh - 300px);
        }
    }
}
</style>

效果:

 4.解决echarts图表没有根据拉伸自适应问题(完整代码)

1.下载element-resize-detector

npm install element-resize-detector -S

2.局部导入

var elementResizeDetectorMaker = require('element-resize-detector');

3.完整代码如下:

<template>
    <div class="content-box">
        <div class="container">
            <div class="container_box">
                <div class="left" :style="{ width: leftWidth + 'px' }">左侧内容区</div>
                <div class="center" @mousedown="onMouseDown"></div>
                <div class="right" :style="{ width: rightWidth + 'px' }">
                    <div class="right_top">右上内容区</div>
                    <div id="echartsWarp">
                        <div id="myChat" :style="{ width: '100%', height: '100%' }"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
//elementResizeDetectorMaker,该全局函数是使元素调整大小检测器实例的maker函数。
var elementResizeDetectorMaker = require('element-resize-detector');
import * as echarts from 'echarts';
export default {
    name: 'Index',
    data() {
        return {
            isResizing: false,
            containerWidth: 600,
            leftWidth: 200,
            rightWidth: 400,
            chartsDom: null
        };
    },
    mounted() {
        this.changeEchartsWidthApi();
    },
    methods: {
        //监听盒子大小,改变echarts宽度,实现echarts自适应
        changeEchartsWidthApi() {
            // 创建实例,无参数
            var erd = elementResizeDetectorMaker(); //使用默认选项(将使用基于对象的方法)
            // 创建实例带参数
            // 使用基于超快速滚动的方法。
            // 这是推荐的策略。
            var erdUltraFast = elementResizeDetectorMaker({
                strategy: 'scroll',
                callOnAdd: true, //callOnAdd选项,用于确定在添加侦听器时是否应调用它们。默认为true。
                //如果为true,则确保在添加侦听器后将对其进行调用。如果为false,则在添加侦听器时将不保证其
                //被调用(不会阻止其被调用)
                debug: true
            });
            //监听class为staticNextMain的元素 大小变化
            var self = this;
            //侦听元素的调整大小事件,并使用元素作为调整大小事件的参数来调用侦听器函数。传递给函数的选项将
            //覆盖实例选项
            erd.listenTo(document.getElementById('echartsWarp'), function(element) {
                self.ChartsApi();
            });
        },
        ChartsApi() {
            // 基于准备好的dom,初始化echarts实例
            this.$nextTick(_ => {
                if (
                    //判断是否存在echarts实例化对象,如果存在则销毁
                    this.chartsDom != null &&
                    this.chartsDom != '' &&
                    this.chartsDom != undefined
                ) {
                    this.chartsDom.dispose();
                }
                const dom = document.getElementById('myChat');
                dom.style.width = dom.parentNode.parentNode.clientWidth + 'px';
                this.chartsDom = echarts.init(dom); //创建echarts实例化对象
                this.chartsDom.clear(); //清空画布数据
                //设置对应的参数,标题,x轴,y轴坐标,以及显示的数据
                let options={
                    xAxis: {
                        type: 'category',
                        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
                    },
                    yAxis: {
                        type: 'value'
                    },
                    series: [
                        {
                            data: [820, 932, 901, 934, 1290, 1330, 1320],
                            type: 'line',
                            smooth: true
                        }
                    ]
                }
                this.chartsDom.setOption(options);
                this.chartsDom.resize();
                setTimeout(function() {
                    window.addEventListener('resize', () => {
                        this.chartsDom.resize();
                    });
                }, 200);
            });
        },
        onMouseDown() {
            // 鼠标按下时开始拖动
            this.isResizing = true;

            // 监听鼠标移动事件
            document.addEventListener('mousemove', this.onMouseMove);
            // 监听鼠标松开事件
            document.addEventListener('mouseup', this.onMouseUp);
        },
        onMouseMove(event) {
            if (this.isResizing) {
                // 计算鼠标在容器中的位置
                const containerRect = this.$el.getBoundingClientRect();
                const mouseX = event.clientX - containerRect.left;

                // 更新左侧和右侧容器的宽度
                this.leftWidth = mouseX;
                this.rightWidth = this.containerWidth - mouseX;
            }
        },
        onMouseUp() {
            // 鼠标松开时停止拖动
            this.isResizing = false;

            // 移除监听鼠标移动和松开事件
            document.removeEventListener('mousemove', this.onMouseMove);
            document.removeEventListener('mouseup', this.onMouseUp);
        }
    }
};
</script>
<style lang="scss" scoped>
.container_box {
    display: flex;
    height: 500px;
    width: 100%;
    .left {
        min-width: 300px;
    }
    .center {
        min-width: 10px;
        height: 100%;
        background-color: #c7adad;
        cursor: col-resize;
    }
    .right {
        flex: 1;
        min-width: 500px;
        display: flex;
        flex-direction: column;
        .right_top {
            height: 60px;
        }
        #echartsWarp {
            height: calc(100vh - 300px);
        }
    }
}
</style>

文章到此结束,希望对你有所帮助~

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

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

相关文章

数据通信——VRRP

引言 之前把实验做了&#xff0c;结果发现我好像没有写过VRRP的文章&#xff0c;连笔记都没记过。可能是因为对STP的记忆&#xff0c;导致现在都没忘太多。 一&#xff0c;什么是VRRP VRRP全名是虚拟路由冗余协议&#xff0c;虚拟路由&#xff0c;看名字就知道这是运行在三层接…

python接口自动化测试框架2.0,让你像Postman一样编写测试用例,支持多环境切换、多业务依赖、数据库断言等

项目介绍 接口自动化测试项目2.0 软件架构 本框架主要是基于 Python unittest ddt HTMLTestRunner log excel mysql 企业微信通知 Jenkins 实现的接口自动化框架。 前言 公司突然要求你做自动化&#xff0c;但是没有代码基础不知道怎么做&#xff1f;或者有自动化…

Fairy下载和使用

写在最前&#xff1a;本系列中将会涉及到 Unity&#xff0c;C#&#xff0c;Lua和FairyGUI&#xff08;FGUI&#xff09;。 FairyGUI介绍 官网&#xff1a; FairyGUI 编辑器下载&#xff1a; FairyGUI 截至文档记录最新版&#xff1a; https://res.fairygui.com/FairyGUI-Ed…

Exams/ece241 2013 q4

蓄水池问题 S3 S2 S1 例如&#xff1a;000 代表 无水 &#xff0c;需要使FR3, FR2, FR1 都打开&#xff08;111&#xff09; S3 S2 S1 FR3 FR2 FR1 000 111 001 011 011 001 111 000 fr代表水变深为…

Eleastisearch5.2.2利用镜像迁移构建实例后ES非健康状态

正常迁移完成后启动服务&#xff0c;查看ES非健康状态 此时观察ES集群状态&#xff1a;curl -XGET -u elastic:xxx localhost:9200/_cluster/health?pretty 注意到"active_shards_percent_as_number" : 88.8888 该项的值不产生变化;集群状态"status" : “…

LAXCUS如何通过技术创新管理数千台服务器

随着互联网技术的不断发展&#xff0c;服务器已经成为企业和个人获取信息、进行计算和存储的重要工具。然而&#xff0c;随着服务器数量的不断增加&#xff0c;传统的服务器管理和运维方式已经无法满足现代企业的需求。LAXCUS做为专注服务器集群的【数存算管】一体化平台&#…

JVM—内存管理(运行时数据区)、垃圾回收

背景介绍 当JVM类加载器加载完字节码文件之后&#xff0c;会交给执行引擎执行&#xff0c;在执行的过程中会有一块JVM内存区域来存放程序运行过程中的数据&#xff0c;也就是我们图中放的运行时数据区&#xff0c;那这一块运行时数据区究竟帮我们做了哪些工作&#xff1f;我们…

【学习FreeRTOS】第6章——FreeRTOS中断管理

【本篇文章的也可参考STM32中断文章http://t.csdn.cn/foF9I&#xff0c;结合着学习效果更好】 1.什么是中断 中断&#xff1a;让CPU打断正常运行的程序&#xff0c;转而去处理紧急的事件&#xff08;程序&#xff09;&#xff0c;就叫中断中断执行机制&#xff0c;可简单概括…

Nginx配置文件理解

之前除了一篇nginx基础安装和基础使用的文章&#xff0c;由于长时间不使用nginx 了&#xff0c;再写一篇文章加强一下对nginx 的理解&#xff1b;当然更深入细致的理解最好去官网细致学习一下&#xff0c;并配和实践多多练习才是最好的&#xff1b; nginx常用的特性&#xff1a…

使用GUI Guider工具在MCU上开发嵌入式GUI应用 (1) - GUI Guider简介及安装

使用GUI Guider工具在MCU上开发嵌入式GUI应用 (1) - GUI Guider简介及安装 受限于每篇文章最多只能贴9张图的限制&#xff0c;这个教程被拆分成了多篇文章连载发布&#xff0c;完整目录结构如下图x所示。后续会发布完整教程的pdf文件&#xff0c;敬请期待。 图x 完整教程文档…

QGIS二次开发六:VS不借助QT插件创建UI界面

上一篇博客我们说了在VS中如何使用QT插件来创建UI界面&#xff0c;但是我们二次开发QGIS的第一篇博客就说了&#xff0c;最好使用OSGeo4W中自动下载的QT进行QGIS二次开发&#xff0c;这样兼容性是最好的&#xff0c;那么该如何在VS中不使用外部安装的QT以及QT的VS插件情况下进行…

解决ElementUI动态表单校验验证不通过

这里记录一下&#xff0c;写项目时遇到的一个问题&#xff1a;就是动态渲染的表单项&#xff0c;加验证规则后一直不通过&#xff01;&#xff01;&#xff01; 原代码 html部分&#xff1a; <el-form-itemv-for"(teaclass,index) in addFom.classIds":label&quo…

Rust 编程小技巧摘选(8)

目录 Rust 编程小技巧(8) 1. 取整函数 floor() 2. 取整函数ceil() 3. 取整函数 round() 4. 保留小数位数 5. 字符串转整数 unwrap() unwrap_or() Rust 编程小技巧(8) 1. 取整函数 floor() floor函数对浮点数进行向下取整 示例代码&#xff1a; fn main() {let x: …

基于概率神经网络的变压器故障诊断

1.案例背景 1.1 PNN概述 概率神经网络(probabilistic neural networks. PNN)是 D.F.Specht博士在1989年首先提出的,是一种基于Bayes分类规则与Parzen窗的概率密度函数估计方法发展而来的并行算法。它是一类结构简单、训练简洁,应用广泛的人工神经网络。在实际应用中,尤其是在解…

【Linux】网络通信

【Linux】网络通信 文章目录 【Linux】网络通信1、网络基础1.1 计算机网络1.2 网络模型TCP & UDP1&#xff09;IP地址2&#xff09;端口3&#xff09;TCP协议与UDP协议的比较 1.3 网络传输1.3.1 传输逻辑1.3.2 传输条件1.3.3 传输流程 1.4 地址管理 2、网络编程2.1 基本概念…

Django项目局域网访问

1、需求 主机运行着Django项目&#xff0c;想要被局域网其它设备访问。 2、解决步骤&#xff08;非常简单&#xff09; 查看本机局域网ip&#xff0c;如&#xff1a;192.168.100.100运行项目&#xff1a;python manage.py runserver 192.168.100.100:8080。 注意这里的地址很…

python+tkinter实现图书管理系统(首发)

文章目录 前文运行环境功能图数据操作图书数据管理用户数据管理借书记录管理 功能界面管理员界面首页图书管理用户管理借书记录更改密码 普通用户界面 其他功能数字时间显示加载画面显示输入框提示词界面居中显示借书时间和还书时间记录公告栏数据操作 结尾 前文 本文将用tkin…

Nuitka实战

安装Nuitka pip install -U nuitka 安装好之后查看版本 python -m nuitka --version 显示gcc版本太低&#xff0c;与nuitka不兼容&#xff0c;所以我们要升级gcc版本 升级之前&#xff0c;先查看一下gcc版本信息 gcc --version 可以看到&#xff0c;Centos 7.7默认gcc版本为…