Search code examples
tooltipecharts

Apache ECharts: How to hide tooltip when mouse outside of data area?


Apache ECharts: In 'category' type charts, tooltip is hidden when mouse is outside of data area. But the behavior is not the same in 'value' type charts which keeps showing tooltip of the first/last data point. How can I hide the tooltip if mouse stays in empty area?

cateory type

option = {
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
  },
  xAxis: {
    type: 'category',
    boundaryGap: false,
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'Test1', 'Test2']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: 'Email',
      type: 'line',
      stack: 'Total',
      data: [120, 132, 101, 134, 90, 230]
    },
    {
      name: 'Union Ads',
      type: 'line',
      stack: 'Total',
      data: [220, 182, 191, 234, 290, 330]
    },
    {
      name: 'Video Ads',
      type: 'line',
      stack: 'Total',
      data: [150, 232, 201, 154, 190, 330]
    },
    {
      name: 'Direct',
      type: 'line',
      stack: 'Total',
      data: [320, 332, 301, 334, 390, 330]
    },
    {
      name: 'Search Engine',
      type: 'line',
      stack: 'Total',
      data: [820, 932, 901, 934, 1290, 1330]
    }
  ]
};

value type

option = {
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
  },
  xAxis: {
    type: 'value',
    boundaryGap: false,
    max: 1200,
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: 'Email',
      type: 'line',
      data: [[100,120], [200,132], [300,101], [400,134], [500,90], [600, 200]]
    },
    {
      name: 'Union Ads',
      type: 'line',
      data: [[100,220], [200,182], [300,191], [400,234], [500,290], [600,90]]
    },

  ]
};

Observation: For 'category' type, axisPointer is not sticked to the first/last data point. But for 'value' type, axisPointer is always sticked to the first/last data point when mouse moves out data area. Is this the reason why tooltip is hidden for the 'categoty' type?

Expect: No tooltip showing when mouse moves out of data area for the 'value' type charts.

2023/12/13 Update :

Instead of using formatter function as Matthias Mertens shows, I use pointer function and hide the tooltip DOM element to prevent modifying tooltip content.
option = {
  tooltip: {
    trigger: 'axis',
    position: function(point, params, dom, rect, size) {
      const idxInvisible = option.series.length - 1;
      const isInvisible = (params[0].seriesIndex === idxInvisible);
      isInvisible ? $(dom).hide() : $(dom).show();
      return point;
    }
  },
  legend: {
    data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
  },
  xAxis: {
    type: 'value',
    boundaryGap: false,
    max: 1200,
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: 'Email',
      type: 'line',
      data: [[100,120], [200,132], [300,101], [400,134], [500,90], [600, 200]]
    },
    {
      name: 'Union Ads',
      type: 'line',
      data: [[100,220], [200,182], [300,191], [400,234], [500,290], [600,90]]
    },
    { // Occupy empty area only.
      name: 'invisible',
      type: 'scatter',
      itemStyle: {color: 'transparent'},
      data: [[800,0], [1000,0], [1200,0]]
    }
  ]
};

Solution

  • The simple reason for that is that the category axis has finite sections and echarts can check in which section the mouse is hovering. For value axis it is not as clear what is "empty space".

    To my knowledge there is no inbuilt feature for your use case. You could try and play around with the tooltip formatter function and an invisible helper series bounding your empty space (the formatter callback function doesnt provide the axis value at the position of hover but rather the closest datapoint; thats why we need another series to determine where the mouse hovers).

    Here is a small (unfinished) example to give you an idea:

    option = {
      tooltip: {
        trigger: 'axis',
        axisPointer: { snap: false },
        formatter: test,
      },
      xAxis: {
      },
      yAxis: {
        type: 'value'
      },
      series: [
        {
          data: [150, 230, 224, 218],
          type: 'line'
        },
        {
          type: 'scatter',
          data: [[100, 0]],
          silent: true,
          itemStyle: {color: 'transparent'}
        }
      ]
    };
    
    function test(params) {
      if (params[0].seriesIndex === 1) {
        return '';
      }
      return params[0].data + '';
    }