Compare commits
64 Commits
@antv/x6@1
...
v2.0.6-bet
Author | SHA1 | Date | |
---|---|---|---|
cff8c126de | |||
346c6a268a | |||
f53f819043 | |||
f351284809 | |||
12c67255ae | |||
7e179844dc | |||
bc5284c6fe | |||
ad63046e89 | |||
12f0345555 | |||
5e0e2acde7 | |||
a10dcdb29f | |||
394c945fa2 | |||
ecfd4263b1 | |||
6ce3980f86 | |||
a09deaadd0 | |||
b8576ce96a | |||
aafdab63ba | |||
41f6b252ac | |||
3700fa683b | |||
f1c80a8cd7 | |||
5a3caed2a4 | |||
a6a2d12b07 | |||
ee7ae2fca9 | |||
425a540f23 | |||
7617efbe40 | |||
55d36e4680 | |||
0aced58056 | |||
9496d1a720 | |||
fcba5e1480 | |||
1436586f85 | |||
825190ee82 | |||
c42c1b21f3 | |||
7a96008010 | |||
237869f496 | |||
7a9f0908d7 | |||
5ae7271a25 | |||
d16066a734 | |||
c32fdfd7f8 | |||
57a50a9dec | |||
23fcea2e8a | |||
c68140504b | |||
ca48de2d7e | |||
690718c18e | |||
aee3666da2 | |||
38c6fd6992 | |||
d1eb01c491 | |||
023b81301e | |||
e8fbcd83fd | |||
10ab981274 | |||
d7cfb6af19 | |||
5ba9b1d2dc | |||
075db14981 | |||
5913369bc5 | |||
445eaf3475 | |||
f07a2eb386 | |||
c1d0fc188e | |||
68c143babf | |||
df11dfbce2 | |||
223cb4330f | |||
9e19ab98b6 | |||
d060d3405f | |||
299b0f7d3d | |||
4e8ef5f5ff | |||
6415927413 |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- name: ⤵️ Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
3
.github/workflows/config/labels.yml
vendored
3
.github/workflows/config/labels.yml
vendored
@ -138,9 +138,6 @@
|
||||
- name: pkg:x6
|
||||
color: eeeeee
|
||||
description: Denotes a PR that changes packages/x6
|
||||
- name: pkg:x6-react
|
||||
color: eeeeee
|
||||
description: Denotes a PR that changes packages/x6-react
|
||||
- name: pkg:x6-react-shape
|
||||
color: eeeeee
|
||||
description: Denotes a PR that changes packages/x6-react-shape
|
||||
|
1
.github/workflows/delete-stale-releases.yml
vendored
1
.github/workflows/delete-stale-releases.yml
vendored
@ -20,7 +20,6 @@ jobs:
|
||||
group: '(?!^)@.*$'
|
||||
exclude: |
|
||||
@antv/x6@**
|
||||
@antv/x6-react@**
|
||||
@antv/x6-vue-shape@**
|
||||
@antv/x6-react-shape@**
|
||||
@antv/x6-angular-shape@**
|
||||
|
2
.github/workflows/deploy-sites.yml
vendored
2
.github/workflows/deploy-sites.yml
vendored
@ -7,7 +7,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- name: ⤵️ Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
2
.github/workflows/preview.yml
vendored
2
.github/workflows/preview.yml
vendored
@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- name: ⤵️ Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
2
.github/workflows/update-cache.yaml
vendored
2
.github/workflows/update-cache.yaml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
node-version: [16.x]
|
||||
steps:
|
||||
- name: ⤵️ Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,3 +11,5 @@ es
|
||||
dist
|
||||
*.pem
|
||||
!mock-cert.pem
|
||||
tmp
|
||||
test
|
1
AUTHORS
1
AUTHORS
@ -37,6 +37,7 @@ lopn <lopnxrp@126.com>
|
||||
luchunwei <luchunwei@gmail.com>
|
||||
luzhuang <364439895@qq.com>
|
||||
lvhuiyang <ilvhuiyang@gmail.com>
|
||||
newbyvector <vectorse@126.com>
|
||||
niexq <1879633916@qq.com>
|
||||
niexq <niexq@firstgrid.cn>
|
||||
pengxingjian.pxj <pengxingjian.pxj@alibaba-inc.com>
|
||||
|
@ -110,8 +110,8 @@ Look at [these files](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJyg
|
||||
|
||||
X6 uses semantic versioning in release process based on [semver](https://semver.org/).
|
||||
|
||||
- [Publishing maintenance releases](https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/maintenance-releases.md)
|
||||
- [Publishing pre-releases](https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/pre-releases.md)
|
||||
- [Publishing maintenance releases](https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/release-workflow/maintenance-releases.md)
|
||||
- [Publishing pre-releases](https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/release-workflow/pre-releases.md)
|
||||
|
||||
### Branch Strategy
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 代码贡献规范
|
||||
|
||||
有任何疑问,欢迎提交 [issue](https://github.com/antvis/x6/issues) 或 [PR](https://github.com/antvis/x6/pulls)!
|
||||
如果你有任何疑问,欢迎提交 [issue](https://github.com/antvis/x6/issues) 或 [PR](https://github.com/antvis/x6/pulls)!
|
||||
|
||||
## 提交 issue
|
||||
|
||||
@ -109,8 +109,8 @@ BREAKING CHANGE:
|
||||
|
||||
## 发布管理
|
||||
|
||||
- [Publishing maintenance releases](https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/maintenance-releases.md)
|
||||
- [Publishing pre-releases](https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/pre-releases.md)
|
||||
- [发布维护版本](https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/release-workflow/maintenance-releases.md)
|
||||
- [发布预发版本](https://github.com/semantic-release/semantic-release/blob/master/docs/recipes/release-workflow/pre-releases.md)
|
||||
|
||||
X6 基于 [semver](http://semver.org/lang/zh-CN/) 语义化版本号进行发布。
|
||||
|
||||
@ -121,7 +121,7 @@ X6 基于 [semver](http://semver.org/lang/zh-CN/) 语义化版本号进行发布
|
||||
|
||||
### 发布策略
|
||||
|
||||
每个大版本都有一个发布经理管理(PM),他/她要做的事情
|
||||
在每个大版本的发布中,都会有一个PM,他在发布的不同阶段负有以下职责:
|
||||
|
||||
#### 准备工作:
|
||||
|
||||
@ -135,6 +135,6 @@ X6 基于 [semver](http://semver.org/lang/zh-CN/) 语义化版本号进行发布
|
||||
|
||||
#### 发布时:
|
||||
|
||||
- 将老的稳定版本(master)备份到以当前大版本为名字的分支上(例如 `1.x`),并设置 tag 为 {v}.x`( v 为当前版本,例如 `1.x`)。
|
||||
- 将老的稳定版本(master)备份到以当前大版本为名字的分支上(例如 `1.x`),并设置 tag 为 {v}.x( v 为当前版本,例如 `1.x`)。
|
||||
- 发布新的稳定版本到 [npm](http://npmjs.com),并通知上层框架进行更新。
|
||||
- `npm publish` 之前,请先阅读[『我是如何发布一个 npm 包的』](https://fengmk2.com/blog/2016/how-i-publish-a-npm-package)。
|
||||
|
169
README.en-us.md
169
README.en-us.md
@ -2,10 +2,9 @@
|
||||
|
||||
<p align="center"><img src="/flow.svg"></p>
|
||||
|
||||
<p align="center"><strong>Graph Editing Engine Of AntV</strong></p>
|
||||
<p align="center"><strong>JavaScript diagramming library that uses SVG and HTML for rendering</strong></p>
|
||||
|
||||
<p align="center"><a href="https://x6.antv.vision/en/docs/tutorial/about">Tutorials</a> · <a href="https://x6.antv.vision/en/examples/gallery">Examples</a> · <a href="https://x6.antv.vision/en/docs/api/graph">API</a></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/antvis/X6/actions/workflows/ci.yml"><img alt="build" src="https://img.shields.io/github/workflow/status/antvis/x6/%F0%9F%91%B7%E3%80%80CI/master?logo=github&style=flat-square"></a>
|
||||
<a href="https://app.codecov.io/gh/antvis/X6"><img alt="coverage" src="https://img.shields.io/codecov/c/gh/antvis/x6?logo=codecov&style=flat-square&token=15CO54WYUV"></a>
|
||||
@ -23,15 +22,22 @@
|
||||
|
||||
## Features
|
||||
|
||||
- 🌱 easy-to-customize: based on well known SVG/HTML/CSS or React/Vue to custom nodes and edges
|
||||
- 🚀 out-of-the-box: built-in 10+ plugins, such as selection, dnd, redo/undo, snapline, minimap, etc.
|
||||
- 🧲 data-driven: base on MVC architecture, you can focus on data logic and business logic
|
||||
- 💯 highly-event-driven: you can react on any event that happens inside the graph
|
||||
- 🌱 Easy-to-customize: based on well known SVG/HTML/CSS or React/Vue/Angular to custom nodes and edges
|
||||
- 🚀 Out-of-the-box: built-in 10+ plugins, such as selection, dnd, redo/undo, snapline, minimap, etc.
|
||||
- 🧲 Data-driven: base on MVC architecture, you can focus on data logic and business logic
|
||||
- 💯 Highly-event-driven: you can react on any event that happens inside the graph
|
||||
|
||||
## Environment Support
|
||||
|
||||
- Modern browsers and Internet Explorer 11 (with polyfills)
|
||||
- Server-side Rendering
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>Safari |
|
||||
| --- | --- | --- | --- |
|
||||
| IE11, Edge | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
## Installation
|
||||
|
||||
### NPM/Yarn
|
||||
|
||||
```shell
|
||||
# npm
|
||||
$ npm install @antv/x6 --save
|
||||
@ -40,51 +46,20 @@ $ npm install @antv/x6 --save
|
||||
$ yarn add @antv/x6
|
||||
```
|
||||
|
||||
### CDNs
|
||||
|
||||
For learning purposes, you can use the latest version with one of the CDN:
|
||||
|
||||
- https://unpkg.com/@antv/x6/dist/x6.js
|
||||
- https://cdn.jsdelivr.net/npm/@antv/x6/dist/x6.js
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/antv-x6/1.3.20/x6.js
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/@antv/x6/dist/x6.js"></script>
|
||||
```
|
||||
|
||||
For production, we recommend linking to a specific version number to avoid unexpected breakage from newer versions:
|
||||
|
||||
- https://unpkg.com/@antv/x6@1.1.1/dist/x6.js
|
||||
- https://cdn.jsdelivr.net/npm/@antv/x6@1.1.1/dist/x6.js
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/antv-x6/1.1.1/x6.js
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/@antv/x6@1.1.1/dist/x6.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
**Step 1**: specify a container the render the diagram.
|
||||
|
||||
```html
|
||||
<div id="container" style="width: 600px; height: 400px"></div>
|
||||
```
|
||||
|
||||
**Step 2**: render nodes and edges.
|
||||
|
||||
```ts
|
||||
// import from node_modules
|
||||
import { Graph } from '@antv/x6'
|
||||
// or use the global variable `X6` exported from CDN links
|
||||
// const { Graph } = X6
|
||||
|
||||
// Create an instance of Graph.
|
||||
const graph = new Graph({
|
||||
container: document.getElementById('container'),
|
||||
grid: true
|
||||
})
|
||||
|
||||
// Render source node.
|
||||
const source = graph.addNode({
|
||||
x: 300,
|
||||
y: 40,
|
||||
@ -93,7 +68,6 @@ const source = graph.addNode({
|
||||
label: 'Hello',
|
||||
})
|
||||
|
||||
// Render target node.
|
||||
const target = graph.addNode({
|
||||
x: 420,
|
||||
y: 180,
|
||||
@ -102,94 +76,23 @@ const target = graph.addNode({
|
||||
label: 'World',
|
||||
})
|
||||
|
||||
// Render edge from source to target.
|
||||
graph.addEdge({
|
||||
source,
|
||||
target,
|
||||
})
|
||||
```
|
||||
|
||||
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*o4W3RLZicagAAAAAAAAAAAAAARQnAQ" alt="HelloWorld" />
|
||||
## Links
|
||||
|
||||
## Documentation
|
||||
|
||||
- [About](https://x6.antv.vision/en/docs/tutorial/about)
|
||||
- [Getting Started](https://x6.antv.vision/en/docs/tutorial/getting-started)
|
||||
- [Basic Usage](https://x6.antv.vision/en/docs/tutorial/basic/graph)
|
||||
- [Advanced Practice](https://x6.antv.vision/en/docs/tutorial/intermediate/serialization)
|
||||
- [Senior Guidance](https://x6.antv.vision/en/docs/tutorial/advanced/animation)
|
||||
- [ChangeLog](https://x6.antv.vision/en/docs/tutorial/log)
|
||||
|
||||
## App Demos Build with X6
|
||||
|
||||
<center>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#flowchart" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*JSr-RbwCgmcAAAAAAAAAAAAAARQnAQ" alt="Flow"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#dag" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*RPiGRaSus3UAAAAAAAAAAAAAARQnAQ" alt="Dag"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#mindmap" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="200" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*GsEGSaBkc84AAAAAAAAAAAAAARQnAQ" alt="MindMap"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#bpmn" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="200" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*aPSySa8oz4sAAAAAAAAAAAAAARQnAQ" alt="BPMN"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#class" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*OaCpR7t_mVoAAAAAAAAAAAAAARQnAQ" alt="Class"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#org" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*FWx5SYDzLw4AAAAAAAAAAAAAARQnAQ" alt="ORG"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#er" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*7yVJQoM6-9AAAAAAAAAAAAAAARQnAQ" alt="ER"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#swimlane" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*mUVrSJMkP1UAAAAAAAAAAAAAARQnAQ" alt="SwimLane"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#tree" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*XDnNRqnj4WkAAAAAAAAAAAAAARQnAQ" alt="Tree"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#elk" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*Z3ebTKy0w9cAAAAAAAAAAAAAARQnAQ" alt="ELK"/>
|
||||
</a>
|
||||
</center>
|
||||
|
||||
## Communication
|
||||
|
||||
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" />
|
||||
</a>
|
||||
- [Documents](https://x6.antv.vision/zh/docs/tutorial/about)
|
||||
- [Samples](https://x6.antv.vision/zh/examples/gallery)
|
||||
- [Blog](https://www.yuque.com/antv/x6/gcinvi)
|
||||
- [Versioning Release Note](https://www.yuque.com/antv/x6/bbfu6r)
|
||||
- [FAQ](https://www.yuque.com/antv/x6/be9pfx)
|
||||
- [CodeSanbox Template](https://codesandbox.io/s/qosj0?file=/src/app.tsx)
|
||||
|
||||
## Development
|
||||
|
||||
This repo is based on [lerna](https://github.com/lerna/lerna) with the following structure:
|
||||
|
||||
```
|
||||
.
|
||||
├── examples
|
||||
│ ├── x6-app-dag # example of dag graph
|
||||
│ ├── x6-app-draw # example of flowchart
|
||||
│ ├── x6-app-er # example of ER chart
|
||||
│ └── x6-example-features # example of basic features
|
||||
├── packages
|
||||
│ ├── x6 # X6
|
||||
│ ├── x6-react # wrap X6 with react(reserved)
|
||||
│ ├── x6-react-components # react componets to build graph apps
|
||||
│ ├── x6-react-shape # support render node with react
|
||||
│ └── x6-vue-shape # support render node with vue
|
||||
└── sites
|
||||
├── x6-sites # sites and documents
|
||||
├── x6-sites-demos # demos in documents
|
||||
└── x6-sites-demos-helper # tools to build demos
|
||||
```
|
||||
|
||||
We need to install some necessary global tools before getting started.
|
||||
|
||||
```shell
|
||||
# install yarn and lerna
|
||||
$ npm install yarn -g
|
||||
@ -197,37 +100,19 @@ $ npm install lerna -g
|
||||
|
||||
# install deps and build
|
||||
$ yarn bootstrap
|
||||
```
|
||||
|
||||
Then we can `cd` to dirs to development and debugging.
|
||||
|
||||
Such as, we can start `examples/x6-example-features` locally:
|
||||
|
||||
```shell
|
||||
cd examples/x6-example-features
|
||||
|
||||
yarn start
|
||||
```
|
||||
|
||||
When need to fix some bugs of X6, we can start with **watch** mode:
|
||||
|
||||
```shell
|
||||
# enter the specified project development and debugging
|
||||
cd packages/x6
|
||||
yarn build:watch
|
||||
|
||||
// build esm to "em" dir
|
||||
yarn build:watch:esm
|
||||
|
||||
// build commonjs to "lib" dir
|
||||
yarn build:watch:cjs
|
||||
# start example to see the effect
|
||||
cd examples/x6-example-features
|
||||
yarn start
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Please let us know how can we help. Do check out [issues](https://github.com/antvis/x6/issues) for bug reports or suggestions first.
|
||||
|
||||
To become a contributor, please follow our [contributing guide](/CONTRIBUTING.md).
|
||||
|
||||
## Contributors
|
||||
To become a contributor, please follow our [contributing guide](/CONTRIBUTING.md). If you are an active contributor, you can apply to be a outside collaborator.
|
||||
|
||||
<a href="https://github.com/antvis/x6/graphs/contributors">
|
||||
<img src="/CONTRIBUTORS.svg" alt="Contributors" width="740" />
|
||||
|
170
README.md
170
README.md
@ -1,10 +1,9 @@
|
||||
简体中文 | [English](/README.en-us.md)
|
||||
|
||||
<p align="center"><img src="/flow.svg"></p>
|
||||
<p align="center"><img alt="flow" src="/flow.svg"></p>
|
||||
|
||||
<p align="center"><strong>X6 是 AntV 旗下的图编辑引擎</strong></p>
|
||||
<p align="center"><strong>提供简单易用的节点定制能力和开箱即用的交互组件,方便我们快速搭建流程图、DAG 图、ER 图等图应用</strong></p>
|
||||
<p align="center"><a href="https://x6.antv.vision/zh/docs/tutorial/about">教程</a> • <a href="https://x6.antv.vision/zh/examples/gallery">示例</a> • <a href="https://x6.antv.vision/zh/docs/api/graph">API</a></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/antvis/X6/actions/workflows/ci.yml"><img alt="build" src="https://img.shields.io/github/workflow/status/antvis/x6/%F0%9F%91%B7%E3%80%80CI/master?logo=github&style=flat-square"></a>
|
||||
@ -21,17 +20,23 @@
|
||||
<a href="https://x6.antv.vision"><img alt="website" src="https://img.shields.io/static/v1?label=&labelColor=505050&message=website&color=0076D6&style=flat-square&logo=google-chrome&logoColor=0076D6"></a>
|
||||
</p>
|
||||
|
||||
|
||||
## 特性
|
||||
|
||||
- 🌱 极易定制:支持使用 SVG/HTML/React/Vue 定制节点样式和交互
|
||||
- 🌱 极易定制:支持使用 SVG/HTML/React/Vue/Angular 定制节点样式和交互
|
||||
- 🚀 开箱即用:内置 10+ 图编辑配套扩展,如框选、对齐线、小地图等
|
||||
- 🧲 数据驱动:基于 MVC 架构,用户更加专注于数据逻辑和业务逻辑
|
||||
- 💯 事件驱动:完备的事件系统,可以监听图表内发生的任何事件
|
||||
|
||||
## 安装
|
||||
## 兼容环境
|
||||
|
||||
### 使用 NPM/Yarn
|
||||
- 现代浏览器和 IE11(需要 polyfills)
|
||||
- 支持服务端渲染。
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>Safari |
|
||||
| --- | --- | --- | --- |
|
||||
| IE11, Edge | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
## 安装
|
||||
|
||||
```shell
|
||||
# npm
|
||||
@ -41,51 +46,20 @@ $ npm install @antv/x6 --save
|
||||
$ yarn add @antv/x6
|
||||
```
|
||||
|
||||
### 使用 CDN
|
||||
|
||||
可以使用下面任意一个最新版本的 CDN 地址:
|
||||
|
||||
- https://unpkg.com/@antv/x6/dist/x6.js
|
||||
- https://cdn.jsdelivr.net/npm/@antv/x6/dist/x6.js
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/antv-x6/1.3.20/x6.js
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/@antv/x6/dist/x6.js"></script>
|
||||
```
|
||||
|
||||
在生产环境中,建议使用指定版本号的链接,以避免版本更新带来的意外破坏:
|
||||
|
||||
- https://unpkg.com/@antv/x6@1.1.1/dist/x6.js
|
||||
- https://cdn.jsdelivr.net/npm/@antv/x6@1.1.1/dist/x6.js
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/antv-x6/1.1.1/x6.js
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/@antv/x6@1.1.1/dist/x6.js"></script>
|
||||
```
|
||||
|
||||
## 快速使用
|
||||
|
||||
**Step 1**: 指定渲染图的容器。
|
||||
## 示例
|
||||
|
||||
```html
|
||||
<div id="container" style="width: 600px; height: 400px"></div>
|
||||
```
|
||||
|
||||
**Step 2**: 渲染节点和边。
|
||||
|
||||
```ts
|
||||
// 从 node_modules 引入
|
||||
import { Graph } from '@antv/x6'
|
||||
// 从 CND 引入时,我们暴露了 X6 这个全局变量
|
||||
// const { Graph } = X6
|
||||
|
||||
// 创建 Graph 的实例
|
||||
const graph = new Graph({
|
||||
container: document.getElementById('container'),
|
||||
grid: true
|
||||
})
|
||||
|
||||
// 渲染源节点
|
||||
const source = graph.addNode({
|
||||
x: 300,
|
||||
y: 40,
|
||||
@ -94,7 +68,6 @@ const source = graph.addNode({
|
||||
label: 'Hello',
|
||||
})
|
||||
|
||||
// 渲染目标节点
|
||||
const target = graph.addNode({
|
||||
x: 420,
|
||||
y: 180,
|
||||
@ -103,97 +76,22 @@ const target = graph.addNode({
|
||||
label: 'World',
|
||||
})
|
||||
|
||||
// 渲染边
|
||||
graph.addEdge({
|
||||
source,
|
||||
target,
|
||||
})
|
||||
```
|
||||
|
||||
渲染结果如下。
|
||||
## 链接
|
||||
|
||||
<img src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*o4W3RLZicagAAAAAAAAAAAAAARQnAQ" alt="HelloWorld" />
|
||||
- [文档](https://x6.antv.vision/zh/docs/tutorial/about)
|
||||
- [示例](https://x6.antv.vision/zh/examples/gallery)
|
||||
- [博客](https://www.yuque.com/antv/x6/gcinvi)
|
||||
- [更新日志](https://www.yuque.com/antv/x6/bbfu6r)
|
||||
- [常见问题](https://www.yuque.com/antv/x6/be9pfx)
|
||||
- [CodeSanbox 模板](https://codesandbox.io/s/qosj0?file=/src/app.tsx)
|
||||
|
||||
## 使用文档
|
||||
|
||||
- [简介](https://x6.antv.vision/zh/docs/tutorial/about)
|
||||
- [快速上手](https://x6.antv.vision/zh/docs/tutorial/getting-started)
|
||||
- [基础教程](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)
|
||||
|
||||
## 应用案例
|
||||
|
||||
<center>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#flowchart" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*JSr-RbwCgmcAAAAAAAAAAAAAARQnAQ" alt="Flow"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#dag" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*RPiGRaSus3UAAAAAAAAAAAAAARQnAQ" alt="Dag"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#mindmap" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="200" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*GsEGSaBkc84AAAAAAAAAAAAAARQnAQ" alt="MindMap"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#bpmn" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="200" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*aPSySa8oz4sAAAAAAAAAAAAAARQnAQ" alt="BPMN"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#class" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*OaCpR7t_mVoAAAAAAAAAAAAAARQnAQ" alt="Class"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#org" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*FWx5SYDzLw4AAAAAAAAAAAAAARQnAQ" alt="ORG"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#er" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*7yVJQoM6-9AAAAAAAAAAAAAAARQnAQ" alt="ER"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#swimlane" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*mUVrSJMkP1UAAAAAAAAAAAAAARQnAQ" alt="SwimLane"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#tree" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*XDnNRqnj4WkAAAAAAAAAAAAAARQnAQ" alt="Tree"/>
|
||||
</a>
|
||||
<a href="https://x6.antv.vision/zh/examples/showcase/practices#elk" target="_blank" rel="noopener noreferrer">
|
||||
<img width="400" height="250" style="margin-bottom: 20px" src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*Z3ebTKy0w9cAAAAAAAAAAAAAARQnAQ" alt="ELK"/>
|
||||
</a>
|
||||
</center>
|
||||
|
||||
## 如何交流
|
||||
|
||||
如果你在使用的过程中碰到问题,可以先通过 [issues](https://github.com/antvis/x6/issues) 看看有没有类似的 bug 或者建议。欢迎提 [issues](https://github.com/antvis/x6/issues/new) 交流,也可以使用[钉钉](https://m.dingtalk.com/)扫描下面二维码加入**X6 交流群**。
|
||||
|
||||
需要注意的是,提问题时请配上 [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="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" />
|
||||
</a>
|
||||
|
||||
## 如何开发
|
||||
|
||||
我们使用了 [lerna](https://github.com/lerna/lerna) 来管理项目,目录结构如下:
|
||||
|
||||
```
|
||||
.
|
||||
├── examples
|
||||
│ ├── x6-app-dag # dag 图示例
|
||||
│ ├── x6-app-draw # 流程图示例
|
||||
│ ├── x6-app-er # ER 图示例
|
||||
│ └── x6-example-features # 特性演示示例
|
||||
├── packages
|
||||
│ ├── x6 # X6
|
||||
│ ├── x6-react # X6 的 React 封装(预留)
|
||||
│ ├── x6-react-components # 配套 React 组件库
|
||||
│ ├── x6-react-shape # 支持使用 React 渲染节点
|
||||
│ └── x6-vue-shape # 支持使用 Vue 渲染节点
|
||||
└── sites
|
||||
├── x6-sites # 官网和文档
|
||||
├── x6-sites-demos # 文档中嵌入的 DEMO
|
||||
└── x6-sites-demos-helper # 构建文档 DEMO 的工具
|
||||
```
|
||||
|
||||
开始之前需要安装必要的全局依赖和初始化:
|
||||
## 本地开发
|
||||
|
||||
```shell
|
||||
# 全局安装 yarn 和 lerna 工具
|
||||
@ -202,35 +100,19 @@ $ npm install lerna -g
|
||||
|
||||
# 安装项目依赖和初始化构建
|
||||
$ yarn bootstrap
|
||||
```
|
||||
|
||||
然后可以进入到指定项目开发和调试。
|
||||
# 进入到指定项目开发和调试
|
||||
cd packages/x6
|
||||
yarn build:watch
|
||||
|
||||
如本地启动 `examples/x6-example-features` 示例:
|
||||
|
||||
```shell
|
||||
# 启动 example 查看效果
|
||||
cd examples/x6-example-features
|
||||
|
||||
yarn start
|
||||
```
|
||||
|
||||
修复 X6 的 BUG 时可以开启 watch 模式,配合上面启动的本地 DEMO,实时查看修复效果:
|
||||
## 参与共建
|
||||
|
||||
```shell
|
||||
cd packages/x6
|
||||
|
||||
// esm 模式,动态构建 es 产物
|
||||
yarn build:watch:esm
|
||||
|
||||
// commonjs 模式,动态构建 lib 产物
|
||||
yarn build:watch:cjs
|
||||
```
|
||||
|
||||
## 如何贡献
|
||||
|
||||
如果你在使用的过程中碰到问题,可以先通过 [issues](https://github.com/antvis/x6/issues) 看看有没有类似的 bug 或者建议。
|
||||
|
||||
如需提交代码,请遵从我们的[贡献指南](/CONTRIBUTING.zh-CN.md)。我们会收集贡献者的 Github 头像到下面贡献者清单中。
|
||||
如果希望参与到 X6 的开发中,请遵从我们的[贡献指南](/CONTRIBUTING.zh-CN.md)。如果你贡献度足够活跃,你可以申请成为社区协作者。
|
||||
|
||||
<a href="https://github.com/antvis/x6/graphs/contributors">
|
||||
<img src="/CONTRIBUTORS.svg" alt="Contributors" width="740" />
|
||||
|
21
SECURITY.md
Normal file
21
SECURITY.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Use this section to tell people about which versions of your project are
|
||||
currently being supported with security updates.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 5.1.x | :white_check_mark: |
|
||||
| 5.0.x | :x: |
|
||||
| 4.0.x | :white_check_mark: |
|
||||
| < 4.0 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Use this section to tell people how to report a vulnerability.
|
||||
|
||||
Tell them where to go, how often they can expect to get an update on a
|
||||
reported vulnerability, what to expect if the vulnerability is accepted or
|
||||
declined, etc.
|
@ -8,6 +8,7 @@
|
||||
"pretty-quick": "^3.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.3"
|
||||
"typescript": "^4.4.3",
|
||||
"release-it": "^14.0.1"
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
"build": "umi build",
|
||||
"postinstall": "umi generate tmp",
|
||||
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
|
||||
"test": "umi-test",
|
||||
"lint": "umi-lint --eslint src/ -p.no-semi --prettier --fix",
|
||||
"test:coverage": "umi-test --coverage"
|
||||
},
|
||||
|
12
examples/x6-app-dag/typings.d.ts
vendored
12
examples/x6-app-dag/typings.d.ts
vendored
@ -1,10 +1,10 @@
|
||||
declare module '*.css';
|
||||
declare module '*.less';
|
||||
declare module '*.png';
|
||||
declare module '*.css'
|
||||
declare module '*.less'
|
||||
declare module '*.png'
|
||||
declare module '*.svg' {
|
||||
export function ReactComponent(
|
||||
props: React.SVGProps<SVGSVGElement>,
|
||||
): React.ReactElement;
|
||||
const url: string;
|
||||
export default url;
|
||||
): React.ReactElement
|
||||
const url: string
|
||||
export default url
|
||||
}
|
||||
|
@ -10,9 +10,7 @@
|
||||
"baseUrl": "./",
|
||||
"strict": true,
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
"allowSyntheticDefaultImports": true
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
"build": "umi build",
|
||||
"postinstall": "umi generate tmp",
|
||||
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
|
||||
"test": "umi-test",
|
||||
"test:coverage": "umi-test --coverage"
|
||||
},
|
||||
"gitHooks": {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@antv/x6-example-features",
|
||||
"version": "1.2.2",
|
||||
"version": "2.0.2-beta.0",
|
||||
"scripts": {
|
||||
"start": "umi dev",
|
||||
"build": "umi build",
|
||||
@ -10,22 +10,23 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/x6": "^1.30.2",
|
||||
"@antv/x6-react-components": "^1.1.16",
|
||||
"@antv/x6-react-shape": "^1.6.0",
|
||||
"@antv/x6-next": "^2.0.3-beta.0",
|
||||
"@antv/x6-react-components": "^2.0.3-beta.0",
|
||||
"@antv/x6-react-shape": "^2.0.3-beta.0",
|
||||
"@antv/x6-vector": "^1.3.0",
|
||||
"antd": "^4.4.2",
|
||||
"classnames": "^2.2.6",
|
||||
"dagre": "^0.8.5",
|
||||
"elkjs": "^0.7.1",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.8.6",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"react-helmet": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ant-design/icons": "^4.2.2",
|
||||
"@types/jest": "^25.2.1",
|
||||
"@types/react": "^16.7.18",
|
||||
"@types/react-dom": "^16.0.11",
|
||||
"@types/react": "^18.0.0",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"@types/react-helmet": "^6.0.0",
|
||||
"@types/react-test-renderer": "^16.0.3",
|
||||
"eslint": "^7.16.0",
|
||||
|
@ -5,12 +5,11 @@ import '../index.less'
|
||||
class BallView extends NodeView {
|
||||
protected speed: number = 0
|
||||
protected angle: number = 0
|
||||
protected timerId: number = 0
|
||||
protected edge: Edge | null
|
||||
|
||||
protected init() {
|
||||
this.timerId = this.cell.transition('attrs/label/opacity', 1, {
|
||||
delay: (1 + Math.random()) * 3000,
|
||||
this.cell.transition('attrs/label/opacity', 1, {
|
||||
delay: 0,
|
||||
duration: 3000,
|
||||
timing: 'inout',
|
||||
interp: function (a: number, b: number) {
|
||||
@ -28,7 +27,7 @@ class BallView extends NodeView {
|
||||
})
|
||||
|
||||
this.cell.on('change:position', ({ cell, current }) => {
|
||||
const node = (cell as any) as Node
|
||||
const node = cell as any as Node
|
||||
this.angle = Point.create(node.getPosition()).theta(
|
||||
node.previous('position'),
|
||||
)
|
||||
@ -97,17 +96,13 @@ class BallView extends NodeView {
|
||||
}
|
||||
|
||||
onMouseDown(e: JQuery.MouseDownEvent, x: number, y: number) {
|
||||
console.log('mousedown1')
|
||||
// Do not allow drag element while it's still in a transition.
|
||||
if (this.cell.getTransitions().indexOf('position') > -1) {
|
||||
console.log('mousedown2')
|
||||
return
|
||||
}
|
||||
|
||||
// Cancel displaying 'drag me!' if dragging already starts.
|
||||
if (this.timerId) {
|
||||
clearTimeout(this.timerId)
|
||||
delete this.timerId
|
||||
}
|
||||
|
||||
this.edge = this.graph.addEdge({
|
||||
shape: 'edge',
|
||||
source: this.cell.getBBox().getCenter(),
|
||||
@ -128,7 +123,7 @@ class BallView extends NodeView {
|
||||
|
||||
// Change the marker arrow color.
|
||||
this.edge.on('change:target', ({ cell }) => {
|
||||
const edge = (cell as any) as Edge
|
||||
const edge = cell as any as Edge
|
||||
const sourcePoint = edge.getSourcePoint()!
|
||||
const targetPoint = edge.getTargetPoint()!
|
||||
const dist = sourcePoint.distance(targetPoint)
|
@ -1,5 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Graph, Cell, Point, Timing, Interp } from '@antv/x6'
|
||||
import { Graph, Cell } from '@antv/x6-next'
|
||||
import { Point } from '@antv/x6-geometry'
|
||||
import { Timing, Interp } from '@antv/x6-common'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
@ -11,6 +13,9 @@ export default class Example extends React.Component {
|
||||
width: 650,
|
||||
height: 400,
|
||||
grid: 1,
|
||||
background: {
|
||||
color: '#F2F7FA',
|
||||
},
|
||||
})
|
||||
|
||||
const ball = graph.addNode({
|
||||
@ -23,9 +28,12 @@ export default class Example extends React.Component {
|
||||
label: {
|
||||
text: 'ball',
|
||||
fontSize: 20,
|
||||
stroke: '#8f8f8f',
|
||||
},
|
||||
body: {
|
||||
fill: '#FFFFFF',
|
||||
stroke: '#8f8f8f',
|
||||
strokeWidth: 1,
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -59,7 +67,6 @@ export default class Example extends React.Component {
|
||||
{
|
||||
delay: 5000,
|
||||
duration: 2000,
|
||||
easing: 'easeInBounce',
|
||||
interp: (
|
||||
start: { text: String; fontSize: number },
|
||||
end: { text: String; fontSize: number },
|
||||
@ -84,9 +91,12 @@ export default class Example extends React.Component {
|
||||
label: {
|
||||
text: 'u.f.o.',
|
||||
fontSize: 10,
|
||||
stroke: '8f8f8f',
|
||||
},
|
||||
body: {
|
||||
fill: '#FFFFFF',
|
||||
stroke: '#8f8f8f',
|
||||
strokeWidth: 1,
|
||||
},
|
||||
},
|
||||
})
|
@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import { Graph, Cell } from '@antv/x6'
|
||||
import { Graph, Cell } from '@antv/x6-next'
|
||||
import { Bus, Connector, Component, Fader, Aux } from './shapes'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
@ -12,9 +12,6 @@ export default class Example extends React.Component {
|
||||
container: this.container,
|
||||
width: 1000,
|
||||
height: 800,
|
||||
async: true,
|
||||
frozen: true,
|
||||
sorting: 'approx',
|
||||
translating: {
|
||||
restrict: true,
|
||||
},
|
||||
@ -206,8 +203,6 @@ export default class Example extends React.Component {
|
||||
connector24,
|
||||
connector25,
|
||||
] as any)
|
||||
|
||||
graph.unfreeze()
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Node, Shape } from '@antv/x6'
|
||||
import { Node, Shape } from '@antv/x6-next'
|
||||
|
||||
export class Bus extends Shape.Edge {
|
||||
static create(x: number, label: string, color: string) {
|
||||
|
@ -1,453 +1,453 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node, Path, Cell } from '@antv/x6'
|
||||
import '@antv/x6-react-shape'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
interface NodeStatus {
|
||||
id: string
|
||||
status: 'default' | 'success' | 'failed' | 'running'
|
||||
label?: string
|
||||
}
|
||||
// import React from 'react'
|
||||
// import { Graph, Node, Path, Cell } from '@antv/x6'
|
||||
// import '@antv/x6-react-shape'
|
||||
// import '../index.less'
|
||||
// import './index.less'
|
||||
// interface NodeStatus {
|
||||
// id: string
|
||||
// status: 'default' | 'success' | 'failed' | 'running'
|
||||
// label?: string
|
||||
// }
|
||||
|
||||
const image = {
|
||||
logo: 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*evDjT5vjkX0AAAAAAAAAAAAAARQnAQ',
|
||||
success:
|
||||
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*6l60T6h8TTQAAAAAAAAAAAAAARQnAQ',
|
||||
failed:
|
||||
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*SEISQ6My-HoAAAAAAAAAAAAAARQnAQ',
|
||||
running:
|
||||
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*t8fURKfgSOgAAAAAAAAAAAAAARQnAQ',
|
||||
}
|
||||
export class AlgoNode extends React.Component<{ node?: Node }> {
|
||||
shouldComponentUpdate() {
|
||||
const { node } = this.props
|
||||
if (node) {
|
||||
if (node.hasChanged('data')) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
// const image = {
|
||||
// logo: 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*evDjT5vjkX0AAAAAAAAAAAAAARQnAQ',
|
||||
// success:
|
||||
// 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*6l60T6h8TTQAAAAAAAAAAAAAARQnAQ',
|
||||
// failed:
|
||||
// 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*SEISQ6My-HoAAAAAAAAAAAAAARQnAQ',
|
||||
// running:
|
||||
// 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*t8fURKfgSOgAAAAAAAAAAAAAARQnAQ',
|
||||
// }
|
||||
// export class AlgoNode extends React.Component<{ node?: Node }> {
|
||||
// shouldComponentUpdate() {
|
||||
// const { node } = this.props
|
||||
// if (node) {
|
||||
// if (node.hasChanged('data')) {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
|
||||
render() {
|
||||
const { node } = this.props
|
||||
const data = node?.getData() as NodeStatus
|
||||
const { label, status = 'default' } = data
|
||||
// render() {
|
||||
// const { node } = this.props
|
||||
// const data = node?.getData() as NodeStatus
|
||||
// const { label, status = 'default' } = data
|
||||
|
||||
return (
|
||||
<div className={`node ${status}`}>
|
||||
<img src={image.logo} />
|
||||
<span className="label">{label}</span>
|
||||
<span className="status">
|
||||
{status === 'success' && <img src={image.success} />}
|
||||
{status === 'failed' && <img src={image.failed} />}
|
||||
{status === 'running' && <img src={image.running} />}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
// return (
|
||||
// <div className={`node ${status}`}>
|
||||
// <img src={image.logo} alt="logo" />
|
||||
// <span className="label">{label}</span>
|
||||
// <span className="status">
|
||||
// {status === 'success' && <img src={image.success} alt="success" />}
|
||||
// {status === 'failed' && <img src={image.failed} alt="failed" />}
|
||||
// {status === 'running' && <img src={image.running} alt="running" />}
|
||||
// </span>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
Graph.registerNode(
|
||||
'dag-node',
|
||||
{
|
||||
inherit: 'react-shape',
|
||||
width: 180,
|
||||
height: 36,
|
||||
component: <AlgoNode />,
|
||||
ports: {
|
||||
groups: {
|
||||
top: {
|
||||
position: 'top',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 4,
|
||||
magnet: true,
|
||||
stroke: '#C2C8D5',
|
||||
strokeWidth: 1,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
bottom: {
|
||||
position: 'bottom',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 4,
|
||||
magnet: true,
|
||||
stroke: '#C2C8D5',
|
||||
strokeWidth: 1,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
)
|
||||
// Graph.registerNode(
|
||||
// 'dag-node',
|
||||
// {
|
||||
// inherit: 'react-shape',
|
||||
// width: 180,
|
||||
// height: 36,
|
||||
// component: <AlgoNode />,
|
||||
// ports: {
|
||||
// groups: {
|
||||
// top: {
|
||||
// position: 'top',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 4,
|
||||
// magnet: true,
|
||||
// stroke: '#C2C8D5',
|
||||
// strokeWidth: 1,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// bottom: {
|
||||
// position: 'bottom',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 4,
|
||||
// magnet: true,
|
||||
// stroke: '#C2C8D5',
|
||||
// strokeWidth: 1,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// true,
|
||||
// )
|
||||
|
||||
Graph.registerEdge(
|
||||
'dag-edge',
|
||||
{
|
||||
inherit: 'edge',
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#C2C8D5',
|
||||
strokeWidth: 1,
|
||||
targetMarker: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
)
|
||||
// Graph.registerEdge(
|
||||
// 'dag-edge',
|
||||
// {
|
||||
// inherit: 'edge',
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#C2C8D5',
|
||||
// strokeWidth: 1,
|
||||
// targetMarker: null,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// true,
|
||||
// )
|
||||
|
||||
Graph.registerConnector(
|
||||
'algo-connector',
|
||||
(s, e) => {
|
||||
const offset = 4
|
||||
const deltaY = Math.abs(e.y - s.y)
|
||||
const control = Math.floor((deltaY / 3) * 2)
|
||||
// Graph.registerConnector(
|
||||
// 'algo-connector',
|
||||
// (s, e) => {
|
||||
// const offset = 4
|
||||
// const deltaY = Math.abs(e.y - s.y)
|
||||
// const control = Math.floor((deltaY / 3) * 2)
|
||||
|
||||
const v1 = { x: s.x, y: s.y + offset + control }
|
||||
const v2 = { x: e.x, y: e.y - offset - control }
|
||||
// const v1 = { x: s.x, y: s.y + offset + control }
|
||||
// const v2 = { x: e.x, y: e.y - offset - control }
|
||||
|
||||
return Path.normalize(
|
||||
`M ${s.x} ${s.y}
|
||||
L ${s.x} ${s.y + offset}
|
||||
C ${v1.x} ${v1.y} ${v2.x} ${v2.y} ${e.x} ${e.y - offset}
|
||||
L ${e.x} ${e.y}
|
||||
`,
|
||||
)
|
||||
},
|
||||
true,
|
||||
)
|
||||
// return Path.normalize(
|
||||
// `M ${s.x} ${s.y}
|
||||
// L ${s.x} ${s.y + offset}
|
||||
// C ${v1.x} ${v1.y} ${v2.x} ${v2.y} ${e.x} ${e.y - offset}
|
||||
// L ${e.x} ${e.y}
|
||||
// `,
|
||||
// )
|
||||
// },
|
||||
// true,
|
||||
// )
|
||||
|
||||
const data = [
|
||||
{
|
||||
id: '1',
|
||||
shape: 'dag-node',
|
||||
x: 290,
|
||||
y: 110,
|
||||
data: {
|
||||
label: '读数据',
|
||||
status: 'success',
|
||||
},
|
||||
ports: [
|
||||
{
|
||||
id: '1-1',
|
||||
group: 'bottom',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
shape: 'dag-node',
|
||||
x: 290,
|
||||
y: 225,
|
||||
data: {
|
||||
label: '读数据',
|
||||
status: 'success',
|
||||
},
|
||||
ports: [
|
||||
{
|
||||
id: '2-1',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: '2-2',
|
||||
group: 'bottom',
|
||||
},
|
||||
{
|
||||
id: '2-3',
|
||||
group: 'bottom',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
shape: 'dag-node',
|
||||
x: 170,
|
||||
y: 350,
|
||||
data: {
|
||||
label: '读数据',
|
||||
status: 'success',
|
||||
},
|
||||
ports: [
|
||||
{
|
||||
id: '3-1',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: '3-2',
|
||||
group: 'bottom',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
shape: 'dag-node',
|
||||
x: 450,
|
||||
y: 350,
|
||||
data: {
|
||||
label: '读数据',
|
||||
status: 'success',
|
||||
},
|
||||
ports: [
|
||||
{
|
||||
id: '4-1',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: '4-2',
|
||||
group: 'bottom',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
shape: 'dag-edge',
|
||||
source: {
|
||||
cell: '1',
|
||||
port: '1-1',
|
||||
},
|
||||
target: {
|
||||
cell: '2',
|
||||
port: '2-1',
|
||||
},
|
||||
zIndex: 0,
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
shape: 'dag-edge',
|
||||
source: {
|
||||
cell: '2',
|
||||
port: '2-2',
|
||||
},
|
||||
target: {
|
||||
cell: '3',
|
||||
port: '3-1',
|
||||
},
|
||||
zIndex: 0,
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
shape: 'dag-edge',
|
||||
source: {
|
||||
cell: '2',
|
||||
port: '2-3',
|
||||
},
|
||||
target: {
|
||||
cell: '4',
|
||||
port: '4-1',
|
||||
},
|
||||
zIndex: 0,
|
||||
},
|
||||
]
|
||||
// const data = [
|
||||
// {
|
||||
// id: '1',
|
||||
// shape: 'dag-node',
|
||||
// x: 290,
|
||||
// y: 110,
|
||||
// data: {
|
||||
// label: '读数据',
|
||||
// status: 'success',
|
||||
// },
|
||||
// ports: [
|
||||
// {
|
||||
// id: '1-1',
|
||||
// group: 'bottom',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// shape: 'dag-node',
|
||||
// x: 290,
|
||||
// y: 225,
|
||||
// data: {
|
||||
// label: '读数据',
|
||||
// status: 'success',
|
||||
// },
|
||||
// ports: [
|
||||
// {
|
||||
// id: '2-1',
|
||||
// group: 'top',
|
||||
// },
|
||||
// {
|
||||
// id: '2-2',
|
||||
// group: 'bottom',
|
||||
// },
|
||||
// {
|
||||
// id: '2-3',
|
||||
// group: 'bottom',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// shape: 'dag-node',
|
||||
// x: 170,
|
||||
// y: 350,
|
||||
// data: {
|
||||
// label: '读数据',
|
||||
// status: 'success',
|
||||
// },
|
||||
// ports: [
|
||||
// {
|
||||
// id: '3-1',
|
||||
// group: 'top',
|
||||
// },
|
||||
// {
|
||||
// id: '3-2',
|
||||
// group: 'bottom',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// shape: 'dag-node',
|
||||
// x: 450,
|
||||
// y: 350,
|
||||
// data: {
|
||||
// label: '读数据',
|
||||
// status: 'success',
|
||||
// },
|
||||
// ports: [
|
||||
// {
|
||||
// id: '4-1',
|
||||
// group: 'top',
|
||||
// },
|
||||
// {
|
||||
// id: '4-2',
|
||||
// group: 'bottom',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// id: '5',
|
||||
// shape: 'dag-edge',
|
||||
// source: {
|
||||
// cell: '1',
|
||||
// port: '1-1',
|
||||
// },
|
||||
// target: {
|
||||
// cell: '2',
|
||||
// port: '2-1',
|
||||
// },
|
||||
// zIndex: 0,
|
||||
// },
|
||||
// {
|
||||
// id: '6',
|
||||
// shape: 'dag-edge',
|
||||
// source: {
|
||||
// cell: '2',
|
||||
// port: '2-2',
|
||||
// },
|
||||
// target: {
|
||||
// cell: '3',
|
||||
// port: '3-1',
|
||||
// },
|
||||
// zIndex: 0,
|
||||
// },
|
||||
// {
|
||||
// id: '7',
|
||||
// shape: 'dag-edge',
|
||||
// source: {
|
||||
// cell: '2',
|
||||
// port: '2-3',
|
||||
// },
|
||||
// target: {
|
||||
// cell: '4',
|
||||
// port: '4-1',
|
||||
// },
|
||||
// zIndex: 0,
|
||||
// },
|
||||
// ]
|
||||
|
||||
const nodeStatusList = [
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
status: 'running',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
status: 'default',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
status: 'default',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
status: 'default',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
status: 'running',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
status: 'default',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
status: 'default',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
status: 'running',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
status: 'running',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
status: 'failed',
|
||||
},
|
||||
],
|
||||
]
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
// const nodeStatusList = [
|
||||
// [
|
||||
// {
|
||||
// id: '1',
|
||||
// status: 'running',
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// status: 'default',
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// status: 'default',
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// status: 'default',
|
||||
// },
|
||||
// ],
|
||||
// [
|
||||
// {
|
||||
// id: '1',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// status: 'running',
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// status: 'default',
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// status: 'default',
|
||||
// },
|
||||
// ],
|
||||
// [
|
||||
// {
|
||||
// id: '1',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// status: 'running',
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// status: 'running',
|
||||
// },
|
||||
// ],
|
||||
// [
|
||||
// {
|
||||
// id: '1',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// status: 'failed',
|
||||
// },
|
||||
// ],
|
||||
// ]
|
||||
// export default class Example extends React.Component {
|
||||
// private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph: Graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
panning: {
|
||||
enabled: true,
|
||||
eventTypes: ['leftMouseDown', 'mouseWheel'],
|
||||
},
|
||||
mousewheel: {
|
||||
enabled: true,
|
||||
modifiers: 'ctrl',
|
||||
factor: 1.1,
|
||||
maxScale: 1.5,
|
||||
minScale: 0.5,
|
||||
},
|
||||
highlighting: {
|
||||
magnetAdsorbed: {
|
||||
name: 'stroke',
|
||||
args: {
|
||||
attrs: {
|
||||
fill: '#fff',
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
connecting: {
|
||||
snap: true,
|
||||
allowBlank: false,
|
||||
allowLoop: false,
|
||||
highlight: true,
|
||||
connector: 'algo-connector',
|
||||
connectionPoint: 'anchor',
|
||||
anchor: 'center',
|
||||
validateMagnet({ magnet }) {
|
||||
return magnet.getAttribute('port-group') !== 'top'
|
||||
},
|
||||
createEdge() {
|
||||
return graph.createEdge({
|
||||
shape: 'dag-edge',
|
||||
attrs: {
|
||||
line: {
|
||||
strokeDasharray: '5 5',
|
||||
},
|
||||
},
|
||||
zIndex: -1,
|
||||
})
|
||||
},
|
||||
},
|
||||
selecting: {
|
||||
enabled: true,
|
||||
multiple: true,
|
||||
rubberEdge: true,
|
||||
rubberNode: true,
|
||||
modifiers: 'shift',
|
||||
rubberband: true,
|
||||
},
|
||||
})
|
||||
// componentDidMount() {
|
||||
// const graph: Graph = new Graph({
|
||||
// container: this.container,
|
||||
// width: 800,
|
||||
// height: 600,
|
||||
// panning: {
|
||||
// enabled: true,
|
||||
// eventTypes: ['leftMouseDown', 'mouseWheel'],
|
||||
// },
|
||||
// mousewheel: {
|
||||
// enabled: true,
|
||||
// modifiers: 'ctrl',
|
||||
// factor: 1.1,
|
||||
// maxScale: 1.5,
|
||||
// minScale: 0.5,
|
||||
// },
|
||||
// highlighting: {
|
||||
// magnetAdsorbed: {
|
||||
// name: 'stroke',
|
||||
// args: {
|
||||
// attrs: {
|
||||
// fill: '#fff',
|
||||
// stroke: '#31d0c6',
|
||||
// strokeWidth: 4,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// connecting: {
|
||||
// snap: true,
|
||||
// allowBlank: false,
|
||||
// allowLoop: false,
|
||||
// highlight: true,
|
||||
// connector: 'algo-connector',
|
||||
// connectionPoint: 'anchor',
|
||||
// anchor: 'center',
|
||||
// validateMagnet({ magnet }) {
|
||||
// return magnet.getAttribute('port-group') !== 'top'
|
||||
// },
|
||||
// createEdge() {
|
||||
// return graph.createEdge({
|
||||
// shape: 'dag-edge',
|
||||
// attrs: {
|
||||
// line: {
|
||||
// strokeDasharray: '5 5',
|
||||
// },
|
||||
// },
|
||||
// zIndex: -1,
|
||||
// })
|
||||
// },
|
||||
// },
|
||||
// selecting: {
|
||||
// enabled: true,
|
||||
// multiple: true,
|
||||
// rubberEdge: true,
|
||||
// rubberNode: true,
|
||||
// modifiers: 'shift',
|
||||
// rubberband: true,
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.on('edge:connected', ({ edge }) => {
|
||||
edge.attr({
|
||||
line: {
|
||||
strokeDasharray: '',
|
||||
},
|
||||
})
|
||||
})
|
||||
// graph.on('edge:connected', ({ edge }) => {
|
||||
// edge.attr({
|
||||
// line: {
|
||||
// strokeDasharray: '',
|
||||
// },
|
||||
// })
|
||||
// })
|
||||
|
||||
graph.on('node:change:data', ({ node }) => {
|
||||
const edges = graph.getIncomingEdges(node)
|
||||
const { status } = node.getData() as NodeStatus
|
||||
edges?.forEach((edge) => {
|
||||
if (status === 'running') {
|
||||
edge.attr('line/strokeDasharray', 5)
|
||||
edge.attr('line/style/animation', 'running-line 30s infinite linear')
|
||||
} else {
|
||||
edge.attr('line/strokeDasharray', '')
|
||||
edge.attr('line/style/animation', '')
|
||||
}
|
||||
})
|
||||
})
|
||||
// graph.on('node:change:data', ({ node }) => {
|
||||
// const edges = graph.getIncomingEdges(node)
|
||||
// const { status } = node.getData() as NodeStatus
|
||||
// edges?.forEach((edge) => {
|
||||
// if (status === 'running') {
|
||||
// edge.attr('line/strokeDasharray', 5)
|
||||
// edge.attr('line/style/animation', 'running-line 30s infinite linear')
|
||||
// } else {
|
||||
// edge.attr('line/strokeDasharray', '')
|
||||
// edge.attr('line/style/animation', '')
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
|
||||
// 初始化节点/边
|
||||
const init = (data: Cell.Metadata[]) => {
|
||||
const cells: Cell[] = []
|
||||
data.forEach((item) => {
|
||||
if (item.shape === 'dag-node') {
|
||||
cells.push(graph.createNode(item))
|
||||
} else {
|
||||
cells.push(graph.createEdge(item))
|
||||
}
|
||||
})
|
||||
graph.resetCells(cells)
|
||||
}
|
||||
// // 初始化节点/边
|
||||
// const init = (data: Cell.Metadata[]) => {
|
||||
// const cells: Cell[] = []
|
||||
// data.forEach((item) => {
|
||||
// if (item.shape === 'dag-node') {
|
||||
// cells.push(graph.createNode(item))
|
||||
// } else {
|
||||
// cells.push(graph.createEdge(item))
|
||||
// }
|
||||
// })
|
||||
// graph.resetCells(cells)
|
||||
// }
|
||||
|
||||
// 显示节点状态
|
||||
const showNodeStatus = async (statusList: NodeStatus[][]) => {
|
||||
const status = statusList.shift()
|
||||
status?.forEach((item) => {
|
||||
const { id, status } = item
|
||||
const node = graph.getCellById(id)
|
||||
const data = node.getData() as NodeStatus
|
||||
node.setData({
|
||||
...data,
|
||||
status: status,
|
||||
})
|
||||
})
|
||||
setTimeout(() => {
|
||||
showNodeStatus(statusList)
|
||||
}, 3000)
|
||||
}
|
||||
// // 显示节点状态
|
||||
// const showNodeStatus = async (statusList: NodeStatus[][]) => {
|
||||
// const status = statusList.shift()
|
||||
// status?.forEach((item) => {
|
||||
// const { id, status } = item
|
||||
// const node = graph.getCellById(id)
|
||||
// const data = node.getData() as NodeStatus
|
||||
// node.setData({
|
||||
// ...data,
|
||||
// status: status,
|
||||
// })
|
||||
// })
|
||||
// setTimeout(() => {
|
||||
// showNodeStatus(statusList)
|
||||
// }, 3000)
|
||||
// }
|
||||
|
||||
init(data)
|
||||
showNodeStatus(nodeStatusList)
|
||||
}
|
||||
// init(data)
|
||||
// showNodeStatus(nodeStatusList)
|
||||
// }
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
// refContainer = (container: HTMLDivElement) => {
|
||||
// this.container = container
|
||||
// }
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
// render() {
|
||||
// return (
|
||||
// <div className="x6-graph-wrap">
|
||||
// <div ref={this.refContainer} className="dag" />
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
@ -155,7 +155,7 @@ export default class Example extends React.Component {
|
||||
const { bendPoints = [] } = edge.sections[0]
|
||||
|
||||
if (pos) {
|
||||
bendPoints.map((bendPoint: Position) => {
|
||||
bendPoints.forEach((bendPoint: Position) => {
|
||||
bendPoint.x += pos.x
|
||||
bendPoint.y += pos.y
|
||||
})
|
||||
|
@ -1,70 +1,72 @@
|
||||
.node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
border: 1px solid #c2c8d5;
|
||||
border-left: 4px solid #1890ff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 5px 1px rgba(0, 0, 0, 0.06);
|
||||
img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex-shrink: 0;
|
||||
margin-left: 8px;
|
||||
}
|
||||
.label {
|
||||
display: inline-block;
|
||||
flex-shrink: 0;
|
||||
width: 104px;
|
||||
margin-left: 8px;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
}
|
||||
.status {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
&.success {
|
||||
border-left: 4px solid #52c41a;
|
||||
}
|
||||
&.failed {
|
||||
border-left: 4px solid #ff4d4f;
|
||||
}
|
||||
&.running .status img {
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
.x6-node-selected {
|
||||
.dag {
|
||||
.node {
|
||||
border-color: #1890ff;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 0 4px #d4e8fe;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
border: 1px solid #c2c8d5;
|
||||
border-left: 4px solid #1890ff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 5px 1px rgba(0, 0, 0, 0.06);
|
||||
img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex-shrink: 0;
|
||||
margin-left: 8px;
|
||||
}
|
||||
.label {
|
||||
display: inline-block;
|
||||
flex-shrink: 0;
|
||||
width: 104px;
|
||||
margin-left: 8px;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
}
|
||||
.status {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
&.success {
|
||||
border-left: 4px solid #52c41a;
|
||||
}
|
||||
&.failed {
|
||||
border-left: 4px solid #ff4d4f;
|
||||
}
|
||||
&.running .status img {
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
}
|
||||
.node.success {
|
||||
border-color: #52c41a;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 0 4px #ccecc0;
|
||||
}
|
||||
.node.failed {
|
||||
border-color: #ff4d4f;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 0 4px #fedcdc;
|
||||
}
|
||||
}
|
||||
|
||||
.x6-edge:hover {
|
||||
path:nth-child(2) {
|
||||
stroke: #1890ff;
|
||||
stroke-width: 1px;
|
||||
.x6-node-selected {
|
||||
.node {
|
||||
border-color: #1890ff;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 0 4px #d4e8fe;
|
||||
}
|
||||
.node.success {
|
||||
border-color: #52c41a;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 0 4px #ccecc0;
|
||||
}
|
||||
.node.failed {
|
||||
border-color: #ff4d4f;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 0 4px #fedcdc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.x6-edge-selected {
|
||||
path:nth-child(2) {
|
||||
stroke: #1890ff;
|
||||
stroke-width: 1.5px !important;
|
||||
.x6-edge:hover {
|
||||
path:nth-child(2) {
|
||||
stroke: #1890ff;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.x6-edge-selected {
|
||||
path:nth-child(2) {
|
||||
stroke: #1890ff;
|
||||
stroke-width: 1.5px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,8 +189,7 @@ export default class Example extends React.Component {
|
||||
stroke: '#31d0c6',
|
||||
fill: '#31d0c6',
|
||||
name: 'path',
|
||||
d:
|
||||
'M4.834,4.834L4.833,4.833c-5.889,5.892-5.89,15.443,0.001,21.334s15.44,5.888,21.33-0.002c5.891-5.891,5.893-15.44,0.002-21.33C20.275-1.056,10.725-1.056,4.834,4.834zM25.459,5.542c0.833,0.836,1.523,1.757,2.104,2.726l-4.08,4.08c-0.418-1.062-1.053-2.06-1.912-2.918c-0.859-0.859-1.857-1.494-2.92-1.913l4.08-4.08C23.7,4.018,24.622,4.709,25.459,5.542zM10.139,20.862c-2.958-2.968-2.959-7.758-0.001-10.725c2.966-2.957,7.756-2.957,10.725,0c2.954,2.965,2.955,7.757-0.001,10.724C17.896,23.819,13.104,23.817,10.139,20.862zM5.542,25.459c-0.833-0.837-1.524-1.759-2.105-2.728l4.081-4.081c0.418,1.063,1.055,2.06,1.914,2.919c0.858,0.859,1.855,1.494,2.917,1.913l-4.081,4.081C7.299,26.982,6.379,26.292,5.542,25.459zM8.268,3.435l4.082,4.082C11.288,7.935,10.29,8.571,9.43,9.43c-0.858,0.859-1.494,1.855-1.912,2.918L3.436,8.267c0.58-0.969,1.271-1.89,2.105-2.727C6.377,4.707,7.299,4.016,8.268,3.435zM22.732,27.563l-4.082-4.082c1.062-0.418,2.061-1.053,2.919-1.912c0.859-0.859,1.495-1.857,1.913-2.92l4.082,4.082c-0.58,0.969-1.271,1.891-2.105,2.728C24.623,26.292,23.701,26.983,22.732,27.563z',
|
||||
d: 'M4.834,4.834L4.833,4.833c-5.889,5.892-5.89,15.443,0.001,21.334s15.44,5.888,21.33-0.002c5.891-5.891,5.893-15.44,0.002-21.33C20.275-1.056,10.725-1.056,4.834,4.834zM25.459,5.542c0.833,0.836,1.523,1.757,2.104,2.726l-4.08,4.08c-0.418-1.062-1.053-2.06-1.912-2.918c-0.859-0.859-1.857-1.494-2.92-1.913l4.08-4.08C23.7,4.018,24.622,4.709,25.459,5.542zM10.139,20.862c-2.958-2.968-2.959-7.758-0.001-10.725c2.966-2.957,7.756-2.957,10.725,0c2.954,2.965,2.955,7.757-0.001,10.724C17.896,23.819,13.104,23.817,10.139,20.862zM5.542,25.459c-0.833-0.837-1.524-1.759-2.105-2.728l4.081-4.081c0.418,1.063,1.055,2.06,1.914,2.919c0.858,0.859,1.855,1.494,2.917,1.913l-4.081,4.081C7.299,26.982,6.379,26.292,5.542,25.459zM8.268,3.435l4.082,4.082C11.288,7.935,10.29,8.571,9.43,9.43c-0.858,0.859-1.494,1.855-1.912,2.918L3.436,8.267c0.58-0.969,1.271-1.89,2.105-2.727C6.377,4.707,7.299,4.016,8.268,3.435zM22.732,27.563l-4.082-4.082c1.062-0.418,2.061-1.053,2.919-1.912c0.859-0.859,1.495-1.857,1.913-2.92l4.082,4.082c-0.58,0.969-1.271,1.891-2.105,2.728C24.623,26.292,23.701,26.983,22.732,27.563z',
|
||||
offsetX: 10,
|
||||
},
|
||||
},
|
||||
|
@ -98,14 +98,12 @@ export default class Example extends React.Component {
|
||||
stroke: '#31d0c6',
|
||||
sourceMarker: {
|
||||
name: 'path',
|
||||
d:
|
||||
'M5.5,15.499,15.8,21.447,15.8,15.846,25.5,21.447,25.5,9.552,15.8,15.152,15.8,9.552z',
|
||||
d: 'M5.5,15.499,15.8,21.447,15.8,15.846,25.5,21.447,25.5,9.552,15.8,15.152,15.8,9.552z',
|
||||
},
|
||||
targetMarker: {
|
||||
name: 'path',
|
||||
offsetX: 10,
|
||||
d:
|
||||
'M4.834,4.834L4.833,4.833c-5.889,5.892-5.89,15.443,0.001,21.334s15.44,5.888,21.33-0.002c5.891-5.891,5.893-15.44,0.002-21.33C20.275-1.056,10.725-1.056,4.834,4.834zM25.459,5.542c0.833,0.836,1.523,1.757,2.104,2.726l-4.08,4.08c-0.418-1.062-1.053-2.06-1.912-2.918c-0.859-0.859-1.857-1.494-2.92-1.913l4.08-4.08C23.7,4.018,24.622,4.709,25.459,5.542zM10.139,20.862c-2.958-2.968-2.959-7.758-0.001-10.725c2.966-2.957,7.756-2.957,10.725,0c2.954,2.965,2.955,7.757-0.001,10.724C17.896,23.819,13.104,23.817,10.139,20.862zM5.542,25.459c-0.833-0.837-1.524-1.759-2.105-2.728l4.081-4.081c0.418,1.063,1.055,2.06,1.914,2.919c0.858,0.859,1.855,1.494,2.917,1.913l-4.081,4.081C7.299,26.982,6.379,26.292,5.542,25.459zM8.268,3.435l4.082,4.082C11.288,7.935,10.29,8.571,9.43,9.43c-0.858,0.859-1.494,1.855-1.912,2.918L3.436,8.267c0.58-0.969,1.271-1.89,2.105-2.727C6.377,4.707,7.299,4.016,8.268,3.435zM22.732,27.563l-4.082-4.082c1.062-0.418,2.061-1.053,2.919-1.912c0.859-0.859,1.495-1.857,1.913-2.92l4.082,4.082c-0.58,0.969-1.271,1.891-2.105,2.728C24.623,26.292,23.701,26.983,22.732,27.563z',
|
||||
d: 'M4.834,4.834L4.833,4.833c-5.889,5.892-5.89,15.443,0.001,21.334s15.44,5.888,21.33-0.002c5.891-5.891,5.893-15.44,0.002-21.33C20.275-1.056,10.725-1.056,4.834,4.834zM25.459,5.542c0.833,0.836,1.523,1.757,2.104,2.726l-4.08,4.08c-0.418-1.062-1.053-2.06-1.912-2.918c-0.859-0.859-1.857-1.494-2.92-1.913l4.08-4.08C23.7,4.018,24.622,4.709,25.459,5.542zM10.139,20.862c-2.958-2.968-2.959-7.758-0.001-10.725c2.966-2.957,7.756-2.957,10.725,0c2.954,2.965,2.955,7.757-0.001,10.724C17.896,23.819,13.104,23.817,10.139,20.862zM5.542,25.459c-0.833-0.837-1.524-1.759-2.105-2.728l4.081-4.081c0.418,1.063,1.055,2.06,1.914,2.919c0.858,0.859,1.855,1.494,2.917,1.913l-4.081,4.081C7.299,26.982,6.379,26.292,5.542,25.459zM8.268,3.435l4.082,4.082C11.288,7.935,10.29,8.571,9.43,9.43c-0.858,0.859-1.494,1.855-1.912,2.918L3.436,8.267c0.58-0.969,1.271-1.89,2.105-2.727C6.377,4.707,7.299,4.016,8.268,3.435zM22.732,27.563l-4.082-4.082c1.062-0.418,2.061-1.053,2.919-1.912c0.859-0.859,1.495-1.857,1.913-2.92l4.082,4.082c-0.58,0.969-1.271,1.891-2.105,2.728C24.623,26.292,23.701,26.983,22.732,27.563z',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -48,7 +48,7 @@ class TooltipTool extends ToolsView.ToolItem<EdgeView, TooltipTool.Options> {
|
||||
() => this.toggleTooltip(true),
|
||||
this.delay,
|
||||
)
|
||||
if (this.options.follow != false) {
|
||||
if (this.options.follow !== false) {
|
||||
document.addEventListener('mousemove', this.onMouseMove)
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ class TooltipTool extends ToolsView.ToolItem<EdgeView, TooltipTool.Options> {
|
||||
() => this.toggleTooltip(false),
|
||||
this.delay,
|
||||
)
|
||||
if (this.options.follow != false) {
|
||||
if (this.options.follow !== false) {
|
||||
document.removeEventListener('mousemove', this.onMouseMove)
|
||||
}
|
||||
}
|
||||
@ -89,6 +89,7 @@ class TooltipTool extends ToolsView.ToolItem<EdgeView, TooltipTool.Options> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
namespace TooltipTool {
|
||||
TooltipTool.config({
|
||||
markup: Markup.getForeignObjectMarkup(),
|
||||
|
@ -14,7 +14,9 @@ export default class Example extends React.Component {
|
||||
validateMagnet({ cell, magnet }) {
|
||||
let count = 0
|
||||
const connectionCount = magnet.getAttribute('connection-count')
|
||||
const max = connectionCount ? parseInt(connectionCount, 10) : Number.MAX_SAFE_INTEGER
|
||||
const max = connectionCount
|
||||
? parseInt(connectionCount, 10)
|
||||
: Number.MAX_SAFE_INTEGER
|
||||
const outgoingEdges = graph.getOutgoingEdges(cell)
|
||||
if (outgoingEdges) {
|
||||
outgoingEdges.forEach((edge: Edge) => {
|
||||
|
@ -94,6 +94,7 @@ export default class Example extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
namespace Example {
|
||||
export interface Props {}
|
||||
export interface State {
|
||||
|
@ -163,7 +163,7 @@ export default class Example extends React.Component {
|
||||
if (!magnet) {
|
||||
return true
|
||||
}
|
||||
var cell = (cellView.cell as any) as TogglableRect
|
||||
var cell = cellView.cell as any as TogglableRect
|
||||
var portId = magnet.getAttribute('port')
|
||||
return portId ? !cell.isPortCollapsed(portId) : true
|
||||
},
|
||||
@ -180,7 +180,7 @@ export default class Example extends React.Component {
|
||||
e.stopPropagation()
|
||||
var portId = magnet.getAttribute('port')
|
||||
if (portId) {
|
||||
const rect = (view.cell as any) as TogglableRect
|
||||
const rect = view.cell as any as TogglableRect
|
||||
rect.expandPort(portId)
|
||||
}
|
||||
})
|
||||
@ -191,13 +191,13 @@ export default class Example extends React.Component {
|
||||
const visible = current !== false
|
||||
const sourceCell = cell.getSourceCell()
|
||||
if (sourceCell) {
|
||||
const rect = (sourceCell as any) as TogglableRect
|
||||
const rect = sourceCell as any as TogglableRect
|
||||
rect.onConnectedEdgeVisibleChange(cell, 'source', visible)
|
||||
}
|
||||
|
||||
const targetCell = cell.getTargetCell()
|
||||
if (targetCell) {
|
||||
const rect = (targetCell as any) as TogglableRect
|
||||
const rect = targetCell as any as TogglableRect
|
||||
rect.onConnectedEdgeVisibleChange(cell, 'target', visible)
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ export default class Example extends React.Component {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
<div id="minimap"/>
|
||||
<div id="minimap" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -53,10 +53,8 @@ export class IntermediateEvent extends Event {
|
||||
})
|
||||
}
|
||||
gateTypes = {
|
||||
or:
|
||||
'M -20 0 C -20 -15 -10 -30 0 -30 C 10 -30 20 -15 20 0 C 10 -6 -10 -6 -20 0',
|
||||
xor:
|
||||
'M -20 0 C -20 -15 -10 -30 0 -30 C 10 -30 20 -15 20 0 C 10 -6 -10 -6 -20 0 M -20 0 0 -30 M 0 -30 20 0',
|
||||
or: 'M -20 0 C -20 -15 -10 -30 0 -30 C 10 -30 20 -15 20 0 C 10 -6 -10 -6 -20 0',
|
||||
xor: 'M -20 0 C -20 -15 -10 -30 0 -30 C 10 -30 20 -15 20 0 C 10 -6 -10 -6 -20 0 M -20 0 0 -30 M 0 -30 20 0',
|
||||
and: 'M -20 0 C -20 -25 -10 -30 0 -30 C 10 -30 20 -25 20 0 Z',
|
||||
priority_and:
|
||||
'M -20 0 C -20 -25 -10 -30 0 -30 C 10 -30 20 -25 20 0 Z M -20 0 0 -30 20 0',
|
||||
|
@ -154,6 +154,7 @@ export class AttributeCard extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace AttributeCard {
|
||||
export interface Props {
|
||||
attrs: {
|
||||
|
@ -212,6 +212,7 @@ export class BackgroundCard extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace BackgroundCard {
|
||||
export interface Props {
|
||||
onChange: (res: Graph.BackgroundOptions) => void
|
||||
|
@ -33,6 +33,7 @@ export class BBoxCard extends React.Component<GridCard.Props> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace GridCard {
|
||||
export interface Props {
|
||||
x: number
|
||||
|
@ -105,6 +105,7 @@ export class FitToContentCard extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace FitToContentCard {
|
||||
export interface Props {
|
||||
onChange: (options: State) => void
|
||||
|
@ -228,6 +228,7 @@ export class GridCard extends React.Component<GridCard.Props, GridCard.State> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace GridCard {
|
||||
export interface Props {
|
||||
onGridSizeChange: (size: number) => void
|
||||
|
@ -77,7 +77,7 @@ export default class Example extends React.Component<
|
||||
}),
|
||||
})
|
||||
})
|
||||
.on('translate', ({origin: {x, y}}) => {
|
||||
.on('translate', ({ origin: { x, y } }) => {
|
||||
this.effect.hideAll()
|
||||
this.setState({
|
||||
attrs: getAttrs({
|
||||
@ -195,6 +195,7 @@ export default class Example extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
namespace Example {
|
||||
export interface Props {}
|
||||
export interface State {
|
||||
|
@ -122,6 +122,7 @@ export class ScaleContentToFitCard extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace ScaleContentToFitCard {
|
||||
export interface Props {
|
||||
onChange: (options: State) => void
|
||||
|
@ -42,7 +42,7 @@ export default class Example extends React.Component {
|
||||
stroke: '#9254de',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
shape: 'rect',
|
||||
@ -57,7 +57,7 @@ export default class Example extends React.Component {
|
||||
stroke: '#9254de',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
shape: 'rect',
|
||||
@ -72,7 +72,7 @@ export default class Example extends React.Component {
|
||||
stroke: '#9254de',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
shape: 'rect',
|
||||
@ -87,7 +87,7 @@ export default class Example extends React.Component {
|
||||
stroke: '#9254de',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
shape: 'rect',
|
||||
@ -185,8 +185,8 @@ export default class Example extends React.Component {
|
||||
}
|
||||
|
||||
onPositionPoint = () => {
|
||||
this.graph1.positionPoint({x: 50, y: 60}, 100, 100)
|
||||
this.graph2.positionPoint({x: 50, y: 60}, 100, 100)
|
||||
this.graph1.positionPoint({ x: 50, y: 60 }, 100, 100)
|
||||
this.graph2.positionPoint({ x: 50, y: 60 }, 100, 100)
|
||||
}
|
||||
|
||||
onPositionRect = () => {
|
||||
@ -214,23 +214,37 @@ export default class Example extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<div className="x6-graph-wrap" style={{ display: 'flex' }}>
|
||||
<div ref={this.refContainer1} className="x6-graph" />
|
||||
<div ref={this.refContainer2} className="x6-graph" />
|
||||
</div>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
flexFlow: 'wrap',
|
||||
flexShrink: 0,
|
||||
padding: '24px 48px',
|
||||
}}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexFlow: 'wrap',
|
||||
flexShrink: 0,
|
||||
padding: '24px 48px',
|
||||
}}
|
||||
>
|
||||
<Button onClick={() => this.onZoom(0.1)}>ZoomIn</Button>
|
||||
<Button onClick={() => this.onZoom(-0.1)}>ZoomOut</Button>
|
||||
<Button onClick={() => this.onZoom(0.1, { center: {x: 300, y: 200} })}>ZoomIn At [300, 200]</Button>
|
||||
<Button onClick={() => this.onZoom(-0.1, { center: {x: 300, y: 200} })}>ZoomOut At [300, 200]</Button>
|
||||
<Button
|
||||
onClick={() => this.onZoom(0.1, { center: { x: 300, y: 200 } })}
|
||||
>
|
||||
ZoomIn At [300, 200]
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => this.onZoom(-0.1, { center: { x: 300, y: 200 } })}
|
||||
>
|
||||
ZoomOut At [300, 200]
|
||||
</Button>
|
||||
<Button onClick={() => this.onZoomTo(1.5)}>ZoomTo</Button>
|
||||
<Button onClick={() => this.onZoomTo(1.5, { center: {x: 200, y: 100} })}>ZoomTo At [200, 100]</Button>
|
||||
<Button
|
||||
onClick={() => this.onZoomTo(1.5, { center: { x: 200, y: 100 } })}
|
||||
>
|
||||
ZoomTo At [200, 100]
|
||||
</Button>
|
||||
<Button onClick={() => this.onZoomToRect()}>ZoomToRect</Button>
|
||||
<Button onClick={() => this.onZoomToFit()}>ZoomToFit</Button>
|
||||
<Button onClick={() => this.onCenterPoint()}>CenterPoint</Button>
|
||||
@ -239,7 +253,9 @@ export default class Example extends React.Component {
|
||||
<Button onClick={() => this.onCenterCell()}>CenterCell</Button>
|
||||
<Button onClick={() => this.onPositionPoint()}>PositionPoint</Button>
|
||||
<Button onClick={() => this.onPositionRect()}>PositionRect</Button>
|
||||
<Button onClick={() => this.onPositionContent()}>PositionContent</Button>
|
||||
<Button onClick={() => this.onPositionContent()}>
|
||||
PositionContent
|
||||
</Button>
|
||||
<Button onClick={() => this.onPositionCell()}>PositionCell</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,310 +1,310 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node } from '@antv/x6'
|
||||
import '@antv/x6-react-shape'
|
||||
import data from './data.json'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
// import React from 'react'
|
||||
// import { Graph, Node } from '@antv/x6'
|
||||
// import '@antv/x6-react-shape'
|
||||
// import data from './data.json'
|
||||
// import '../index.less'
|
||||
// import './index.less'
|
||||
|
||||
//#region react component
|
||||
interface IProps {
|
||||
node?: Node
|
||||
}
|
||||
interface IState {
|
||||
collapsed: boolean
|
||||
}
|
||||
class GroupComponent extends React.Component<IProps, IState> {
|
||||
state = {
|
||||
collapsed: false,
|
||||
}
|
||||
// //#region react component
|
||||
// interface IProps {
|
||||
// node?: Node
|
||||
// }
|
||||
// interface IState {
|
||||
// collapsed: boolean
|
||||
// }
|
||||
// class GroupComponent extends React.Component<IProps, IState> {
|
||||
// state = {
|
||||
// collapsed: false,
|
||||
// }
|
||||
|
||||
shouldComponentUpdate(nextProps: IProps, nextState: IState) {
|
||||
return nextState.collapsed !== this.state.collapsed
|
||||
}
|
||||
// shouldComponentUpdate(nextProps: IProps, nextState: IState) {
|
||||
// return nextState.collapsed !== this.state.collapsed
|
||||
// }
|
||||
|
||||
onCollapse = () => {
|
||||
const node = this.props.node
|
||||
const target = !this.state.collapsed
|
||||
// onCollapse = () => {
|
||||
// const node = this.props.node
|
||||
// const target = !this.state.collapsed
|
||||
|
||||
if (node) {
|
||||
const cells = node.getChildren()
|
||||
if (cells) {
|
||||
cells.forEach((cell: Node) => {
|
||||
if (target) {
|
||||
cell.hide()
|
||||
} else {
|
||||
cell.show()
|
||||
}
|
||||
})
|
||||
}
|
||||
if (target) {
|
||||
node.prop('previousSize', node.size())
|
||||
node.size(160, 32)
|
||||
} else {
|
||||
const previousSize = node.prop('previousSize')
|
||||
node.size(previousSize.width, previousSize.height)
|
||||
}
|
||||
}
|
||||
// if (node) {
|
||||
// const cells = node.getChildren()
|
||||
// if (cells) {
|
||||
// cells.forEach((cell: Node) => {
|
||||
// if (target) {
|
||||
// cell.hide()
|
||||
// } else {
|
||||
// cell.show()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// if (target) {
|
||||
// node.prop('previousSize', node.size())
|
||||
// node.size(160, 32)
|
||||
// } else {
|
||||
// const previousSize = node.prop('previousSize')
|
||||
// node.size(previousSize.width, previousSize.height)
|
||||
// }
|
||||
// }
|
||||
|
||||
this.setState({
|
||||
collapsed: target,
|
||||
})
|
||||
}
|
||||
// this.setState({
|
||||
// collapsed: target,
|
||||
// })
|
||||
// }
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="group">
|
||||
<div className="header">
|
||||
<span>
|
||||
<img
|
||||
src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*rYacTYE0PR0AAAAAAAAAAAAAARQnAQ"
|
||||
alt="group"
|
||||
/>
|
||||
<span>Group</span>
|
||||
</span>
|
||||
<span className="btn" onClick={this.onCollapse}>
|
||||
{this.state.collapsed ? '+' : '-'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
Graph.registerReactComponent('group', <GroupComponent />, true)
|
||||
//#endregion
|
||||
// render() {
|
||||
// return (
|
||||
// <div className="group">
|
||||
// <div className="header">
|
||||
// <span>
|
||||
// <img
|
||||
// src="https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*rYacTYE0PR0AAAAAAAAAAAAAARQnAQ"
|
||||
// alt="group"
|
||||
// />
|
||||
// <span>Group</span>
|
||||
// </span>
|
||||
// <span className="btn" onClick={this.onCollapse}>
|
||||
// {this.state.collapsed ? '+' : '-'}
|
||||
// </span>
|
||||
// </div>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// Graph.registerReactComponent('group', <GroupComponent />, true)
|
||||
// //#endregion
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private graph: Graph
|
||||
private container: HTMLDivElement
|
||||
// export default class Example extends React.Component {
|
||||
// private graph: Graph
|
||||
// private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
connecting: {
|
||||
connector: 'smooth',
|
||||
},
|
||||
})
|
||||
// componentDidMount() {
|
||||
// const graph = new Graph({
|
||||
// container: this.container,
|
||||
// width: 800,
|
||||
// height: 600,
|
||||
// grid: true,
|
||||
// connecting: {
|
||||
// connector: 'smooth',
|
||||
// },
|
||||
// })
|
||||
|
||||
this.graph = graph
|
||||
this.initShape()
|
||||
this.initEvent()
|
||||
}
|
||||
// this.graph = graph
|
||||
// this.initShape()
|
||||
// this.initEvent()
|
||||
// }
|
||||
|
||||
initShape = () => {
|
||||
const nodes = data.nodes
|
||||
const edges = data.edges
|
||||
const groups = data.groups
|
||||
const newEdges: typeof edges = []
|
||||
// initShape = () => {
|
||||
// const nodes = data.nodes
|
||||
// const edges = data.edges
|
||||
// const groups = data.groups
|
||||
// const newEdges: typeof edges = []
|
||||
|
||||
const getNode = (nodeId: string) => {
|
||||
if (nodeId) {
|
||||
return nodes.find((node) => node.id === nodeId)
|
||||
}
|
||||
return null
|
||||
}
|
||||
// const getNode = (nodeId: string) => {
|
||||
// if (nodeId) {
|
||||
// return nodes.find((node) => node.id === nodeId)
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
|
||||
const getGroup = (groupId: string | undefined) => {
|
||||
if (groupId) {
|
||||
return groups.find((group) => group.id === groupId)
|
||||
}
|
||||
return null
|
||||
}
|
||||
// const getGroup = (groupId: string | undefined) => {
|
||||
// if (groupId) {
|
||||
// return groups.find((group) => group.id === groupId)
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
|
||||
// 将连接到群组内部节点的连线进行拆分
|
||||
// source target op
|
||||
// √ X source->群组->target
|
||||
// X √ source->群组->target
|
||||
// √ √ source->群组1->群组2->target
|
||||
edges.forEach((edge) => {
|
||||
const sourceNodeId =
|
||||
typeof edge.source === 'string' ? edge.source : edge.source.cell
|
||||
const targetNodeId =
|
||||
typeof edge.target === 'string' ? edge.target : edge.target.cell
|
||||
const sourceNode = getNode(sourceNodeId)
|
||||
const targetNode = getNode(targetNodeId)
|
||||
const sourceGroup = getGroup(sourceNode?.group)
|
||||
const targetGroup = getGroup(targetNode?.group)
|
||||
// // 将连接到群组内部节点的连线进行拆分
|
||||
// // source target op
|
||||
// // √ X source->群组->target
|
||||
// // X √ source->群组->target
|
||||
// // √ √ source->群组1->群组2->target
|
||||
// edges.forEach((edge) => {
|
||||
// const sourceNodeId =
|
||||
// typeof edge.source === 'string' ? edge.source : edge.source.cell
|
||||
// const targetNodeId =
|
||||
// typeof edge.target === 'string' ? edge.target : edge.target.cell
|
||||
// const sourceNode = getNode(sourceNodeId)
|
||||
// const targetNode = getNode(targetNodeId)
|
||||
// const sourceGroup = getGroup(sourceNode?.group)
|
||||
// const targetGroup = getGroup(targetNode?.group)
|
||||
|
||||
if (sourceGroup !== targetGroup) {
|
||||
if (sourceGroup && targetGroup) {
|
||||
const sourceGroupPort = {
|
||||
cell: sourceGroup.id,
|
||||
port: sourceGroup.ports.items[0].id,
|
||||
}
|
||||
const targetGroupPort = {
|
||||
cell: targetGroup.id,
|
||||
port: targetGroup.ports.items[0].id,
|
||||
}
|
||||
newEdges.push(
|
||||
...[
|
||||
{
|
||||
...edge,
|
||||
source: edge.source,
|
||||
target: sourceGroupPort,
|
||||
id: `${edge.id}_1`,
|
||||
for: edge.id,
|
||||
},
|
||||
{
|
||||
...edge,
|
||||
source: targetGroupPort,
|
||||
target: edge.target,
|
||||
id: `${edge.id}_2`,
|
||||
for: edge.id,
|
||||
},
|
||||
],
|
||||
)
|
||||
edge.source = sourceGroupPort
|
||||
edge.target = targetGroupPort
|
||||
// if (sourceGroup !== targetGroup) {
|
||||
// if (sourceGroup && targetGroup) {
|
||||
// const sourceGroupPort = {
|
||||
// cell: sourceGroup.id,
|
||||
// port: sourceGroup.ports.items[0].id,
|
||||
// }
|
||||
// const targetGroupPort = {
|
||||
// cell: targetGroup.id,
|
||||
// port: targetGroup.ports.items[0].id,
|
||||
// }
|
||||
// newEdges.push(
|
||||
// ...[
|
||||
// {
|
||||
// ...edge,
|
||||
// source: edge.source,
|
||||
// target: sourceGroupPort,
|
||||
// id: `${edge.id}_1`,
|
||||
// for: edge.id,
|
||||
// },
|
||||
// {
|
||||
// ...edge,
|
||||
// source: targetGroupPort,
|
||||
// target: edge.target,
|
||||
// id: `${edge.id}_2`,
|
||||
// for: edge.id,
|
||||
// },
|
||||
// ],
|
||||
// )
|
||||
// edge.source = sourceGroupPort
|
||||
// edge.target = targetGroupPort
|
||||
|
||||
const sourceChildren = sourceGroup.children as string[]
|
||||
const targetChildren = targetGroup.children as string[]
|
||||
sourceChildren.push(sourceNode!.id)
|
||||
targetChildren.push(targetNode!.id)
|
||||
} else if (sourceGroup) {
|
||||
const sourceGroupPort = {
|
||||
cell: sourceGroup.id,
|
||||
port: sourceGroup.ports.items[0].id,
|
||||
}
|
||||
newEdges.push(
|
||||
...[
|
||||
{
|
||||
...edge,
|
||||
source: edge.source,
|
||||
target: sourceGroupPort,
|
||||
id: `${edge.id}_1`,
|
||||
for: edge.id,
|
||||
},
|
||||
],
|
||||
)
|
||||
edge.source = sourceGroupPort
|
||||
// const sourceChildren = sourceGroup.children as string[]
|
||||
// const targetChildren = targetGroup.children as string[]
|
||||
// sourceChildren.push(sourceNode!.id)
|
||||
// targetChildren.push(targetNode!.id)
|
||||
// } else if (sourceGroup) {
|
||||
// const sourceGroupPort = {
|
||||
// cell: sourceGroup.id,
|
||||
// port: sourceGroup.ports.items[0].id,
|
||||
// }
|
||||
// newEdges.push(
|
||||
// ...[
|
||||
// {
|
||||
// ...edge,
|
||||
// source: edge.source,
|
||||
// target: sourceGroupPort,
|
||||
// id: `${edge.id}_1`,
|
||||
// for: edge.id,
|
||||
// },
|
||||
// ],
|
||||
// )
|
||||
// edge.source = sourceGroupPort
|
||||
|
||||
const children = sourceGroup.children as string[]
|
||||
children.push(sourceNode!.id)
|
||||
} else if (targetGroup) {
|
||||
const targetGroupPort = {
|
||||
cell: targetGroup.id,
|
||||
port: targetGroup.ports.items[0].id,
|
||||
}
|
||||
newEdges.push(
|
||||
...[
|
||||
{
|
||||
...edge,
|
||||
source: targetGroupPort,
|
||||
target: edge.target,
|
||||
id: `${edge.id}_1`,
|
||||
for: edge.id,
|
||||
},
|
||||
],
|
||||
)
|
||||
edge.target = targetGroupPort
|
||||
// const children = sourceGroup.children as string[]
|
||||
// children.push(sourceNode!.id)
|
||||
// } else if (targetGroup) {
|
||||
// const targetGroupPort = {
|
||||
// cell: targetGroup.id,
|
||||
// port: targetGroup.ports.items[0].id,
|
||||
// }
|
||||
// newEdges.push(
|
||||
// ...[
|
||||
// {
|
||||
// ...edge,
|
||||
// source: targetGroupPort,
|
||||
// target: edge.target,
|
||||
// id: `${edge.id}_1`,
|
||||
// for: edge.id,
|
||||
// },
|
||||
// ],
|
||||
// )
|
||||
// edge.target = targetGroupPort
|
||||
|
||||
const children = targetGroup.children as string[]
|
||||
children.push(targetNode!.id)
|
||||
}
|
||||
}
|
||||
})
|
||||
// const children = targetGroup.children as string[]
|
||||
// children.push(targetNode!.id)
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
this.graph.addNodes([...nodes, ...groups])
|
||||
this.graph.addEdges([...edges, ...newEdges])
|
||||
}
|
||||
// this.graph.addNodes([...nodes, ...groups])
|
||||
// this.graph.addEdges([...edges, ...newEdges])
|
||||
// }
|
||||
|
||||
initEvent = () => {
|
||||
const graph = this.graph
|
||||
graph.on('node:moving', ({ node }) => {
|
||||
const isGroup = node.prop('isGroup')
|
||||
if (isGroup) {
|
||||
node.prop('originPosition', node.getPosition())
|
||||
return
|
||||
}
|
||||
// initEvent = () => {
|
||||
// const graph = this.graph
|
||||
// graph.on('node:moving', ({ node }) => {
|
||||
// const isGroup = node.prop('isGroup')
|
||||
// if (isGroup) {
|
||||
// node.prop('originPosition', node.getPosition())
|
||||
// return
|
||||
// }
|
||||
|
||||
const groupId = node.prop('group')
|
||||
const group = graph.getNodes().find((node) => node.id === groupId)
|
||||
if (!group) {
|
||||
return
|
||||
}
|
||||
// const groupId = node.prop('group')
|
||||
// const group = graph.getNodes().find((node) => node.id === groupId)
|
||||
// if (!group) {
|
||||
// return
|
||||
// }
|
||||
|
||||
let hasChange = false
|
||||
let originSize = group.prop('originSize')
|
||||
if (originSize == null) {
|
||||
originSize = group.size()
|
||||
group.prop('originSize', originSize)
|
||||
}
|
||||
let originPosition = group.prop('originPosition')
|
||||
if (originPosition == null) {
|
||||
originPosition = group.position()
|
||||
group.prop('originPosition', originPosition)
|
||||
}
|
||||
// let hasChange = false
|
||||
// let originSize = group.prop('originSize')
|
||||
// if (originSize == null) {
|
||||
// originSize = group.size()
|
||||
// group.prop('originSize', originSize)
|
||||
// }
|
||||
// let originPosition = group.prop('originPosition')
|
||||
// if (originPosition == null) {
|
||||
// originPosition = group.position()
|
||||
// group.prop('originPosition', originPosition)
|
||||
// }
|
||||
|
||||
let x = originPosition.x
|
||||
let y = originPosition.y
|
||||
let cornerX = originPosition.x + originSize.width
|
||||
let cornerY = originPosition.y + originSize.height
|
||||
const childs = group.getChildren()
|
||||
if (childs) {
|
||||
childs.forEach((child) => {
|
||||
const bbox = child.getBBox().inflate(32)
|
||||
const corner = bbox.getCorner()
|
||||
// let x = originPosition.x
|
||||
// let y = originPosition.y
|
||||
// let cornerX = originPosition.x + originSize.width
|
||||
// let cornerY = originPosition.y + originSize.height
|
||||
// const childs = group.getChildren()
|
||||
// if (childs) {
|
||||
// childs.forEach((child) => {
|
||||
// const bbox = child.getBBox().inflate(32)
|
||||
// const corner = bbox.getCorner()
|
||||
|
||||
if (bbox.x < x) {
|
||||
x = bbox.x
|
||||
hasChange = true
|
||||
}
|
||||
// if (bbox.x < x) {
|
||||
// x = bbox.x
|
||||
// hasChange = true
|
||||
// }
|
||||
|
||||
if (bbox.y < y) {
|
||||
y = bbox.y
|
||||
hasChange = true
|
||||
}
|
||||
// if (bbox.y < y) {
|
||||
// y = bbox.y
|
||||
// hasChange = true
|
||||
// }
|
||||
|
||||
if (corner.x > cornerX) {
|
||||
cornerX = corner.x
|
||||
hasChange = true
|
||||
}
|
||||
// if (corner.x > cornerX) {
|
||||
// cornerX = corner.x
|
||||
// hasChange = true
|
||||
// }
|
||||
|
||||
if (corner.y > cornerY) {
|
||||
cornerY = corner.y
|
||||
hasChange = true
|
||||
}
|
||||
})
|
||||
}
|
||||
// if (corner.y > cornerY) {
|
||||
// cornerY = corner.y
|
||||
// hasChange = true
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
if (hasChange) {
|
||||
group.prop({
|
||||
position: { x, y },
|
||||
size: { width: cornerX - x, height: cornerY - y },
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
// if (hasChange) {
|
||||
// group.prop({
|
||||
// position: { x, y },
|
||||
// size: { width: cornerX - x, height: cornerY - y },
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
toJson = () => {
|
||||
const res = this.graph.toJSON()
|
||||
const cells = res.cells
|
||||
res.cells = cells
|
||||
.filter((cell) => !cell.for)
|
||||
.map((cell) => {
|
||||
if (cell.shape === 'edge') {
|
||||
return {
|
||||
...cell,
|
||||
source: cell.originSource || cell.source,
|
||||
target: cell.originTarget || cell.target,
|
||||
}
|
||||
}
|
||||
return cell
|
||||
})
|
||||
return res
|
||||
}
|
||||
// toJson = () => {
|
||||
// const res = this.graph.toJSON()
|
||||
// const cells = res.cells
|
||||
// res.cells = cells
|
||||
// .filter((cell) => !cell.for)
|
||||
// .map((cell) => {
|
||||
// if (cell.shape === 'edge') {
|
||||
// return {
|
||||
// ...cell,
|
||||
// source: cell.originSource || cell.source,
|
||||
// target: cell.originTarget || cell.target,
|
||||
// }
|
||||
// }
|
||||
// return cell
|
||||
// })
|
||||
// return res
|
||||
// }
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
// refContainer = (container: HTMLDivElement) => {
|
||||
// this.container = container
|
||||
// }
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
// render() {
|
||||
// return (
|
||||
// <div className="x6-graph-wrap">
|
||||
// <div ref={this.refContainer} className="x6-graph" />
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
@ -23,3 +23,9 @@
|
||||
box-shadow: 0 0 10px 1px #e9e9e9;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.home {
|
||||
width: 800px;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
@ -1,9 +1,42 @@
|
||||
import React from 'react'
|
||||
import { Table } from 'antd'
|
||||
import './index.less'
|
||||
|
||||
export default function() {
|
||||
const dataSource = [
|
||||
{
|
||||
key: '1',
|
||||
example: 'animation/transition',
|
||||
description: 'transition 动画',
|
||||
},
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'example',
|
||||
dataIndex: 'example',
|
||||
render(text: string) {
|
||||
return (
|
||||
<a href={`./${text}`} target="_blank">
|
||||
{text}
|
||||
</a>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'description',
|
||||
dataIndex: 'description',
|
||||
},
|
||||
]
|
||||
|
||||
export default function () {
|
||||
return (
|
||||
<div>
|
||||
<h1>Feature List</h1>
|
||||
<div className="home">
|
||||
<Table
|
||||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -245,6 +245,7 @@ export default class Example extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Example {
|
||||
export interface Props {}
|
||||
|
||||
|
@ -174,6 +174,7 @@ export default class Example extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Example {
|
||||
export interface Props {}
|
||||
|
||||
|
@ -32,7 +32,7 @@ class ContextMenuTool extends ToolsView.ToolItem<
|
||||
trigger={['click']}
|
||||
overlay={this.options.menu}
|
||||
>
|
||||
<a />
|
||||
<a href="#" />
|
||||
</Dropdown>,
|
||||
this.knob,
|
||||
() => {
|
||||
|
@ -43,8 +43,7 @@ const data = {
|
||||
y: 40,
|
||||
attrs: {
|
||||
label: {
|
||||
text:
|
||||
'testing测试测试测试thisisaveryveryveryveryveryverylongword jsvascriptjsvascriptjsvascript',
|
||||
text: 'testing测试测试测试thisisaveryveryveryveryveryverylongword jsvascriptjsvascriptjsvascript',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -84,6 +84,7 @@ export default class Example extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Example {
|
||||
export interface Props {}
|
||||
|
||||
|
@ -56,14 +56,10 @@ export default class Example extends React.Component {
|
||||
|
||||
graph.on('edge:connected', ({ edge }) => {
|
||||
graph.batchUpdate(() => {
|
||||
const {
|
||||
port: sourcePort,
|
||||
...source
|
||||
} = edge.getSource() as Edge.TerminalCellData
|
||||
const {
|
||||
port: targetPort,
|
||||
...target
|
||||
} = edge.getTarget() as Edge.TerminalCellData
|
||||
const { port: sourcePort, ...source } =
|
||||
edge.getSource() as Edge.TerminalCellData
|
||||
const { port: targetPort, ...target } =
|
||||
edge.getTarget() as Edge.TerminalCellData
|
||||
|
||||
edge.removeProp('source')
|
||||
edge.removeProp('target')
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
import {
|
||||
Graph,
|
||||
Node,
|
||||
@ -138,7 +139,7 @@ Graph.registerEdge(
|
||||
return defaults
|
||||
}
|
||||
|
||||
const attr = (val as {}) as AngleEdge.AngleOptions
|
||||
const attr = val as {} as AngleEdge.AngleOptions
|
||||
var angleRadius = attr.radius || 40
|
||||
var angleStart = attr.start || 'self'
|
||||
var anglePie = attr.pie || false
|
||||
@ -181,7 +182,7 @@ Graph.registerEdge(
|
||||
set(val, options) {
|
||||
let text = ''
|
||||
const view = options.view as EdgeView
|
||||
const attr = (val as {}) as AngleEdge.AngleTextOptions
|
||||
const attr = val as {} as AngleEdge.AngleTextOptions
|
||||
|
||||
let meta = AngleEdge.getArcMeta(view, attr.type, { radius: 40 })
|
||||
if (meta) {
|
||||
@ -213,8 +214,8 @@ Graph.registerEdge(
|
||||
line = new Line(connectionPoint, p).setLength(distance)
|
||||
} else {
|
||||
const c = new Line(arcPoint1, arcPoint2).getCenter()
|
||||
;(line = new Line(connectionPoint, c).setLength(distance)),
|
||||
largeArcFlag && line.scale(-1, -1, line.start)
|
||||
line = new Line(connectionPoint, c).setLength(distance)
|
||||
largeArcFlag && line.scale(-1, -1, line.start)
|
||||
}
|
||||
|
||||
const pos = line.end
|
||||
@ -230,6 +231,7 @@ Graph.registerEdge(
|
||||
true,
|
||||
)
|
||||
|
||||
// eslint-disable-next-line
|
||||
namespace Cache {
|
||||
function ensure(view: EdgeView) {
|
||||
const cacheKey = 'angleData'
|
||||
@ -237,7 +239,7 @@ namespace Cache {
|
||||
if (!(cacheKey in cache)) {
|
||||
cache[cacheKey] = {}
|
||||
}
|
||||
return (cache[cacheKey] as Object) as {
|
||||
return cache[cacheKey] as Object as {
|
||||
[key: string]: AngleEdge.Metadata | null
|
||||
}
|
||||
}
|
||||
@ -261,6 +263,7 @@ namespace Cache {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
namespace AngleEdge {
|
||||
export type AngleStart = 'self' | 'source' | 'target'
|
||||
export type AngleDirection = 'clockwise' | 'anticlockwise' | 'small' | 'large'
|
||||
|
@ -202,8 +202,7 @@ export default class Example extends React.Component {
|
||||
{
|
||||
tagName: 'path',
|
||||
attrs: {
|
||||
d:
|
||||
'M -4 -0.8 L -7.2 2.4 L -4 5.6 L -4 3.2 L 1.6 3.2 L 1.6 1.6 L -4 1.6 L -4 -0.8 Z M 7.2 -2.4 L 4 -5.6 L 4 -3.2 L -1.6 -3.2 L -1.6 -1.6 L 4 -1.6 L 4 0.8 L 7.2 -2.4 Z',
|
||||
d: 'M -4 -0.8 L -7.2 2.4 L -4 5.6 L -4 3.2 L 1.6 3.2 L 1.6 1.6 L -4 1.6 L -4 -0.8 Z M 7.2 -2.4 L 4 -5.6 L 4 -3.2 L -1.6 -3.2 L -1.6 -1.6 L 4 -1.6 L 4 0.8 L 7.2 -2.4 Z',
|
||||
cursor: 'pointer',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
@ -241,8 +240,7 @@ export default class Example extends React.Component {
|
||||
{
|
||||
tagName: 'path',
|
||||
attrs: {
|
||||
d:
|
||||
'M -4 -0.8 L -7.2 2.4 L -4 5.6 L -4 3.2 L 1.6 3.2 L 1.6 1.6 L -4 1.6 L -4 -0.8 Z M 7.2 -2.4 L 4 -5.6 L 4 -3.2 L -1.6 -3.2 L -1.6 -1.6 L 4 -1.6 L 4 0.8 L 7.2 -2.4 Z',
|
||||
d: 'M -4 -0.8 L -7.2 2.4 L -4 5.6 L -4 3.2 L 1.6 3.2 L 1.6 1.6 L -4 1.6 L -4 -0.8 Z M 7.2 -2.4 L 4 -5.6 L 4 -3.2 L -1.6 -3.2 L -1.6 -1.6 L 4 -1.6 L 4 0.8 L 7.2 -2.4 Z',
|
||||
cursor: 'pointer',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-namespace */
|
||||
import { Graph, Shape, EdgeView, Edge, Registry, Point, Angle } from '@antv/x6'
|
||||
|
||||
Graph.registerNode(
|
||||
@ -138,7 +139,7 @@ export const DistanceEdgeBase = Graph.registerEdge(
|
||||
distanceAnchor: {
|
||||
set(val, { view }) {
|
||||
if (typeof val === 'object') {
|
||||
const attr = (val as {}) as DistanceEdge.DistanceAnchorOptions
|
||||
const attr = val as {} as DistanceEdge.DistanceAnchorOptions
|
||||
const edgeView = view as EdgeView
|
||||
const anchor = edgeView.getTerminalAnchor(attr.type)
|
||||
const kont = edgeView.getTerminalConnectionPoint(attr.type)
|
||||
@ -151,7 +152,7 @@ export const DistanceEdgeBase = Graph.registerEdge(
|
||||
distanceText: {
|
||||
set(val, options) {
|
||||
const view = options.view as EdgeView
|
||||
const attr = (val as {}) as DistanceEdge.DistanceTextOptions
|
||||
const attr = val as {} as DistanceEdge.DistanceTextOptions
|
||||
const text = DistanceEdge.getDistanceText(view, attr)
|
||||
const raw = Registry.Attr.presets.text as Registry.Attr.SetDefinition
|
||||
raw.set.call(this, text, options)
|
||||
|
@ -247,6 +247,7 @@ export default class Example extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Example {
|
||||
export interface Props {}
|
||||
|
||||
|
@ -31,6 +31,7 @@ class Coords {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
namespace RandomDir {
|
||||
let radian = 4
|
||||
|
||||
|
@ -181,7 +181,7 @@ export default class Example extends React.Component<
|
||||
|
||||
edges.shift()
|
||||
|
||||
this.viewport = (viewportTemplate.clone() as any) as Node
|
||||
this.viewport = viewportTemplate.clone() as any as Node
|
||||
|
||||
console.time('perf-reset')
|
||||
|
||||
@ -305,6 +305,7 @@ export default class Example extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Example {
|
||||
export interface Props {}
|
||||
|
||||
|
@ -1,81 +1,102 @@
|
||||
[{
|
||||
"num": 200,
|
||||
"time": 0.379,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 400,
|
||||
"time": 0.481,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 600,
|
||||
"time": 0.569,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 800,
|
||||
"time": 0.681,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1000,
|
||||
"time": 0.79,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1200,
|
||||
"time": 0.915,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1400,
|
||||
"time": 1.056,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1600,
|
||||
"time": 1.24,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1800,
|
||||
"time": 1.388,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 2000,
|
||||
"time": 1.497,
|
||||
"type": "async"
|
||||
},{
|
||||
"num": 200,
|
||||
"time": 0.224,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 400,
|
||||
"time": 0.355,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 600,
|
||||
"time": 0.489,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 800,
|
||||
"time": 0.579,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1000,
|
||||
"time": 0.764,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1200,
|
||||
"time": 0.858,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1400,
|
||||
"time": 0.992,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1600,
|
||||
"time": 1.126,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1800,
|
||||
"time": 1.282,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 2000,
|
||||
"time": 1.763,
|
||||
"type": "sync"
|
||||
}]
|
||||
[
|
||||
{
|
||||
"num": 200,
|
||||
"time": 0.379,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 400,
|
||||
"time": 0.481,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 600,
|
||||
"time": 0.569,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 800,
|
||||
"time": 0.681,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1000,
|
||||
"time": 0.79,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1200,
|
||||
"time": 0.915,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1400,
|
||||
"time": 1.056,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1600,
|
||||
"time": 1.24,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1800,
|
||||
"time": 1.388,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 2000,
|
||||
"time": 1.497,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 200,
|
||||
"time": 0.224,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 400,
|
||||
"time": 0.355,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 600,
|
||||
"time": 0.489,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 800,
|
||||
"time": 0.579,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1000,
|
||||
"time": 0.764,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1200,
|
||||
"time": 0.858,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1400,
|
||||
"time": 0.992,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1600,
|
||||
"time": 1.126,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1800,
|
||||
"time": 1.282,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 2000,
|
||||
"time": 1.763,
|
||||
"type": "sync"
|
||||
}
|
||||
]
|
||||
|
@ -73,7 +73,7 @@ export default class Example extends React.Component {
|
||||
})
|
||||
nodes.push(a)
|
||||
})
|
||||
|
||||
|
||||
Array.from({ length: num }).forEach(() => {
|
||||
const a = graph.createEdge({
|
||||
shape: 'performance_normal_edge',
|
||||
@ -92,7 +92,7 @@ export default class Example extends React.Component {
|
||||
function test(num: number, iterations: number) {
|
||||
const { nodes, edges } = mockCells(num)
|
||||
graph.model.resetCells(nodes)
|
||||
|
||||
|
||||
const startTime = new Date().getTime()
|
||||
graph.model.addCells(edges)
|
||||
if (ASYNC) {
|
||||
@ -121,7 +121,11 @@ export default class Example extends React.Component {
|
||||
function output() {
|
||||
const res = Object.keys(result).map((key: string) => ({
|
||||
num: parseInt(key, 10),
|
||||
time: parseFloat((result[key].reduce((pre, cur) => pre + cur, 0) / ITERATIONS).toFixed(3)),
|
||||
time: parseFloat(
|
||||
(result[key].reduce((pre, cur) => pre + cur, 0) / ITERATIONS).toFixed(
|
||||
3,
|
||||
),
|
||||
),
|
||||
type: ASYNC ? 'async' : 'sync',
|
||||
}))
|
||||
document.getElementById('result')!.innerText = JSON.stringify(res)
|
||||
@ -137,7 +141,7 @@ export default class Example extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div id="result" style={{ paddingLeft: 8, paddingBottom: 8 }}/>
|
||||
<div id="result" style={{ paddingLeft: 8, paddingBottom: 8 }} />
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
|
@ -1,81 +1,102 @@
|
||||
[{
|
||||
"num": 500,
|
||||
"time": 0.285,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1000,
|
||||
"time": 0.477,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1500,
|
||||
"time": 0.744,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 2000,
|
||||
"time": 0.964,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 2500,
|
||||
"time": 1.347,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 3000,
|
||||
"time": 1.561,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 3500,
|
||||
"time": 1.831,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 4000,
|
||||
"time": 2.14,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 4500,
|
||||
"time": 2.715,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 5000,
|
||||
"time": 2.848,
|
||||
"type": "sync"
|
||||
},{
|
||||
"num": 500,
|
||||
"time": 0.276,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1000,
|
||||
"time": 0.429,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1500,
|
||||
"time": 0.677,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 2000,
|
||||
"time": 0.897,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 2500,
|
||||
"time": 1.356,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 3000,
|
||||
"time": 1.584,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 3500,
|
||||
"time": 2.045,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 4000,
|
||||
"time": 2.347,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 4500,
|
||||
"time": 2.705,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 5000,
|
||||
"time": 3.072,
|
||||
"type": "async"
|
||||
}]
|
||||
[
|
||||
{
|
||||
"num": 500,
|
||||
"time": 0.285,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1000,
|
||||
"time": 0.477,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1500,
|
||||
"time": 0.744,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 2000,
|
||||
"time": 0.964,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 2500,
|
||||
"time": 1.347,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 3000,
|
||||
"time": 1.561,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 3500,
|
||||
"time": 1.831,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 4000,
|
||||
"time": 2.14,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 4500,
|
||||
"time": 2.715,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 5000,
|
||||
"time": 2.848,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 500,
|
||||
"time": 0.276,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1000,
|
||||
"time": 0.429,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1500,
|
||||
"time": 0.677,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 2000,
|
||||
"time": 0.897,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 2500,
|
||||
"time": 1.356,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 3000,
|
||||
"time": 1.584,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 3500,
|
||||
"time": 2.045,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 4000,
|
||||
"time": 2.347,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 4500,
|
||||
"time": 2.705,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 5000,
|
||||
"time": 3.072,
|
||||
"type": "async"
|
||||
}
|
||||
]
|
||||
|
@ -90,7 +90,11 @@ export default class Example extends React.Component {
|
||||
function output() {
|
||||
const res = Object.keys(result).map((key: string) => ({
|
||||
num: parseInt(key, 10),
|
||||
time: parseFloat((result[key].reduce((pre, cur) => pre + cur, 0) / ITERATIONS).toFixed(3)),
|
||||
time: parseFloat(
|
||||
(result[key].reduce((pre, cur) => pre + cur, 0) / ITERATIONS).toFixed(
|
||||
3,
|
||||
),
|
||||
),
|
||||
type: ASYNC ? 'async' : 'sync',
|
||||
}))
|
||||
document.getElementById('result')!.innerText = JSON.stringify(res)
|
||||
@ -106,7 +110,7 @@ export default class Example extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div id="result" style={{ paddingLeft: 8, paddingBottom: 8 }}/>
|
||||
<div id="result" style={{ paddingLeft: 8, paddingBottom: 8 }} />
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
|
@ -1,81 +1,102 @@
|
||||
[{
|
||||
"num": 500,
|
||||
"time": 0.594,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1000,
|
||||
"time": 1.005,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1500,
|
||||
"time": 1.514,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 2000,
|
||||
"time": 2.014,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 2500,
|
||||
"time": 2.775,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 3000,
|
||||
"time": 3.103,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 3500,
|
||||
"time": 3.689,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 4000,
|
||||
"time": 4.844,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 4500,
|
||||
"time": 4.972,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 5000,
|
||||
"time": 6.49,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 500,
|
||||
"time": 0.546,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1000,
|
||||
"time": 0.934,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1500,
|
||||
"time": 1.37,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 2000,
|
||||
"time": 1.867,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 2500,
|
||||
"time": 2.976,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 3000,
|
||||
"time": 3.687,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 3500,
|
||||
"time": 4.809,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 4000,
|
||||
"time": 5.251,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 4500,
|
||||
"time": 6.628,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 5000,
|
||||
"time": 7.04,
|
||||
"type": "async"
|
||||
}]
|
||||
[
|
||||
{
|
||||
"num": 500,
|
||||
"time": 0.594,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1000,
|
||||
"time": 1.005,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1500,
|
||||
"time": 1.514,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 2000,
|
||||
"time": 2.014,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 2500,
|
||||
"time": 2.775,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 3000,
|
||||
"time": 3.103,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 3500,
|
||||
"time": 3.689,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 4000,
|
||||
"time": 4.844,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 4500,
|
||||
"time": 4.972,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 5000,
|
||||
"time": 6.49,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 500,
|
||||
"time": 0.546,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1000,
|
||||
"time": 0.934,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1500,
|
||||
"time": 1.37,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 2000,
|
||||
"time": 1.867,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 2500,
|
||||
"time": 2.976,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 3000,
|
||||
"time": 3.687,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 3500,
|
||||
"time": 4.809,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 4000,
|
||||
"time": 5.251,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 4500,
|
||||
"time": 6.628,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 5000,
|
||||
"time": 7.04,
|
||||
"type": "async"
|
||||
}
|
||||
]
|
||||
|
@ -156,7 +156,11 @@ export default class Example extends React.Component {
|
||||
function output() {
|
||||
const res = Object.keys(result).map((key: string) => ({
|
||||
num: parseInt(key, 10),
|
||||
time: parseFloat((result[key].reduce((pre, cur) => pre + cur, 0) / ITERATIONS).toFixed(3)),
|
||||
time: parseFloat(
|
||||
(result[key].reduce((pre, cur) => pre + cur, 0) / ITERATIONS).toFixed(
|
||||
3,
|
||||
),
|
||||
),
|
||||
type: ASYNC ? 'async' : 'sync',
|
||||
}))
|
||||
document.getElementById('result')!.innerText = JSON.stringify(res)
|
||||
@ -172,7 +176,7 @@ export default class Example extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div id="result" style={{ paddingLeft: 8, paddingBottom: 8 }}/>
|
||||
<div id="result" style={{ paddingLeft: 8, paddingBottom: 8 }} />
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
|
@ -1,81 +1,102 @@
|
||||
[{
|
||||
"num": 500,
|
||||
"time": 0.232,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1000,
|
||||
"time": 0.344,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1500,
|
||||
"time": 0.565,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 2000,
|
||||
"time": 0.707,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 2500,
|
||||
"time": 0.903,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 3000,
|
||||
"time": 1.147,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 3500,
|
||||
"time": 1.36,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 4000,
|
||||
"time": 1.589,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 4500,
|
||||
"time": 1.848,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 5000,
|
||||
"time": 2.332,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 500,
|
||||
"time": 0.39,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1000,
|
||||
"time": 0.633,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1500,
|
||||
"time": 0.903,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 2000,
|
||||
"time": 1.163,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 2500,
|
||||
"time": 1.831,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 3000,
|
||||
"time": 2.172,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 3500,
|
||||
"time": 2.739,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 4000,
|
||||
"time": 3.073,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 4500,
|
||||
"time": 3.7,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 5000,
|
||||
"time": 4.065,
|
||||
"type": "async"
|
||||
}]
|
||||
[
|
||||
{
|
||||
"num": 500,
|
||||
"time": 0.232,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1000,
|
||||
"time": 0.344,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1500,
|
||||
"time": 0.565,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 2000,
|
||||
"time": 0.707,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 2500,
|
||||
"time": 0.903,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 3000,
|
||||
"time": 1.147,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 3500,
|
||||
"time": 1.36,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 4000,
|
||||
"time": 1.589,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 4500,
|
||||
"time": 1.848,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 5000,
|
||||
"time": 2.332,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 500,
|
||||
"time": 0.39,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1000,
|
||||
"time": 0.633,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1500,
|
||||
"time": 0.903,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 2000,
|
||||
"time": 1.163,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 2500,
|
||||
"time": 1.831,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 3000,
|
||||
"time": 2.172,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 3500,
|
||||
"time": 2.739,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 4000,
|
||||
"time": 3.073,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 4500,
|
||||
"time": 3.7,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 5000,
|
||||
"time": 4.065,
|
||||
"type": "async"
|
||||
}
|
||||
]
|
||||
|
@ -102,7 +102,11 @@ export default class Example extends React.Component {
|
||||
function output() {
|
||||
const res = Object.keys(result).map((key: string) => ({
|
||||
num: parseInt(key, 10),
|
||||
time: parseFloat((result[key].reduce((pre, cur) => pre + cur, 0) / ITERATIONS).toFixed(3)),
|
||||
time: parseFloat(
|
||||
(result[key].reduce((pre, cur) => pre + cur, 0) / ITERATIONS).toFixed(
|
||||
3,
|
||||
),
|
||||
),
|
||||
type: ASYNC ? 'async' : 'sync',
|
||||
}))
|
||||
document.getElementById('result')!.innerText = JSON.stringify(res)
|
||||
@ -118,7 +122,7 @@ export default class Example extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div id="result" style={{ paddingLeft: 8, paddingBottom: 8 }}/>
|
||||
<div id="result" style={{ paddingLeft: 8, paddingBottom: 8 }} />
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
|
@ -1,81 +1,102 @@
|
||||
[{
|
||||
"num": 500,
|
||||
"time": 1.167,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1000,
|
||||
"time": 1.969,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 1500,
|
||||
"time": 2.944,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 2000,
|
||||
"time": 3.886,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 2500,
|
||||
"time": 6.275,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 3000,
|
||||
"time": 7.236,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 3500,
|
||||
"time": 9.368,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 4000,
|
||||
"time": 10.251,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 4500,
|
||||
"time": 12.526,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 5000,
|
||||
"time": 13.472,
|
||||
"type": "async"
|
||||
}, {
|
||||
"num": 500,
|
||||
"time": 0.768,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1000,
|
||||
"time": 1.353,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 1500,
|
||||
"time": 1.951,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 2000,
|
||||
"time": 2.604,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 2500,
|
||||
"time": 3.522,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 3000,
|
||||
"time": 4.03,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 3500,
|
||||
"time": 4.803,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 4000,
|
||||
"time": 6.168,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 4500,
|
||||
"time": 7.369,
|
||||
"type": "sync"
|
||||
}, {
|
||||
"num": 5000,
|
||||
"time": 8.581,
|
||||
"type": "sync"
|
||||
}]
|
||||
[
|
||||
{
|
||||
"num": 500,
|
||||
"time": 1.167,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1000,
|
||||
"time": 1.969,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 1500,
|
||||
"time": 2.944,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 2000,
|
||||
"time": 3.886,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 2500,
|
||||
"time": 6.275,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 3000,
|
||||
"time": 7.236,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 3500,
|
||||
"time": 9.368,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 4000,
|
||||
"time": 10.251,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 4500,
|
||||
"time": 12.526,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 5000,
|
||||
"time": 13.472,
|
||||
"type": "async"
|
||||
},
|
||||
{
|
||||
"num": 500,
|
||||
"time": 0.768,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1000,
|
||||
"time": 1.353,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 1500,
|
||||
"time": 1.951,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 2000,
|
||||
"time": 2.604,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 2500,
|
||||
"time": 3.522,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 3000,
|
||||
"time": 4.03,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 3500,
|
||||
"time": 4.803,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 4000,
|
||||
"time": 6.168,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 4500,
|
||||
"time": 7.369,
|
||||
"type": "sync"
|
||||
},
|
||||
{
|
||||
"num": 5000,
|
||||
"time": 8.581,
|
||||
"type": "sync"
|
||||
}
|
||||
]
|
||||
|
@ -35,48 +35,48 @@ const Node = N.registry.register(
|
||||
position: 'top',
|
||||
attrs: {
|
||||
fo: {
|
||||
width: 10,
|
||||
height: 10,
|
||||
x: -5,
|
||||
y: -5,
|
||||
magnet: 'true',
|
||||
},
|
||||
width: 10,
|
||||
height: 10,
|
||||
x: -5,
|
||||
y: -5,
|
||||
magnet: 'true',
|
||||
},
|
||||
},
|
||||
},
|
||||
right: {
|
||||
position: 'right',
|
||||
attrs: {
|
||||
fo: {
|
||||
width: 10,
|
||||
height: 10,
|
||||
x: -5,
|
||||
y: -5,
|
||||
magnet: 'true',
|
||||
},
|
||||
width: 10,
|
||||
height: 10,
|
||||
x: -5,
|
||||
y: -5,
|
||||
magnet: 'true',
|
||||
},
|
||||
},
|
||||
},
|
||||
bottom: {
|
||||
position: 'bottom',
|
||||
attrs: {
|
||||
fo: {
|
||||
width: 10,
|
||||
height: 10,
|
||||
x: -5,
|
||||
y: -5,
|
||||
magnet: 'true',
|
||||
},
|
||||
width: 10,
|
||||
height: 10,
|
||||
x: -5,
|
||||
y: -5,
|
||||
magnet: 'true',
|
||||
},
|
||||
},
|
||||
},
|
||||
left: {
|
||||
position: 'left',
|
||||
attrs: {
|
||||
fo: {
|
||||
width: 10,
|
||||
height: 10,
|
||||
x: -5,
|
||||
y: -5,
|
||||
magnet: 'true',
|
||||
},
|
||||
width: 10,
|
||||
height: 10,
|
||||
x: -5,
|
||||
y: -5,
|
||||
magnet: 'true',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -114,15 +114,15 @@ export default class Example extends React.Component {
|
||||
const container = selectors && selectors.foContent
|
||||
if (container) {
|
||||
ReactDOM.render(
|
||||
(
|
||||
<div style={{
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
border: '1px solid #808080',
|
||||
borderRadius: '100%',
|
||||
background: '#eee',
|
||||
}} />
|
||||
),
|
||||
}}
|
||||
/>,
|
||||
container as HTMLElement,
|
||||
)
|
||||
}
|
||||
@ -176,7 +176,11 @@ export default class Example extends React.Component {
|
||||
function output() {
|
||||
const res = Object.keys(result).map((key: string) => ({
|
||||
num: parseInt(key, 10),
|
||||
time: parseFloat((result[key].reduce((pre, cur) => pre + cur, 0) / ITERATIONS).toFixed(3)),
|
||||
time: parseFloat(
|
||||
(result[key].reduce((pre, cur) => pre + cur, 0) / ITERATIONS).toFixed(
|
||||
3,
|
||||
),
|
||||
),
|
||||
type: ASYNC ? 'async' : 'sync',
|
||||
}))
|
||||
document.getElementById('result')!.innerText = JSON.stringify(res)
|
||||
@ -192,7 +196,7 @@ export default class Example extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div id="result" style={{ paddingLeft: 8, paddingBottom: 8 }}/>
|
||||
<div id="result" style={{ paddingLeft: 8, paddingBottom: 8 }} />
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
|
@ -1,383 +1,383 @@
|
||||
import React from 'react'
|
||||
import { Graph, Color } from '@antv/x6'
|
||||
import '@antv/x6-react-shape'
|
||||
import { Button } from 'antd'
|
||||
import '../index.less'
|
||||
// import React from 'react'
|
||||
// import { Graph, Color } from '@antv/x6'
|
||||
// import '@antv/x6-react-shape'
|
||||
// import { Button } from 'antd'
|
||||
// import '../index.less'
|
||||
|
||||
Graph.registerNode(
|
||||
'org-node',
|
||||
{
|
||||
width: 260,
|
||||
height: 88,
|
||||
markup: [
|
||||
{
|
||||
tagName: 'rect',
|
||||
attrs: {
|
||||
class: 'card',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'image',
|
||||
attrs: {
|
||||
class: 'image',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
attrs: {
|
||||
class: 'rank',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
attrs: {
|
||||
class: 'name',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'g',
|
||||
attrs: {
|
||||
class: 'btn add',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
tagName: 'circle',
|
||||
attrs: {
|
||||
class: 'add',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
attrs: {
|
||||
class: 'add',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
tagName: 'g',
|
||||
attrs: {
|
||||
class: 'btn del',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
tagName: 'circle',
|
||||
attrs: {
|
||||
class: 'del',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
attrs: {
|
||||
class: 'del',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
'.card': {
|
||||
rx: 10,
|
||||
ry: 10,
|
||||
refWidth: '100%',
|
||||
refHeight: '100%',
|
||||
fill: '#FFF',
|
||||
stroke: '#000',
|
||||
strokeWidth: 0,
|
||||
pointerEvents: 'visiblePainted',
|
||||
},
|
||||
'.image': {
|
||||
x: 16,
|
||||
y: 16,
|
||||
width: 56,
|
||||
height: 56,
|
||||
opacity: 0.7,
|
||||
},
|
||||
'.rank': {
|
||||
refX: 0.95,
|
||||
refY: 0.5,
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: 13,
|
||||
textAnchor: 'end',
|
||||
textVerticalAnchor: 'middle',
|
||||
},
|
||||
'.name': {
|
||||
refX: 0.95,
|
||||
refY: 0.7,
|
||||
fontFamily: 'Arial',
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
textAnchor: 'end',
|
||||
},
|
||||
'.btn.add': {
|
||||
refDx: -16,
|
||||
refY: 16,
|
||||
event: 'node:add',
|
||||
},
|
||||
'.btn.del': {
|
||||
refDx: -44,
|
||||
refY: 16,
|
||||
event: 'node:delete',
|
||||
},
|
||||
'.btn > circle': {
|
||||
r: 10,
|
||||
fill: 'transparent',
|
||||
stroke: '#333',
|
||||
strokeWidth: 1,
|
||||
},
|
||||
'.btn.add > text': {
|
||||
fontSize: 20,
|
||||
fontWeight: 800,
|
||||
stroke: '#000',
|
||||
x: -5.5,
|
||||
y: 7,
|
||||
fontFamily: 'Times New Roman',
|
||||
text: '+',
|
||||
},
|
||||
'.btn.del > text': {
|
||||
fontSize: 28,
|
||||
fontWeight: 500,
|
||||
stroke: '#000',
|
||||
x: -4.5,
|
||||
y: 6,
|
||||
fontFamily: 'Times New Roman',
|
||||
text: '-',
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
)
|
||||
// Graph.registerNode(
|
||||
// 'org-node',
|
||||
// {
|
||||
// width: 260,
|
||||
// height: 88,
|
||||
// markup: [
|
||||
// {
|
||||
// tagName: 'rect',
|
||||
// attrs: {
|
||||
// class: 'card',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// tagName: 'image',
|
||||
// attrs: {
|
||||
// class: 'image',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// attrs: {
|
||||
// class: 'rank',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// attrs: {
|
||||
// class: 'name',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// tagName: 'g',
|
||||
// attrs: {
|
||||
// class: 'btn add',
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// tagName: 'circle',
|
||||
// attrs: {
|
||||
// class: 'add',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// attrs: {
|
||||
// class: 'add',
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// tagName: 'g',
|
||||
// attrs: {
|
||||
// class: 'btn del',
|
||||
// },
|
||||
// children: [
|
||||
// {
|
||||
// tagName: 'circle',
|
||||
// attrs: {
|
||||
// class: 'del',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// attrs: {
|
||||
// class: 'del',
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// attrs: {
|
||||
// '.card': {
|
||||
// rx: 10,
|
||||
// ry: 10,
|
||||
// refWidth: '100%',
|
||||
// refHeight: '100%',
|
||||
// fill: '#FFF',
|
||||
// stroke: '#000',
|
||||
// strokeWidth: 0,
|
||||
// pointerEvents: 'visiblePainted',
|
||||
// },
|
||||
// '.image': {
|
||||
// x: 16,
|
||||
// y: 16,
|
||||
// width: 56,
|
||||
// height: 56,
|
||||
// opacity: 0.7,
|
||||
// },
|
||||
// '.rank': {
|
||||
// refX: 0.95,
|
||||
// refY: 0.5,
|
||||
// fontFamily: 'Courier New',
|
||||
// fontSize: 13,
|
||||
// textAnchor: 'end',
|
||||
// textVerticalAnchor: 'middle',
|
||||
// },
|
||||
// '.name': {
|
||||
// refX: 0.95,
|
||||
// refY: 0.7,
|
||||
// fontFamily: 'Arial',
|
||||
// fontSize: 14,
|
||||
// fontWeight: '600',
|
||||
// textAnchor: 'end',
|
||||
// },
|
||||
// '.btn.add': {
|
||||
// refDx: -16,
|
||||
// refY: 16,
|
||||
// event: 'node:add',
|
||||
// },
|
||||
// '.btn.del': {
|
||||
// refDx: -44,
|
||||
// refY: 16,
|
||||
// event: 'node:delete',
|
||||
// },
|
||||
// '.btn > circle': {
|
||||
// r: 10,
|
||||
// fill: 'transparent',
|
||||
// stroke: '#333',
|
||||
// strokeWidth: 1,
|
||||
// },
|
||||
// '.btn.add > text': {
|
||||
// fontSize: 20,
|
||||
// fontWeight: 800,
|
||||
// stroke: '#000',
|
||||
// x: -5.5,
|
||||
// y: 7,
|
||||
// fontFamily: 'Times New Roman',
|
||||
// text: '+',
|
||||
// },
|
||||
// '.btn.del > text': {
|
||||
// fontSize: 28,
|
||||
// fontWeight: 500,
|
||||
// stroke: '#000',
|
||||
// x: -4.5,
|
||||
// y: 6,
|
||||
// fontFamily: 'Times New Roman',
|
||||
// text: '-',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// true,
|
||||
// )
|
||||
|
||||
Graph.registerReactComponent(
|
||||
'custom',
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
border: '1px solid #1890ff',
|
||||
backgroundColor: 'rgba(227,244,255,.9)',
|
||||
boxShadow: '0 0 3px 3px rgb(64 169 255 / 20%)',
|
||||
borderRadius: '16px',
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<svg
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 16 16"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9.636 1c.133 0 .26.053.355.147l3.362 3.364a.5.5 0 01.147.353V14.5a.5.5 0 01-.5.5H3a.5.5 0 01-.5-.5v-13A.5.5 0 013 1h6.636zM8.42 9.2c-1.032.048-1.572.593-1.621 1.637.039.93.583 1.465 1.48 1.61l.554.753.902-.273-.613-.61.138-.057c.572-.274.752-.869.738-1.423-.026-1.036-.594-1.58-1.578-1.637zm-3.546-.4c-.786.043-1.211.56-1.274 1.125-.021.524.32 1.02.959 1.155.236.04.495.105.692.184.252.101.34.215.33.4-.02.267-.2.416-.534.431-.357.017-.582-.204-.645-.677l-.802.108c.168.76.467 1.259 1.43 1.274.88.013 1.335-.51 1.366-1.166-.01-.37-.114-.642-.471-.862a3.35 3.35 0 00-.818-.324c-.425-.11-.634-.263-.613-.447.02-.205.15-.393.455-.4.303-.007.476.093.644.415l.806-.214C6.264 9.145 5.703 8.78 4.875 8.8zm6.351.4H10.4v3.2h2.4v-.76h-1.574V9.2zm-2.834.705c.448 0 .821.254.842.934-.02.69-.37.901-.842.901-.452 0-.836-.231-.856-.9.03-.67.42-.935.856-.935zm1.014-7.752v2.94h2.94l-2.94-2.94z"
|
||||
fill="#1890FF"
|
||||
fillRule="nonzero"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div>SCQL脚本-1</div>
|
||||
</div>,
|
||||
true,
|
||||
)
|
||||
// Graph.registerReactComponent(
|
||||
// 'custom',
|
||||
// <div
|
||||
// style={{
|
||||
// display: 'flex',
|
||||
// alignItems: 'center',
|
||||
// border: '1px solid #1890ff',
|
||||
// backgroundColor: 'rgba(227,244,255,.9)',
|
||||
// boxShadow: '0 0 3px 3px rgb(64 169 255 / 20%)',
|
||||
// borderRadius: '16px',
|
||||
// }}
|
||||
// >
|
||||
// <div>
|
||||
// <svg
|
||||
// width="1em"
|
||||
// height="1em"
|
||||
// viewBox="0 0 16 16"
|
||||
// xmlns="http://www.w3.org/2000/svg"
|
||||
// >
|
||||
// <path
|
||||
// d="M9.636 1c.133 0 .26.053.355.147l3.362 3.364a.5.5 0 01.147.353V14.5a.5.5 0 01-.5.5H3a.5.5 0 01-.5-.5v-13A.5.5 0 013 1h6.636zM8.42 9.2c-1.032.048-1.572.593-1.621 1.637.039.93.583 1.465 1.48 1.61l.554.753.902-.273-.613-.61.138-.057c.572-.274.752-.869.738-1.423-.026-1.036-.594-1.58-1.578-1.637zm-3.546-.4c-.786.043-1.211.56-1.274 1.125-.021.524.32 1.02.959 1.155.236.04.495.105.692.184.252.101.34.215.33.4-.02.267-.2.416-.534.431-.357.017-.582-.204-.645-.677l-.802.108c.168.76.467 1.259 1.43 1.274.88.013 1.335-.51 1.366-1.166-.01-.37-.114-.642-.471-.862a3.35 3.35 0 00-.818-.324c-.425-.11-.634-.263-.613-.447.02-.205.15-.393.455-.4.303-.007.476.093.644.415l.806-.214C6.264 9.145 5.703 8.78 4.875 8.8zm6.351.4H10.4v3.2h2.4v-.76h-1.574V9.2zm-2.834.705c.448 0 .821.254.842.934-.02.69-.37.901-.842.901-.452 0-.836-.231-.856-.9.03-.67.42-.935.856-.935zm1.014-7.752v2.94h2.94l-2.94-2.94z"
|
||||
// fill="#1890FF"
|
||||
// fillRule="nonzero"
|
||||
// ></path>
|
||||
// </svg>
|
||||
// </div>
|
||||
// <div>SCQL脚本-1</div>
|
||||
// </div>,
|
||||
// true,
|
||||
// )
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
private graph: Graph
|
||||
// export default class Example extends React.Component {
|
||||
// private container: HTMLDivElement
|
||||
// private graph: Graph
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 1600,
|
||||
height: 1000,
|
||||
grid: true,
|
||||
async: false,
|
||||
})
|
||||
this.graph = graph
|
||||
}
|
||||
// componentDidMount() {
|
||||
// const graph = new Graph({
|
||||
// container: this.container,
|
||||
// width: 1600,
|
||||
// height: 1000,
|
||||
// grid: true,
|
||||
// async: false,
|
||||
// })
|
||||
// this.graph = graph
|
||||
// }
|
||||
|
||||
addNodes = () => {
|
||||
const nodes = []
|
||||
for (let i = 0; i < 500; i++) {
|
||||
nodes.push({
|
||||
id: i + '',
|
||||
x: Math.floor(Math.random() * 1600),
|
||||
y: Math.floor(Math.random() * 1000),
|
||||
shape: 'org-node',
|
||||
attrs: {
|
||||
'.card': { fill: Color.randomHex() },
|
||||
'.image': {
|
||||
xlinkHref:
|
||||
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*kUy8SrEDp6YAAAAAAAAAAAAAARQnAQ',
|
||||
},
|
||||
'.rank': {
|
||||
fill: '#31d0c6',
|
||||
text: `${i}`,
|
||||
},
|
||||
'.name': {
|
||||
fill: '#000',
|
||||
text: `${i}`,
|
||||
},
|
||||
'.btn > circle': { stroke: '#000' },
|
||||
'.btn > text': { fill: '#000', stroke: '#000' },
|
||||
},
|
||||
})
|
||||
}
|
||||
const start = performance.now()
|
||||
this.graph.addNodes(nodes)
|
||||
console.log('addNodes', performance.now() - start)
|
||||
}
|
||||
// addNodes = () => {
|
||||
// const nodes = []
|
||||
// for (let i = 0; i < 500; i++) {
|
||||
// nodes.push({
|
||||
// id: i + '',
|
||||
// x: Math.floor(Math.random() * 1600),
|
||||
// y: Math.floor(Math.random() * 1000),
|
||||
// shape: 'org-node',
|
||||
// attrs: {
|
||||
// '.card': { fill: Color.randomHex() },
|
||||
// '.image': {
|
||||
// xlinkHref:
|
||||
// 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*kUy8SrEDp6YAAAAAAAAAAAAAARQnAQ',
|
||||
// },
|
||||
// '.rank': {
|
||||
// fill: '#31d0c6',
|
||||
// text: `${i}`,
|
||||
// },
|
||||
// '.name': {
|
||||
// fill: '#000',
|
||||
// text: `${i}`,
|
||||
// },
|
||||
// '.btn > circle': { stroke: '#000' },
|
||||
// '.btn > text': { fill: '#000', stroke: '#000' },
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// const start = performance.now()
|
||||
// this.graph.addNodes(nodes)
|
||||
// console.log('addNodes', performance.now() - start)
|
||||
// }
|
||||
|
||||
addEdges = () => {
|
||||
const edges = []
|
||||
for (let i = 0; i < 500; i++) {
|
||||
edges.push({
|
||||
source: Math.floor(Math.random() * 500) + '',
|
||||
target: Math.floor(Math.random() * 500) + '',
|
||||
})
|
||||
}
|
||||
const start = performance.now()
|
||||
this.graph.addEdges(edges)
|
||||
console.log('addEdges', performance.now() - start)
|
||||
}
|
||||
// addEdges = () => {
|
||||
// const edges = []
|
||||
// for (let i = 0; i < 500; i++) {
|
||||
// edges.push({
|
||||
// source: Math.floor(Math.random() * 500) + '',
|
||||
// target: Math.floor(Math.random() * 500) + '',
|
||||
// })
|
||||
// }
|
||||
// const start = performance.now()
|
||||
// this.graph.addEdges(edges)
|
||||
// console.log('addEdges', performance.now() - start)
|
||||
// }
|
||||
|
||||
addNodesAndEdges = () => {
|
||||
this.addNodes()
|
||||
this.addEdges()
|
||||
}
|
||||
// addNodesAndEdges = () => {
|
||||
// this.addNodes()
|
||||
// this.addEdges()
|
||||
// }
|
||||
|
||||
addNodesWithPorts = () => {
|
||||
const nodes = []
|
||||
for (let i = 0; i < 500; i++) {
|
||||
nodes.push({
|
||||
id: i + '',
|
||||
x: Math.floor(Math.random() * 1600),
|
||||
y: Math.floor(Math.random() * 1000),
|
||||
shape: 'org-node',
|
||||
attrs: {
|
||||
'.card': { fill: '#31d0c6' },
|
||||
'.image': {
|
||||
xlinkHref:
|
||||
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*kUy8SrEDp6YAAAAAAAAAAAAAARQnAQ',
|
||||
},
|
||||
'.rank': {
|
||||
fill: '#31d0c6',
|
||||
text: '123',
|
||||
},
|
||||
'.name': {
|
||||
fill: '#000',
|
||||
text: 'abc',
|
||||
},
|
||||
'.btn > circle': { stroke: '#000' },
|
||||
'.btn > text': { fill: '#000', stroke: '#000' },
|
||||
},
|
||||
ports: {
|
||||
groups: {
|
||||
top: {
|
||||
position: 'top',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
right: {
|
||||
position: 'right',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
bottom: {
|
||||
position: 'bottom',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
left: {
|
||||
position: 'left',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
items: [
|
||||
{
|
||||
group: 'top',
|
||||
id: i + `_port_top`,
|
||||
},
|
||||
{
|
||||
group: 'right',
|
||||
id: i + `_port_right`,
|
||||
},
|
||||
{
|
||||
group: 'bottom',
|
||||
id: i + `_port_bottom`,
|
||||
},
|
||||
{
|
||||
group: 'left',
|
||||
id: i + `_port_left`,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
}
|
||||
const start = performance.now()
|
||||
this.graph.addNodes(nodes)
|
||||
console.log('addNodesWithPorts', performance.now() - start)
|
||||
}
|
||||
// addNodesWithPorts = () => {
|
||||
// const nodes = []
|
||||
// for (let i = 0; i < 500; i++) {
|
||||
// nodes.push({
|
||||
// id: i + '',
|
||||
// x: Math.floor(Math.random() * 1600),
|
||||
// y: Math.floor(Math.random() * 1000),
|
||||
// shape: 'org-node',
|
||||
// attrs: {
|
||||
// '.card': { fill: '#31d0c6' },
|
||||
// '.image': {
|
||||
// xlinkHref:
|
||||
// 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*kUy8SrEDp6YAAAAAAAAAAAAAARQnAQ',
|
||||
// },
|
||||
// '.rank': {
|
||||
// fill: '#31d0c6',
|
||||
// text: '123',
|
||||
// },
|
||||
// '.name': {
|
||||
// fill: '#000',
|
||||
// text: 'abc',
|
||||
// },
|
||||
// '.btn > circle': { stroke: '#000' },
|
||||
// '.btn > text': { fill: '#000', stroke: '#000' },
|
||||
// },
|
||||
// ports: {
|
||||
// groups: {
|
||||
// top: {
|
||||
// position: 'top',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 6,
|
||||
// magnet: true,
|
||||
// stroke: '#31d0c6',
|
||||
// strokeWidth: 2,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// right: {
|
||||
// position: 'right',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 6,
|
||||
// magnet: true,
|
||||
// stroke: '#31d0c6',
|
||||
// strokeWidth: 2,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// bottom: {
|
||||
// position: 'bottom',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 6,
|
||||
// magnet: true,
|
||||
// stroke: '#31d0c6',
|
||||
// strokeWidth: 2,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// left: {
|
||||
// position: 'left',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 6,
|
||||
// magnet: true,
|
||||
// stroke: '#31d0c6',
|
||||
// strokeWidth: 2,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// items: [
|
||||
// {
|
||||
// group: 'top',
|
||||
// id: i + `_port_top`,
|
||||
// },
|
||||
// {
|
||||
// group: 'right',
|
||||
// id: i + `_port_right`,
|
||||
// },
|
||||
// {
|
||||
// group: 'bottom',
|
||||
// id: i + `_port_bottom`,
|
||||
// },
|
||||
// {
|
||||
// group: 'left',
|
||||
// id: i + `_port_left`,
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// const start = performance.now()
|
||||
// this.graph.addNodes(nodes)
|
||||
// console.log('addNodesWithPorts', performance.now() - start)
|
||||
// }
|
||||
|
||||
addReactNodes = () => {
|
||||
const nodes = []
|
||||
for (let i = 0; i < 500; i++) {
|
||||
nodes.push({
|
||||
id: i + '',
|
||||
x: Math.floor(Math.random() * 1600),
|
||||
y: Math.floor(Math.random() * 1000),
|
||||
shape: 'react-shape',
|
||||
component: 'custom',
|
||||
width: 160,
|
||||
height: 30,
|
||||
})
|
||||
}
|
||||
const start = performance.now()
|
||||
this.graph.addNodes(nodes)
|
||||
console.log('addReactNodes', performance.now() - start)
|
||||
}
|
||||
// addReactNodes = () => {
|
||||
// const nodes = []
|
||||
// for (let i = 0; i < 500; i++) {
|
||||
// nodes.push({
|
||||
// id: i + '',
|
||||
// x: Math.floor(Math.random() * 1600),
|
||||
// y: Math.floor(Math.random() * 1000),
|
||||
// shape: 'react-shape',
|
||||
// component: 'custom',
|
||||
// width: 160,
|
||||
// height: 30,
|
||||
// })
|
||||
// }
|
||||
// const start = performance.now()
|
||||
// this.graph.addNodes(nodes)
|
||||
// console.log('addReactNodes', performance.now() - start)
|
||||
// }
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
// refContainer = (container: HTMLDivElement) => {
|
||||
// this.container = container
|
||||
// }
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
<Button onClick={this.addNodes}>addNodes</Button>
|
||||
<Button onClick={this.addEdges}>addEdges</Button>
|
||||
<Button onClick={this.addNodesAndEdges}>addNodesAndEdges</Button>
|
||||
<Button onClick={this.addNodesWithPorts}>addNodesWithPorts</Button>
|
||||
<Button onClick={this.addReactNodes}>addReactNodes</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
// render() {
|
||||
// return (
|
||||
// <div className="x6-graph-wrap">
|
||||
// <div ref={this.refContainer} className="x6-graph" />
|
||||
// <Button onClick={this.addNodes}>addNodes</Button>
|
||||
// <Button onClick={this.addEdges}>addEdges</Button>
|
||||
// <Button onClick={this.addNodesAndEdges}>addNodesAndEdges</Button>
|
||||
// <Button onClick={this.addNodesWithPorts}>addNodesWithPorts</Button>
|
||||
// <Button onClick={this.addReactNodes}>addReactNodes</Button>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
77
examples/x6-example-features/src/pages/react/extends.tsx
Normal file
77
examples/x6-example-features/src/pages/react/extends.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node } from '@antv/x6-next'
|
||||
import { ReactShape, register } from '@antv/x6-react-shape'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
|
||||
class GroupNode extends ReactShape {
|
||||
isGroup() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
Graph.registerNode('group-node', GroupNode, true)
|
||||
|
||||
const NodeComponent = ({ node }: { node: Node }) => {
|
||||
const data = node.getData()
|
||||
|
||||
return (
|
||||
<div className="react-algo-node">
|
||||
<img
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/d9f3b597-3a2e-49c3-8469-64a1168ed779.svg"
|
||||
alt=""
|
||||
/>
|
||||
<span>{data.name}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
register(NodeComponent, {
|
||||
shape: 'algo-node-3',
|
||||
width: 144,
|
||||
height: 28,
|
||||
effect: ['data'],
|
||||
inherit: 'group-node',
|
||||
})
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
private count = 0
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
})
|
||||
|
||||
const node = graph.createNode({
|
||||
shape: 'algo-node-3',
|
||||
x: 80,
|
||||
y: 80,
|
||||
data: {
|
||||
name: '逻辑回归',
|
||||
},
|
||||
})
|
||||
|
||||
console.log(node.isGroup())
|
||||
|
||||
const update = () => {
|
||||
node.setData({ name: `逻辑回归 ${(this.count += 1)}` })
|
||||
setTimeout(update, 1000)
|
||||
}
|
||||
|
||||
update()
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
27
examples/x6-example-features/src/pages/react/index.less
Normal file
27
examples/x6-example-features/src/pages/react/index.less
Normal file
@ -0,0 +1,27 @@
|
||||
.react-algo-node {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #5f95ff;
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-left: 4px;
|
||||
font-size: 12px;
|
||||
color: #000000a6;
|
||||
}
|
||||
|
||||
&.dark {
|
||||
background-color: #141414;
|
||||
|
||||
span {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +1,33 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node, Color } from '@antv/x6'
|
||||
import '@antv/x6-react-shape'
|
||||
import { Graph, Node } from '@antv/x6-next'
|
||||
import { register } from '@antv/x6-react-shape'
|
||||
import '../index.less'
|
||||
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
|
||||
}
|
||||
}
|
||||
const NodeComponent = ({ node }: { node: Node }) => {
|
||||
const data = node.getData()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
render() {
|
||||
const color = Color.randomHex()
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
color: Color.invert(color, true),
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
textAlign: 'center',
|
||||
lineHeight: '60px',
|
||||
borderRadius: 30,
|
||||
background: color,
|
||||
}}
|
||||
>
|
||||
{this.props.text}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div className="react-algo-node">
|
||||
<img
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/d9f3b597-3a2e-49c3-8469-64a1168ed779.svg"
|
||||
alt=""
|
||||
/>
|
||||
<span>{data.name}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
register(NodeComponent, {
|
||||
shape: 'algo-node-1',
|
||||
width: 144,
|
||||
height: 28,
|
||||
effect: ['data'],
|
||||
})
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
private count = 0
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
@ -45,60 +36,21 @@ export default class Example extends React.Component {
|
||||
height: 600,
|
||||
})
|
||||
|
||||
const source = graph.addNode({
|
||||
shape: 'react-shape',
|
||||
primer: 'circle',
|
||||
const node = graph.addNode({
|
||||
shape: 'algo-node-1',
|
||||
x: 80,
|
||||
y: 80,
|
||||
width: 60,
|
||||
height: 60,
|
||||
data: {},
|
||||
xxx: {},
|
||||
component: <MyComponent text="Source" />,
|
||||
})
|
||||
|
||||
const target = graph.addNode({
|
||||
shape: 'react-shape',
|
||||
x: 320,
|
||||
y: 320,
|
||||
width: 120,
|
||||
height: 48,
|
||||
component: (node) => {
|
||||
return (
|
||||
<div style={{ lineHeight: '48px', textAlign: 'center' }}>
|
||||
{node.attr('body/fill')}
|
||||
</div>
|
||||
)
|
||||
data: {
|
||||
name: '逻辑回归',
|
||||
},
|
||||
// component: () => <Test text="target" />,
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
shape: 'react-shape',
|
||||
primer: 'circle',
|
||||
x: 80,
|
||||
y: 320,
|
||||
width: 60,
|
||||
height: 60,
|
||||
useForeignObject: false,
|
||||
component: () => {
|
||||
return <circle stroke="red" cx="30" cy="30" r="30"/>
|
||||
},
|
||||
})
|
||||
|
||||
graph.addEdge({
|
||||
source,
|
||||
target,
|
||||
})
|
||||
|
||||
const update = () => {
|
||||
target.prop('attrs/body/fill', Color.randomHex())
|
||||
node.setData({ name: `逻辑回归 ${(this.count += 1)}` })
|
||||
setTimeout(update, 1000)
|
||||
}
|
||||
|
||||
update()
|
||||
|
||||
console.log(graph.toJSON())
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
|
@ -1,42 +1,41 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node, Color } from '@antv/x6'
|
||||
import { Portal } from '@antv/x6-react-shape'
|
||||
import React, { useContext } from 'react'
|
||||
import { Graph } from '@antv/x6-next'
|
||||
import { register, Portal } from '@antv/x6-react-shape'
|
||||
import { Button } from 'antd'
|
||||
import '../index.less'
|
||||
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
|
||||
}
|
||||
}
|
||||
const X6ReactPortalProvider = Portal.getProvider() // 注意,一个 graph 只能申明一个 portal provider
|
||||
const ThemeContext = React.createContext('light')
|
||||
|
||||
return false
|
||||
}
|
||||
const NodeComponent = () => {
|
||||
const theme = useContext(ThemeContext)
|
||||
|
||||
render() {
|
||||
const color = Color.randomHex()
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
color: Color.invert(color, true),
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
textAlign: 'center',
|
||||
lineHeight: '60px',
|
||||
background: color,
|
||||
}}
|
||||
>
|
||||
{this.props.text}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div className={`react-algo-node ${theme === 'light' ? 'light' : 'dark'}`}>
|
||||
<img
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/d9f3b597-3a2e-49c3-8469-64a1168ed779.svg"
|
||||
alt=""
|
||||
/>
|
||||
<span>逻辑回归</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
register(NodeComponent, {
|
||||
shape: 'algo-node-2',
|
||||
width: 144,
|
||||
height: 28,
|
||||
effect: [],
|
||||
})
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
state = {
|
||||
theme: 'light',
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
@ -44,42 +43,20 @@ export default class Example extends React.Component {
|
||||
height: 600,
|
||||
})
|
||||
|
||||
const source = graph.addNode({
|
||||
shape: 'react-shape',
|
||||
graph.addNode({
|
||||
shape: 'algo-node-2',
|
||||
x: 80,
|
||||
y: 80,
|
||||
width: 160,
|
||||
height: 60,
|
||||
data: {},
|
||||
xxx: {},
|
||||
component: <MyComponent text="Source" />,
|
||||
})
|
||||
|
||||
const target = graph.addNode({
|
||||
shape: 'react-shape',
|
||||
x: 320,
|
||||
y: 320,
|
||||
width: 160,
|
||||
height: 60,
|
||||
component: (node) => {
|
||||
return <div>{node.attr('body/fill')}</div>
|
||||
data: {
|
||||
name: '逻辑回归',
|
||||
},
|
||||
// component: () => <Test text="target" />,
|
||||
})
|
||||
}
|
||||
|
||||
graph.addEdge({
|
||||
source,
|
||||
target,
|
||||
changeTheme = () => {
|
||||
this.setState({
|
||||
theme: this.state.theme === 'light' ? 'dark' : 'light',
|
||||
})
|
||||
|
||||
const update = () => {
|
||||
target.prop('attrs/body/fill', Color.randomHex())
|
||||
setTimeout(update, 1000)
|
||||
}
|
||||
|
||||
update()
|
||||
|
||||
console.log(graph.toJSON())
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
@ -87,10 +64,16 @@ export default class Example extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const X6ReactPortalProvider = Portal.getProvider()
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<X6ReactPortalProvider />
|
||||
<ThemeContext.Provider value={this.state.theme}>
|
||||
<X6ReactPortalProvider />
|
||||
</ThemeContext.Provider>
|
||||
<div className="x6-graph-tools">
|
||||
<Button onClick={this.changeTheme}>
|
||||
{this.state.theme === 'light' ? 'Light' : 'Dark'}
|
||||
</Button>
|
||||
</div>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
|
@ -191,6 +191,7 @@ export default class Example extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Example {
|
||||
export interface Props {}
|
||||
|
||||
|
71
examples/x6-example-features/src/pages/scroller/test.tsx
Normal file
71
examples/x6-example-features/src/pages/scroller/test.tsx
Normal file
@ -0,0 +1,71 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6-next'
|
||||
import { Scroller } from '@antv/x6-plugin-scroller'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private graph: Graph
|
||||
private graphContainer: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.graphContainer,
|
||||
width: 800,
|
||||
height: 500,
|
||||
background: {
|
||||
color: '#f5f5f5',
|
||||
},
|
||||
grid: {
|
||||
visible: true,
|
||||
},
|
||||
mousewheel: {
|
||||
enabled: true,
|
||||
// fixed: false,
|
||||
modifiers: ['ctrl', 'meta'],
|
||||
minScale: 0.5,
|
||||
maxScale: 2,
|
||||
},
|
||||
})
|
||||
|
||||
graph.use(
|
||||
new Scroller({
|
||||
enabled: true,
|
||||
// width: 600,
|
||||
// height: 400,
|
||||
pageVisible: true,
|
||||
pageBreak: true,
|
||||
pannable: {
|
||||
enabled: true,
|
||||
eventTypes: ['leftMouseDown', 'rightMouseDown'],
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
graph.addNode({
|
||||
shape: 'rect',
|
||||
x: 300,
|
||||
y: 300,
|
||||
width: 90,
|
||||
height: 60,
|
||||
attrs: {
|
||||
rect: { fill: '#31D0C6', stroke: '#4B4A67', 'stroke-width': 2 },
|
||||
text: { text: 'rect', fill: 'white' },
|
||||
},
|
||||
ports: [{}],
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.graphContainer = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<h1>Scroller</h1>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ export default class Example extends React.Component {
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
const target = graph.addNode({
|
||||
shape: 'rect',
|
||||
x: 320,
|
||||
@ -41,7 +41,7 @@ export default class Example extends React.Component {
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
graph.addEdge({
|
||||
source,
|
||||
target,
|
||||
@ -51,33 +51,32 @@ export default class Example extends React.Component {
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
graph.on('selection:changed', (args: {
|
||||
added: Cell[],
|
||||
removed: Cell[],
|
||||
selected: Cell[],
|
||||
}) => {
|
||||
args.added.forEach((cell: Cell) => {
|
||||
if (cell.isNode()) {
|
||||
cell.attr('body', {
|
||||
fill: '#ffd591',
|
||||
stroke: '#ffa940',
|
||||
})
|
||||
} else {
|
||||
cell.attr('line/stroke', '#ffa940')
|
||||
}
|
||||
})
|
||||
args.removed.forEach((cell: Cell) => {
|
||||
if (cell.isNode()) {
|
||||
cell.attr('body', {
|
||||
fill: '#f5f5f5',
|
||||
stroke: '#d9d9d9',
|
||||
})
|
||||
} else {
|
||||
cell.attr('line/stroke', '#d9d9d9')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
graph.on(
|
||||
'selection:changed',
|
||||
(args: { added: Cell[]; removed: Cell[]; selected: Cell[] }) => {
|
||||
args.added.forEach((cell: Cell) => {
|
||||
if (cell.isNode()) {
|
||||
cell.attr('body', {
|
||||
fill: '#ffd591',
|
||||
stroke: '#ffa940',
|
||||
})
|
||||
} else {
|
||||
cell.attr('line/stroke', '#ffa940')
|
||||
}
|
||||
})
|
||||
args.removed.forEach((cell: Cell) => {
|
||||
if (cell.isNode()) {
|
||||
cell.attr('body', {
|
||||
fill: '#f5f5f5',
|
||||
stroke: '#d9d9d9',
|
||||
})
|
||||
} else {
|
||||
cell.attr('line/stroke', '#d9d9d9')
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
|
@ -86,8 +86,7 @@ export default class Example extends React.Component {
|
||||
width: 40,
|
||||
height: 40,
|
||||
label: 'path',
|
||||
d:
|
||||
'M25.979,12.896 19.312,12.896 19.312,6.229 12.647,6.229 12.647,12.896 5.979,12.896 5.979,19.562 12.647,19.562 12.647,26.229 19.312,26.229 19.312,19.562 25.979,19.562z',
|
||||
d: 'M25.979,12.896 19.312,12.896 19.312,6.229 12.647,6.229 12.647,12.896 5.979,12.896 5.979,19.562 12.647,19.562 12.647,26.229 19.312,26.229 19.312,19.562 25.979,19.562z',
|
||||
})
|
||||
|
||||
console.log(path)
|
||||
|
@ -1,139 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Graph as GraphES } from '@antv/x6/lib'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: {
|
||||
visible: true,
|
||||
type: 'doubleMesh',
|
||||
args: [
|
||||
{
|
||||
color: '#eee', // 主网格线颜色
|
||||
thickness: 1, // 主网格线宽度
|
||||
},
|
||||
{
|
||||
color: '#ddd', // 次网格线颜色
|
||||
thickness: 1, // 次网格线宽度
|
||||
factor: 4, // 主次网格线间隔
|
||||
},
|
||||
],
|
||||
},
|
||||
// background: {
|
||||
// color: '#fcfcfc',
|
||||
// image:
|
||||
// 'https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg',
|
||||
// opacity: 0.2,
|
||||
// repeat: 'watermark',
|
||||
// angle: 30,
|
||||
// },
|
||||
panning: true,
|
||||
})
|
||||
|
||||
console.log(graph)
|
||||
console.log(Object.prototype.toString.call(graph))
|
||||
console.log(GraphES.isGraph(graph))
|
||||
|
||||
// const data = [
|
||||
// {
|
||||
// id: 'node1',
|
||||
// shape: 'rect',
|
||||
// x: 100,
|
||||
// y: 100,
|
||||
// width: 80,
|
||||
// height: 40,
|
||||
// label: 'hello',
|
||||
// },
|
||||
// {
|
||||
// id: 'node2',
|
||||
// shape: 'rect',
|
||||
// x: 240,
|
||||
// y: 300,
|
||||
// width: 80,
|
||||
// height: 40,
|
||||
// label: 'world',
|
||||
// },
|
||||
// {
|
||||
// shape: 'edge',
|
||||
// source: 'node1',
|
||||
// target: 'node2',
|
||||
// },
|
||||
// ]
|
||||
|
||||
const data = {
|
||||
// 节点
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
shape: 'rect',
|
||||
x: 120,
|
||||
y: 100,
|
||||
width: 80,
|
||||
height: 40,
|
||||
label: 'Hello',
|
||||
attrs: {
|
||||
body: {
|
||||
strokeWidth: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'node2',
|
||||
x: 120,
|
||||
y: 240,
|
||||
width: 80,
|
||||
height: 40,
|
||||
label: 'World',
|
||||
attrs: {
|
||||
body: {
|
||||
strokeWidth: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
// 边
|
||||
edges: [
|
||||
{
|
||||
source: 'node1',
|
||||
target: 'node2',
|
||||
attrs: {
|
||||
line: {
|
||||
sourceMarker: 'classic',
|
||||
targetMarker: 'classic',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
graph.fromJSON(data)
|
||||
// console.log(graph.toJSON())
|
||||
// graph.scaleContentToFit()
|
||||
|
||||
const node = graph.getCellById('node2')
|
||||
node.transition('attrs/body/strokeWidth', 10, {
|
||||
duration: 3000,
|
||||
complete() {},
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,15 +1,6 @@
|
||||
import React from 'react'
|
||||
import { Graph, Markup, ObjectExt, Dom } from '@antv/x6'
|
||||
import '../index.less'
|
||||
`
|
||||
<foreignObject width="160" height="60">
|
||||
<body style="width: 100%; height: 100%; background: transparent;">
|
||||
<div style="width: 100%; height: 100%;">
|
||||
<div>#C969F1</div>
|
||||
</div>
|
||||
</body>
|
||||
</foreignObject>
|
||||
`
|
||||
|
||||
Graph.registerNode('xml-node', {}, true)
|
||||
|
||||
|
@ -135,6 +135,7 @@ export class Component extends React.Component<Component.Props> {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Component {
|
||||
export interface Props {
|
||||
node?: Node
|
@ -6,7 +6,7 @@ import { generateData, parsePorts } from './data'
|
||||
import { getPortsDefinition } from './port'
|
||||
import { Component } from './component'
|
||||
import './view'
|
||||
import '../../index.less'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
@ -31,7 +31,7 @@ class ContextMenuTool extends ToolsView.ToolItem<
|
||||
trigger={['contextMenu']}
|
||||
overlay={this.options.menu}
|
||||
>
|
||||
<a />
|
||||
<a href="#" />
|
||||
</Dropdown>,
|
||||
this.knob,
|
||||
)
|
||||
|
@ -17,18 +17,20 @@ class TooltipTool extends ToolsView.ToolItem<EdgeView, TooltipToolOptions> {
|
||||
}
|
||||
|
||||
private toggleTooltip(visible: boolean) {
|
||||
ReactDom.unmountComponentAtNode(this.knob)
|
||||
if (visible) {
|
||||
ReactDom.render(
|
||||
<Tooltip
|
||||
title={this.options.tooltip}
|
||||
visible={true}
|
||||
destroyTooltipOnHide
|
||||
>
|
||||
<div />
|
||||
</Tooltip>,
|
||||
this.knob,
|
||||
)
|
||||
if (this.knob) {
|
||||
ReactDom.unmountComponentAtNode(this.knob)
|
||||
if (visible) {
|
||||
ReactDom.render(
|
||||
<Tooltip
|
||||
title={this.options.tooltip}
|
||||
visible={true}
|
||||
destroyTooltipOnHide
|
||||
>
|
||||
<div />
|
||||
</Tooltip>,
|
||||
this.knob,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +71,7 @@ class TooltipTool extends ToolsView.ToolItem<EdgeView, TooltipToolOptions> {
|
||||
}
|
||||
|
||||
protected onRemove() {
|
||||
this.toggleTooltip(false)
|
||||
this.cellView.off('cell:mouseenter', this.onMosueEnter, this)
|
||||
this.cellView.off('cell:mouseleave', this.onMouseLeave, this)
|
||||
this.cellView.off('cell:mousemove', this.onMouseMove, this)
|
||||
|
@ -56,7 +56,7 @@ export class Universe extends Model {
|
||||
for (var i = 0, n = subgraph.length; i < n; i++) {
|
||||
var cell = subgraph[i]
|
||||
if (cell.isEdge()) {
|
||||
(cell as Connection).highlight()
|
||||
;(cell as Connection).highlight()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,7 +67,7 @@ export class Universe extends Model {
|
||||
for (var i = 0, n = subgraph.length; i < n; i++) {
|
||||
var cell = subgraph[i]
|
||||
if (cell.isEdge()) {
|
||||
(cell as Connection).unhighlight()
|
||||
;(cell as Connection).unhighlight()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ export default class Example extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Example {
|
||||
export interface Props {}
|
||||
|
||||
|
84
examples/x6-example-features/src/pages/v2/clock.tsx
Normal file
84
examples/x6-example-features/src/pages/v2/clock.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import React, { createRef, PureComponent } from 'react'
|
||||
import './index.less'
|
||||
|
||||
const SPEED = 0.003 / Math.PI
|
||||
const FRAMES = 10
|
||||
|
||||
export default class Clock extends PureComponent {
|
||||
faceRef = createRef<SVGCircleElement>()
|
||||
arcGroupRef = createRef<SVGGElement>()
|
||||
clockHandRef = createRef<SVGPathElement>()
|
||||
frame: number = 0
|
||||
rotation = 0
|
||||
t0 = Date.now()
|
||||
arcs: { rotation: number; td: number }[] = []
|
||||
|
||||
animate = () => {
|
||||
const now = Date.now()
|
||||
const td = now - this.t0
|
||||
this.rotation = (this.rotation + SPEED * td) % (2 * Math.PI)
|
||||
this.t0 = now
|
||||
|
||||
this.arcs.push({ rotation: this.rotation, td })
|
||||
|
||||
let lx = 0
|
||||
let ly = 0
|
||||
let tx = 0
|
||||
let ty = 0
|
||||
if (this.arcs.length > FRAMES) {
|
||||
this.arcs.forEach(({ rotation, td }, i) => {
|
||||
lx = tx
|
||||
ly = ty
|
||||
const r = 145
|
||||
tx = 155 + r * Math.cos(rotation)
|
||||
ty = 155 + r * Math.sin(rotation)
|
||||
const bigArc = SPEED * td < Math.PI ? '0' : '1'
|
||||
const path = `M${tx} ${ty}A${r} ${r} 0 ${bigArc} 0 ${lx} ${ly}L155 155`
|
||||
const hue = 120 - Math.min(120, td / 4)
|
||||
const colour = `hsl(${hue}, 100%, ${60 - i * (30 / FRAMES)}%)`
|
||||
if (i !== 0) {
|
||||
const arcEl = this.arcGroupRef.current!.children[i - 1]
|
||||
arcEl.setAttribute('d', path)
|
||||
arcEl.setAttribute('fill', colour)
|
||||
}
|
||||
})
|
||||
this.clockHandRef.current!.setAttribute('d', `M155 155L${tx} ${ty}`)
|
||||
this.arcs.shift()
|
||||
}
|
||||
|
||||
this.frame = requestAnimationFrame(this.animate)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.frame = requestAnimationFrame(this.animate)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.frame) {
|
||||
cancelAnimationFrame(this.frame)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const paths = new Array(FRAMES)
|
||||
for (let i = 0; i < FRAMES; i++) {
|
||||
paths.push(<path className="arcHand" key={i} />)
|
||||
}
|
||||
return (
|
||||
<div className="stutterer">
|
||||
<svg height="310" width="310">
|
||||
<circle
|
||||
className="clockFace"
|
||||
cx={155}
|
||||
cy={155}
|
||||
r={150}
|
||||
ref={this.faceRef}
|
||||
fill="hsla(0, 0%, 5%, 0.95)"
|
||||
/>
|
||||
<g ref={this.arcGroupRef}>{paths}</g>
|
||||
<path className="clockHand" ref={this.clockHandRef} />
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
93008
examples/x6-example-features/src/pages/v2/data.ts
Normal file
93008
examples/x6-example-features/src/pages/v2/data.ts
Normal file
File diff suppressed because it is too large
Load Diff
153
examples/x6-example-features/src/pages/v2/graph-v1.tsx
Normal file
153
examples/x6-example-features/src/pages/v2/graph-v1.tsx
Normal file
@ -0,0 +1,153 @@
|
||||
import React from 'react'
|
||||
import { Graph, Path } from '@antv/x6'
|
||||
import data from './data'
|
||||
|
||||
Graph.registerConnector(
|
||||
'algo-connector',
|
||||
(s, e) => {
|
||||
const offset = 4
|
||||
const deltaY = Math.abs(e.y - s.y)
|
||||
const control = Math.floor((deltaY / 3) * 2)
|
||||
|
||||
const v1 = { x: s.x, y: s.y + offset + control }
|
||||
const v2 = { x: e.x, y: e.y - offset - control }
|
||||
|
||||
return Path.normalize(
|
||||
`M ${s.x} ${s.y}
|
||||
L ${s.x} ${s.y + offset}
|
||||
C ${v1.x} ${v1.y} ${v2.x} ${v2.y} ${e.x} ${e.y - offset}
|
||||
L ${e.x} ${e.y}
|
||||
`,
|
||||
)
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
Graph.registerNode(
|
||||
'perf-node',
|
||||
{
|
||||
width: 144,
|
||||
height: 28,
|
||||
markup: [
|
||||
{
|
||||
tagName: 'rect',
|
||||
},
|
||||
{
|
||||
tagName: 'image',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
rect: {
|
||||
rx: 14,
|
||||
ry: 14,
|
||||
refWidth: '100%',
|
||||
refHeight: '100%',
|
||||
fill: '#FFF',
|
||||
stroke: '#5f95ff',
|
||||
strokeWidth: 1,
|
||||
},
|
||||
image: {
|
||||
x: 2,
|
||||
y: 2,
|
||||
width: 24,
|
||||
height: 24,
|
||||
xlinkHref:
|
||||
'https://gw.alipayobjects.com/zos/bmw-prod/d9f3b597-3a2e-49c3-8469-64a1168ed779.svg',
|
||||
},
|
||||
// text: {
|
||||
// textWrap: {
|
||||
// text: 'abcdefghijklmnopqrstnvwxyzhadfsadfsda23333333333dasdasda',
|
||||
// width: 30, // 宽度减少 10px
|
||||
// height: 60,
|
||||
// ellipsis: true, // 文本超出显示范围时,自动添加省略号
|
||||
// breakWord: false
|
||||
// }
|
||||
// }
|
||||
text: {
|
||||
x: 28,
|
||||
y: 18,
|
||||
text: '深度学习',
|
||||
fontSize: 12,
|
||||
fill: '#000000a6',
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
interface Props {
|
||||
enableTextWrap: boolean
|
||||
length: number
|
||||
}
|
||||
|
||||
export default class Canvas extends React.Component<Props> {
|
||||
private container: HTMLDivElement
|
||||
private graph: Graph
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: false,
|
||||
connecting: {
|
||||
connector: 'algo-connector',
|
||||
connectionPoint: 'anchor',
|
||||
anchor: 'center',
|
||||
},
|
||||
mousewheel: true,
|
||||
panning: true,
|
||||
})
|
||||
this.graph = graph
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
if (prevProps.length !== this.props.length) {
|
||||
this.draw(this.props.length)
|
||||
}
|
||||
}
|
||||
|
||||
draw(length: number) {
|
||||
const cells: any[] = []
|
||||
if (this.props.enableTextWrap) {
|
||||
data.nodes.forEach((node: any) => {
|
||||
node.attrs = {
|
||||
text: {
|
||||
x: 28,
|
||||
y: 18,
|
||||
fontSize: 12,
|
||||
fill: '#000000a6',
|
||||
textWrap: {
|
||||
text: '深度学习',
|
||||
width: 40,
|
||||
height: 20,
|
||||
ellipsis: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
if (length > 10) {
|
||||
cells.push(...data.nodes)
|
||||
cells.push(...data.edges.slice(0, 100 * (length - 10)))
|
||||
} else {
|
||||
cells.push(...data.nodes.slice(0, 100 * length))
|
||||
}
|
||||
this.graph.fromJSON(cells)
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
161
examples/x6-example-features/src/pages/v2/graph-v2.tsx
Normal file
161
examples/x6-example-features/src/pages/v2/graph-v2.tsx
Normal file
@ -0,0 +1,161 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6-next'
|
||||
import { Path } from '@antv/x6-geometry'
|
||||
import data from './data'
|
||||
|
||||
Graph.registerConnector(
|
||||
'algo-connector',
|
||||
(s, e) => {
|
||||
const offset = 4
|
||||
const deltaY = Math.abs(e.y - s.y)
|
||||
const control = Math.floor((deltaY / 3) * 2)
|
||||
|
||||
const v1 = { x: s.x, y: s.y + offset + control }
|
||||
const v2 = { x: e.x, y: e.y - offset - control }
|
||||
|
||||
return Path.normalize(
|
||||
`M ${s.x} ${s.y}
|
||||
L ${s.x} ${s.y + offset}
|
||||
C ${v1.x} ${v1.y} ${v2.x} ${v2.y} ${e.x} ${e.y - offset}
|
||||
L ${e.x} ${e.y}
|
||||
`,
|
||||
)
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
Graph.registerNode(
|
||||
'perf-node',
|
||||
{
|
||||
width: 144,
|
||||
height: 28,
|
||||
markup: [
|
||||
{
|
||||
tagName: 'rect',
|
||||
},
|
||||
{
|
||||
tagName: 'image',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
rect: {
|
||||
rx: 14,
|
||||
ry: 14,
|
||||
refWidth: '100%',
|
||||
refHeight: '100%',
|
||||
fill: '#FFF',
|
||||
stroke: '#5f95ff',
|
||||
strokeWidth: 1,
|
||||
},
|
||||
image: {
|
||||
x: 2,
|
||||
y: 2,
|
||||
width: 24,
|
||||
height: 24,
|
||||
xlinkHref:
|
||||
'https://gw.alipayobjects.com/zos/bmw-prod/d9f3b597-3a2e-49c3-8469-64a1168ed779.svg',
|
||||
},
|
||||
// text: {
|
||||
// textWrap: {
|
||||
// text: 'abcdefghijklmnopqrstnvwxyzhadfsadfsda23333333333dasdasda',
|
||||
// width: 30, // 宽度减少 10px
|
||||
// height: 60,
|
||||
// ellipsis: true, // 文本超出显示范围时,自动添加省略号
|
||||
// breakWord: false
|
||||
// }
|
||||
// }
|
||||
text: {
|
||||
x: 28,
|
||||
y: 18,
|
||||
text: '深度学习',
|
||||
fontSize: 12,
|
||||
fill: '#000000a6',
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
interface Props {
|
||||
enableTextWrap: boolean
|
||||
enableVirtualRender: boolean
|
||||
length: number
|
||||
}
|
||||
|
||||
export default class Canvas extends React.Component<Props> {
|
||||
private container: HTMLDivElement
|
||||
private graph: Graph
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: false,
|
||||
connecting: {
|
||||
connector: 'algo-connector',
|
||||
connectionPoint: 'anchor',
|
||||
anchor: 'center',
|
||||
},
|
||||
mousewheel: true,
|
||||
panning: true,
|
||||
})
|
||||
this.graph = graph
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
if (this.props.enableVirtualRender) {
|
||||
this.graph.enableVirtualRender()
|
||||
} else {
|
||||
this.graph.disableVirtualRender()
|
||||
}
|
||||
|
||||
if (prevProps.length !== this.props.length) {
|
||||
this.draw(this.props.length)
|
||||
}
|
||||
}
|
||||
|
||||
draw(length: number) {
|
||||
const cells: any[] = []
|
||||
if (this.props.enableTextWrap) {
|
||||
data.nodes.forEach((node: any) => {
|
||||
node.attrs = {
|
||||
text: {
|
||||
x: 28,
|
||||
y: 18,
|
||||
fontSize: 12,
|
||||
fill: '#000000a6',
|
||||
textWrap: {
|
||||
text: '深度学习',
|
||||
width: 40,
|
||||
height: 20,
|
||||
ellipsis: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
if (length > 10) {
|
||||
cells.push(...data.nodes)
|
||||
cells.push(...data.edges.slice(0, 100 * (length - 10)))
|
||||
} else {
|
||||
cells.push(...data.nodes.slice(0, 100 * length))
|
||||
}
|
||||
this.graph.fromJSON(cells)
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
61
examples/x6-example-features/src/pages/v2/index.less
Normal file
61
examples/x6-example-features/src/pages/v2/index.less
Normal file
@ -0,0 +1,61 @@
|
||||
.tools {
|
||||
width: 800px;
|
||||
margin: 32px auto;
|
||||
.ant-input {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.react-node {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #5f95ff;
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
span {
|
||||
margin-left: 4px;
|
||||
font-size: 12px;
|
||||
color: #000000a6;
|
||||
}
|
||||
}
|
||||
|
||||
.stutterer {
|
||||
transform: scale(1.5);
|
||||
height: 310px;
|
||||
width: 310px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 200px;
|
||||
}
|
||||
|
||||
.clockHand {
|
||||
stroke: white;
|
||||
stroke-width: 10px;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
.clockFace {
|
||||
stroke: white;
|
||||
stroke-width: 10px;
|
||||
}
|
||||
|
||||
.innerLine {
|
||||
border-radius: 6px;
|
||||
position: absolute;
|
||||
height: 149px;
|
||||
left: 47.5%;
|
||||
top: 0%;
|
||||
width: 5%;
|
||||
background-color: red;
|
||||
transform-origin: bottom center;
|
||||
}
|
58
examples/x6-example-features/src/pages/v2/index.tsx
Normal file
58
examples/x6-example-features/src/pages/v2/index.tsx
Normal file
@ -0,0 +1,58 @@
|
||||
import React, { useState } from 'react'
|
||||
import GraphV1 from './graph-v1'
|
||||
import GraphV2 from './graph-v2'
|
||||
import Clock from './clock'
|
||||
import { Input, Radio, Checkbox } from 'antd'
|
||||
import './index.less'
|
||||
|
||||
export default () => {
|
||||
const [value, setValue] = useState('')
|
||||
const [version, setVersion] = useState('v1')
|
||||
const [enableTextWrap, setEnableTextWrap] = useState(false)
|
||||
const [enableVirtualRender, setEnableVirtualRender] = useState(false)
|
||||
|
||||
const onChangeVersion = (val: string) => {
|
||||
setValue('')
|
||||
setVersion(val)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={'tools'}>
|
||||
<Input
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
maxLength={20}
|
||||
/>
|
||||
<p>
|
||||
{value.length > 10
|
||||
? `1000 节点 ${(value.length - 10) * 100} 边`
|
||||
: `${value.length * 100} 节点`}
|
||||
</p>
|
||||
<Radio.Group
|
||||
onChange={(e) => onChangeVersion(e.target.value)}
|
||||
value={version}
|
||||
>
|
||||
<Radio value={'v1'}>V1</Radio>
|
||||
<Radio value={'v2'}>V2</Radio>
|
||||
</Radio.Group>
|
||||
<Checkbox onChange={(e) => setEnableTextWrap(e.target.checked)}>
|
||||
文本截断
|
||||
</Checkbox>
|
||||
<Checkbox onChange={(e) => setEnableVirtualRender(e.target.checked)}>
|
||||
可视区域渲染
|
||||
</Checkbox>
|
||||
</div>
|
||||
{version === 'v1' ? (
|
||||
<GraphV1 enableTextWrap={enableTextWrap} length={value.length} />
|
||||
) : (
|
||||
<GraphV2
|
||||
enableTextWrap={enableTextWrap}
|
||||
enableVirtualRender={enableVirtualRender}
|
||||
length={value.length}
|
||||
/>
|
||||
)}
|
||||
<Clock />
|
||||
</div>
|
||||
)
|
||||
}
|
166
examples/x6-example-features/src/pages/v2/react.tsx
Normal file
166
examples/x6-example-features/src/pages/v2/react.tsx
Normal file
@ -0,0 +1,166 @@
|
||||
// import React from 'react'
|
||||
// import { Graph } from '@antv/x6-next'
|
||||
// import { Path } from '@antv/x6-geometry'
|
||||
// import data from './data'
|
||||
// import './index.less'
|
||||
// import { register } from '@antv/x6-react-shape'
|
||||
|
||||
// Graph.registerConnector(
|
||||
// 'algo-connector',
|
||||
// (s, e) => {
|
||||
// const offset = 4
|
||||
// const deltaY = Math.abs(e.y - s.y)
|
||||
// const control = Math.floor((deltaY / 3) * 2)
|
||||
|
||||
// const v1 = { x: s.x, y: s.y + offset + control }
|
||||
// const v2 = { x: e.x, y: e.y - offset - control }
|
||||
|
||||
// return Path.normalize(
|
||||
// `M ${s.x} ${s.y}
|
||||
// L ${s.x} ${s.y + offset}
|
||||
// C ${v1.x} ${v1.y} ${v2.x} ${v2.y} ${e.x} ${e.y - offset}
|
||||
// L ${e.x} ${e.y}
|
||||
// `,
|
||||
// )
|
||||
// },
|
||||
// true,
|
||||
// )
|
||||
|
||||
// const NodeComponent = () => {
|
||||
// return (
|
||||
// <div className="react-node">
|
||||
// <img
|
||||
// src="https://gw.alipayobjects.com/zos/bmw-prod/d9f3b597-3a2e-49c3-8469-64a1168ed779.svg"
|
||||
// alt=""
|
||||
// />
|
||||
// <span>深度学习</span>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
|
||||
// register(NodeComponent, {
|
||||
// shape: 'perf-node',
|
||||
// width: 144,
|
||||
// height: 28,
|
||||
// effect: ['width'],
|
||||
// })
|
||||
|
||||
// export default class Canvas extends React.Component {
|
||||
// private container: HTMLDivElement
|
||||
// private graph: Graph
|
||||
|
||||
// componentDidMount() {
|
||||
// const graph = new Graph({
|
||||
// container: this.container,
|
||||
// width: 800,
|
||||
// height: 600,
|
||||
// grid: false,
|
||||
// connecting: {
|
||||
// connector: 'algo-connector',
|
||||
// connectionPoint: 'anchor',
|
||||
// anchor: 'center',
|
||||
// },
|
||||
// })
|
||||
// this.graph = graph
|
||||
// document.getElementById('add-btn')?.addEventListener('click', () => {
|
||||
// this.add()
|
||||
// })
|
||||
// }
|
||||
|
||||
// add = () => {
|
||||
// data.nodes.forEach((node: any, i) => {
|
||||
// node.ports = {
|
||||
// groups: {
|
||||
// top: {
|
||||
// position: 'top',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 4,
|
||||
// magnet: true,
|
||||
// stroke: 'gray',
|
||||
// strokeWidth: 1,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// right: {
|
||||
// position: 'right',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 4,
|
||||
// magnet: true,
|
||||
// stroke: 'gray',
|
||||
// strokeWidth: 1,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// bottom: {
|
||||
// position: 'bottom',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 4,
|
||||
// magnet: true,
|
||||
// stroke: 'gray',
|
||||
// strokeWidth: 1,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// left: {
|
||||
// position: 'left',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 4,
|
||||
// magnet: true,
|
||||
// stroke: 'gray',
|
||||
// strokeWidth: 1,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// items: [
|
||||
// {
|
||||
// group: 'top',
|
||||
// id: i + `_port_top`,
|
||||
// },
|
||||
// {
|
||||
// group: 'right',
|
||||
// id: i + `_port_right`,
|
||||
// },
|
||||
// {
|
||||
// group: 'bottom',
|
||||
// id: i + `_port_bottom`,
|
||||
// },
|
||||
// {
|
||||
// group: 'left',
|
||||
// id: i + `_port_left`,
|
||||
// },
|
||||
// ],
|
||||
// }
|
||||
// })
|
||||
// data.edges.forEach((edge: any) => {
|
||||
// edge.attrs = {
|
||||
// line: {
|
||||
// stroke: '#c5c5c5',
|
||||
// strokeWidth: 1,
|
||||
// },
|
||||
// }
|
||||
// })
|
||||
// this.graph.fromJSON(data)
|
||||
// }
|
||||
|
||||
// refContainer = (container: HTMLDivElement) => {
|
||||
// this.container = container
|
||||
// }
|
||||
|
||||
// render() {
|
||||
// return (
|
||||
// <div className="x6-graph-wrap">
|
||||
// <div ref={this.refContainer} className="x6-graph" />
|
||||
// <button id="add-btn">add</button>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
@ -1,33 +0,0 @@
|
||||
import React from 'react'
|
||||
import { SVG } from '@antv/x6-vector'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const svg = new SVG()
|
||||
const rect = svg.rect(100, 100).node
|
||||
svg.appendTo(this.container)
|
||||
rect.animate(
|
||||
[{ fill: '#000000' }, { fill: '#0000FF' }, { fill: '#00FFFF' }],
|
||||
{
|
||||
duration: 3000,
|
||||
iterations: Infinity,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<h1>Default Settings</h1>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
import { version } from '@antv/x6-vector'
|
||||
|
||||
console.log(version)
|
@ -17,9 +17,7 @@
|
||||
"strictPropertyInitialization": false,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
lerna.json
11
lerna.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "independent",
|
||||
"version": "2.0.6-beta.0",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
@ -24,5 +24,12 @@
|
||||
"pr(refactor)": ":100: Refactoring",
|
||||
"pr(test)": ":white_check_mark: Test Case"
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages": [
|
||||
"packages/x6-common",
|
||||
"packages/x6-geometry",
|
||||
"packages/x6-next",
|
||||
"packages/x6-react-shape",
|
||||
"packages/x6-vue-shape"
|
||||
]
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user