Compare commits
32 Commits
2.0.1-beta
...
v2.0.6-bet
Author | SHA1 | Date | |
---|---|---|---|
8d645f980a | |||
1701150042 | |||
6b8d7a4ef2 | |||
8a17bfac81 | |||
14ba132592 | |||
f43e0a5417 | |||
25b238fd0b | |||
bf536778ca | |||
693e351957 | |||
9a95594a72 | |||
b7cef9edd2 | |||
f4c977759f | |||
1f653d27d4 | |||
27f27f1e75 | |||
cff8c126de | |||
346c6a268a | |||
f53f819043 | |||
f351284809 | |||
12c67255ae | |||
7e179844dc | |||
bc5284c6fe | |||
ad63046e89 | |||
12f0345555 | |||
5e0e2acde7 | |||
a10dcdb29f | |||
394c945fa2 | |||
ecfd4263b1 | |||
6ce3980f86 | |||
a09deaadd0 | |||
b8576ce96a | |||
aafdab63ba | |||
41f6b252ac |
@ -8,7 +8,6 @@
|
||||
"pretty-quick": "^3.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.3",
|
||||
"release-it": "^14.0.1"
|
||||
"typescript": "^4.4.3"
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
"build": "umi build",
|
||||
"postinstall": "umi generate tmp",
|
||||
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
|
||||
"test": "umi-test",
|
||||
"lint": "umi-lint --eslint src/ -p.no-semi --prettier --fix",
|
||||
"test:coverage": "umi-test --coverage"
|
||||
},
|
||||
|
@ -7,7 +7,6 @@
|
||||
"build": "umi build",
|
||||
"postinstall": "umi generate tmp",
|
||||
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
|
||||
"test": "umi-test",
|
||||
"test:coverage": "umi-test --coverage"
|
||||
},
|
||||
"gitHooks": {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@antv/x6-example-features",
|
||||
"version": "1.2.2",
|
||||
"version": "2.0.2-beta.0",
|
||||
"scripts": {
|
||||
"start": "umi dev",
|
||||
"build": "umi build",
|
||||
@ -10,8 +10,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/x6": "^1.30.2",
|
||||
"@antv/x6-react-components": "^1.1.16",
|
||||
"@antv/x6-react-shape": "^1.6.0",
|
||||
"@antv/x6-next": "^2.0.6-beta.0",
|
||||
"@antv/x6-react-components": "^2.0.6-beta.0",
|
||||
"@antv/x6-react-shape": "^2.0.6-beta.0",
|
||||
"@antv/x6-vector": "^1.3.0",
|
||||
"antd": "^4.4.2",
|
||||
"classnames": "^2.2.6",
|
||||
|
@ -5,12 +5,11 @@ import '../index.less'
|
||||
class BallView extends NodeView {
|
||||
protected speed: number = 0
|
||||
protected angle: number = 0
|
||||
protected timerId: number = 0
|
||||
protected edge: Edge | null
|
||||
|
||||
protected init() {
|
||||
this.timerId = this.cell.transition('attrs/label/opacity', 1, {
|
||||
delay: (1 + Math.random()) * 3000,
|
||||
this.cell.transition('attrs/label/opacity', 1, {
|
||||
delay: 0,
|
||||
duration: 3000,
|
||||
timing: 'inout',
|
||||
interp: function (a: number, b: number) {
|
||||
@ -97,17 +96,13 @@ class BallView extends NodeView {
|
||||
}
|
||||
|
||||
onMouseDown(e: JQuery.MouseDownEvent, x: number, y: number) {
|
||||
console.log('mousedown1')
|
||||
// Do not allow drag element while it's still in a transition.
|
||||
if (this.cell.getTransitions().indexOf('position') > -1) {
|
||||
console.log('mousedown2')
|
||||
return
|
||||
}
|
||||
|
||||
// Cancel displaying 'drag me!' if dragging already starts.
|
||||
if (this.timerId) {
|
||||
clearTimeout(this.timerId)
|
||||
delete this.timerId
|
||||
}
|
||||
|
||||
this.edge = this.graph.addEdge({
|
||||
shape: 'edge',
|
||||
source: this.cell.getBBox().getCenter(),
|
@ -1,5 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Graph, Cell, Point, Timing, Interp } from '@antv/x6'
|
||||
import { Graph, Cell } from '@antv/x6-next'
|
||||
import { Point } from '@antv/x6-geometry'
|
||||
import { Timing, Interp } from '@antv/x6-common'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
@ -11,6 +13,9 @@ export default class Example extends React.Component {
|
||||
width: 650,
|
||||
height: 400,
|
||||
grid: 1,
|
||||
background: {
|
||||
color: '#F2F7FA',
|
||||
},
|
||||
})
|
||||
|
||||
const ball = graph.addNode({
|
||||
@ -23,9 +28,12 @@ export default class Example extends React.Component {
|
||||
label: {
|
||||
text: 'ball',
|
||||
fontSize: 20,
|
||||
stroke: '#8f8f8f',
|
||||
},
|
||||
body: {
|
||||
fill: '#FFFFFF',
|
||||
stroke: '#8f8f8f',
|
||||
strokeWidth: 1,
|
||||
},
|
||||
},
|
||||
})
|
||||
@ -59,7 +67,6 @@ export default class Example extends React.Component {
|
||||
{
|
||||
delay: 5000,
|
||||
duration: 2000,
|
||||
easing: 'easeInBounce',
|
||||
interp: (
|
||||
start: { text: String; fontSize: number },
|
||||
end: { text: String; fontSize: number },
|
||||
@ -84,9 +91,12 @@ export default class Example extends React.Component {
|
||||
label: {
|
||||
text: 'u.f.o.',
|
||||
fontSize: 10,
|
||||
stroke: '8f8f8f',
|
||||
},
|
||||
body: {
|
||||
fill: '#FFFFFF',
|
||||
stroke: '#8f8f8f',
|
||||
strokeWidth: 1,
|
||||
},
|
||||
},
|
||||
})
|
@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import { Graph, Cell } from '@antv/x6'
|
||||
import { Graph, Cell } from '@antv/x6-next'
|
||||
import { Bus, Connector, Component, Fader, Aux } from './shapes'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
@ -12,9 +12,6 @@ export default class Example extends React.Component {
|
||||
container: this.container,
|
||||
width: 1000,
|
||||
height: 800,
|
||||
async: true,
|
||||
frozen: true,
|
||||
sorting: 'approx',
|
||||
translating: {
|
||||
restrict: true,
|
||||
},
|
||||
@ -206,8 +203,6 @@ export default class Example extends React.Component {
|
||||
connector24,
|
||||
connector25,
|
||||
] as any)
|
||||
|
||||
graph.unfreeze()
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Node, Shape } from '@antv/x6'
|
||||
import { Node, Shape } from '@antv/x6-next'
|
||||
|
||||
export class Bus extends Shape.Edge {
|
||||
static create(x: number, label: string, color: string) {
|
||||
|
@ -23,3 +23,9 @@
|
||||
box-shadow: 0 0 10px 1px #e9e9e9;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.home {
|
||||
width: 800px;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
@ -1,9 +1,42 @@
|
||||
import React from 'react'
|
||||
import { Table } from 'antd'
|
||||
import './index.less'
|
||||
|
||||
const dataSource = [
|
||||
{
|
||||
key: '1',
|
||||
example: 'animation/transition',
|
||||
description: 'transition 动画',
|
||||
},
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'example',
|
||||
dataIndex: 'example',
|
||||
render(text: string) {
|
||||
return (
|
||||
<a href={`./${text}`} target="_blank">
|
||||
{text}
|
||||
</a>
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'description',
|
||||
dataIndex: 'description',
|
||||
},
|
||||
]
|
||||
|
||||
export default function () {
|
||||
return (
|
||||
<div>
|
||||
<h1>Feature List</h1>
|
||||
<div className="home">
|
||||
<Table
|
||||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Graph } from '@antv/x6-next'
|
||||
import { Keyboard } from '@antv/x6-plugin-keyboard'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
@ -11,17 +12,28 @@ export default class Example extends React.Component {
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
selecting: {
|
||||
// selecting: {
|
||||
// enabled: true,
|
||||
// showNodeSelectionBox: true,
|
||||
// },
|
||||
// clipboard: {
|
||||
// enabled: true,
|
||||
// },
|
||||
// keyboard: {
|
||||
// enabled: true,
|
||||
// global: false,
|
||||
// },
|
||||
})
|
||||
|
||||
graph.use(
|
||||
new Keyboard({
|
||||
enabled: true,
|
||||
showNodeSelectionBox: true,
|
||||
},
|
||||
clipboard: {
|
||||
enabled: true,
|
||||
},
|
||||
keyboard: {
|
||||
enabled: true,
|
||||
global: false,
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
const keyboard = graph.getPlugin('keyboard') as Keyboard
|
||||
keyboard.bindKey('backspace', () => {
|
||||
console.log('backspace')
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
@ -48,30 +60,30 @@ export default class Example extends React.Component {
|
||||
attrs: { label: { text: 'C' } },
|
||||
})
|
||||
|
||||
graph.bindKey('meta+c', () => {
|
||||
const cells = graph.getSelectedCells()
|
||||
if (cells.length) {
|
||||
graph.copy(cells)
|
||||
}
|
||||
return false
|
||||
})
|
||||
// graph.bindKey('meta+c', () => {
|
||||
// const cells = graph.getSelectedCells()
|
||||
// if (cells.length) {
|
||||
// graph.copy(cells)
|
||||
// }
|
||||
// return false
|
||||
// })
|
||||
|
||||
graph.bindKey('meta+v', () => {
|
||||
if (!graph.isClipboardEmpty()) {
|
||||
const cells = graph.paste({ offset: 32 })
|
||||
graph.resetSelection(cells)
|
||||
}
|
||||
console.log(graph.toJSON())
|
||||
return false
|
||||
})
|
||||
// graph.bindKey('meta+v', () => {
|
||||
// if (!graph.isClipboardEmpty()) {
|
||||
// const cells = graph.paste({ offset: 32 })
|
||||
// graph.resetSelection(cells)
|
||||
// }
|
||||
// console.log(graph.toJSON())
|
||||
// return false
|
||||
// })
|
||||
|
||||
graph.bindKey('backspace', () => {
|
||||
graph.removeCells(graph.getSelectedCells())
|
||||
})
|
||||
// graph.bindKey('backspace', () => {
|
||||
// graph.removeCells(graph.getSelectedCells())
|
||||
// })
|
||||
|
||||
graph.on('selection:changed', ({ selected }) => {
|
||||
console.log(selected)
|
||||
})
|
||||
// graph.on('selection:changed', ({ selected }) => {
|
||||
// console.log(selected)
|
||||
// })
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
|
77
examples/x6-example-features/src/pages/react/extends.tsx
Normal file
77
examples/x6-example-features/src/pages/react/extends.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node } from '@antv/x6-next'
|
||||
import { ReactShape, register } from '@antv/x6-react-shape'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
|
||||
class GroupNode extends ReactShape {
|
||||
isGroup() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
Graph.registerNode('group-node', GroupNode, true)
|
||||
|
||||
const NodeComponent = ({ node }: { node: Node }) => {
|
||||
const data = node.getData()
|
||||
|
||||
return (
|
||||
<div className="react-algo-node">
|
||||
<img
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/d9f3b597-3a2e-49c3-8469-64a1168ed779.svg"
|
||||
alt=""
|
||||
/>
|
||||
<span>{data.name}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
register(NodeComponent, {
|
||||
shape: 'algo-node-3',
|
||||
width: 144,
|
||||
height: 28,
|
||||
effect: ['data'],
|
||||
inherit: 'group-node',
|
||||
})
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
private count = 0
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
})
|
||||
|
||||
const node = graph.createNode({
|
||||
shape: 'algo-node-3',
|
||||
x: 80,
|
||||
y: 80,
|
||||
data: {
|
||||
name: '逻辑回归',
|
||||
},
|
||||
})
|
||||
|
||||
console.log(node.isGroup())
|
||||
|
||||
const update = () => {
|
||||
node.setData({ name: `逻辑回归 ${(this.count += 1)}` })
|
||||
setTimeout(update, 1000)
|
||||
}
|
||||
|
||||
update()
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
27
examples/x6-example-features/src/pages/react/index.less
Normal file
27
examples/x6-example-features/src/pages/react/index.less
Normal file
@ -0,0 +1,27 @@
|
||||
.react-algo-node {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #5f95ff;
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-left: 4px;
|
||||
font-size: 12px;
|
||||
color: #000000a6;
|
||||
}
|
||||
|
||||
&.dark {
|
||||
background-color: #141414;
|
||||
|
||||
span {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +1,33 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node, Color } from '@antv/x6'
|
||||
import '@antv/x6-react-shape'
|
||||
import { Graph, Node } from '@antv/x6-next'
|
||||
import { register } from '@antv/x6-react-shape'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
|
||||
class MyComponent extends React.Component<{ node?: Node; text: string }> {
|
||||
shouldComponentUpdate() {
|
||||
const node = this.props.node
|
||||
if (node) {
|
||||
if (node.hasChanged('data')) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
const NodeComponent = ({ node }: { node: Node }) => {
|
||||
const data = node.getData()
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
render() {
|
||||
const color = Color.randomHex()
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
color: Color.invert(color, true),
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
textAlign: 'center',
|
||||
lineHeight: '60px',
|
||||
borderRadius: 30,
|
||||
background: color,
|
||||
}}
|
||||
>
|
||||
{this.props.text}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div className="react-algo-node">
|
||||
<img
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/d9f3b597-3a2e-49c3-8469-64a1168ed779.svg"
|
||||
alt=""
|
||||
/>
|
||||
<span>{data.name}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
register(NodeComponent, {
|
||||
shape: 'algo-node-1',
|
||||
width: 144,
|
||||
height: 28,
|
||||
effect: ['data'],
|
||||
})
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
private count = 0
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
@ -45,60 +36,21 @@ export default class Example extends React.Component {
|
||||
height: 600,
|
||||
})
|
||||
|
||||
const source = graph.addNode({
|
||||
shape: 'react-shape',
|
||||
primer: 'circle',
|
||||
const node = graph.addNode({
|
||||
shape: 'algo-node-1',
|
||||
x: 80,
|
||||
y: 80,
|
||||
width: 60,
|
||||
height: 60,
|
||||
data: {},
|
||||
xxx: {},
|
||||
component: <MyComponent text="Source" />,
|
||||
})
|
||||
|
||||
const target = graph.addNode({
|
||||
shape: 'react-shape',
|
||||
x: 320,
|
||||
y: 320,
|
||||
width: 120,
|
||||
height: 48,
|
||||
component: (node) => {
|
||||
return (
|
||||
<div style={{ lineHeight: '48px', textAlign: 'center' }}>
|
||||
{node.attr('body/fill')}
|
||||
</div>
|
||||
)
|
||||
data: {
|
||||
name: '逻辑回归',
|
||||
},
|
||||
// component: () => <Test text="target" />,
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
shape: 'react-shape',
|
||||
primer: 'circle',
|
||||
x: 80,
|
||||
y: 320,
|
||||
width: 60,
|
||||
height: 60,
|
||||
useForeignObject: false,
|
||||
component: () => {
|
||||
return <circle stroke="red" cx="30" cy="30" r="30" />
|
||||
},
|
||||
})
|
||||
|
||||
graph.addEdge({
|
||||
source,
|
||||
target,
|
||||
})
|
||||
|
||||
const update = () => {
|
||||
target.prop('attrs/body/fill', Color.randomHex())
|
||||
node.setData({ name: `逻辑回归 ${(this.count += 1)}` })
|
||||
setTimeout(update, 1000)
|
||||
}
|
||||
|
||||
update()
|
||||
|
||||
console.log(graph.toJSON())
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
|
@ -1,42 +1,41 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node, Color } from '@antv/x6'
|
||||
import { Portal } from '@antv/x6-react-shape'
|
||||
import React, { useContext } from 'react'
|
||||
import { Graph } from '@antv/x6-next'
|
||||
import { register, Portal } from '@antv/x6-react-shape'
|
||||
import { Button } from 'antd'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
|
||||
class MyComponent extends React.Component<{ node?: Node; text: string }> {
|
||||
shouldComponentUpdate() {
|
||||
const node = this.props.node
|
||||
if (node) {
|
||||
if (node.hasChanged('data')) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
const X6ReactPortalProvider = Portal.getProvider() // 注意,一个 graph 只能申明一个 portal provider
|
||||
const ThemeContext = React.createContext('light')
|
||||
|
||||
return false
|
||||
}
|
||||
const NodeComponent = () => {
|
||||
const theme = useContext(ThemeContext)
|
||||
|
||||
render() {
|
||||
const color = Color.randomHex()
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
color: Color.invert(color, true),
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
textAlign: 'center',
|
||||
lineHeight: '60px',
|
||||
background: color,
|
||||
}}
|
||||
>
|
||||
{this.props.text}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div className={`react-algo-node ${theme === 'light' ? 'light' : 'dark'}`}>
|
||||
<img
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/d9f3b597-3a2e-49c3-8469-64a1168ed779.svg"
|
||||
alt=""
|
||||
/>
|
||||
<span>逻辑回归</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
register(NodeComponent, {
|
||||
shape: 'algo-node-2',
|
||||
width: 144,
|
||||
height: 28,
|
||||
effect: [],
|
||||
})
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
state = {
|
||||
theme: 'light',
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
@ -44,42 +43,20 @@ export default class Example extends React.Component {
|
||||
height: 600,
|
||||
})
|
||||
|
||||
const source = graph.addNode({
|
||||
shape: 'react-shape',
|
||||
graph.addNode({
|
||||
shape: 'algo-node-2',
|
||||
x: 80,
|
||||
y: 80,
|
||||
width: 160,
|
||||
height: 60,
|
||||
data: {},
|
||||
xxx: {},
|
||||
component: <MyComponent text="Source" />,
|
||||
})
|
||||
|
||||
const target = graph.addNode({
|
||||
shape: 'react-shape',
|
||||
x: 320,
|
||||
y: 320,
|
||||
width: 160,
|
||||
height: 60,
|
||||
component: (node) => {
|
||||
return <div>{node.attr('body/fill')}</div>
|
||||
data: {
|
||||
name: '逻辑回归',
|
||||
},
|
||||
// component: () => <Test text="target" />,
|
||||
})
|
||||
}
|
||||
|
||||
graph.addEdge({
|
||||
source,
|
||||
target,
|
||||
changeTheme = () => {
|
||||
this.setState({
|
||||
theme: this.state.theme === 'light' ? 'dark' : 'light',
|
||||
})
|
||||
|
||||
const update = () => {
|
||||
target.prop('attrs/body/fill', Color.randomHex())
|
||||
setTimeout(update, 1000)
|
||||
}
|
||||
|
||||
update()
|
||||
|
||||
console.log(graph.toJSON())
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
@ -87,10 +64,16 @@ export default class Example extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const X6ReactPortalProvider = Portal.getProvider()
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<X6ReactPortalProvider />
|
||||
<ThemeContext.Provider value={this.state.theme}>
|
||||
<X6ReactPortalProvider />
|
||||
</ThemeContext.Provider>
|
||||
<div className="x6-graph-tools">
|
||||
<Button onClick={this.changeTheme}>
|
||||
{this.state.theme === 'light' ? 'Light' : 'Dark'}
|
||||
</Button>
|
||||
</div>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
|
71
examples/x6-example-features/src/pages/scroller/test.tsx
Normal file
71
examples/x6-example-features/src/pages/scroller/test.tsx
Normal file
@ -0,0 +1,71 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6-next'
|
||||
import { Scroller } from '@antv/x6-plugin-scroller'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private graph: Graph
|
||||
private graphContainer: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.graphContainer,
|
||||
width: 800,
|
||||
height: 500,
|
||||
background: {
|
||||
color: '#f5f5f5',
|
||||
},
|
||||
grid: {
|
||||
visible: true,
|
||||
},
|
||||
mousewheel: {
|
||||
enabled: true,
|
||||
// fixed: false,
|
||||
modifiers: ['ctrl', 'meta'],
|
||||
minScale: 0.5,
|
||||
maxScale: 2,
|
||||
},
|
||||
})
|
||||
|
||||
graph.use(
|
||||
new Scroller({
|
||||
enabled: true,
|
||||
// width: 600,
|
||||
// height: 400,
|
||||
pageVisible: true,
|
||||
pageBreak: true,
|
||||
pannable: {
|
||||
enabled: true,
|
||||
eventTypes: ['leftMouseDown', 'rightMouseDown'],
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
graph.addNode({
|
||||
shape: 'rect',
|
||||
x: 300,
|
||||
y: 300,
|
||||
width: 90,
|
||||
height: 60,
|
||||
attrs: {
|
||||
rect: { fill: '#31D0C6', stroke: '#4B4A67', 'stroke-width': 2 },
|
||||
text: { text: 'rect', fill: 'white' },
|
||||
},
|
||||
ports: [{}],
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.graphContainer = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<h1>Scroller</h1>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import { generateData, parsePorts } from './data'
|
||||
import { getPortsDefinition } from './port'
|
||||
import { Component } from './component'
|
||||
import './view'
|
||||
import '../../index.less'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
@ -1,33 +0,0 @@
|
||||
import React from 'react'
|
||||
import { SVG } from '@antv/x6-vector'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const svg = new SVG()
|
||||
const rect = svg.rect(100, 100).node
|
||||
svg.appendTo(this.container)
|
||||
rect.animate(
|
||||
[{ fill: '#000000' }, { fill: '#0000FF' }, { fill: '#00FFFF' }],
|
||||
{
|
||||
duration: 3000,
|
||||
iterations: Infinity,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<h1>Default Settings</h1>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
import { version } from '@antv/x6-vector'
|
||||
|
||||
console.log(version)
|
11
lerna.json
11
lerna.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "independent",
|
||||
"version": "2.0.6-beta.5",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
@ -24,5 +24,12 @@
|
||||
"pr(refactor)": ":100: Refactoring",
|
||||
"pr(test)": ":white_check_mark: Test Case"
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages": [
|
||||
"packages/x6-common",
|
||||
"packages/x6-geometry",
|
||||
"packages/x6-next",
|
||||
"packages/x6-react-shape",
|
||||
"packages/x6-vue-shape"
|
||||
]
|
||||
}
|
||||
|
@ -26,7 +26,10 @@
|
||||
"package:check": "yarn package-inherit check",
|
||||
"package:inherit": "yarn package-inherit update",
|
||||
"prepare": "is-ci || husky install configs/husky-config",
|
||||
"precommit": "yarn lint-staged && lerna run --concurrency 1 --stream precommit"
|
||||
"precommit": "yarn lint-staged && lerna run --concurrency 1 --stream precommit",
|
||||
"version": "lerna version --no-private",
|
||||
"publish:latest": "lerna publish from-package --no-private --ignore-scripts",
|
||||
"publish:beta": "lerna publish from-package --no-private --ignore-scripts --canary --preid beta --dist-tag=beta"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*.{js,jsx,tsx,ts,less,md,json}": [
|
||||
|
21
packages/x6-common/LICENSE
Normal file
21
packages/x6-common/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-common",
|
||||
"version": "2.0.1-beta.4",
|
||||
"version": "2.0.6-beta.3",
|
||||
"description": "Basic toolkit for x6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -24,7 +24,7 @@
|
||||
"clean": "run-p clean:build clean:coverage",
|
||||
"lint": "eslint 'src/**/*.{js,ts}?(x)' --fix",
|
||||
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
|
||||
"build:cjs": "tsc --module commonjs --target es5 --outDir ./lib",
|
||||
"build:cjs": "tsc --module commonjs --target es2015 --outDir ./lib",
|
||||
"build:umd": "rollup -c",
|
||||
"build:dev": "run-p build:cjs build:esm",
|
||||
"build:watch": "yarn build:esm --w",
|
||||
@ -36,21 +36,7 @@
|
||||
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
|
||||
"pretest": "run-p clean:coverage",
|
||||
"prepare": "run-s test build",
|
||||
"precommit": "lint-staged",
|
||||
"release": "release-it"
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
"commitMessage": "chore: release ${version}"
|
||||
},
|
||||
"github": {
|
||||
"release": true
|
||||
},
|
||||
"hooks": {
|
||||
"before:init": [
|
||||
"yarn run build"
|
||||
]
|
||||
}
|
||||
"precommit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.ts": [
|
||||
@ -136,5 +122,6 @@
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
},
|
||||
"gitHead": "576fa342fa65a6867ead29f6801a30dcb31bcdb5"
|
||||
}
|
||||
|
3
packages/x6-common/src/css-loader/index.ts
Normal file
3
packages/x6-common/src/css-loader/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import * as CssLoader from './loader'
|
||||
|
||||
export { CssLoader }
|
44
packages/x6-common/src/css-loader/loader.ts
Normal file
44
packages/x6-common/src/css-loader/loader.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Platform } from '../platform'
|
||||
|
||||
interface CssModule {
|
||||
name: string
|
||||
styleElement: HTMLStyleElement | null
|
||||
}
|
||||
|
||||
const cssModules: CssModule[] = []
|
||||
|
||||
export function ensure(name: string, content: string) {
|
||||
const cssModule = cssModules.find((m) => m.name === name)
|
||||
if (cssModule) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!Platform.isApplyingHMR()) {
|
||||
const styleElement = document.createElement('style')
|
||||
styleElement.setAttribute('type', 'text/css')
|
||||
styleElement.textContent = content
|
||||
|
||||
const head = document.querySelector('head') as HTMLHeadElement
|
||||
if (head) {
|
||||
head.insertBefore(styleElement, head.firstChild)
|
||||
}
|
||||
|
||||
cssModules.push({
|
||||
name,
|
||||
styleElement,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function clean(name: string) {
|
||||
const index = cssModules.findIndex((m) => m.name === name)
|
||||
|
||||
if (index > -1) {
|
||||
let styleElement = cssModules[index].styleElement
|
||||
if (styleElement && styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement)
|
||||
}
|
||||
styleElement = null
|
||||
cssModules.splice(index, 1)
|
||||
}
|
||||
}
|
@ -201,6 +201,21 @@ export function before(
|
||||
}
|
||||
}
|
||||
|
||||
export function after(
|
||||
elem: Element,
|
||||
elems: Element | DocumentFragment | (Element | DocumentFragment)[],
|
||||
) {
|
||||
const parent = elem.parentNode
|
||||
if (parent) {
|
||||
const arr = Array.isArray(elems) ? elems : [elems]
|
||||
arr.forEach((child) => {
|
||||
if (child != null) {
|
||||
parent.insertBefore(child, elem.nextSibling)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function appendTo(elem: Element, target: Element) {
|
||||
if (target != null) {
|
||||
target.appendChild(elem)
|
||||
|
@ -3,6 +3,7 @@ import { EventHook } from './hook'
|
||||
import { Store } from './store'
|
||||
import { EventObject } from './object'
|
||||
import { EventHandler } from './types'
|
||||
import './special'
|
||||
|
||||
export namespace Core {
|
||||
let triggered: string | undefined
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { EventHook } from './hook'
|
||||
import { Util } from './util'
|
||||
|
||||
// Prevent triggered image.load events from bubbling to window.load
|
||||
export namespace Special {
|
||||
@ -19,3 +20,38 @@ export namespace Special {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// For mouseenter/leave call the handler if related is outside the target.
|
||||
// NB: No relatedTarget if the mouse left/entered the browser window
|
||||
export namespace Special {
|
||||
EventHook.register('mouseenter', {
|
||||
delegateType: 'mouseover',
|
||||
bindType: 'mouseover',
|
||||
handle(target, event) {
|
||||
let ret
|
||||
const related = event.relatedTarget
|
||||
const handleObj = event.handleObj
|
||||
if (!related || (related !== target && !Util.contains(target, related))) {
|
||||
event.type = handleObj.originType
|
||||
ret = handleObj.handler.call(target, event)
|
||||
event.type = 'mouseover'
|
||||
}
|
||||
return ret
|
||||
},
|
||||
})
|
||||
EventHook.register('mouseleave', {
|
||||
delegateType: 'mouseout',
|
||||
bindType: 'mouseout',
|
||||
handle(target, event) {
|
||||
let ret
|
||||
const related = event.relatedTarget
|
||||
const handleObj = event.handleObj
|
||||
if (!related || (related !== target && !Util.contains(target, related))) {
|
||||
event.type = handleObj.originType
|
||||
ret = handleObj.handler.call(target, event)
|
||||
event.type = 'mouseout'
|
||||
}
|
||||
return ret
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -173,3 +173,23 @@ export namespace Util {
|
||||
return obj != null && obj === obj.window
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Util {
|
||||
export function contains(a: any, b: any) {
|
||||
const adown = a.nodeType === 9 ? a.documentElement : a
|
||||
const bup = b && b.parentNode
|
||||
|
||||
return (
|
||||
a === bup ||
|
||||
!!(
|
||||
bup &&
|
||||
bup.nodeType === 1 &&
|
||||
// Support: IE 9 - 11+
|
||||
// IE doesn't have `contains` on SVG.
|
||||
(adown.contains
|
||||
? adown.contains(bup)
|
||||
: a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ export * from './prefix'
|
||||
export * from './selection'
|
||||
export * from './css'
|
||||
export * from './data'
|
||||
export * from './prop'
|
||||
|
||||
// svg
|
||||
// ---
|
||||
|
45
packages/x6-common/src/dom/prop.ts
Normal file
45
packages/x6-common/src/dom/prop.ts
Normal file
@ -0,0 +1,45 @@
|
||||
const propMap: Record<string, string> = {
|
||||
/* GENERAL */
|
||||
class: 'className',
|
||||
contenteditable: 'contentEditable',
|
||||
/* LABEL */
|
||||
for: 'htmlFor',
|
||||
/* INPUT */
|
||||
readonly: 'readOnly',
|
||||
maxlength: 'maxLength',
|
||||
tabindex: 'tabIndex',
|
||||
/* TABLE */
|
||||
colspan: 'colSpan',
|
||||
rowspan: 'rowSpan',
|
||||
/* IMAGE */
|
||||
usemap: 'useMap',
|
||||
}
|
||||
|
||||
export function prop(elem: Element, props: string): any
|
||||
export function prop(elem: Element, props: string, value: any): void
|
||||
export function prop(elem: Element, props: Record<string, any>): void
|
||||
export function prop(
|
||||
elem: Element,
|
||||
props: string | Record<string, any>,
|
||||
value?: any,
|
||||
) {
|
||||
if (!props) {
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof props === 'string') {
|
||||
props = propMap[props] || props // eslint-disable-line
|
||||
|
||||
if (arguments.length < 3) {
|
||||
return (elem as any)[props]
|
||||
}
|
||||
|
||||
;(elem as any)[props] = value
|
||||
return
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
for (const key in props) {
|
||||
prop(elem, key, props[key])
|
||||
}
|
||||
}
|
@ -21,4 +21,5 @@ export * from './dictionary'
|
||||
export * from './registry'
|
||||
export * from './modifier'
|
||||
export * from './animation'
|
||||
export * from './css-loader'
|
||||
export * from './types'
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { Dom } from '../dom'
|
||||
|
||||
export type ModifierKey = 'alt' | 'ctrl' | 'meta' | 'shift'
|
||||
|
||||
// eslint-disable-next-line
|
||||
@ -51,7 +53,7 @@ export namespace ModifierKey {
|
||||
}
|
||||
|
||||
export function isMatch(
|
||||
e: JQuery.TriggeredEvent | WheelEvent,
|
||||
e: Dom.EventObject | WheelEvent,
|
||||
modifiers?: string | ModifierKey[] | null,
|
||||
strict?: boolean,
|
||||
) {
|
||||
|
21
packages/x6-core/LICENSE
Normal file
21
packages/x6-core/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@antv/x6-core",
|
||||
"version": "2.0.1-beta.3",
|
||||
"version": "2.0.3-beta.0",
|
||||
"description": "A lightweight graphic render library.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -24,7 +25,7 @@
|
||||
"clean": "run-p clean:build clean:coverage",
|
||||
"lint": "eslint 'src/**/*.{js,ts}?(x)' --fix",
|
||||
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
|
||||
"build:cjs": "tsc --module commonjs --target es5 --outDir ./lib",
|
||||
"build:cjs": "tsc --module commonjs --target es2015 --outDir ./lib",
|
||||
"build:umd": "rollup -c",
|
||||
"build:dev": "run-p build:cjs build:esm",
|
||||
"build:watch": "yarn build:esm --w",
|
||||
@ -50,8 +51,8 @@
|
||||
"@antv/x6-package-json/rollup.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"@antv/x6-common": "2.0.1-beta.3",
|
||||
"@antv/x6-geometry": "2.0.1-beta.3"
|
||||
"@antv/x6-common": "^2.0.6-beta.0",
|
||||
"@antv/x6-geometry": "^2.0.6-beta.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^20.0.0",
|
||||
@ -123,5 +124,6 @@
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
},
|
||||
"gitHead": "576fa342fa65a6867ead29f6801a30dcb31bcdb5"
|
||||
}
|
||||
|
21
packages/x6-geometry/LICENSE
Normal file
21
packages/x6-geometry/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2.0.1-beta.3",
|
||||
"version": "2.0.6-beta.2",
|
||||
"name": "@antv/x6-geometry",
|
||||
"description": "Geometry operations for x6.",
|
||||
"main": "lib/index.js",
|
||||
@ -24,7 +24,7 @@
|
||||
"clean": "run-p clean:build clean:coverage",
|
||||
"lint": "eslint 'src/**/*.{js,ts}?(x)' --fix",
|
||||
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
|
||||
"build:cjs": "tsc --module commonjs --target es5 --outDir ./lib",
|
||||
"build:cjs": "tsc --module commonjs --target es2015 --outDir ./lib",
|
||||
"build:umd": "rollup -c",
|
||||
"build:watch": "yarn build:esm --w",
|
||||
"build:watch:esm": "yarn build:esm --w",
|
||||
@ -36,27 +36,13 @@
|
||||
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
|
||||
"pretest": "run-p clean:coverage",
|
||||
"prepare": "run-s test build",
|
||||
"precommit": "lint-staged",
|
||||
"release": "release-it"
|
||||
"precommit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.ts": [
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
"commitMessage": "chore: release ${version}"
|
||||
},
|
||||
"github": {
|
||||
"release": true
|
||||
},
|
||||
"hooks": {
|
||||
"before:init": [
|
||||
"yarn run build"
|
||||
]
|
||||
}
|
||||
},
|
||||
"inherits": [
|
||||
"@antv/x6-package-json/cli.json",
|
||||
"@antv/x6-package-json/eslint.json",
|
||||
@ -118,5 +104,6 @@
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
},
|
||||
"gitHead": "576fa342fa65a6867ead29f6801a30dcb31bcdb5"
|
||||
}
|
||||
|
21
packages/x6-next/LICENSE
Normal file
21
packages/x6-next/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,9 +0,0 @@
|
||||
import { version } from '../src'
|
||||
|
||||
describe('version', () => {
|
||||
it('should match the `version` field of package.json', () => {
|
||||
// eslint-disable-next-line
|
||||
const expected = require('../package.json').version
|
||||
expect(version).toBe(expected)
|
||||
})
|
||||
})
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-next",
|
||||
"version": "2.0.1-beta.3",
|
||||
"version": "2.0.6-beta.3",
|
||||
"description": "JavaScript diagramming library that uses SVG and HTML for rendering.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -32,7 +32,7 @@
|
||||
"lint:style": "stylelint 'src/**/*.less' --syntax less --fix",
|
||||
"lint": "run-s lint:ts lint:style",
|
||||
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
|
||||
"build:cjs": "tsc --module commonjs --target es5 --outDir ./lib",
|
||||
"build:cjs": "tsc --module commonjs --target es2015 --outDir ./lib",
|
||||
"build:umd": "rollup -c",
|
||||
"build:less": "node ./scripts/style",
|
||||
"build:readme": "node ./scripts/readme.js",
|
||||
@ -41,14 +41,13 @@
|
||||
"build:watch": "yarn build:esm --w",
|
||||
"build:watch:esm": "yarn build:esm --w",
|
||||
"build:watch:cjs": "yarn build:cjs --w",
|
||||
"build": "run-p build:readme build:version build:dev build:umd",
|
||||
"build": "run-p build:readme build:dev build:umd",
|
||||
"prebuild": "run-s lint clean",
|
||||
"test": "karma start",
|
||||
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
|
||||
"pretest": "run-p clean:coverage",
|
||||
"prepare": "run-s build:version test build",
|
||||
"precommit": "lint-staged",
|
||||
"release": "release-it"
|
||||
"prepare": "run-s test build",
|
||||
"precommit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.less": [
|
||||
@ -58,19 +57,6 @@
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"release-it": {
|
||||
"git": {
|
||||
"commitMessage": "chore: release ${version}"
|
||||
},
|
||||
"github": {
|
||||
"release": true
|
||||
},
|
||||
"hooks": {
|
||||
"before:init": [
|
||||
"yarn run build"
|
||||
]
|
||||
}
|
||||
},
|
||||
"inherits": [
|
||||
"@antv/x6-package-json/cli.json",
|
||||
"@antv/x6-package-json/less.json",
|
||||
@ -79,8 +65,8 @@
|
||||
"@antv/x6-package-json/rollup.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"@antv/x6-common": "2.0.1-beta.3",
|
||||
"@antv/x6-geometry": "2.0.1-beta.3"
|
||||
"@antv/x6-common": "^2.0.6-beta.3",
|
||||
"@antv/x6-geometry": "^2.0.6-beta.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^20.0.0",
|
||||
@ -158,5 +144,6 @@
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
},
|
||||
"gitHead": "576fa342fa65a6867ead29f6801a30dcb31bcdb5"
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Platform } from '@antv/x6-common'
|
||||
import { CssLoader } from '@antv/x6-common'
|
||||
import { Config } from '../config'
|
||||
import { content } from '../style/raw'
|
||||
import { Base } from './base'
|
||||
@ -6,43 +6,12 @@ import { Base } from './base'
|
||||
export class CSSManager extends Base {
|
||||
protected init() {
|
||||
if (Config.autoInsertCSS) {
|
||||
CSSManager.ensure()
|
||||
CssLoader.ensure('core', content)
|
||||
}
|
||||
}
|
||||
|
||||
@CSSManager.dispose()
|
||||
dispose() {
|
||||
CSSManager.clean()
|
||||
}
|
||||
}
|
||||
|
||||
export namespace CSSManager {
|
||||
let styleElement: HTMLStyleElement | null
|
||||
let counter = 0
|
||||
|
||||
export function ensure() {
|
||||
counter += 1
|
||||
if (counter > 1) return
|
||||
|
||||
if (!Platform.isApplyingHMR()) {
|
||||
styleElement = document.createElement('style')
|
||||
styleElement.setAttribute('type', 'text/css')
|
||||
styleElement.textContent = content
|
||||
|
||||
const head = document.querySelector('head') as HTMLHeadElement
|
||||
if (head) {
|
||||
head.insertBefore(styleElement, head.firstChild)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function clean() {
|
||||
counter -= 1
|
||||
if (counter > 0) return
|
||||
|
||||
if (styleElement && styleElement.parentNode) {
|
||||
styleElement.parentNode.removeChild(styleElement)
|
||||
}
|
||||
styleElement = null
|
||||
CssLoader.clean('core')
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ import { HighlightManager as Highlight } from './highlight'
|
||||
import { CellView } from '../view'
|
||||
|
||||
export class Graph extends Basecoat<EventArgs> {
|
||||
private installedPlugins: Set<Graph.Plugin> = new Set()
|
||||
|
||||
public readonly options: GraphOptions.Definition
|
||||
public readonly css: Css
|
||||
public readonly model: Model
|
||||
@ -552,6 +554,11 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
return this
|
||||
}
|
||||
|
||||
resizeGraph(width?: number, height?: number) {
|
||||
this.transform.resize(width, height)
|
||||
return this
|
||||
}
|
||||
|
||||
scale(): Dom.Scale
|
||||
scale(sx: number, sy?: number, cx?: number, cy?: number): this
|
||||
scale(sx?: number, sy: number = sx as number, cx = 0, cy = 0) {
|
||||
@ -1035,6 +1042,30 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region plugin
|
||||
|
||||
use(plugin: Graph.Plugin, ...options: any[]) {
|
||||
if (!this.installedPlugins.has(plugin)) {
|
||||
this.installedPlugins.add(plugin)
|
||||
plugin.init(this, ...options)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
getPlugin(pluginName: string) {
|
||||
let result: Graph.Plugin | undefined
|
||||
|
||||
this.installedPlugins.forEach((plugin) => {
|
||||
if (plugin.name === pluginName) {
|
||||
result = plugin
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region dispose
|
||||
|
||||
@Basecoat.dispose()
|
||||
@ -1053,6 +1084,10 @@ export class Graph extends Basecoat<EventArgs> {
|
||||
this.panning.dispose()
|
||||
this.view.dispose()
|
||||
this.renderer.dispose()
|
||||
|
||||
this.installedPlugins.forEach((plugin) => {
|
||||
plugin.dispose()
|
||||
})
|
||||
}
|
||||
|
||||
// #endregion
|
||||
@ -1169,3 +1204,11 @@ export namespace Graph {
|
||||
export const unregisterConnectionPoint =
|
||||
Registry.ConnectionPoint.registry.unregister
|
||||
}
|
||||
|
||||
export namespace Graph {
|
||||
export type Plugin = {
|
||||
name: string
|
||||
init: (graph: Graph, ...options: any[]) => any
|
||||
dispose: () => void
|
||||
}
|
||||
}
|
||||
|
@ -1 +1,5 @@
|
||||
export * from './graph'
|
||||
export * from './view'
|
||||
export * from './events'
|
||||
export * from './transform'
|
||||
export * from './background'
|
||||
|
@ -8,7 +8,7 @@ import { PanningManager } from './panning'
|
||||
import { MouseWheel } from './mousewheel'
|
||||
import { Edge as StandardEdge } from '../shape'
|
||||
import { Model, Cell, Node, Edge } from '../model'
|
||||
import { View, CellView, NodeView, EdgeView } from '../view'
|
||||
import { CellView, NodeView, EdgeView, Markup } from '../view'
|
||||
import {
|
||||
Router,
|
||||
Connector,
|
||||
@ -17,6 +17,7 @@ import {
|
||||
ConnectionPoint,
|
||||
} from '../registry'
|
||||
import { HighlightManager } from './highlight'
|
||||
import { PortManager } from '../model/port'
|
||||
|
||||
export namespace Options {
|
||||
interface Common {
|
||||
@ -45,15 +46,11 @@ export namespace Options {
|
||||
preventDefaultBlankAction: boolean
|
||||
interacting: CellView.Interacting
|
||||
|
||||
virtualRender?: boolean
|
||||
virtual?: boolean
|
||||
|
||||
guard: (e: Dom.EventObject, view?: CellView | null) => boolean
|
||||
onToolItemCreated: (args: {
|
||||
name: string
|
||||
cell: Cell
|
||||
view: CellView
|
||||
tool: View
|
||||
}) => void
|
||||
|
||||
onPortRendered?: (args: OnPortRenderedArgs) => void
|
||||
}
|
||||
|
||||
export interface ManualBooleans {
|
||||
@ -367,6 +364,19 @@ export namespace Options {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Options {
|
||||
export interface OnPortRenderedArgs {
|
||||
node: Node
|
||||
port: PortManager.Port
|
||||
container: Element
|
||||
selectors?: Markup.Selectors
|
||||
labelContainer?: Element
|
||||
labelSelectors?: Markup.Selectors | null
|
||||
contentContainer: Element
|
||||
contentSelectors?: Markup.Selectors
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Options {
|
||||
export const defaults: Partial<Definition> = {
|
||||
x: 0,
|
||||
|
@ -21,17 +21,17 @@ export class VirtualRenderManager extends Base {
|
||||
}
|
||||
|
||||
enableVirtualRender() {
|
||||
this.options.virtualRender = true
|
||||
this.options.virtual = true
|
||||
this.resetRenderArea()
|
||||
}
|
||||
|
||||
disableVirtualRender() {
|
||||
this.options.virtualRender = false
|
||||
this.options.virtual = false
|
||||
this.graph.renderer.setRenderArea(undefined)
|
||||
}
|
||||
|
||||
resetRenderArea() {
|
||||
if (this.options.virtualRender) {
|
||||
if (this.options.virtual) {
|
||||
const renderArea = this.graph.getGraphArea()
|
||||
this.graph.renderer.setRenderArea(renderArea)
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import * as Registry from './registry'
|
||||
export * from './model'
|
||||
export * from './view'
|
||||
export * from './graph'
|
||||
export * from './version'
|
||||
export * from './config'
|
||||
export * from './util'
|
||||
|
||||
export { Shape, Registry }
|
||||
|
@ -57,8 +57,6 @@ export class Animation {
|
||||
}
|
||||
|
||||
if (progress === 1) {
|
||||
// TODO: remove in the next major version
|
||||
this.cell.notify('transition:end', this.getArgs<T>(key))
|
||||
this.cell.notify('transition:complete', this.getArgs<T>(key))
|
||||
options.complete && options.complete(this.getArgs<T>(key))
|
||||
|
||||
@ -73,8 +71,6 @@ export class Animation {
|
||||
this.cache[key] = { startValue, targetValue, options: localOptions }
|
||||
this.ids[key] = Dom.requestAnimationFrame(iterate)
|
||||
|
||||
// TODO: remove in the next major version
|
||||
this.cell.notify('transition:begin', this.getArgs<T>(key))
|
||||
this.cell.notify('transition:start', this.getArgs<T>(key))
|
||||
options.start && options.start(this.getArgs<T>(key))
|
||||
}, options.delay)
|
||||
|
@ -924,6 +924,7 @@ export namespace Edge {
|
||||
|
||||
export interface SetCellTerminalArgs extends SetTerminalCommonArgs {
|
||||
port?: string
|
||||
priority?: boolean
|
||||
anchor?: string | NodeAnchor.NativeItem | NodeAnchor.ManaualItem
|
||||
}
|
||||
|
||||
|
@ -55,13 +55,6 @@ export class Segments extends ToolsView.ToolItem<EdgeView, Segments.Options> {
|
||||
this.options.processHandle(handle)
|
||||
}
|
||||
|
||||
this.graph.options.onToolItemCreated({
|
||||
name: 'segments',
|
||||
cell: this.cell,
|
||||
view: this.cellView,
|
||||
tool: handle,
|
||||
})
|
||||
|
||||
this.updateHandle(handle, vertex, nextVertex)
|
||||
this.container.appendChild(handle.container)
|
||||
this.startHandleListening(handle)
|
||||
|
@ -69,13 +69,6 @@ export class Vertices extends ToolsView.ToolItem<EdgeView, Vertices.Options> {
|
||||
processHandle(handle)
|
||||
}
|
||||
|
||||
this.graph.options.onToolItemCreated({
|
||||
name: 'vertices',
|
||||
cell: this.cell,
|
||||
view: this.cellView,
|
||||
tool: handle,
|
||||
})
|
||||
|
||||
handle.updatePosition(vertex.x, vertex.y)
|
||||
this.stamp(handle.container)
|
||||
this.container.appendChild(handle.container)
|
||||
|
@ -14,7 +14,6 @@ let isFlushPending = false
|
||||
let scheduleId = 0
|
||||
const queue: Job[] = []
|
||||
const frameInterval = 33
|
||||
let time = 0
|
||||
|
||||
let getCurrentTime: () => number
|
||||
const hasPerformanceNow =
|
||||
@ -80,10 +79,6 @@ export function clearJobs() {
|
||||
cancelScheduleJob()
|
||||
}
|
||||
|
||||
export function resetTimer() {
|
||||
time = performance.now()
|
||||
}
|
||||
|
||||
function flushJobs() {
|
||||
isFlushPending = false
|
||||
isFlushing = true
|
||||
@ -106,8 +101,6 @@ function flushJobs() {
|
||||
|
||||
if (queue.length) {
|
||||
queueFlush()
|
||||
} else {
|
||||
console.log('spend', performance.now() - time) // eslint-disable-line
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,13 +2,7 @@ import { KeyValue, Dom } from '@antv/x6-common'
|
||||
import { Rectangle } from '@antv/x6-geometry'
|
||||
import { Model, Cell } from '../model'
|
||||
import { View, CellView, NodeView, EdgeView } from '../view'
|
||||
import {
|
||||
queueJob,
|
||||
queueFlush,
|
||||
clearJobs,
|
||||
JOB_PRIORITY,
|
||||
resetTimer,
|
||||
} from './queueJob'
|
||||
import { queueJob, queueFlush, clearJobs, JOB_PRIORITY } from './queueJob'
|
||||
import { FlagManager } from '../view/flag'
|
||||
import { Graph } from '../graph'
|
||||
|
||||
@ -181,7 +175,6 @@ export class Scheduler {
|
||||
)
|
||||
})
|
||||
|
||||
resetTimer()
|
||||
queueFlush()
|
||||
}
|
||||
|
||||
@ -222,7 +215,6 @@ export class Scheduler {
|
||||
}
|
||||
}
|
||||
|
||||
resetTimer()
|
||||
queueFlush()
|
||||
}
|
||||
|
||||
|
11
packages/x6-next/src/shape/circle.ts
Normal file
11
packages/x6-next/src/shape/circle.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { createShape } from './util'
|
||||
|
||||
export const Circle = createShape('circle', {
|
||||
attrs: {
|
||||
body: {
|
||||
refCx: '50%',
|
||||
refCy: '50%',
|
||||
refR: '50%',
|
||||
},
|
||||
},
|
||||
})
|
12
packages/x6-next/src/shape/ellipse.ts
Normal file
12
packages/x6-next/src/shape/ellipse.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { createShape } from './util'
|
||||
|
||||
export const Ellipse = createShape('ellipse', {
|
||||
attrs: {
|
||||
body: {
|
||||
refCx: '50%',
|
||||
refCy: '50%',
|
||||
refRx: '50%',
|
||||
refRy: '50%',
|
||||
},
|
||||
},
|
||||
})
|
17
packages/x6-next/src/shape/image.ts
Normal file
17
packages/x6-next/src/shape/image.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { getImageUrlHook, createShape } from './util'
|
||||
|
||||
export const Image = createShape(
|
||||
'image',
|
||||
{
|
||||
attrs: {
|
||||
image: {
|
||||
refWidth: '100%',
|
||||
refHeight: '100%',
|
||||
},
|
||||
},
|
||||
propHooks: getImageUrlHook(),
|
||||
},
|
||||
{
|
||||
selector: 'image',
|
||||
},
|
||||
)
|
@ -1,2 +1,11 @@
|
||||
export * from './rect'
|
||||
export * from './edge'
|
||||
export * from './rect'
|
||||
export * from './ellipse'
|
||||
export * from './polygon'
|
||||
export * from './polyline'
|
||||
export * from './path'
|
||||
export * from './text-block'
|
||||
export * from './image'
|
||||
export * from './edge'
|
||||
export * from './circle'
|
||||
|
42
packages/x6-next/src/shape/path.ts
Normal file
42
packages/x6-next/src/shape/path.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { ObjectExt } from '@antv/x6-common'
|
||||
import { Base } from './base'
|
||||
|
||||
export const Path = Base.define({
|
||||
shape: 'path',
|
||||
markup: [
|
||||
{
|
||||
tagName: 'rect',
|
||||
selector: 'bg',
|
||||
},
|
||||
{
|
||||
tagName: 'path',
|
||||
selector: 'body',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'label',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
bg: {
|
||||
refWidth: '100%',
|
||||
refHeight: '100%',
|
||||
fill: 'none',
|
||||
stroke: 'none',
|
||||
pointerEvents: 'all',
|
||||
},
|
||||
body: {
|
||||
fill: 'none',
|
||||
stroke: '#000',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
},
|
||||
propHooks(metadata) {
|
||||
const { path, ...others } = metadata
|
||||
if (path) {
|
||||
ObjectExt.setByPath(others, 'attrs/body/refD', path)
|
||||
}
|
||||
|
||||
return others
|
||||
},
|
||||
})
|
69
packages/x6-next/src/shape/poly.ts
Normal file
69
packages/x6-next/src/shape/poly.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import { Point } from '@antv/x6-geometry'
|
||||
import { ObjectExt } from '@antv/x6-common'
|
||||
import { Base } from './base'
|
||||
import { Node } from '../model/node'
|
||||
|
||||
export class Poly extends Base {
|
||||
get points() {
|
||||
return this.getPoints()
|
||||
}
|
||||
|
||||
set points(pts: string | undefined | null) {
|
||||
this.setPoints(pts)
|
||||
}
|
||||
|
||||
getPoints() {
|
||||
return this.getAttrByPath<string>('body/refPoints')
|
||||
}
|
||||
|
||||
setPoints(
|
||||
points?: string | Point.PointLike[] | Point.PointData[] | null,
|
||||
options?: Node.SetOptions,
|
||||
) {
|
||||
if (points == null) {
|
||||
this.removePoints()
|
||||
} else {
|
||||
this.setAttrByPath('body/refPoints', Poly.pointsToString(points), options)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
removePoints() {
|
||||
this.removeAttrByPath('body/refPoints')
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Poly {
|
||||
export function pointsToString(
|
||||
points: Point.PointLike[] | Point.PointData[] | string,
|
||||
) {
|
||||
return typeof points === 'string'
|
||||
? points
|
||||
: (points as Point.PointLike[])
|
||||
.map((p) => {
|
||||
if (Array.isArray(p)) {
|
||||
return p.join(',')
|
||||
}
|
||||
if (Point.isPointLike(p)) {
|
||||
return `${p.x}, ${p.y}`
|
||||
}
|
||||
return ''
|
||||
})
|
||||
.join(' ')
|
||||
}
|
||||
|
||||
Poly.config({
|
||||
propHooks(metadata) {
|
||||
const { points, ...others } = metadata
|
||||
if (points) {
|
||||
const data = pointsToString(points)
|
||||
if (data) {
|
||||
ObjectExt.setByPath(others, 'attrs/body/refPoints', data)
|
||||
}
|
||||
}
|
||||
return others
|
||||
},
|
||||
})
|
||||
}
|
9
packages/x6-next/src/shape/polygon.ts
Normal file
9
packages/x6-next/src/shape/polygon.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Base } from './base'
|
||||
import { Poly } from './poly'
|
||||
import { createShape } from './util'
|
||||
|
||||
export const Polygon = createShape(
|
||||
'polygon',
|
||||
{},
|
||||
{ parent: Poly as typeof Base },
|
||||
)
|
9
packages/x6-next/src/shape/polyline.ts
Normal file
9
packages/x6-next/src/shape/polyline.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Base } from './base'
|
||||
import { Poly } from './poly'
|
||||
import { createShape } from './util'
|
||||
|
||||
export const Polyline = createShape(
|
||||
'polyline',
|
||||
{},
|
||||
{ parent: Poly as typeof Base },
|
||||
)
|
101
packages/x6-next/src/shape/text-block.ts
Normal file
101
packages/x6-next/src/shape/text-block.ts
Normal file
@ -0,0 +1,101 @@
|
||||
import { Platform, Dom, FunctionExt, ObjectExt } from '@antv/x6-common'
|
||||
import { Attr } from '../registry'
|
||||
import { Base } from './base'
|
||||
|
||||
export const TextBlock = Base.define({
|
||||
shape: 'text-block',
|
||||
markup: [
|
||||
{
|
||||
tagName: 'rect',
|
||||
selector: 'body',
|
||||
},
|
||||
Platform.SUPPORT_FOREIGNOBJECT
|
||||
? {
|
||||
tagName: 'foreignObject',
|
||||
selector: 'foreignObject',
|
||||
children: [
|
||||
{
|
||||
tagName: 'div',
|
||||
ns: Dom.ns.xhtml,
|
||||
selector: 'label',
|
||||
style: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'static',
|
||||
backgroundColor: 'transparent',
|
||||
textAlign: 'center',
|
||||
margin: 0,
|
||||
padding: '0px 5px',
|
||||
boxSizing: 'border-box',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
: {
|
||||
tagName: 'text',
|
||||
selector: 'label',
|
||||
attrs: {
|
||||
textAnchor: 'middle',
|
||||
},
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
body: {
|
||||
...Base.bodyAttr,
|
||||
refWidth: '100%',
|
||||
refHeight: '100%',
|
||||
},
|
||||
foreignObject: {
|
||||
refWidth: '100%',
|
||||
refHeight: '100%',
|
||||
},
|
||||
label: {
|
||||
style: {
|
||||
fontSize: 14,
|
||||
},
|
||||
},
|
||||
},
|
||||
propHooks(metadata) {
|
||||
const { text, ...others } = metadata
|
||||
if (text) {
|
||||
ObjectExt.setByPath(others, 'attrs/label/text', text)
|
||||
}
|
||||
return others
|
||||
},
|
||||
attrHooks: {
|
||||
text: {
|
||||
set(text: string, { cell, view, refBBox, elem, attrs }) {
|
||||
if (elem instanceof HTMLElement) {
|
||||
elem.textContent = text
|
||||
} else {
|
||||
// No foreign object
|
||||
const style = (attrs.style as Attr.SimpleAttrs) || {}
|
||||
const wrapValue = { text, width: -5, height: '100%' }
|
||||
const wrapAttrs = {
|
||||
textVerticalAnchor: 'middle',
|
||||
...style,
|
||||
}
|
||||
|
||||
const textWrap = Attr.presets.textWrap as Attr.SetDefinition
|
||||
FunctionExt.call(textWrap.set, this, wrapValue, {
|
||||
cell,
|
||||
view,
|
||||
elem,
|
||||
refBBox,
|
||||
attrs: wrapAttrs,
|
||||
})
|
||||
|
||||
return { fill: (style.color as string) || null }
|
||||
}
|
||||
},
|
||||
position(text, { refBBox, elem }) {
|
||||
if (elem instanceof SVGElement) {
|
||||
return refBBox.getCenter()
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
@ -1,5 +1,5 @@
|
||||
import { ObjectExt } from '@antv/x6-common'
|
||||
import { Node } from '../model'
|
||||
import { Cell, Node } from '../model'
|
||||
import { Markup } from '../view'
|
||||
import { Base } from './base'
|
||||
|
||||
@ -16,6 +16,45 @@ export function getMarkup(tagName: string, selector = 'body'): Markup {
|
||||
]
|
||||
}
|
||||
|
||||
export function getImageUrlHook(attrName = 'xlink:href') {
|
||||
const hook: Cell.PropHook = (metadata) => {
|
||||
const { imageUrl, imageWidth, imageHeight, ...others } = metadata
|
||||
if (imageUrl != null || imageWidth != null || imageHeight != null) {
|
||||
const apply = () => {
|
||||
if (others.attrs) {
|
||||
const image = others.attrs.image
|
||||
if (imageUrl != null) {
|
||||
image[attrName] = imageUrl
|
||||
}
|
||||
if (imageWidth != null) {
|
||||
image.width = imageWidth
|
||||
}
|
||||
if (imageHeight != null) {
|
||||
image.height = imageHeight
|
||||
}
|
||||
others.attrs.image = image
|
||||
}
|
||||
}
|
||||
|
||||
if (others.attrs) {
|
||||
if (others.attrs.image == null) {
|
||||
others.attrs.image = {}
|
||||
}
|
||||
apply()
|
||||
} else {
|
||||
others.attrs = {
|
||||
image: {},
|
||||
}
|
||||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
return others
|
||||
}
|
||||
|
||||
return hook
|
||||
}
|
||||
|
||||
export function createShape(
|
||||
shape: string,
|
||||
config: Node.Config,
|
||||
|
@ -376,7 +376,9 @@ export namespace Util {
|
||||
let tagName = node.tagName
|
||||
if (typeof tagName !== 'string') return null
|
||||
tagName = tagName.toUpperCase()
|
||||
if (tagName === 'G') {
|
||||
if (Dom.hasClass(node, 'x6-port')) {
|
||||
node = node.nextElementSibling as Element
|
||||
} else if (tagName === 'G') {
|
||||
node = node.firstElementChild as Element
|
||||
} else if (tagName === 'TITLE') {
|
||||
node = node.nextElementSibling as Element
|
||||
|
@ -1,7 +0,0 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* Auto generated version file, do not modify it!
|
||||
*/
|
||||
const version = '2.0.1-beta.3'
|
||||
export { version }
|
@ -533,70 +533,6 @@ export class CellView<
|
||||
return magnet
|
||||
}
|
||||
|
||||
// #region animate todo
|
||||
|
||||
// animate(elem: SVGElement | string, options: Dom.AnimationOptions) {
|
||||
// const target = typeof elem === 'string' ? this.findOne(elem) : elem
|
||||
// if (target == null) {
|
||||
// throw new Error('Invalid animation element.')
|
||||
// }
|
||||
|
||||
// const parent = target.parentNode
|
||||
// const revert = () => {
|
||||
// if (!parent) {
|
||||
// Dom.remove(target)
|
||||
// }
|
||||
// }
|
||||
|
||||
// const vTarget = Vector.create(target as SVGElement)
|
||||
// if (!parent) {
|
||||
// vTarget.appendTo(this.graph.view.stage)
|
||||
// }
|
||||
|
||||
// const onComplete = options.complete
|
||||
// options.complete = (e: Event) => {
|
||||
// revert()
|
||||
|
||||
// if (onComplete) {
|
||||
// onComplete(e)
|
||||
// }
|
||||
// }
|
||||
|
||||
// return vTarget.animate(options)
|
||||
// }
|
||||
|
||||
// animateTransform(elem: SVGElement | string, options: Dom.AnimationOptions) {
|
||||
// const target = typeof elem === 'string' ? this.findOne(elem) : elem
|
||||
// if (target == null) {
|
||||
// throw new Error('Invalid animation element.')
|
||||
// }
|
||||
|
||||
// const parent = target.parentNode
|
||||
// const revert = () => {
|
||||
// if (!parent) {
|
||||
// Dom.remove(target)
|
||||
// }
|
||||
// }
|
||||
|
||||
// const vTarget = Vector.create(target as SVGElement)
|
||||
// if (!parent) {
|
||||
// vTarget.appendTo(this.graph.view.stage)
|
||||
// }
|
||||
|
||||
// const onComplete = options.complete
|
||||
// options.complete = (e: Event) => {
|
||||
// revert()
|
||||
|
||||
// if (onComplete) {
|
||||
// onComplete(e)
|
||||
// }
|
||||
// }
|
||||
|
||||
// return vTarget.animateTransform(options)
|
||||
// }
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region tools
|
||||
|
||||
protected tools: ToolsView | null
|
||||
|
@ -538,9 +538,23 @@ export class EdgeView<
|
||||
}
|
||||
|
||||
protected findAnchors(vertices: Point.PointLike[]) {
|
||||
const edge = this.cell
|
||||
const source = edge.source as Edge.TerminalCellData
|
||||
const target = edge.target as Edge.TerminalCellData
|
||||
const firstVertex = vertices[0]
|
||||
const lastVertex = vertices[vertices.length - 1]
|
||||
|
||||
if (target.priority && !source.priority) {
|
||||
// Reversed order
|
||||
return this.findAnchorsOrdered(
|
||||
'target',
|
||||
lastVertex,
|
||||
'source',
|
||||
firstVertex,
|
||||
)
|
||||
}
|
||||
|
||||
// Usual order
|
||||
return this.findAnchorsOrdered('source', firstVertex, 'target', lastVertex)
|
||||
}
|
||||
|
||||
|
@ -333,17 +333,18 @@ export class NodeView<
|
||||
portContentSelectors,
|
||||
}
|
||||
|
||||
// todo
|
||||
// this.graph.hook.onPortRendered({
|
||||
// port,
|
||||
// node: this.cell,
|
||||
// container: portElement,
|
||||
// selectors: portSelectors,
|
||||
// labelContainer: portLabelElement,
|
||||
// labelSelectors: portLabelSelectors,
|
||||
// contentContainer: portContentElement,
|
||||
// contentSelectors: portContentSelectors,
|
||||
// })
|
||||
if (this.graph.options.onPortRendered) {
|
||||
this.graph.options.onPortRendered({
|
||||
port,
|
||||
node: this.cell,
|
||||
container: portElement,
|
||||
selectors: portSelectors,
|
||||
labelContainer: portLabelElement,
|
||||
labelSelectors: portLabelSelectors,
|
||||
contentContainer: portContentElement,
|
||||
contentSelectors: portContentSelectors,
|
||||
})
|
||||
}
|
||||
|
||||
return portElement
|
||||
}
|
||||
|
21
packages/x6-plugin-keyboard/LICENSE
Normal file
21
packages/x6-plugin-keyboard/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
5
packages/x6-plugin-keyboard/README.md
Normal file
5
packages/x6-plugin-keyboard/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# `x6-plugin-keyboard`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
1
packages/x6-plugin-keyboard/index.ts
Normal file
1
packages/x6-plugin-keyboard/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './src'
|
113
packages/x6-plugin-keyboard/package.json
Normal file
113
packages/x6-plugin-keyboard/package.json
Normal file
@ -0,0 +1,113 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-keyboard",
|
||||
"version": "2.0.6-beta.5",
|
||||
"description": "keyboard plugin for X6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"unpkg": "dist/x6-plugin-keyboard.js",
|
||||
"jsdelivr": "dist/x6-plugin-keyboard.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"es",
|
||||
"lib"
|
||||
],
|
||||
"keywords": [
|
||||
"plugin",
|
||||
"keyboard",
|
||||
"x6",
|
||||
"antv"
|
||||
],
|
||||
"scripts": {
|
||||
"clean:build": "rimraf dist es lib",
|
||||
"clean:coverage": "rimraf ./test/coverage",
|
||||
"clean": "run-p clean:build clean:coverage",
|
||||
"lint": "eslint 'src/**/*.{js,ts}?(x)' --fix",
|
||||
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
|
||||
"build:cjs": "tsc --module commonjs --target es2015 --outDir ./lib",
|
||||
"build:umd": "rollup -c",
|
||||
"build:dev": "run-p build:cjs build:esm",
|
||||
"build:watch": "yarn build:esm --w",
|
||||
"build:watch:esm": "yarn build:esm --w",
|
||||
"build:watch:cjs": "yarn build:cjs --w",
|
||||
"build": "run-p build:dev build:umd",
|
||||
"prebuild": "run-s lint clean",
|
||||
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
|
||||
"pretest": "run-p clean:coverage",
|
||||
"prepare": "run-s test build",
|
||||
"precommit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.ts": [
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"inherits": [
|
||||
"@antv/x6-package-json/cli.json",
|
||||
"@antv/x6-package-json/eslint.json",
|
||||
"@antv/x6-package-json/rollup.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"mousetrap": "^1.6.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@antv/x6-next": "2.0.6-beta.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^20.0.0",
|
||||
"@rollup/plugin-node-resolve": "^13.0.4",
|
||||
"@rollup/plugin-replace": "^3.0.0",
|
||||
"@rollup/plugin-typescript": "^8.2.5",
|
||||
"@types/mousetrap": "^1.6.5",
|
||||
"@typescript-eslint/eslint-plugin": "^4.31.0",
|
||||
"@typescript-eslint/parser": "^4.31.0",
|
||||
"coveralls": "^3.1.1",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
"eslint-plugin-jest": "^24.4.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-react": "^7.25.1",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-unicorn": "^36.0.0",
|
||||
"less": "^4.1.1",
|
||||
"lint-staged": "^11.1.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.3.6",
|
||||
"prettier": "^2.4.0",
|
||||
"pretty-quick": "^3.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.56.3",
|
||||
"rollup-plugin-auto-external": "^2.0.0",
|
||||
"rollup-plugin-filesize": "^9.1.1",
|
||||
"rollup-plugin-postcss": "^4.0.1",
|
||||
"rollup-plugin-progress": "^1.1.2",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"ts-node": "^10.2.1",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.4.3"
|
||||
},
|
||||
"author": {
|
||||
"name": "bubkoo",
|
||||
"email": "bubkoo.wy@gmail.com"
|
||||
},
|
||||
"contributors": [],
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/antvis/x6",
|
||||
"bugs": {
|
||||
"url": "https://github.com/antvis/x6/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/antvis/x6.git",
|
||||
"directory": "packages/x6-common"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
}
|
17
packages/x6-plugin-keyboard/rollup.config.js
Normal file
17
packages/x6-plugin-keyboard/rollup.config.js
Normal file
@ -0,0 +1,17 @@
|
||||
import config from '../../configs/rollup-config'
|
||||
|
||||
export default config({
|
||||
output: [
|
||||
{
|
||||
name: 'X6PluginKeyboard',
|
||||
format: 'umd',
|
||||
file: 'dist/x6-plugin-keyboard.js',
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
'@antv/x6-next': 'X6',
|
||||
'@antv/x6-common': 'X6Common',
|
||||
},
|
||||
},
|
||||
],
|
||||
external: ['@antv/x6-next', '@antv/x6-common'],
|
||||
})
|
69
packages/x6-plugin-keyboard/src/index.ts
Normal file
69
packages/x6-plugin-keyboard/src/index.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import { Disposable } from '@antv/x6-common'
|
||||
import { Graph } from '@antv/x6-next'
|
||||
import { KeyboardImpl } from './keyboard'
|
||||
|
||||
export class Keyboard extends Disposable {
|
||||
public name = 'keyboard'
|
||||
private keyboard: KeyboardImpl
|
||||
|
||||
constructor(public readonly options: KeyboardImpl.Options) {
|
||||
super()
|
||||
}
|
||||
|
||||
public init(graph: Graph) {
|
||||
this.keyboard = new KeyboardImpl({
|
||||
...this.options,
|
||||
graph,
|
||||
})
|
||||
}
|
||||
|
||||
isKeyboardEnabled() {
|
||||
return !this.keyboard.disabled
|
||||
}
|
||||
|
||||
enableKeyboard() {
|
||||
this.keyboard.enable()
|
||||
return this
|
||||
}
|
||||
|
||||
disableKeyboard() {
|
||||
this.keyboard.disable()
|
||||
return this
|
||||
}
|
||||
|
||||
toggleKeyboard(enabled?: boolean) {
|
||||
if (enabled != null) {
|
||||
if (enabled !== this.isKeyboardEnabled()) {
|
||||
if (enabled) {
|
||||
this.enableKeyboard()
|
||||
} else {
|
||||
this.disableKeyboard()
|
||||
}
|
||||
}
|
||||
} else if (this.isKeyboardEnabled()) {
|
||||
this.disableKeyboard()
|
||||
} else {
|
||||
this.enableKeyboard()
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
bindKey(
|
||||
keys: string | string[],
|
||||
callback: KeyboardImpl.Handler,
|
||||
action?: KeyboardImpl.Action,
|
||||
) {
|
||||
this.keyboard.on(keys, callback, action)
|
||||
return this
|
||||
}
|
||||
|
||||
unbindKey(keys: string | string[], action?: KeyboardImpl.Action) {
|
||||
this.keyboard.off(keys, action)
|
||||
return this
|
||||
}
|
||||
|
||||
@Disposable.dispose()
|
||||
dispose() {
|
||||
this.keyboard.dispose()
|
||||
}
|
||||
}
|
189
packages/x6-plugin-keyboard/src/keyboard.ts
Normal file
189
packages/x6-plugin-keyboard/src/keyboard.ts
Normal file
@ -0,0 +1,189 @@
|
||||
import Mousetrap from 'mousetrap'
|
||||
import { Dom, FunctionExt, Disposable, IDisablable } from '@antv/x6-common'
|
||||
import { Graph, EventArgs } from '@antv/x6-next'
|
||||
|
||||
export class KeyboardImpl extends Disposable implements IDisablable {
|
||||
public readonly target: HTMLElement | Document
|
||||
private readonly container: HTMLElement
|
||||
private readonly mousetrap: Mousetrap.MousetrapInstance
|
||||
|
||||
private get graph() {
|
||||
return this.options.graph
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly options: KeyboardImpl.Options & { graph: Graph },
|
||||
) {
|
||||
super()
|
||||
|
||||
const scroller = this.graph.getPlugin('scroller') as any
|
||||
this.container = scroller ? scroller.container : this.graph.container
|
||||
|
||||
if (options.global) {
|
||||
this.target = document
|
||||
} else {
|
||||
this.target = this.container
|
||||
if (!this.disabled) {
|
||||
// ensure the container focusable
|
||||
this.target.setAttribute('tabindex', '-1')
|
||||
}
|
||||
|
||||
// change to mouseup event,prevent page stalling caused by focus
|
||||
this.graph.on('cell:mouseup', this.focus, this)
|
||||
this.graph.on('blank:mouseup', this.focus, this)
|
||||
}
|
||||
|
||||
this.mousetrap = KeyboardImpl.createMousetrap(this)
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return this.options.enabled !== true
|
||||
}
|
||||
|
||||
enable() {
|
||||
if (this.disabled) {
|
||||
this.options.enabled = true
|
||||
if (this.target instanceof HTMLElement) {
|
||||
this.target.setAttribute('tabindex', '-1')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disable() {
|
||||
if (!this.disabled) {
|
||||
this.options.enabled = false
|
||||
if (this.target instanceof HTMLElement) {
|
||||
this.target.removeAttribute('tabindex')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
on(
|
||||
keys: string | string[],
|
||||
callback: KeyboardImpl.Handler,
|
||||
action?: KeyboardImpl.Action,
|
||||
) {
|
||||
this.mousetrap.bind(this.getKeys(keys), callback, action)
|
||||
}
|
||||
|
||||
off(keys: string | string[], action?: KeyboardImpl.Action) {
|
||||
this.mousetrap.unbind(this.getKeys(keys), action)
|
||||
}
|
||||
|
||||
private focus(e: EventArgs['node:mouseup']) {
|
||||
const isInputEvent = this.isInputEvent(e.e)
|
||||
if (isInputEvent) {
|
||||
return
|
||||
}
|
||||
const target = this.target as HTMLElement
|
||||
target.focus({
|
||||
preventScroll: true,
|
||||
})
|
||||
}
|
||||
|
||||
private getKeys(keys: string | string[]) {
|
||||
return (Array.isArray(keys) ? keys : [keys]).map((key) =>
|
||||
this.formatkey(key),
|
||||
)
|
||||
}
|
||||
|
||||
protected formatkey(key: string) {
|
||||
const formated = key
|
||||
.toLowerCase()
|
||||
.replace(/\s/g, '')
|
||||
.replace('delete', 'del')
|
||||
.replace('cmd', 'command')
|
||||
|
||||
const formatFn = this.options.format
|
||||
if (formatFn) {
|
||||
return FunctionExt.call(formatFn, this.graph, formated)
|
||||
}
|
||||
|
||||
return formated
|
||||
}
|
||||
|
||||
protected isGraphEvent(e: KeyboardEvent) {
|
||||
const target = (e.srcElement || e.target) as Element
|
||||
const currentTarget = e.currentTarget as Element
|
||||
if (target) {
|
||||
if (
|
||||
target === this.target ||
|
||||
currentTarget === this.target ||
|
||||
target === document.body
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
return Dom.contains(this.container, target)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
isInputEvent(e: KeyboardEvent | JQuery.MouseUpEvent) {
|
||||
const target = e.target as Element
|
||||
const tagName = target?.tagName?.toLowerCase()
|
||||
return ['input', 'textarea'].includes(tagName)
|
||||
}
|
||||
|
||||
isEnabledForEvent(e: KeyboardEvent) {
|
||||
const allowed = !this.disabled && this.isGraphEvent(e)
|
||||
const isInputEvent = this.isInputEvent(e)
|
||||
if (allowed) {
|
||||
const code = e.keyCode || e.which
|
||||
if (isInputEvent && (code === 8 || code === 46)) {
|
||||
return false
|
||||
}
|
||||
if (this.options.guard) {
|
||||
return FunctionExt.call(this.options.guard, this.graph, e)
|
||||
}
|
||||
}
|
||||
return allowed
|
||||
}
|
||||
|
||||
@Disposable.dispose()
|
||||
dispose() {
|
||||
this.mousetrap.reset()
|
||||
}
|
||||
}
|
||||
|
||||
export namespace KeyboardImpl {
|
||||
export type Action = 'keypress' | 'keydown' | 'keyup'
|
||||
export type Handler = (e: KeyboardEvent) => void
|
||||
|
||||
export interface Options {
|
||||
enabled?: boolean
|
||||
|
||||
/**
|
||||
* Specifies if keyboard event should bind on docuemnt or on container.
|
||||
*
|
||||
* Default is `false` that will bind keyboard event on the container.
|
||||
*/
|
||||
global?: boolean
|
||||
|
||||
format?: (this: Graph, key: string) => string
|
||||
guard?: (this: Graph, e: KeyboardEvent) => boolean
|
||||
}
|
||||
}
|
||||
|
||||
export namespace KeyboardImpl {
|
||||
export function createMousetrap(keyboard: KeyboardImpl) {
|
||||
const mousetrap = new Mousetrap(keyboard.target as Element)
|
||||
const stopCallback = mousetrap.stopCallback
|
||||
mousetrap.stopCallback = (
|
||||
e: KeyboardEvent,
|
||||
elem: HTMLElement,
|
||||
combo: string,
|
||||
) => {
|
||||
if (keyboard.isEnabledForEvent(e)) {
|
||||
if (stopCallback) {
|
||||
return stopCallback.call(mousetrap, e, elem, combo)
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return mousetrap
|
||||
}
|
||||
}
|
3
packages/x6-plugin-keyboard/tsconfig.json
Normal file
3
packages/x6-plugin-keyboard/tsconfig.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json"
|
||||
}
|
21
packages/x6-plugin-scroller/LICENSE
Normal file
21
packages/x6-plugin-scroller/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
5
packages/x6-plugin-scroller/README.md
Normal file
5
packages/x6-plugin-scroller/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# `x6-plugin-scroller`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
1
packages/x6-plugin-scroller/index.ts
Normal file
1
packages/x6-plugin-scroller/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './src'
|
110
packages/x6-plugin-scroller/package.json
Normal file
110
packages/x6-plugin-scroller/package.json
Normal file
@ -0,0 +1,110 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-scroller",
|
||||
"version": "2.0.6-beta.4",
|
||||
"description": "scroller plugin for X6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"unpkg": "dist/x6-plugin-scroller.js",
|
||||
"jsdelivr": "dist/x6-plugin-scroller.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"es",
|
||||
"lib"
|
||||
],
|
||||
"keywords": [
|
||||
"plugin",
|
||||
"scroller",
|
||||
"x6",
|
||||
"antv"
|
||||
],
|
||||
"scripts": {
|
||||
"clean:build": "rimraf dist es lib",
|
||||
"clean:coverage": "rimraf ./test/coverage",
|
||||
"clean": "run-p clean:build clean:coverage",
|
||||
"lint": "eslint 'src/**/*.{js,ts}?(x)' --fix",
|
||||
"build:less": "node ./scripts/style",
|
||||
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
|
||||
"build:cjs": "tsc --module commonjs --target es2015 --outDir ./lib",
|
||||
"build:umd": "rollup -c",
|
||||
"build:dev": "run-p build:less build:cjs build:esm",
|
||||
"build:watch": "yarn build:esm --w",
|
||||
"build:watch:esm": "yarn build:esm --w",
|
||||
"build:watch:cjs": "yarn build:cjs --w",
|
||||
"build": "run-p build:dev build:umd",
|
||||
"prebuild": "run-s lint clean",
|
||||
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
|
||||
"pretest": "run-p clean:coverage",
|
||||
"prepare": "run-s test build",
|
||||
"precommit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.ts": [
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"inherits": [
|
||||
"@antv/x6-package-json/cli.json",
|
||||
"@antv/x6-package-json/eslint.json",
|
||||
"@antv/x6-package-json/rollup.json"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@antv/x6-next": ">=2.0.6-beta.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^20.0.0",
|
||||
"@rollup/plugin-node-resolve": "^13.0.4",
|
||||
"@rollup/plugin-replace": "^3.0.0",
|
||||
"@rollup/plugin-typescript": "^8.2.5",
|
||||
"@typescript-eslint/eslint-plugin": "^4.31.0",
|
||||
"@typescript-eslint/parser": "^4.31.0",
|
||||
"coveralls": "^3.1.1",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-airbnb-base": "^14.2.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
"eslint-plugin-jest": "^24.4.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-react": "^7.25.1",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-unicorn": "^36.0.0",
|
||||
"less": "^4.1.1",
|
||||
"lint-staged": "^11.1.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.3.6",
|
||||
"prettier": "^2.4.0",
|
||||
"pretty-quick": "^3.1.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.56.3",
|
||||
"rollup-plugin-auto-external": "^2.0.0",
|
||||
"rollup-plugin-filesize": "^9.1.1",
|
||||
"rollup-plugin-postcss": "^4.0.1",
|
||||
"rollup-plugin-progress": "^1.1.2",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"ts-node": "^10.2.1",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.4.3"
|
||||
},
|
||||
"author": {
|
||||
"name": "bubkoo",
|
||||
"email": "bubkoo.wy@gmail.com"
|
||||
},
|
||||
"contributors": [],
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/antvis/x6",
|
||||
"bugs": {
|
||||
"url": "https://github.com/antvis/x6/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/antvis/x6.git",
|
||||
"directory": "packages/x6-common"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
}
|
18
packages/x6-plugin-scroller/rollup.config.js
Normal file
18
packages/x6-plugin-scroller/rollup.config.js
Normal file
@ -0,0 +1,18 @@
|
||||
import config from '../../configs/rollup-config'
|
||||
|
||||
export default config({
|
||||
output: [
|
||||
{
|
||||
name: 'X6PluginScroller',
|
||||
format: 'umd',
|
||||
file: 'dist/x6-plugin-scroller.js',
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
'@antv/x6-next': 'X6',
|
||||
'@antv/x6-common': 'X6Common',
|
||||
'@antv/x6-geometry': 'X6Geometry',
|
||||
},
|
||||
},
|
||||
],
|
||||
external: ['@antv/x6-next', '@antv/x6-common', '@antv/x6-geometry'],
|
||||
})
|
85
packages/x6-plugin-scroller/scripts/style.js
Normal file
85
packages/x6-plugin-scroller/scripts/style.js
Normal file
@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const fse = require('fs-extra')
|
||||
const cp = require('child_process')
|
||||
|
||||
const cwd = process.cwd()
|
||||
const es = path.join(cwd, 'es')
|
||||
const lib = path.join(cwd, 'lib')
|
||||
const src = path.join(cwd, 'src')
|
||||
const dist = path.join(cwd, 'dist')
|
||||
|
||||
function compile(source, target) {
|
||||
let cmd = './node_modules/.bin/lessc'
|
||||
if (os.type() === 'Windows_NT') {
|
||||
cmd = path.join(cwd, './node_modules/.bin/lessc.cmd')
|
||||
}
|
||||
cp.execFileSync(cmd, [source, target])
|
||||
}
|
||||
|
||||
compile(path.join(src, 'index.less'), path.join(es, 'index.css'))
|
||||
compile(path.join(src, 'index.less'), path.join(lib, 'index.css'))
|
||||
compile(path.join(src, 'index.less'), path.join(dist, 'scroller.css'))
|
||||
|
||||
function toCSSPath(source) {
|
||||
const dir = path.dirname(source)
|
||||
const file = `${path.basename(source, '.less')}.css`
|
||||
return path.join(dir, file)
|
||||
}
|
||||
|
||||
// Copy less files
|
||||
function processLessInDir(dir) {
|
||||
const stat = fs.statSync(dir)
|
||||
if (stat) {
|
||||
if (stat.isDirectory()) {
|
||||
fs.readdir(dir, (err, files) => {
|
||||
files.forEach((file) => {
|
||||
processLessInDir(path.join(dir, file))
|
||||
})
|
||||
})
|
||||
} else {
|
||||
const ext = path.extname(dir)
|
||||
if (ext === '.less' || ext === '.css') {
|
||||
fse.copySync(dir, path.join(es, path.relative(src, dir)))
|
||||
fse.copySync(dir, path.join(lib, path.relative(src, dir)))
|
||||
}
|
||||
|
||||
if (ext === '.less') {
|
||||
let source = path.join(es, path.relative(src, dir))
|
||||
let target = toCSSPath(source)
|
||||
compile(dir, target)
|
||||
|
||||
source = path.join(lib, path.relative(src, dir))
|
||||
target = toCSSPath(source)
|
||||
compile(dir, target)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function makeStyleModule() {
|
||||
const source = path.join(dist, 'scroller.css')
|
||||
const target = path.join(src, 'style/raw.ts')
|
||||
const content = fs.readFileSync(source, { encoding: 'utf8' })
|
||||
const prev = fs.existsSync(target)
|
||||
? fs.readFileSync(target, { encoding: 'utf8' })
|
||||
: null
|
||||
const curr = `/* eslint-disable */
|
||||
|
||||
/**
|
||||
* Auto generated file, do not modify it!
|
||||
*/
|
||||
|
||||
export const content = \`${content}\`
|
||||
`
|
||||
|
||||
if (prev !== curr) {
|
||||
fs.writeFileSync(target, curr)
|
||||
}
|
||||
}
|
||||
|
||||
processLessInDir(src)
|
||||
makeStyleModule()
|
76
packages/x6-plugin-scroller/src/index.less
Executable file
76
packages/x6-plugin-scroller/src/index.less
Executable file
@ -0,0 +1,76 @@
|
||||
@scroller-prefix-cls: ~'x6-graph-scroller';
|
||||
|
||||
.@{scroller-prefix-cls} {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
overflow: scroll;
|
||||
outline: none;
|
||||
|
||||
&-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.x6-graph {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
|
||||
> svg {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&&-paged {
|
||||
.x6-graph {
|
||||
box-shadow: 0 0 4px 0 #eee;
|
||||
}
|
||||
}
|
||||
|
||||
&&-pannable[data-panning='false'] {
|
||||
cursor: grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: -webkit-grab;
|
||||
}
|
||||
|
||||
&&-pannable[data-panning='true'] {
|
||||
cursor: grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: -webkit-grabbing;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
.x6-graph-pagebreak {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
&-vertical {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
box-sizing: border-box;
|
||||
width: 1px;
|
||||
border-left: 1px dashed #bdbdbd;
|
||||
}
|
||||
|
||||
&-horizontal {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
height: 1px;
|
||||
border-top: 1px dashed #bdbdbd;
|
||||
}
|
||||
}
|
181
packages/x6-plugin-scroller/src/index.ts
Normal file
181
packages/x6-plugin-scroller/src/index.ts
Normal file
@ -0,0 +1,181 @@
|
||||
import { Dom, ModifierKey, Disposable, CssLoader } from '@antv/x6-common'
|
||||
import { Graph, Config } from '@antv/x6-next'
|
||||
import { ScrollerImpl } from './scroller'
|
||||
import { content } from './style/raw'
|
||||
|
||||
export class Scroller extends Disposable {
|
||||
private graph: Graph
|
||||
public name = 'scroller'
|
||||
public scrollerImpl: ScrollerImpl
|
||||
|
||||
constructor(public readonly options: Scroller.Options) {
|
||||
super()
|
||||
}
|
||||
|
||||
get pannable() {
|
||||
if (this.options) {
|
||||
if (typeof this.options.pannable === 'object') {
|
||||
return this.options.pannable.enabled
|
||||
}
|
||||
return !!this.options.pannable
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
public init(graph: Graph) {
|
||||
this.graph = graph
|
||||
CssLoader.ensure('scroller', content)
|
||||
this.scrollerImpl = new ScrollerImpl({
|
||||
...this.options,
|
||||
graph,
|
||||
})
|
||||
this.startListening()
|
||||
this.updateClassName()
|
||||
this.scrollerImpl.center()
|
||||
}
|
||||
|
||||
protected startListening() {
|
||||
let eventTypes = []
|
||||
const pannable = this.options.pannable
|
||||
if (typeof pannable === 'object') {
|
||||
eventTypes = pannable.eventTypes || []
|
||||
} else {
|
||||
eventTypes = ['leftMouseDown']
|
||||
}
|
||||
if (eventTypes.includes('leftMouseDown')) {
|
||||
this.graph.on('blank:mousedown', this.preparePanning, this)
|
||||
this.graph.on('node:unhandled:mousedown', this.preparePanning, this)
|
||||
this.graph.on('edge:unhandled:mousedown', this.preparePanning, this)
|
||||
}
|
||||
if (eventTypes.includes('rightMouseDown')) {
|
||||
this.onRightMouseDown = this.onRightMouseDown.bind(this)
|
||||
Dom.Event.on(
|
||||
this.scrollerImpl.container,
|
||||
'mousedown',
|
||||
this.onRightMouseDown,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
protected stopListening() {
|
||||
let eventTypes = []
|
||||
const pannable = this.options.pannable
|
||||
if (typeof pannable === 'object') {
|
||||
eventTypes = pannable.eventTypes || []
|
||||
} else {
|
||||
eventTypes = ['leftMouseDown']
|
||||
}
|
||||
if (eventTypes.includes('leftMouseDown')) {
|
||||
this.graph.off('blank:mousedown', this.preparePanning, this)
|
||||
this.graph.off('node:unhandled:mousedown', this.preparePanning, this)
|
||||
this.graph.off('edge:unhandled:mousedown', this.preparePanning, this)
|
||||
}
|
||||
if (eventTypes.includes('rightMouseDown')) {
|
||||
Dom.Event.off(
|
||||
this.scrollerImpl.container,
|
||||
'mousedown',
|
||||
this.onRightMouseDown,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
protected onRightMouseDown(e: Dom.MouseDownEvent) {
|
||||
if (e.button === 2 && this.allowPanning(e, true)) {
|
||||
this.updateClassName(true)
|
||||
this.scrollerImpl.startPanning(e)
|
||||
this.scrollerImpl.once('pan:stop', () => this.updateClassName(false))
|
||||
}
|
||||
}
|
||||
|
||||
protected preparePanning({ e }: { e: Dom.MouseDownEvent }) {
|
||||
const allowPanning = this.allowPanning(e, true)
|
||||
const selection = this.graph.getPlugin('selection') as any
|
||||
const allowRubberband =
|
||||
this.allowPanning(e) && selection && selection.allowRubberband(e, true)
|
||||
if (allowPanning || !allowRubberband) {
|
||||
this.updateClassName(true)
|
||||
this.scrollerImpl.startPanning(e)
|
||||
this.scrollerImpl.once('pan:stop', () => this.updateClassName(false))
|
||||
}
|
||||
}
|
||||
|
||||
allowPanning(e: Dom.MouseDownEvent, strict?: boolean) {
|
||||
return (
|
||||
this.pannable && ModifierKey.isMatch(e, this.options.modifiers, strict)
|
||||
)
|
||||
}
|
||||
|
||||
protected updateClassName(isPanning?: boolean) {
|
||||
const container = this.scrollerImpl.container!
|
||||
const pannable = Config.prefix('graph-scroller-pannable')
|
||||
if (this.pannable) {
|
||||
Dom.addClass(container, pannable)
|
||||
container.dataset.panning = (!!isPanning).toString() // Use dataset to control scroller panning style to avoid reflow caused by changing classList
|
||||
} else {
|
||||
Dom.removeClass(container, pannable)
|
||||
}
|
||||
}
|
||||
|
||||
enablePanning() {
|
||||
if (!this.pannable) {
|
||||
this.options.pannable = true
|
||||
this.updateClassName()
|
||||
|
||||
// if (
|
||||
// ModifierKey.equals(
|
||||
// this.graph.options.scroller.modifiers,
|
||||
// this.graph.options.selecting.modifiers,
|
||||
// )
|
||||
// ) {
|
||||
// this.graph.selection.disableRubberband()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
disablePanning() {
|
||||
if (this.pannable) {
|
||||
this.options.pannable = false
|
||||
this.updateClassName()
|
||||
}
|
||||
}
|
||||
|
||||
lock() {
|
||||
this.scrollerImpl.lock()
|
||||
}
|
||||
|
||||
unlock() {
|
||||
this.scrollerImpl.unlock()
|
||||
}
|
||||
|
||||
update() {
|
||||
this.scrollerImpl.update()
|
||||
}
|
||||
|
||||
enableAutoResize() {
|
||||
this.scrollerImpl.enableAutoResize()
|
||||
}
|
||||
|
||||
disableAutoResize() {
|
||||
this.scrollerImpl.disableAutoResize()
|
||||
}
|
||||
|
||||
resize(width?: number, height?: number) {
|
||||
this.scrollerImpl.resize(width, height)
|
||||
}
|
||||
|
||||
@Disposable.dispose()
|
||||
dispose() {
|
||||
this.scrollerImpl.dispose()
|
||||
this.stopListening()
|
||||
CssLoader.clean('scroller')
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Scroller {
|
||||
type EventType = 'leftMouseDown' | 'rightMouseDown'
|
||||
export interface Options extends ScrollerImpl.CommonOptions {
|
||||
pannable?: boolean | { enabled: boolean; eventTypes: EventType[] }
|
||||
modifiers?: string | ModifierKey[] | null // alt, ctrl, shift, meta
|
||||
}
|
||||
}
|
1433
packages/x6-plugin-scroller/src/scroller.ts
Normal file
1433
packages/x6-plugin-scroller/src/scroller.ts
Normal file
File diff suppressed because it is too large
Load Diff
69
packages/x6-plugin-scroller/src/style/raw.ts
Normal file
69
packages/x6-plugin-scroller/src/style/raw.ts
Normal file
@ -0,0 +1,69 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* Auto generated file, do not modify it!
|
||||
*/
|
||||
|
||||
export const content = `.x6-graph-scroller {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
overflow: scroll;
|
||||
outline: none;
|
||||
}
|
||||
.x6-graph-scroller-content {
|
||||
position: relative;
|
||||
}
|
||||
.x6-graph-scroller-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.x6-graph-scroller .x6-graph {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
.x6-graph-scroller .x6-graph > svg {
|
||||
display: block;
|
||||
}
|
||||
.x6-graph-scroller.x6-graph-scroller-paged .x6-graph {
|
||||
box-shadow: 0 0 4px 0 #eee;
|
||||
}
|
||||
.x6-graph-scroller.x6-graph-scroller-pannable[data-panning='false'] {
|
||||
cursor: grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: -webkit-grab;
|
||||
}
|
||||
.x6-graph-scroller.x6-graph-scroller-pannable[data-panning='true'] {
|
||||
cursor: grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: -webkit-grabbing;
|
||||
user-select: none;
|
||||
}
|
||||
.x6-graph-pagebreak {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.x6-graph-pagebreak-vertical {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
box-sizing: border-box;
|
||||
width: 1px;
|
||||
border-left: 1px dashed #bdbdbd;
|
||||
}
|
||||
.x6-graph-pagebreak-horizontal {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
height: 1px;
|
||||
border-top: 1px dashed #bdbdbd;
|
||||
}
|
||||
`
|
3
packages/x6-plugin-scroller/tsconfig.json
Normal file
3
packages/x6-plugin-scroller/tsconfig.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json"
|
||||
}
|
21
packages/x6-react-components/LICENSE
Normal file
21
packages/x6-react-components/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-react-components",
|
||||
"version": "1.1.16",
|
||||
"version": "2.0.6-beta.2",
|
||||
"description": "React components for building x6 editors",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -22,7 +22,7 @@
|
||||
"lint:ts": "eslint 'src/**/*.{js,ts}?(x)' --fix",
|
||||
"lint:style": "stylelint 'src/**/*.less' --syntax less --fix",
|
||||
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
|
||||
"build:cjs": "tsc --module commonjs --target es5 --outDir ./lib",
|
||||
"build:cjs": "tsc --module commonjs --target es2015 --outDir ./lib",
|
||||
"build:umd": "rollup -c",
|
||||
"build:watch": "yarn build:esm --w",
|
||||
"build:watch:esm": "yarn build:esm --w",
|
||||
@ -143,5 +143,6 @@
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
},
|
||||
"gitHead": "576fa342fa65a6867ead29f6801a30dcb31bcdb5"
|
||||
}
|
||||
|
21
packages/x6-react-shape/LICENSE
Normal file
21
packages/x6-react-shape/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-react-shape",
|
||||
"version": "2.0.1-beta.3",
|
||||
"version": "2.0.6-beta.2",
|
||||
"description": "X6 shape for rendering react components.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -24,7 +24,7 @@
|
||||
"lint": "eslint 'src/**/*.{js,ts}?(x)' --fix",
|
||||
"watch": "watch 'yarn build' ./src",
|
||||
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
|
||||
"build:cjs": "tsc --module commonjs --target es5 --outDir ./lib",
|
||||
"build:cjs": "tsc --module commonjs --target es2015 --outDir ./lib",
|
||||
"build:umd": "rollup -c",
|
||||
"build:watch": "yarn build:esm --w",
|
||||
"build:watch:esm": "yarn build:esm --w",
|
||||
@ -45,8 +45,8 @@
|
||||
"@antv/x6-package-json/rollup.json"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@antv/x6-next": "2.0.1-beta.3",
|
||||
"@antv/x6-common": "2.0.1-beta.3",
|
||||
"@antv/x6-common": ">=2.0.6-beta.0",
|
||||
"@antv/x6-next": ">=2.0.6-beta.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
@ -109,5 +109,6 @@
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
},
|
||||
"gitHead": "576fa342fa65a6867ead29f6801a30dcb31bcdb5"
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { Graph, Node } from '@antv/x6-next'
|
||||
export type ReactShapeConfig = Node.Properties & {
|
||||
shape: string
|
||||
effect?: (keyof Node.Properties)[]
|
||||
inherit?: string
|
||||
}
|
||||
|
||||
export const shapeMaps: Record<
|
||||
@ -18,7 +19,7 @@ export function register(
|
||||
componentOrFC: React.ComponentType,
|
||||
config: ReactShapeConfig,
|
||||
) {
|
||||
const { shape, effect, ...others } = config
|
||||
const { shape, effect, inherit, ...others } = config
|
||||
if (!shape) {
|
||||
throw new Error('should specify shape in config')
|
||||
}
|
||||
@ -30,7 +31,7 @@ export function register(
|
||||
Graph.registerNode(
|
||||
shape,
|
||||
{
|
||||
inherit: 'react-shape',
|
||||
inherit: inherit || 'react-shape',
|
||||
...others,
|
||||
},
|
||||
true,
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "1.3.0",
|
||||
"name": "@antv/x6-vector",
|
||||
"description": "Lightweight library for manipulating and animating SVG.",
|
||||
|
21
packages/x6-vue-shape/LICENSE
Normal file
21
packages/x6-vue-shape/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 Alipay.inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-vue-shape",
|
||||
"version": "2.0.1-beta.3",
|
||||
"version": "2.0.6-beta.2",
|
||||
"description": "X6 shape for rendering vue components.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -23,7 +23,7 @@
|
||||
"clean": "rimraf dist es lib",
|
||||
"lint": "eslint 'src/**/*.{js,ts}?(x)' --fix",
|
||||
"build:esm": "tsc --module esnext --target es2015 --outDir ./es",
|
||||
"build:cjs": "tsc --module commonjs --target es5 --outDir ./lib",
|
||||
"build:cjs": "tsc --module commonjs --target es2015 --outDir ./lib",
|
||||
"build:umd": "rollup -c",
|
||||
"build:watch": "yarn build:esm --w",
|
||||
"build:watch:esm": "yarn build:esm --w",
|
||||
@ -48,8 +48,8 @@
|
||||
"vue-demi": "^0.7.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@antv/x6-next": "2.0.1-beta.3",
|
||||
"@antv/x6-common": "2.0.1-beta.3",
|
||||
"@antv/x6-common": ">=2.0.6-beta.0",
|
||||
"@antv/x6-next": ">=2.0.6-beta.0",
|
||||
"@vue/composition-api": "^1.0.0-rc.6",
|
||||
"vue": "^2.6.12 || ^3.0.0"
|
||||
},
|
||||
@ -115,5 +115,6 @@
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
},
|
||||
"gitHead": "576fa342fa65a6867ead29f6801a30dcb31bcdb5"
|
||||
}
|
||||
|
@ -17,5 +17,7 @@ wait
|
||||
|
||||
lerna run build --stream --scope @antv/x6-vue-shape \
|
||||
--scope @antv/x6-react-shape \
|
||||
--scope @antv/x6-plugin-keyboard \
|
||||
--scope @antv/x6-plugin-scroller
|
||||
|
||||
wait
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user