【自用笔记】设置简单的实时数据Echarts图表

来自业务需求,感觉还挺好玩的,所以记录一下。

Vue2项目,该需求内容是,当鼠标移动到指定位置块时,浮窗显示对应数据的Echarts图表数据,并且要求数据实时变动。

主要用到的是div和echarts,确保项目中有echarts即可完成该需求,可以根据自身项目需求增减配置值及内容。

大概效果:

因为该页面中,嵌套多个子组件,所以数据在大页面中统一处理保存,然后分发,使用ref绑定获取。直接上二级页面(数据展示块组件)和三级页面(图表组件)的代码

父组件统一绑定分发数据的代码:

<sonComponent :ref="componentOne"></sonComponent>

data() {
    return {
        ShareData: {
            DataOne: null,
            DataTwo: null,
            ...    //自定义
        }
    }
}

methods:{
    InitalComponents() {
        if(this.$refs.componentOne) {
            var one = this.$refs.componentOne;
            one.BindShareData(this.ShareData);    //注意分享的是一个对象,把要分享的数据包裹在里面,不然无法通过响应式更新给子组件
        }
    }
}

二级组件页面:

<template>
    <div class="demoToolChart">
        <div @mouseenter="ShowToolEchart($event, '数据1')" @mouseleave="HideToolEchart">
            <div>展示数据内容,如展示DataOne的相关数据</div>
        </div>

        <!-- echarts图表浮窗 -->
        <div class="customizeStyle" v-show="IsShowEchart" :style="{left: ChartLeft+'px', top: ChartTop+'px'}">
            <div>其他数据(自定义取舍)</div>
            <EchartsDataPage ref="Echarts"></EchartsDataPage>
        </div>
    </div>
</template>

<script>
import EchartsDataPage from "@/components/EchartsDataPage.vue"; //自定义图表组件位置
export default {
    name: "DemoToolChart",
    components:
    {
        EchartsDataPage,
    },
    data() {
        return {
            ChartType: null,        //显示数据
            IsShowEchart: false,    //图表浮窗盒子
            ChartLeft: 0,
            ChartTop: 0,
            ChartData: null,        //图表数据
            SharData: { //父组件分享数据 若有展示数据,可先设置与父组件数据结构一致的初始模板
                ShowData: {
                    DataOne: {
                        DetailDataOne: null,        //自定义
                        EchartData: [0,0,0,0,0],    //Y轴数据
                    },
                    DataTwo: {
                        DetailDataOne: null,        //自定义
                        EchartData: [0,0,0,0,0],    //Y轴数据
                    }
                }
            },
        }
    },
    mounted()
    {

    },
    watch:
    {
        SharData: {
            handler(newVal, old) {
                if(newVal && this.IsShowEchart) {
                    if(this.ChartType == 'one') this.ChartData = this.ShowData.ShowData.DataOne;    //获取实时展示数据
                    else this.ChartData = this.ShowData.ShowData.DataTwo;

                    //更新图表信息
                    var chart = this.$refs.Echarts;
                    if(chart) chart.InitEcharts(this.ChartData);
                }
            },
            deep: true,
        }
    },
    methods:
    {
        //获取并计算浮窗图表位置
        ShowToolEchart(event, type)
        {
            this.ChartType = type;

            if(this.ChartType == 'one') this.ChartData = this.ShowData.ShowData.DataOne;    //获取需要展示的数据
            else this.ChartData = this.ShowData.ShowData.DataTwo;

            //获取盒子位置
            const triggerEle = event.currentTarget;
            if(!triggerEle) return;

            const triggerRect = triggerEle.getBoundingClientRect();
            this.ChartLeft = triggerRect.left;  //浮窗距左宽度
            this.ChartTop = triggerRect.bottom + 150 + 30;  //距顶高度 + 盒子一半高度 + 浮窗和父盒子的间距

            //更新图表信息
            var chart = this.$refs.Echarts;
            if(chart) chart.InitEcharts(this.ChartData);

            this.IsShowEchart = true;
        },

        //隐藏盒子
        HideToolEchart()
        {
            this.IsShowEchart = false;
            this.ChartData = null;
            var chart = this.$refs.Echarts;
            if(chart) chart.ClearEcharts();

        },

        //绑定外部分享数据
        BindiSharData(data)
        {
            if(data) this.SharData = data;
        }
    },
}
</script>

三级组件页面(图表):

<template>
    <div class="EchartsDataPage">
        <!-- Echarts图表容器 -->
        <div ref="Echarts"></div>
    </div>
</template>

<script>
import * as echarts from "echarts"; //确保项目中有图表
export default {
    name: "EchartsDataPage",
    data()
    {
        return {
            MyChart: null,
            ChartData: null,    //Y轴数据
        }
    },
    mounted()
    {

    },
    methods:
    {
        //初始化图表并接收数据
        InitEcharts(data)
        {
            if(!data) return;
            if(!this.MyChart) {
                this.MyChart = echarts,init(this.$refs.Echarts);

                //监听窗口变化,防止报错
                window.addEventListener('resize', ()=> {
                    this.MyChart.resize();
                })
            }

            this.ChartData = data;

            this.RenderEcharts(this.ChartData.EchartData);  //这里的数据是外部处理好的Y轴数据
        },

        //渲染图表
        RenderEcharts(seriesData)
        {
            var xAxisData = [xx,x,xxx,...]; //这里是固定的X轴数据
            const flatIndex = xAxisData.indexOf("平盘");    //因个人业务需求,需根据涨跌平来设置不同的颜色,所以这里是找的X轴中平盘索引位置

            const option = {
                backgroundColor: '#333',    //背景色, 其他设定根据Echarts用法自己设定即可
                xAxis: {
                    type: 'category',
                    data: xAxisData,
                    axisLabel: {
                        color: '#fff',  //坐标文字颜色
                        interval: 0,    //显示全部标签
                    }
                },
                yAxis: {
                    type: 'value',
                    axisLabel: {
                        color: "#FFF"
                    },
                    axisLine: { //轴线配置
                        show: true,
                        lineStyle: {
                            color: '#FFF',  //轴线颜色
                        }
                    },
                    splitLine: { show: false, },    //关闭Y轴网格线
                },
                
                series: [
                    {
                        name: '涨跌分布',
                        type: 'bar',
                        data: seriesData,
                        itemStyle: {
                            color: (params) => {
                                if(params.dataIndex == flatIndex) return 'white';       //平盘
                                else if (params.dataIndex > flatIndex) return 'red';    //涨
                                else return 'green';    //跌
                            }
                        },
                        label: {
                            show: true,
                            position: 'top',
                            color: '#fff',
                        }
                    }
                ]
            }
            this.MyChart.setOption(option);
        },

        ClearEcharts()
        {
            if(this.MyChart) {
                this.MyChart.clear();
                this.MyChart.dispose();
                this.MyChart=null;
            }
        },
    },
    beforeDestroy()
    {
        //移除监听,删除图表
        window.removeEventListener('resize', ()=>{
            this.MyChart.resize();
        })
        this.ClearEcharts();
    },
}
</script>

完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值