G6
G6 copied to clipboard
feat: add scroll-canvas behavior
任务
- https://github.com/antvis/G6/issues/5548
改动
- feat: 迁移v5_old behavior: scroll-canvas to v5
- chore: 增加demo和测试用例
breakingchanges
- 删除
enableOptimize
/optimizeZoom
,因为graph缺少隐藏node keyShape的等相关api,无法实现此功能,看后续是否需要再开发,而且通过隐藏keyShape来提升性能是否是一个好的方案; - 删除
zoomKey
/zoomRatio
, 因为zoom-canvas
基本覆盖此功能,没必要在scroll-canvas
再次处理缩放; - 删除
scalableRange
,drag相关的功能,没必要在scroll-canvas
内实现,不过目前drag-canvas
也没有此功能,看后续是否追加; - 删除
allowDragOnItem
,冗余的配置项,可通过enable
实现相同能力,故删除;
Checklist
- [x]
npm test
passes - [ ] tests and/or benchmarks are included
- [ ] commit message follows commit guidelines
Description of change
再探讨下,对于大数据量下(node+edge的图元超过1w+),滚动和拖拽等交互的性能优化方向:
- 是否可以借鉴类似```虚拟列表```的原理,仅渲染和处理canvas区域内的节点/边,但如果图元高度密集,估计也收效甚微;
我之前在v4的```scroll-canvas```, 实现过类似的demo:https://codesandbox.io/p/github/k644606347/g6-dagre-scroll-perf/main
- 还是说可以迁移到WebGL/WebGpu来彻底解决交互性能问题;
再探讨下,对于大数据量下(node+edge的图元超过1w+),滚动和拖拽等交互的性能优化方向:
- 是否可以借鉴类似
虚拟列表
的原理,仅渲染和处理canvas区域内的节点/边,但如果图元高度密集,估计也收效甚微;我之前在v4的
scroll-canvas
, 实现过类似的demo:https://codesandbox.io/p/github/k644606347/g6-dagre-scroll-perf/main
- 还是说可以迁移到WebGL/WebGpu来彻底解决交互性能问题;
大数据量下推荐迁移到 WebGL 渲染器,此时相机是真实的, 对于滚动、缩放等操作其实是通过调整相机实现的。而对于拖拽操作,后续会完善分层绘制机制,将交互的元素放置在交互层。
@Aarebecca 你好,在测试scroll-canvas
时发现了一个现象,就是将容器div#app的height设置为2000px,让其带有滚动条后,滚动canvas时,div容器也会跟着滚动;
预期: 只有canvas内容滚动才对;
现状: 上层div和canvas都会滚动;
测试环境:
- 设备:Apple M3 Pro
- 浏览器:chrome 123.0.6312.59(正式版本) (arm64) / safari 17.2.1 (19617.1.17.11.12) / firefox 121.0.1 (64 位)
示例:
原因分析:
- 首先尝试禁用wheel事件默认行为,在
scroll-canvas
下调用ev.nativeEvent.preventDefault();
,但是报错:
- debug发现DOMInteractionPlugin有设置
passive: true
https://github.com/antvis/G/blob/037f76e73dfcd47843fcda2e2151139c65ac2934/packages/g-plugin-dom-interaction/src/DOMInteractionPlugin.ts#L155
- 改为
passive: false
后,滚动行为符合预期:
因为改动的是G库的代码,辛苦看下这是否是bug,如果是该如何修复;
这里存在一个误解,滚动 Canvas 并非是指将容器设置得足够高以出现滚动条,而是画布内元素呈纵向排布且超出了视口高度。因此这个组件的实现逻辑应该与 drag-canvas
基本一致,只是 trigger
支持 wheel
或者 up
/down
,方向只支持纵向调整。
这里存在一个误解,滚动 Canvas 并非是指将容器设置得足够高以出现滚动条,而是画布内元素呈纵向排布且超出了视口高度。因此这个组件的实现逻辑应该与
drag-canvas
基本一致,只是trigger
支持wheel
或者up
/down
,方向只支持纵向调整。
@Aarebecca 我其是指antv封装的`wheel`事件,底层实现是否有欠缺,我的环境下,在滚动G6的画布时,外层的其他带有滚动条的div也跟着滚动了(div是外部系统生成的且决定是否可滚动,不是G6库生成的),这种交互效果可能会被使用G6v5的用户吐槽,比如只是想看G6的非视口区域数据,结果滚动后,整个外层div都跟着滚动,导致G6整体都滚出了div的视口;;
且无法通过wheel事件给出的`event.nativeEvent.preventDefault`阻止div滚动,因为底层代码在绑定原生wheel时设置了passive: true,(如有更优解决方案请指出);
可以在我这个分支下,将div#app的height改大一些,运行下demo上下滚动看看效果就明白了;
之前我简单研究过 passive 滚动的问题,也可以一起讨论下:
https://g.antv.antgroup.com/api/event/faq#%E5%9C%A8-chrome-%E4%B8%AD%E7%A6%81%E6%AD%A2%E9%A1%B5%E9%9D%A2%E9%BB%98%E8%AE%A4%E6%BB%9A%E5%8A%A8%E8%A1%8C%E4%B8%BA
或者我把它做成开关,创建 Canvas 时可以指定:
new Canvas({ enablePassiveScrolling: false });
之前我简单研究过 passive 滚动的问题,也可以一起讨论下:
https://g.antv.antgroup.com/api/event/faq#%E5%9C%A8-chrome-%E4%B8%AD%E7%A6%81%E6%AD%A2%E9%A1%B5%E9%9D%A2%E9%BB%98%E8%AE%A4%E6%BB%9A%E5%8A%A8%E8%A1%8C%E4%B8%BA
或者我把它做成开关,创建 Canvas 时可以指定:
new Canvas({ enablePassiveScrolling: false });
@xiaoiver 其实我在想底层还是默认不启用passive较好吧,然后G6库提供配置并透传给G,让用户侧分场景去决定是否启用;既然这是G的实现,估计以后其他依赖G的库也会有类似的问题;总之感谢回复;目前还没时间细看,等忙完这两天的
之前我简单研究过 passive 滚动的问题,也可以一起讨论下:
https://g.antv.antgroup.com/api/event/faq#%E5%9C%A8-chrome-%E4%B8%AD%E7%A6%81%E6%AD%A2%E9%A1%B5%E9%9D%A2%E9%BB%98%E8%AE%A4%E6%BB%9A%E5%8A%A8%E8%A1%8C%E4%B8%BA
或者我把它做成开关,创建 Canvas 时可以指定:new Canvas({ enablePassiveScrolling: false });
@xiaoiver 其实我在想底层还是默认不启用passive较好吧,然后G6库提供配置并透传给G,让用户侧分场景去决定是否启用;既然这是G的实现,估计以后其他依赖G的库也会有类似的问题;总之感谢回复;目前还没时间细看,等忙完这两天的
@xiaoiver 想了下 enablePassiveScrolling
方案是个不错的方案,比如可以G库底层保持逻辑不变,G6库提供配置项默认enablePassiveScrolling: false,文档告知用户可开启来提升特定场景性能;不过具体怎么做还是得你们官方决定;
之前我简单研究过 passive 滚动的问题,也可以一起讨论下:
https://g.antv.antgroup.com/api/event/faq#%E5%9C%A8-chrome-%E4%B8%AD%E7%A6%81%E6%AD%A2%E9%A1%B5%E9%9D%A2%E9%BB%98%E8%AE%A4%E6%BB%9A%E5%8A%A8%E8%A1%8C%E4%B8%BA
或者我把它做成开关,创建 Canvas 时可以指定:
new Canvas({ enablePassiveScrolling: false });
@Aarebecca 我已经使用 @xiaoiver 提供的链接教程,把g6封装的`wheel`替换为原生dom的`wheel`,已经修复了因无法执行preventDefault导致外层容器意外滚动的问题,请看下最新代码
@Aarebecca 抱歉,之前没注意ci build faild,已fix