- 导读
 - Interaction
 - demo
|
- 核心:监听 mask:change 事件,触发 element-sibling-filter(这里的问题,在于 ElementSiblingFilter 的实现非常麻烦:需要自己根据 mask 内部的 element 去获取圈选起来的 records,然后再根据 sibling 的 elemnets 的 record 是否匹配,进行筛选)
">| | other-filter
- demo
|
- 核心:监听 mask:change 事件,触发 element-sibling-filter(这里的问题,在于 ElementSiblingFilter 的实现非常麻烦:需要自己根据 mask 内部的 element 去获取圈选起来的 records,然后再根据 sibling 的 elemnets 的 record 是否匹配,进行筛选) - Action
 - | elementSelection | 
- selectedElements
| 描述:记录当前交互关联的 Elements。
配置:
- filterBy 根据指定通道筛选获取匹配的选中图形元素。可选项:null | 'x' | 'color' | 'triggerInfo'。当为空时,只保留当前选中图形元素 (等价于 SurfacePointSelection)。
- multiple 是否支持多选。多选场景,不会清空之前保存的 selectedElements
- range 获取的是否是区间内的交集元素。需要结合 selectStartPoint action. - 配置:
- multiple 是否支持多选。 - 案例验证
 
导读
:::success G2 5.0 把交互、反馈进行解耦,交互由系列的触发事件和反馈 action 组合而成。
- 反馈 Action:拆解更加细粒度化,满足可组合、可复用的诉求(如: brush 交互)
 触发事件:增加了高阶事件封装(好处是什么?) :::
Action 主要分为: Service 和 Transformer, Service 类似于 Provider, Transformer 类似于 Consumer。
- Service 会获取交互过程中产生的一些信息,并且存储在上下文的 shared 变量中(注:不同交互的上下文是独立的)
- 一般来说,有:
- 鼠标位置 :
mouseX,mouseY - 当前交互的图形元素 :
selectedElements - 当前交互的组件信息:
triggerInfo(可能是分类图例、连续图例或轴标签等) - 当前交互的图例项:
selectedLegendItems 当前交互的轴项:~~selectedAxisItems~~~~ (会有吗? 再看看)~~
 - 鼠标位置 :
 - 其它:
- 鱼眼交互的聚焦位置:
focusX,focusY - 时间条、滚动条、缩略轴 等交互,最好也抽象一个变量,去处理视图过滤:
_selectedDataRange_或合并到 triggerInfo 中 
 - 鱼眼交互的聚焦位置:
 
 - 一般来说,有:
 - Transformer 会消费 Service 中产生的信息,执行具体的反馈操作。Transformer 会根据交互有很多,G2 内置有:
- 针对图形元素的反馈:见 Transformer 表格
 - 针对图例的反馈:见 Transformer 表格
 - 针对坐标轴的反馈:见 Transformer 表格
 - 其它:
 
 
| 状态 | 交互 | 交互 | 备注 | 
|---|---|---|---|
| ✅ | tooltip | Action:   1、[Service] SurfacePointSelection2、[Transformer] toolip | 
|
| ✅ | element-active | 反馈:SurfacePointSelection -> HighlightSelection | |
| ellipsis-text | 描述:图例项名、图例项值、轴标签、甚至数据标签 label 等若存在 ellipsis 行为,则可触发该交互,展示 mini tip (该类交互的操作对象,一般都有tip属性,可以作为一个通用交互)Action: 1、[Transformer] ShowTip | 
![]()  | 
|
| element-selected | Action: 1、[Service] elementSelection(multiple: true 不清空之前存储的变量)2、[Transformer] SelectElement | 
![]()  | 
|
| element-single-selected | Action: 1、[Service] elementSelection2、[Transformer] SelectElement | 
![]()  | 
|
| ✅ | element-highlight | Action: 1、[Service] elementSelection 2、[Transformer] highlightElement  | 
![]()  | 
| ✅ | element-highlight-by-x | Action: 1、[Service] elementSelection (filterBy: ‘x’) 2、[Transformer] highlightElement  | 
![]()  | 
| ✅ | element-highlight-by-color | Action: 1、[Service] elementSelection (filterBy: ‘color’) 2、[Transformer] highlightElement  | 
![]()  | 
| ✅ | legend-active | Action: 1、[Service] triggerInfoSelection 2、[Service] legendItemSelection (from: ‘triggerInfo’) 3、[Transformer] setItemState( items:[‘legend-item’],state:’active’) 4、[Service] elementSelection (bind: ‘triggerInfo’) 5、[Transformer] activeElement  | 
|
| ✅ | legend-highlight | Action: 1、[Service] triggerInfoSelection 2、[Service] legendItemSelection (from: ‘triggerInfo’) 3、[Transformer] setItemState( items:[‘legend-item’],state:’highlight’) 4、[Service] elementSelection (bind: ‘triggerInfo’) 5、[Transformer] highlight  | 
|
| ✅ | element-list-highlight | 描述: - 触发对象:element 交互; - 触发反馈:element-highlight、legend-highlight  | 
Action:
见案例验证 |  |
|  | axis-label-highlight |  |  |
| Brush 相关交互 |  |  |  |
|  | brush | 描述:
- 触发对象: plot;
- 触发反馈:【mousedown】 brush mask 开始绘制(在临时层)-> 【mouseup】过滤、展示 reset 按钮 -> 【reset:click】brush 重置,隐藏 mask
反馈:
- mousedown -> 获取当前鼠标 startPointSelection
- mousemove -> 根据当前点以及 startPoint 绘制 mask
- mouseup -> 根据当前点以及 startPoint 获取区间内的元素(进行 brush)、重置按钮
- reset:click -> 回滚 brush,隐藏 mask
 | brush with tooltip (when brushing, not display crosshair.)
考虑:brush-highlight, brush-selected 的结合 |
|  | brush-visible | 
 |  |
|  | brush-x | 
- 同 brush 很相似,不过是在 mouseup 的时候,获取的区间是根据 xScale 来获取的
 |  |
|  | brush-y | 
- 同 brush-x
 |  |
|  | element-range-highlight | 
 | 
 |
|  | element-path-highlight | 
- 自定义 path mask
 |  |
|  |  |  |  |
|  | other-filter
- demo
 | 
- 核心:监听 mask:change 事件,触发 element-sibling-filter(这里的问题,在于 ElementSiblingFilter 的实现非常麻烦:需要自己根据 mask 内部的 element 去获取圈选起来的 records,然后再根据 sibling 的 elemnets 的 record 是否匹配,进行筛选)
- element-sibling-filter,  element-sibling-filter-record.
| | | | legend-filter |
| | | | continuous-filter |
- 触发事件:legend:valuechanged
| | | | legend-visible-filter |
- 似乎和legend-filter有重复
| | | | active-region |
| | | | axis-description | 备注:
- 后来才增加的,轴字段描述说明(tooltip 交互或者监听点击事件,外置交互处理)
Action:
[Transformer] showTip、hideTip | | | | view-drag |
| | | | view-zoom |
| | | | sibling-tooltip |
| | | | plot-mousewheel-scroll |
| | | | |
| | 
pan & zoom
- https://vega.github.io/vega-lite/examples/selection_translate_scatterplot_drag.html
 - 对应 G2 4.0 的 drag-move 和 view-zoom
 
Action
Service
| Action | 共享变量 | 备注 | 进度 | 
|---|---|---|---|
| surfacePointSelection | - mouseX number- mouseY number- selectedElements  | 
描述:记录当前鼠标事件的鼠标位置 & 交互元素(考虑有元素背景的实时,也可以获取到准确的元素) | 
备注:selectedElements 适用于 tooltip 交互,但是 tooltip shared 等对 selectedElements 的处理,其实更适合在下面的 serivce 中处理。 | 
 |
| recordStartPoint | 
- startX  number
- startY number
 | 描述:记录鼠标事件的初始位置,适用于  mousedown、touchdown 等事件 |  |
| elementSelection | 
- selectedElements 
 | 描述:记录当前交互关联的 Elements。
配置:
- filterBy 根据指定通道筛选获取匹配的选中图形元素。可选项:null | 'x' | 'color' | 'triggerInfo'。当为空时,只保留当前选中图形元素 (等价于 SurfacePointSelection)。
- multiple 是否支持多选。多选场景,不会清空之前保存的 selectedElements
- range 获取的是否是区间内的交集元素。需要结合 selectStartPoint action.
备注:
1、存在多选场景,如 element-highlight-by-x, element-highlight-by-color以及 tooltip shared 等交互
2、针对以下情形,获取交集中的元素:① mask 下的交集元素 ② 如果没有 mask,则根据 startPoint 和 endPoint 获取区间 |  |
| legendItemSelection |  |  |  |
| triggerInfoSelection | 
-  triggerInfo object[]
详细:见参数定义
 | 描述:记录当前交互过程中的组件关联信息。操作对象一般有两种类型:list 型、slider 型。
- list 型:图例项、轴标签(对应 4.0 的 ListItem)
- slider 型:连续图例等
配置:
- multiple 是否支持多选。
备注:存在多选场景,如:图例的 checked、unchecked | |
type TriggerInfo = {// ① List 型。对混合图例,可以是 color, shape 等;对轴,可能是 x, y// ② Slider 型。对连续图例,可以是 size,color 或其它如:slider, 4.0 不支持对 y 通道进行过滤,5.0 可以支持。items?: Array<{id?: string; // 针对 List 型rangeMin?: any; // 针对 Slider 型rangeMax?: any; // 针对 Slider 型scaleType?: string;}>;}
Transformer
| Action | 备注 | 进度 | 
|---|---|---|
| Element (操作 shared.selectedElement 变量) | ||
| ActiveElement | 描述:用于设置当前选中的图形元素的状态为激活态- multiple 是否多选(非多选的话,需要对其它元素进行非激活处理)  | 
|
| HighlightElement | 描述:设置当前选中的图形元素的状态为高亮态,其它元素为非高亮态 | 
|
| SelectElement | 描述:用于设置或取消当前选中的图形元素的选中态- multiple 是否多选(非多选的话,需要对其它元素进行非选中处理)  | 
|
| Filter | 描述:用于筛选当前交互选中的图形元素 | |
| SiblingFilter | 描述:根据当前交互选中的图形元素筛选相邻视图( view) 的图形元素 | |
| ActiveRangeElement | 描述:设置当前框选区域内的图形元素的状态为激活态 | 
|
| HighlightRangeElement | 描述:设置当前框选区域内的图形元素的状态为高亮态,其它元素为非高亮态 | 
|
| SelectRangeElement | 描述:设置当前框选区域内的图形元素的状态为选中态 | 
|
| LinkElementsByColor | ||
| Component (操作 shared.selectedElements 变量) | ||
| Tooltip | 需要考虑 tooltip shared 以及相关自定义配置(组件层面) - 通过 shared.selectedElements 获取当前需要展示的信息  | 
备注:通过 shared.selectedElements 获取 tooltip items 的方法,需要抽取为纯函数;两个作用:1、sibling tooltip 需要 2、外部自己做联动 tooltip 的时候,也需要(参数一般是当前选中元素 + view) | ⭕️ |
| SiblingTooltip |  |  |
| 其它 |  |  |
| ShowTip | 描述:该交互只要保证当前交互的对象拥有 tip 属性即可 。
- 目前会考虑直接操作 event.currentTarget 对象,需要 trigger 事件具体到指定对象上,如: legend-item-name:mouseenter, legend-item-value:mousseenter
- 对应 4.0 中的 tooltip/ellipsis-text。此外,axis/axis-description 和这个非常类似,可以合并起来
配置:
- id(用于 HideTip 反馈中使用)
 | 
 |
| HideTip | 描述:隐藏当前交互的 tooltip |  |
| Legend Component  (操作 shared.LegendItems 变量) |  |  |
| ActiveListItem | 描述:用于设置当前选中组件项(通常为: 分类图例项、坐标轴文本)的的状态为~~激活态~~~~ 配置:
**** |  | 
 |
| ~~HightlightListItem描述:用于设置当前选中组件项(通常为: 分类图例项、坐标轴文本)的的状态为~~高亮态~~~~ 配置:
****不存在多选~~ |  |
| SelectListItem | 描述:用于设置当前选中组件项(通常为: 分类图例项、坐标轴文本)的的状态为~~选中态~~~~ 配置: 
**~~TODO备注:考虑下融合 list-focus、list-checked、list-unchecked、list-selected 等 |  |
| ActiveLegendItem | 描述:用于设置当前交互的分类图例项的状态为激活态 (同时,会取消其它项的激活态 )
- 这个是变更点
 |  |
| HighlightLegendItem | 描述:用于设置当前交互的分类图例项的状态为高亮态  |  |
| ToggleLegendItem | 描述:用于切换当前交互的分类图例项的选中态  |  |
| Mask  (操作 shared.startPoint 变量) |  |  |
| 
 | 描述:根据当前鼠标位置以及起始点绘制 mask,类型:  rect, circle, path, dim-rect, smooth-path
配置:
- type: 'rect'|'circle'|'x-rect'|'y-rect'|'path'|'smooth-path'
备注:Mask 作为一个组件(为此封装绑定 drag 事件等;绘制在 Transient Layer 上;绘制过程,触发 mask:change 事件, view 上监听 mask:change 事件,计算 mask 下涵盖的 elements, 触发 highlightElementRange 等 |  |
| Data (根据一些与数据筛选相关的共享变量进行数据筛选) 【todo 分类名换一下】 |  |  |
| 
 | 备注:
1. 根据 listItem 进行过滤(一般是分类图例项)
1. 根据 slider 类型的进行过滤(一般是连续图例,暂时还没有包含 slider、scrollbar)
1. 根据 intersectedElements 进行过滤
 |  |
| View** … |  |  |
| 
 | 备注:操作 mainLayer,进行 updater 就好了 |  |
一些备注:
- active 元素绘制在 selectionLayer 上
 - mask 绘制在 TransientLayer 上
 
案例验证
EllipsisText
registerInteraction('ellipsis-text', {start: [{trigger: 'legend-item-name:mousemove',action: 'ellipsis-text:show',throttle: { wait: 50, leading: true, trailing: false },},{trigger: 'legend-item-name:touchstart',action: 'ellipsis-text:show',throttle: { wait: 50, leading: true, trailing: false },},{trigger: 'axis-label:mousemove',action: 'ellipsis-text:show',throttle: { wait: 50, leading: true, trailing: false },},{trigger: 'axis-label:touchstart',action: 'ellipsis-text:show',throttle: { wait: 50, leading: true, trailing: false },},],end: [{ trigger: 'legend-item-name:mouseleave', action: 'ellipsis-text:hide' },{ trigger: 'legend-item-name:touchend', action: 'ellipsis-text:hide' },{ trigger: 'axis-label:mouseleave', action: 'ellipsis-text:hide' },{ trigger: 'axis-label:touchend', action: 'ellipsis-text:hide' },],});
const EllipsisText: IC<EllipsisTextOptions> = (options) => ({start: [// PC: hover, 移动: touchstart (两者不是同一个 pointer 可以合并的,故而区分开){trigger: 'legend-item-name:mousemove',// `showTip` Transformer 操作 event.currentTarget,因此事件必须指定到具体元素action: 'showTip',},{trigger: 'legend-item-name:touchstart',action: 'showTip',},{trigger: 'legend-item-value:mousemove',action: 'showTip',},{trigger: 'legend-item-value:touchstart',action: 'showTip',},{trigger: 'axis-label:mousemove',action: 'showTip',},{trigger: 'axis-label:touchstart',action: 'showTip',}],end: [{trigger: 'legend-item-name:mouseleave',action: 'hideTip',},{trigger: 'legend-item-name:touchend',action: 'hideTip',},{trigger: 'legend-item-value:mouseleave',action: 'hideTip',},{trigger: 'legend-item-value:touchend',action: 'hideTip',},{trigger: 'axis-label:mouseleave',action: 'hideTip',},{trigger: 'axis-label:touchend',action: 'hideTip',}],});
ElementSingleSelected
// 点击选中,允许取消registerInteraction('element-single-selected', {start: [{ trigger: 'element:click', action: 'element-single-selected:toggle' }],});
const ElementSelected: IC<ElementSelectedOptions> = (options) => ({start: [{trigger: 'element:pointerdown',action: [// [Service]. 记录 selectedElements 变量{ type: 'elementSelection', toggle: true },// [Transformer]. 设置或取消当前选中元素 `选中态`{ type: 'selected' }],},],});
ElementSelected
// 点击选中,允许取消registerInteraction('element-selected', {start: [{ trigger: 'element:click', action: 'element-selected:toggle' }],});
const ElementSelected: IC<ElementSelectedOptions> = (options) => ({start: [{trigger: 'element:pointerdown',action: [// [Service]. 记录 selectedElements 变量{ type: 'elementSelection', multiple: true, toggle: true },// [Transformer]. 设置或取消当前选中元素 `选中态`{ type: 'selected' }],},],});
自定义多选交互1
- 在 4.0 中,无法实现的交互,举例:多选元素,然后通过 
plot:mouseleave( event target 不涉及到 element ) 或者外部操作等来,取消全部选中的元素。5.0 解法,如下:自定义 ElementSelectedconst CustomElementSelected: IC<CustomElementSelectedOptions> = (options) => ({start: [{trigger: 'plot:pointerdown',action: [// [Service]. 记录 selectedElements 变量{ type: 'recordElements', multiple: true },{ type: 'selectElement' }],},],end: [{trigger: 'plot:pointerleave',action: [// Service. 操作数据 (外部 dispathAction,差不多也是这种用法,覆盖 shared 变量){ type: 'recordElements', selectedElements: [] },// Transformer{ type: 'selectElement' },],},],});
自定义多选交互2 🚀
const CustomElementSelected: IC<CustomElementSelectedOptions> = (options) => ({start: [{trigger: 'plot:mousedown',action: [// [Service]. 记录 selectedElements 变量{ type: 'elementSelection', multiple: true },{ type: 'selected' },],},{trigger: 'plot:mousemove',isEnable: (context) => {// 按下 shift 键的时候,才指定 actionif (context.event.shiftKey) return true;return false;},action: [{ type: 'showTooltip' }],},// 以下两种场景,隐藏 tooltip (注意,不是清空选中的 elements){trigger: 'plot:mousemove',isEnable: (context) => {// 按下 shift 键的时候,才指定 actionif (!context.event.shiftKey) return true;return false;},action: [{ type: 'hideTooltip' }],},{trigger: 'plot:mouseup',isEnable: (context) => {if (!context.event.shiftKey) return true;return false;},action: [{ type: 'hideTooltip' }],},],end: [{// 双击取消所有选择trigger: 'plot:click',isEnable: (context) => {// https://g-next.antv.vision/zh/docs/api/event#鼠标双击事件return context.event.detail === 2;},action: [// Service. 操作数据{ type: 'recordElements', selectedElements: [] },// Transformer{ type: 'selectElement' },],},],});
自定义多选交互3 🚀
1、按住 Ctrl 键开始交互 (按住 Ctrl 键之后,设置 init 为 true) 2、点击元素的时候,实现多选 (第一次点击的时候,将选中元素设置为空,且 init 为 false,开始多选) 3、松开 Ctrl 键停止多选交互,抛出一个事件(外部可以处理)
 
const CustomElementSelected: IC<CustomElementSelectedOptions> = (options) => ({start: [{trigger: 'plot:mousedown',isEnable: (context) => {return context.event.ctrlKey && !context.shared.init;},action: [{type: (context) => {context.shared.init = true;context.shared.selectedElements = [];}}]}],processing: [{trigger: 'plot:mousedown',isEnable: (context) => {return context.event.ctrlKey && context.shared.init;},action: [{ type: 'elementSelection', multiple: true, toggle: true }]},{// Transformertrigger: 'plot:mousedown',isEnable: (context) => {return context.event.ctrlKey;},// 设置当前交互选中的元素为 “选中态”action: [{ type: 'selected' }]}],end: [{trigger: 'plot:mouseup',isEnable: (context) => {return !context.event.ctrlKey;},action: [{type: (context) => {context.shared.init = false;// 操作 shared.selectedElements 去做其他的事情}}]}]});
✅ ElementActive (把之前的 highlightSelection 改为 activeElement)
// 移动到 element 上 activeregisterInteraction('element-active', {start: [{ trigger: 'element:mouseenter', action: 'element-active:active' }],end: [{ trigger: 'element:mouseleave', action: 'element-active:reset' }],});
- 自定义 elementActive 交互(https://riddle.alibaba-inc.com/riddles/a8e1ce84),需要考虑下是否加上 
toggle配置const ElementActive: IC<ElementActiveOptions> = (options) => ({start: [{trigger: 'plot:pointermove',action: [{ type: 'surfacePointSelection' },// Transformer. Selection Layer 上绘制 .active-element{ type: 'activeElement' },],},],end: [{trigger: 'plot:pointerleave',action: [{ type: 'surfacePointSelection' },{ type: 'activeElement' },],},],});
✅ ElementHighlight
```typescript // hover highlight,允许取消 registerInteraction(‘element-highlight’, { start: [{ trigger: ‘element:mouseenter’, action: ‘element-highlight:highlight’ }], end: [{ trigger: ‘element:mouseleave’, action: ‘element-highlight:reset’ }], }); 
```typescriptexport const ElementHighlight: IC<ElementHighlightOptions> = (options) => ({start: [{trigger: "plot:pointerenter",action: [{ type: "elementSelection" },// Transformer. Selection Layer 上绘制 .highlight-element{ type: "highlight" },],},],end: [{trigger: "plot:pointerleave",action: [{ type: "elementSelection" }, { type: "highlight" }],},],});
✅ ElementHighlightByX
// hover highlight by x,允许取消registerInteraction('element-highlight-by-x', {start: [{ trigger: 'element:mouseenter', action: 'element-highlight-by-x:highlight' }],end: [{ trigger: 'element:mouseleave', action: 'element-highlight-by-x:reset' }],});
export const ElementHighlightByX: IC<ElementHighlightByXOptions> = (options) => ({start: [{trigger: "plot:pointerenter",action: [{ type: "elementSelection", filterBy: 'x' },// Transformer. Selection Layer 上绘制 .highlight-element{ type: "highlight" },],},],end: [{trigger: "plot:pointerleave",action: [{ type: "elementSelection", filterBy: 'x' },{ type: "highlight" }],},],});
✅ ElementHighlightByColor
// hover highlight by color,允许取消registerInteraction('element-highlight-by-color', {start: [{ trigger: 'element:mouseenter', action: 'element-highlight-by-color:highlight' }],end: [{ trigger: 'element:mouseleave', action: 'element-highlight-by-color:reset' }],});
export const ElementHighlightByColor: IC<ElementHighlightByColorOptions> = (options) => ({start: [{trigger: "plot:pointerenter",action: [{ type: "elementSelection", filterBy: 'color' },// Transformer. Selection Layer 上绘制 .highlight-element{ type: "highlight" },],},],end: [{trigger: "plot:pointerleave",action: [{ type: "elementSelection", filterBy: 'color' },{ type: "highlight" }],},],});
✅ ElementListHighlight
// legend hover,element activeregisterInteraction('element-list-highlight', {start: [{ trigger: 'element:mouseenter', action: ['list-highlight:highlight', 'element-highlight:highlight'] }],end: [{ trigger: 'element:mouseleave', action: ['list-highlight:reset', 'element-highlight:reset'] }],});
const InteractionDescriptor = (options?: ElementListHighlightOptions,) => ({start: [{trigger: 'plot:pointermove',action: [{ type: 'elementSelection' },{ type: 'highlight', ...options },{ type: 'legendItemSelection', from: 'selectedElements' },{ type: 'setItemState', items: ['legendItem'], state: 'highlight' },],},],end: [{trigger: 'plot:pointerleave',action: [{ type: 'elementSelection' },{ type: 'highlight', ...options },{ type: 'legendItemSelection', from: 'selectedElements' },{ type: 'setItemState', items: ['legendItem'], state: 'highlight' },],},],});
✅ LegendActive
// legend hover,element activeregisterInteraction('legend-active', {start: [{ trigger: 'legend-item:mouseenter', action: ['list-active:active', 'element-active:active'] }],end: [{ trigger: 'legend-item:mouseleave', action: ['list-active:reset', 'element-active:reset'] }],});
export const LegendActive: IC<LegendActiveOptions> = (options) => ({start: [{trigger: "legend-item:mouseenter",action: [{ type: "triggerInfoSelection" },// Service. 根据 triggerInfo 记录当前交互的组件元素(shared.selectedLegendItems){ type: "legendItemSelection", from: "triggerInfo" },// Transformer. 直接操作 legend-item 状态. items 可能是 axis-label 或者其它{ type: "setItemState", state: 'active', items: ['legendItem'] },// Service. 根据 triggerInfo 记录当前交互的图形元素(shared.selectedElements){ type: "elementSelecion", from: "triggerInfo" },// Transformer. Selection Layer 上绘制 .active-element{ type: "activeElement" },],},],end: [{trigger: "legend-item:mouseleave",action: [{ type: "legendItemSelection", selectedLegendItems: [] },// { type: "legendItemSelection", reset: true },{ type: "activeLegendItem", from: "triggerInfo" },{ type: "elementSelecion", selectedElements: [] },{ type: "activeElement", from: "triggerInfo" },],},],});
✅ LegendHighlight
// legend hover,element activeregisterInteraction('legend-highlight', {start: [{ trigger: 'legend-item:mouseenter', action: ['legend-item-highlight:highlight', 'element-highlight:highlight'] },],end: [{ trigger: 'legend-item:mouseleave', action: ['legend-item-highlight:reset', 'element-highlight:reset'] }],});
const InteractionDescriptor = (options?: LegendHighlightOptions) => ({start: [{trigger: 'legend-item:pointermove',action: [{ type: 'triggerInfoSelection' },// Service. 根据 triggerInfo 记录当前交互的组件元素(shared.selectedLegendItems){ type: 'legendItemSelection', from: 'triggerInfo' },// Transformer. 直接操作 legend-item 状态{ type: 'setItemState', items: 'legendItem', state: 'highlight' },{ type: 'elementSelection', from: 'triggerInfo' },// Transformer. Selection Layer 上绘制 .highlight-element{ type: 'highlight' },],},],end: [{trigger: 'legend-item:pointerleave',action: [{ type: 'triggerInfoSelection' },{ type: 'legendItemSelection', from: 'triggerInfo' },{ type: 'setItemState', items: 'legendItem', state: 'highlight' },{ type: 'elementSelection', from: 'triggerInfo' },{ type: 'highlight' },],},],});
AxisLabelHighlight
// legend hover,element activeregisterInteraction('axis-label-highlight', {start: [{ trigger: 'axis-label:mouseenter', action: ['axis-label-highlight:highlight', 'element-highlight:highlight'] },],end: [{ trigger: 'axis-label:mouseleave', action: ['axis-label-highlight:reset', 'element-highlight:reset'] }],});
TODO
AxisDescription
// 显示坐标轴标题详情信息registerInteraction('axis-description', {start: [{ trigger: 'axis-description:mousemove', action: 'axis-description:show' }],end: [{ trigger: 'axis-description:mouseleave', action: 'axis-description:hide' }]});
const AxisDescription: IC<AxisDescriptionOptions> = (options) => ({start: [// PC: hover, 移动: touchstart (两者不是同一个 pointer 可以合并的,故而区分开){trigger: 'axis-description:mousemove',// `showTip` Transformer 操作 event.currentTarget,因此事件必须指定到具体元素action: 'showTip',formatter: (tip) => `字段说明: ${tip}`},],end: [{trigger: 'axis-description:mouseleave',action: 'hideTip',},],});
Brush / BrushHighlight
交互描述:圈选元素(矩形圈选、x,y 方向圈选、不规则圈选、甚至是多选)-> 进行反馈(筛选或高亮、选中)
- ECharts Brush:https://echarts.apache.org/en/option.html#brush(圈选的 mask 可拖拽、调整大小)
 - Vega Brush:https://vega.github.io/vega-lite/examples/interactive_brush.html
 
    
  
/** Brush 交互共享变量 */type BrushSharedInfo = {// 是否在圈选状态,不在圈选状态时,不根据鼠标位置实时改变 endX,endY 坐标brushing?: boolean;// 支持多个选区areas: Array<// 记录每个选区的关键点// brushType 为 rect, rect-x, rect-y, circle 时,记录圈选的起始点和结束点 [[point1X, point1Y], [point2X, point2Y]]// brushType 为 polygon 时,记录了圈选的不规则图形的若干个关键点. [[point1X, point1Y], [point2X, point2Y], [point3X, point3Y], ...]Array<[number, number]>>;selectedElements: any[];};enum Services {/** 处理 brushing 变量,代表当前是否处于圈选阶段 */ToggleBrushing,RecordBrushAreas,}enum Transformers {/** draw mask, according to points */mask,// 根据 selectedElements 进行数据过滤FilterRange,/** Get selectedElements by mask intersection. */elementSelection,}
registerInteraction('brush', {showEnable: [{ trigger: 'plot:mouseenter', action: 'cursor:crosshair' },{ trigger: 'plot:mouseleave', action: 'cursor:default' },],start: [{trigger: 'mousedown',isEnable: isPointInView,action: ['brush:start', 'rect-mask:start', 'rect-mask:show'],},],processing: [{trigger: 'mousemove',isEnable: isPointInView,action: ['rect-mask:resize'],},],end: [{trigger: 'mouseup',isEnable: isPointInView,action: ['brush:filter', 'brush:end', 'rect-mask:end', 'rect-mask:hide', 'reset-button:show'],},],rollback: [{ trigger: 'reset-button:click', action: ['brush:reset', 'reset-button:hide', 'cursor:crosshair'] }],});






