echartsapache-echarts

Apply emphasis fade & focus to select group of series in apache echarts line chart?


I can't figure out how you would default chart options to group series and allow emphasis on a whole group when one of the series within the group is hovered over. For example, if you have four lines:

option = {
  dataset: {
    dimensions: ['weekday', 'l1', 'l2', 'l3', 'l4'],
    source: [
      ['Mon', 250, 120, 75, 30],
      ['Tue', 220, 140, 100, 30],
      ['Wed', 230, 160, 80, 60],
      ['Thurs', 260, 200, 90, 20],
      ['Fri', 300, 128, 100, 40],
      ['Sat', 275, 150, 111, 20],
      ['Sun', 250, 175, 89, 20]
    ],
    sourceHeader: false
  },
  xAxis: {
    type: 'category',
  },
  yAxis: {
    type: 'value'
  },
  legend: {},
  series: [
    {
      name: 'line 1',
      encode: {x: 0, y: 1},
      type: 'line',
      emphasis: {
        focus: 'series',
      }
    },
    {
      name: 'line 2',
      encode: {x: 0, y: 2},
      type: 'line',
      emphasis: {
        focus: 'series'
      }
    },
    {
      name: 'line 3',
      encode: {x: 0, y: 3},
      type: 'line',
      emphasis: {
        focus: 'series'
      }
    },
    {
      name: 'line 4',
      encode: {x: 0, y: 4},
      type: 'line',
      emphasis: {
        focus: 'series'
      }
    }
  ]
};

Essentially, I want to to group series together like this:

Group 1: line 1 & line 2

Group 2: line 3 & line 4

I then want to control the emphasis of the groups rather than the individual series. So if someone hovered their mouse over line 1, it would keep line 1 and 2 in focus and fade out 3 and 4. Is this possible to do?

I looked at series.id, series.dataGroupId, series.data.groupId, and series.data.childGroupId and I don't think any of those would control the emphasis in the way I am wanting. I also tried series.universalTransition

universalTransition: {
   enabled: true,
   seriesKey: //'group1' or 'group2' depending on the series
}

but after reading about universalTransition, it seems to be about merging data and their associated animations rather than allowing grouping of emphasis animations.

Here's a link to the above code in an ECharts editor.


Solution

  • Alternative emphasis could be done (as suggested) through mouse events: Example.

    option = {
      dataset: {
        dimensions: ['weekday', 'l1', 'l2', 'l3', 'l4'],
        source: [
          ['Mon', 250, 120, 75, 30],
          ['Tue', 220, 140, 100, 30],
          ['Wed', 230, 160, 80, 60],
          ['Thurs', 260, 200, 90, 20],
          ['Fri', 300, 128, 100, 40],
          ['Sat', 275, 150, 111, 20],
          ['Sun', 250, 175, 89, 20]
        ],
        sourceHeader: false
      },
      xAxis: {
        type: 'category'
      },
      yAxis: {
        type: 'value'
      },
      legend: {},
      series: [
        {
          name: 'line 1',
          encode: { x: 0, y: 1 },
          type: 'line', lineStyle:{width:3},
          dataGroupId: 1, triggerLineEvent: true,
          //emphasis: { focus: 'series' }
        },
        {
          name: 'line 2',
          encode: { x: 0, y: 2 },
          type: 'line', lineStyle:{width:3},
          dataGroupId: 1, triggerLineEvent: true,
          //emphasis: { focus: 'series' }
        },
        {
          name: 'line 3',
          encode: { x: 0, y: 3 },
          type: 'line', lineStyle:{width:3},
          dataGroupId: 2, triggerLineEvent: true,
          //emphasis: { focus: 'series' }
        },
        {
          name: 'line 4',
          encode: { x: 0, y: 4 },
          type: 'line', lineStyle:{width:3},
          dataGroupId: 2, triggerLineEvent: true,
          //emphasis: { focus: 'series' }
        }
      ]
    };
    sin = null;
    myChart.on('mouseover', (p) => {
      var opts = myChart.getOption();
      if (sin == null) {
        sin = p.seriesIndex;
        grp = opts.series[sin].dataGroupId;
        for (let i = opts.series.length - 1; i >= 0; i--) {
          if (opts.series[i].dataGroupId === grp) {
            opts.series[i].lineStyle = { opacity: 1 };
          } else {
            opts.series[i].lineStyle = { opacity: 0.2 };
            opts.series[i].itemStyle = { opacity: 0.2 };
          }
        }
      }
      myChart.setOption(opts);
    });
    myChart.on('mouseout', (p) => {
      var opts = myChart.getOption();
      if (sin != null) {
        //reset
        opts.series.forEach((s) => {
          s.lineStyle = { opacity: 1 };
          s.itemStyle = { opacity: 1 };
        });
        sin = null;
      }
      myChart.setOption(opts);
    });