The left and right div structures of vue are manually stretched and the echarts chart is adaptive according to the stretched width and height

need:

  1. The div of the left and right structures can be lifted and pressed according to the data to stretch and modify the width of the container
  2. Set stretch adaptation for a chart of the left and right structures
  3. The left and right structures are set with a minimum width, which can only be stretched to a certain area
  4. Solve the bug of echarts (repeated loading of chart instances): [ECharts] There is a chart instance already initialized on the dom.
  5. Solve the problem of browser compatibility error

       5. Solve the problem that the width and height of echarts are not displayed under the flex layout

1. Effect

 2. Left and right structural layout

The left and right layouts are given a basic width, and a minimum width, min-width. If the minimum width is not given, then it will be pulled to the bottom when stretching, and it is not good for other elements to be squeezed or hidden.

<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>

The effect is as follows:

 3. Realization of stretching effect

  1. First download echarts, needless to say, just download the latest version
npm install echarts -S

     2. Local import and global import, according to your own needs

Partial import: You can import it on the page you need to use. In order for you to see it more clearly, I use the partial import method

import * as echarts from 'echarts';

Global import: import and mount in the main.js file

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

Use on the page after global import:

this.$echarts.方法名

        3. Add a mouse press event in the middle gray area

<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>

Effect:

 3. Add echarts chart

If it is according to the previous method, the self-adaptation cannot be realized. It can only be said that the icon is displayed, but the line chart cannot be self-adapted when it is stretched.

The key code to solve the bug of echarts (repeated loading of chart instances) is as follows:

  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>

Effect:

 4. Solve the problem that the echarts chart does not adapt to stretching (full code)

1. Download element-resize-detector

npm install element-resize-detector -S

2. Partial import

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

3. The complete code is as follows:

<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>

This is the end of the article, I hope it will be helpful to you~

Guess you like

Origin blog.csdn.net/qq_44278289/article/details/132226446