移动端echarts的tooltip点击图表外部隐藏
描述在移动端没有hover事件,所以触发echart的高亮事件只有点击事件,这个时候如果有页面滚动事件的时候,滚动的时候并不能隐藏tooltip。这个时候页面滚动是不会隐藏的。除此之外,如果页面同时多个图表,这个时候会出现多个tooltip,这个产品认为可能体验会比较不好,希望能够一个页面只高亮一个图表。方案需要做到跨图表状态管理,很明显选择使用vuex来存储状态是比较方便。所以这里使用vuex来
描述
在移动端没有hover事件,所以触发echarts的高亮事件只有点击事件,这个时候如果有页面滚动事件的时候,滚动的时候并不能隐藏tooltip。
这个时候页面滚动是不会隐藏的。
除此之外,如果页面同时多个图表,这个时候会出现多个tooltip,这个产品认为可能体验会比较不好,希望能够一个页面只高亮一个图表。
方案
需要做到跨图表状态管理,很明显选择使用vuex来存储状态是比较方便。所以这里使用vuex来存储图表直接是否存在高亮的属性。
同时为了引入方便,这里使用mixin来专门处理这个属性值的变化。
代码
vuex
在vuex中为了方便修改值,写了一个Mutation和属性值设置
export default {
state:{
hideAllToolTip: false,
},
changeHideTooltip(state,payload){
state.hideAllToolTip = payload
}
}
mixin:hideAllTooltip
import {
mapState,
mapMutations,
} from 'vuex';
let hasBinded = false;
let bindedId = '';
export const hideAllToolTip = {
computed: {
...mapState({
// 使用大写 尽量避免命名冲突覆盖
HIDE_ALL_TOOLTIP: (state) => state.hideAllToolTip,
}),
},
mounted() {
// 如果已经绑定了,则直接返回
if (hasBinded) {
return;
}
hasBinded = true;
// eslint-disable-next-line no-underscore-dangle
bindedId = this.__uid;
// 绑定事件 - 捕获
document.documentElement.addEventListener('touchstart', this.EVENT_CAPTURE, true);
// 绑定事件 - 冒泡
},
methods: {
...mapMutations({
CHANGEGLOBALSTATE: 'changeHideTooltip',
}),
EVENT_CAPTURE(event) {
if (event.target.tagName.toUpperCase() === 'CANVAS') {
// 判断一下
if (this.HIDE_ALL_TOOLTIP !== false) {
this.CHANGEGLOBALSTATE({
hideAllToolTip: false,
});
}
return;
}
// this.showToolTip = false;
// clickId = '';
if (this.HIDE_ALL_TOOLTIP !== true) {
this.CHANGEGLOBALSTATE({
hideAllToolTip: true,
});
}
},
},
beforeDestroy() {
// eslint-disable-next-line no-underscore-dangle
if (bindedId === this.__uid) {
// 解绑事件 - 捕获
document.documentElement.removeEventListener('touchstart', this.EVENT_CAPTURE, true);
// 重置变量
hasBinded = false;
bindedId = '';
}
},
};
export default {
hideAllToolTip,
};
需要注意的是,这里的mixin的属性都使用大写,这样避免覆盖了引入的组件的方法和属性。
使用
只需要在对应的echart组件直接引入即可,通过监听HIDE_ALL_TOOLTIP
状态进行设置tooltip的显示与否。
例子:一个简单的linechart
这里使用的是自己封装多一层的V-CHARTS
组件,可以避免写重复的API,直接配置option即可。
<template>
<v-chart ref='chart' class="chart" :options="options" :autoresize="true"></v-chart>
</template>
<script>
import { hideAllToolTip } from '@/mixins/hideAllToolTip';
export default {
mixins: [hideAllToolTip],
data(){
return {
option : {
tooltip:{
show:true,
trigger:'axis'
},
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'
}]
};
}
},
watch: {
// 动态隐藏tooltip
HIDE_ALL_TOOLTIP(v) {
this.$refs.chart.mergeOptions({
tooltip: {
show: !v,
},
});
},
},
}
</script>
mergeOptions
这里是调用echart官方提供的动态设置option,支持merge合并模式。
如果直接去修改option的属性的,会出现重新渲染数据,导致图表都会重新闪烁或者出现初始化的动画。如果使用了dataZoom的话,还会导致滚动位置重置,这样体验会非常不好的,所以最好使用官方提供的修改option的api。
主要是封装了一层,方便使用。
V-CHART组件部分代码
export default {
methods:{
// provide an explicit merge option method
mergeOptions(options, notMerge, lazyUpdate) {
if (this.manualUpdate) {
this.manualOptions = options;
}
if (!this.chart) {
this.init(options);
} else {
// 调用echart方法
this.delegateMethod('setOption', options, notMerge, lazyUpdate);
}
},
delegateMethod(name, ...args) {
return this.chart[name](...args);
},
}
}
更多推荐
所有评论(0)