【BUG】ECharts 多图表在h5页面,只显示一个 tooltip

432 阅读2分钟

ECharts 多图表在同一页面时,只显示一个 tooltip

之前在h5数据看板页面提测阶段时,测试大大们,提出了个视图上的bug,说是点击完某个图表,显示出tooltip提示框后,再点击另一个图表,并不能使上次点击的tooltip自动消失。

这不,原本刚想把问题甩锅给百度可视化部门,让他们在h5上的效果也优化下,结果产品经理轻轻地把双手放我肩膀上,温柔地捏了起来:“帮忙整一下,奶茶肯定有得喝”。行吧,就是这么贪吃,只能回他句:“多加点椰果”。

思考过程

看到这个问题第一个想法,就是pc上的ECharts似乎没有这个问题啊,那这问题出在哪呢?思来想去,似乎就是h5与pc的差异上了吧,感觉是h5上没有鼠标导致的。那么就先判断监听下手机上的touchstarttouchend事件,记录下触摸屏幕时的xy的坐标,和手指离开屏幕时的坐标进行比较,如果绝对值大于0并且还处于canvas,就显示tooltip,如果触摸的元素不是canvas,那么就说明脱离了Echarts的范围,就隐藏tooltip。 可能就是需要统一写个方法,给每个ECharts设置个tooltip的开关,去设置显示、隐藏状态的切换。

解决方案

import { debounce } from "lodash";
import { mapState, mapMutations } from "vuex";

export const hideAllTooltip = {
  data() {
    return {
      // HIDE_ALL_TOOLTIP: false,
      startx: 0,
      starty: 0,
      domTag: "",
    };
  },
  computed: {
    ...mapState({
      HIDE_ALL_TOOLTIP: (state) => state.echarts.HIDE_ALL_TOOLTIP,
    }),
  },
  mounted() {
    const _this = this;
    document.addEventListener(
      "touchstart",
      function (e) {
        _this.startx = e.touches[0].pageX;
        _this.starty = e.touches[0].pageY;
        _this.domTag = e.target.tagName.toUpperCase();
        if (_this.domTag === "CANVAS") {
          _this.handleCheckAllTooltip(false);
        } else {
          _this.handleCheckAllTooltip(true);
        }
      },
      false
    );
    document.addEventListener(
      "touchend",
      debounce(
        function (e) {
          const endx = e.changedTouches[0].pageX;
          const endy = e.changedTouches[0].pageY;
          const x = Math.abs(endx - _this.startx);
          const y = Math.abs(endy - _this.starty);
          // console.log(e.target.tagName, _this.HIDE_ALL_TOOLTIP);
          // return _this.debounce(() => {
          //   console.log("x", x);
          //   console.log("y", y);
          // }, 500);
          if (x > 0 || y > 0) {
            _this.handleCheckAllTooltip(true);
          } else {
            _this.handleCheckAllTooltip(false);
          }
        },
        100,
        false
      ),
      false
    );
  },
  beforeDestory() {
    document.removeEventListener("touchstart");
    document.removeEventListener("touchend");
  },
  watch: {
    HIDE_ALL_TOOLTIP(v) {
      console.log(this.myChart);
      if (this.myChart) {
        this.myChart.setOption({
          animation: !v,
          tooltip: {
            show: !v,
          },
        });
      }
    },
  },
  methods: {
    // ...mapMutations({
    //   handleCheckAllTooltip: "SET_HIDE_ALL_TOOLTIP",
    // }),
    handleCheckAllTooltip(bool) {
      this.$store.commit("echarts/SET_HIDE_ALL_TOOLTIP", bool);
    },
    // debounce(fn, delay, immediate) {
    //   let timer;
    //   let result;
    //   return function (...args) {
    //     if (timer) clearTimeout(timer);
    //     if (immediate) {
    //       if (timer) {
    //         timer = setTimeout(() => (timer = null), delay);
    //       } else {
    //         result = fn.apply(this, args);
    //         return result;
    //       }
    //     } else {
    //       timer = setTimeout(() => fn.apply(this, args), delay);
    //     }
    //   };
    // },
    //根据起点终点返回方向 1向上 2向下 3向左 4向右 0未滑动
    // getDirection(startx, starty, endx, endy) {
    //   const x = endx - startx;
    //   const y = endy - starty;
    //   let result = "none";
    //   if (Math.abs(x) > Math.abs(y) && x > 0) {
    //     result = "right";
    //   } else if (Math.abs(x) > Math.abs(y) && x < 0) {
    //     result = "left";
    //   } else if (Math.abs(y) > Math.abs(x) && y > 0) {
    //     result = "down";
    //   } else if (Math.abs(y) > Math.abs(x) && y < 0) {
    //     result = "up";
    //   } else {
    //     result = "none";
    //   }
    //   return result;
    // },
  },
};

参考资料