Compare commits

..

31 Commits

Author SHA1 Message Date
Struggle Roue
fba531064a feat: history add max stack size (#3253)
* feat: init

* feat: add demo

* feat: add demo

* feat: add demo

* feat: limit undoStack size

* feat: 0 means not limit

---------

Co-authored-by: lijianqiang.seven <lijianqiang.seven@bytedance.com>
Co-authored-by: zhangzirui.1993 <zhangzirui.1993@bytedance.com>
2023-02-17 21:46:59 +08:00
Lloyd Zhou
04656f33f4 feat: add updateNode/updateEdge API #3235 (#3239)
* feat: add updateNode/updateEdge API #3235

* feat: add updateNode/updateEdge API #3235

* feat: update return value

* fix: call error create function
2023-02-17 21:27:40 +08:00
x6-bot[bot]
441dd564b4 chore: update CONTRIBUTORS [skip ci] 2023-02-16 11:11:30 +00:00
vector
9ccda3e96f fix: donot empty text when only has title elem (#3248) 2023-02-16 19:04:46 +08:00
x6-bot[bot]
979b2556e9 chore: update contributors [skip ci] 2023-02-16 01:29:34 +00:00
x6-bot[bot]
153013a606 chore: update CONTRIBUTORS [skip ci] 2023-02-15 03:16:40 +00:00
Struggle Roue
2c7b966f45 chore: queueJob optimize (#3226)
* chore: queueJob optimize

* chore: queueJob optimize

* chore: queueJob optimize
2023-02-15 11:10:00 +08:00
x6-bot[bot]
b199153f3b chore: update CONTRIBUTORS [skip ci] 2023-02-13 15:12:24 +00:00
x6-bot[bot]
608ce9ac6c chore: update contributors [skip ci] 2023-02-13 15:05:20 +00:00
Xia Wenqi
eb921f7018 docs: fix typo (#3234) 2023-02-13 23:04:59 +08:00
x6-bot[bot]
68e7132213 chore: update contributors [skip ci] 2023-02-12 01:29:21 +00:00
x6-bot[bot]
62aa5323ce chore: update contributors [skip ci] 2023-02-11 01:28:45 +00:00
x6-bot[bot]
e380cba7d9 chore: update CONTRIBUTORS [skip ci] 2023-02-10 02:03:59 +00:00
vector
8fada570e4 fix: add padding options for position api (#3225) 2023-02-10 09:57:41 +08:00
vector
1096bf171b fix: fix scroller options typo (#3224) 2023-02-10 09:57:22 +08:00
x6-bot[bot]
1834cd2143 chore: update contributors [skip ci] 2023-02-09 06:26:51 +00:00
Struggle Roue
1cf9cb654f chore: should use local to format (#3222) 2023-02-09 14:26:30 +08:00
x6-bot[bot]
b392d78856 chore(release): release 3 packages [skip ci]
[@antv/x6@2.3.0](https://www.npmjs.com/package/@antv/x6/v/2.3.0)
[@antv/x6@2.3.0](https://github.com/antvis/X6/releases/tag/%40antv/x6%402.3.0)

[@antv/x6-plugin-keyboard@2.2.0](https://www.npmjs.com/package/@antv/x6-plugin-keyboard/v/2.2.0)
[@antv/x6-plugin-keyboard@2.2.0](https://github.com/antvis/X6/releases/tag/%40antv/x6-plugin-keyboard%402.2.0)

[@antv/x6-sites@1.5.0](https://github.com/antvis/X6/releases/tag/%40antv/x6-sites%401.5.0)
2023-02-06 14:39:13 +00:00
vector
58c0fe459c feat: add options for positionCell api (#3208) 2023-02-06 22:28:20 +08:00
x6-bot[bot]
8a510fa8f8 chore: update contributors [skip ci] 2023-02-06 14:16:48 +00:00
Struggle Roue
668c93242f feat: keyboard support clear and custom trigger (#3202)
* feat: keyboard support clear and custom trigger

* feat: keyboard support clear and custom trigger

* feat: add return this

* feat: add doc

* feat: add doc

* feat: adjust order

* feat: change order

---------

Co-authored-by: Struggle <lijianqiang.seven@bytedance.com>
2023-02-06 22:16:28 +08:00
x6-bot[bot]
c122b2122c chore: update CONTRIBUTORS [skip ci] 2023-02-06 04:14:50 +00:00
x6-bot[bot]
3b9957efbb chore: update contributors [skip ci] 2023-02-06 04:08:38 +00:00
Samuel Bodin
1f83a2b8a8 fix(scheduler): remove spammy console.log (#3200)
fix: remove spammy console.log

Hey, 
This console.log ended up in production build, not sure it was on purpose.
2023-02-06 12:08:14 +08:00
x6-bot[bot]
6699c2bd00 chore: update contributors [skip ci] 2023-02-03 06:10:28 +00:00
Struggle Roue
7192209a5c Feat plugins dis and en (#3171)
* fix: graph plugin support disable and enable

* fix: graph plugin support disable and enable

* fix: graph plugin support disable and enable and add getPlugins

* fix: deal compatibility problem

* chore: unify plugin disable and enable return value

* chore: unify plugin disable and enable return value

* feat: add disposePlugins and isEnabled

* feat: optimize test form

---------

Co-authored-by: seven <lijianqiang.seven@bytedance.com>
2023-02-03 14:10:03 +08:00
bubkoo
5da5575451 chore: remove empty line in comment 2023-02-03 12:13:15 +08:00
bubkoo
3377049a49 chore: checkout repo without credentials 2023-02-03 12:13:15 +08:00
x6-bot[bot]
4e76734cee chore(release): release 1 package [skip ci]
[@antv/x6@2.2.1](https://www.npmjs.com/package/@antv/x6/v/2.2.1)
[@antv/x6@2.2.1](https://github.com/antvis/X6/releases/tag/%40antv/x6%402.2.1)
2023-02-02 09:13:25 +00:00
vector
3a59703f1c fix: ensure the container in html view (#3196) 2023-02-02 17:00:48 +08:00
vector
45218c36f6 fix: set correct scroller options (#3195) 2023-02-02 16:39:46 +08:00
34 changed files with 499 additions and 128 deletions

View File

@@ -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:

View File

@@ -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: |

View File

@@ -28,14 +28,17 @@ Opportunity <opportunity@live.in>
Questions <chip@twostewards.com>
RuiLin Dong <48054715+halodong@users.noreply.github.com>
SSC <273702440@qq.com>
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 Zeugner <tomsoftware@gmx.de>
Tony Wu <93302820+tonywu6@users.noreply.github.com>
Utopia <greatauk11@gmail.com>
XLZY <1017866168@qq.com>
Xia Wenqi <xiawenqi90@gmail.com>
Xingjian Zhang <44231913+THUzxj@users.noreply.github.com>
Zhenyu Hou <skyking_H@hotmail.com>
_XiaoTian <istianlei@qq.com>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 12 MiB

After

Width:  |  Height:  |  Size: 13 MiB

View 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>
)
}
}

View File

@@ -179,6 +179,10 @@ const dataSource = [
example: 'animation/transition',
description: '动画',
},
{
example: 'history',
description: '时光回溯',
},
].map((item, index) => ({ key: index, ...item }))
const columns = [

View File

@@ -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>
)
}

View File

@@ -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.

View File

@@ -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) {

View File

@@ -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

View File

@@ -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)

View File

@@ -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",

View File

@@ -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
}

View File

@@ -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

View File

@@ -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')

View File

@@ -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",

View File

@@ -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'>
}

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -29,12 +29,10 @@ export class Snapline extends Disposable {
enable() {
this.snaplineImpl.enable()
return this
}
disable() {
this.snaplineImpl.disable()
return this
}
toggleEnabled(enabled?: boolean) {

View File

@@ -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)

View File

@@ -1,3 +1,22 @@
# @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)

View File

@@ -1,6 +1,6 @@
{
"name": "@antv/x6",
"version": "2.2.0",
"version": "2.3.0",
"description": "JavaScript diagramming library that uses SVG and HTML for rendering",
"main": "lib/index.js",
"module": "es/index.js",

View File

@@ -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)
}
@@ -1198,6 +1219,53 @@ export class Graph extends Basecoat<EventArgs> {
) as T
}
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
}
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
// #region dispose
@@ -1343,5 +1411,8 @@ export namespace Graph {
name: string
init: (graph: Graph, ...options: any[]) => any
dispose: () => void
disable?: () => void
enable?: () => void
isEnabled?: () => boolean
}
}

View File

@@ -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(

View File

@@ -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) {

View File

@@ -215,7 +215,6 @@ export class Scheduler extends Disposable {
}
if (result) {
console.log('left flag', result) // eslint-disable-line
if (
cell.isEdge() &&
(result & view.getFlag(['source', 'target'])) === 0

View File

@@ -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]

View File

@@ -1,3 +1,10 @@
# @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)

View File

@@ -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` | | 高亮选项。 | {...} |

View File

@@ -342,7 +342,7 @@ new Graph({
上面 `magnetAvailable.name` 其实是高亮器的名称X6 内置了 `stroke``className` 两种高亮器,详细信息参考 [Highlighter](/zh/docs/api/registry/highlighter)
## trasnlating
## translating
可以在全局配置 `translating` 来限制节点的移动范围。

View File

@@ -107,6 +107,25 @@ unbindKey(
解绑快捷键。
### graph.clearKeys()
```sign
clearKeys(): this
```
清除所有快捷键。
### graph.triggerKey()
```sign
triggerKey(
keys: string,
action?: 'keypress' | 'keydown' | 'keyup',
): this
```
手动触发快捷键。
### graph.isKeyboardEnabled()
```sign

View File

@@ -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'
}
}

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "@antv/x6-sites",
"version": "1.4.0",
"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",