Compare commits
75 Commits
@antv/x6-s
...
@antv/x6-c
Author | SHA1 | Date | |
---|---|---|---|
c510756fe4 | |||
9b4fa86daa | |||
7e86ba90d6 | |||
f27bec6bb8 | |||
c38006a358 | |||
5f2783aade | |||
fba531064a | |||
04656f33f4 | |||
441dd564b4 | |||
9ccda3e96f | |||
979b2556e9 | |||
153013a606 | |||
2c7b966f45 | |||
b199153f3b | |||
608ce9ac6c | |||
eb921f7018 | |||
68e7132213 | |||
62aa5323ce | |||
e380cba7d9 | |||
8fada570e4 | |||
1096bf171b | |||
1834cd2143 | |||
1cf9cb654f | |||
b392d78856 | |||
58c0fe459c | |||
8a510fa8f8 | |||
668c93242f | |||
c122b2122c | |||
3b9957efbb | |||
1f83a2b8a8 | |||
6699c2bd00 | |||
7192209a5c | |||
5da5575451 | |||
3377049a49 | |||
4e76734cee | |||
3a59703f1c | |||
45218c36f6 | |||
17b36e21c7 | |||
1682a1d953 | |||
bcf3380d2b | |||
24368d4f86 | |||
3265fe5b98 | |||
5599286473 | |||
d64150bfad | |||
cae8625feb | |||
d8f1729f09 | |||
20c170b44a | |||
0e8769642a | |||
bd30f7f61d | |||
e3e7cfc66f | |||
c86ed1a031 | |||
ae179eb2cd | |||
2a3e523b1b | |||
b5af7844af | |||
9c48ad8dfc | |||
1a5f1655df | |||
90dad14d7e | |||
323e01559d | |||
bfc8d7f17a | |||
df24392728 | |||
fc940fa53c | |||
604c848c2a | |||
7b091f35de | |||
95c72c3033 | |||
0c91218b64 | |||
61c030a162 | |||
5c5f3e5319 | |||
06a8f28c2d | |||
ece198265b | |||
6abd0683ea | |||
fff95806c8 | |||
a069449782 | |||
3b25683529 | |||
45337e4a62 | |||
91fc97791b |
.github/workflows
CONTRIBUTORSCONTRIBUTORS.svgREADME.mdexamples/x6-example-features
packages
x6-common
x6-plugin-clipboard/src
x6-plugin-dnd
x6-plugin-history
x6-plugin-keyboard
x6-plugin-scroller
x6-plugin-selection/src
x6-plugin-snapline/src
x6-plugin-transform/src
x6-react-components
x6
sites/x6-sites
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@ -15,7 +15,8 @@ jobs:
|
||||
steps:
|
||||
- name: ⤵️ Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: 🎉 Setup nodejs
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
|
2
.github/workflows/welcome.yml
vendored
2
.github/workflows/welcome.yml
vendored
@ -20,9 +20,7 @@ jobs:
|
||||
👋 @{{ author }}
|
||||
|
||||
Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it.
|
||||
|
||||
To help make it easier for us to investigate your issue, please follow the [contributing guidelines](https://github.com/antvis/X6/blob/master/CONTRIBUTING.md).
|
||||
|
||||
We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
|
||||
|
||||
FIRST_PR: |
|
||||
|
35
CONTRIBUTORS
35
CONTRIBUTORS
@ -1,7 +1,7 @@
|
||||
BARM <284942955@qq.com>
|
||||
Candy <563378816@qq.com>
|
||||
Chaoqi <HAN>
|
||||
Clifford <ajard>
|
||||
Chaoqi ZHANG <prncoprs@163.com>
|
||||
Clifford Fajardo <cliffordfajardo@users.noreply.github.com>
|
||||
DaiGang <42136433+daigang666@users.noreply.github.com>
|
||||
Dong <48054715+halodong@users.noreply.github.com>
|
||||
Draco <Draco.coder@gmail.com>
|
||||
@ -10,13 +10,13 @@ Eve-Sama <948832626@qq.com>
|
||||
Gossypol <31892817+gossypol@users.noreply.github.com>
|
||||
ImgBotApp <ImgBotHelp@gmail.com>
|
||||
Indomi <indomi126@gmail.com>
|
||||
James <san>
|
||||
Jógvan <lse>
|
||||
Ken <ei>
|
||||
Kent <oo>
|
||||
James Tsang <wtzeng1@gmail.com>
|
||||
Jógvan Olsen <jogvanolsen@hotmail.com>
|
||||
Ken Geis <geis.ken@gmail.com>
|
||||
Kent Wood <minzojian@hotmail.com>
|
||||
Limbo <49612796+JUST-Limbo@users.noreply.github.com>
|
||||
Lixu <37231473+wflixu@users.noreply.github.com>
|
||||
Lloyd <ho>
|
||||
Lloyd Zhou <lloydzhou@users.noreply.github.com>
|
||||
Lyn <47809781+lyn-boyu@users.noreply.github.com>
|
||||
MOMO <329053928@qq.com>
|
||||
Mingfei <az8641683@163.com>
|
||||
@ -26,17 +26,22 @@ NewByVector <NewByVector@users.noreply.github.com>
|
||||
Olive.Wang <olivewind.wang@gmail.com>
|
||||
Opportunity <opportunity@live.in>
|
||||
Questions <chip@twostewards.com>
|
||||
RuiLin <on>
|
||||
RuiLin Dong <48054715+halodong@users.noreply.github.com>
|
||||
SSC <273702440@qq.com>
|
||||
Simon <>
|
||||
Samuel Bodin <1637651+bodinsamuel@users.noreply.github.com>
|
||||
Simon He <57086651+Simon-He95@users.noreply.github.com>
|
||||
Sindori <441933726@qq.com>
|
||||
Struggle <1178825961@qq.com>
|
||||
Struggle Roue <47975400+struggleRoue@users.noreply.github.com>
|
||||
Susan <527971893@qq.com>
|
||||
Thomas <eugne>
|
||||
Tony <>
|
||||
Thomas Zeugner <tomsoftware@gmx.de>
|
||||
Tony Wu <93302820+tonywu6@users.noreply.github.com>
|
||||
Utopia <greatauk11@gmail.com>
|
||||
XLZY <1017866168@qq.com>
|
||||
Xingjian <han>
|
||||
Zhenyu <o>
|
||||
Xia Wenqi <xiawenqi90@gmail.com>
|
||||
Xingjian Zhang <44231913+THUzxj@users.noreply.github.com>
|
||||
Zhenyu Hou <skyking_H@hotmail.com>
|
||||
_XiaoTian <istianlei@qq.com>
|
||||
arthur657834 <kingkom7834@126.com>
|
||||
boyu.zlj <boyu.zlj@antgroup.com>
|
||||
breezefaith <nyzhangzc@qq.com>
|
||||
@ -67,10 +72,11 @@ qingchi <qinky94@163.com>
|
||||
qu <33251372+Qujh97@users.noreply.github.com>
|
||||
sallen450 <qinghua10199@gmail.com>
|
||||
semantic-release-bot <semantic-release-bot@martynus.net>
|
||||
siaikin <abc1310054026@outlook.com>
|
||||
vector <vectorse@126.com>
|
||||
wenbei <38773084+wb-wenbei@users.noreply.github.com>
|
||||
wgf <34190465+evelope@users.noreply.github.com>
|
||||
wind <>
|
||||
wind X <35559153+XueMeijing@users.noreply.github.com>
|
||||
wjqsummer <52412389+wjqsummer@users.noreply.github.com>
|
||||
wtzeng1 <wtzeng1@gmail.com>
|
||||
x6-bot <x6-bot@users.noreply.github.com>
|
||||
@ -85,6 +91,7 @@ zdc1111 <39116292+zdc1111@users.noreply.github.com>
|
||||
小耀 <jinyue.gjy@antfin.com>
|
||||
崖 <bubkoo.wy@gmail.com>
|
||||
崖崖崖 <bubkoo.wy@gmail.com>
|
||||
张子睿 <411489774@qq.com>
|
||||
文瑀 <wenyu.jqq@antfin.com>
|
||||
映月 <38279397+orientMoon@users.noreply.github.com>
|
||||
杨凌 <89915256@qq.com>
|
||||
|
138
CONTRIBUTORS.svg
138
CONTRIBUTORS.svg
File diff suppressed because one or more lines are too long
Before (image error) Size: 12 MiB After (image error) Size: 13 MiB |
17
README.md
17
README.md
@ -6,18 +6,17 @@
|
||||
<p align="center"><strong>提供简单易用的节点定制能力和开箱即用的交互组件,方便我们快速搭建流程图、DAG 图、ER 图等图应用</strong></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/antvis/X6/actions/workflows/ci.yml"><img alt="build" src="https://img.shields.io/github/actions/workflow/status/antvis/x6/ci.yml?branch=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> -->
|
||||
<a href="https://lgtm.com/projects/g/antvis/x6/context:javascript"><img alt="Language grade: JavaScript" src="https://img.shields.io/lgtm/grade/javascript/g/antvis/x6.svg?logo=lgtm&style=flat-square"></a>
|
||||
<a href="https://www.npmjs.com/package/@antv/x6"><img alt="NPM Package" src="https://img.shields.io/npm/v/@antv/x6.svg?style=flat-square"></a>
|
||||
<a href="https://www.npmjs.com/package/@antv/x6"><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/@antv/x6?logo=npm&style=flat-square"></a>
|
||||
<a href="https://github.com/antvis/X6/actions/workflows/ci.yml"><img alt="build" src="https://img.shields.io/github/actions/workflow/status/antvis/x6/ci.yml?branch=master&style=for-the-badge&logo=github"></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=for-the-badge&token=15CO54WYUV"></a> -->
|
||||
<a href="https://www.npmjs.com/package/@antv/x6"><img alt="NPM Package" src="https://img.shields.io/npm/v/@antv/x6.svg?logo=npm&style=for-the-badge"></a>
|
||||
<a href="https://www.npmjs.com/package/@antv/x6"><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/@antv/x6?logo=npm&style=for-the-badge"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="/LICENSE"><img src="https://img.shields.io/github/license/antvis/x6?style=flat-square" alt="MIT License"></a>
|
||||
<a href="https://www.typescriptlang.org"><img alt="Language" src="https://img.shields.io/badge/language-TypeScript-blue.svg?style=flat-square"></a>
|
||||
<a href="https://github.com/antvis/x6/pulls"><img alt="PRs Welcome" src="https://img.shields.io/badge/PRs-Welcome-brightgreen.svg?style=flat-square"></a>
|
||||
<a href="https://x6.antv.antgroup.com"><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>
|
||||
<a href="/LICENSE"><img src="https://img.shields.io/github/license/antvis/x6?style=for-the-badge" alt="MIT License"></a>
|
||||
<a href="https://www.typescriptlang.org"><img alt="Language" src="https://img.shields.io/badge/language-TypeScript-blue.svg?style=for-the-badge"></a>
|
||||
<a href="https://github.com/antvis/x6/pulls"><img alt="PRs Welcome" src="https://img.shields.io/badge/PRs-Welcome-brightgreen.svg?style=for-the-badge"></a>
|
||||
<a href="https://x6.antv.antgroup.com"><img alt="website" src="https://img.shields.io/static/v1?label=&labelColor=505050&message=website&color=0076D6&style=for-the-badge&logo=google-chrome&logoColor=f5f5f5"></a>
|
||||
</p>
|
||||
|
||||
## 特性
|
||||
|
@ -1,3 +1,17 @@
|
||||
# @antv/x6-example-features [2.1.0](https://github.com/antvis/X6/compare/@antv/x6-example-features@2.0.3...@antv/x6-example-features@2.1.0) (2023-02-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* history add max stack size ([#3253](https://github.com/antvis/X6/issues/3253)) ([fba5310](https://github.com/antvis/X6/commit/fba531064ad8027c451a81b60d5efd7f7314a0fa))
|
||||
|
||||
## @antv/x6-example-features [2.0.2](https://github.com/antvis/X6/compare/@antv/x6-example-features@2.0.1...@antv/x6-example-features@2.0.2) (2023-01-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **mindmap demo:** can not find target id when create edge ([#3144](https://github.com/antvis/X6/issues/3144)) ([bfc8d7f](https://github.com/antvis/X6/commit/bfc8d7f17ac900f70b696c1fa7a3f3f3a389103f))
|
||||
|
||||
## @antv/x6-example-features [2.0.1](https://github.com/antvis/X6/compare/@antv/x6-example-features@2.0.0...@antv/x6-example-features@2.0.1) (2022-12-16)
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@antv/x6-example-features",
|
||||
"version": "2.0.1",
|
||||
"version": "2.1.0",
|
||||
"scripts": {
|
||||
"start": "umi dev",
|
||||
"build": "umi build",
|
||||
|
@ -212,12 +212,15 @@ export default class Example extends React.Component {
|
||||
return 'right'
|
||||
},
|
||||
})
|
||||
const cells: Cell[] = []
|
||||
const traverse = (hierarchyItem: HierarchyResult) => {
|
||||
if (hierarchyItem) {
|
||||
const { data, children } = hierarchyItem
|
||||
cells.push(
|
||||
graph.createNode({
|
||||
// 检查当前遍历的节点已经存在还是需要新添加?
|
||||
if (graph.hasCell(data.id)) {
|
||||
const node = graph.getCellById(data.id)
|
||||
node.prop('position', { x: hierarchyItem.x, y: hierarchyItem.y })
|
||||
} else {
|
||||
const node = graph.addNode({
|
||||
id: data.id,
|
||||
shape: data.type === 'topic-child' ? 'topic-child' : 'topic',
|
||||
x: hierarchyItem.x,
|
||||
@ -226,13 +229,18 @@ export default class Example extends React.Component {
|
||||
height: data.height,
|
||||
label: data.label,
|
||||
type: data.type,
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
if (children) {
|
||||
children.forEach((item: HierarchyResult) => {
|
||||
const { id, data } = item
|
||||
cells.push(
|
||||
graph.createEdge({
|
||||
// 先遍历子节点(里面包含创建逻辑,如果画布没有开启async的时候,创建边会提示找不到target节点)
|
||||
traverse(item)
|
||||
const eid = `${hierarchyItem.id}-->${id}`
|
||||
// 检查当前边是否已经存在
|
||||
if (!graph.hasCell(eid)) {
|
||||
graph.addEdge({
|
||||
id: eid,
|
||||
shape: 'mindmap-edge',
|
||||
source: {
|
||||
cell: hierarchyItem.id,
|
||||
@ -257,15 +265,13 @@ export default class Example extends React.Component {
|
||||
name: 'left',
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
traverse(item)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
traverse(result)
|
||||
graph.resetCells(cells)
|
||||
graph.centerContent()
|
||||
}
|
||||
|
||||
@ -303,9 +309,14 @@ export default class Example extends React.Component {
|
||||
if (dataItem) {
|
||||
let item: MindMapData | null = null
|
||||
const length = dataItem.children ? dataItem.children.length : 0
|
||||
let nid = `${id}-${length + 1}`
|
||||
if (graph.hasCell(nid)) {
|
||||
// 如果通过length + 1拼接出来的节点id在画布中存在了,就在id后面加上随机数
|
||||
nid = nid + Math.random()
|
||||
}
|
||||
if (type === 'topic') {
|
||||
item = {
|
||||
id: `${id}-${length + 1}`,
|
||||
id: nid,
|
||||
type: 'topic-branch',
|
||||
label: `分支主题${length + 1}`,
|
||||
width: 100,
|
||||
@ -313,7 +324,7 @@ export default class Example extends React.Component {
|
||||
}
|
||||
} else if (type === 'topic-branch') {
|
||||
item = {
|
||||
id: `${id}-${length + 1}`,
|
||||
id: nid,
|
||||
type: 'topic-child',
|
||||
label: `子主题${length + 1}`,
|
||||
width: 60,
|
||||
@ -334,10 +345,16 @@ export default class Example extends React.Component {
|
||||
|
||||
const removeNode = (id: string) => {
|
||||
const res = findItem(data, id)
|
||||
const dataItem = res?.parent
|
||||
if (dataItem && dataItem.children) {
|
||||
const { children } = dataItem
|
||||
const parentItem = res?.parent
|
||||
const nodeItem = res?.node
|
||||
if (parentItem && parentItem.children) {
|
||||
const { children } = parentItem
|
||||
const index = children.findIndex((item) => item.id === id)
|
||||
// 删除的时候,先删节点以及可能存在的子节点,再调用render,对data数据进行遍历
|
||||
if (nodeItem && nodeItem.children) {
|
||||
nodeItem.children.forEach((item) => graph.removeCell(item.id))
|
||||
}
|
||||
graph.removeCell(id)
|
||||
return children.splice(index, 1)
|
||||
}
|
||||
return null
|
||||
|
104
examples/x6-example-features/src/pages/history/index.tsx
Normal file
104
examples/x6-example-features/src/pages/history/index.tsx
Normal file
@ -0,0 +1,104 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Keyboard } from '@antv/x6-plugin-keyboard'
|
||||
import { Selection } from '@antv/x6-plugin-selection'
|
||||
import { History } from '@antv/x6-plugin-history'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component<
|
||||
{},
|
||||
{ graph: Graph | undefined }
|
||||
> {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
})
|
||||
|
||||
this.setState({ graph })
|
||||
|
||||
const selection = new Selection({ enabled: true })
|
||||
const keyboard = new Keyboard({ enabled: true })
|
||||
const history = new History({ enabled: true, stackSize: 5 })
|
||||
|
||||
graph.use(selection)
|
||||
graph.use(keyboard)
|
||||
graph.use(history)
|
||||
|
||||
graph.addNode({
|
||||
x: 50,
|
||||
y: 50,
|
||||
width: 100,
|
||||
height: 40,
|
||||
attrs: { label: { text: 'A' } },
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
x: 250,
|
||||
y: 50,
|
||||
width: 100,
|
||||
height: 40,
|
||||
attrs: { label: { text: 'B' } },
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
x: 350,
|
||||
y: 150,
|
||||
width: 100,
|
||||
height: 40,
|
||||
attrs: { label: { text: 'C' } },
|
||||
})
|
||||
|
||||
keyboard.bindKey('backspace', () => {
|
||||
graph.removeCells(selection.getSelectedCells())
|
||||
})
|
||||
keyboard.bindKey('command+z', () => {
|
||||
this.undo()
|
||||
})
|
||||
keyboard.bindKey('command+shift+z', () => {
|
||||
this.redo()
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
enablePlugins = () => {
|
||||
const { graph } = this.state
|
||||
graph?.enablePlugins('keyboard')
|
||||
}
|
||||
|
||||
disablePlugins = () => {
|
||||
const { graph } = this.state
|
||||
graph?.disablePlugins('keyboard')
|
||||
}
|
||||
|
||||
undo = () => {
|
||||
const { graph } = this.state
|
||||
const history = graph?.getPlugin('history') as History
|
||||
history?.undo()
|
||||
}
|
||||
|
||||
redo = () => {
|
||||
const { graph } = this.state
|
||||
const history = graph?.getPlugin('history') as History
|
||||
history?.redo()
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
<button onClick={this.enablePlugins}>enable</button>
|
||||
<button onClick={this.disablePlugins}>disable</button>
|
||||
<button onClick={this.undo}>undo</button>
|
||||
<button onClick={this.redo}>redo</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -179,6 +179,10 @@ const dataSource = [
|
||||
example: 'animation/transition',
|
||||
description: '动画',
|
||||
},
|
||||
{
|
||||
example: 'history',
|
||||
description: '时光回溯',
|
||||
},
|
||||
].map((item, index) => ({ key: index, ...item }))
|
||||
|
||||
const columns = [
|
||||
|
@ -4,7 +4,10 @@ import { Keyboard } from '@antv/x6-plugin-keyboard'
|
||||
import { Selection } from '@antv/x6-plugin-selection'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
export default class Example extends React.Component<
|
||||
{},
|
||||
{ graph: Graph | undefined }
|
||||
> {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
@ -15,6 +18,8 @@ export default class Example extends React.Component {
|
||||
grid: true,
|
||||
})
|
||||
|
||||
this.setState({ graph })
|
||||
|
||||
const selection = new Selection({ enabled: true })
|
||||
const keyboard = new Keyboard({ enabled: true })
|
||||
graph.use(selection)
|
||||
@ -53,10 +58,22 @@ export default class Example extends React.Component {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
enablePlugins = () => {
|
||||
const { graph } = this.state
|
||||
graph.enablePlugins('keyboard')
|
||||
}
|
||||
|
||||
disablePlugins = () => {
|
||||
const { graph } = this.state
|
||||
graph.disablePlugins('keyboard')
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
<button onClick={this.enablePlugins}>enable</button>
|
||||
<button onClick={this.disablePlugins}>disable</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
## @antv/x6-common [2.0.6](https://github.com/antvis/x6/compare/@antv/x6-common@2.0.5...@antv/x6-common@2.0.6) (2023-01-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix index error for priorityQueue ([#3179](https://github.com/antvis/x6/issues/3179)) ([d64150b](https://github.com/antvis/x6/commit/d64150bfadf10fe21f44734a0267261260b8c53b))
|
||||
|
||||
## @antv/x6-common [2.0.5](https://github.com/antvis/x6/compare/@antv/x6-common@2.0.4...@antv/x6-common@2.0.5) (2023-01-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* optimize css loader ([#3156](https://github.com/antvis/x6/issues/3156)) ([9c48ad8](https://github.com/antvis/x6/commit/9c48ad8dfc99e623a57855295d07c35be5483073))
|
||||
|
||||
## @antv/x6-common [2.0.4](https://github.com/antvis/x6/compare/@antv/x6-common@2.0.3...@antv/x6-common@2.0.4) (2022-12-20)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-common",
|
||||
"version": "2.0.4",
|
||||
"version": "2.0.6",
|
||||
"description": "Basic toolkit for X6",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -45,7 +45,7 @@ export class PriorityQueue<T> {
|
||||
*/
|
||||
insert(priority: number, value: T, id?: string) {
|
||||
const item: PriorityQueue.DataItem<T> = { priority, value }
|
||||
const index = this.data.length - 1
|
||||
const index = this.data.length
|
||||
if (id) {
|
||||
item.id = id
|
||||
this.index[id] = index
|
||||
@ -96,7 +96,9 @@ export class PriorityQueue<T> {
|
||||
const data = this.data
|
||||
const peek = data[0]
|
||||
const last = data.pop()!
|
||||
delete this.index[data.length]
|
||||
if (peek.id) {
|
||||
delete this.index[peek.id]
|
||||
}
|
||||
|
||||
if (data.length > 0) {
|
||||
data[0] = last
|
||||
|
@ -2,6 +2,7 @@ import { Platform } from '../platform'
|
||||
|
||||
interface CssModule {
|
||||
name: string
|
||||
loadTimes: number
|
||||
styleElement: HTMLStyleElement | null
|
||||
}
|
||||
|
||||
@ -10,7 +11,10 @@ const cssModules: CssModule[] = []
|
||||
export function ensure(name: string, content: string) {
|
||||
const cssModule = cssModules.find((m) => m.name === name)
|
||||
if (cssModule) {
|
||||
return
|
||||
cssModule.loadTimes += 1
|
||||
if (cssModule.loadTimes > 1) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!Platform.isApplyingHMR()) {
|
||||
@ -25,6 +29,7 @@ export function ensure(name: string, content: string) {
|
||||
|
||||
cssModules.push({
|
||||
name,
|
||||
loadTimes: 1,
|
||||
styleElement,
|
||||
})
|
||||
}
|
||||
@ -34,7 +39,13 @@ export function clean(name: string) {
|
||||
const index = cssModules.findIndex((m) => m.name === name)
|
||||
|
||||
if (index > -1) {
|
||||
let styleElement = cssModules[index].styleElement
|
||||
const cssModule = cssModules[index]
|
||||
cssModule.loadTimes -= 1
|
||||
if (cssModule.loadTimes > 0) {
|
||||
return
|
||||
}
|
||||
|
||||
let styleElement = cssModule.styleElement
|
||||
if (styleElement && styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement)
|
||||
}
|
||||
|
@ -729,7 +729,7 @@ type TypeEventHandlersBase<TDelegateTarget, TData, TCurrentTarget, TTarget> = {
|
||||
TCurrentTarget,
|
||||
TTarget
|
||||
>]?:
|
||||
| TypeEventHandler<TDelegateTarget, TData, TCurrentTarget, TTarget, TType>
|
||||
| TypeEventHandler<TDelegateTarget, TData, TCurrentTarget, TTarget, string>
|
||||
| false
|
||||
| Record<string, unknown>
|
||||
}
|
||||
|
@ -198,7 +198,14 @@ export function text(
|
||||
const autoLineHeight = defaultLineHeight === 'auto'
|
||||
const lineHeight = autoLineHeight ? '1.5em' : defaultLineHeight || '1em'
|
||||
|
||||
empty(elem)
|
||||
let needEmptyElem = true
|
||||
const childs = elem.children
|
||||
if (childs.length === 1 && childs[0].tagName.toUpperCase() === 'TITLE') {
|
||||
needEmptyElem = false
|
||||
}
|
||||
if (needEmptyElem) {
|
||||
empty(elem)
|
||||
}
|
||||
|
||||
attr(elem, {
|
||||
// Preserve spaces, do not consecutive spaces to get collapsed to one.
|
||||
|
@ -7,7 +7,7 @@ declare module '@antv/x6/lib/graph/graph' {
|
||||
enableClipboard: () => Graph
|
||||
disableClipboard: () => Graph
|
||||
toggleClipboard: (enabled?: boolean) => Graph
|
||||
isClipboardEmpty: () => boolean
|
||||
isClipboardEmpty: (options?: Clipboard.Options) => boolean
|
||||
getCellsInClipboard: () => Cell[]
|
||||
cleanClipboard: () => Graph
|
||||
copy: (cells: Cell[], options?: Clipboard.CopyOptions) => Graph
|
||||
@ -55,10 +55,10 @@ Graph.prototype.toggleClipboard = function (enabled?: boolean) {
|
||||
return this
|
||||
}
|
||||
|
||||
Graph.prototype.isClipboardEmpty = function () {
|
||||
Graph.prototype.isClipboardEmpty = function (options?: Clipboard.Options) {
|
||||
const clipboard = this.getPlugin('clipboard') as Clipboard
|
||||
if (clipboard) {
|
||||
return clipboard.isEmpty()
|
||||
return clipboard.isEmpty(options)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -89,7 +89,12 @@ export class ClipboardImpl {
|
||||
}
|
||||
}
|
||||
|
||||
isEmpty() {
|
||||
isEmpty(options: ClipboardImpl.Options = {}) {
|
||||
if (options.useLocalStorage) {
|
||||
// With useLocalStorage turned on, no real cells can be obtained without deserialize first
|
||||
// https://github.com/antvis/X6/issues/2573
|
||||
this.deserialize(options)
|
||||
}
|
||||
return this.cells.length <= 0
|
||||
}
|
||||
|
||||
|
@ -32,14 +32,12 @@ export class Clipboard
|
||||
if (this.disabled) {
|
||||
this.options.enabled = true
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
disable() {
|
||||
if (!this.disabled) {
|
||||
this.options.enabled = false
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
toggleEnabled(enabled?: boolean) {
|
||||
@ -60,8 +58,8 @@ export class Clipboard
|
||||
return this
|
||||
}
|
||||
|
||||
isEmpty() {
|
||||
return this.clipboardImpl.isEmpty()
|
||||
isEmpty(options: Clipboard.Options = {}) {
|
||||
return this.clipboardImpl.isEmpty(options)
|
||||
}
|
||||
|
||||
getCellsInClipboard() {
|
||||
|
@ -1,3 +1,10 @@
|
||||
## @antv/x6-plugin-dnd [2.0.4](https://github.com/antvis/x6/compare/@antv/x6-plugin-dnd@2.0.3...@antv/x6-plugin-dnd@2.0.4) (2023-01-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* change dragging container options ([#3139](https://github.com/antvis/x6/issues/3139)) ([7b091f3](https://github.com/antvis/x6/commit/7b091f35dee147c5e7bf97577e14e11ceb7e8e3d))
|
||||
|
||||
## @antv/x6-plugin-dnd [2.0.3](https://github.com/antvis/x6/compare/@antv/x6-plugin-dnd@2.0.2...@antv/x6-plugin-dnd@2.0.3) (2022-11-25)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-dnd",
|
||||
"version": "2.0.3",
|
||||
"version": "2.0.4",
|
||||
"description": "dnd plugin for X6",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -81,7 +81,10 @@ export class Dnd extends View {
|
||||
|
||||
this.targetModel.startBatch('dnd')
|
||||
Dom.addClass(this.container, 'dragging')
|
||||
Dom.appendTo(this.container, this.options.containerParent || document.body)
|
||||
Dom.appendTo(
|
||||
this.container,
|
||||
this.options.draggingContainer || document.body,
|
||||
)
|
||||
|
||||
this.sourceNode = node
|
||||
this.prepareDragging(node, e.clientX, e.clientY)
|
||||
@ -481,7 +484,7 @@ export namespace Dnd {
|
||||
// duration?: number
|
||||
// easing?: string
|
||||
// }
|
||||
containerParent?: HTMLElement
|
||||
draggingContainer?: HTMLElement
|
||||
/**
|
||||
* dnd tool box container.
|
||||
*/
|
||||
|
@ -1,3 +1,10 @@
|
||||
# @antv/x6-plugin-history [2.2.0](https://github.com/antvis/x6/compare/@antv/x6-plugin-history@2.1.3...@antv/x6-plugin-history@2.2.0) (2023-02-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* history add max stack size ([#3253](https://github.com/antvis/x6/issues/3253)) ([fba5310](https://github.com/antvis/x6/commit/fba531064ad8027c451a81b60d5efd7f7314a0fa))
|
||||
|
||||
## @antv/x6-plugin-history [2.1.3](https://github.com/antvis/x6/compare/@antv/x6-plugin-history@2.1.2...@antv/x6-plugin-history@2.1.3) (2022-11-25)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-history",
|
||||
"version": "2.1.3",
|
||||
"version": "2.2.0",
|
||||
"description": "history plugin for X6",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -25,6 +25,7 @@ export class History
|
||||
protected batchLevel = 0
|
||||
protected lastBatchIndex = -1
|
||||
protected freezed = false
|
||||
protected stackSize = 0 // 0: not limit
|
||||
|
||||
protected readonly handlers: (<T extends History.ModelEvents>(
|
||||
event: T,
|
||||
@ -33,6 +34,8 @@ export class History
|
||||
|
||||
constructor(options: History.Options) {
|
||||
super()
|
||||
const { stackSize = 0 } = options
|
||||
this.stackSize = stackSize
|
||||
this.options = Util.getOptions(options)
|
||||
this.validator = new History.Validator({
|
||||
history: this,
|
||||
@ -101,7 +104,7 @@ export class History
|
||||
const cmd = this.redoStack.pop()
|
||||
if (cmd) {
|
||||
this.applyCommand(cmd, options)
|
||||
this.undoStack.push(cmd)
|
||||
this.undoStackPush(cmd)
|
||||
this.notify('redo', cmd, options)
|
||||
}
|
||||
}
|
||||
@ -424,7 +427,7 @@ export class History
|
||||
const cmds = this.filterBatchCommand(this.batchCommands)
|
||||
if (cmds.length > 0) {
|
||||
this.redoStack = []
|
||||
this.undoStack.push(cmds)
|
||||
this.undoStackPush(cmds)
|
||||
this.consolidateCommands()
|
||||
this.notify('add', cmds, options)
|
||||
}
|
||||
@ -498,7 +501,7 @@ export class History
|
||||
this.lastBatchIndex = Math.max(this.lastBatchIndex, 0)
|
||||
this.emit('batch', { cmd, options })
|
||||
} else {
|
||||
this.undoStack.push(cmd)
|
||||
this.undoStackPush(cmd)
|
||||
this.consolidateCommands()
|
||||
this.notify('add', cmd, options)
|
||||
}
|
||||
@ -560,6 +563,17 @@ export class History
|
||||
this.undoStack.pop()
|
||||
}
|
||||
|
||||
protected undoStackPush(cmd: History.Commands) {
|
||||
if (this.stackSize === 0) {
|
||||
this.undoStack.push(cmd)
|
||||
return
|
||||
}
|
||||
if (this.undoStack.length >= this.stackSize) {
|
||||
this.undoStack.shift()
|
||||
}
|
||||
this.undoStack.push(cmd)
|
||||
}
|
||||
|
||||
@Basecoat.dispose()
|
||||
dispose() {
|
||||
this.validator.dispose()
|
||||
@ -614,7 +628,9 @@ export namespace History {
|
||||
cancelInvalid?: boolean
|
||||
}
|
||||
|
||||
export interface Options extends Partial<CommonOptions> {}
|
||||
export interface Options extends Partial<CommonOptions> {
|
||||
stackSize?: number
|
||||
}
|
||||
|
||||
interface Data {
|
||||
id?: string
|
||||
|
@ -1,3 +1,10 @@
|
||||
# @antv/x6-plugin-keyboard [2.2.0](https://github.com/antvis/x6/compare/@antv/x6-plugin-keyboard@2.1.4...@antv/x6-plugin-keyboard@2.2.0) (2023-02-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* keyboard support clear and custom trigger ([#3202](https://github.com/antvis/x6/issues/3202)) ([668c932](https://github.com/antvis/x6/commit/668c93242fbcebb987cccc3dcfd56982f7c66252))
|
||||
|
||||
## @antv/x6-plugin-keyboard [2.1.4](https://github.com/antvis/x6/compare/@antv/x6-plugin-keyboard@2.1.3...@antv/x6-plugin-keyboard@2.1.4) (2022-11-29)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-keyboard",
|
||||
"version": "2.1.4",
|
||||
"version": "2.2.0",
|
||||
"description": "keyboard plugin for X6",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -14,6 +14,8 @@ declare module '@antv/x6/lib/graph/graph' {
|
||||
action?: KeyboardImpl.Action,
|
||||
) => Graph
|
||||
unbindKey: (keys: string | string[], action?: KeyboardImpl.Action) => Graph
|
||||
clearKeys: () => Graph
|
||||
triggerKey: (key: string, action: KeyboardImpl.Action) => Graph
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,3 +73,19 @@ Graph.prototype.unbindKey = function (
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
Graph.prototype.clearKeys = function() {
|
||||
const keyboard = this.getPlugin('keyboard') as Keyboard
|
||||
if(keyboard) {
|
||||
keyboard.clear()
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
Graph.prototype.triggerKey = function(key: string, action: KeyboardImpl.Action) {
|
||||
const keyboard = this.getPlugin('keyboard') as Keyboard
|
||||
if(keyboard) {
|
||||
keyboard.trigger(key, action)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
@ -27,12 +27,10 @@ export class Keyboard extends Disposable {
|
||||
|
||||
enable() {
|
||||
this.keyboardImpl.enable()
|
||||
return this
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.keyboardImpl.disable()
|
||||
return this
|
||||
}
|
||||
|
||||
toggleEnabled(enabled?: boolean) {
|
||||
@ -61,6 +59,17 @@ export class Keyboard extends Disposable {
|
||||
return this
|
||||
}
|
||||
|
||||
trigger(key: string, action?: KeyboardImpl.Action) {
|
||||
this.keyboardImpl.trigger(key, action)
|
||||
return this
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.keyboardImpl.clear()
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
unbindKey(keys: string | string[], action?: KeyboardImpl.Action) {
|
||||
this.keyboardImpl.off(keys, action)
|
||||
return this
|
||||
|
@ -21,7 +21,6 @@ export class KeyboardImpl extends Disposable implements IDisablable {
|
||||
private readonly options: KeyboardImpl.Options & { graph: Graph },
|
||||
) {
|
||||
super()
|
||||
|
||||
const scroller = this.graph.getPlugin('scroller') as any
|
||||
this.container = scroller ? scroller.container : this.graph.container
|
||||
|
||||
@ -76,6 +75,14 @@ export class KeyboardImpl extends Disposable implements IDisablable {
|
||||
this.mousetrap.unbind(this.getKeys(keys), action)
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.mousetrap.reset()
|
||||
}
|
||||
|
||||
trigger(key: string, action?: KeyboardImpl.Action) {
|
||||
this.mousetrap.trigger(key, action)
|
||||
}
|
||||
|
||||
private focus(e: EventArgs['node:mouseup']) {
|
||||
const isInputEvent = this.isInputEvent(e.e)
|
||||
if (isInputEvent) {
|
||||
@ -95,7 +102,7 @@ export class KeyboardImpl extends Disposable implements IDisablable {
|
||||
|
||||
protected formatkey(key: string) {
|
||||
const formated = key
|
||||
.toLowerCase()
|
||||
.toLocaleLowerCase()
|
||||
.replace(/\s/g, '')
|
||||
.replace('delete', 'del')
|
||||
.replace('cmd', 'command')
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-scroller",
|
||||
"version": "2.0.7",
|
||||
"version": "2.0.8",
|
||||
"description": "scroller plugin for X6",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -35,17 +35,16 @@ export class Scroller extends Basecoat<Scroller.EventArgs> {
|
||||
return this.scrollerImpl.container
|
||||
}
|
||||
|
||||
constructor(public readonly options: Scroller.Options) {
|
||||
constructor(public options: Scroller.Options) {
|
||||
super()
|
||||
CssLoader.ensure(this.name, content)
|
||||
}
|
||||
|
||||
public init(graph: Graph) {
|
||||
this.graph = graph
|
||||
this.scrollerImpl = new ScrollerImpl({
|
||||
...this.options,
|
||||
graph,
|
||||
})
|
||||
const options = ScrollerImpl.getOptions({ ...this.options, graph })
|
||||
this.options = options
|
||||
this.scrollerImpl = new ScrollerImpl(options)
|
||||
this.setup()
|
||||
this.startListening()
|
||||
this.updateClassName()
|
||||
@ -401,8 +400,10 @@ export namespace Scroller {
|
||||
export interface EventArgs extends ScrollerImpl.EventArgs {}
|
||||
|
||||
type EventType = 'leftMouseDown' | 'rightMouseDown'
|
||||
export interface Options extends ScrollerImpl.CommonOptions {
|
||||
interface ScrollerOptions extends ScrollerImpl.Options {
|
||||
pannable?: boolean | { enabled: boolean; eventTypes: EventType[] }
|
||||
modifiers?: string | ModifierKey[] | null // alt, ctrl, shift, meta
|
||||
}
|
||||
|
||||
export type Options = Omit<ScrollerOptions, 'graph'>
|
||||
}
|
||||
|
@ -1128,7 +1128,8 @@ export namespace ScrollerImpl {
|
||||
panning: { e: Dom.MouseMoveEvent }
|
||||
'pan:stop': { e: Dom.MouseUpEvent }
|
||||
}
|
||||
export interface CommonOptions {
|
||||
export interface Options {
|
||||
graph: Graph
|
||||
enabled?: boolean
|
||||
className?: string
|
||||
width?: number
|
||||
@ -1151,10 +1152,6 @@ export namespace ScrollerImpl {
|
||||
scroller: ScrollerImpl,
|
||||
) => TransformManager.FitToContentFullOptions)
|
||||
}
|
||||
|
||||
export interface Options extends CommonOptions {
|
||||
graph: Graph
|
||||
}
|
||||
export interface CenterOptions {
|
||||
padding?: NumberExt.SideOptions
|
||||
}
|
||||
@ -1266,7 +1263,7 @@ export namespace ScrollerImpl {
|
||||
result.background == null
|
||||
) {
|
||||
result.background = graphOptions.background
|
||||
delete graphOptions.background
|
||||
options.graph.background.clear()
|
||||
}
|
||||
|
||||
return result as ScrollerImpl.Options
|
||||
|
@ -62,14 +62,12 @@ export class Selection extends Basecoat<SelectionImpl.EventArgs> {
|
||||
if (this.disabled) {
|
||||
this.options.enabled = true
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
disable() {
|
||||
if (!this.disabled) {
|
||||
this.options.enabled = false
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
toggleEnabled(enabled?: boolean) {
|
||||
|
@ -29,12 +29,10 @@ export class Snapline extends Disposable {
|
||||
|
||||
enable() {
|
||||
this.snaplineImpl.enable()
|
||||
return this
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.snaplineImpl.disable()
|
||||
return this
|
||||
}
|
||||
|
||||
toggleEnabled(enabled?: boolean) {
|
||||
|
@ -7,6 +7,7 @@ export class Transform extends Basecoat<Transform.EventArgs> {
|
||||
private graph: Graph
|
||||
protected widgets: Map<Node, TransformImpl> = new Map()
|
||||
public name = 'transform'
|
||||
private disabled = false
|
||||
|
||||
constructor(public readonly options: Transform.Options) {
|
||||
super()
|
||||
@ -15,6 +16,9 @@ export class Transform extends Basecoat<Transform.EventArgs> {
|
||||
|
||||
init(graph: Graph) {
|
||||
this.graph = graph
|
||||
if (this.disabled) {
|
||||
return
|
||||
}
|
||||
this.startListening()
|
||||
}
|
||||
|
||||
@ -28,6 +32,24 @@ export class Transform extends Basecoat<Transform.EventArgs> {
|
||||
this.graph.off('blank:mousedown', this.onBlankMouseDown, this)
|
||||
}
|
||||
|
||||
enable() {
|
||||
if (this.disabled) {
|
||||
this.disabled = false
|
||||
this.startListening()
|
||||
}
|
||||
}
|
||||
|
||||
disable() {
|
||||
if (!this.disabled) {
|
||||
this.disabled = true
|
||||
this.stopListening()
|
||||
}
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return !this.disabled
|
||||
}
|
||||
|
||||
protected onNodeClick({ node }: EventArgs['node:click']) {
|
||||
this.clearWidgets()
|
||||
const widget = this.createTransform(node)
|
||||
|
@ -1,3 +1,17 @@
|
||||
## @antv/x6-react-components [2.0.7](https://github.com/antvis/x6/compare/@antv/x6-react-components@2.0.6...@antv/x6-react-components@2.0.7) (2023-01-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* don't hide when click on color picker ([#3172](https://github.com/antvis/x6/issues/3172)) ([cae8625](https://github.com/antvis/x6/commit/cae8625feb20fd93cc8002fa6ed00d345d3cf33c))
|
||||
|
||||
## @antv/x6-react-components [2.0.6](https://github.com/antvis/x6/compare/@antv/x6-react-components@2.0.5...@antv/x6-react-components@2.0.6) (2023-01-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* stop propagation when click menu item ([#3147](https://github.com/antvis/x6/issues/3147)) ([90dad14](https://github.com/antvis/x6/commit/90dad14d7e1ad8639b80b215596c8f4bad7b00ed))
|
||||
|
||||
## @antv/x6-react-components [2.0.5](https://github.com/antvis/x6/compare/@antv/x6-react-components@2.0.4...@antv/x6-react-components@2.0.5) (2022-11-25)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-react-components",
|
||||
"version": "2.0.5",
|
||||
"version": "2.0.7",
|
||||
"description": "React components for building x6 editors",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -37,7 +37,9 @@ export class ColorPicker extends React.Component<
|
||||
|
||||
onDocumentClick = (e: React.MouseEvent) => {
|
||||
const target = e.target as HTMLDivElement
|
||||
if (target === this.container || this.container.contains(target)) {
|
||||
const picker = this.container.querySelector('.sketch-picker')!
|
||||
|
||||
if (target === picker || picker.contains(target)) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -59,12 +61,9 @@ export class ColorPicker extends React.Component<
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(value, event)
|
||||
}
|
||||
|
||||
this.setState({
|
||||
active: false,
|
||||
color: value.rgb,
|
||||
})
|
||||
this.unbindDocEvent()
|
||||
}
|
||||
|
||||
handleClick = (e: React.MouseEvent) => {
|
||||
@ -84,8 +83,10 @@ export class ColorPicker extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
refContainer = (popoverRef: { getContainer: () => HTMLDivElement }) => {
|
||||
if (popoverRef) {
|
||||
this.container = popoverRef.getContainer()
|
||||
}
|
||||
}
|
||||
|
||||
renderPicker() {
|
||||
@ -123,10 +124,12 @@ export class ColorPicker extends React.Component<
|
||||
{...popoverProps}
|
||||
content={this.renderPicker()}
|
||||
overlayClassName={`${baseCls}-overlay`}
|
||||
destroyTooltipOnHide
|
||||
ref={this.refContainer}
|
||||
trigger={[]}
|
||||
>
|
||||
<div
|
||||
style={style}
|
||||
ref={this.refContainer}
|
||||
onClick={this.handleClick}
|
||||
className={classNames(baseCls, {
|
||||
[`${baseCls}-disabled`]: disabled,
|
||||
|
@ -26,6 +26,7 @@ class MenubarItemInner extends React.PureComponent<
|
||||
}
|
||||
|
||||
onClick = (e: React.MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
this.props.context.activeMenubar()
|
||||
this.removeDeactive(e.currentTarget.parentElement)
|
||||
this.active()
|
||||
|
@ -1,3 +1,45 @@
|
||||
# @antv/x6 [2.3.0](https://github.com/antvis/x6/compare/@antv/x6@2.2.1...@antv/x6@2.3.0) (2023-02-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **scheduler:** remove spammy console.log ([#3200](https://github.com/antvis/x6/issues/3200)) ([1f83a2b](https://github.com/antvis/x6/commit/1f83a2b8a84b53303293e724e7f9d0ee49182efc))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add options for positionCell api ([#3208](https://github.com/antvis/x6/issues/3208)) ([58c0fe4](https://github.com/antvis/x6/commit/58c0fe459c0314997440b4af7dc0443abe199924))
|
||||
|
||||
## @antv/x6 [2.2.1](https://github.com/antvis/x6/compare/@antv/x6@2.2.0...@antv/x6@2.2.1) (2023-02-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* ensure the container in html view ([#3196](https://github.com/antvis/x6/issues/3196)) ([3a59703](https://github.com/antvis/x6/commit/3a59703f1c2da3ac8c8471eb9b864ac4cf468f97))
|
||||
|
||||
# @antv/x6 [2.2.0](https://github.com/antvis/x6/compare/@antv/x6@2.1.7...@antv/x6@2.2.0) (2023-01-31)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add port events ([#3185](https://github.com/antvis/x6/issues/3185)) ([3265fe5](https://github.com/antvis/x6/commit/3265fe5b983f22e34d60c647212824961ecfdab5))
|
||||
|
||||
## @antv/x6 [2.1.6](https://github.com/antvis/x6/compare/@antv/x6@2.1.5...@antv/x6@2.1.6) (2023-01-19)
|
||||
|
||||
## @antv/x6 [2.1.5](https://github.com/antvis/x6/compare/@antv/x6@2.1.4...@antv/x6@2.1.5) (2023-01-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* update group even group is empty ([#3117](https://github.com/antvis/x6/issues/3117)) ([6abd068](https://github.com/antvis/x6/commit/6abd0683eab22eb0fa1a4702642ab76b91320694))
|
||||
|
||||
## @antv/x6 [2.1.4](https://github.com/antvis/x6/compare/@antv/x6@2.1.3...@antv/x6@2.1.4) (2023-01-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* optimize rendering logic to prevent loops ([#3108](https://github.com/antvis/x6/issues/3108)) ([45337e4](https://github.com/antvis/x6/commit/45337e4a62224aaffd60fc8b2670a071c5560796))
|
||||
|
||||
## @antv/x6 [2.1.3](https://github.com/antvis/x6/compare/@antv/x6@2.1.2...@antv/x6@2.1.3) (2022-12-24)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6",
|
||||
"version": "2.1.3",
|
||||
"version": "2.3.0",
|
||||
"description": "JavaScript diagramming library that uses SVG and HTML for rendering",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -702,8 +702,8 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
/**
|
||||
* Position the center of graph to the center of the viewport.
|
||||
*/
|
||||
center() {
|
||||
return this.centerPoint()
|
||||
center(options?: Transform.CenterOptions) {
|
||||
return this.centerPoint(options)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -712,13 +712,25 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
* only center along the specified dimension and keep the other coordinate
|
||||
* unchanged.
|
||||
*/
|
||||
centerPoint(x: number, y: null | number): this
|
||||
centerPoint(x: null | number, y: number): this
|
||||
centerPoint(): this
|
||||
centerPoint(x?: number | null, y?: number | null) {
|
||||
centerPoint(
|
||||
x: number,
|
||||
y: null | number,
|
||||
options?: Transform.CenterOptions,
|
||||
): this
|
||||
centerPoint(
|
||||
x: null | number,
|
||||
y: number,
|
||||
options?: Transform.CenterOptions,
|
||||
): this
|
||||
centerPoint(optons?: Transform.CenterOptions): this
|
||||
centerPoint(
|
||||
x?: number | null | Transform.CenterOptions,
|
||||
y?: number | null,
|
||||
options?: Transform.CenterOptions,
|
||||
) {
|
||||
const scroller = this.getPlugin<any>('scroller')
|
||||
if (scroller) {
|
||||
scroller.centerPoint(x as number, y as number)
|
||||
scroller.centerPoint(x as number, y as number, options)
|
||||
} else {
|
||||
this.transform.centerPoint(x as number, y as number)
|
||||
}
|
||||
@ -737,10 +749,10 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
return this
|
||||
}
|
||||
|
||||
centerCell(cell: Cell) {
|
||||
centerCell(cell: Cell, options?: Transform.PositionContentOptions) {
|
||||
const scroller = this.getPlugin<any>('scroller')
|
||||
if (scroller) {
|
||||
scroller.centerCell(cell)
|
||||
scroller.centerCell(cell, options)
|
||||
} else {
|
||||
this.transform.centerCell(cell)
|
||||
}
|
||||
@ -752,10 +764,11 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
point: Point.PointLike,
|
||||
x: number | string,
|
||||
y: number | string,
|
||||
options: Transform.CenterOptions = {},
|
||||
) {
|
||||
const scroller = this.getPlugin<any>('scroller')
|
||||
if (scroller) {
|
||||
scroller.positionPoint(point, x, y)
|
||||
scroller.positionPoint(point, x, y, options)
|
||||
} else {
|
||||
this.transform.positionPoint(point, x, y)
|
||||
}
|
||||
@ -763,10 +776,14 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
return this
|
||||
}
|
||||
|
||||
positionRect(rect: Rectangle.RectangleLike, direction: Transform.Direction) {
|
||||
positionRect(
|
||||
rect: Rectangle.RectangleLike,
|
||||
direction: Transform.Direction,
|
||||
options?: Transform.CenterOptions,
|
||||
) {
|
||||
const scroller = this.getPlugin<any>('scroller')
|
||||
if (scroller) {
|
||||
scroller.positionRect(rect, direction)
|
||||
scroller.positionRect(rect, direction, options)
|
||||
} else {
|
||||
this.transform.positionRect(rect, direction)
|
||||
}
|
||||
@ -774,10 +791,14 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
return this
|
||||
}
|
||||
|
||||
positionCell(cell: Cell, direction: Transform.Direction) {
|
||||
positionCell(
|
||||
cell: Cell,
|
||||
direction: Transform.Direction,
|
||||
options?: Transform.CenterOptions,
|
||||
) {
|
||||
const scroller = this.getPlugin<any>('scroller')
|
||||
if (scroller) {
|
||||
scroller.positionCell(cell, direction)
|
||||
scroller.positionCell(cell, direction, options)
|
||||
} else {
|
||||
this.transform.positionCell(cell, direction)
|
||||
}
|
||||
@ -1193,15 +1214,56 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
}
|
||||
|
||||
getPlugin<T extends Graph.Plugin>(pluginName: string): T | undefined {
|
||||
let result: Graph.Plugin | undefined
|
||||
return Array.from(this.installedPlugins).find(
|
||||
(plugin) => plugin.name === pluginName,
|
||||
) as T
|
||||
}
|
||||
|
||||
this.installedPlugins.forEach((plugin) => {
|
||||
if (plugin.name === pluginName) {
|
||||
result = plugin
|
||||
}
|
||||
getPlugins<T extends Graph.Plugin[]>(pluginName: string[]): T | undefined {
|
||||
return Array.from(this.installedPlugins).filter((plugin) =>
|
||||
pluginName.includes(plugin.name),
|
||||
) as T
|
||||
}
|
||||
|
||||
disablePlugins(plugins: string[] | string) {
|
||||
let postPlugins = plugins
|
||||
if (!Array.isArray(postPlugins)) {
|
||||
postPlugins = [postPlugins]
|
||||
}
|
||||
const aboutToChangePlugins = this.getPlugins(postPlugins)
|
||||
aboutToChangePlugins?.forEach((plugin) => {
|
||||
plugin?.disable?.()
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
return result as T
|
||||
enablePlugins(plugins: string[] | string) {
|
||||
let postPlugins = plugins
|
||||
if (!Array.isArray(postPlugins)) {
|
||||
postPlugins = [postPlugins]
|
||||
}
|
||||
const aboutToChangePlugins = this.getPlugins(postPlugins)
|
||||
aboutToChangePlugins?.forEach((plugin) => {
|
||||
plugin?.enable?.()
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
disposePlugins(plugins: string[] | string) {
|
||||
let postPlugins = plugins
|
||||
if (!Array.isArray(postPlugins)) {
|
||||
postPlugins = [postPlugins]
|
||||
}
|
||||
const aboutToChangePlugins = this.getPlugins(postPlugins)
|
||||
aboutToChangePlugins?.forEach((plugin) => {
|
||||
plugin.dispose()
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
isPluginEnabled(pluginName: string) {
|
||||
const pluginIns = this.getPlugin(pluginName)
|
||||
return pluginIns?.isEnabled?.()
|
||||
}
|
||||
|
||||
// #endregion
|
||||
@ -1349,5 +1411,8 @@ export namespace Graph {
|
||||
name: string
|
||||
init: (graph: Graph, ...options: any[]) => any
|
||||
dispose: () => void
|
||||
disable?: () => void
|
||||
enable?: () => void
|
||||
isEnabled?: () => boolean
|
||||
}
|
||||
}
|
||||
|
@ -244,6 +244,13 @@ export class Model extends Basecoat<Model.EventArgs> {
|
||||
return node
|
||||
}
|
||||
|
||||
updateNode(metadata: Node.Metadata, options: Model.SetOptions = {}) {
|
||||
const node = this.createNode(metadata)
|
||||
const prop = node.getProp()
|
||||
node.dispose()
|
||||
return this.updateCell(prop, options)
|
||||
}
|
||||
|
||||
createNode(metadata: Node.Metadata) {
|
||||
return Node.create(metadata)
|
||||
}
|
||||
@ -258,6 +265,13 @@ export class Model extends Basecoat<Model.EventArgs> {
|
||||
return Edge.create(metadata)
|
||||
}
|
||||
|
||||
updateEdge(metadata: Edge.Metadata, options: Model.SetOptions = {}) {
|
||||
const edge = this.createEdge(metadata)
|
||||
const prop = edge.getProp()
|
||||
edge.dispose()
|
||||
return this.updateCell(prop, options)
|
||||
}
|
||||
|
||||
addCell(cell: Cell | Cell[], options: Model.AddOptions = {}) {
|
||||
if (Array.isArray(cell)) {
|
||||
return this.addCells(cell, options)
|
||||
@ -295,6 +309,23 @@ export class Model extends Basecoat<Model.EventArgs> {
|
||||
return this
|
||||
}
|
||||
|
||||
updateCell(prop: Cell.Properties, options: Model.SetOptions = {}): boolean {
|
||||
const existing = prop.id && this.getCell(prop.id)
|
||||
if (existing) {
|
||||
return this.batchUpdate(
|
||||
'update',
|
||||
() => {
|
||||
Object.keys(prop).forEach((key) =>
|
||||
existing.setProp(key, prop[key], options),
|
||||
)
|
||||
return true
|
||||
},
|
||||
prop,
|
||||
)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
removeCell(cellId: string, options?: Collection.RemoveOptions): Cell | null
|
||||
removeCell(cell: Cell, options?: Collection.RemoveOptions): Cell | null
|
||||
removeCell(
|
||||
|
@ -7,7 +7,7 @@ export class JobQueue {
|
||||
private initialTime = Date.now()
|
||||
|
||||
queueJob(job: Job) {
|
||||
if (job.priority === JOB_PRIORITY.PRIOR) {
|
||||
if (job.priority & JOB_PRIORITY.PRIOR) {
|
||||
job.cb()
|
||||
} else {
|
||||
const index = this.findInsertionIndex(job)
|
||||
@ -81,11 +81,20 @@ export class JobQueue {
|
||||
}
|
||||
|
||||
private findInsertionIndex(job: Job) {
|
||||
let start = 0
|
||||
while (this.queue[start] && this.queue[start].priority >= job.priority) {
|
||||
start += 1
|
||||
let left = 0
|
||||
let ins = this.queue.length
|
||||
let right = ins - 1
|
||||
const priority = job.priority
|
||||
while (left <= right) {
|
||||
const mid = ((right - left) >> 1) + left
|
||||
if (priority <= this.queue[mid].priority) {
|
||||
left = mid + 1
|
||||
} else {
|
||||
ins = mid
|
||||
right = mid - 1
|
||||
}
|
||||
}
|
||||
return start
|
||||
return ins
|
||||
}
|
||||
|
||||
private scheduleJob() {
|
||||
@ -135,10 +144,10 @@ export interface Job {
|
||||
}
|
||||
|
||||
export enum JOB_PRIORITY {
|
||||
RenderEdge = 1,
|
||||
RenderNode = 2,
|
||||
Update = 3,
|
||||
PRIOR = 100,
|
||||
RenderEdge = /**/ 1 << 1,
|
||||
RenderNode = /**/ 1 << 2,
|
||||
Update = /* */ 1 << 3,
|
||||
PRIOR = /* */ 1 << 20,
|
||||
}
|
||||
|
||||
// function findInsertionIndex(job: Job) {
|
||||
|
@ -8,6 +8,7 @@ import { Graph } from '../graph'
|
||||
|
||||
export class Scheduler extends Disposable {
|
||||
public views: KeyValue<Scheduler.View> = {}
|
||||
public willRemoveViews: KeyValue<Scheduler.View> = {}
|
||||
protected zPivots: KeyValue<Comment>
|
||||
private graph: Graph
|
||||
private renderArea?: Rectangle
|
||||
@ -51,7 +52,7 @@ export class Scheduler extends Disposable {
|
||||
protected onModelReseted({ options }: Model.EventArgs['reseted']) {
|
||||
this.queue.clearJobs()
|
||||
this.removeZPivots()
|
||||
this.removeViews()
|
||||
this.resetViews()
|
||||
this.renderViews(this.model.getCells(), options)
|
||||
}
|
||||
|
||||
@ -59,12 +60,8 @@ export class Scheduler extends Disposable {
|
||||
this.renderViews([cell], options)
|
||||
}
|
||||
|
||||
protected onCellRemoved({ cell, options }: Model.EventArgs['cell:removed']) {
|
||||
const viewItem = this.views[cell.id]
|
||||
if (viewItem) {
|
||||
const view = viewItem.view
|
||||
this.requestViewUpdate(view, Scheduler.FLAG_REMOVE, options)
|
||||
}
|
||||
protected onCellRemoved({ cell }: Model.EventArgs['cell:removed']) {
|
||||
this.removeViews([cell])
|
||||
}
|
||||
|
||||
protected onCellZIndexChanged({
|
||||
@ -186,7 +183,7 @@ export class Scheduler extends Disposable {
|
||||
viewItem.view,
|
||||
flag,
|
||||
options,
|
||||
cell.isNode() ? JOB_PRIORITY.RenderNode : JOB_PRIORITY.RenderEdge,
|
||||
this.getRenderPriority(viewItem.view),
|
||||
false,
|
||||
)
|
||||
}
|
||||
@ -218,22 +215,43 @@ export class Scheduler extends Disposable {
|
||||
}
|
||||
|
||||
if (result) {
|
||||
console.log('left flag', result) // eslint-disable-line
|
||||
if (
|
||||
cell.isEdge() &&
|
||||
(result & view.getFlag(['source', 'target'])) === 0
|
||||
) {
|
||||
this.requestViewUpdate(
|
||||
view,
|
||||
result,
|
||||
options,
|
||||
JOB_PRIORITY.RenderEdge,
|
||||
false,
|
||||
)
|
||||
this.queue.queueJob({
|
||||
id,
|
||||
priority: JOB_PRIORITY.RenderEdge,
|
||||
cb: () => {
|
||||
this.updateView(view, flag, options)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected removeViews(cells: Cell[]) {
|
||||
cells.forEach((cell) => {
|
||||
const id = cell.id
|
||||
const viewItem = this.views[id]
|
||||
|
||||
if (viewItem) {
|
||||
this.willRemoveViews[id] = viewItem
|
||||
delete this.views[id]
|
||||
|
||||
this.queue.queueJob({
|
||||
id,
|
||||
priority: this.getRenderPriority(viewItem.view),
|
||||
cb: () => {
|
||||
this.removeView(viewItem.view)
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
this.flush()
|
||||
}
|
||||
|
||||
protected flush() {
|
||||
this.graph.options.async
|
||||
? this.queue.queueFlush()
|
||||
@ -246,10 +264,13 @@ export class Scheduler extends Disposable {
|
||||
const viewItem = this.views[ids[i]]
|
||||
if (viewItem && viewItem.state === Scheduler.ViewState.WAITTING) {
|
||||
const { view, flag, options } = viewItem
|
||||
const priority = view.cell.isNode()
|
||||
? JOB_PRIORITY.RenderNode
|
||||
: JOB_PRIORITY.RenderEdge
|
||||
this.requestViewUpdate(view, flag, options, priority, false)
|
||||
this.requestViewUpdate(
|
||||
view,
|
||||
flag,
|
||||
options,
|
||||
this.getRenderPriority(view),
|
||||
false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,23 +316,25 @@ export class Scheduler extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
protected removeViews() {
|
||||
Object.keys(this.views).forEach((id) => {
|
||||
const viewItem = this.views[id]
|
||||
protected resetViews() {
|
||||
this.willRemoveViews = { ...this.views }
|
||||
Object.keys(this.willRemoveViews).forEach((id) => {
|
||||
const viewItem = this.willRemoveViews[id]
|
||||
if (viewItem) {
|
||||
this.removeView(viewItem.view.cell)
|
||||
this.removeView(viewItem.view)
|
||||
}
|
||||
})
|
||||
this.views = {}
|
||||
this.willRemoveViews = {}
|
||||
}
|
||||
|
||||
protected removeView(cell: Cell) {
|
||||
const viewItem = this.views[cell.id]
|
||||
if (viewItem) {
|
||||
protected removeView(view: CellView) {
|
||||
const cell = view.cell
|
||||
const viewItem = this.willRemoveViews[cell.id]
|
||||
if (view) {
|
||||
viewItem.view.remove()
|
||||
delete this.views[cell.id]
|
||||
delete this.willRemoveViews[cell.id]
|
||||
}
|
||||
return viewItem.view
|
||||
}
|
||||
|
||||
protected toggleVisible(cell: Cell, visible: boolean) {
|
||||
@ -455,6 +478,12 @@ export class Scheduler extends Disposable {
|
||||
)
|
||||
}
|
||||
|
||||
protected getRenderPriority(view: CellView) {
|
||||
return view.cell.isNode()
|
||||
? JOB_PRIORITY.RenderNode
|
||||
: JOB_PRIORITY.RenderEdge
|
||||
}
|
||||
|
||||
@Disposable.dispose()
|
||||
dispose() {
|
||||
this.stopListening()
|
||||
|
@ -36,7 +36,8 @@ export namespace HTML {
|
||||
}
|
||||
|
||||
protected renderHTMLComponent() {
|
||||
const container = this.selectors.foContent as Element
|
||||
const container =
|
||||
this.selectors && (this.selectors.foContent as HTMLDivElement)
|
||||
if (container) {
|
||||
Dom.empty(container)
|
||||
const content = shapeMaps[this.cell.shape]
|
||||
|
@ -1398,6 +1398,7 @@ export class EdgeView<
|
||||
}
|
||||
|
||||
onMouseDown(e: Dom.MouseDownEvent, x: number, y: number) {
|
||||
this.notifyMouseDown(e, x, y)
|
||||
this.startEdgeDragging(e, x, y)
|
||||
}
|
||||
|
||||
@ -2191,7 +2192,9 @@ export class EdgeView<
|
||||
for (let i = 0, ii = cells.length; i < ii; i += 1) {
|
||||
const view = graph.findViewByCell(cells[i])
|
||||
|
||||
if (!view) {
|
||||
// Prevent highlighting new edge
|
||||
// Close https://github.com/antvis/X6/issues/2853
|
||||
if (!view || view.cell.id === this.cell.id) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -357,7 +357,12 @@ export class NodeView<
|
||||
|
||||
protected updatePorts() {
|
||||
const groups = this.cell.getParsedGroups()
|
||||
Object.keys(groups).forEach((groupName) => this.updatePortGroup(groupName))
|
||||
const groupList = Object.keys(groups)
|
||||
if (groupList.length === 0) {
|
||||
this.updatePortGroup()
|
||||
} else {
|
||||
groupList.forEach((groupName) => this.updatePortGroup(groupName))
|
||||
}
|
||||
}
|
||||
|
||||
protected updatePortGroup(groupName?: string) {
|
||||
@ -452,6 +457,28 @@ export class NodeView<
|
||||
return { e, x, y, view, node, cell } as NodeView.PositionEventArgs<E>
|
||||
}
|
||||
|
||||
protected getPortEventArgs<E>(
|
||||
e: E,
|
||||
port: string,
|
||||
pos?: { x: number; y: number },
|
||||
) {
|
||||
const view = this // eslint-disable-line
|
||||
const node = view.cell
|
||||
const cell = node
|
||||
if (pos) {
|
||||
return {
|
||||
e,
|
||||
x: pos.x,
|
||||
y: pos.y,
|
||||
view,
|
||||
node,
|
||||
cell,
|
||||
port,
|
||||
} as NodeView.PositionEventArgs<E>
|
||||
}
|
||||
return { e, view, node, cell, port } as NodeView.MouseEventArgs<E>
|
||||
}
|
||||
|
||||
notifyMouseDown(e: Dom.MouseDownEvent, x: number, y: number) {
|
||||
super.onMouseDown(e, x, y)
|
||||
this.notify('node:mousedown', this.getEventArgs(e, x, y))
|
||||
@ -467,19 +494,33 @@ export class NodeView<
|
||||
this.notify('node:mouseup', this.getEventArgs(e, x, y))
|
||||
}
|
||||
|
||||
notifyPortEvent(
|
||||
name: string,
|
||||
e: Dom.EventObject,
|
||||
pos?: { x: number; y: number },
|
||||
) {
|
||||
const port = this.findAttr('port', e.target)
|
||||
if (port) {
|
||||
this.notify(name, this.getPortEventArgs(e, port, pos))
|
||||
}
|
||||
}
|
||||
|
||||
onClick(e: Dom.ClickEvent, x: number, y: number) {
|
||||
super.onClick(e, x, y)
|
||||
this.notify('node:click', this.getEventArgs(e, x, y))
|
||||
this.notifyPortEvent('node:port:click', e, { x, y })
|
||||
}
|
||||
|
||||
onDblClick(e: Dom.DoubleClickEvent, x: number, y: number) {
|
||||
super.onDblClick(e, x, y)
|
||||
this.notify('node:dblclick', this.getEventArgs(e, x, y))
|
||||
this.notifyPortEvent('node:port:dblclick', e, { x, y })
|
||||
}
|
||||
|
||||
onContextMenu(e: Dom.ContextMenuEvent, x: number, y: number) {
|
||||
super.onContextMenu(e, x, y)
|
||||
this.notify('node:contextmenu', this.getEventArgs(e, x, y))
|
||||
this.notifyPortEvent('node:port:contextmenu', e, { x, y })
|
||||
}
|
||||
|
||||
onMouseDown(e: Dom.MouseDownEvent, x: number, y: number) {
|
||||
@ -487,6 +528,7 @@ export class NodeView<
|
||||
return
|
||||
}
|
||||
this.notifyMouseDown(e, x, y)
|
||||
this.notifyPortEvent('node:port:mousedown', e, { x, y })
|
||||
this.startNodeDragging(e, x, y)
|
||||
}
|
||||
|
||||
@ -510,6 +552,7 @@ export class NodeView<
|
||||
})
|
||||
}
|
||||
this.notifyMouseMove(e, x, y)
|
||||
this.notifyPortEvent('node:port:mousemove', e, { x, y })
|
||||
}
|
||||
|
||||
this.setEventData<EventData.Mousemove>(e, data)
|
||||
@ -522,6 +565,7 @@ export class NodeView<
|
||||
this.stopMagnetDragging(e, x, y)
|
||||
} else {
|
||||
this.notifyMouseUp(e, x, y)
|
||||
this.notifyPortEvent('node:port:mouseup', e, { x, y })
|
||||
if (action === 'move') {
|
||||
const meta = data as EventData.Moving
|
||||
const view = meta.targetView || this
|
||||
@ -540,22 +584,26 @@ export class NodeView<
|
||||
onMouseOver(e: Dom.MouseOverEvent) {
|
||||
super.onMouseOver(e)
|
||||
this.notify('node:mouseover', this.getEventArgs(e))
|
||||
this.notifyPortEvent('node:port:mouseover', e)
|
||||
}
|
||||
|
||||
onMouseOut(e: Dom.MouseOutEvent) {
|
||||
super.onMouseOut(e)
|
||||
this.notify('node:mouseout', this.getEventArgs(e))
|
||||
this.notifyPortEvent('node:port:mouseout', e)
|
||||
}
|
||||
|
||||
onMouseEnter(e: Dom.MouseEnterEvent) {
|
||||
this.updateClassName(e)
|
||||
super.onMouseEnter(e)
|
||||
this.notify('node:mouseenter', this.getEventArgs(e))
|
||||
this.notifyPortEvent('node:port:mouseenter', e)
|
||||
}
|
||||
|
||||
onMouseLeave(e: Dom.MouseLeaveEvent) {
|
||||
super.onMouseLeave(e)
|
||||
this.notify('node:mouseleave', this.getEventArgs(e))
|
||||
this.notifyPortEvent('node:port:mouseleave', e)
|
||||
}
|
||||
|
||||
onMouseWheel(e: Dom.EventObject, x: number, y: number, delta: number) {
|
||||
@ -1087,14 +1135,13 @@ export namespace NodeView {
|
||||
interface MagnetEventArgs {
|
||||
magnet: Element
|
||||
}
|
||||
|
||||
export interface MouseEventArgs<E> {
|
||||
e: E
|
||||
node: Node
|
||||
cell: Node
|
||||
view: NodeView
|
||||
port?: string
|
||||
}
|
||||
|
||||
export interface PositionEventArgs<E>
|
||||
extends MouseEventArgs<E>,
|
||||
CellView.PositionEventArgs {}
|
||||
@ -1119,6 +1166,17 @@ export namespace NodeView {
|
||||
'node:mousewheel': PositionEventArgs<Dom.EventObject> &
|
||||
CellView.MouseDeltaEventArgs
|
||||
|
||||
'node:port:click': PositionEventArgs<Dom.ClickEvent>
|
||||
'node:port:dblclick': PositionEventArgs<Dom.DoubleClickEvent>
|
||||
'node:port:contextmenu': PositionEventArgs<Dom.ContextMenuEvent>
|
||||
'node:port:mousedown': PositionEventArgs<Dom.MouseDownEvent>
|
||||
'node:port:mousemove': PositionEventArgs<Dom.MouseMoveEvent>
|
||||
'node:port:mouseup': PositionEventArgs<Dom.MouseUpEvent>
|
||||
'node:port:mouseover': MouseEventArgs<Dom.MouseOverEvent>
|
||||
'node:port:mouseout': MouseEventArgs<Dom.MouseOutEvent>
|
||||
'node:port:mouseenter': MouseEventArgs<Dom.MouseEnterEvent>
|
||||
'node:port:mouseleave': MouseEventArgs<Dom.MouseLeaveEvent>
|
||||
|
||||
'node:customevent': PositionEventArgs<Dom.MouseDownEvent> & {
|
||||
name: string
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
if (window) {
|
||||
(window as any).react = require('react');
|
||||
(window as any).reactDom = require('react-dom');
|
||||
(window as any).antd = require('antd');
|
||||
(window as any).dagre = require('dagre');
|
||||
(window as any).x6 = require('@antv/x6');
|
||||
(window as any).x6PluginSnapline = require('@antv/x6-plugin-snapline');
|
||||
(window as any).x6PluginClipboard = require('@antv/x6-plugin-clipboard');
|
||||
(window as any).x6PluginKeyboard = require('@antv/x6-plugin-keyboard');
|
||||
(window as any).x6PluginSelection = require('@antv/x6-plugin-selection');
|
||||
(window as any).x6PluginTransform = require('@antv/x6-plugin-transform');
|
||||
(window as any).x6PluginStencil = require('@antv/x6-plugin-stencil');
|
||||
(window as any).x6PluginHistory = require('@antv/x6-plugin-history');
|
||||
(window as any).x6ReactShape = require('@antv/x6-react-shape');
|
||||
(window as any).x6Common = require('@antv/x6-common');
|
||||
(window as any).layout = require('@antv/layout');
|
||||
(window as any).classnames = require('classnames');
|
||||
(window as any).hierarchy = require('@antv/hierarchy');
|
||||
(window as any).elkjs = require('elkjs/lib/elk.bundled.js');
|
||||
;(window as any).react = require('react')
|
||||
;(window as any).reactDom = require('react-dom')
|
||||
;(window as any).antd = require('antd')
|
||||
;(window as any).dagre = require('dagre')
|
||||
;(window as any).x6 = require('@antv/x6')
|
||||
;(window as any).x6PluginSnapline = require('@antv/x6-plugin-snapline')
|
||||
;(window as any).x6PluginClipboard = require('@antv/x6-plugin-clipboard')
|
||||
;(window as any).x6PluginKeyboard = require('@antv/x6-plugin-keyboard')
|
||||
;(window as any).x6PluginSelection = require('@antv/x6-plugin-selection')
|
||||
;(window as any).x6PluginTransform = require('@antv/x6-plugin-transform')
|
||||
;(window as any).x6PluginStencil = require('@antv/x6-plugin-stencil')
|
||||
;(window as any).x6PluginHistory = require('@antv/x6-plugin-history')
|
||||
;(window as any).x6ReactShape = require('@antv/x6-react-shape')
|
||||
;(window as any).layout = require('@antv/layout')
|
||||
;(window as any).classnames = require('classnames')
|
||||
;(window as any).hierarchy = require('@antv/hierarchy')
|
||||
;(window as any).elkjs = require('elkjs/lib/elk.bundled.js')
|
||||
}
|
||||
|
@ -1,23 +1,26 @@
|
||||
import { defineConfig } from 'dumi';
|
||||
import { repository, version } from './package.json';
|
||||
import { defineConfig } from 'dumi'
|
||||
import { repository, version } from './package.json'
|
||||
|
||||
export default defineConfig({
|
||||
locales: [{ id: 'zh', name: '中文' }, { id: 'en', name: 'English' }],
|
||||
locales: [
|
||||
{ id: 'zh', name: '中文' },
|
||||
{ id: 'en', name: 'English' },
|
||||
],
|
||||
themeConfig: {
|
||||
title: 'X6',
|
||||
description: 'JavaScript diagramming library',
|
||||
defaultLanguage: 'zh',
|
||||
siteUrl: 'https://x6.antv.antgroup.com',
|
||||
isAntVSite: false,
|
||||
githubUrl: repository, // GitHub 地址
|
||||
showSearch: true, // 是否显示搜索框
|
||||
showGithubCorner: true, // 是否显示头部的 GitHub icon
|
||||
showGithubStars: true, // 是否显示 GitHub star 数量
|
||||
showAntVProductsCard: true, // 是否显示 AntV 产品汇总的卡片
|
||||
showLanguageSwitcher: false, // 是否显示官网语言切换
|
||||
showWxQrcode: true, // 是否显示头部菜单的微信公众号
|
||||
showChartResize: true, // 是否在 demo 页展示图表视图切换
|
||||
showAPIDoc: false, // 是否在 demo 页展示API文档
|
||||
githubUrl: repository, // GitHub 地址
|
||||
showSearch: true, // 是否显示搜索框
|
||||
showGithubCorner: true, // 是否显示头部的 GitHub icon
|
||||
showGithubStars: true, // 是否显示 GitHub star 数量
|
||||
showAntVProductsCard: true, // 是否显示 AntV 产品汇总的卡片
|
||||
showLanguageSwitcher: false, // 是否显示官网语言切换
|
||||
showWxQrcode: true, // 是否显示头部菜单的微信公众号
|
||||
showChartResize: true, // 是否在 demo 页展示图表视图切换
|
||||
showAPIDoc: false, // 是否在 demo 页展示API文档
|
||||
versions: {
|
||||
[version]: 'https://x6.antv.antgroup.com',
|
||||
'1.x': 'https://x6.antv.vision',
|
||||
@ -73,7 +76,8 @@ export default defineConfig({
|
||||
zh: 'X6 是基于 HTML 和 SVG 的图编辑引擎,提供低成本的定制能力和开箱即用的内置扩展,方便我们快速搭建 DAG 图、ER 图、流程图、血缘图等应用。',
|
||||
en: 'X6 是基于 HTML 和 SVG 的图编辑引擎,提供低成本的定制能力和开箱即用的内置扩展,方便我们快速搭建 DAG 图、ER 图、流程图、血缘图等应用。',
|
||||
},
|
||||
image: 'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*A1g0RaZ-GJcAAAAAAAAAAAAADtOHAQ/original',
|
||||
image:
|
||||
'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*A1g0RaZ-GJcAAAAAAAAAAAAADtOHAQ/original',
|
||||
buttons: [
|
||||
{
|
||||
text: {
|
||||
@ -152,19 +156,44 @@ export default defineConfig({
|
||||
zh: '可视化编排可以用简单的方式将复杂的流程呈现出来,让用户更容易理解工作流',
|
||||
en: '可视化编排可以用简单的方式将复杂的流程呈现出来,让用户更容易理解工作流',
|
||||
},
|
||||
image: 'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*QsT0TpxA8-AAAAAAAAAAAAAADtOHAQ/original',
|
||||
image:
|
||||
'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*QsT0TpxA8-AAAAAAAAAAAAAADtOHAQ/original',
|
||||
isAppLogo: true,
|
||||
},
|
||||
],
|
||||
companies: [
|
||||
{ name: '阿里云', img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*V_xMRIvw2iwAAAAAAAAAAABkARQnAQ' },
|
||||
{ name: '支付宝', img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*lYDrRZvcvD4AAAAAAAAAAABkARQnAQ', },
|
||||
{ name: '天猫', img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*BQrxRK6oemMAAAAAAAAAAABkARQnAQ', },
|
||||
{ name: '淘宝网', img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*1l8-TqUr7UcAAAAAAAAAAABkARQnAQ', },
|
||||
{ name: '网上银行', img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*ZAKFQJ5Bz4MAAAAAAAAAAABkARQnAQ', },
|
||||
{ name: '京东', img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*yh-HRr3hCpgAAAAAAAAAAABkARQnAQ', },
|
||||
{ name: 'yunos', img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*_js7SaNosUwAAAAAAAAAAABkARQnAQ', },
|
||||
{ name: '菜鸟', img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*TgV-RZDODJIAAAAAAAAAAABkARQnAQ', },
|
||||
{
|
||||
name: '阿里云',
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*V_xMRIvw2iwAAAAAAAAAAABkARQnAQ',
|
||||
},
|
||||
{
|
||||
name: '支付宝',
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*lYDrRZvcvD4AAAAAAAAAAABkARQnAQ',
|
||||
},
|
||||
{
|
||||
name: '天猫',
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*BQrxRK6oemMAAAAAAAAAAABkARQnAQ',
|
||||
},
|
||||
{
|
||||
name: '淘宝网',
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*1l8-TqUr7UcAAAAAAAAAAABkARQnAQ',
|
||||
},
|
||||
{
|
||||
name: '网上银行',
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*ZAKFQJ5Bz4MAAAAAAAAAAABkARQnAQ',
|
||||
},
|
||||
{
|
||||
name: '京东',
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*yh-HRr3hCpgAAAAAAAAAAABkARQnAQ',
|
||||
},
|
||||
{
|
||||
name: 'yunos',
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*_js7SaNosUwAAAAAAAAAAABkARQnAQ',
|
||||
},
|
||||
{
|
||||
name: '菜鸟',
|
||||
img: 'https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*TgV-RZDODJIAAAAAAAAAAABkARQnAQ',
|
||||
},
|
||||
],
|
||||
docs: [
|
||||
{
|
||||
@ -264,22 +293,21 @@ export default defineConfig({
|
||||
},
|
||||
playground: {
|
||||
extraLib: '',
|
||||
container: '<div id="container"></div>',
|
||||
container:
|
||||
'<div id="container" style="min-width: 400px; min-height: 600px;"></div>',
|
||||
devDependencies: {
|
||||
typescript: 'latest',
|
||||
},
|
||||
},
|
||||
announcement: {
|
||||
zh: '',
|
||||
en: ''
|
||||
}
|
||||
en: '',
|
||||
},
|
||||
},
|
||||
mfsu: false,
|
||||
alias: {
|
||||
'@': __dirname,
|
||||
},
|
||||
links: [
|
||||
],
|
||||
scripts: [
|
||||
],
|
||||
})
|
||||
links: [],
|
||||
scripts: [],
|
||||
})
|
||||
|
@ -1,3 +1,45 @@
|
||||
# @antv/x6-sites [1.5.0](https://github.com/antvis/x6/compare/@antv/x6-sites@1.4.1...@antv/x6-sites@1.5.0) (2023-02-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* keyboard support clear and custom trigger ([#3202](https://github.com/antvis/x6/issues/3202)) ([668c932](https://github.com/antvis/x6/commit/668c93242fbcebb987cccc3dcfd56982f7c66252))
|
||||
|
||||
# @antv/x6-sites [1.4.0](https://github.com/antvis/x6/compare/@antv/x6-sites@1.3.2...@antv/x6-sites@1.4.0) (2023-01-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix index error for priorityQueue ([#3179](https://github.com/antvis/x6/issues/3179)) ([d64150b](https://github.com/antvis/x6/commit/d64150bfadf10fe21f44734a0267261260b8c53b))
|
||||
* prevent highlighting new edge ([#3170](https://github.com/antvis/x6/issues/3170)) ([bd30f7f](https://github.com/antvis/x6/commit/bd30f7f61de530a9b6671aaedd4be2e026de8d44))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add port events ([#3185](https://github.com/antvis/x6/issues/3185)) ([3265fe5](https://github.com/antvis/x6/commit/3265fe5b983f22e34d60c647212824961ecfdab5))
|
||||
|
||||
## @antv/x6-sites [1.3.2](https://github.com/antvis/x6/compare/@antv/x6-sites@1.3.1...@antv/x6-sites@1.3.2) (2023-01-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* change dragging container options ([#3139](https://github.com/antvis/x6/issues/3139)) ([7b091f3](https://github.com/antvis/x6/commit/7b091f35dee147c5e7bf97577e14e11ceb7e8e3d))
|
||||
* update group even group is empty ([#3117](https://github.com/antvis/x6/issues/3117)) ([6abd068](https://github.com/antvis/x6/commit/6abd0683eab22eb0fa1a4702642ab76b91320694))
|
||||
|
||||
## @antv/x6-sites [1.3.1](https://github.com/antvis/x6/compare/@antv/x6-sites@1.3.0...@antv/x6-sites@1.3.1) (2023-01-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* optimize rendering logic to prevent loops ([#3108](https://github.com/antvis/x6/issues/3108)) ([45337e4](https://github.com/antvis/x6/commit/45337e4a62224aaffd60fc8b2670a071c5560796))
|
||||
|
||||
# @antv/x6-sites [1.3.0](https://github.com/antvis/X6/compare/@antv/x6-sites@1.2.2...@antv/x6-sites@1.3.0) (2023-01-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add data processing dag example ([#3091](https://github.com/antvis/X6/issues/3091)) ([d3301d3](https://github.com/antvis/X6/commit/d3301d33d575269d9219ab1337a2ec1785d61494))
|
||||
|
||||
## @antv/x6-sites [1.2.2](https://github.com/antvis/X6/compare/@antv/x6-sites@1.2.1...@antv/x6-sites@1.2.2) (2022-12-24)
|
||||
|
||||
|
||||
|
7
sites/x6-sites/LEGAL.md
Normal file
7
sites/x6-sites/LEGAL.md
Normal file
@ -0,0 +1,7 @@
|
||||
Legal Disclaimer
|
||||
|
||||
Within this source code, the comments in Chinese shall be the original, governing version. Any comment in other languages are for reference only. In the event of any conflict between the Chinese language version comments and other language version comments, the Chinese language version shall prevail.
|
||||
|
||||
法律免责声明
|
||||
|
||||
关于代码注释部分,中文注释为官方版本,其它语言注释仅做参考。中文注释可能与其它语言注释存在不一致,当中文注释与其它语言注释存在不一致时,请以中文注释为准。
|
@ -24,7 +24,7 @@ new Graph(options: Options)
|
||||
| [mousewheel](/zh/docs/api/graph/mousewheel) | boolean \| `MouseWheel.Options` | | 鼠标滚轮缩放,默认禁用。 | `false` |
|
||||
| [grid](/zh/docs/api/graph/grid) | boolean \| number \| `GridManager.Options` | | 网格,默认使用 `10px` 的网格,但不绘制网格背景。 | `false` |
|
||||
| [background](/zh/docs/api/graph/background) | false \| `BackgroundManager.Options` | | 背景,默认不绘制背景。 | `false` |
|
||||
| [translating](/zh/docs/api/interacting/interaction#trasnlating) | `Translating.Options` | | 限制节点移动。 | { restrict: false } |
|
||||
| [translating](/zh/docs/api/interacting/interaction#translating) | `Translating.Options` | | 限制节点移动。 | { restrict: false } |
|
||||
| [embedding](/zh/docs/api/interacting/interaction#embedding) | boolean \| `Embedding.Options` | | 嵌套节点,默认禁用。 | `false` |
|
||||
| [connecting](/zh/docs/api/interacting/interaction#connecting) | `Connecting.Options` | | 连线选项。 | { snap: false, ... } |
|
||||
| [highlighting](/zh/docs/api/interacting/interaction#highlighting) | `Highlighting.Options` | | 高亮选项。 | {...} |
|
||||
|
@ -342,7 +342,7 @@ new Graph({
|
||||
|
||||
上面 `magnetAvailable.name` 其实是高亮器的名称,X6 内置了 `stroke` 和 `className` 两种高亮器,详细信息参考 [Highlighter](/zh/docs/api/registry/highlighter)
|
||||
|
||||
## trasnlating
|
||||
## translating
|
||||
|
||||
可以在全局配置 `translating` 来限制节点的移动范围。
|
||||
|
||||
|
@ -221,11 +221,11 @@ graph.addEdge({
|
||||
|
||||
支持的参数如下表:
|
||||
|
||||
| 参数名 | 参数类型 | 是否必选 | 默认值 | 参数说明 |
|
||||
| --------- | ------------------ | :------: | ------ | -------------------------------------------------------------------------------------------------- | --- | ---- | --- | --------- | ------------------------------------ |
|
||||
| offset | number \| 'center' | 否 | `32` | 路由的第一个点和最后一个点与节点之间的距离。当取值为 `'center'` 时,节点距离的中心作为路由点坐标。 |
|
||||
| min | number | 否 | `16` | 路由的第一个点和最后一个点与节点之间的最小距离。 |
|
||||
| direction | `'T' | 'B' | 'L' | 'R' | 'H' | 'V'` | 否 | undefined | 路由方向,缺省时将自动选择最优方向。 |
|
||||
| 参数名 | 参数类型 | 是否必选 | 默认值 | 参数说明 |
|
||||
| --------- | ---------------------------------------- | -------- | --------- | ------------------------------------------------------------ |
|
||||
| offset | number \|'center' | 否 | `32` | 路由的第一个点和最后一个点与节点之间的距离。当取值为 `'center'` 时,节点距离的中心作为路由点坐标。 |
|
||||
| min | number | 否 | `16` | 路由的第一个点和最后一个点与节点之间的最小距离。 |
|
||||
| direction | `'T'`\|`'B'`\|`'L'`\|`'R'`\|`'H'`\|`'V'` | 否 | undefined | 路由方向,缺省时将自动选择最优方向。 |
|
||||
|
||||
例如:
|
||||
|
||||
|
@ -11,9 +11,9 @@ X6 是基于 HTML 和 SVG 的图编辑引擎,提供低成本的定制能力和
|
||||
如果你还没有使用过 X6, 建议通过 [快速上手](/zh/docs/tutorial/getting-started) 抢先体验 X6 的魅力。
|
||||
|
||||
<p align="left">
|
||||
<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>
|
||||
<a href="https://lgtm.com/projects/g/antvis/x6/context:javascript"><img alt="Language grade: JavaScript" src="https://img.shields.io/lgtm/grade/javascript/g/antvis/x6.svg?logo=lgtm&style=flat-square"></a>
|
||||
<a href="https://github.com/antvis/X6/actions/workflows/ci.yml"><img alt="build" src="https://img.shields.io/github/actions/workflow/status/antvis/x6/ci.yml?branch=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>
|
||||
<a href="https://lgtm.com/projects/g/antvis/x6/context:javascript"><img alt="Language grade: JavaScript" src="https://img.shields.io/lgtm/grade/javascript/g/antvis/x6.svg?logo=lgtm&style=flat-square"></a> -->
|
||||
<a href="https://www.npmjs.com/package/@antv/x6"><img alt="NPM Package" src="https://img.shields.io/npm/v/@antv/x6.svg?style=flat-square"></a>
|
||||
<a href="https://www.npmjs.com/package/@antv/x6"><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/@antv/x6?logo=npm&style=flat-square"></a>
|
||||
</p>
|
||||
|
@ -19,17 +19,17 @@ redirect_from:
|
||||
|
||||
### 鼠标事件
|
||||
|
||||
| 事件 | cell 节点/边 | node 节点 | edge 边 | blank 画布空白区域 |
|
||||
| -------- | ------------------ | ------------------ | ------------------ | ------------------- |
|
||||
| 单击 | `cell:click` | `node:click` | `edge:click` | `blank:click` |
|
||||
| 双击 | `cell:dblclick` | `node:dblclick` | `edge:dblclick` | `blank:dblclick` |
|
||||
| 右键 | `cell:contextmenu` | `node:contextmenu` | `edge:contextmenu` | `blank:contextmenu` |
|
||||
| 鼠标按下 | `cell:mousedown` | `node:mousedown` | `edge:mousedown` | `blank:mousedown` |
|
||||
| 移动鼠标 | `cell:mousemove` | `node:mousemove` | `edge:mousemove` | `blank:mousemove` |
|
||||
| 鼠标抬起 | `cell:mouseup` | `node:mouseup` | `edge:mouseup` | `blank:mouseup` |
|
||||
| 鼠标滚轮 | `cell:mousewheel` | `node:mousewheel` | `edge:mousewheel` | `blank:mousewheel` |
|
||||
| 鼠标进入 | `cell:mouseenter` | `node:mouseenter` | `edge:mouseenter` | `graph:mouseenter` |
|
||||
| 鼠标离开 | `cell:mouseleave` | `node:mouseleave` | `edge:mouseleave` | `graph:mouseleave` |
|
||||
| 事件 | cell 节点/边 | node 节点 | port 连接桩 | edge 边 | blank 画布空白区域 |
|
||||
|-------|---------------------|---------------------|--------------------------|---------------------|----------------------|
|
||||
| 单击 | `cell:click` | `node:click` | `node:port:click` | `edge:click` | `blank:click` |
|
||||
| 双击 | `cell:dblclick` | `node:dblclick` | `node:port:dblclick` | `edge:dblclick` | `blank:dblclick` |
|
||||
| 右键 | `cell:contextmenu` | `node:contextmenu` | `node:port:contextmenu` | `edge:contextmenu` | `blank:contextmenu` |
|
||||
| 鼠标按下 | `cell:mousedown` | `node:mousedown` | `node:port:mousedown` | `edge:mousedown` | `blank:mousedown` |
|
||||
| 移动鼠标 | `cell:mousemove` | `node:mousemove` | `node:port:mousemove` | `edge:mousemove` | `blank:mousemove` |
|
||||
| 鼠标抬起 | `cell:mouseup` | `node:mouseup` | `node:port:mouseup` | `edge:mouseup` | `blank:mouseup` |
|
||||
| 鼠标滚轮 | `cell:mousewheel` | `node:mousewheel` | - | `edge:mousewheel` | `blank:mousewheel` |
|
||||
| 鼠标进入 | `cell:mouseenter` | `node:mouseenter` | `node:port:mouseenter` | `edge:mouseenter` | `graph:mouseenter` |
|
||||
| 鼠标离开 | `cell:mouseleave` | `node:mouseleave` | `node:port:mouseleave` | `edge:mouseleave` | `graph:mouseleave` |
|
||||
|
||||
:::warning{title=注意:}
|
||||
需要注意的是,这里的 `mousemove` 事件和通常的鼠标移动事件有所区别,它需要在鼠标按下后移动鼠标才能触发。
|
||||
|
@ -70,11 +70,12 @@ export default () => {
|
||||
|
||||
| 选项 | 类型 | 必选 | 默认值 | 说明 |
|
||||
| -------------------- | ----------------------------------------------------------------------------------- | :--: | ------ | -------------------------------------------------------------------------------------------------------- |
|
||||
| options.target | Graph | ✓️ | | 目标画布。 |
|
||||
| options.getDragNode | (sourceNode: Node, options: GetDragNodeOptions) => Node | | | 拖拽开始时,获取被拖拽的节点,默认克隆 `dnd.start` 传入的节点。 |
|
||||
| options.getDropNode | (draggingNode: Node, options: GetDropNodeOptions) => Node | | | 拖拽结束时,获取放置到目标画布的节点,默认克隆被拖拽的节点。 |
|
||||
| options.validateNode | (droppingNode: Node, options: ValidateNodeOptions) => boolean \| Promins\<boolean\> | | | 拖拽结束时,验证节点是否可以放置到目标画布中。 |
|
||||
| options.dndContainer | HTMLElement | | | 如果设置 `dndContainer`,在 `dndContainer` 上放开鼠标不会放置节点,常用于 `dnd` 容器处于画布上面的场景。 |
|
||||
| target | Graph | ✓️ | | 目标画布。 |
|
||||
| getDragNode | (sourceNode: Node, options: GetDragNodeOptions) => Node | | | 拖拽开始时,获取被拖拽的节点,默认克隆 `dnd.start` 传入的节点。 |
|
||||
| getDropNode | (draggingNode: Node, options: GetDropNodeOptions) => Node | | | 拖拽结束时,获取放置到目标画布的节点,默认克隆被拖拽的节点。 |
|
||||
| validateNode | (droppingNode: Node, options: ValidateNodeOptions) => boolean \| Promins\<boolean\> | | | 拖拽结束时,验证节点是否可以放置到目标画布中。 |
|
||||
| dndContainer | HTMLElement | | | 如果设置 `dndContainer`,在 `dndContainer` 上放开鼠标不会放置节点,常用于 `dnd` 容器处于画布上面的场景。 |
|
||||
| draggingContainer | HTMLElement | | `document.body` | 自定义拖拽画布容器。 |
|
||||
|
||||
## 常见问题
|
||||
|
||||
|
@ -54,6 +54,7 @@ graph.use(
|
||||
| 属性名 | 类型 | 默认值 | 必选 | 描述 |
|
||||
| ---------------- | ------------------------------- | ------- | ---- | ---------------------------------------------------------------------------------------------------- |
|
||||
| enabled | boolean | `false` | | 是否开启撤销重做功能 |
|
||||
| stackSize | number | `0` | | `stackSize` 为 0 表示不限制历史记录栈的长度,如果设置为其他数字表示最多只会记录该数字长度的历史记录 |
|
||||
| ignoreAdd | boolean | `false` | | `ignoreAdd` 如果为 `true`,添加添加元素不会被记录到历史记录 |
|
||||
| ignoreRemove | boolean | `false` | | `ignoreRemove` 如果为 `true`,删除元素不会被记录到历史记录 |
|
||||
| ignoreChange | boolean | `false` | | `ignoreChange` 如果为 `true`,元素属性变化是否被记录到历史记录 |
|
||||
|
@ -107,6 +107,25 @@ unbindKey(
|
||||
|
||||
解绑快捷键。
|
||||
|
||||
### graph.clearKeys()
|
||||
|
||||
```sign
|
||||
clearKeys(): this
|
||||
```
|
||||
|
||||
清除所有快捷键。
|
||||
|
||||
### graph.triggerKey()
|
||||
|
||||
```sign
|
||||
triggerKey(
|
||||
keys: string,
|
||||
action?: 'keypress' | 'keydown' | 'keyup',
|
||||
): this
|
||||
```
|
||||
|
||||
手动触发快捷键。
|
||||
|
||||
### graph.isKeyboardEnabled()
|
||||
|
||||
```sign
|
||||
|
@ -55,7 +55,6 @@ graph.use(
|
||||
| width | number | - | | `Scroller` 的宽度,默认为画布容器宽度 |
|
||||
| height | number | - | | `Scroller` 的高度,默认为画布容器高度 |
|
||||
| modifiers | ModifierKey | - | | 设置修饰键后需要点击鼠标并按下修饰键才能触发画布拖拽 |
|
||||
| cursor | string | - | | 画布鼠标样式,默认为空。当 `cursor` 为空并开启拖拽时,将自动为画布设置 `grab` 鼠标样式 |
|
||||
| pageWidth | number | - | | 每一页的宽度,默认为画布容器宽度 |
|
||||
| pageHeight | number | - | | 每一页的高度,默认为画布容器高度 |
|
||||
| pageVisible | boolean | `false` | | 是否分页 |
|
||||
|
@ -62,8 +62,8 @@ graph.use(
|
||||
| className | string | - | | 附加样式名,用于定制样式 |
|
||||
| multiple | boolean | `true` | | 是否启用点击多选,启用后按住 `ctrl` 或 `command` 键点击节点实现多选 |
|
||||
| multipleSelectionModifiers | ModifierKey | `['ctrl', 'meta']` | | 用于设置上面点击多选配套的修饰键 |
|
||||
| rubberband | boolean | `false` | | 是否启用多选节点功能 |
|
||||
| modifiers | ModifierKey | - | | 设置修饰键后需要点击鼠标并按下修饰键才能触发多选 |
|
||||
| rubberband | boolean | `false` | | 是否启用框选节点功能 |
|
||||
| modifiers | ModifierKey | - | | 用于设置上面框选配套的修饰键 |
|
||||
| strict | boolean | `false` | | 选框是否需要完全包围节点时才选中节点 |
|
||||
| movable | boolean | `true` | | 拖动选框时框选的节点是否一起移动 |
|
||||
| content | string | - | | 设置附加显示的内容 |
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node, Path, Edge, Platform } from '@antv/x6'
|
||||
import { Graph, Node, Path, Edge, Platform, StringExt } from '@antv/x6'
|
||||
import { Selection } from '@antv/x6-plugin-selection'
|
||||
import { StringExt } from '@antv/x6-common'
|
||||
import classnames from 'classnames'
|
||||
import insertCss from 'insert-css'
|
||||
import { register } from '@antv/x6-react-shape'
|
||||
@ -57,12 +56,16 @@ const PROCESSING_TYPE_LIST = [
|
||||
|
||||
// 不同节点类型的icon
|
||||
const NODE_TYPE_LOGO = {
|
||||
INPUT: 'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*RXnuTpQ22xkAAAAAAAAAAAAADtOHAQ/original', // 数据输入
|
||||
FILTER: 'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*ZJ6qToit8P4AAAAAAAAAAAAADtOHAQ/original', // 数据筛选
|
||||
INPUT:
|
||||
'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*RXnuTpQ22xkAAAAAAAAAAAAADtOHAQ/original', // 数据输入
|
||||
FILTER:
|
||||
'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*ZJ6qToit8P4AAAAAAAAAAAAADtOHAQ/original', // 数据筛选
|
||||
JOIN: 'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*EHqyQoDeBvIAAAAAAAAAAAAADtOHAQ/original', // 数据连接
|
||||
UNION: 'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*k4eyRaXv8gsAAAAAAAAAAAAADtOHAQ/original', // 数据合并
|
||||
UNION:
|
||||
'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*k4eyRaXv8gsAAAAAAAAAAAAADtOHAQ/original', // 数据合并
|
||||
AGG: 'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*TKG8R6nfYiAAAAAAAAAAAAAADtOHAQ/original', // 数据聚合
|
||||
OUTPUT: 'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*zUgORbGg1HIAAAAAAAAAAAAADtOHAQ/original', // 数据输出
|
||||
OUTPUT:
|
||||
'https://mdn.alipayobjects.com/huamei_f4t1bn/afts/img/A*zUgORbGg1HIAAAAAAAAAAAAADtOHAQ/original', // 数据输出
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,7 +108,7 @@ const getDownstreamNodePosition = (
|
||||
|
||||
return {
|
||||
x: minX !== Infinity ? minX : position.x + dx,
|
||||
y: maxY !== -Infinity ? maxY + dy : position.y,
|
||||
y: maxY !== -Infinity ? maxY + dy : position.y,
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,8 +164,12 @@ export const createNode = (
|
||||
return {}
|
||||
}
|
||||
let newNode = {}
|
||||
const sameTypeNodes = graph.getNodes().filter(item => item.getData()?.type === type);
|
||||
const typeName = PROCESSING_TYPE_LIST?.find((item) => item.type === type)?.name;
|
||||
const sameTypeNodes = graph
|
||||
.getNodes()
|
||||
.filter((item) => item.getData()?.type === type)
|
||||
const typeName = PROCESSING_TYPE_LIST?.find(
|
||||
(item) => item.type === type,
|
||||
)?.name
|
||||
const id = StringExt.uuid()
|
||||
const node = {
|
||||
id,
|
||||
@ -243,21 +250,24 @@ class DataProcessingDagNode extends React.Component<{
|
||||
getPlusDagMenu = () => {
|
||||
return (
|
||||
<ul>
|
||||
{
|
||||
PROCESSING_TYPE_LIST.map((item) => {
|
||||
const content = (
|
||||
<a onClick={() => this.clickPlusDragMenu(item.type)}>
|
||||
<i
|
||||
className="node-mini-logo"
|
||||
style={{ backgroundImage: `url(${NODE_TYPE_LOGO[item.type]})` }}
|
||||
/>
|
||||
{PROCESSING_TYPE_LIST.map((item) => {
|
||||
const content = (
|
||||
// eslint-disable-next-line
|
||||
<a onClick={() => this.clickPlusDragMenu(item.type)}>
|
||||
<i
|
||||
className="node-mini-logo"
|
||||
style={{ backgroundImage: `url(${NODE_TYPE_LOGO[item.type]})` }}
|
||||
/>
|
||||
|
||||
<span>{item.name}</span>
|
||||
</a>
|
||||
)
|
||||
return <li className="each-sub-menu">{content}</li>
|
||||
})
|
||||
}
|
||||
<span>{item.name}</span>
|
||||
</a>
|
||||
)
|
||||
return (
|
||||
<li className="each-sub-menu" key={item.type}>
|
||||
{content}
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
@ -273,9 +283,12 @@ class DataProcessingDagNode extends React.Component<{
|
||||
onMainMouseEnter = () => {
|
||||
const { node } = this.props
|
||||
// 获取该节点下的所有连接桩
|
||||
const ports = node.getPorts() || [];
|
||||
const ports = node.getPorts() || []
|
||||
ports.forEach((port) => {
|
||||
node.setPortProp(port.id, 'attrs/circle', { fill: '#fff', stroke: '#85A5FF' })
|
||||
node.setPortProp(port.id, 'attrs/circle', {
|
||||
fill: '#fff',
|
||||
stroke: '#85A5FF',
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -285,7 +298,10 @@ class DataProcessingDagNode extends React.Component<{
|
||||
// 获取该节点下的所有连接桩
|
||||
const ports = node.getPorts() || []
|
||||
ports.forEach((port) => {
|
||||
node.setPortProp(port.id, 'attrs/circle', { fill: 'transparent', stroke: 'transparent' })
|
||||
node.setPortProp(port.id, 'attrs/circle', {
|
||||
fill: 'transparent',
|
||||
stroke: 'transparent',
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -404,21 +420,31 @@ Graph.registerConnector(
|
||||
(sourcePoint, targetPoint) => {
|
||||
const hgap = Math.abs(targetPoint.x - sourcePoint.x)
|
||||
const path = new Path()
|
||||
path.appendSegment(Path.createSegment('M', sourcePoint.x - 4, sourcePoint.y))
|
||||
path.appendSegment(Path.createSegment('L', sourcePoint.x + 12, sourcePoint.y))
|
||||
path.appendSegment(
|
||||
Path.createSegment('M', sourcePoint.x - 4, sourcePoint.y),
|
||||
)
|
||||
path.appendSegment(
|
||||
Path.createSegment('L', sourcePoint.x + 12, sourcePoint.y),
|
||||
)
|
||||
// 水平三阶贝塞尔曲线
|
||||
path.appendSegment(
|
||||
Path.createSegment(
|
||||
'C',
|
||||
sourcePoint.x < targetPoint.x ? sourcePoint.x + hgap / 2 : sourcePoint.x - hgap / 2,
|
||||
sourcePoint.x < targetPoint.x
|
||||
? sourcePoint.x + hgap / 2
|
||||
: sourcePoint.x - hgap / 2,
|
||||
sourcePoint.y,
|
||||
sourcePoint.x < targetPoint.x ? targetPoint.x - hgap / 2 : targetPoint.x + hgap / 2,
|
||||
sourcePoint.x < targetPoint.x
|
||||
? targetPoint.x - hgap / 2
|
||||
: targetPoint.x + hgap / 2,
|
||||
targetPoint.y,
|
||||
targetPoint.x - 6,
|
||||
targetPoint.y,
|
||||
),
|
||||
)
|
||||
path.appendSegment(Path.createSegment('L', targetPoint.x + 2, targetPoint.y))
|
||||
path.appendSegment(
|
||||
Path.createSegment('L', targetPoint.x + 2, targetPoint.y),
|
||||
)
|
||||
|
||||
return path.serialize()
|
||||
},
|
||||
@ -521,7 +547,7 @@ const graph: Graph = new Graph({
|
||||
})
|
||||
},
|
||||
// 连接桩校验
|
||||
validateConnection({ sourceView, targetView, sourceMagnet, targetMagnet }) {
|
||||
validateConnection({ sourceMagnet, targetMagnet }) {
|
||||
// 只能从输出链接桩创建连接
|
||||
if (!sourceMagnet || sourceMagnet.getAttribute('port-group') === 'in') {
|
||||
return false
|
||||
@ -535,14 +561,16 @@ const graph: Graph = new Graph({
|
||||
},
|
||||
})
|
||||
|
||||
graph.use(new Selection({
|
||||
enabled: true,
|
||||
multiple: true,
|
||||
rubberEdge: true,
|
||||
rubberNode: true,
|
||||
modifiers: 'shift',
|
||||
rubberband: true,
|
||||
}))
|
||||
graph.use(
|
||||
new Selection({
|
||||
enabled: true,
|
||||
multiple: true,
|
||||
rubberEdge: true,
|
||||
rubberNode: true,
|
||||
modifiers: 'shift',
|
||||
rubberband: true,
|
||||
}),
|
||||
)
|
||||
|
||||
// 节点状态列表
|
||||
const nodeStatusList = [
|
||||
@ -565,7 +593,7 @@ const nodeStatusList = [
|
||||
{
|
||||
id: 'node-4',
|
||||
status: 'error',
|
||||
statusMsg: '错误信息示例'
|
||||
statusMsg: '错误信息示例',
|
||||
},
|
||||
]
|
||||
|
||||
@ -656,7 +684,6 @@ fetch('/data/data-processing-dag.json')
|
||||
}, 3000)
|
||||
})
|
||||
|
||||
|
||||
insertCss(`
|
||||
.data-processing-dag-node {
|
||||
display: flex;
|
||||
|
@ -23,12 +23,7 @@ const graph = new Graph({
|
||||
maxScale: 3,
|
||||
},
|
||||
connecting: {
|
||||
router: {
|
||||
name: 'manhattan',
|
||||
args: {
|
||||
padding: 1,
|
||||
},
|
||||
},
|
||||
router: 'manhattan',
|
||||
connector: {
|
||||
name: 'rounded',
|
||||
args: {
|
||||
@ -77,27 +72,39 @@ const graph = new Graph({
|
||||
|
||||
// #region 使用插件
|
||||
graph
|
||||
.use(new Transform({
|
||||
resizing: true,
|
||||
rotating: true,
|
||||
}))
|
||||
.use(new Selection({
|
||||
enabled: true,
|
||||
rubberband: true,
|
||||
showNodeSelectionBox: true,
|
||||
}))
|
||||
.use(new Snapline({
|
||||
enabled: true,
|
||||
}))
|
||||
.use(new Keyboard({
|
||||
enabled: true,
|
||||
}))
|
||||
.use(new Clipboard({
|
||||
enabled: true,
|
||||
}))
|
||||
.use(new History({
|
||||
enabled: true,
|
||||
}))
|
||||
.use(
|
||||
new Transform({
|
||||
resizing: true,
|
||||
rotating: true,
|
||||
}),
|
||||
)
|
||||
.use(
|
||||
new Selection({
|
||||
enabled: true,
|
||||
rubberband: true,
|
||||
showNodeSelectionBox: true,
|
||||
}),
|
||||
)
|
||||
.use(
|
||||
new Snapline({
|
||||
enabled: true,
|
||||
}),
|
||||
)
|
||||
.use(
|
||||
new Keyboard({
|
||||
enabled: true,
|
||||
}),
|
||||
)
|
||||
.use(
|
||||
new Clipboard({
|
||||
enabled: true,
|
||||
}),
|
||||
)
|
||||
.use(
|
||||
new History({
|
||||
enabled: true,
|
||||
}),
|
||||
)
|
||||
// #endregion
|
||||
|
||||
// #region 初始化 stencil
|
||||
@ -154,7 +161,7 @@ graph.bindKey(['meta+v', 'ctrl+v'], () => {
|
||||
return false
|
||||
})
|
||||
|
||||
//undo redo
|
||||
// undo redo
|
||||
graph.bindKey(['meta+z', 'ctrl+z'], () => {
|
||||
if (graph.canUndo()) {
|
||||
graph.undo()
|
||||
@ -176,7 +183,7 @@ graph.bindKey(['meta+a', 'ctrl+a'], () => {
|
||||
}
|
||||
})
|
||||
|
||||
//delete
|
||||
// delete
|
||||
graph.bindKey('backspace', () => {
|
||||
const cells = graph.getSelectedCells()
|
||||
if (cells.length) {
|
||||
@ -200,7 +207,7 @@ graph.bindKey(['ctrl+2', 'meta+2'], () => {
|
||||
|
||||
// 控制连接桩显示/隐藏
|
||||
const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
|
||||
for (let i = 0, len = ports.length; i < len; i = i + 1) {
|
||||
for (let i = 0, len = ports.length; i < len; i += 1) {
|
||||
ports[i].style.visibility = show ? 'visible' : 'hidden'
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@antv/x6-sites",
|
||||
"version": "1.2.2",
|
||||
"version": "2.3.0",
|
||||
"description": "X6 sites deployed on gh-pages",
|
||||
"scripts": {
|
||||
"dev": "dumi dev",
|
||||
@ -14,7 +14,7 @@
|
||||
"sites"
|
||||
],
|
||||
"dependencies": {
|
||||
"@antv/dumi-theme-antv": "^0.3.0-beta.22",
|
||||
"@antv/dumi-theme-antv": "^0.3.5",
|
||||
"@antv/hierarchy": "^0.6.6",
|
||||
"@antv/layout": "^0.3.12",
|
||||
"@antv/x6": "^2.x",
|
||||
@ -33,13 +33,13 @@
|
||||
"@antv/x6-react-shape": "^2.x",
|
||||
"antd": "^4.4.2",
|
||||
"dagre": "^0.8.5",
|
||||
"dumi": "^2.x",
|
||||
"dumi": "2.0.16",
|
||||
"elkjs": "^0.8.2",
|
||||
"highlight.js": "^10.1.2",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"react-i18next": "^11.5.0",
|
||||
"classnames": "^2.2.6",
|
||||
"@antv/x6-common": "^2.0.x"
|
||||
}
|
||||
"classnames": "^2.2.6"
|
||||
},
|
||||
"repository": "https://github.com/antvis/x6"
|
||||
}
|
||||
|
Reference in New Issue
Block a user