Compare commits

..

137 Commits

Author SHA1 Message Date
b7d0c0bd62 chore: 🔧 release x6-react-shape@1.6.6 2024-08-15 13:59:13 +08:00
753bc29dcc fix: react-shape this.selectors must valid (#4374)
Co-authored-by: 魄兵 <pobing.slb@alibaba-inc.com>
2024-08-14 09:54:49 +08:00
9f200a272d chore: 🔧 change publish script 2023-11-14 10:28:35 +08:00
556121d68d chore(release): 🚀 publish
- @antv/x6-react-shape@1.6.5
2023-11-14 10:19:20 +08:00
2a132a2c19 fix: 🐛 support multiple graph 2023-11-14 10:16:18 +08:00
6d37943855 chore(release): 🚀 publish
- @antv/x6@1.35.0
2023-09-25 18:00:00 +08:00
1ca2114005 fix: 🐛 add judge when call renderHTMLComponent 2023-09-25 17:52:31 +08:00
032cce51df fix: 🐛 stop listen event when transform removed 2023-09-25 17:30:43 +08:00
add5600a26 chore(release): 🚀 publish
- @antv/x6@1.34.14
2023-07-06 09:41:49 +08:00
0fb2dcc96a fix: 🐛 check label node existed before change position 2023-07-05 22:46:52 +08:00
d440dfc6b1 docs: fixed the link to the homepage of the official website (#3651) (#3652)
Co-authored-by: qiufeihong <qiufeihong.qfh@alibaba-inc.com>
2023-06-06 19:26:20 +08:00
87fac22cd0 docs: 📚️ add animation example 2023-05-12 15:17:17 +08:00
de35af5d84 chore(release): 🚀 publish
- @antv/x6@1.34.13
2023-03-31 21:56:30 +08:00
d59e62605a fix: 🐛 fix parseInt error 2023-03-31 21:50:29 +08:00
b242a00bd0 chore(release): 🚀 publish
- @antv/x6@1.34.12
2023-03-22 16:51:32 +08:00
0b27331a4d fix: 🐛 parseint zindex to get correct max zindex node 2023-03-22 16:44:18 +08:00
05c3821ee9 docs(v1-react): fix memo equal condition (#3368)
docs(react): fix memo equal condition
2023-03-10 21:55:43 +08:00
afeab7b300 chore(release): 🚀 publish
- @antv/x6-angular-shape@1.3.2
 - @antv/x6-react-shape@1.6.4
 - @antv/x6-vue-shape@1.5.4
2023-02-22 11:22:21 +08:00
897a1a1812 fix: 🐛 limit peer dependencies version 2023-02-22 11:14:01 +08:00
399ca71075 chore(release): 🚀 publish
- @antv/x6@1.34.11
2023-02-21 23:33:13 +08:00
7c4e1b9272 fix: 🐛 cannot use this here 2023-02-21 22:30:34 +08:00
b8330d164b docs: fix typo about ‘defaultLabel’ (v1) (#3263)
docs: fix typo in labels.zh.md (v1)
2023-02-21 18:13:47 +08:00
d761f59789 chore(release): 🚀 publish
- @antv/x6@1.34.10
2023-02-03 10:35:20 +08:00
a07be165f0 fix: 🐛 change execludeNodes typo (#3199) 2023-02-02 18:08:58 +08:00
8c7dec349d chore(release): 🚀 publish
- @antv/x6@1.34.9
2023-02-02 11:23:32 +08:00
733fb867b2 fix(dnd): change dragging container options (#3186)
Co-authored-by: jinxiayi <jinxiayi@nbicc.com>
2023-02-01 17:41:37 +08:00
709f6021be chore(release): 🚀 publish
- @antv/x6@1.34.8
2023-01-31 11:08:07 +08:00
3ca9d416ff chore: 🔧 release new version (#3181) 2023-01-31 11:07:31 +08:00
8f891d06b6 fix: 🐛 fix index error for priorityQueue (#3180) 2023-01-31 03:30:46 +08:00
ea14d843cc docs: 📚️ show corrected demos in gallery (#3178) 2023-01-30 18:04:31 +08:00
25d56d0a66 docs: 📚️ update deps for demos 2022-11-30 16:35:32 +08:00
1e7a14d21d chore(release): 🚀 publish
- @antv/x6-react-components@1.1.20
2022-11-16 10:44:30 +08:00
d6e6b907fd fix: 🐛 fix typo for color-picker (#2885) 2022-11-16 10:42:59 +08:00
ba1fc3fd77 feat(x6-react-component): support for antd 5.0 (#2878)
feat(x6-react-component): support for antd 5.0, fix #2873

Co-authored-by: 诸岳 <fuping.dfp@antgroup.com>
2022-11-16 10:20:47 +08:00
d44dce03de chore(release): 🚀 publish
- @antv/x6@1.34.6
2022-11-09 15:37:34 +08:00
7873c546ff fix: 🐛 add timeout for animation setup (#2858)
Co-authored-by: 文瑀 <wenyu.jqq@antfin.com>
2022-11-09 15:34:19 +08:00
31c124aec7 chore: update contributors [skip ci] 2022-11-01 01:31:27 +00:00
91a59c7709 chore: update contributors [skip ci] 2022-10-30 01:32:05 +00:00
13e5cf36e1 chore: update contributors [skip ci] 2022-10-27 01:30:55 +00:00
537c3e8a50 chore: update contributors [skip ci] 2022-10-25 12:19:53 +00:00
549fe1cf56 docs: 📚️ add tips for insertPort api (#2806) 2022-10-25 20:19:31 +08:00
2b46e804c3 chore: update AUTHORS [skip ci] 2022-10-25 09:38:27 +00:00
745a9f4367 chore: update contributors [skip ci] 2022-10-25 09:33:14 +00:00
eef7ccf8bd fix: 🐛 fix nodes moved error when snapped (#2805) 2022-10-25 17:32:52 +08:00
1f7603ec05 chore: update contributors [skip ci] 2022-10-25 09:32:34 +00:00
5814103767 fix:🐛fix the bug cannot read properties of null when cell is not exit (#2802)
Co-authored-by: 温贝 <wenbei.wb@alibaba-inc.com>
2022-10-25 17:32:10 +08:00
595858558e fix: 🐛 add warn when use fallback router (#2799) 2022-10-25 06:46:07 +08:00
a6e3b4d4d3 fix: 🐛 fix the error in selected nodes position when snapline enabled (#2798) 2022-10-24 21:40:13 +08:00
466bc5d324 chore: update contributors [skip ci] 2022-10-23 01:30:26 +00:00
2bdd945670 chore: update contributors [skip ci] 2022-10-20 01:31:58 +00:00
a1ed7ee212 chore: update contributors [skip ci] 2022-10-19 01:30:34 +00:00
aeed9a6d3c chore: update contributors [skip ci] 2022-10-15 01:31:11 +00:00
18e5eb8378 chore: update contributors [skip ci] 2022-10-14 01:32:09 +00:00
609ed7e3d3 chore(release): 🚀 publish
- @antv/x6-geometry@1.0.14
 - @antv/x6-vector@1.4.2
 - @antv/x6@1.34.5
2022-10-13 21:32:50 +08:00
8a8d14abfa fix: 🐛 check if the navigator global is available before usage (#2768) 2022-10-13 10:39:54 +08:00
c6ca04317b chore: 🔧 remove version and track file for publish problem (#2763) 2022-10-10 15:38:28 +08:00
a57091306c chore(release): 🚀 publish
- @antv/x6-react-components@1.1.19
 - @antv/x6-react-shape@1.6.3
 - @antv/x6-vue-shape@1.5.3
 - @antv/x6@1.34.3
2022-10-10 12:31:53 +08:00
8f0b6fc6e4 chore: 🔧 change publish opts (#2762) 2022-10-10 12:28:03 +08:00
28341ac102 chore: 🔧 update publish script (#2757) 2022-10-09 22:39:23 +08:00
2e066ab625 2739/revert snapline sharp option deprecation (#2746)
* fix: 🐛 re-enable alternative line style in snapline

* docs(snapline): 📚️ remove deprecation notice

* fix: 🐛 revert import order
2022-10-09 22:33:59 +08:00
e09cb8ce93 fix: 🐛 add resizeOptions to getContentArea (#2745)
#2408
2022-10-09 22:25:14 +08:00
232064b74c chore: update contributors [skip ci] 2022-10-07 01:30:49 +00:00
64710553ee chore: update contributors [skip ci] 2022-10-06 01:30:19 +00:00
78c462ed79 chore: update AUTHORS [skip ci] 2022-09-30 08:46:01 +00:00
4954578288 chore: update contributors [skip ci] 2022-09-30 08:38:57 +00:00
6c87514ce7 docs:修复中文文档关于zIndex描述中的错别字 (#2738) 2022-09-30 16:38:33 +08:00
1f3fbd7993 docs: 📚️ color not support gradients (#2734)
Co-authored-by: 文瑀 <wenyu.jqq@antfin.com>
2022-09-28 18:13:07 +08:00
ff24e5eef7 chore: update AUTHORS [skip ci] 2022-09-28 10:03:04 +00:00
481c6e1963 chore: update contributors [skip ci] 2022-09-28 09:56:58 +00:00
f33a2979a2 docs: 📚️ Translate some docs\tutorial\intermediate .md to english (#2722)
* Translate to en using deepl.com

* Fix accessibility issue: wrong formated link

Co-authored-by: Thomas Zeugner <thomas.zeugner@kuka.com>
2022-09-28 17:56:33 +08:00
505d8dd89a chore(deps): bump actions/stale from 5 to 6 (#2721)
Bumps [actions/stale](https://github.com/actions/stale) from 5 to 6.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-28 17:42:42 +08:00
bda642cd15 chore: 🔧 update react-shape version for sites demo (#2732)
* chore(release): 🚀 publish

 - @antv/x6-react-components@1.1.18
 - @antv/x6-react-shape@1.6.2
 - @antv/x6-vue-shape@1.5.2
 - @antv/x6@1.34.2

* chore: 🔧 update react-shape version for sites demo

Co-authored-by: 文瑀 <wenyu.jqq@antfin.com>
2022-09-28 13:50:42 +08:00
9c539efab9 chore: update contributors [skip ci] 2022-09-23 01:32:31 +00:00
1cc9d2940c chore: update contributors [skip ci] 2022-09-20 14:40:24 +00:00
d49cf472a2 fix: 🐛 add case sensitive attrs (#2711)
* fix: 🐛 add case sensitive attrs

* chore(release): 🚀 publish

 - @antv/x6-react-components@1.1.18
 - @antv/x6-react-shape@1.6.2
 - @antv/x6-vue-shape@1.5.2
 - @antv/x6@1.34.2

Co-authored-by: 文瑀 <wenyu.jqq@antfin.com>
2022-09-20 22:40:00 +08:00
fee4b13750 feat: foreignObject内部元素默认不触发拖动和选中行为 close #2549 (#2676)
* feat:  foreignObject内部元素默认不触发拖动和选中行为 close #2549

* fix: 🐛 add return type
2022-09-20 22:03:53 +08:00
7c43726a2d chore: update contributors [skip ci] 2022-09-20 05:52:00 +00:00
4c5354ab70 fix: 🐛 fix scroller options typo (#2706)
* chore(release): 🚀 publish

 - @antv/x6-react-components@1.1.17
 - @antv/x6-vue-shape@1.5.1
 - @antv/x6@1.34.1

* fix: 🐛 fix scroller options typo
2022-09-20 13:51:35 +08:00
7725bacc93 docs: 📚️ update demo for readme (#2707) 2022-09-20 13:51:19 +08:00
f9b2600353 chore: update AUTHORS [skip ci] 2022-09-15 01:54:18 +00:00
d4393d6a39 chore: 🔧 update react-resize-detector version (#2684) 2022-09-15 09:48:23 +08:00
f0ee53a125 chore: update contributors [skip ci] 2022-09-15 01:34:45 +00:00
57c8525bb4 chore: update AUTHORS [skip ci] 2022-09-14 13:35:43 +00:00
9f3dfb7a8d chore: update AUTHORS [skip ci] 2022-09-14 13:13:47 +00:00
72b050c386 docs: change changelog href (#2679)
Co-authored-by: 薛腾飞 <xuetf@maycur.com>
2022-09-14 21:07:05 +08:00
0c024cefed docs: fix the docs in use Vue3 Teleport (#2677) 2022-09-14 21:06:30 +08:00
8abcb4bca0 fix: 🐛 add page size check condition (#2675) 2022-09-14 09:28:51 +08:00
5f53a09621 chore: update contributors [skip ci] 2022-09-13 01:31:21 +00:00
9f33e01a82 chore: update contributors [skip ci] 2022-09-12 09:17:31 +00:00
f846067448 feat: dnd support dndContainer. close #2562 #2572 (#2585) 2022-09-12 17:17:07 +08:00
8a6338ae3c chore: update contributors [skip ci] 2022-09-11 01:30:51 +00:00
3a79c686cd docs: 📚️ add qrcode for communication (#2651) 2022-09-08 15:28:23 +08:00
7db7a15cac chore: update contributors [skip ci] 2022-09-08 01:32:46 +00:00
375c3b190c chore: update contributors [skip ci] 2022-09-07 13:44:49 +00:00
24892181ca chore: 🔧 add publish cmd (#2622)
* chore: 🔧 add publish cmd

* chore: 🔧 delete release-it cmd
2022-09-07 21:44:27 +08:00
841531ecc1 chore: update contributors [skip ci] 2022-09-05 03:26:19 +00:00
2460f20a42 chore(release): 🚀 publish
- @antv/x6-vue-shape@1.5.0
 - @antv/x6@1.34.0
2022-09-05 11:25:33 +08:00
c8f8b9b4e0 fix: 🐛 update style (#2621) 2022-09-05 11:22:19 +08:00
0d0d973d3e fix: 🐛 change the update function name to avoid unnecessary updates (#2620) 2022-09-04 21:41:53 +08:00
eed25260af chore: update contributors [skip ci] 2022-09-04 01:32:43 +00:00
9f1130f260 chore: update contributors [skip ci] 2022-09-03 01:34:05 +00:00
cd9df4d609 chore: update AUTHORS [skip ci] 2022-09-02 11:02:36 +00:00
eb195abe3c chore: update contributors [skip ci] 2022-09-02 10:55:55 +00:00
fa8f71a3e1 doc: fix prop names of menu component in doc (#2615)
Co-authored-by: 雪奈 <xuenai.zxl@antgroup.com>
2022-09-02 18:55:29 +08:00
4171975d62 chore: update contributors [skip ci] 2022-09-01 11:10:58 +00:00
f0bbb828a3 fix: 🐛 support percent in edge button tool (#2608) 2022-09-01 19:10:34 +08:00
d52ddfad87 fix: fix problem that selection rubberband cannot be created (#2606)
* docs: 📚️ remove update methods in scroller

* chore: 🔧 update x6-sites deps

* fix: 🐛 fix problem that selection rubberband cannot be created
2022-09-01 17:41:47 +08:00
5c39bcf2c8 chore: update contributors [skip ci] 2022-09-01 01:33:45 +00:00
8cac05deaf chore: update AUTHORS [skip ci] 2022-08-29 09:20:21 +00:00
96a387822e chore: update contributors [skip ci] 2022-08-29 09:17:36 +00:00
2f3a565843 fix: 🐛修复 issue #2504问题 (#2540) 2022-08-29 17:17:14 +08:00
64de4c7753 chore: update contributors [skip ci] 2022-08-29 09:14:12 +00:00
502ceb1abb fix: 🐛 #2581 修复 scheduler 任务调度的问题 (#2581) (#2582) 2022-08-29 17:13:52 +08:00
0509fd4897 chore: update contributors [skip ci] 2022-08-29 01:31:02 +00:00
1f6196e663 refactor: ♻️ refactor x6 vue shape. close #2566 (#2569) 2022-08-26 11:56:26 +08:00
e9de0ba4c0 chore: update contributors [skip ci] 2022-08-26 01:31:29 +00:00
8ab3810c5e chore: update contributors [skip ci] 2022-08-25 14:05:08 +00:00
7405eba4e4 chore(deps): bump @actions/core in /scripts/monorepo-semantic-release (#2544)
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.2.6 to 1.9.1.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

---
updated-dependencies:
- dependency-name: "@actions/core"
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-25 22:03:57 +08:00
b1add84978 chore: update contributors [skip ci] 2022-08-25 13:46:44 +00:00
d51c0db472 feat: support scroller resize direction (#2408)
* feat:  support scroller resize direction

Closes: #2323

* feat:  adjust calcContextArea param

Co-authored-by: MrMengJ <mrmengj@gmail.com>
2022-08-25 21:46:18 +08:00
59919533ce chore: update contributors [skip ci] 2022-08-20 01:31:01 +00:00
43fee42084 chore: update contributors [skip ci] 2022-08-19 01:31:35 +00:00
7066d63a35 chore: update contributors [skip ci] 2022-08-18 01:31:54 +00:00
0ebf120be3 fix: 🐛 fontSize拼写错误 #2531 (#2533) 2022-08-17 23:14:46 +08:00
710c249c15 chore: update contributors [skip ci] 2022-08-17 15:04:52 +00:00
e4d3c2b253 fix: 🐛 #2505 修复toggleVisible之后导致不渲染的问题 (#2520) 2022-08-17 23:04:20 +08:00
e83b1ed507 fix(history): 🐛 try to merge move+embed into 1 undo (#2492) 2022-08-17 23:03:25 +08:00
cc2cd5fdb8 chore: update contributors [skip ci] 2022-08-16 14:02:03 +00:00
17dcde8426 fix: 🐛 fix some issues (#2528)
1、解决点击画布时,input无法正常失去焦点
2、添加touch-action: none;阻止移动端中滑动节点页面一起移动
3、https://github.com/antvis/X6/issues/2527
2022-08-16 22:01:31 +08:00
a9dcc84994 chore: update contributors [skip ci] 2022-08-13 01:30:53 +00:00
725372fa96 chore: 🔧 release @antv/x6@1.33.1 2022-08-12 08:09:15 +08:00
46af7cd55a fix: 🐛 not sort views after visible change (#2501) 2022-08-12 08:01:02 +08:00
e7f3257640 chore: update contributors [skip ci] 2022-08-11 09:57:54 +00:00
9791dbb09f docs: 📚️ modernize react portal usage and examples (#2491) 2022-08-11 17:57:42 +08:00
ff2d29889d docs: 📚️ add deprecation notice for Snapline.sharp (#2490) 2022-08-11 17:57:29 +08:00
74b8256ce1 chore: update contributors [skip ci] 2022-08-10 01:30:20 +00:00
2248b27258 docs: 📚️ specify createEdge description (#2473) 2022-08-08 21:41:36 +08:00
275 changed files with 1817 additions and 1225 deletions

View File

@ -13,7 +13,7 @@ jobs:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.PRIVATE_KEY }}
env_name: bot_token
- uses: actions/stale@v5
- uses: actions/stale@v6
with:
repo-token: ${{ env.bot_token }}
stale-issue-message: |

View File

@ -1,4 +1,5 @@
BARM <284942955@qq.com>
Candy <563378816@qq.com>
Chaoqi <HAN>
Clifford <ajard>
DaiGang <42136433+daigang666@users.noreply.github.com>
@ -12,6 +13,7 @@ Indomi <indomi126@gmail.com>
James <san>
Jógvan <lse>
Ken <ei>
Limbo <49612796+JUST-Limbo@users.noreply.github.com>
Lixu <37231473+wflixu@users.noreply.github.com>
Lloyd <ho>
Lyn <47809781+lyn-boyu@users.noreply.github.com>
@ -26,6 +28,7 @@ RuiLin <on>
SSC <273702440@qq.com>
Sindori <441933726@qq.com>
Susan <527971893@qq.com>
Thomas <eugne>
Tony <>
Utopia <greatauk11@gmail.com>
XLZY <1017866168@qq.com>
@ -42,6 +45,7 @@ daigang <1210242662@qq.com>
doublewu <592581554@qq.com>
iceytea <liyunheasap@yeah.net>
jiqili <43718732+jiqili@users.noreply.github.com>
kelin.zrh <34393362+AricZhu@users.noreply.github.com>
kingshuaishuai <ken.wang@mrs.ai>
kio <1421104933@qq.com>
lijing666 <lijing241@yeah.net>
@ -49,6 +53,7 @@ lopn <lopnxrp@126.com>
luchunwei <luchunwei@gmail.com>
luzhuang <364439895@qq.com>
lvhuiyang <ilvhuiyang@gmail.com>
myzxlin <myzxlin@163.com>
newbyvector <vectorse@126.com>
niexq <1879633916@qq.com>
niexq <niexq@firstgrid.cn>
@ -59,7 +64,9 @@ qu <33251372+Qujh97@users.noreply.github.com>
sallen450 <qinghua10199@gmail.com>
semantic-release-bot <semantic-release-bot@martynus.net>
vector <vectorse@126.com>
wenbei <38773084+wb-wenbei@users.noreply.github.com>
wgf <34190465+evelope@users.noreply.github.com>
wind <>
wjqsummer <52412389+wjqsummer@users.noreply.github.com>
wtzeng1 <wtzeng1@gmail.com>
x6-bot <x6-bot@users.noreply.github.com>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 12 MiB

After

Width:  |  Height:  |  Size: 15 MiB

View File

@ -160,9 +160,7 @@ graph.addEdge({
Welcome to join the **X6 Communication Group** (Scan the QR Code to Join us). We also welcome the github [issues](https://github.com/antvis/x6/issues).
<a href="https://qr.dingtalk.com/action/joingroup?code=v1,k1,rOHuvgq5s0EHDktyyQJffDE3ZAmHnbB2e6iwn/w4BKs=&_dt_no_comment=1&origin=11" target="_blank" rel="noopener noreferrer">
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*Up-4S4v8H-0AAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群1" width="375" />
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*4Y_5S7i26LAAAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群2" width="375" />
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*KHB4QJAsW4QAAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群3" width="375" />
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*nFa5TaWsSOoAAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群4" width="260" />
</a>
## Development

View File

@ -121,7 +121,7 @@ graph.addEdge({
- [基础教程](https://x6.antv.vision/zh/docs/tutorial/basic/graph)
- [进阶实践](https://x6.antv.vision/zh/docs/tutorial/intermediate/serialization)
- [高级指引](https://x6.antv.vision/zh/docs/tutorial/advanced/animation)
- [更新日志](https://x6.antv.vision/zh/docs/tutorial/log)
- [更新日志](https://www.yuque.com/antv/x6/xgb04i)
## 应用案例
@ -165,9 +165,7 @@ graph.addEdge({
需要注意的是,提问题时请配上 [CodeSandbox](https://codesandbox.io/s/pensive-sound-f4nhc) 的复现代码,方便快速定位和解决问题。
<a href="https://qr.dingtalk.com/action/joingroup?code=v1,k1,rOHuvgq5s0EHDktyyQJffDE3ZAmHnbB2e6iwn/w4BKs=&_dt_no_comment=1&origin=11" target="_blank" rel="noopener noreferrer">
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*Up-4S4v8H-0AAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群1" width="260" />
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*4Y_5S7i26LAAAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群2" width="260" />
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*KHB4QJAsW4QAAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群3" width="260" />
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*nFa5TaWsSOoAAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群4" width="260" />
</a>
## 如何开发

View File

@ -1,6 +1,6 @@
{
"peerDependencies": {
"antd": ">=4.4.2"
"antd": ">=4.4.2 || >=5.0.0-beta.0"
},
"devDependencies": {
"antd": "^4.4.2"

View File

@ -8,7 +8,6 @@
"pretty-quick": "^3.1.1",
"rimraf": "^3.0.2",
"ts-node": "^10.2.1",
"typescript": "^4.4.3",
"release-it": "^14.0.1"
"typescript": "^4.4.3"
}
}

View File

@ -9,7 +9,7 @@
"precommit": "lint-staged"
},
"dependencies": {
"@antv/x6": "^1.32.3",
"@antv/x6": "^1.34.0",
"@antv/x6-react-components": "^1.1.16",
"@antv/x6-react-shape": "^1.6.0",
"@antv/x6-vector": "^1.4.0",

View File

@ -0,0 +1,81 @@
import React from 'react'
import { Graph, EdgeView, NodeView } from '@antv/x6'
import { animateAlongEdge, animateAlongNode, clearAnimation } from './animation'
import '../index.less'
export default class Example extends React.Component {
private container: HTMLDivElement
private animate = false
componentDidMount() {
const graph = new Graph({
container: this.container,
width: 800,
height: 600,
grid: true,
})
const source = graph.addNode({
id: 'source',
shape: 'rect',
x: 80,
y: 250,
width: 160,
height: 60,
})
const target = graph.addNode({
id: 'target',
shape: 'rect',
x: 520,
y: 250,
width: 160,
height: 60,
})
graph.addEdge({
id: 'edge',
source,
target,
})
document.addEventListener('click', () => {
if (this.animate) {
this.animate = false
clearAnimation()
} else {
this.animate = true
this.play(graph)
}
})
}
play(graph: Graph) {
const sourceNodeView = graph.findViewByCell(
graph.getCellById('source'),
) as NodeView
const targetNodeView = graph.findViewByCell(
graph.getCellById('target'),
) as NodeView
const edgeView = graph.findViewByCell(graph.getCellById('edge')) as EdgeView
animateAlongNode(sourceNodeView, 'M 0 30 L 0 0 L 160 0 L 160 30')
animateAlongNode(sourceNodeView, 'M 0 30 L 0 60 L 160 60 L 160 30', () => {
animateAlongEdge(edgeView, () => {
animateAlongNode(targetNodeView, 'M 0 0 L 160 0 L 160 60 L 0 60')
})
})
}
refContainer = (container: HTMLDivElement) => {
this.container = container
}
render() {
return (
<div className="x6-graph-wrap">
<div ref={this.refContainer} className="x6-graph" />
</div>
)
}
}

View File

@ -0,0 +1,94 @@
import { Vector, EdgeView, NodeView, Dom } from '@antv/x6'
const animateToken: SVGElement[] = []
export const removeAnimationElem = (elem: SVGElement) => {
const index = animateToken.findIndex((token) => token === elem)
if (index) {
animateToken.splice(index, 1)
}
Dom.remove(elem)
}
export const animateAlongEdge = (
edgeView: EdgeView,
compelete?: () => void,
) => {
const token = Vector.create('circle', { r: 4, fill: 'red' })
const path = edgeView.container.querySelector('path')
const animate = Dom.createSvgElement<SVGAnimateMotionElement>('animateMotion')
const mpath = Dom.createSvgElement('mpath')
const attrs = {
dur: '1000ms',
repeatCount: '1',
calcMode: 'linear',
fill: 'freeze',
}
const id = Dom.ensureId(path!)
animate.appendChild(mpath)
token.node.appendChild(animate)
token.appendTo(edgeView.container)
Dom.attr(mpath, { 'xlink:href': `#${id}` })
Dom.attr(animate, attrs)
animateToken.push(token.node)
animate.addEventListener('endEvent', () => {
removeAnimationElem(token.node)
if (compelete) {
compelete()
}
})
const ani = animate as any
setTimeout(() => {
ani.beginElement()
})
}
export const animateAlongNode = (
nodeView: NodeView,
path: string,
compelete?: () => void,
) => {
const token = Vector.create('circle', { r: 4, fill: 'red' })
const animate = Dom.createSvgElement<SVGAnimateMotionElement>('animateMotion')
const attrs = {
dur: '2000ms',
repeatCount: '1',
calcMode: 'linear',
fill: 'freeze',
}
Dom.attr(animate, {
...attrs,
path,
})
token.append(animate)
nodeView.container.appendChild(token.node)
animateToken.push(token.node)
animate.addEventListener('endEvent', () => {
removeAnimationElem(token.node)
if (compelete) {
compelete()
}
})
const ani = animate as any
setTimeout(() => {
ani.beginElement()
})
}
export const clearAnimation = () => {
const animations = [...animateToken]
animations.forEach((item) => {
removeAnimationElem(item)
})
}

View File

@ -327,6 +327,7 @@ export default class Example extends React.Component {
container: this.container,
width: 800,
height: 600,
snapline: true,
panning: {
enabled: true,
eventTypes: ['leftMouseDown', 'mouseWheel'],

View File

@ -1,21 +1,16 @@
import React from 'react'
import React, { memo, useEffect, useRef, useState } from 'react'
import { Graph, Node, Color } from '@antv/x6'
import { Portal } from '@antv/x6-react-shape'
import { Portal, ReactShape } from '@antv/x6-react-shape'
import '../index.less'
class MyComponent extends React.Component<{ node?: Node; text: string }> {
shouldComponentUpdate() {
const node = this.props.node
if (node) {
if (node.hasChanged('data')) {
return true
}
}
// You should do this outside your components
// (or make sure its not recreated on every render).
//
// 这个调用需要在组件外进行。
const X6ReactPortalProvider = Portal.getProvider()
return false
}
render() {
const MyComponent = memo(
({ node, text }: { node?: ReactShape; text: string }) => {
const color = Color.randomHex()
return (
<div
@ -28,18 +23,25 @@ class MyComponent extends React.Component<{ node?: Node; text: string }> {
background: color,
}}
>
{this.props.text}
{text}
</div>
)
}
}
},
(prev, next) => {
return Boolean(next.node?.hasChanged('data'))
},
)
export default class Example extends React.Component {
private container: HTMLDivElement
export default () => {
const container = useRef<HTMLDivElement>(null)
useEffect(() => {
if (!container.current) {
return
}
componentDidMount() {
const graph = new Graph({
container: this.container,
container: container.current,
width: 800,
height: 600,
})
@ -61,7 +63,7 @@ export default class Example extends React.Component {
y: 320,
width: 160,
height: 60,
component: (node) => {
component: (node: Node) => {
return <div>{node.attr('body/fill')}</div>
},
// component: () => <Test text="target" />,
@ -80,19 +82,18 @@ export default class Example extends React.Component {
update()
console.log(graph.toJSON())
}
return () => graph.dispose()
}, [])
refContainer = (container: HTMLDivElement) => {
this.container = container
}
const [counter, setCounter] = useState(0)
render() {
const X6ReactPortalProvider = Portal.getProvider()
return (
<div className="x6-graph-wrap">
<X6ReactPortalProvider />
<div ref={this.refContainer} className="x6-graph" />
</div>
)
}
return (
<div className="x6-graph-wrap">
<button onClick={() => setCounter((i) => i + 1)}>
Counter: {counter}
</button>
<X6ReactPortalProvider />
<div ref={container} className="x6-graph" />
</div>
)
}

View File

@ -1,6 +1,8 @@
import React from 'react'
import { Button } from 'antd'
import React from 'react'
import { Graph } from '@antv/x6'
import '../index.less'
export default class Example extends React.Component<
@ -22,10 +24,13 @@ export default class Example extends React.Component<
height: 600,
grid: true,
history: true,
embedding: {
enabled: true,
},
})
this.history = graph.history
this.history.on('change', () => {
this.history.on('change', (info) => {
this.setState({
canRedo: this.history.canRedo(),
canUndo: this.history.canUndo(),
@ -62,6 +67,21 @@ export default class Example extends React.Component<
},
})
graph.addNode({
x: 400,
y: 100,
width: 150,
height: 150,
attrs: {
label: {
text: '🌎',
},
body: {
strokeWidth: 1,
},
},
})
graph.addEdge({ source, target, arrts: { line: { strokeWidth: 1 } } })
}

View File

@ -1,3 +0,0 @@
import { version } from '@antv/x6-vector'
console.log(version)

View File

@ -26,7 +26,8 @@
"package:check": "yarn package-inherit check",
"package:inherit": "yarn package-inherit update",
"prepare": "is-ci || husky install configs/husky-config",
"precommit": "yarn lint-staged && lerna run --concurrency 1 --stream precommit"
"precommit": "yarn lint-staged && lerna run --concurrency 1 --stream precommit",
"publish:latest": "lerna publish from-package --no-private --ignore-scripts --dist-tag v1"
},
"lint-staged": {
"**/*.{js,jsx,tsx,ts,less,md,json}": [

View File

@ -1,6 +1,6 @@
{
"name": "@antv/x6-angular-shape",
"version": "1.3.1",
"version": "1.3.2",
"description": "X6 shape for rendering angular components.",
"main": "lib/index.js",
"module": "es/index.js",
@ -49,7 +49,7 @@
"@angular/cdk": ">=10.2.3",
"@angular/common": "^10.2.3",
"@angular/core": ">=10.2.3",
"@antv/x6": ">=1.0.0"
"@antv/x6": "^1.x"
},
"devDependencies": {
"@angular/cdk": "^10.2.3",

View File

@ -1,5 +1,5 @@
{
"version": "1.0.12",
"version": "1.0.14",
"name": "@antv/x6-geometry",
"description": "Some useful geometry operations.",
"main": "lib/index.js",
@ -26,17 +26,16 @@
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
"build:cjs": "tsc --module commonjs --target es5 --outDir ./lib",
"build:umd": "rollup -c",
"build:version": "node ../../scripts/version.js",
"build:watch": "yarn build:esm --w",
"build:watch:esm": "yarn build:esm --w",
"build:watch:cjs": "yarn build:cjs --w",
"build:dev": "run-p build:cjs build:esm",
"build": "run-p build:version build:dev build:umd",
"build": "run-p build:dev build:umd",
"prebuild": "run-s lint clean",
"test": "jest",
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
"pretest": "run-p clean:coverage",
"prepare": "run-s build:version test build",
"prepare": "run-s test build",
"precommit": "lint-staged"
},
"lint-staged": {

View File

@ -1,4 +1,3 @@
export * from './version'
export * from './angle'
export * from './point'
export * from './line'

View File

@ -1,9 +0,0 @@
import { version } from './version'
describe('version', () => {
it('should match the `version` field of package.json', () => {
// eslint-disable-next-line
const expected = require('../package.json').version
expect(version).toBe(expected)
})
})

View File

@ -1,7 +0,0 @@
/* eslint-disable */
/**
* Auto generated version file, do not modify it!
*/
const version = '1.0.12'
export { version }

View File

@ -1,6 +1,6 @@
{
"name": "@antv/x6-react-components",
"version": "1.1.16",
"version": "1.1.20",
"description": "React components for building x6 editors",
"main": "lib/index.js",
"module": "es/index.js",
@ -61,7 +61,7 @@
"@antv/x6-package-json/rollup.json"
],
"peerDependencies": {
"antd": ">=4.4.2",
"antd": ">=4.4.2 || >=5.0.0-beta.0",
"react": ">=16.8.6 || >=17.0.0",
"react-dom": ">=16.8.6 || >=17.0.0"
},
@ -71,7 +71,7 @@
"rc-dropdown": "^3.0.0-alpha.0",
"rc-util": "^4.15.7",
"react-color": "2.17.1",
"react-resize-detector": "^6.6.4",
"react-resize-detector": "^7.0.0",
"ua-parser-js": "^0.7.20"
},
"devDependencies": {

View File

@ -5,7 +5,6 @@ import React from 'react'
import classNames from 'classnames'
import { Popover } from 'antd'
import { PopoverProps } from 'antd/es/popover'
import 'antd/es/popover/style/index.css'
import addEventListener from 'rc-util/lib/Dom/addEventListener'
import {
SketchPicker,
@ -101,11 +100,15 @@ export class ColorPicker extends React.Component<
const { color } = this.state
const { disabled, overlayProps, style } = this.props
const baseCls = `${this.props.prefixCls}-color-picker`
const popoverProps: PopoverProps = {}
const popoverProps: PopoverProps & { open?: boolean } = {}
if (disabled) {
popoverProps.visible = false
// Support for antd 5.0
popoverProps.open = false
} else {
popoverProps.visible = this.state.active
// Support for antd 5.0
popoverProps.open = this.state.active
}
const colorStr =

View File

@ -2,7 +2,6 @@ import React from 'react'
import classNames from 'classnames'
import { Tooltip } from 'antd'
import { TooltipProps } from 'antd/es/tooltip'
import 'antd/es/tooltip/style/index.css'
import { Menu } from '../menu'
import { Dropdown } from '../dropdown'
import { ToolbarContext } from './context'

View File

@ -1,6 +1,6 @@
{
"name": "@antv/x6-react-shape",
"version": "1.6.1",
"version": "1.6.6",
"description": "X6 shape for rendering react components.",
"main": "lib/index.js",
"module": "es/index.js",
@ -31,9 +31,8 @@
"build:watch:esm": "yarn build:esm --w",
"build:watch:cjs": "yarn build:cjs --w",
"build": "run-p build:cjs build:esm build:umd",
"prebuild": "run-s lint clean",
"prepare": "yarn build",
"precommit": "lint-staged"
"prebuild": "run-s clean",
"prepare": "yarn build"
},
"lint-staged": {
"src/**/*.ts": [
@ -47,7 +46,7 @@
"@antv/x6-package-json/rollup.json"
],
"peerDependencies": {
"@antv/x6": ">=1.0.0",
"@antv/x6": "^1.x",
"react": ">=16.8.6 || >=17.0.0",
"react-dom": ">=16.8.6 || >=17.0.0"
},

View File

@ -6,17 +6,24 @@ import { Portal } from './portal'
import { Wrap } from './wrap'
export class ReactShapeView extends NodeView<ReactShape> {
protected targetId() {
return `${this.graph.view.cid}:${this.cell.id}`
}
protected init() {
super.init()
this.cell.on('removed', () => {
Portal.disconnect(this.cell.id)
Portal.disconnect(this.targetId())
})
}
getComponentContainer() {
return this.cell.prop('useForeignObject') === false
? (this.selectors.content as SVGElement)
: (this.selectors.foContent as HTMLDivElement)
return (
this.selectors &&
(this.cell.prop('useForeignObject') === false
? (this.selectors.content as SVGElement)
: (this.selectors.foContent as HTMLDivElement))
)
}
confirmUpdate(flag: number) {
@ -42,7 +49,7 @@ export class ReactShapeView extends NodeView<ReactShape> {
const component = this.graph.hook.getReactComponent(node)
const elem = React.createElement(Wrap, { graph, node, component })
if (Portal.isActive()) {
Portal.connect(this.cell.id, ReactDOM.createPortal(elem, root))
Portal.connect(this.targetId(), ReactDOM.createPortal(elem, root))
} else {
ReactDOM.render(elem, root)
}
@ -57,32 +64,8 @@ export class ReactShapeView extends NodeView<ReactShape> {
return root
}
onMouseDown(e: JQuery.MouseDownEvent, x: number, y: number) {
const target = e.target as Element
const tagName = target.tagName.toLowerCase()
if (tagName === 'input') {
const type = target.getAttribute('type')
if (
type == null ||
[
'text',
'password',
'number',
'email',
'search',
'tel',
'url',
].includes(type)
) {
return
}
}
super.onMouseDown(e, x, y)
}
unmount() {
Portal.disconnect(this.cell.id)
Portal.disconnect(this.targetId())
this.unmountReactComponent()
super.unmount()
return this

View File

@ -1,5 +1,5 @@
{
"version": "1.4.0",
"version": "1.4.2",
"name": "@antv/x6-vector",
"description": "Lightweight library for manipulating and animating SVG.",
"main": "lib/index.js",
@ -26,20 +26,19 @@
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
"build:cjs": "tsc --module commonjs --target es5 --outDir ./lib",
"build:umd": "rollup -c",
"build:version": "node ../../scripts/version.js",
"build:csstype": "node ./scripts/csstype.js",
"build:watch": "yarn build:esm --w",
"build:watch:esm": "yarn build:esm --w",
"build:watch:cjs": "yarn build:cjs --w",
"build:dev": "run-p build:csstype build:cjs build:esm",
"build": "run-p build:version build:dev build:umd",
"build": "run-p build:dev build:umd",
"prebuild": "run-s lint clean",
"test": "karma start",
"test:watch": "karma start --single-run=false --auto-watch",
"test:debug": "karma start --browsers=Chrome --single-run=false --auto-watch --debug",
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
"pretest": "run-p clean:coverage",
"prepare": "run-s build:version test build",
"prepare": "run-s test build",
"precommit": "lint-staged"
},
"lint-staged": {

View File

@ -1,9 +0,0 @@
import { version } from './version'
describe('version', () => {
it('should match the `version` field of package.json', () => {
// eslint-disable-next-line
const expected = require('../../package.json').version
expect(version).toBe(expected)
})
})

View File

@ -1,7 +0,0 @@
/* eslint-disable */
/**
* Auto generated version file, do not modify it!
*/
const version = '1.4.0'
export { version }

View File

@ -1,3 +1,2 @@
export * from './global/version'
export * from './dom'
export * from './vector'

View File

@ -26,17 +26,7 @@ graph.addNode({
y: 48,
width: 180,
height: 40,
component: {
template: `<hello-world :name="name"></hello-world>`,
data() {
return {
name: 'x6',
}
},
components: {
HelloWorld,
}
},
component: HelloWorld,
})
```

View File

@ -1,6 +1,6 @@
{
"name": "@antv/x6-vue-shape",
"version": "1.4.2",
"version": "1.5.4",
"description": "X6 shape for rendering vue components.",
"main": "lib/index.js",
"module": "es/index.js",
@ -31,23 +31,7 @@
"build": "run-p build:cjs build:esm build:umd",
"prebuild": "run-s lint clean",
"prepare": "yarn build",
"precommit": "lint-staged",
"release": "release-it"
},
"release-it": {
"git": {
"tagName": "@antv/x6-vue-shape@${version}",
"commitMessage": "chore: release ${name}@${version}",
"requireCleanWorkingDir": false
},
"github": {
"release": true
},
"hooks": {
"before:init": [
"yarn run build"
]
}
"precommit": "lint-staged"
},
"lint-staged": {
"src/**/*.ts": [
@ -64,7 +48,7 @@
"vue-demi": "latest"
},
"peerDependencies": {
"@antv/x6": ">=1.0.0",
"@antv/x6": "^1.x",
"@vue/composition-api": "^1.0.0-rc.6",
"vue": "^2.6.12 || ^3.0.0"
},

View File

@ -1,14 +1,9 @@
import { Graph, Node, Registry } from '@antv/x6'
import { ComponentInstance } from 'vue-demi'
export type VueComponent = {
template: string
data?: { [key: string]: any }
components?: { [key: string]: any }
computed?: { [key: string]: any }
methods?: { [key: string]: any }
}
export declare type VueComponent = ComponentInstance
export type Definition =
export declare type Definition =
| VueComponent
| ((this: Graph, node: Node) => VueComponent)

View File

@ -1,5 +1,5 @@
import { defineComponent, h, reactive, isVue3, Vue } from 'vue-demi'
import { Graph, NodeView } from '@antv/x6'
import { Graph, NodeView, Scheduler } from '@antv/x6'
import { VueShape } from './node'
import { VueShapeView } from './view'
@ -28,12 +28,16 @@ export function useTeleport(uniqViewId: string) {
component: any,
getContainer: () => HTMLDivElement,
) => {
if (items[id]) {
// confirmUpdate可能导致多次调用所以判断一下
return
}
items[id] = markRaw(
defineComponent({
render: () =>
(getContainer()
? h(Teleport, { to: getContainer() } as typeof VNodeData, [
h(component),
h(component, { graph, node } as any),
])
: null) as typeof VNode,
provide: () => ({
@ -48,12 +52,19 @@ export function useTeleport(uniqViewId: string) {
}
class VuePortalShapeView extends NodeView<VueShape> {
getTargetId() {
return `${this.graph.view.cid}:${this.cell.id}`
}
init() {
super.init()
const targetId = `${this.graph.view.cid}:${this.cell.id}`
const targetId = this.getTargetId()
this.cell.on('removed', () => {
disconnect(targetId)
})
this.renderVueComponent()
}
renderVueComponent() {
const targetId = this.getTargetId()
const component = this.graph.hook.getVueComponent(this.cell)
// 这里需要将当前View的cell以及graph还有component等对象存储起来给TeleportContainer使用
connect(
@ -72,9 +83,19 @@ export function useTeleport(uniqViewId: string) {
confirmUpdate(flag: any) {
const ret = super.confirmUpdate(flag)
return this.handleAction(ret, action, () => {
// 这里无需做任何处理,但是,没有这个函数的时候,会卡死...
// 参照VueShapeView进行渲染修复 #2505
Scheduler.scheduleTask(() => {
this.renderVueComponent()
})
})
}
unmount(elem: Element) {
// 基类调用removeView的时候会自动调用unmount
const targetId = this.getTargetId()
disconnect(targetId)
super.unmount(elem)
return this
}
}
VuePortalShapeView.config({
bootstrap: [action],

View File

@ -1,7 +1,6 @@
import { NodeView, Scheduler } from '@antv/x6'
import { isVue2, isVue3, createApp, h, Vue2 } from 'vue-demi'
import { VueShape } from './node'
import { VueComponent } from './registry'
export class VueShapeView extends NodeView<VueShape> {
private vm: any
@ -33,31 +32,28 @@ export class VueShapeView extends NodeView<VueShape> {
const component = this.graph.hook.getVueComponent(node)
if (isVue2) {
const Vue = Vue2 as any
const div = document.createElement('div')
div.style.width = '100%'
div.style.height = '100%'
if (typeof component === 'string') {
div.innerHTML = component
this.vm = new Vue({ el: div })
this.vm = new Vue({ template: component })
} else {
const { template, ...other } = component as VueComponent
div.innerHTML = template
this.vm = new Vue({
el: div,
render() {
// 保留之前的provide增加传递graph和node
return h(component as any, { graph, node } as any)
},
provide() {
return {
getGraph: () => graph,
getNode: () => node,
}
},
...other,
})
}
root.appendChild(this.vm.$el)
this.vm.$mount(root)
} else if (isVue3) {
this.vm = createApp({
render() {
return h(component as any)
// 保留之前的provide增加传递graph和node
return h(component as any, { graph, node } as any)
},
provide() {
return {

View File

@ -121,7 +121,7 @@ graph.addEdge({
- [基础教程](https://x6.antv.vision/zh/docs/tutorial/basic/graph)
- [进阶实践](https://x6.antv.vision/zh/docs/tutorial/intermediate/serialization)
- [高级指引](https://x6.antv.vision/zh/docs/tutorial/advanced/animation)
- [更新日志](https://x6.antv.vision/zh/docs/tutorial/log)
- [更新日志](https://www.yuque.com/antv/x6/xgb04i)
## 应用案例
@ -165,9 +165,7 @@ graph.addEdge({
需要注意的是,提问题时请配上 [CodeSandbox](https://codesandbox.io/s/pensive-sound-f4nhc) 的复现代码,方便快速定位和解决问题。
<a href="https://qr.dingtalk.com/action/joingroup?code=v1,k1,rOHuvgq5s0EHDktyyQJffDE3ZAmHnbB2e6iwn/w4BKs=&_dt_no_comment=1&origin=11" target="_blank" rel="noopener noreferrer">
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*Up-4S4v8H-0AAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群1" width="260" />
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*4Y_5S7i26LAAAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群2" width="260" />
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*KHB4QJAsW4QAAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群3" width="260" />
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*nFa5TaWsSOoAAAAAAAAAAAAAARQnAQ" alt="X6 图可视化交流群4" width="260" />
</a>
## 如何开发

View File

@ -1,6 +1,6 @@
{
"name": "@antv/x6",
"version": "1.33.0",
"version": "1.35.0",
"description": "JavaScript diagramming library that uses SVG and HTML for rendering.",
"main": "lib/index.js",
"module": "es/index.js",
@ -36,20 +36,18 @@
"build:umd": "rollup -c",
"build:less": "node ./scripts/style",
"build:readme": "node ./scripts/readme.js",
"build:version": "node ../../scripts/version.js",
"build:csstype": "node ./scripts/csstype.js",
"build:dev": "run-p build:csstype build:less build:cjs build:esm",
"build:watch": "yarn build:esm --w",
"build:watch:esm": "yarn build:esm --w",
"build:watch:cjs": "yarn build:cjs --w",
"build": "run-p build:readme build:version build:dev build:umd",
"build": "run-p build:readme build:dev build:umd",
"prebuild": "run-s lint clean",
"test": "karma start",
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
"pretest": "run-p clean:coverage",
"prepare": "run-s build:version test build",
"precommit": "lint-staged",
"release": "release-it"
"prepare": "run-s test build",
"precommit": "lint-staged"
},
"lint-staged": {
"src/**/*.less": [
@ -59,20 +57,6 @@
"eslint --fix"
]
},
"release-it": {
"git": {
"tagName": "@antv/x6@${version}",
"commitMessage": "chore: release ${name}@${version}"
},
"github": {
"release": true
},
"hooks": {
"before:init": [
"yarn run build"
]
}
},
"inherits": [
"@antv/x6-package-json/cli.json",
"@antv/x6-package-json/less.json",

View File

@ -73,7 +73,7 @@ export class Dnd extends View {
this.targetModel.startBatch('dnd')
this.$container
.addClass('dragging')
.appendTo(this.options.containerParent || document.body)
.appendTo(this.options.draggingContainer || document.body)
this.sourceNode = node
this.prepareDragging(node, e.clientX, e.clientY)
@ -338,9 +338,15 @@ export class Dnd extends View {
protected isInsideValidArea(p: Point.PointLike) {
let targetRect: Rectangle
let dndRect: Rectangle | null = null
const targetGraph = this.targetGraph
const targetScroller = this.targetScroller
if (this.options.dndContainer) {
dndRect = this.getDropArea(this.options.dndContainer)
}
const isInsideDndRect = dndRect && dndRect.containsPoint(p)
if (targetScroller) {
if (targetScroller.options.autoResize) {
targetRect = this.getDropArea(targetScroller.container)
@ -354,7 +360,7 @@ export class Dnd extends View {
targetRect = this.getDropArea(targetGraph.container)
}
return targetRect && targetRect.containsPoint(p)
return !isInsideDndRect && targetRect && targetRect.containsPoint(p)
}
protected getDropArea(elem: Element) {
@ -456,7 +462,11 @@ export namespace Dnd {
duration?: number
easing?: string
}
containerParent?: HTMLElement
draggingContainer?: HTMLElement
/**
* dnd tool box container.
*/
dndContainer?: HTMLElement
getDragNode: (sourceNode: Node, options: GetDragNodeOptions) => Node
getDropNode: (draggingNode: Node, options: GetDropNodeOptions) => Node
validateNode?: (

View File

@ -346,6 +346,11 @@ export class Scroller extends View {
const graphHeight = this.graph.options.height
const pageWidth = this.options.pageWidth! * this.sx
const pageHeight = this.options.pageHeight! * this.sy
if (pageWidth === 0 || pageHeight === 0) {
return
}
if (graphWidth > pageWidth || graphHeight > pageHeight) {
let hasPageBreak = false
const container = document.createElement('div')
@ -396,12 +401,76 @@ export class Scroller extends View {
gridWidth: this.options.pageWidth,
gridHeight: this.options.pageHeight,
allowNewOrigin: 'negative',
contentArea: this.calcContextArea(resizeOptions),
...resizeOptions,
}
this.graph.fitToContent(this.getFitToContentOptions(options))
}
protected calcContextArea(
resizeOptions:
| (TransformManager.FitToContentFullOptions & {
direction?:
| Scroller.AutoResizeDirection
| Scroller.AutoResizeDirection[]
})
| undefined,
) {
const direction = resizeOptions?.direction
if (!direction) {
return this.graph.transform.getContentArea(resizeOptions)
}
function getCellBBox(cell: Cell) {
let rect = cell.getBBox()
if (rect) {
if (cell.isNode()) {
const angle = cell.getAngle()
if (angle != null && angle !== 0) {
rect = rect.bbox(angle)
}
}
}
return rect
}
const gridWidth = this.options.pageWidth || 1
const gridHeight = this.options.pageHeight || 1
let calculativeCells = this.graph.getCells()
if (!direction.includes('top')) {
calculativeCells = calculativeCells.filter((cell) => {
const bbox = getCellBBox(cell)
return bbox.y >= 0
})
}
if (!direction.includes('left')) {
calculativeCells = calculativeCells.filter((cell) => {
const bbox = getCellBBox(cell)
return bbox.x >= 0
})
}
if (!direction.includes('right')) {
calculativeCells = calculativeCells.filter((cell) => {
const bbox = getCellBBox(cell)
return bbox.x + bbox.width <= gridWidth
})
}
if (!direction.includes('bottom')) {
calculativeCells = calculativeCells.filter((cell) => {
const bbox = getCellBBox(cell)
return bbox.y + bbox.height <= gridHeight
})
}
return this.model.getCellsBBox(calculativeCells) || new Rectangle()
}
protected getFitToContentOptions(
options: TransformManager.FitToContentFullOptions,
) {
@ -1201,17 +1270,25 @@ export namespace Scroller {
* @deprecated
*/
fitTocontentOptions?:
| TransformManager.FitToContentFullOptions
| (TransformManager.FitToContentFullOptions & {
direction?: AutoResizeDirection | AutoResizeDirection[]
})
| ((
this: Scroller,
scroller: Scroller,
) => TransformManager.FitToContentFullOptions)
) => TransformManager.FitToContentFullOptions & {
direction?: AutoResizeDirection | AutoResizeDirection[]
})
autoResizeOptions?:
| TransformManager.FitToContentFullOptions
| (TransformManager.FitToContentFullOptions & {
direction?: AutoResizeDirection | AutoResizeDirection[]
})
| ((
this: Scroller,
scroller: Scroller,
) => TransformManager.FitToContentFullOptions)
) => TransformManager.FitToContentFullOptions & {
direction?: AutoResizeDirection | AutoResizeDirection[]
})
}
export interface Options extends CommonOptions {
@ -1258,6 +1335,8 @@ export namespace Scroller {
visibility?: number
center?: Point.PointLike
}
export type AutoResizeDirection = 'top' | 'right' | 'bottom' | 'left'
}
export namespace Scroller {

View File

@ -125,23 +125,16 @@ export class Selection extends View<Selection.EventArgs> {
options,
}: Collection.EventArgs['node:change:position']) {
const { showNodeSelectionBox, pointerEvents } = this.options
const { ui, selection, translateBy } = options
let allowTranslating = !this.translating
const { ui, selection, translateBy, snapped } = options
/* Scenarios where this method is not called:
* 1. ShowNodeSelection is true or ponterEvents is none
* 2. Avoid circular calls with the selection tag
*/
allowTranslating =
allowTranslating &&
(showNodeSelectionBox !== true || pointerEvents === 'none')
allowTranslating = allowTranslating && ui && !selection
const allowTranslating =
(showNodeSelectionBox !== true || pointerEvents === 'none') &&
!this.translating &&
!selection
// Avoid circular calls of child nodes
allowTranslating =
allowTranslating && translateBy && node.id === translateBy
const translateByUi = ui && translateBy && node.id === translateBy
if (allowTranslating) {
if (allowTranslating && (translateByUi || snapped)) {
this.translating = true
const current = node.position()
const previous = node.previous('position')!
@ -293,6 +286,7 @@ export class Selection extends View<Selection.EventArgs> {
offsetY: y,
scrollerX: 0,
scrollerY: 0,
moving: false,
})
this.delegateDocumentEvents(Private.documentEvents, evt.data)

View File

@ -84,8 +84,8 @@ export class Snapline extends View implements IDisablable {
protected render() {
const container = (this.containerWrapper = new Vector('svg'))
const horizontal = (this.horizontal = new Vector('path'))
const vertical = (this.vertical = new Vector('path'))
const horizontal = (this.horizontal = new Vector('line'))
const vertical = (this.vertical = new Vector('line'))
container.addClass(this.containerClassName)
horizontal.addClass(this.horizontalClassName)
@ -586,7 +586,10 @@ export class Snapline extends View implements IDisablable {
),
)
this.horizontal.setAttributes({
d: `M ${start.x},${start.y} L ${end.x},${end.y}`,
x1: this.options.sharp ? `${start.x}` : '0',
y1: `${start.y}`,
x2: this.options.sharp ? `${end.x}` : '100%',
y2: `${end.y}`,
display: 'inherit',
})
} else {
@ -604,7 +607,10 @@ export class Snapline extends View implements IDisablable {
),
)
this.vertical.setAttributes({
d: `M ${start.x},${start.y} L ${end.x},${end.y}`,
x1: `${start.x}`,
y1: this.options.sharp ? `${start.y}` : '0',
x2: `${end.x}`,
y2: this.options.sharp ? `${end.y}` : '100%',
display: 'inherit',
})
} else {
@ -661,14 +667,6 @@ export namespace Snapline {
enabled?: boolean
className?: string
tolerance?: number
/**
* @deprecated The default behavior is now to clamp snaplines to the elements
* that are being aligned (instead of them spanning the entire graph),
* equivalent to `sharp: true`. The `sharp` option will be removed in a future release.
*
* @deprecated 对齐线将默认在对齐的元素边界截断,而不是跨越整个图的横轴/纵轴;相当于 `sharp: true`.
* `sharp` 选项将在之后的版本中去除。
*/
sharp?: boolean
/**
* Specify if snap on node resizing or not.

View File

@ -521,6 +521,11 @@ export class Transform extends Widget<Transform.Options> {
}
}
}
protected onRemove() {
this.stopListening()
super.onRemove()
}
}
export namespace Transform {

View File

@ -45,7 +45,7 @@ export class PriorityQueue<T> {
*/
insert(priority: number, value: T, id?: string) {
const item: PriorityQueue.DataItem<T> = { priority, value }
const index = this.data.length - 1
const index = this.data.length
if (id) {
item.id = id
this.index[id] = index
@ -96,7 +96,9 @@ export class PriorityQueue<T> {
const data = this.data
const peek = data[0]
const last = data.pop()!
delete this.index[data.length]
if (peek.id) {
delete this.index[peek.id]
}
if (data.length > 0) {
data[0] = last

View File

@ -1,3 +1,2 @@
export * from './util'
export * from './config'
export * from './version'

View File

@ -1,23 +0,0 @@
import { Config } from './config'
import { version } from './version'
function track() {
if (Config.trackable) {
const host = 'https://kcart.alipay.com/web/bi.do'
const img = new Image()
const metadata = {
...Config.trackInfo,
version,
pg: document.URL,
r: new Date().getTime(),
x6: true,
page_type: 'syslog',
}
const data = encodeURIComponent(JSON.stringify([metadata]))
img.src = `${host}?BIProfile=merge&d=${data}`
}
}
if (process.env.NODE_ENV !== 'development' && Config.trackable) {
setTimeout(track, 3000)
}

View File

@ -1,9 +0,0 @@
import { version } from './version'
describe('version', () => {
it('should match the `version` field of package.json', () => {
// eslint-disable-next-line
const expected = require('../../package.json').version
expect(version).toBe(expected)
})
})

View File

@ -1,7 +0,0 @@
/* eslint-disable */
/**
* Auto generated version file, do not modify it!
*/
const version = '1.32.11'
export { version }

View File

@ -204,7 +204,7 @@ export class HistoryManager
(Util.isAddEvent(event) && revert) ||
(Util.isRemoveEvent(event) && !revert)
) {
cell.remove(options)
cell && cell.remove(options)
} else if (
(Util.isAddEvent(event) && !revert) ||
(Util.isRemoveEvent(event) && revert)
@ -218,7 +218,7 @@ export class HistoryManager
} else if (Util.isChangeEvent(event)) {
const data = cmd.data as HistoryManager.ChangingData
const key = data.key
if (key) {
if (key && cell) {
const value = revert ? data.prev[key] : data.next[key]
cell.prop(key, value, options)
}
@ -398,6 +398,7 @@ export class HistoryManager
if (cmds.length > 0) {
this.redoStack = []
this.undoStack.push(cmds)
this.consolidateCommands()
this.notify('add', cmds, options)
}
this.batchCommands = null
@ -469,9 +470,66 @@ export class HistoryManager
this.emit('batch', { cmd, options })
} else {
this.undoStack.push(cmd)
this.consolidateCommands()
this.notify('add', cmd, options)
}
}
/**
* Conditionally combine multiple undo items into one.
*
* Currently this is only used combine a `cell:changed:position` event
* followed by multiple `cell:change:parent` and `cell:change:children`
* events, such that a "move + embed" action can be undone in one step.
*
* See https://github.com/antvis/X6/issues/2421
*
* This is an ugly WORKAROUND. It does not solve deficiencies in the batch
* system itself.
*/
private consolidateCommands() {
const lastCommandGroup = this.undoStack[this.undoStack.length - 1]
const penultimateCommandGroup = this.undoStack[this.undoStack.length - 2]
// We are looking for at least one cell:change:parent
// and one cell:change:children
if (!Array.isArray(lastCommandGroup)) {
return
}
const eventTypes = new Set(lastCommandGroup.map((cmd) => cmd.event))
if (
eventTypes.size !== 2 ||
!eventTypes.has('cell:change:parent') ||
!eventTypes.has('cell:change:children')
) {
return
}
// We are looking for events from user interactions
if (!lastCommandGroup.every((cmd) => cmd.batch && cmd.options?.ui)) {
return
}
// We are looking for a command group with exactly one event, whose event
// type is cell:change:position, and is from user interactions
if (
!Array.isArray(penultimateCommandGroup) ||
penultimateCommandGroup.length !== 1
) {
return
}
const maybePositionChange = penultimateCommandGroup[0]
if (
maybePositionChange.event !== 'cell:change:position' ||
!maybePositionChange.options?.ui
) {
return
}
// Actually consolidating the commands we get
penultimateCommandGroup.push(...lastCommandGroup)
this.undoStack.pop()
}
}
export namespace HistoryManager {

View File

@ -124,7 +124,7 @@ export class Keyboard extends Disposable implements IDisablable {
isInputEvent(e: KeyboardEvent | JQuery.MouseUpEvent) {
const target = e.target as Element
const tagName = target && target.tagName.toLowerCase()
const tagName = target?.tagName?.toLowerCase()
return ['input', 'textarea'].includes(tagName)
}

View File

@ -163,7 +163,7 @@ export class Renderer extends Base {
this.processEdgeOnTerminalVisibleChanged(cell, true)
}
this.sortViews()
// this.sortViews()
}
protected processEdgeOnTerminalVisibleChanged(node: Cell, visible: boolean) {

View File

@ -218,7 +218,10 @@ export class GraphView extends View {
if (view) {
view.onMouseDown(e, localPoint.x, localPoint.y)
} else {
if (this.options.preventDefaultBlankAction) {
if (
this.options.preventDefaultBlankAction &&
['touchstart'].includes(e.type)
) {
e.preventDefault()
}

View File

@ -2,10 +2,6 @@ import { Shape } from './shape'
import * as Addon from './addon'
import * as Registry from './registry'
// start track
// -----------
import './global/track'
export * from './util'
export * from './common'
export * from './geometry'

View File

@ -76,11 +76,16 @@ export class ObstacleMap {
const excludeShapes = options.excludeShapes
const excType = shape ? excludeShapes.includes(shape) : false
const excTerminal = excludedTerminals.some((cell) => cell.id === node.id)
const excNode = options.excludeNodes.includes(node)
const excludedNode = options.excludeNodes.some((item) => {
if (typeof item === 'string') {
return node.id === item
}
return item === node
})
const excAncestor = excludedAncestors.includes(node.id)
const excHidden = options.excludeHiddenNodes && !node.isVisible()
const excluded =
excType || excTerminal || excNode || excAncestor || excHidden
excType || excTerminal || excludedNode || excAncestor || excHidden
if (!excluded) {
const bbox = node.getBBox().moveAndExpand(options.paddingBox)

View File

@ -49,7 +49,7 @@ export interface ResolvedOptions {
/**
* Should certain nodes not be considered as obstacles?
*/
excludeNodes: Node[]
excludeNodes: (Node | string)[]
/**
* Should certain hidden nodes not be considered as obstacles?

View File

@ -327,6 +327,8 @@ export const router: Router.Definition<ManhattanRouterOptions> = function (
// Cannot found the partial route.
if (partialRoute === null) {
// eslint-next-line
console.warn(`Unable to execute manhattan algorithm, use orth instead`)
return FunctionExt.call(
options.fallbackRouter,
this,

View File

@ -80,10 +80,12 @@ export class Button extends ToolsView.ToolItem<
let tangent
let position
let angle
if (NumberExt.isPercentage(distance)) {
tangent = view.getTangentAtRatio(parseFloat(distance) / 100)
const d = NumberExt.normalizePercentage(distance, 1)
if (d >= 0 && d <= 1) {
tangent = view.getTangentAtRatio(d)
} else {
tangent = view.getTangentAtLength(distance)
tangent = view.getTangentAtLength(d)
}
if (tangent) {

View File

@ -14,7 +14,7 @@ export class CellEditor extends ToolsView.ToolItem<
render() {
this.createElement()
this.update()
this.updateEditor()
this.autoFocus()
this.delegateDocumentEvents(this.options.documentEvents!)
@ -33,7 +33,7 @@ export class CellEditor extends ToolsView.ToolItem<
this.container.appendChild(this.editor)
}
update() {
updateEditor() {
const { graph, cell, editor } = this
const style = editor.style

View File

@ -77,7 +77,7 @@ export namespace HTML {
}
protected renderHTMLComponent() {
const container = this.selectors.foContent
const container = this.selectors && this.selectors.foContent
if (container) {
const $wrap = this.$(container).empty()
const component = this.graph.hook.getHTMLComponent(this.cell)

View File

@ -7,6 +7,7 @@
.@{x6-prefix}-graph {
position: relative;
outline: none;
touch-action: none;
&-background,
&-grid,

View File

@ -7,6 +7,7 @@
export const content = `.x6-graph {
position: relative;
outline: none;
touch-action: none;
}
.x6-graph-background,
.x6-graph-grid,

View File

@ -1,7 +1,7 @@
import { ns } from './elem'
import { kebabCase } from '../string/format'
const CASE_SENSITIVE_ATTR = [
export const CASE_SENSITIVE_ATTR = [
'viewBox',
'attributeName',
'attributeType',

View File

@ -224,3 +224,35 @@ export function isHTMLElement(elem: any): elem is HTMLElement {
)
}
}
export function clickable(elem: Element): boolean {
if (!elem || !isHTMLElement(elem)) {
return false
}
if (['a', 'button'].includes(tagName(elem))) {
return true
}
if (
elem.getAttribute('role') === 'button' ||
elem.getAttribute('type') === 'button'
) {
return true
}
return clickable(elem.parentNode as Element)
}
export function isInputElement(elem: any): boolean {
const elemTagName = tagName(elem)
if (elemTagName === 'input') {
const type = elem.getAttribute('type')
if (
type == null ||
['text', 'password', 'number', 'email', 'search', 'tel', 'url'].includes(
type,
)
) {
return true
}
}
return false
}

View File

@ -445,7 +445,11 @@ function setupAnimation(
repeat && animate.addEventListener('repeatEvent', repeat)
const ani = animate as any
ani.beginElement()
setTimeout(() => {
ani.beginElement()
})
return () => ani.endElement()
}

View File

@ -1,56 +1,70 @@
const ua = navigator.userAgent
/* eslint-disable no-underscore-dangle */
let _IS_MAC = false
let _IS_IOS = false
let _IS_WINDOWS = false
let _IS_IE = false
let _IS_IE11 = false
let _IS_EDGE = false
let _IS_NETSCAPE = false
let _IS_CHROME_APP = false
let _IS_CHROME = false
let _IS_OPERA = false
let _IS_FIREFOX = false
let _IS_SAFARI = false
let _SUPPORT_TOUCH = false
let _SUPPORT_POINTER = false
let _SUPPORT_PASSIVE = false
let _NO_FOREIGNOBJECT = false
export namespace Platform {
export const IS_MAC = navigator.appVersion.indexOf('Mac') > 0
export const IS_IOS = !!ua.match(/(iPad|iPhone|iPod)/g)
export const IS_WINDOWS = navigator.appVersion.indexOf('Win') > 0
if (typeof navigator === 'object') {
const ua = navigator.userAgent
_IS_MAC = ua.indexOf('Macintosh') >= 0
_IS_IOS = !!ua.match(/(iPad|iPhone|iPod)/g)
_IS_WINDOWS = ua.indexOf('Windows') >= 0
export const IS_IE = ua.indexOf('MSIE') >= 0
export const IS_IE11 = !!ua.match(/Trident\/7\./)
export const IS_EDGE = !!ua.match(/Edge\//)
_IS_IE = ua.indexOf('MSIE') >= 0
_IS_IE11 = !!ua.match(/Trident\/7\./)
_IS_EDGE = !!ua.match(/Edge\//)
/**
* A flag indicating whether the browser is Netscape (including Firefox).
*/
export const IS_NETSCAPE =
_IS_NETSCAPE =
ua.indexOf('Mozilla/') >= 0 &&
ua.indexOf('MSIE') < 0 &&
ua.indexOf('Edge/') < 0
/**
* A flag indicating whether the the this is running inside a Chrome App.
*/
export const IS_CHROME_APP =
(window as any).chrome != null &&
(window as any).chrome.app != null &&
(window as any).chrome.app.runtime != null
export const IS_CHROME = ua.indexOf('Chrome/') >= 0 && ua.indexOf('Edge/') < 0
export const IS_OPERA = ua.indexOf('Opera/') >= 0 || ua.indexOf('OPR/') >= 0
export const IS_FIREFOX = ua.indexOf('Firefox/') >= 0
export const IS_SAFARI =
_IS_CHROME = ua.indexOf('Chrome/') >= 0 && ua.indexOf('Edge/') < 0
_IS_OPERA = ua.indexOf('Opera/') >= 0 || ua.indexOf('OPR/') >= 0
_IS_FIREFOX = ua.indexOf('Firefox/') >= 0
_IS_SAFARI =
ua.indexOf('AppleWebKit/') >= 0 &&
ua.indexOf('Chrome/') < 0 &&
ua.indexOf('Edge/') < 0
/**
* A flag indicating whether this device supports touchstart/-move/-end
* events (Apple iOS, Android, Chromebook and Chrome Browser on touch-enabled
* devices).
*/
export const SUPPORT_TOUCH = 'ontouchstart' in document.documentElement
if (typeof document === 'object') {
_NO_FOREIGNOBJECT =
!document.createElementNS ||
`${document.createElementNS(
'http://www.w3.org/2000/svg',
'foreignObject',
)}` !== '[object SVGForeignObjectElement]' ||
ua.indexOf('Opera/') >= 0
}
}
/**
* A flag indicating whether this device supports Microsoft pointer events.
*/
export const SUPPORT_POINTER = (window as any).PointerEvent != null && !IS_MAC
if (typeof window === 'object') {
_IS_CHROME_APP =
(window as any).chrome != null &&
(window as any).chrome.app != null &&
(window as any).chrome.app.runtime != null
_SUPPORT_POINTER = (window as any).PointerEvent != null && !_IS_MAC
}
export let SUPPORT_PASSIVE = false // eslint-disable-line import/no-mutable-exports
if (typeof document === 'object') {
_SUPPORT_TOUCH = 'ontouchstart' in document.documentElement
try {
const options = Object.defineProperty({}, 'passive', {
get() {
SUPPORT_PASSIVE = true
_SUPPORT_PASSIVE = true
},
})
const div = document.createElement('div')
@ -60,18 +74,50 @@ export namespace Platform {
} catch (err) {
// pass
}
}
export namespace Platform {
export const IS_MAC = _IS_MAC
export const IS_IOS = _IS_IOS
export const IS_WINDOWS = _IS_WINDOWS
export const IS_IE = _IS_IE
export const IS_IE11 = _IS_IE11
export const IS_EDGE = _IS_EDGE
/**
* A flag indicating whether the browser is Netscape (including Firefox).
*/
export const IS_NETSCAPE = _IS_NETSCAPE
/**
* A flag indicating whether the the this is running inside a Chrome App.
*/
export const IS_CHROME_APP = _IS_CHROME_APP
export const IS_CHROME = _IS_CHROME
export const IS_OPERA = _IS_OPERA
export const IS_FIREFOX = _IS_FIREFOX
export const IS_SAFARI = _IS_SAFARI
/**
* A flag indicating whether this device supports touchstart/-move/-end
* events (Apple iOS, Android, Chromebook and Chrome Browser on touch-enabled
* devices).
*/
export const SUPPORT_TOUCH = _SUPPORT_TOUCH
/**
* A flag indicating whether this device supports Microsoft pointer events.
*/
export const SUPPORT_POINTER = _SUPPORT_POINTER
export const SUPPORT_PASSIVE = _SUPPORT_PASSIVE
/**
* A flag indicating whether foreignObject support is not available. This
* is the case for Opera, older SVG-based browsers and all versions of IE.
*/
export const NO_FOREIGNOBJECT =
!document.createElementNS ||
`${document.createElementNS(
'http://www.w3.org/2000/svg',
'foreignObject',
)}` !== '[object SVGForeignObjectElement]' ||
ua.indexOf('Opera/') >= 0
export const NO_FOREIGNOBJECT = _NO_FOREIGNOBJECT
export const SUPPORT_FOREIGNOBJECT = !NO_FOREIGNOBJECT
}

View File

@ -17,7 +17,7 @@ export namespace Scheduler {
const schedule = (cb: FlushTaskFn) => unit.push(cb) === 1 && postMessage()
const postMessage = (() => {
const cb = () => unit.splice(0, unit.length).forEach((c) => c())
const cb = () => unit.splice(0, unit.length)[0]?.()
if (typeof MessageChannel !== 'undefined') {
const { port1, port2 } = new MessageChannel()
port1.onmessage = cb

View File

@ -66,7 +66,7 @@ export class AttrManager {
if (normal == null) {
normal = {}
}
const normalName = AttrManager.CASE_SENSITIVE_ATTR.includes(name)
const normalName = Dom.CASE_SENSITIVE_ATTR.includes(name)
? name
: StringExt.kebabCase(name)
normal[normalName] = val as Attr.SimpleAttrValue
@ -584,7 +584,6 @@ export namespace AttrManager {
delay?: Attr.ComplexAttrs | undefined
}
export const CASE_SENSITIVE_ATTR = ['viewBox']
export const DELAY_ATTRS = [
'text',
'textWrap',

View File

@ -1153,15 +1153,18 @@ export class EdgeView<
for (let i = 0, ii = labels.length; i < ii; i += 1) {
const label = labels[i]
const labelNode = this.labelCache[i]
if (!labelNode) {
continue
}
const labelPosition = this.normalizeLabelPosition(
label.position as Edge.LabelPosition,
)
const pos = ObjectExt.merge({}, defaultPosition, labelPosition)
const matrix = this.getLabelTransformationMatrix(pos)
this.labelCache[i].setAttribute(
'transform',
Dom.matrixToTransformString(matrix),
)
labelNode.setAttribute('transform', Dom.matrixToTransformString(matrix))
}
return this

View File

@ -612,6 +612,13 @@ export class NodeView<
}
notifyMouseUp(e: JQuery.MouseUpEvent, x: number, y: number) {
// Problem: super will call stopBatch before event listeners
// attached to this **node** run. Those events will not count
// towards this batch, despite being triggered by the same UI event.
//
// This complicates a lot of stuff e.g. history recording.
//
// See https://github.com/antvis/X6/issues/2421 for background.
super.onMouseUp(e, x, y)
this.notify('node:mouseup', this.getEventArgs(e, x, y))
}
@ -635,6 +642,12 @@ export class NodeView<
if (this.isPropagationStopped(e)) {
return
}
// 避免处于foreignObject内部元素触发onMouseDown导致节点被拖拽
// 拖拽的时候是以onMouseDown启动的
const target = e.target as Element
if (Dom.clickable(target) || Dom.isInputElement(target)) {
return
}
this.notifyMouseDown(e, x, y)
this.startNodeDragging(e, x, y)
}
@ -670,6 +683,12 @@ export class NodeView<
if (action === 'magnet') {
this.stopMagnetDragging(e, x, y)
} else {
// 避免处于foreignObject内部元素触发onMouseUp导致节点被选中
// 选中的时候是以onMouseUp启动的
const target = e.target as Element
if (Dom.clickable(target) || Dom.isInputElement(target)) {
return
}
this.notifyMouseUp(e, x, y)
if (action === 'move') {
const meta = data as EventData.Moving
@ -842,7 +861,9 @@ export class NodeView<
if (options.frontOnly) {
if (candidates.length > 0) {
const zIndexMap = ArrayExt.groupBy(candidates, 'zIndex')
const maxZIndex = ArrayExt.max(Object.keys(zIndexMap))
const maxZIndex = ArrayExt.max(
Object.keys(zIndexMap).map((z) => parseInt(z, 10)),
)
if (maxZIndex) {
candidates = zIndexMap[maxZIndex]
}
@ -907,6 +928,7 @@ export class NodeView<
}
finalizeEmbedding(e: JQuery.MouseUpEvent, data: EventData.MovingTargetNode) {
this.graph.startBatch('embedding')
const cell = data.cell || this.cell
const graph = data.graph || this.graph
const view = graph.findViewByCell(cell)
@ -940,6 +962,7 @@ export class NodeView<
currentParent: cell.getParent(),
})
}
this.graph.stopBatch('embedding')
}
getDelegatedView() {

View File

@ -421,7 +421,7 @@ export namespace ToolsView {
return this
}
protected stamp(elem: Element = this.container) {
protected stamp(elem: Element) {
if (elem) {
elem.setAttribute('data-cell-id', this.cellView.cell.id)
}

View File

@ -8,7 +8,7 @@
"build": "yarn clean && ./node_modules/.bin/tsc"
},
"dependencies": {
"@actions/core": "^1.2.5",
"@actions/core": "^1.9.1",
"@actions/github": "^4.0.0",
"@semantic-release/changelog": "^5.0.1",
"@semantic-release/exec": "^5.0.0",

View File

@ -2,10 +2,13 @@
# yarn lockfile v1
"@actions/core@^1.2.5":
version "1.2.6"
resolved "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz#a78d49f41a4def18e88ce47c2cac615d5694bf09"
integrity sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA==
"@actions/core@^1.9.1":
version "1.9.1"
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.9.1.tgz#97c0201b1f9856df4f7c3a375cdcdb0c2a2f750b"
integrity sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==
dependencies:
"@actions/http-client" "^2.0.1"
uuid "^8.3.2"
"@actions/github@^4.0.0":
version "4.0.0"
@ -24,6 +27,13 @@
dependencies:
tunnel "0.0.6"
"@actions/http-client@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-2.0.1.tgz#873f4ca98fe32f6839462a6f046332677322f99c"
integrity sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==
dependencies:
tunnel "^0.0.6"
"@babel/code-frame@^7.0.0":
version "7.10.4"
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
@ -6549,7 +6559,7 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
tunnel@0.0.6:
tunnel@0.0.6, tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
@ -6772,6 +6782,11 @@ uuid@^3.0.1, uuid@^3.3.2, uuid@^3.3.3:
resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"

View File

@ -13,7 +13,7 @@ import './index.css'
// eslint-disable-next-line
const repo = require('../../loaders/repo.js!./data.js')
const iconOpenInNewWindow: React.SFC = () => (
const iconOpenInNewWindow: React.FC = () => (
<svg
width="15"
height="12"

View File

@ -1,8 +1,11 @@
import React from 'react'
import React, { PropsWithChildren } from 'react'
import { Toolbar } from '../toolbar'
import './content.css'
export class Content extends React.Component<Content.Props, Content.State> {
export class Content extends React.Component<
PropsWithChildren<Content.Props>,
Content.State
> {
private container: HTMLDivElement
constructor(props: Content.Props) {

View File

@ -15,9 +15,9 @@
"dependencies": {
"@ant-design/icons": "^4.2.1",
"@antv/layout": "^0.1.9",
"@antv/x6": "latest",
"@antv/x6-react-components": "^1.1.16",
"@antv/x6-react-shape": "^1.6.0",
"@antv/x6": "1.x",
"@antv/x6-react-components": "1.x",
"@antv/x6-react-shape": "1.x",
"@antv/x6-sites-demos-helper": "^1.2.2",
"@types/d3-sankey": "^0.11.1",
"@types/highlight.js": "^9.12.4",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,8 +3,8 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6-react-components": "latest",
"@antv/x6": "latest",
"@antv/x6-react-components": "1.x",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

View File

@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/x6": "latest",
"@antv/x6": "1.x",
"@antv/x6-sites-demos-helper": "latest",
"antd": "^4.4.2",
"react": "^16.13.1",

Some files were not shown because too many files have changed in this diff Show More