G2 图表使用心得 | 4.x 版本图例支持单选模式

1,921 阅读2分钟

原文链接:www.rabbitzzc.top/blog/tab-ja…


g2 4.x版本图例支持单选模式

上一篇心得已经介绍过关于 tooltip 支持鼠标划入的的坑,以及如何解决坑。今天又遇到一个问题:

🗑️ selectedMode 属性移除,4.0 可通过自定义交互行为实现*。

在G2 4.x 升级指南中写到了新版本将se;ectedMode属性也移除了,也就是不能支持单选功能了,而官网也没有写到具体的升级指南,就直接一笔带过,包括 github 相关的issue都直接被关闭了(个人挺讨厌这种开源工具的,完全不负责任)。

自定义交互

为了解决这个问题,我也是翻阅了文档和源码,看了一下自定义交互的基本实现,接口如下:

G2.registerInteraction(name, InteractionClass | InteractionSteps);

G2也是内置了很多交互的,比如tooltip的默认交互都是通过·自定义交互实现的。但是毕竟不能支持单选,所以还是得自己写一个交互事件:

registerInteraction('single-legend', {
  showEnable: [
    { trigger: 'legend-item:mouseenter', action: 'cursor:pointer' },
    { trigger: 'legend-item:mouseleave', action: 'cursor:default' },
  ],
  start: [
    {
      trigger: 'legend-item:click',
      action: 'single-selected:single',
    },
    {
      trigger: 'legend-item:click',
      action: 'list-unchecked:toggle',
    },
    {
      trigger: 'legend-item:click',
      action: 'data-filter:filter',
    },
  ],
})

start属性中,还加了一个自定义名称'single-selected:single'action,这个action也是自定义的,所以也得手动编码:

/**
 * 源码注册了很多事件, list-* 属于图例的相关事件,传入名字即可获得基类 Action
 */
class SingleSelected extends getActionClass('list-unchecked') {
  single() {
    const triggerInfo = this.getTriggerListInfo()
    if (triggerInfo && triggerInfo.item) {
      const { list, item } = triggerInfo

      const items = list.getItems()
      items.forEach(v => {
        // 这里的 name 属性可以根据自身传入的数据进行判断
        if (v.name === item.name) {
          item.active = true
          this.setItemState(list, item, true)
        } else {
          v.active = false
          this.setItemState(list, v, true)
        }
      })
    }
  }
}

将上面的自定义交互与自定义的Action代码合并,就可以解决单选问题了:

import { registerInteraction, registerAction, getActionClass } from '@antv/g2'

/**
 * 源码注册了很多事件, list-* 属于图例的相关事件,传入名字即可获得基类 Action
 */
class SingleSelected extends getActionClass('list-unchecked') {
  single() {
    const triggerInfo = this.getTriggerListInfo()
    if (triggerInfo && triggerInfo.item) {
      const { list, item } = triggerInfo

      const items = list.getItems()
      items.forEach(v => {
        // 这里的 name 属性可以根据自身传入的数据进行判断
        if (v.name === item.name) {
          item.active = true
          this.setItemState(list, item, true)
        } else {
          v.active = false
          this.setItemState(list, v, true)
        }
      })
    }
  }
}

registerAction('single-selected', SingleSelected)
registerInteraction('single-legend', {
  showEnable: [
    { trigger: 'legend-item:mouseenter', action: 'cursor:pointer' },
    { trigger: 'legend-item:mouseleave', action: 'cursor:default' },
  ],
  start: [
    {
      trigger: 'legend-item:click',
      action: 'single-selected:single',
    },
    {
      trigger: 'legend-item:click',
      action: 'list-unchecked:toggle',
    },
    {
      trigger: 'legend-item:click',
      action: 'data-filter:filter',
    },
  ],
})

其他

这个我也给G2提了issue,具体链接为:github.com/antvis/G2/i… 感兴趣的可以去github浏览。

本文使用 mdnice 排版