定时动态显示之echarts的tooltip、leaflet的tooltip和纵向滚动广告栏

1,855 阅读1分钟

效果图

echart的tooltip动态显示 地图点的动态显示

表格、列表动态滚动

核心代码

echarts:

this.myChart.dispatchAction({
    type: 'showTip', // 触发的行为
    seriesIndex: 0, // 触发的数据对应的坐标系(通常只有一个y轴,取0)
    dataIndex: currentIndex // 第几个数据显示toolTip
});

map: 使用定时器,定时显示和关闭bindTooltip

表格和列表:

setTimeout(() => {
    dataArr.push(dataArr[0]);
    dataArr.shift(0);
    this[styleAnimate] = false;
},time/4);

完整代码

<template>
    <div class="tool-tip-container">
        <el-tabs class="tab-box" v-model="activeName">
            <el-tab-pane class="tab-pane-box" label="echarts" name="echarts">                
                <div class="my-charts" ref="myEcharts"></div>
            </el-tab-pane>
            <el-tab-pane class="tab-pane-box" label="地图" name="map">
                <div class="my-map" id="myMap"></div>
            </el-tab-pane>
            <el-tab-pane class="tab-pane-box other-box" label="纵向滚动栏" name="other">
                
                <div class="other-content table-box" :class="[{'table-anim':tableAnimate==true}]">
                    <div class="table-info" v-for="(item, index) in tableList" :key="index">
                        <p class="table-content">
                            <span class="table-details">{{item.name}}</span>
                            <span class="table-details">{{item.value}}</span>
                        </p>
                    </div>

                </div>
                <div class="other-content scroll-table" :class="[{'scroll-anim':scrollAnimate==true}]">
                    <p class="scroll-info" :class="{'color-deep':!item.isBg}" v-for="(item, index) in scrollList" :key="index">
                        {{item.name}}
                    </p>


                </div>
            </el-tab-pane>
        </el-tabs>
        
    </div>
</template>
<script>
import L from 'leaflet'
import Provider from './chinatmsproviders'
require('leaflet/dist/leaflet.css')
export default {
    components: {},
    props: {},
    data() {
        return {
            activeName: 'echarts',
            chartsInfo: {
                xChartData: [],
                yChartData: []
            },
            myChart: null, // echarts实例
            echartsInterval: null, // echarts的定时器

            mapKey: '', // 地图key值
            map: null, // 地图示例
            marker: [], // 地图静态标记点
            activeMarker: null, // 地图动态标记点
            mapData: [],
            mapInterval: null, // 地图定时器

            tableList: [],
            tableInterval: null, // 表格滚动定时器
            tableAnimate: false, // 滚动效果

            scrollList: [],
            scrollInterval: null, // 列表滚动定时器
            scrollAnimate: false, // 滚动效果
        };
    },
    computed: {},
    watch: {
        activeName:{
            handler(val){
                if(val == 'echarts'){
                    this.$nextTick(()=>{
                        this.getCharts()
                    })
                }else if(val == 'map'){
                    this.$nextTick(()=>{
                        this.getPointer()
                    })
                }else if(val == 'other'){
                    this.$nextTick(()=>{
                        this.changeData('scrollList','scrollAnimate','scrollInterval',2000,12,true)
                        this.changeData('tableList','tableAnimate','tableInterval',1500,12)
                    })
                }
            },
            immediate: true
        }
    },
    created() {
        for(let i = 0; i < 10; i++ ){
            this.mapData.push({name: "标记"+1, tips: "这是标记"+i, lat: '30.'+Math.ceil(Math.random()*100), lng: '120.'+Math.ceil(Math.random()*10)})

            this.chartsInfo.xChartData.push('名称'+i)
            this.chartsInfo.yChartData.push(Math.ceil(Math.random()*10))

            this.tableList.push({name:'表格名字'+i,value:'表格数据'+i})
            this.scrollList.push({name: '滚动数据'+i})
        }
    },
    mounted() {
        window.onresize = () => {
            this.$echarts.init(this.$refs.myEcharts).resize()
        }
        Provider(L)
        this.getMap()
    },
    methods: {
        /*
            dataArr: 数据
            styleAnimate: 过渡滚动的样式是否显示
            interVall: 定时器名称
            time: 循环速度
            circleNum: 数据长度限制:滚动数据长度指定不足,翻倍增长长度
            isBg: 是否设置背景色,长度变成双数(单数数据翻倍),防止背景色冲突
        */
        changeData(dataArr,styleAnimate,interVal,time,circleNum,isBg){
            let arr = JSON.parse(JSON.stringify(this[dataArr]))            
            if(circleNum){
                // 不是双数的时候翻倍变成双数
                if(this[dataArr].length%2 != 0){
                    this[dataArr] = this[dataArr].concat(arr)
                }
                arr = JSON.parse(JSON.stringify(this[dataArr]))
                // 长度不足指定长度的时候翻倍至超过指定长度
                if(this[dataArr].length>0){
                    while (this[dataArr].length < circleNum) {
                        this[dataArr] = this[dataArr].concat(arr)
                    }
                }
            }
            if(isBg){
                this[dataArr].map((res,index)=>{                    
                    res.isBg = index%2===0
                })
            }
            setTimeout(() => {
                this.loadScroll(this[dataArr],styleAnimate,interVal,time)
            }, 0);
            
        },
        // 定时器
        loadScroll(dataArr,styleAnimate,interVal,time){
            clearTimeout(this[interVal]);
            this[interVal] = setTimeout(() => {
                this[styleAnimate] = true;
                setTimeout(() => {
                    dataArr.push(dataArr[0]);
                    dataArr.shift(0);
                    this[styleAnimate] = false;
                },time/4);
                this.loadScroll(dataArr,styleAnimate,interVal,time);
            }, time);
        },
        getCharts(){
            // 加载
            this.myChart = this.$echarts.init(this.$refs.myEcharts)
            this.myChart.clear()
            // echarts 的配置
            let option = {
                tooltip : {
                    trigger: 'axis',
                    axisPointer : {
                        type : 'line'
                    },
                    formatter:(params)=>{  
                        let text = ''
                        params.map((res,index)=>{                            
                            text =  `名称:${res.axisValue}<br/>数据:${res.value}`
                        })
                        return text
                    },
                },
                xAxis: {
                    type: 'category',
                    data: this.chartsInfo.xChartData,
                },
                yAxis: {
                    type: 'value',
                },
                series: [
                    {
                        type: "line", 
                        color: 'rgba(90,190,246,1)',
                        symbolSize :6,
                        symbol: 'circle',
                        lineStyle:{
                            width:'1'
                        },
                        data: this.chartsInfo.yChartData
                    }
                ]
            };
            this.myChart.setOption(option)
            setTimeout(() => {
                // 加载完成后执行resize事件,以使图适应dom大小
                this.$echarts.init(this.$refs.myEcharts).resize()
            }, 0);
            this.activeEcharts(-1)
        },
        // 定时echarts的tooltip,传入 当前选中的数据标记 和 echarts对象
        activeEcharts(currentIndex){
            // 数据长度
            let dataLength = this.chartsInfo.yChartData.length
            // 清空tooltip定时器
            clearTimeout(this.echartsInterval);
            // 加载tooltip定时器
            this.echartsInterval = setTimeout(() => {
                // 获取当前显示第几个数据,从0 开始。(取 显示次数除以数据长度的余数)
                currentIndex = (currentIndex + 1) % dataLength;                
                // echarts的触发图表行为
                this.myChart.dispatchAction({
                    type: 'showTip', // 触发的行为
                    seriesIndex: 0, // 触发的数据对应的坐标系(通常只有一个y轴,取0)
                    dataIndex: currentIndex // 第几个数据显示toolTip
                });
                this.activeEcharts(currentIndex)
            }, 3000);
        },

        // 添加地图
        getMap(){
            let myCenter = new L.LatLng(30.18,120.45)
            let map = L.map('myMap',{
                center: myCenter,
                zoom: 10
            })
            L.tileLayer.chinaProvider('TianDiTu.Normal.Map',{maxZoom:18,minZoom:5,key:this.mapKey}).addTo(map);
            L.tileLayer.chinaProvider('TianDiTu.Normal.Annotion',{maxZoom:18,minZoom:5,key:this.mapKey}).addTo(map);

            this.map = map
            
        },
        // 添加地图标记点
        getPointer(){
            let map = this.map
            let htmlPoint = ''
            // 每次重绘先清空点
            if(this.marker){
                this.marker.map(res=>{ 
                    map.removeLayer(res)
                })
                this.marker = []
            }
            this.mapData.map((res,index)=>{
                if(index == 0){
                    map.setView(new L.LatLng(res.lat,res.lng),11)  

                }
                // 添加静态标记点
                htmlPoint = 
                    `<div class="point-content">
                        <div class="one"></div>
                    </div>`
                    
                let marker = new L.Marker(new L.LatLng(res.lat,res.lng));
                map.addLayer(marker)
                marker.setIcon(L.divIcon({
                    html: htmlPoint,
                    className: `point-tips`
                }));
                this.marker.push(marker)
            })
            
            // 动态显示地图标记点,传入表示显示第几个的参数
            this.getActiveMap(-1)
        },
        // 动态显示地图标记点
        getActiveMap(currentIndex){
            let map = this.map

            // 关闭定时器
            clearTimeout(this.mapInterval);
            
            this.mapInterval = setTimeout(() => {                
                if(this.activeMarker){
                    // 关闭tooltip显示
                    this.activeMarker.closeTooltip()
                    // 清空动态标记点
                    map.removeLayer(this.activeMarker)
                    this.activeMarker = null
                }

                currentIndex = (currentIndex + 1) % this.mapData.length
                // 在地图上添加动态点(我这里是直接覆盖已有点)
                let htmlPoint =
                    `<div class="point-content">
                        <div class="one"><p class="circle circle-one"></p><span class="circle circle-two"></span></div>
                    </div>`
                let activeMarker = new L.Marker(new L.LatLng(this.mapData[currentIndex].lat,this.mapData[currentIndex].lng));

                map.addLayer(activeMarker)
                activeMarker.setIcon(L.divIcon({
                    html: htmlPoint,
                    className: `point-tips`
                }));

                activeMarker.bindTooltip(this.mapData[currentIndex].name, {
                    direction: 'top' ,
                    className: `tool-div`,
                }).openTooltip()

                this.activeMarker = activeMarker
                
                this.getActiveMap(currentIndex)
            }, 3000);

        }
    },
};
</script>
<style lang="less">
.tool-tip-container{
    background: #fff;
    display: flex;
    .tab-box{
        flex: 1;
        display: flex;
        flex-direction: column;
        .el-tabs__content{
            flex: 1;
            overflow: hidden;
            .tab-pane-box{
                width: 100%;
                height: 100%;
                display: flex;
                flex-direction: column;
                .my-charts{
                    flex: 1;
                }
                .my-map{
                    flex: 1;
                    .point-tips{
                        .point-content{
                            position: relative;
                            .one{
                                width: 10px;
                                height: 10px;
                                position: absolute;
                                background: red;
                                border-radius: 50%;
                            }
                            .circle{
                                position: absolute;
                                top: 2.5px;
                                left: 2.5px;
                                bottom: 0;
                                width: 5px;
                                height: 5px;
                                border-radius:50%;
                                animation: myfirst 1.3s infinite;
                            }
                            .circle-one{
                                box-shadow: 0px 0px 5px red;
                            }
                            .circle-two{
                                box-shadow: 0px 0px 3px red;
                                display:block;
                                animation-delay: 0.5s;
                            }
                            @keyframes myfirst{
                                20% {transform: scale(2);}
                                40% {transform: scale(3);}
                                60% {transform: scale(4);}
                                80% {transform: scale(5);}
                                100% {transform: scale(6);}
                            }
                        }
                    }
                }
            }
            .other-box{
                flex: 1;
                display: flex;
                flex-direction: row;
                .other-content{
                    flex: 1;
                }
                .table-box{
                    height: 121px;
                    overflow: hidden;
                    .table-info{
                        width: 50%;
                        &:first-child{
                            border-top: 1px solid #999;
                        }
                        .table-content{
                            text-align: center;
                            display: flex;
                            justify-content: space-between;
                            height: 30px;
                            line-height: 30px;
                            border-left: 1px solid #999;
                            .table-details{
                                border-bottom: 1px solid #999;
                                border-right: 1px solid #999;
                                display: inline-block;
                                flex: 1;
                            }
                        }
                    }
                }
                .table-anim{
                    transition: all 1s;
                    margin-top: -40px; // 单行高度,会有微小误差,需调整
                    height: 150px; // 整体高度+单行高度 120+30
                }
                .scroll-table{
                    height: 120px;
                    overflow: hidden;
                    .scroll-info{
                        height: 30px;
                        line-height: 30px;
                        width: 100px;
                        background: #74BFDE;
                        color: #fff;
                    }
                    .color-deep{
                        background: #1B405A;
                    }
                }
                .scroll-anim{
                    transition: all 1s;
                    margin-top: -33px; // 单行高度,会有微小误差,需调整
                    height: 150px; // 整体高度+单行高度 120+30
                }
                            
            }
        }
    }
}
</style>