效果图
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>