fix: skip default select when interactions already registers element-select - #4696
Conversation
…select When spec.interactions includes element-select (including isMultiple: true), do not also register the default single-select trigger so the two do not fight. Co-authored-by: David <dyk1454683243-sudo@users.noreply.github.com>
Co-authored-by: David <dyk1454683243-sudo@users.noreply.github.com>
xile611
left a comment
There was a problem hiding this comment.
@dyk1454683243-sudo 已完成 review。这个改动确实修复了饼图 interactions: [{ type: 'element-select', isMultiple: true }] 与默认单选冲突的问题,但目前会关闭自定义交互作用范围以外的默认选中,建议修复这一回归后再合并。
验证基线 c4191139a340f18f0e32dcb353c51009d88a6205 与 PR 312350584a389c56dbfc6010f6cdceb8591509b0:
| 场景 | 基线 | PR |
|---|---|---|
| 饼图连续点击两个扇区(配置 selected 样式) | 仅保留一个选中 | 正确多选 |
| 柱线组合图仅对 bar 配置 element-select,点击折线 point | 正常选中 | 无法选中 |
| 折线图仅对 line 配置 element-select,点击 point | 正常选中 | 无法选中 |
本地补充用例通过真实 VChart 创建图元,在 Node + canvas 环境显式配置 select: { trigger: 'pointertap' },通过已注册的事件处理器依次发送 pointertap / click;没有手动修改系列字段或替换图元。未做浏览器鼠标实测。PR 自带 3 个测试及修改文件的 ESLint、Prettier 均通过,但未覆盖限定 markNames 的场景。
请在解析实际匹配的图元后处理冲突,保留未被自定义交互覆盖的图元的默认选中;同时补充上述局部图元、跨系列场景的回归测试。具体位置见行内意见。
| if (interactions?.some(interaction => interaction.type === TRIGGER_TYPE_ENUM.ELEMENT_SELECT)) { | ||
| const defaultSelectIndex = res.findIndex(item => item.trigger.type === TRIGGER_TYPE_ENUM.ELEMENT_SELECT); | ||
| if (defaultSelectIndex >= 0) { | ||
| res.splice(defaultSelectIndex, 1); |
There was a problem hiding this comment.
[P2] 保留自定义交互作用范围外的默认选中
这里只要存在 element-select 就删除整个默认 select,忽略了 markNames / markIds 的作用范围。例如柱线组合图在图表级配置 interactions: [{ type: 'element-select', markNames: ['bar'], isMultiple: true }]:该配置会传给两个系列,折线系列虽然没有匹配的 bar 图元,也会先删除默认 select,随后又因匹配结果为空而不注册自定义交互,最终折线点完全无法选中。单个折线图配置 markNames: ['line'] 时,未被覆盖的 point 同样失去选中能力。上述两个场景均已验证基线通过、PR 失败。请先解析实际匹配的图元,仅处理重叠范围内的冲突,保留其他图元的默认选中,并补充回归测试。
There was a problem hiding this comment.
已核对冻结 diff、默认与自定义 element-select 的注册及状态更新路径,新增发现 1 项独立的反选样式回归。既有作用范围缺陷仍待解决,参见 https://github.com/VisActor/VChart/pull/4696#discussion_r4056020786;本次不重复提交该问题。
验证:静态核验:默认 select 配置 reverseState='selected_reverse';本次改动移除该触发器;自定义 ElementSelect 默认选项未补 reverseState;Interaction.updateStates 因而绕开反选状态分支。依赖未安装,未运行自动化或视觉测试,不能视为测试通过。
限制:隔离环境未安装仓库依赖且无网络,未运行 Jest、浏览器交互或视觉回归;结论基于冻结源码的交互配置和状态更新调用链静态核对。;未对基线和 PR 进行可执行渲染对照;既有 review 所述局部图元与跨系列回归仅引用既有讨论,不作为本次新发现。
状态:completed
| if (interactions?.some(interaction => interaction.type === TRIGGER_TYPE_ENUM.ELEMENT_SELECT)) { | ||
| const defaultSelectIndex = res.findIndex(item => item.trigger.type === TRIGGER_TYPE_ENUM.ELEMENT_SELECT); | ||
| if (defaultSelectIndex >= 0) { | ||
| res.splice(defaultSelectIndex, 1); |
There was a problem hiding this comment.
[P2] 替换默认选中时保留 selected_reverse 状态
当系列配置 state.selected_reverse,同时使用文档形式的 interactions: [{ type: 'element-select', isMultiple: true }](未显式填写 reverseState)时,删除默认 select 后,未选中的图元不再进入 selected_reverse,原本的淡化等样式消失。原因是 _defaultSelectConfig 为默认触发器设置了 reverseState: STATE_SELECTED_REVERSE,而自定义触发器直接使用原始 spec;ElementSelect.defaultOptions 仅补 state 和 trigger,Interaction.updateStates 收到空的 reverseState 时只执行选中分支。此前默认触发器会设置未选中图元的反选状态;且 IElementSelectSpec 的注释明确允许用 state.selected_reverse 配置非激活图元。建议在避免双触发器冲突的同时为未显式覆盖该字段的自定义 select 保留默认反选状态,并增加该样式的真实状态回归测试。此问题与现有讨论所述 markNames / markIds 导致图元无法选中的作用范围问题不同:这里即使自定义交互覆盖全部图元,反选视觉状态也会丢失。
Fixes #4563
🤔 This is a ...
🔗 Related issue link
Fixes #4563
💡 Background and solution
Specs that follow the official pie multi-select example:
could not keep more than one sector selected.
Default
select.enable: truestill registered a single-selectelement-selecttrigger (pointertap, replace). The specinteractionsentry registered a second one (click, accumulate). Those configs are notisEqual, soBaseChart._initInteractionskept both live. On click, default select appliedselectedfirst; the multi-select trigger then sawhasStateand did nothing.This change skips the default select trigger when
spec.interactionsalready contains anelement-selectentry. Hover / dimension-hover defaults are unchanged.interactionsmulti-select works withoutselect: falseinteractions) stays single-selectselect: { mode: 'multiple' }withoutinteractionsstill accumulates📝 Changelog
interactionsalready registerselement-select, soisMultiplemulti-select worksinteractions已配置element-select时不再注册默认单选,使isMultiple多选生效☑️ Self-Check before Merge
Verification
eslint --quietonpackages/vchart/src/series/base/base-series.tsand the new test: cleanprettier --checkon the same files: cleanjest __tests__/unit/interaction/element-select.test.ts --runner=jest-runner --testEnvironment=node: 3 passedjest-electronrunner is the default; the node runner is enough for this non-render wiring/state regression.