Selva
Selva

Reputation: 1153

How can I have common tooltip for a grid in Apache echart?

I have two line charts in a grid so that I can have common zooming. Now, I want to have tooltip such that when I hover on one chart, tooltip popups in other as well. So, I can see, how the values are in both charts at the specific x-axis value.

Below is my code,

let base = +new Date(1968, 9, 3);
let oneDay = 24 * 3600 * 1000;
let date = [];
let values1 = [Math.random() * 300];
let values2 = [Math.random() * 300];
for (let i = 1; i < 20000; i++) {
  var now = new Date((base += oneDay));
  date.push(i)
  // date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
  values1.push(Math.round((Math.random() - 0.5) * 20 + values1[i - 1]));
  values2.push(Math.round((Math.random() - 0.5) * 20 + values2[i - 1]));
}

option = {
  // tooltip: {
  //   trigger: 'none',
  //   // position: function (pt) {
  //   //   return [pt[0], '10%'];
  //   // }
  // },
  toolbox: {
    feature: {
      dataZoom: {
        yAxisIndex: 'none'
      },
      restore: {},
      saveAsImage: {}
    }
  },
  grid: [
    {
      // left: '3%',
      // right: '4%',
      top: '50%',
      containLabel: true,
      // show: true
    },
    {
      // left: '3%',
      // right: '4%',
      bottom: '50%',
      containLabel: true,
      // show: true
    },
  ],
  xAxis: [
    {
      type: 'category',
      boundaryGap: false,
      data: date,
      gridIndex: 0,
    },
    {
      type: 'category',
      boundaryGap: false,
      data: date,
      gridIndex: 1,
    },
  ],
  yAxis: [
    {
      type: 'value',
      boundaryGap: [0, '100%'],
      gridIndex: 0,
    },
    {
      type: 'value',
      boundaryGap: [0, '100%'],
      gridIndex: 1,
    },
  ],
  dataZoom: [
    {
      type: 'inside',
      // start: 0,
      // end: 10
      xAxisIndex: [0, 1],
    },
    // {
    //   // start: 0,
    //   // end: 10
    //   xAxisIndex: [0, 1],
    // }
  ],
  series: [
    {
      name: 'Fake Data',
      type: 'line',
      symbol: 'none',
      sampling: 'lttb',
      itemStyle: {
        color: 'rgb(255, 70, 131)'
      },
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 0,
            color: 'rgb(255, 158, 68)'
          },
          {
            offset: 1,
            color: 'rgb(255, 70, 131)'
          }
        ])
      },
      data: values1,
      gridIndex: 0,
      xAxisIndex: 0,
      yAxisIndex: 0,
    },
    {
      name: 'Faker Data',
      type: 'line',
      symbol: 'none',
      sampling: 'lttb',
      itemStyle: {
        color: 'rgb(255, 70, 131)'
      },
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 0,
            color: 'rgb(255, 158, 68)'
          },
          {
            offset: 1,
            color: 'rgb(255, 70, 131)'
          }
        ])
      },
      data: values2,
      gridIndex: 1,
      xAxisIndex: 1,
      yAxisIndex: 1,
    }
  ]
};

The above code will render 2 charts with common zooming. I tried tooltip with item, axes and none but they didnt work.

How can I do this?

Thank you.

Upvotes: 2

Views: 1880

Answers (1)

A mere dev
A mere dev

Reputation: 1790

Solution 1

First, when using this kind of chart (with xAxis), it's recommanded to use trigger: "axis".

Then to connect the tooltip, what you actually want to do is to connect the axisPointer :

// add this to your chart option
axisPointer: {
  link: [
    {
      xAxisIndex: 'all'
    }
  ]
},

This being done, your 2 tooltips will be connected. But echart seems to struggle to display the tooltip on large dataset using xAxis.type = 'category' (20K points in your example). If you want to use big dataset with 'date' format on x, I recommand this :

  • Format you series like a list of [date, value]
  • Use xAxis.type = 'time'
  • Remove xAxis.data

Here is the full working code of your example.


Solution 2

Another solution would be to create 2 separate charts and to connect them (zoom, tooltip ...) using

echarts.connect([chart1, chart2]);

Here is what the code would look like with this method :

var myChart1 = echarts.init(document.getElementById('main1'));
var myChart2 = echarts.init(document.getElementById('main2'));

let base = +new Date(1968, 9, 3);
let oneDay = 24 * 3600 * 1000;
let date = [];
let values1 = [Math.random() * 300];
let values2 = [Math.random() * 300];
for (let i = 1; i < 200; i++) {
  var now = new Date((base += oneDay));
  date.push(i)
  // date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
  values1.push(Math.round((Math.random() - 0.5) * 20 + values1[i - 1]));
  values2.push(Math.round((Math.random() - 0.5) * 20 + values2[i - 1]));
}

var option1 = {
  tooltip: {
    trigger: 'axis',
  },
  xAxis: [
    {
      type: 'category',
      boundaryGap: false,
      data: date
    }
  ],
  yAxis: [
    {
      type: 'value',
      boundaryGap: [0, '100%'],
    },
  ],
  dataZoom: [
    {
      type: 'inside',
    },
  ],
  series: [
    {
      name: 'Fake Data',
      type: 'line',
      symbol: 'none',
      sampling: 'lttb',
      itemStyle: {
        color: 'rgb(255, 70, 131)'
      },
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 0,
            color: 'rgb(255, 158, 68)'
          },
          {
            offset: 1,
            color: 'rgb(255, 70, 131)'
          }
        ])
      },
      data: values1,
    },
  ]
};

var option2 = {
  tooltip: {
    trigger: 'axis',
  },
  xAxis: [
    {
      type: 'category',
      boundaryGap: false,
      data: date
    }
  ],
  yAxis: [
    {
      type: 'value',
      boundaryGap: [0, '100%'],
    },
  ],
  dataZoom: [
    {
      type: 'inside',
    },
  ],
  series: [
    {
      name: 'Faker Data',
      type: 'line',
      symbol: 'none',
      sampling: 'lttb',
      itemStyle: {
        color: 'rgb(255, 70, 131)'
      },
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 0,
            color: 'rgb(255, 158, 68)'
          },
          {
            offset: 1,
            color: 'rgb(255, 70, 131)'
          }
        ])
      },
      data: values2,
    },
  ]
};

myChart1.setOption(option1)
myChart2.setOption(option2)

echarts.connect([myChart1, myChart2]);
<html>
  <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.3.2/echarts.min.js"></script>
    <div id="main1" style="width: 600px; height:200px;"></div>
    <div id="main2" style="width: 600px; height:200px;"></div>
  </body>
</html>

Upvotes: 3

Related Questions