coboltvogel
coboltvogel

Reputation: 11

ECharts line series to custom tooltip to group some lines together and show tooltip data accordingly?

I am using ECharts Line series to plot some kind of distance-time graph where xaxis is time (time) and yaxis is location (categorical).

In my series, I have multiple lines. So, an array of objects with each object corresponding to one "series-line".

Say I have 6 lines, travelling the same route just starting from different time.

At each given y-value (location), there would be 6 values shown on the tooltip if i set the tooltip.type to "axis", corresponding to all the times of the 6 graph at this location.

However, I dont want all values to show up on the tooltip. Setting tooltip.type to "item" will only show the data point which I hovered on, which is not what I want either.

I want it such that based on what I hovered on, e.g. at location B of series 2, the tooltip will show the time of series 2 and series 4 at location B, as they belong to the same type "car", assuming type is part of the data.

Is there any way to do it? I have been at this for so long and cant seem to find a solution. I've managed to use mouseover event to manually "highlight" lines based on type but cant seem to change the tooltip.

For more info, my tooltip configuration is

tooltip: { trigger: 'axis', axisPointer: { type: 'cross' } }

I tried using formatter as well, but based on the params, how do I know which is the series I hovered on?

Params will always return me the data points of all series.

Upvotes: 1

Views: 150

Answers (3)

Matthias Mertens
Matthias Mertens

Reputation: 2541

If you use trigger: 'item' for tooltip you can filter everything you want from your data in the formatter function.

Example:

const data = [
  { x: 100, y: 'A', cat: 1, type: 'car'},
  { x: 200, y: 'B', cat: 1, type: 'car' },
  { x: 600, y: 'C', cat: 1, type: 'car' },
  { x: 200, y: 'A', cat: 2, type: 'plane' },
  { x: 400, y: 'B', cat: 2, type: 'plane' },
  { x: 500, y: 'C', cat: 2, type: 'plane' },
  { x: 400, y: 'A', cat: 3, type: 'car' },
  { x: 500, y: 'B', cat: 3, type: 'car' },
  { x: 700, y: 'C', cat: 3, type: 'car' }
];

option = {
  xAxis: {
    type: 'time'
  },
  yAxis: {
    type: 'category'
  },
  tooltip: {
    formatter: (params) => {
      let items = data.filter(item => item.y === params.data[1] && item.type === params.data[3]);
      let html = items.map(item => "<tr><td>" + item.x + "</td><td>" + item.y + "</td><td>" + item.type + "</td></tr>").join("");
      return ["<table><th>Time</th><th>Value</th><th>Type</th>", html, "</table>"].join("");
    }
  },
  series: [
    {
      type: 'line',
      data: data.filter(item => item.cat === 1).map(item => [item.x, item.y, item.cat, item.type])
    },
    {
      type: 'line',
      data: data.filter(item => item.cat === 2).map(item => [item.x, item.y, item.cat, item.type])
    },
    {
      type: 'line',
      data: data.filter(item => item.cat === 3).map(item => [item.x, item.y, item.cat, item.type])
    }
  ]
};

Upvotes: 0

Wellen zhong
Wellen zhong

Reputation: 106

You can use the formatter callback function in ECharts to customize the content of the tooltip. The detailed steps are as follows:

  1. Add a type property to each series object to identify the type of that series, such as "car", "train", etc.

  2. In the tooltip.formatter, use the params argument to get the series of the current hovered data point.

  3. Iterate through all the series, find the series with the same type as the current hovered point, and construct the custom tooltip content.

Here is a sample code:

option = {
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'cross'
        },
        formatter: function(params) {
            let html = '';
            let hoverSeries = params.filter(item => item.seriesType === 'line')[0];
            if (hoverSeries) {
                let hoverType = hoverSeries.seriesType;
                html += `<div>Hover on ${hoverType} at location ${hoverSeries.name}</div>`;
                html += '<table><tr><th>Time</th><th>Value</th></tr>';
                params.forEach(item => {
                    if (item.seriesType === 'line' && item.data[1] === hoverSeries.data[1]) {
                        html += `<tr><td>${item.axisValue}</td><td>${item.value[1]}</td></tr>`;
                    }
                });
                html += '</table>';
            }
            return html;
        }
    },
    xAxis: {
        type: 'category',
        data: ['A', 'B', 'C', 'D', 'E', 'F']
    },
    yAxis: {
        type: 'value'
    },
    series: [
        {
            name: 'car 1',
            type: 'line',
            data: [120, 132, 101, 134, 90, 230],
            type: 'car'
        },
        {
            name: 'car 2',
            type: 'line',
            data: [220, 182, 191, 234, 290, 330],
            type: 'car'
        },
        {
            name: 'train 1',
            type: 'line',
            data: [150, 232, 201, 154, 190, 330],
            type: 'train'
        },
        {
            name: 'train 2',
            type: 'line',
            data: [320, 332, 301, 334, 390, 330],
            type: 'train'
        }
    ]
};

Upvotes: 0

ned
ned

Reputation: 538

based on what I hovered on, e.g. at location B of series 2 ...

Means you need to identify the hovered point, which is done in event mouseover.
Then it's easy to filter only points that belong to the same group, and show them in tooltip.
Example

Upvotes: 0

Related Questions