Compare commits
20 Commits
v2.0.6-bet
...
v2.0.6-bet
Author | SHA1 | Date | |
---|---|---|---|
c9494e7f79 | |||
1e7f132bed | |||
9a1834e808 | |||
6e1bd9b530 | |||
12e4ac55d7 | |||
294672b306 | |||
68c2346e0c | |||
24de1254a1 | |||
88918f7611 | |||
5e102a39c5 | |||
2f310fcceb | |||
40d53355ce | |||
1dcb3d92fd | |||
9fe7cd51a3 | |||
34481de1db | |||
9d597a92da | |||
40f278f064 | |||
f3edbbc95d | |||
50a5dc7cd8 | |||
5aeae976cd |
examples/x6-example-features/src/pages
animation
auto-resize
basic
case
connector
edge
fta
hull
index.tsxissues
performance
react
selection
shape
snapline
packages
x6-common
index.tspackage.json
src
__tests__
color
common
datauri
dom
af.test.tsattr.test.tsclass.test.tscss.test.tsdata.test.tselem.test.tsevent.test.tsmatrix.test.tspath.test.tsprefix.test.tsselection.test.tsstyle.test.tstext.test.tstransform.test.ts
event
function
json
number
object
string
text
unit
vector
dom
x6-geometry
x6-plugin-keyboard
x6-plugin-scroller
x6-plugin-selection
x6-plugin-snapline
x6-react-components
x6-react-shape
x6-vue-shape
x6
scripts
sites/x6-svg-to-shape
@ -1,262 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node, Edge, NodeView, Point, Angle, Interp } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
class BallView extends NodeView {
|
||||
protected speed: number = 0
|
||||
protected angle: number = 0
|
||||
protected edge: Edge | null
|
||||
|
||||
protected init() {
|
||||
this.cell.transition('attrs/label/opacity', 1, {
|
||||
delay: 0,
|
||||
duration: 3000,
|
||||
timing: 'inout',
|
||||
interp: function (a: number, b: number) {
|
||||
return function (t: number) {
|
||||
return a + b * (1 - Math.abs(1 - 2 * t))
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
this.cell.on('transition:complete', ({ cell, path }) => {
|
||||
if (path === 'position' && this.speed > 5) {
|
||||
this.speed /= cell.prop<number>('bounciness') || 2
|
||||
this.fly({ angle: 180 - this.angle, speed: this.speed })
|
||||
}
|
||||
})
|
||||
|
||||
this.cell.on('change:position', ({ cell, current }) => {
|
||||
const node = cell as any as Node
|
||||
this.angle = Point.create(node.getPosition()).theta(
|
||||
node.previous('position'),
|
||||
)
|
||||
//this.speed = we are using constant speed for simplicity
|
||||
|
||||
if (current) {
|
||||
if (
|
||||
current.x < 0 ||
|
||||
current.x > this.graph.options.width - node.getSize().width
|
||||
) {
|
||||
this.angle -= 180
|
||||
node.position(node.previous('position')!.x, current.y, {
|
||||
silent: true,
|
||||
})
|
||||
cell.stopTransition('position')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fly(opts: { speed?: number; angle?: number } = {}) {
|
||||
const options = {
|
||||
speed: 100,
|
||||
angle: 90,
|
||||
...opts,
|
||||
}
|
||||
const pos = this.cell.getPosition()
|
||||
const size = this.cell.getSize()
|
||||
const ga = 9.81
|
||||
const h0 = this.graph.options.height - pos.y - size.height
|
||||
const v0 = options.speed
|
||||
const sin1 = Math.sin(Angle.toRad(options.angle))
|
||||
|
||||
const flightTime =
|
||||
(v0 * sin1 +
|
||||
Math.sqrt(Math.pow(v0, 2) * Math.pow(sin1, 2) + 2 * h0 * ga)) /
|
||||
ga
|
||||
|
||||
this.cell.transition('position', options, {
|
||||
duration: 100 * flightTime,
|
||||
interp(
|
||||
position: Point.PointLike,
|
||||
params: { speed: number; angle: number },
|
||||
) {
|
||||
return function (t: number) {
|
||||
t = flightTime * t
|
||||
return {
|
||||
x:
|
||||
position.x +
|
||||
params.speed * t * Math.cos((Math.PI / 180) * params.angle),
|
||||
y:
|
||||
position.y -
|
||||
params.speed * t * Math.sin((Math.PI / 180) * params.angle) +
|
||||
(ga / 2) * t * t,
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
this.cell.transition('angle', -options.angle, {
|
||||
duration: 100 * flightTime,
|
||||
})
|
||||
|
||||
this.speed = options.speed
|
||||
this.angle = options.angle
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
this.edge = this.graph.addEdge({
|
||||
shape: 'edge',
|
||||
source: this.cell.getBBox().getCenter(),
|
||||
target: { x, y },
|
||||
zIndex: -1,
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: 'rgba(0,0,0,0.1)',
|
||||
strokeWidth: 6,
|
||||
targetMarker: {
|
||||
stroke: 'black',
|
||||
strokeWidth: 2,
|
||||
d: 'M 20 -10 L 0 0 L 20 10 z',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Change the marker arrow color.
|
||||
this.edge.on('change:target', ({ cell }) => {
|
||||
const edge = cell as any as Edge
|
||||
const sourcePoint = edge.getSourcePoint()!
|
||||
const targetPoint = edge.getTargetPoint()!
|
||||
const dist = sourcePoint.distance(targetPoint)
|
||||
const maxDist = Math.max(
|
||||
this.graph.options.width,
|
||||
this.graph.options.height,
|
||||
)
|
||||
const interp = Interp.color('#ffffff', '#ff0000')
|
||||
edge.attr('line/targetMarker/fill', interp(dist / maxDist / Math.sqrt(2)))
|
||||
})
|
||||
}
|
||||
|
||||
onMouseMove(e: JQuery.MouseMoveEvent, x: number, y: number) {
|
||||
if (this.edge) {
|
||||
this.edge.setTarget({ x, y })
|
||||
}
|
||||
}
|
||||
|
||||
onMouseUp(e: JQuery.MouseUpEvent, x: number, y: number) {
|
||||
if (!this.edge) {
|
||||
return
|
||||
}
|
||||
|
||||
const sourcePoint = this.edge.getSourcePoint()!
|
||||
const targetPoint = this.edge.getTargetPoint()!
|
||||
|
||||
this.edge.remove()
|
||||
this.edge = null
|
||||
|
||||
this.fly({
|
||||
angle: Math.abs(targetPoint.theta(sourcePoint) - 180),
|
||||
speed: sourcePoint.distance(targetPoint) / 2,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
NodeView.registry.register('ball', BallView as any, true)
|
||||
|
||||
Node.registry.register(
|
||||
'ball',
|
||||
{
|
||||
view: 'ball',
|
||||
markup: [
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'label',
|
||||
},
|
||||
{
|
||||
tagName: 'image',
|
||||
selector: 'ball',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
label: {
|
||||
text: 'Drag me!',
|
||||
fontSize: 40,
|
||||
fontWeight: 900,
|
||||
refX: 0.5,
|
||||
refY: -20,
|
||||
textVerticalAnchor: 'middle',
|
||||
textAnchor: 'middle',
|
||||
fill: 'white',
|
||||
strokeWidth: 2,
|
||||
stroke: 'black',
|
||||
opacity: 0,
|
||||
pointerEvents: 'none',
|
||||
},
|
||||
ball: {
|
||||
refWidth: 1,
|
||||
refHeight: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 650,
|
||||
height: 400,
|
||||
grid: 1,
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
shape: 'ball',
|
||||
x: 250,
|
||||
y: 370,
|
||||
width: 30,
|
||||
height: 30,
|
||||
bounciness: 3,
|
||||
attrs: {
|
||||
image: {
|
||||
'xlink:href':
|
||||
'data:image/svg+xml;base64,PHN2ZyB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIiB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIgaWQ9InN2ZzIiIHZpZXdCb3g9IjAgMCA1MTAgNTEwIiB2ZXJzaW9uPSIxLjEiIGlua3NjYXBlOnZlcnNpb249IjAuNDcgcjIyNTgzIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBzb2RpcG9kaTpkb2NuYW1lPSJibHVlIGJhbGwuc3ZnIj4KICA8c29kaXBvZGk6bmFtZWR2aWV3IHBhZ2Vjb2xvcj0iI2ZmZmZmZiIgYm9yZGVyY29sb3I9IiM2NjY2NjYiIGJvcmRlcm9wYWNpdHk9IjEiIG9iamVjdHRvbGVyYW5jZT0iMTAiIGdyaWR0b2xlcmFuY2U9IjEwIiBndWlkZXRvbGVyYW5jZT0iMTAiIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwIiBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIiBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjEwMjQiIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjU0OCIgaWQ9Im5hbWVkdmlldzE2IiBzaG93Z3JpZD0iZmFsc2UiIGlua3NjYXBlOnNuYXAtZ2xvYmFsPSJmYWxzZSIgaW5rc2NhcGU6em9vbT0iMC40MzY2Mzc1MyIgaW5rc2NhcGU6Y3g9IjI1Ni4yMzMxMSIgaW5rc2NhcGU6Y3k9IjI1OC44NTEwNyIgaW5rc2NhcGU6d2luZG93LXg9Ii04IiBpbmtzY2FwZTp3aW5kb3cteT0iLTgiIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIvPgogIDxkZWZzIGlkPSJkZWZzNCI+CiAgICA8aW5rc2NhcGU6cGF0aC1lZmZlY3QgZWZmZWN0PSJzcGlybyIgaWQ9InBhdGgtZWZmZWN0MzYyMCIgaXNfdmlzaWJsZT0idHJ1ZSIvPgogICAgPGlua3NjYXBlOnBlcnNwZWN0aXZlIHNvZGlwb2RpOnR5cGU9Imlua3NjYXBlOnBlcnNwM2QiIGlua3NjYXBlOnZwX3g9IjAgOiAyNTUgOiAxIiBpbmtzY2FwZTp2cF95PSIwIDogMTAwMCA6IDAiIGlua3NjYXBlOnZwX3o9IjUxMCA6IDI1NSA6IDEiIGlua3NjYXBlOnBlcnNwM2Qtb3JpZ2luPSIyNTUgOiAxNzAgOiAxIiBpZD0icGVyc3BlY3RpdmUxOCIvPgogICAgPGxpbmVhckdyYWRpZW50IGlkPSJsaW5lYXJHcmFkaWVudDM1OTQiPgogICAgICA8c3RvcCBpZD0ic3RvcDM1OTYiIHN0b3AtY29sb3I9IiNGRkYiIG9mZnNldD0iMCIvPgogICAgICA8c3RvcCBpZD0ic3RvcDM1OTgiIHN0b3AtY29sb3I9IiMwMDAiIHN0b3Atb3BhY2l0eT0iMC40MTA3MTQzIiBvZmZzZXQ9IjEiLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgICA8ZmlsdGVyIGlkPSJmaWx0ZXI0MDY3IiBoZWlnaHQ9IjEuMjYwMTk3MiIgd2lkdGg9IjEuMjg0MjYyOCIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIiB5PSItMC4xMzAwOTg1OCIgeD0iLTAuMTQyMTMxNCI+CiAgICAgIDxmZUdhdXNzaWFuQmx1ciBpZD0iZmVHYXVzc2lhbkJsdXI0MDY5IiBzdGREZXZpYXRpb249IjEuOTEyMzg5NCIvPgogICAgPC9maWx0ZXI+CiAgICA8cmFkaWFsR3JhZGllbnQgaWQ9InJhZGlhbEdyYWRpZW50NDA4MyIgeGxpbms6aHJlZj0iI2xpbmVhckdyYWRpZW50MzU5NCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGN5PSI0NzkuNTQiIGN4PSIyNzIuMTUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoLTAuMzExNjQ5OTIsMS4zMTAxMDczLC0xLjMxMDE2NjEsLTAuMzExNjYzODksMTA0MS4yNzkxLDE5OS4yMDMwOSkiIHI9IjI1My4yNiIvPgogICAgPGZpbHRlciB4PSItMC4xNDMxMjQ1NSIgeT0iLTAuMTMxMDEwNzYiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiIgd2lkdGg9IjEuMjg2MjQ5IiBoZWlnaHQ9IjEuMjYyMDIxNSIgaWQ9ImZpbHRlcjM2MDEiPgogICAgICA8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIyMy4xMDkyNDgiIGlkPSJmZUdhdXNzaWFuQmx1cjM2MDMiLz4KICAgIDwvZmlsdGVyPgogICAgPGZpbHRlciB4PSItMC4xNDIxMzE0IiB5PSItMC4xMzAwOTg1OCIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIiB3aWR0aD0iMS4yODQyNjI4IiBoZWlnaHQ9IjEuMjYwMTk3MiIgaWQ9ImZpbHRlcjM2MDUiPgogICAgICA8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIyMi45NDg2NzMiIGlkPSJmZUdhdXNzaWFuQmx1cjM2MDciLz4KICAgIDwvZmlsdGVyPgogICAgPGZpbHRlciB4PSItMC4xNDIxMzE0IiB5PSItMC4xMzAwOTg1OCIgY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzPSJzUkdCIiB3aWR0aD0iMS4yODQyNjI4IiBoZWlnaHQ9IjEuMjYwMTk3MiIgaWQ9ImZpbHRlcjM2MDkiPgogICAgICA8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIyMi45NDg2NzMiIGlkPSJmZUdhdXNzaWFuQmx1cjM2MTEiLz4KICAgIDwvZmlsdGVyPgogICAgPGZpbHRlciBpbmtzY2FwZTpjb2xsZWN0PSJhbHdheXMiIGlkPSJmaWx0ZXIzNzU2Ij4KICAgICAgPGZlR2F1c3NpYW5CbHVyIGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyIgc3RkRGV2aWF0aW9uPSI3LjMxNTE1MzMiIGlkPSJmZUdhdXNzaWFuQmx1cjM3NTgiLz4KICAgIDwvZmlsdGVyPgogIDwvZGVmcz4KICA8bWV0YWRhdGEgaWQ9Im1ldGFkYXRhNyI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiLz4KICAgICAgICA8ZGM6dGl0bGUvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZyBpZD0ibGF5ZXIxIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNTQuMjg1NjksLTIyOC4wNzY0OSkiPgogICAgPHBhdGggaWQ9InBhdGgyODE4IiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHlsZT0ic3Ryb2tlLWRhc2hhcnJheTpub25lOyIgZD0iTTY2MCw0ODUuNzhhMjUyLjg2LDI1Mi44NiwwLDEsMSwwLC0wLjU2IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0LC0yKSIgc3Ryb2tlLWRhc2hvZmZzZXQ9IjAuNDc5IiBzdHJva2U9IiM3ODc4NzgiIHN0cm9rZS1taXRlcmxpbWl0PSI0IiBzdHJva2Utd2lkdGg9IjAuODAwMDAwMDEiIGZpbGw9IiMxMDZkZDUiLz4KICAgIDxwYXRoIGlkPSJwYXRoMzU5MiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNCwtMikiIGZpbGw9InVybCgjcmFkaWFsR3JhZGllbnQ0MDgzKSIgZD0iTTY2MCw0ODUuNzhhMjUyLjg2LDI1Mi44NiwwLDEsMSwwLC0wLjU2Ii8+CiAgICA8cGF0aCBpZD0icGF0aDQwNzgiIGQ9Ik02NjAsNDg1Ljc4YTI1Mi44NiwyNTIuODYsMCwxLDEsMCwtMC41NiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNCwtMikiIGZpbGw9InVybCgjcmFkaWFsR3JhZGllbnQ0MDgzKSIvPgogIDwvZz4KPC9zdmc+',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
shape: 'ball',
|
||||
x: 400,
|
||||
y: 350,
|
||||
width: 50,
|
||||
height: 50,
|
||||
bounciness: 1.5,
|
||||
attrs: {
|
||||
image: {
|
||||
'xlink:href':
|
||||
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iODAwIiBoZWlnaHQ9IjgwMCIgdmlld0JveD0iLTEwNSAtMTA1IDIxMCAyMTAiPgogICA8ZGVmcz4KICAgICAgPGNsaXBQYXRoIGlkPSJiYWxsIj4KICAgICAgICAgPGNpcmNsZSByPSIxMDAiIHN0cm9rZS13aWR0aD0iMCIvPgogICAgICA8L2NsaXBQYXRoPgogICAgICA8cmFkaWFsR3JhZGllbnQgaWQ9InNoYWRvdzEiIGN4PSIuNCIgY3k9Ii4zIiByPSIuOCI+CiAgICAgICAgPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICAgICAgPHN0b3Agb2Zmc2V0PSIuNCIgc3RvcC1jb2xvcj0id2hpdGUiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgICAgIDxzdG9wIG9mZnNldD0iLjgiIHN0b3AtY29sb3I9IiNFRUVFRUUiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgICA8L3JhZGlhbEdyYWRpZW50PgogICAgICA8cmFkaWFsR3JhZGllbnQgaWQ9InNoYWRvdzIiIGN4PSIuNSIgY3k9Ii41IiByPSIuNSI+CiAgICAgICAgPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSJ3aGl0ZSIgc3RvcC1vcGFjaXR5PSIwIi8+CiAgICAgICAgPHN0b3Agb2Zmc2V0PSIuOCIgc3RvcC1jb2xvcj0id2hpdGUiIHN0b3Atb3BhY2l0eT0iMCIvPgogICAgICAgIDxzdG9wIG9mZnNldD0iLjk5IiBzdG9wLWNvbG9yPSJibGFjayIgc3RvcC1vcGFjaXR5PSIuMyIvPgogICAgICAgIDxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iYmxhY2siIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgICA8L3JhZGlhbEdyYWRpZW50PgogICAgICA8ZyBpZD0iYmxhY2tfc3R1ZmYiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsaXAtcGF0aD0idXJsKCNiYWxsKSI+CiAgICAgICAgIDxnIGZpbGw9ImJsYWNrIj4KICAgICAgICAgICAgPHBhdGggZD0iTSA2LC0zMiBRIDI2LC0yOCA0NiwtMTkgUSA1NywtMzUgNjQsLTQ3IFEgNTAsLTY4IDM3LC03NiBRIDE3LC03NSAxLC02OCBRIDQsLTUxIDYsLTMyIi8+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0gLTI2LC0yIFEgLTQ1LC04IC02MiwtMTEgUSAtNzQsNSAtNzYsMjIgUSAtNjksNDAgLTUwLDU0IFEgLTMyLDQ3IC0xNywzOSBRIC0yMywxNSAtMjYsLTIiLz4KICAgICAgICAgICAgPHBhdGggZD0iTSAtOTUsMjIgUSAtMTAyLDEyIC0xMDIsLTggViA4MCBIIC04NSBRIC05NSw0NSAtOTUsMjIiLz4KICAgICAgICAgICAgPHBhdGggZD0iTSA1NSwyNCBRIDQxLDQxIDI0LDUyIFEgMjgsNjUgMzEsNzkgUSA1NSw3OCA2OCw2NyBRIDc4LDUwIDgwLDM1IFEgNjUsMjggNTUsMjQiLz4KICAgICAgICAgICAgPHBhdGggZD0iTSAwLDEyMCBMIC0zLDk1IFEgLTI1LDkzIC00Miw4MiBRIC01MCw4NCAtNjAsODEiLz4KICAgICAgICAgICAgPHBhdGggZD0iTSAtOTAsLTQ4IFEgLTgwLC01MiAtNjgsLTQ5IFEgLTUyLC03MSAtMzUsLTc3IFEgLTM1LC0xMDAgLTQwLC0xMDAgSCAtMTAwIi8+CiAgICAgICAgICAgIDxwYXRoIGQ9Ik0gMTAwLC01NSBMIDg3LC0zNyBRIDk4LC0xMCA5Nyw1IEwgMTAwLDYiLz4KICAgICAgICAgPC9nPgogICAgICAgICA8ZyBmaWxsPSJub25lIj4KICAgICAgICAgICAgPHBhdGggZD0iTSA2LC0zMiBRIC0xOCwtMTIgLTI2LC0yICAgICAgICAgICAgICAgICAgICAgIE0gNDYsLTE5IFEgNTQsNSA1NSwyNCAgICAgICAgICAgICAgICAgICAgICBNIDY0LC00NyBRIDc3LC00NCA4NywtMzcgICAgICAgICAgICAgICAgICAgICAgTSAzNywtNzYgUSAzOSwtOTAgMzYsLTEwMCAgICAgICAgICAgICAgICAgICAgICBNIDEsLTY4IFEgLTEzLC03NyAtMzUsLTc3ICAgICAgICAgICAgICAgICAgICAgIE0gLTYyLC0xMSBRIC02NywtMjUgLTY4LC00OSAgICAgICAgICAgICAgICAgICAgICBNIC03NiwyMiBRIC04NSwyNCAtOTUsMjIgICAgICAgICAgICAgICAgICAgICAgTSAtNTAsNTQgUSAtNDksNzAgLTQyLDgyICAgICAgICAgICAgICAgICAgICAgIE0gLTE3LDM5IFEgMCw0OCAyNCw1MiAgICAgICAgICAgICAgICAgICAgICBNIDMxLDc5IFEgMjAsOTIgLTMsOTUgICAgICAgICAgICAgICAgICAgICAgTSA2OCw2NyBMIDgwLDgwICAgICAgICAgICAgICAgICAgICAgIE0gODAsMzUgUSA5MCwyNSA5Nyw1ICAgICAgICAgICAgICIvPgogICAgICAgICA8L2c+CiAgICAgIDwvZz4KICAgPC9kZWZzPgogICA8Y2lyY2xlIHI9IjEwMCIgZmlsbD0id2hpdGUiIHN0cm9rZT0ibm9uZSIvPgogICA8Y2lyY2xlIHI9IjEwMCIgZmlsbD0idXJsKCNzaGFkb3cxKSIgc3Ryb2tlPSJub25lIi8+CiAgIDx1c2UgeGxpbms6aHJlZj0iI2JsYWNrX3N0dWZmIiBzdHJva2U9IiNFRUUiIHN0cm9rZS13aWR0aD0iNyIvPgogICA8dXNlIHhsaW5rOmhyZWY9IiNibGFja19zdHVmZiIgc3Ryb2tlPSIjREREIiBzdHJva2Utd2lkdGg9IjQiLz4KICAgPHVzZSB4bGluazpocmVmPSIjYmxhY2tfc3R1ZmYiIHN0cm9rZT0iIzk5OSIgc3Ryb2tlLXdpZHRoPSIyIi8+CiAgIDx1c2UgeGxpbms6aHJlZj0iI2JsYWNrX3N0dWZmIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjEiLz4KICAgPGNpcmNsZSByPSIxMDAiIGZpbGw9InVybCgjc2hhZG93MikiIHN0cm9rZT0ibm9uZSIvPgo8L3N2Zz4=',
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div
|
||||
ref={this.refContainer}
|
||||
className="x6-graph"
|
||||
style={{
|
||||
backgroundImage: 'linear-gradient(to bottom, #00BFFF , #FFFFFF)',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -12,7 +12,6 @@ export default class Example extends React.Component {
|
||||
container: this.container,
|
||||
width: 650,
|
||||
height: 400,
|
||||
grid: 1,
|
||||
background: {
|
||||
color: '#F2F7FA',
|
||||
},
|
||||
|
@ -0,0 +1,9 @@
|
||||
.full {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.x6-split-box-horizontal > .x6-split-box-resizer,
|
||||
.x6-split-box-vertical > .x6-split-box-resizer {
|
||||
background: #ffe58f;
|
||||
}
|
@ -1,68 +1,45 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Scroller } from '@antv/x6-plugin-scroller'
|
||||
import { SplitBox } from '@antv/x6-react-components'
|
||||
import '@antv/x6-react-components/es/split-box/style/index.css'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private graphContainer1: HTMLDivElement
|
||||
private graphContainer2: HTMLDivElement
|
||||
private graphContainer3: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph1 = new Graph({
|
||||
new Graph({
|
||||
container: this.graphContainer1,
|
||||
background: {
|
||||
color: '#f5f5f5',
|
||||
color: '#D94111',
|
||||
},
|
||||
grid: true,
|
||||
scroller: true,
|
||||
autoResize: true,
|
||||
})
|
||||
|
||||
const rect = graph1.addNode({
|
||||
x: 300,
|
||||
y: 300,
|
||||
width: 90,
|
||||
height: 60,
|
||||
})
|
||||
|
||||
const circle = graph1.addNode({
|
||||
x: 400,
|
||||
y: 400,
|
||||
width: 40,
|
||||
height: 40,
|
||||
})
|
||||
|
||||
graph1.addEdge({
|
||||
source: rect,
|
||||
target: circle,
|
||||
})
|
||||
|
||||
const graph2 = new Graph({
|
||||
new Graph({
|
||||
container: this.graphContainer2,
|
||||
background: {
|
||||
color: '#f5f5f5',
|
||||
color: '#90C54C',
|
||||
},
|
||||
grid: true,
|
||||
autoResize: true,
|
||||
})
|
||||
|
||||
const source = graph2.addNode({
|
||||
x: 40,
|
||||
y: 40,
|
||||
width: 80,
|
||||
height: 40,
|
||||
})
|
||||
|
||||
const target = graph2.addNode({
|
||||
x: 120,
|
||||
y: 100,
|
||||
width: 80,
|
||||
height: 40,
|
||||
})
|
||||
|
||||
graph2.addEdge({
|
||||
source,
|
||||
target,
|
||||
const graph = new Graph({
|
||||
container: this.graphContainer3,
|
||||
background: {
|
||||
color: '#0491E4',
|
||||
},
|
||||
autoResize: true,
|
||||
})
|
||||
graph.use(
|
||||
new Scroller({
|
||||
enabled: true,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
refContainer1 = (container: HTMLDivElement) => {
|
||||
@ -73,23 +50,29 @@ export default class Example extends React.Component {
|
||||
this.graphContainer2 = container
|
||||
}
|
||||
|
||||
refContainer3 = (container: HTMLDivElement) => {
|
||||
this.graphContainer3 = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{ width: '100%', height: '100%' }}>
|
||||
<div className="x6-graph-wrap" style={{ display: 'flex' }}>
|
||||
<div
|
||||
ref={this.refContainer1}
|
||||
style={{ flex: 1, margin: '0 32px' }}
|
||||
className="x6-graph"
|
||||
/>
|
||||
</div>
|
||||
<div className="x6-graph-wrap" style={{ display: 'flex' }}>
|
||||
<div
|
||||
ref={this.refContainer2}
|
||||
style={{ flex: 1, margin: '0 32px' }}
|
||||
className="x6-graph"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="x6-graph-wrap"
|
||||
style={{ width: 800, height: 800, margin: '0 auto' }}
|
||||
>
|
||||
<SplitBox split="horizontal">
|
||||
<div className="full">
|
||||
<div ref={this.refContainer1} className="x6-graph" />
|
||||
</div>
|
||||
<SplitBox split="vertical">
|
||||
<div className="full">
|
||||
<div ref={this.refContainer2} className="x6-graph" />
|
||||
</div>
|
||||
<div className="full">
|
||||
<div ref={this.refContainer3} className="x6-graph" />
|
||||
</div>
|
||||
</SplitBox>
|
||||
</SplitBox>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -9,24 +9,31 @@ export default class Example extends React.Component {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 400,
|
||||
height: 600,
|
||||
grid: true,
|
||||
async: true,
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
x: 120,
|
||||
const source = graph.addNode({
|
||||
shape: 'rect',
|
||||
x: 80,
|
||||
y: 80,
|
||||
width: 100,
|
||||
height: 40,
|
||||
label: 'rect',
|
||||
zIndex: 10,
|
||||
width: 160,
|
||||
height: 60,
|
||||
label: 'source',
|
||||
})
|
||||
|
||||
const target = graph.addNode({
|
||||
shape: 'rect',
|
||||
x: 320,
|
||||
y: 320,
|
||||
width: 160,
|
||||
height: 60,
|
||||
label: 'target',
|
||||
})
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 10, y: 10 },
|
||||
target: { x: 300, y: 200 },
|
||||
zIndex: 1,
|
||||
source,
|
||||
target,
|
||||
})
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import { Graph, Cell } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
Graph.registerNode(
|
||||
'event',
|
||||
'bpmn-event',
|
||||
{
|
||||
inherit: 'circle',
|
||||
attrs: {
|
||||
@ -18,7 +18,7 @@ Graph.registerNode(
|
||||
)
|
||||
|
||||
Graph.registerNode(
|
||||
'activity',
|
||||
'bpmn-activity',
|
||||
{
|
||||
inherit: 'rect',
|
||||
markup: [
|
||||
@ -61,7 +61,7 @@ Graph.registerNode(
|
||||
)
|
||||
|
||||
Graph.registerNode(
|
||||
'gateway',
|
||||
'bpmn-gateway',
|
||||
{
|
||||
inherit: 'polygon',
|
||||
attrs: {
|
||||
@ -98,14 +98,14 @@ Graph.registerEdge(
|
||||
const data = [
|
||||
{
|
||||
id: '1',
|
||||
shape: 'event',
|
||||
shape: 'bpmn-event',
|
||||
width: 40,
|
||||
height: 40,
|
||||
position: { x: 50, y: 180 },
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
shape: 'activity',
|
||||
shape: 'bpmn-activity',
|
||||
width: 100,
|
||||
height: 60,
|
||||
position: { x: 20, y: 280 },
|
||||
@ -119,7 +119,7 @@ const data = [
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
shape: 'gateway',
|
||||
shape: 'bpmn-gateway',
|
||||
width: 55,
|
||||
height: 55,
|
||||
position: { x: 170, y: 282.5 },
|
||||
@ -132,7 +132,7 @@ const data = [
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
shape: 'activity',
|
||||
shape: 'bpmn-activity',
|
||||
width: 100,
|
||||
height: 60,
|
||||
position: { x: 300, y: 240 },
|
||||
@ -140,7 +140,7 @@ const data = [
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
shape: 'activity',
|
||||
shape: 'bpmn-activity',
|
||||
width: 100,
|
||||
height: 60,
|
||||
position: { x: 300, y: 320 },
|
||||
@ -160,7 +160,7 @@ const data = [
|
||||
},
|
||||
{
|
||||
id: '10',
|
||||
shape: 'gateway',
|
||||
shape: 'bpmn-gateway',
|
||||
width: 55,
|
||||
height: 55,
|
||||
position: { x: 460, y: 282.5 },
|
||||
@ -179,7 +179,7 @@ const data = [
|
||||
},
|
||||
{
|
||||
id: '13',
|
||||
shape: 'activity',
|
||||
shape: 'bpmn-activity',
|
||||
width: 100,
|
||||
height: 60,
|
||||
position: { x: 560, y: 280 },
|
||||
@ -193,7 +193,7 @@ const data = [
|
||||
},
|
||||
{
|
||||
id: '15',
|
||||
shape: 'event',
|
||||
shape: 'bpmn-event',
|
||||
width: 40,
|
||||
height: 40,
|
||||
position: { x: 710, y: 290 },
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import { Graph, ObjectExt, Cell } from '@antv/x6'
|
||||
import { Graph, Cell } from '@antv/x6'
|
||||
import { ObjectExt } from '@antv/x6-common'
|
||||
import '../index.less'
|
||||
|
||||
Graph.registerNode(
|
||||
|
@ -1,453 +1,454 @@
|
||||
// import React from 'react'
|
||||
// import { Graph, Node, Path, Cell } from '@antv/x6'
|
||||
// import '@antv/x6-react-shape'
|
||||
// import '../index.less'
|
||||
// import './index.less'
|
||||
// interface NodeStatus {
|
||||
// id: string
|
||||
// status: 'default' | 'success' | 'failed' | 'running'
|
||||
// label?: string
|
||||
// }
|
||||
import React from 'react'
|
||||
import { Graph, Node, Cell } from '@antv/x6'
|
||||
import { Path } from '@antv/x6-geometry'
|
||||
import { register } from '@antv/x6-react-shape'
|
||||
import { Selection } from '@antv/x6-plugin-selection'
|
||||
import { Snapline } from '@antv/x6-plugin-snapline'
|
||||
import '../index.less'
|
||||
import './index.less'
|
||||
interface NodeStatus {
|
||||
id: string
|
||||
status: string
|
||||
label?: string
|
||||
}
|
||||
|
||||
// const image = {
|
||||
// logo: 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*evDjT5vjkX0AAAAAAAAAAAAAARQnAQ',
|
||||
// success:
|
||||
// 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*6l60T6h8TTQAAAAAAAAAAAAAARQnAQ',
|
||||
// failed:
|
||||
// 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*SEISQ6My-HoAAAAAAAAAAAAAARQnAQ',
|
||||
// running:
|
||||
// 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*t8fURKfgSOgAAAAAAAAAAAAAARQnAQ',
|
||||
// }
|
||||
// export class AlgoNode extends React.Component<{ node?: Node }> {
|
||||
// shouldComponentUpdate() {
|
||||
// const { node } = this.props
|
||||
// if (node) {
|
||||
// if (node.hasChanged('data')) {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
const image = {
|
||||
logo: 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*evDjT5vjkX0AAAAAAAAAAAAAARQnAQ',
|
||||
success:
|
||||
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*6l60T6h8TTQAAAAAAAAAAAAAARQnAQ',
|
||||
failed:
|
||||
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*SEISQ6My-HoAAAAAAAAAAAAAARQnAQ',
|
||||
running:
|
||||
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*t8fURKfgSOgAAAAAAAAAAAAAARQnAQ',
|
||||
}
|
||||
export class AlgoNode extends React.Component<{ node?: Node }> {
|
||||
shouldComponentUpdate() {
|
||||
const { node } = this.props
|
||||
if (node) {
|
||||
if (node.hasChanged('data')) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// render() {
|
||||
// const { node } = this.props
|
||||
// const data = node?.getData() as NodeStatus
|
||||
// const { label, status = 'default' } = data
|
||||
render() {
|
||||
const { node } = this.props
|
||||
const data = node?.getData() as NodeStatus
|
||||
const { label, status = 'default' } = data
|
||||
|
||||
// return (
|
||||
// <div className={`node ${status}`}>
|
||||
// <img src={image.logo} alt="logo" />
|
||||
// <span className="label">{label}</span>
|
||||
// <span className="status">
|
||||
// {status === 'success' && <img src={image.success} alt="success" />}
|
||||
// {status === 'failed' && <img src={image.failed} alt="failed" />}
|
||||
// {status === 'running' && <img src={image.running} alt="running" />}
|
||||
// </span>
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
return (
|
||||
<div className={`node ${status}`}>
|
||||
<img src={image.logo} alt="logo" />
|
||||
<span className="label">{label}</span>
|
||||
<span className="status">
|
||||
{status === 'success' && <img src={image.success} alt="success" />}
|
||||
{status === 'failed' && <img src={image.failed} alt="failed" />}
|
||||
{status === 'running' && <img src={image.running} alt="running" />}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Graph.registerNode(
|
||||
// 'dag-node',
|
||||
// {
|
||||
// inherit: 'react-shape',
|
||||
// width: 180,
|
||||
// height: 36,
|
||||
// component: <AlgoNode />,
|
||||
// ports: {
|
||||
// groups: {
|
||||
// top: {
|
||||
// position: 'top',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 4,
|
||||
// magnet: true,
|
||||
// stroke: '#C2C8D5',
|
||||
// strokeWidth: 1,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// bottom: {
|
||||
// position: 'bottom',
|
||||
// attrs: {
|
||||
// circle: {
|
||||
// r: 4,
|
||||
// magnet: true,
|
||||
// stroke: '#C2C8D5',
|
||||
// strokeWidth: 1,
|
||||
// fill: '#fff',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// true,
|
||||
// )
|
||||
register(AlgoNode, {
|
||||
shape: 'dag-node',
|
||||
width: 180,
|
||||
height: 36,
|
||||
ports: {
|
||||
groups: {
|
||||
top: {
|
||||
position: 'top',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 4,
|
||||
magnet: true,
|
||||
stroke: '#C2C8D5',
|
||||
strokeWidth: 1,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
bottom: {
|
||||
position: 'bottom',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 4,
|
||||
magnet: true,
|
||||
stroke: '#C2C8D5',
|
||||
strokeWidth: 1,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Graph.registerEdge(
|
||||
// 'dag-edge',
|
||||
// {
|
||||
// inherit: 'edge',
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#C2C8D5',
|
||||
// strokeWidth: 1,
|
||||
// targetMarker: null,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// true,
|
||||
// )
|
||||
Graph.registerEdge(
|
||||
'dag-edge',
|
||||
{
|
||||
inherit: 'edge',
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#C2C8D5',
|
||||
strokeWidth: 1,
|
||||
targetMarker: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
// Graph.registerConnector(
|
||||
// 'algo-connector',
|
||||
// (s, e) => {
|
||||
// const offset = 4
|
||||
// const deltaY = Math.abs(e.y - s.y)
|
||||
// const control = Math.floor((deltaY / 3) * 2)
|
||||
Graph.registerConnector(
|
||||
'algo-connector',
|
||||
(s, e) => {
|
||||
const offset = 4
|
||||
const deltaY = Math.abs(e.y - s.y)
|
||||
const control = Math.floor((deltaY / 3) * 2)
|
||||
|
||||
// const v1 = { x: s.x, y: s.y + offset + control }
|
||||
// const v2 = { x: e.x, y: e.y - offset - control }
|
||||
const v1 = { x: s.x, y: s.y + offset + control }
|
||||
const v2 = { x: e.x, y: e.y - offset - control }
|
||||
|
||||
// return Path.normalize(
|
||||
// `M ${s.x} ${s.y}
|
||||
// L ${s.x} ${s.y + offset}
|
||||
// C ${v1.x} ${v1.y} ${v2.x} ${v2.y} ${e.x} ${e.y - offset}
|
||||
// L ${e.x} ${e.y}
|
||||
// `,
|
||||
// )
|
||||
// },
|
||||
// true,
|
||||
// )
|
||||
return Path.normalize(
|
||||
`M ${s.x} ${s.y}
|
||||
L ${s.x} ${s.y + offset}
|
||||
C ${v1.x} ${v1.y} ${v2.x} ${v2.y} ${e.x} ${e.y - offset}
|
||||
L ${e.x} ${e.y}
|
||||
`,
|
||||
)
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
// const data = [
|
||||
// {
|
||||
// id: '1',
|
||||
// shape: 'dag-node',
|
||||
// x: 290,
|
||||
// y: 110,
|
||||
// data: {
|
||||
// label: '读数据',
|
||||
// status: 'success',
|
||||
// },
|
||||
// ports: [
|
||||
// {
|
||||
// id: '1-1',
|
||||
// group: 'bottom',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// shape: 'dag-node',
|
||||
// x: 290,
|
||||
// y: 225,
|
||||
// data: {
|
||||
// label: '读数据',
|
||||
// status: 'success',
|
||||
// },
|
||||
// ports: [
|
||||
// {
|
||||
// id: '2-1',
|
||||
// group: 'top',
|
||||
// },
|
||||
// {
|
||||
// id: '2-2',
|
||||
// group: 'bottom',
|
||||
// },
|
||||
// {
|
||||
// id: '2-3',
|
||||
// group: 'bottom',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// shape: 'dag-node',
|
||||
// x: 170,
|
||||
// y: 350,
|
||||
// data: {
|
||||
// label: '读数据',
|
||||
// status: 'success',
|
||||
// },
|
||||
// ports: [
|
||||
// {
|
||||
// id: '3-1',
|
||||
// group: 'top',
|
||||
// },
|
||||
// {
|
||||
// id: '3-2',
|
||||
// group: 'bottom',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// shape: 'dag-node',
|
||||
// x: 450,
|
||||
// y: 350,
|
||||
// data: {
|
||||
// label: '读数据',
|
||||
// status: 'success',
|
||||
// },
|
||||
// ports: [
|
||||
// {
|
||||
// id: '4-1',
|
||||
// group: 'top',
|
||||
// },
|
||||
// {
|
||||
// id: '4-2',
|
||||
// group: 'bottom',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// id: '5',
|
||||
// shape: 'dag-edge',
|
||||
// source: {
|
||||
// cell: '1',
|
||||
// port: '1-1',
|
||||
// },
|
||||
// target: {
|
||||
// cell: '2',
|
||||
// port: '2-1',
|
||||
// },
|
||||
// zIndex: 0,
|
||||
// },
|
||||
// {
|
||||
// id: '6',
|
||||
// shape: 'dag-edge',
|
||||
// source: {
|
||||
// cell: '2',
|
||||
// port: '2-2',
|
||||
// },
|
||||
// target: {
|
||||
// cell: '3',
|
||||
// port: '3-1',
|
||||
// },
|
||||
// zIndex: 0,
|
||||
// },
|
||||
// {
|
||||
// id: '7',
|
||||
// shape: 'dag-edge',
|
||||
// source: {
|
||||
// cell: '2',
|
||||
// port: '2-3',
|
||||
// },
|
||||
// target: {
|
||||
// cell: '4',
|
||||
// port: '4-1',
|
||||
// },
|
||||
// zIndex: 0,
|
||||
// },
|
||||
// ]
|
||||
const data = [
|
||||
{
|
||||
id: '1',
|
||||
shape: 'dag-node',
|
||||
x: 290,
|
||||
y: 110,
|
||||
data: {
|
||||
label: '读数据',
|
||||
status: 'success',
|
||||
},
|
||||
ports: [
|
||||
{
|
||||
id: '1-1',
|
||||
group: 'bottom',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
shape: 'dag-node',
|
||||
x: 290,
|
||||
y: 225,
|
||||
data: {
|
||||
label: '读数据',
|
||||
status: 'success',
|
||||
},
|
||||
ports: [
|
||||
{
|
||||
id: '2-1',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: '2-2',
|
||||
group: 'bottom',
|
||||
},
|
||||
{
|
||||
id: '2-3',
|
||||
group: 'bottom',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
shape: 'dag-node',
|
||||
x: 170,
|
||||
y: 350,
|
||||
data: {
|
||||
label: '读数据',
|
||||
status: 'success',
|
||||
},
|
||||
ports: [
|
||||
{
|
||||
id: '3-1',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: '3-2',
|
||||
group: 'bottom',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
shape: 'dag-node',
|
||||
x: 450,
|
||||
y: 350,
|
||||
data: {
|
||||
label: '读数据',
|
||||
status: 'success',
|
||||
},
|
||||
ports: [
|
||||
{
|
||||
id: '4-1',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: '4-2',
|
||||
group: 'bottom',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
shape: 'dag-edge',
|
||||
source: {
|
||||
cell: '1',
|
||||
port: '1-1',
|
||||
},
|
||||
target: {
|
||||
cell: '2',
|
||||
port: '2-1',
|
||||
},
|
||||
zIndex: 0,
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
shape: 'dag-edge',
|
||||
source: {
|
||||
cell: '2',
|
||||
port: '2-2',
|
||||
},
|
||||
target: {
|
||||
cell: '3',
|
||||
port: '3-1',
|
||||
},
|
||||
zIndex: 0,
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
shape: 'dag-edge',
|
||||
source: {
|
||||
cell: '2',
|
||||
port: '2-3',
|
||||
},
|
||||
target: {
|
||||
cell: '4',
|
||||
port: '4-1',
|
||||
},
|
||||
zIndex: 0,
|
||||
},
|
||||
]
|
||||
|
||||
// const nodeStatusList = [
|
||||
// [
|
||||
// {
|
||||
// id: '1',
|
||||
// status: 'running',
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// status: 'default',
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// status: 'default',
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// status: 'default',
|
||||
// },
|
||||
// ],
|
||||
// [
|
||||
// {
|
||||
// id: '1',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// status: 'running',
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// status: 'default',
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// status: 'default',
|
||||
// },
|
||||
// ],
|
||||
// [
|
||||
// {
|
||||
// id: '1',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// status: 'running',
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// status: 'running',
|
||||
// },
|
||||
// ],
|
||||
// [
|
||||
// {
|
||||
// id: '1',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '2',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '3',
|
||||
// status: 'success',
|
||||
// },
|
||||
// {
|
||||
// id: '4',
|
||||
// status: 'failed',
|
||||
// },
|
||||
// ],
|
||||
// ]
|
||||
// export default class Example extends React.Component {
|
||||
// private container: HTMLDivElement
|
||||
const nodeStatusList = [
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
status: 'running',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
status: 'default',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
status: 'default',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
status: 'default',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
status: 'running',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
status: 'default',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
status: 'default',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
status: 'running',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
status: 'running',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: '1',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
status: 'success',
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
status: 'failed',
|
||||
},
|
||||
],
|
||||
]
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
// componentDidMount() {
|
||||
// const graph: Graph = new Graph({
|
||||
// container: this.container,
|
||||
// width: 800,
|
||||
// height: 600,
|
||||
// panning: {
|
||||
// enabled: true,
|
||||
// eventTypes: ['leftMouseDown', 'mouseWheel'],
|
||||
// },
|
||||
// mousewheel: {
|
||||
// enabled: true,
|
||||
// modifiers: 'ctrl',
|
||||
// factor: 1.1,
|
||||
// maxScale: 1.5,
|
||||
// minScale: 0.5,
|
||||
// },
|
||||
// highlighting: {
|
||||
// magnetAdsorbed: {
|
||||
// name: 'stroke',
|
||||
// args: {
|
||||
// attrs: {
|
||||
// fill: '#fff',
|
||||
// stroke: '#31d0c6',
|
||||
// strokeWidth: 4,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// connecting: {
|
||||
// snap: true,
|
||||
// allowBlank: false,
|
||||
// allowLoop: false,
|
||||
// highlight: true,
|
||||
// connector: 'algo-connector',
|
||||
// connectionPoint: 'anchor',
|
||||
// anchor: 'center',
|
||||
// validateMagnet({ magnet }) {
|
||||
// return magnet.getAttribute('port-group') !== 'top'
|
||||
// },
|
||||
// createEdge() {
|
||||
// return graph.createEdge({
|
||||
// shape: 'dag-edge',
|
||||
// attrs: {
|
||||
// line: {
|
||||
// strokeDasharray: '5 5',
|
||||
// },
|
||||
// },
|
||||
// zIndex: -1,
|
||||
// })
|
||||
// },
|
||||
// },
|
||||
// selecting: {
|
||||
// enabled: true,
|
||||
// multiple: true,
|
||||
// rubberEdge: true,
|
||||
// rubberNode: true,
|
||||
// modifiers: 'shift',
|
||||
// rubberband: true,
|
||||
// },
|
||||
// })
|
||||
componentDidMount() {
|
||||
const graph: Graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
panning: {
|
||||
enabled: true,
|
||||
eventTypes: ['leftMouseDown', 'mouseWheel'],
|
||||
},
|
||||
mousewheel: {
|
||||
enabled: true,
|
||||
modifiers: 'ctrl',
|
||||
factor: 1.1,
|
||||
maxScale: 1.5,
|
||||
minScale: 0.5,
|
||||
},
|
||||
highlighting: {
|
||||
magnetAdsorbed: {
|
||||
name: 'stroke',
|
||||
args: {
|
||||
attrs: {
|
||||
fill: '#fff',
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
connecting: {
|
||||
snap: true,
|
||||
allowBlank: false,
|
||||
allowLoop: false,
|
||||
highlight: true,
|
||||
connector: 'algo-connector',
|
||||
connectionPoint: 'anchor',
|
||||
anchor: 'center',
|
||||
validateMagnet({ magnet }) {
|
||||
return magnet.getAttribute('port-group') !== 'top'
|
||||
},
|
||||
createEdge() {
|
||||
return graph.createEdge({
|
||||
shape: 'dag-edge',
|
||||
attrs: {
|
||||
line: {
|
||||
strokeDasharray: '5 5',
|
||||
},
|
||||
},
|
||||
zIndex: -1,
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// graph.on('edge:connected', ({ edge }) => {
|
||||
// edge.attr({
|
||||
// line: {
|
||||
// strokeDasharray: '',
|
||||
// },
|
||||
// })
|
||||
// })
|
||||
const selection = new Selection({
|
||||
enabled: true,
|
||||
multiple: true,
|
||||
rubberEdge: true,
|
||||
rubberNode: true,
|
||||
modifiers: 'shift',
|
||||
rubberband: true,
|
||||
})
|
||||
graph.use(selection)
|
||||
graph.use(new Snapline({ enabled: true }))
|
||||
|
||||
// graph.on('node:change:data', ({ node }) => {
|
||||
// const edges = graph.getIncomingEdges(node)
|
||||
// const { status } = node.getData() as NodeStatus
|
||||
// edges?.forEach((edge) => {
|
||||
// if (status === 'running') {
|
||||
// edge.attr('line/strokeDasharray', 5)
|
||||
// edge.attr('line/style/animation', 'running-line 30s infinite linear')
|
||||
// } else {
|
||||
// edge.attr('line/strokeDasharray', '')
|
||||
// edge.attr('line/style/animation', '')
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
graph.on('edge:connected', ({ edge }) => {
|
||||
edge.attr({
|
||||
line: {
|
||||
strokeDasharray: '',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
// // 初始化节点/边
|
||||
// const init = (data: Cell.Metadata[]) => {
|
||||
// const cells: Cell[] = []
|
||||
// data.forEach((item) => {
|
||||
// if (item.shape === 'dag-node') {
|
||||
// cells.push(graph.createNode(item))
|
||||
// } else {
|
||||
// cells.push(graph.createEdge(item))
|
||||
// }
|
||||
// })
|
||||
// graph.resetCells(cells)
|
||||
// }
|
||||
graph.on('node:change:data', ({ node }) => {
|
||||
const edges = graph.getIncomingEdges(node)
|
||||
const { status } = node.getData() as NodeStatus
|
||||
edges?.forEach((edge) => {
|
||||
if (status === 'running') {
|
||||
edge.attr('line/strokeDasharray', 5)
|
||||
edge.attr('line/style/animation', 'running-line 30s infinite linear')
|
||||
} else {
|
||||
edge.attr('line/strokeDasharray', '')
|
||||
edge.attr('line/style/animation', '')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// // 显示节点状态
|
||||
// const showNodeStatus = async (statusList: NodeStatus[][]) => {
|
||||
// const status = statusList.shift()
|
||||
// status?.forEach((item) => {
|
||||
// const { id, status } = item
|
||||
// const node = graph.getCellById(id)
|
||||
// const data = node.getData() as NodeStatus
|
||||
// node.setData({
|
||||
// ...data,
|
||||
// status: status,
|
||||
// })
|
||||
// })
|
||||
// setTimeout(() => {
|
||||
// showNodeStatus(statusList)
|
||||
// }, 3000)
|
||||
// }
|
||||
// 初始化节点/边
|
||||
const init = (data: Cell.Metadata[]) => {
|
||||
const cells: Cell[] = []
|
||||
data.forEach((item) => {
|
||||
if (item.shape === 'dag-node') {
|
||||
cells.push(graph.createNode(item))
|
||||
} else {
|
||||
cells.push(graph.createEdge(item))
|
||||
}
|
||||
})
|
||||
graph.resetCells(cells)
|
||||
}
|
||||
|
||||
// init(data)
|
||||
// showNodeStatus(nodeStatusList)
|
||||
// }
|
||||
// 显示节点状态
|
||||
const showNodeStatus = async (statusList: NodeStatus[][]) => {
|
||||
const status = statusList.shift()
|
||||
status?.forEach((item) => {
|
||||
const { id, status } = item
|
||||
const node = graph.getCellById(id)
|
||||
const data = node.getData() as NodeStatus
|
||||
node.setData({
|
||||
...data,
|
||||
status: status,
|
||||
})
|
||||
})
|
||||
setTimeout(() => {
|
||||
showNodeStatus(statusList)
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
// refContainer = (container: HTMLDivElement) => {
|
||||
// this.container = container
|
||||
// }
|
||||
init(data)
|
||||
showNodeStatus(nodeStatusList)
|
||||
}
|
||||
|
||||
// render() {
|
||||
// return (
|
||||
// <div className="x6-graph-wrap">
|
||||
// <div ref={this.refContainer} className="dag" />
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="dag" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ import React from 'react'
|
||||
import { Graph, Cell, Node } from '@antv/x6'
|
||||
import { connectors } from '../connector/xmind-definitions'
|
||||
import Hierarchy from '@antv/hierarchy'
|
||||
import { Selection } from '@antv/x6-plugin-selection'
|
||||
import { Keyboard } from '@antv/x6-plugin-keyboard'
|
||||
import '../index.less'
|
||||
import './mind.less'
|
||||
|
||||
@ -181,13 +183,15 @@ export default class Example extends React.Component {
|
||||
connecting: {
|
||||
connectionPoint: 'anchor',
|
||||
},
|
||||
selecting: {
|
||||
enabled: true,
|
||||
},
|
||||
keyboard: {
|
||||
enabled: true,
|
||||
},
|
||||
})
|
||||
const selection = new Selection({
|
||||
enabled: true,
|
||||
})
|
||||
graph.use(selection)
|
||||
const keyboard = new Keyboard({
|
||||
enabled: true,
|
||||
})
|
||||
graph.use(keyboard)
|
||||
|
||||
const render = () => {
|
||||
const result: HierarchyResult = Hierarchy.mindmap(data, {
|
||||
@ -346,8 +350,8 @@ export default class Example extends React.Component {
|
||||
render()
|
||||
}
|
||||
})
|
||||
graph.bindKey(['backspace', 'delete'], () => {
|
||||
const selectedNodes = graph
|
||||
keyboard.bindKey(['backspace', 'delete'], () => {
|
||||
const selectedNodes = selection
|
||||
.getSelectedCells()
|
||||
.filter((item) => item.isNode())
|
||||
if (selectedNodes.length) {
|
||||
@ -358,9 +362,9 @@ export default class Example extends React.Component {
|
||||
}
|
||||
})
|
||||
|
||||
graph.bindKey('tab', (e) => {
|
||||
keyboard.bindKey('tab', (e) => {
|
||||
e.preventDefault()
|
||||
const selectedNodes = graph
|
||||
const selectedNodes = selection
|
||||
.getSelectedCells()
|
||||
.filter((item) => item.isNode())
|
||||
if (selectedNodes.length) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Graph, Path, Point } from '@antv/x6'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Path, Point } from '@antv/x6-geometry'
|
||||
import { Connector } from '@antv/x6/lib/registry'
|
||||
|
||||
export const connectors = {
|
||||
|
@ -1,468 +1,468 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Marker } from '@antv/x6/es/registry'
|
||||
import '../index.less'
|
||||
// import React from 'react'
|
||||
// import { Graph } from '@antv/x6'
|
||||
// import { Marker } from '@antv/x6/es/registry'
|
||||
// import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
// export default class Example extends React.Component {
|
||||
// private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
interacting: { edgeMovable: false },
|
||||
connecting: {
|
||||
connectionPoint: {
|
||||
name: 'boundary',
|
||||
args: {
|
||||
extrapolate: true,
|
||||
sticky: true,
|
||||
},
|
||||
},
|
||||
validateConnection: function () {
|
||||
return false
|
||||
},
|
||||
},
|
||||
})
|
||||
// componentDidMount() {
|
||||
// const graph = new Graph({
|
||||
// container: this.container,
|
||||
// width: 800,
|
||||
// height: 600,
|
||||
// interacting: { edgeMovable: false },
|
||||
// connecting: {
|
||||
// connectionPoint: {
|
||||
// name: 'boundary',
|
||||
// args: {
|
||||
// extrapolate: true,
|
||||
// sticky: true,
|
||||
// },
|
||||
// },
|
||||
// validateConnection: function () {
|
||||
// return false
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 20, y: 20 },
|
||||
target: { x: 350, y: 20 },
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#222138',
|
||||
sourceMarker: {
|
||||
name: 'classic',
|
||||
fill: '#31d0c6',
|
||||
stroke: 'none',
|
||||
size: 20,
|
||||
},
|
||||
targetMarker: {
|
||||
name: 'block',
|
||||
fill: '#fe854f',
|
||||
stroke: 'none',
|
||||
size: 20,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 20, y: 20 },
|
||||
// target: { x: 350, y: 20 },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#222138',
|
||||
// sourceMarker: {
|
||||
// name: 'classic',
|
||||
// fill: '#31d0c6',
|
||||
// stroke: 'none',
|
||||
// size: 20,
|
||||
// },
|
||||
// targetMarker: {
|
||||
// name: 'block',
|
||||
// fill: '#fe854f',
|
||||
// stroke: 'none',
|
||||
// size: 20,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 20, y: 80 },
|
||||
target: { x: 350, y: 80 },
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#fe854f',
|
||||
strokeWidth: 1,
|
||||
sourceMarker: 'block',
|
||||
targetMarker: {
|
||||
tagName: 'circle',
|
||||
r: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 20, y: 80 },
|
||||
// target: { x: 350, y: 80 },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#fe854f',
|
||||
// strokeWidth: 1,
|
||||
// sourceMarker: 'block',
|
||||
// targetMarker: {
|
||||
// tagName: 'circle',
|
||||
// r: 5,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 20, y: 400 },
|
||||
target: { x: 280, y: 400 },
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#fe854f',
|
||||
strokeWidth: 1,
|
||||
sourceMarker: 'block',
|
||||
targetMarker: {
|
||||
name: 'block',
|
||||
width: 12,
|
||||
height: 6,
|
||||
open: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 20, y: 400 },
|
||||
// target: { x: 280, y: 400 },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#fe854f',
|
||||
// strokeWidth: 1,
|
||||
// sourceMarker: 'block',
|
||||
// targetMarker: {
|
||||
// name: 'block',
|
||||
// width: 12,
|
||||
// height: 6,
|
||||
// open: true,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 20, y: 430 },
|
||||
target: { x: 280, y: 430 },
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#fe854f',
|
||||
strokeWidth: 1,
|
||||
sourceMarker: 'diamond',
|
||||
targetMarker: {
|
||||
name: 'diamond',
|
||||
width: 12,
|
||||
height: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 20, y: 430 },
|
||||
// target: { x: 280, y: 430 },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#fe854f',
|
||||
// strokeWidth: 1,
|
||||
// sourceMarker: 'diamond',
|
||||
// targetMarker: {
|
||||
// name: 'diamond',
|
||||
// width: 12,
|
||||
// height: 6,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 20, y: 460 },
|
||||
target: { x: 280, y: 460 },
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#fe854f',
|
||||
strokeWidth: 1,
|
||||
sourceMarker: 'ellipse',
|
||||
targetMarker: {
|
||||
name: 'ellipse',
|
||||
rx: 6,
|
||||
ry: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 20, y: 460 },
|
||||
// target: { x: 280, y: 460 },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#fe854f',
|
||||
// strokeWidth: 1,
|
||||
// sourceMarker: 'ellipse',
|
||||
// targetMarker: {
|
||||
// name: 'ellipse',
|
||||
// rx: 6,
|
||||
// ry: 4,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 20, y: 490 },
|
||||
target: { x: 280, y: 490 },
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#fe854f',
|
||||
strokeWidth: 1,
|
||||
sourceMarker: 'circle',
|
||||
targetMarker: {
|
||||
name: 'circlePlus',
|
||||
r: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 20, y: 490 },
|
||||
// target: { x: 280, y: 490 },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#fe854f',
|
||||
// strokeWidth: 1,
|
||||
// sourceMarker: 'circle',
|
||||
// targetMarker: {
|
||||
// name: 'circlePlus',
|
||||
// r: 10,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 20, y: 520 },
|
||||
target: { x: 280, y: 520 },
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#fe854f',
|
||||
strokeWidth: 1,
|
||||
sourceMarker: 'cross',
|
||||
targetMarker: {
|
||||
name: 'cross',
|
||||
width: 12,
|
||||
height: 8,
|
||||
offset: -10,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 20, y: 520 },
|
||||
// target: { x: 280, y: 520 },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#fe854f',
|
||||
// strokeWidth: 1,
|
||||
// sourceMarker: 'cross',
|
||||
// targetMarker: {
|
||||
// name: 'cross',
|
||||
// width: 12,
|
||||
// height: 8,
|
||||
// offset: -10,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 20, y: 550 },
|
||||
target: { x: 280, y: 550 },
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#fe854f',
|
||||
strokeWidth: 1,
|
||||
sourceMarker: 'async',
|
||||
targetMarker: {
|
||||
name: 'async',
|
||||
width: 12,
|
||||
height: 8,
|
||||
offset: -10,
|
||||
open: true,
|
||||
flip: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 20, y: 550 },
|
||||
// target: { x: 280, y: 550 },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#fe854f',
|
||||
// strokeWidth: 1,
|
||||
// sourceMarker: 'async',
|
||||
// targetMarker: {
|
||||
// name: 'async',
|
||||
// width: 12,
|
||||
// height: 8,
|
||||
// offset: -10,
|
||||
// open: true,
|
||||
// flip: true,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 10, y: 140 },
|
||||
target: { x: 350, y: 140 },
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 3,
|
||||
strokeDasharray: '5 2',
|
||||
sourceMarker: {
|
||||
stroke: '#31d0c6',
|
||||
fill: '#31d0c6',
|
||||
d: Marker.normalize(
|
||||
'M5.5,15.499,15.8,21.447,15.8,15.846,25.5,21.447,25.5,9.552,15.8,15.152,15.8,9.552z',
|
||||
),
|
||||
},
|
||||
targetMarker: {
|
||||
stroke: '#31d0c6',
|
||||
fill: '#31d0c6',
|
||||
name: 'path',
|
||||
d: 'M4.834,4.834L4.833,4.833c-5.889,5.892-5.89,15.443,0.001,21.334s15.44,5.888,21.33-0.002c5.891-5.891,5.893-15.44,0.002-21.33C20.275-1.056,10.725-1.056,4.834,4.834zM25.459,5.542c0.833,0.836,1.523,1.757,2.104,2.726l-4.08,4.08c-0.418-1.062-1.053-2.06-1.912-2.918c-0.859-0.859-1.857-1.494-2.92-1.913l4.08-4.08C23.7,4.018,24.622,4.709,25.459,5.542zM10.139,20.862c-2.958-2.968-2.959-7.758-0.001-10.725c2.966-2.957,7.756-2.957,10.725,0c2.954,2.965,2.955,7.757-0.001,10.724C17.896,23.819,13.104,23.817,10.139,20.862zM5.542,25.459c-0.833-0.837-1.524-1.759-2.105-2.728l4.081-4.081c0.418,1.063,1.055,2.06,1.914,2.919c0.858,0.859,1.855,1.494,2.917,1.913l-4.081,4.081C7.299,26.982,6.379,26.292,5.542,25.459zM8.268,3.435l4.082,4.082C11.288,7.935,10.29,8.571,9.43,9.43c-0.858,0.859-1.494,1.855-1.912,2.918L3.436,8.267c0.58-0.969,1.271-1.89,2.105-2.727C6.377,4.707,7.299,4.016,8.268,3.435zM22.732,27.563l-4.082-4.082c1.062-0.418,2.061-1.053,2.919-1.912c0.859-0.859,1.495-1.857,1.913-2.92l4.082,4.082c-0.58,0.969-1.271,1.891-2.105,2.728C24.623,26.292,23.701,26.983,22.732,27.563z',
|
||||
offsetX: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 10, y: 140 },
|
||||
// target: { x: 350, y: 140 },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#31d0c6',
|
||||
// strokeWidth: 3,
|
||||
// strokeDasharray: '5 2',
|
||||
// sourceMarker: {
|
||||
// stroke: '#31d0c6',
|
||||
// fill: '#31d0c6',
|
||||
// d: Marker.normalize(
|
||||
// 'M5.5,15.499,15.8,21.447,15.8,15.846,25.5,21.447,25.5,9.552,15.8,15.152,15.8,9.552z',
|
||||
// ),
|
||||
// },
|
||||
// targetMarker: {
|
||||
// stroke: '#31d0c6',
|
||||
// fill: '#31d0c6',
|
||||
// name: 'path',
|
||||
// d: 'M4.834,4.834L4.833,4.833c-5.889,5.892-5.89,15.443,0.001,21.334s15.44,5.888,21.33-0.002c5.891-5.891,5.893-15.44,0.002-21.33C20.275-1.056,10.725-1.056,4.834,4.834zM25.459,5.542c0.833,0.836,1.523,1.757,2.104,2.726l-4.08,4.08c-0.418-1.062-1.053-2.06-1.912-2.918c-0.859-0.859-1.857-1.494-2.92-1.913l4.08-4.08C23.7,4.018,24.622,4.709,25.459,5.542zM10.139,20.862c-2.958-2.968-2.959-7.758-0.001-10.725c2.966-2.957,7.756-2.957,10.725,0c2.954,2.965,2.955,7.757-0.001,10.724C17.896,23.819,13.104,23.817,10.139,20.862zM5.542,25.459c-0.833-0.837-1.524-1.759-2.105-2.728l4.081-4.081c0.418,1.063,1.055,2.06,1.914,2.919c0.858,0.859,1.855,1.494,2.917,1.913l-4.081,4.081C7.299,26.982,6.379,26.292,5.542,25.459zM8.268,3.435l4.082,4.082C11.288,7.935,10.29,8.571,9.43,9.43c-0.858,0.859-1.494,1.855-1.912,2.918L3.436,8.267c0.58-0.969,1.271-1.89,2.105-2.727C6.377,4.707,7.299,4.016,8.268,3.435zM22.732,27.563l-4.082-4.082c1.062-0.418,2.061-1.053,2.919-1.912c0.859-0.859,1.495-1.857,1.913-2.92l4.082,4.082c-0.58,0.969-1.271,1.891-2.105,2.728C24.623,26.292,23.701,26.983,22.732,27.563z',
|
||||
// offsetX: 10,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 400, y: 20 },
|
||||
target: { x: 740, y: 20 },
|
||||
vertices: [
|
||||
{ x: 400, y: 60 },
|
||||
{ x: 550, y: 60 },
|
||||
{ x: 550, y: 20 },
|
||||
],
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#3c4260',
|
||||
strokeWidth: 2,
|
||||
sourceMarker: {
|
||||
fill: '#4b4a67',
|
||||
stroke: '#4b4a67',
|
||||
d: Marker.normalize(
|
||||
'M5.5,15.499,15.8,21.447,15.8,15.846,25.5,21.447,25.5,9.552,15.8,15.152,15.8,9.552z',
|
||||
),
|
||||
},
|
||||
targetMarker: {
|
||||
fill: '#4b4a67',
|
||||
stroke: '#4b4a67',
|
||||
d: Marker.normalize(
|
||||
'M5.5,15.499,15.8,21.447,15.8,15.846,25.5,21.447,25.5,9.552,15.8,15.152,15.8,9.552z',
|
||||
),
|
||||
},
|
||||
vertexMarker: {
|
||||
tagName: 'circle',
|
||||
r: 4,
|
||||
strokeWidth: 2,
|
||||
fill: 'white',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 400, y: 20 },
|
||||
// target: { x: 740, y: 20 },
|
||||
// vertices: [
|
||||
// { x: 400, y: 60 },
|
||||
// { x: 550, y: 60 },
|
||||
// { x: 550, y: 20 },
|
||||
// ],
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#3c4260',
|
||||
// strokeWidth: 2,
|
||||
// sourceMarker: {
|
||||
// fill: '#4b4a67',
|
||||
// stroke: '#4b4a67',
|
||||
// d: Marker.normalize(
|
||||
// 'M5.5,15.499,15.8,21.447,15.8,15.846,25.5,21.447,25.5,9.552,15.8,15.152,15.8,9.552z',
|
||||
// ),
|
||||
// },
|
||||
// targetMarker: {
|
||||
// fill: '#4b4a67',
|
||||
// stroke: '#4b4a67',
|
||||
// d: Marker.normalize(
|
||||
// 'M5.5,15.499,15.8,21.447,15.8,15.846,25.5,21.447,25.5,9.552,15.8,15.152,15.8,9.552z',
|
||||
// ),
|
||||
// },
|
||||
// vertexMarker: {
|
||||
// tagName: 'circle',
|
||||
// r: 4,
|
||||
// strokeWidth: 2,
|
||||
// fill: 'white',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 440, y: 100 },
|
||||
target: { x: 740, y: 100 },
|
||||
vertices: [
|
||||
{ x: 400, y: 140 },
|
||||
{ x: 550, y: 100 },
|
||||
{ x: 600, y: 140 },
|
||||
],
|
||||
smooth: true,
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#7c68fc',
|
||||
strokeWidth: 3,
|
||||
sourceMarker: {
|
||||
stroke: '#7c68fc',
|
||||
fill: '#7c68fc',
|
||||
d: Marker.normalize(
|
||||
'M24.316,5.318,9.833,13.682,9.833,5.5,5.5,5.5,5.5,25.5,9.833,25.5,9.833,17.318,24.316,25.682z',
|
||||
),
|
||||
},
|
||||
targetMarker: {
|
||||
stroke: '#feb663',
|
||||
fill: '#feb663',
|
||||
d: Marker.normalize(
|
||||
'M14.615,4.928c0.487-0.986,1.284-0.986,1.771,0l2.249,4.554c0.486,0.986,1.775,1.923,2.864,2.081l5.024,0.73c1.089,0.158,1.335,0.916,0.547,1.684l-3.636,3.544c-0.788,0.769-1.28,2.283-1.095,3.368l0.859,5.004c0.186,1.085-0.459,1.553-1.433,1.041l-4.495-2.363c-0.974-0.512-2.567-0.512-3.541,0l-4.495,2.363c-0.974,0.512-1.618,0.044-1.432-1.041l0.858-5.004c0.186-1.085-0.307-2.6-1.094-3.368L3.93,13.977c-0.788-0.768-0.542-1.525,0.547-1.684l5.026-0.73c1.088-0.158,2.377-1.095,2.864-2.081L14.615,4.928z',
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 440, y: 100 },
|
||||
// target: { x: 740, y: 100 },
|
||||
// vertices: [
|
||||
// { x: 400, y: 140 },
|
||||
// { x: 550, y: 100 },
|
||||
// { x: 600, y: 140 },
|
||||
// ],
|
||||
// smooth: true,
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#7c68fc',
|
||||
// strokeWidth: 3,
|
||||
// sourceMarker: {
|
||||
// stroke: '#7c68fc',
|
||||
// fill: '#7c68fc',
|
||||
// d: Marker.normalize(
|
||||
// 'M24.316,5.318,9.833,13.682,9.833,5.5,5.5,5.5,5.5,25.5,9.833,25.5,9.833,17.318,24.316,25.682z',
|
||||
// ),
|
||||
// },
|
||||
// targetMarker: {
|
||||
// stroke: '#feb663',
|
||||
// fill: '#feb663',
|
||||
// d: Marker.normalize(
|
||||
// 'M14.615,4.928c0.487-0.986,1.284-0.986,1.771,0l2.249,4.554c0.486,0.986,1.775,1.923,2.864,2.081l5.024,0.73c1.089,0.158,1.335,0.916,0.547,1.684l-3.636,3.544c-0.788,0.769-1.28,2.283-1.095,3.368l0.859,5.004c0.186,1.085-0.459,1.553-1.433,1.041l-4.495-2.363c-0.974-0.512-2.567-0.512-3.541,0l-4.495,2.363c-0.974,0.512-1.618,0.044-1.432-1.041l0.858-5.004c0.186-1.085-0.307-2.6-1.094-3.368L3.93,13.977c-0.788-0.768-0.542-1.525,0.547-1.684l5.026-0.73c1.088-0.158,2.377-1.095,2.864-2.081L14.615,4.928z',
|
||||
// ),
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
shape: 'double-edge',
|
||||
source: { x: 10, y: 200 },
|
||||
target: { x: 350, y: 200 },
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#7c68fc',
|
||||
},
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
attrs: { text: { text: 'Label' } },
|
||||
position: {
|
||||
offset: 15,
|
||||
distance: 0.5,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
// graph.addEdge({
|
||||
// shape: 'double-edge',
|
||||
// source: { x: 10, y: 200 },
|
||||
// target: { x: 350, y: 200 },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#7c68fc',
|
||||
// },
|
||||
// },
|
||||
// labels: [
|
||||
// {
|
||||
// attrs: { text: { text: 'Label' } },
|
||||
// position: {
|
||||
// offset: 15,
|
||||
// distance: 0.5,
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 400, y: 200 },
|
||||
target: { x: 740, y: 200 },
|
||||
connector: { name: 'smooth' },
|
||||
attrs: {
|
||||
line: {
|
||||
targetMarker: {
|
||||
d: 'M 0 -5 L -10 0 L 0 5 Z',
|
||||
},
|
||||
},
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
markup: [
|
||||
{
|
||||
tagName: 'rect',
|
||||
selector: 'labelBody',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'labelText',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
labelText: {
|
||||
text: 'First',
|
||||
fill: '#7c68fc',
|
||||
fontFamily: 'sans-serif',
|
||||
textAnchor: 'middle',
|
||||
textVerticalAnchor: 'middle',
|
||||
},
|
||||
labelBody: {
|
||||
ref: 'labelText',
|
||||
refX: -5,
|
||||
refY: -5,
|
||||
refWidth: '100%',
|
||||
refHeight: '100%',
|
||||
refWidth2: 10,
|
||||
refHeight2: 10,
|
||||
stroke: '#7c68fc',
|
||||
fill: 'white',
|
||||
strokeWidth: 2,
|
||||
rx: 5,
|
||||
ry: 5,
|
||||
},
|
||||
},
|
||||
position: {
|
||||
distance: 0.3,
|
||||
options: {
|
||||
keepGradient: true,
|
||||
ensureLegibility: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
markup: [
|
||||
{
|
||||
tagName: 'ellipse',
|
||||
selector: 'labelBody',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'labelText',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
labelText: {
|
||||
text: 'Second',
|
||||
fill: '#31d0c6',
|
||||
fontFamily: 'sans-serif',
|
||||
textAnchor: 'middle',
|
||||
textVerticalAnchor: 'middle',
|
||||
},
|
||||
labelBody: {
|
||||
ref: 'labelText',
|
||||
refRx: '70%',
|
||||
refRy: '80%',
|
||||
stroke: '#31d0c6',
|
||||
fill: 'white',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
},
|
||||
position: {
|
||||
distance: 0.7,
|
||||
angle: 45,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
// graph.addEdge({
|
||||
// source: { x: 400, y: 200 },
|
||||
// target: { x: 740, y: 200 },
|
||||
// connector: { name: 'smooth' },
|
||||
// attrs: {
|
||||
// line: {
|
||||
// targetMarker: {
|
||||
// d: 'M 0 -5 L -10 0 L 0 5 Z',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// labels: [
|
||||
// {
|
||||
// markup: [
|
||||
// {
|
||||
// tagName: 'rect',
|
||||
// selector: 'labelBody',
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// selector: 'labelText',
|
||||
// },
|
||||
// ],
|
||||
// attrs: {
|
||||
// labelText: {
|
||||
// text: 'First',
|
||||
// fill: '#7c68fc',
|
||||
// fontFamily: 'sans-serif',
|
||||
// textAnchor: 'middle',
|
||||
// textVerticalAnchor: 'middle',
|
||||
// },
|
||||
// labelBody: {
|
||||
// ref: 'labelText',
|
||||
// refX: -5,
|
||||
// refY: -5,
|
||||
// refWidth: '100%',
|
||||
// refHeight: '100%',
|
||||
// refWidth2: 10,
|
||||
// refHeight2: 10,
|
||||
// stroke: '#7c68fc',
|
||||
// fill: 'white',
|
||||
// strokeWidth: 2,
|
||||
// rx: 5,
|
||||
// ry: 5,
|
||||
// },
|
||||
// },
|
||||
// position: {
|
||||
// distance: 0.3,
|
||||
// options: {
|
||||
// keepGradient: true,
|
||||
// ensureLegibility: true,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// markup: [
|
||||
// {
|
||||
// tagName: 'ellipse',
|
||||
// selector: 'labelBody',
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// selector: 'labelText',
|
||||
// },
|
||||
// ],
|
||||
// attrs: {
|
||||
// labelText: {
|
||||
// text: 'Second',
|
||||
// fill: '#31d0c6',
|
||||
// fontFamily: 'sans-serif',
|
||||
// textAnchor: 'middle',
|
||||
// textVerticalAnchor: 'middle',
|
||||
// },
|
||||
// labelBody: {
|
||||
// ref: 'labelText',
|
||||
// refRx: '70%',
|
||||
// refRy: '80%',
|
||||
// stroke: '#31d0c6',
|
||||
// fill: 'white',
|
||||
// strokeWidth: 2,
|
||||
// },
|
||||
// },
|
||||
// position: {
|
||||
// distance: 0.7,
|
||||
// angle: 45,
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
shape: 'shadow-edge',
|
||||
source: { x: 10, y: 280 },
|
||||
target: { x: 440, y: 280 },
|
||||
vertices: [
|
||||
{ x: 150, y: 350 },
|
||||
{ x: 300, y: 280 },
|
||||
],
|
||||
connector: { name: 'smooth' },
|
||||
markup: [
|
||||
{
|
||||
tagName: 'path',
|
||||
selector: 'shadow',
|
||||
attrs: {
|
||||
fill: 'none',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'path',
|
||||
selector: 'line',
|
||||
attrs: {
|
||||
fill: 'none',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'label',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#3c4260',
|
||||
},
|
||||
label: {
|
||||
textPath: {
|
||||
selector: 'line',
|
||||
startOffset: '50%',
|
||||
},
|
||||
textAnchor: 'middle',
|
||||
textVerticalAnchor: 'middle',
|
||||
text: 'Label Along Path',
|
||||
fill: '#f6f6f6',
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
fontFamily: 'fantasy',
|
||||
},
|
||||
},
|
||||
})
|
||||
// graph.addEdge({
|
||||
// shape: 'shadow-edge',
|
||||
// source: { x: 10, y: 280 },
|
||||
// target: { x: 440, y: 280 },
|
||||
// vertices: [
|
||||
// { x: 150, y: 350 },
|
||||
// { x: 300, y: 280 },
|
||||
// ],
|
||||
// connector: { name: 'smooth' },
|
||||
// markup: [
|
||||
// {
|
||||
// tagName: 'path',
|
||||
// selector: 'shadow',
|
||||
// attrs: {
|
||||
// fill: 'none',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// tagName: 'path',
|
||||
// selector: 'line',
|
||||
// attrs: {
|
||||
// fill: 'none',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// selector: 'label',
|
||||
// },
|
||||
// ],
|
||||
// attrs: {
|
||||
// line: {
|
||||
// stroke: '#3c4260',
|
||||
// },
|
||||
// label: {
|
||||
// textPath: {
|
||||
// selector: 'line',
|
||||
// startOffset: '50%',
|
||||
// },
|
||||
// textAnchor: 'middle',
|
||||
// textVerticalAnchor: 'middle',
|
||||
// text: 'Label Along Path',
|
||||
// fill: '#f6f6f6',
|
||||
// fontSize: 15,
|
||||
// fontWeight: 'bold',
|
||||
// fontFamily: 'fantasy',
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
// Custom Edge
|
||||
// -----------
|
||||
// // Custom Edge
|
||||
// // -----------
|
||||
|
||||
const node1 = graph.addNode({
|
||||
shape: 'path',
|
||||
x: 500,
|
||||
y: 450,
|
||||
width: 100,
|
||||
height: 100,
|
||||
attrs: {
|
||||
body: {
|
||||
fill: '#31d0c6',
|
||||
refD: 'M 0 20 10 20 10 30 30 30 30 0 40 0 40 40 0 40 z',
|
||||
},
|
||||
},
|
||||
})
|
||||
// const node1 = graph.addNode({
|
||||
// shape: 'path',
|
||||
// x: 500,
|
||||
// y: 450,
|
||||
// width: 100,
|
||||
// height: 100,
|
||||
// attrs: {
|
||||
// body: {
|
||||
// fill: '#31d0c6',
|
||||
// refD: 'M 0 20 10 20 10 30 30 30 30 0 40 0 40 40 0 40 z',
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 300, y: 400 },
|
||||
target: node1,
|
||||
attrs: {
|
||||
line: {
|
||||
sourceMarker: {
|
||||
d: 'M 0 0 15 0',
|
||||
stroke: 'white',
|
||||
strokeWidth: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
// graph.addEdge({
|
||||
// source: { x: 300, y: 400 },
|
||||
// target: node1,
|
||||
// attrs: {
|
||||
// line: {
|
||||
// sourceMarker: {
|
||||
// d: 'M 0 0 15 0',
|
||||
// stroke: 'white',
|
||||
// strokeWidth: 3,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
// refContainer = (container: HTMLDivElement) => {
|
||||
// this.container = container
|
||||
// }
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
// render() {
|
||||
// return (
|
||||
// <div className="x6-graph-wrap">
|
||||
// <div ref={this.refContainer} className="x6-graph" />
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
@ -1,75 +1,75 @@
|
||||
import React from 'react'
|
||||
import { Graph, Point } from '@antv/x6'
|
||||
import { Router } from '@antv/x6/es/registry/router'
|
||||
import '../index.less'
|
||||
// import React from 'react'
|
||||
// import { Graph, Point } from '@antv/x6'
|
||||
// import { Router } from '@antv/x6/es/registry/router'
|
||||
// import '../index.less'
|
||||
|
||||
Router.registry.register(
|
||||
'random',
|
||||
(vertices, args, view) => {
|
||||
const BOUNCES = args.bounces || 20
|
||||
const points = vertices.map((p) => Point.create(p))
|
||||
// Router.registry.register(
|
||||
// 'random',
|
||||
// (vertices, args, view) => {
|
||||
// const BOUNCES = args.bounces || 20
|
||||
// const points = vertices.map((p) => Point.create(p))
|
||||
|
||||
for (var i = 0; i < BOUNCES; i++) {
|
||||
const sourceCorner = view.sourceBBox.getCenter()
|
||||
const targetCorner = view.targetBBox.getCenter()
|
||||
const randomPoint = Point.random(
|
||||
sourceCorner.x,
|
||||
targetCorner.x,
|
||||
sourceCorner.y,
|
||||
targetCorner.y,
|
||||
)
|
||||
points.push(randomPoint)
|
||||
}
|
||||
// for (var i = 0; i < BOUNCES; i++) {
|
||||
// const sourceCorner = view.sourceBBox.getCenter()
|
||||
// const targetCorner = view.targetBBox.getCenter()
|
||||
// const randomPoint = Point.random(
|
||||
// sourceCorner.x,
|
||||
// targetCorner.x,
|
||||
// sourceCorner.y,
|
||||
// targetCorner.y,
|
||||
// )
|
||||
// points.push(randomPoint)
|
||||
// }
|
||||
|
||||
return points
|
||||
},
|
||||
true,
|
||||
)
|
||||
// return points
|
||||
// },
|
||||
// true,
|
||||
// )
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
// export default class Example extends React.Component {
|
||||
// private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 1000,
|
||||
height: 600,
|
||||
grid: 10,
|
||||
})
|
||||
// componentDidMount() {
|
||||
// const graph = new Graph({
|
||||
// container: this.container,
|
||||
// width: 1000,
|
||||
// height: 600,
|
||||
// grid: 10,
|
||||
// })
|
||||
|
||||
const source = graph.addNode({
|
||||
x: 50,
|
||||
y: 50,
|
||||
width: 120,
|
||||
height: 80,
|
||||
attrs: { label: { text: 'Source' } },
|
||||
})
|
||||
// const source = graph.addNode({
|
||||
// x: 50,
|
||||
// y: 50,
|
||||
// width: 120,
|
||||
// height: 80,
|
||||
// attrs: { label: { text: 'Source' } },
|
||||
// })
|
||||
|
||||
const target = graph.addNode(
|
||||
source.clone().translate(600, 400).attr('label/text', 'Target'),
|
||||
)
|
||||
// const target = graph.addNode(
|
||||
// source.clone().translate(600, 400).attr('label/text', 'Target'),
|
||||
// )
|
||||
|
||||
graph.addEdge({
|
||||
source,
|
||||
target,
|
||||
router: {
|
||||
name: 'random',
|
||||
args: {
|
||||
bounces: 10,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
// graph.addEdge({
|
||||
// source,
|
||||
// target,
|
||||
// router: {
|
||||
// name: 'random',
|
||||
// args: {
|
||||
// bounces: 10,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
// refContainer = (container: HTMLDivElement) => {
|
||||
// this.container = container
|
||||
// }
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
// render() {
|
||||
// return (
|
||||
// <div className="x6-graph-wrap">
|
||||
// <div ref={this.refContainer} className="x6-graph" />
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
@ -1,298 +1,298 @@
|
||||
import { Rect, Edge } from '@antv/x6/es/shape/standard'
|
||||
// import { Rect, Edge } from '@antv/x6/es/shape/standard'
|
||||
|
||||
export class Event extends Rect {
|
||||
static create(label: string) {
|
||||
return new Event({
|
||||
attrs: {
|
||||
label: {
|
||||
text: label,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
// export class Event extends Rect {
|
||||
// static create(label: string) {
|
||||
// return new Event({
|
||||
// attrs: {
|
||||
// label: {
|
||||
// text: label,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
Event.config({
|
||||
zIndex: 3,
|
||||
attrs: {
|
||||
root: {
|
||||
pointerEvents: 'bounding-box',
|
||||
},
|
||||
body: {
|
||||
strokeWidth: 2,
|
||||
fillOpacity: 0.2,
|
||||
},
|
||||
label: {
|
||||
textWrap: {
|
||||
height: -20,
|
||||
width: -20,
|
||||
ellipsis: true,
|
||||
},
|
||||
refX: '50%',
|
||||
refY: '50%',
|
||||
fontSize: 16,
|
||||
fontFamily: 'sans-serif',
|
||||
fill: '#333333',
|
||||
textAnchor: 'middle',
|
||||
textVerticalAnchor: 'middle',
|
||||
},
|
||||
},
|
||||
})
|
||||
// Event.config({
|
||||
// zIndex: 3,
|
||||
// attrs: {
|
||||
// root: {
|
||||
// pointerEvents: 'bounding-box',
|
||||
// },
|
||||
// body: {
|
||||
// strokeWidth: 2,
|
||||
// fillOpacity: 0.2,
|
||||
// },
|
||||
// label: {
|
||||
// textWrap: {
|
||||
// height: -20,
|
||||
// width: -20,
|
||||
// ellipsis: true,
|
||||
// },
|
||||
// refX: '50%',
|
||||
// refY: '50%',
|
||||
// fontSize: 16,
|
||||
// fontFamily: 'sans-serif',
|
||||
// fill: '#333333',
|
||||
// textAnchor: 'middle',
|
||||
// textVerticalAnchor: 'middle',
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
export class IntermediateEvent extends Event {
|
||||
static create(label: string, type?: string) {
|
||||
return new IntermediateEvent({
|
||||
attrs: {
|
||||
label: {
|
||||
text: label,
|
||||
},
|
||||
gate: {
|
||||
gateType: type,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
gateTypes = {
|
||||
or: 'M -20 0 C -20 -15 -10 -30 0 -30 C 10 -30 20 -15 20 0 C 10 -6 -10 -6 -20 0',
|
||||
xor: 'M -20 0 C -20 -15 -10 -30 0 -30 C 10 -30 20 -15 20 0 C 10 -6 -10 -6 -20 0 M -20 0 0 -30 M 0 -30 20 0',
|
||||
and: 'M -20 0 C -20 -25 -10 -30 0 -30 C 10 -30 20 -25 20 0 Z',
|
||||
priority_and:
|
||||
'M -20 0 C -20 -25 -10 -30 0 -30 C 10 -30 20 -25 20 0 Z M -20 0 0 -30 20 0',
|
||||
inhibit: 'M -10 0 -20 -15 -10 -30 10 -30 20 -15 10 0 Z',
|
||||
transfer: 'M -20 0 20 0 0 -30 z',
|
||||
}
|
||||
// export class IntermediateEvent extends Event {
|
||||
// static create(label: string, type?: string) {
|
||||
// return new IntermediateEvent({
|
||||
// attrs: {
|
||||
// label: {
|
||||
// text: label,
|
||||
// },
|
||||
// gate: {
|
||||
// gateType: type,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// gateTypes = {
|
||||
// or: 'M -20 0 C -20 -15 -10 -30 0 -30 C 10 -30 20 -15 20 0 C 10 -6 -10 -6 -20 0',
|
||||
// xor: 'M -20 0 C -20 -15 -10 -30 0 -30 C 10 -30 20 -15 20 0 C 10 -6 -10 -6 -20 0 M -20 0 0 -30 M 0 -30 20 0',
|
||||
// and: 'M -20 0 C -20 -25 -10 -30 0 -30 C 10 -30 20 -25 20 0 Z',
|
||||
// priority_and:
|
||||
// 'M -20 0 C -20 -25 -10 -30 0 -30 C 10 -30 20 -25 20 0 Z M -20 0 0 -30 20 0',
|
||||
// inhibit: 'M -10 0 -20 -15 -10 -30 10 -30 20 -15 10 0 Z',
|
||||
// transfer: 'M -20 0 20 0 0 -30 z',
|
||||
// }
|
||||
|
||||
gate(): string
|
||||
gate(type: string): this
|
||||
gate(type?: string) {
|
||||
if (type === undefined) {
|
||||
return this.attr<string>(['gate', 'gateType'])
|
||||
}
|
||||
// gate(): string
|
||||
// gate(type: string): this
|
||||
// gate(type?: string) {
|
||||
// if (type === undefined) {
|
||||
// return this.attr<string>(['gate', 'gateType'])
|
||||
// }
|
||||
|
||||
this.attr(['gate'], {
|
||||
gateType: type,
|
||||
title: type.toUpperCase() + ' Gate',
|
||||
})
|
||||
// this.attr(['gate'], {
|
||||
// gateType: type,
|
||||
// title: type.toUpperCase() + ' Gate',
|
||||
// })
|
||||
|
||||
return this
|
||||
}
|
||||
}
|
||||
// return this
|
||||
// }
|
||||
// }
|
||||
|
||||
IntermediateEvent.config(
|
||||
{
|
||||
size: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
markup: [
|
||||
{
|
||||
tagName: 'path',
|
||||
selector: 'gate',
|
||||
},
|
||||
{
|
||||
tagName: 'rect',
|
||||
selector: 'body',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'label',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
root: {
|
||||
title: 'Intermediate Event',
|
||||
},
|
||||
body: {
|
||||
refWidth: '100%',
|
||||
refHeight: -40,
|
||||
stroke: '#3c4260',
|
||||
fill: '#3c4260',
|
||||
},
|
||||
gate: {
|
||||
event: 'element:gate:click',
|
||||
gateType: 'xor',
|
||||
stroke: '#7c68fc',
|
||||
fill: '#7c68fc',
|
||||
fillOpacity: 0.2,
|
||||
strokeWidth: 2,
|
||||
refX: '50%',
|
||||
refY: '100%',
|
||||
fillRule: 'nonzero',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
label: {
|
||||
textWrap: {
|
||||
height: -40,
|
||||
width: -10,
|
||||
},
|
||||
refY2: -20,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
gateType: {
|
||||
set(type: string) {
|
||||
var data = this.cell.gateTypes[type]
|
||||
return { d: data ? data + ' M 0 -30 0 -40' : 'M 0 0 0 0' }
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
// IntermediateEvent.config(
|
||||
// {
|
||||
// size: {
|
||||
// width: 100,
|
||||
// height: 100,
|
||||
// },
|
||||
// markup: [
|
||||
// {
|
||||
// tagName: 'path',
|
||||
// selector: 'gate',
|
||||
// },
|
||||
// {
|
||||
// tagName: 'rect',
|
||||
// selector: 'body',
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// selector: 'label',
|
||||
// },
|
||||
// ],
|
||||
// attrs: {
|
||||
// root: {
|
||||
// title: 'Intermediate Event',
|
||||
// },
|
||||
// body: {
|
||||
// refWidth: '100%',
|
||||
// refHeight: -40,
|
||||
// stroke: '#3c4260',
|
||||
// fill: '#3c4260',
|
||||
// },
|
||||
// gate: {
|
||||
// event: 'element:gate:click',
|
||||
// gateType: 'xor',
|
||||
// stroke: '#7c68fc',
|
||||
// fill: '#7c68fc',
|
||||
// fillOpacity: 0.2,
|
||||
// strokeWidth: 2,
|
||||
// refX: '50%',
|
||||
// refY: '100%',
|
||||
// fillRule: 'nonzero',
|
||||
// cursor: 'pointer',
|
||||
// },
|
||||
// label: {
|
||||
// textWrap: {
|
||||
// height: -40,
|
||||
// width: -10,
|
||||
// },
|
||||
// refY2: -20,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// gateType: {
|
||||
// set(type: string) {
|
||||
// var data = this.cell.gateTypes[type]
|
||||
// return { d: data ? data + ' M 0 -30 0 -40' : 'M 0 0 0 0' }
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// )
|
||||
|
||||
export class ExternalEvent extends Event {}
|
||||
// export class ExternalEvent extends Event {}
|
||||
|
||||
ExternalEvent.config({
|
||||
size: {
|
||||
width: 80,
|
||||
height: 100,
|
||||
},
|
||||
markup: [
|
||||
{
|
||||
tagName: 'path',
|
||||
selector: 'body',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'label',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
root: {
|
||||
title: 'External Event',
|
||||
},
|
||||
body: {
|
||||
refD: 'M 0 0 10 -10 20 0 20 40 0 40 Z',
|
||||
stroke: '#fe854f',
|
||||
fill: '#fe854f',
|
||||
},
|
||||
},
|
||||
})
|
||||
// ExternalEvent.config({
|
||||
// size: {
|
||||
// width: 80,
|
||||
// height: 100,
|
||||
// },
|
||||
// markup: [
|
||||
// {
|
||||
// tagName: 'path',
|
||||
// selector: 'body',
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// selector: 'label',
|
||||
// },
|
||||
// ],
|
||||
// attrs: {
|
||||
// root: {
|
||||
// title: 'External Event',
|
||||
// },
|
||||
// body: {
|
||||
// refD: 'M 0 0 10 -10 20 0 20 40 0 40 Z',
|
||||
// stroke: '#fe854f',
|
||||
// fill: '#fe854f',
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
export class UndevelopedEvent extends Event {}
|
||||
UndevelopedEvent.config({
|
||||
size: {
|
||||
width: 140,
|
||||
height: 80,
|
||||
},
|
||||
markup: [
|
||||
{
|
||||
tagName: 'path',
|
||||
selector: 'body',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'label',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
root: {
|
||||
title: 'Undeveloped Event',
|
||||
},
|
||||
body: {
|
||||
refD: 'M -1 0 0 1 1 0 0 -1 Z',
|
||||
stroke: '#feb663',
|
||||
fill: '#feb663',
|
||||
},
|
||||
},
|
||||
})
|
||||
// export class UndevelopedEvent extends Event {}
|
||||
// UndevelopedEvent.config({
|
||||
// size: {
|
||||
// width: 140,
|
||||
// height: 80,
|
||||
// },
|
||||
// markup: [
|
||||
// {
|
||||
// tagName: 'path',
|
||||
// selector: 'body',
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// selector: 'label',
|
||||
// },
|
||||
// ],
|
||||
// attrs: {
|
||||
// root: {
|
||||
// title: 'Undeveloped Event',
|
||||
// },
|
||||
// body: {
|
||||
// refD: 'M -1 0 0 1 1 0 0 -1 Z',
|
||||
// stroke: '#feb663',
|
||||
// fill: '#feb663',
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
export class BasicEvent extends Event {}
|
||||
BasicEvent.config({
|
||||
zIndex: 3,
|
||||
size: {
|
||||
width: 80,
|
||||
height: 80,
|
||||
},
|
||||
markup: [
|
||||
{
|
||||
tagName: 'circle',
|
||||
selector: 'body',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'label',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
root: {
|
||||
title: 'Basic Event',
|
||||
},
|
||||
body: {
|
||||
refCx: '50%',
|
||||
refCy: '50%',
|
||||
refR: '50%',
|
||||
stroke: '#30d0c6',
|
||||
fill: '#30d0c6',
|
||||
},
|
||||
},
|
||||
})
|
||||
// export class BasicEvent extends Event {}
|
||||
// BasicEvent.config({
|
||||
// zIndex: 3,
|
||||
// size: {
|
||||
// width: 80,
|
||||
// height: 80,
|
||||
// },
|
||||
// markup: [
|
||||
// {
|
||||
// tagName: 'circle',
|
||||
// selector: 'body',
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// selector: 'label',
|
||||
// },
|
||||
// ],
|
||||
// attrs: {
|
||||
// root: {
|
||||
// title: 'Basic Event',
|
||||
// },
|
||||
// body: {
|
||||
// refCx: '50%',
|
||||
// refCy: '50%',
|
||||
// refR: '50%',
|
||||
// stroke: '#30d0c6',
|
||||
// fill: '#30d0c6',
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
export class ConditioningEvent extends Event {}
|
||||
ConditioningEvent.config({
|
||||
zIndex: 2,
|
||||
size: {
|
||||
width: 140,
|
||||
height: 80,
|
||||
},
|
||||
markup: [
|
||||
{
|
||||
tagName: 'ellipse',
|
||||
selector: 'body',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'label',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
root: {
|
||||
title: 'Conditioning Event',
|
||||
},
|
||||
body: {
|
||||
refCx: '50%',
|
||||
refCy: '50%',
|
||||
refRx: '50%',
|
||||
refRy: '50%',
|
||||
stroke: '#7c68fc',
|
||||
fill: '#7c68fc',
|
||||
fillOpacity: 0.2,
|
||||
},
|
||||
},
|
||||
})
|
||||
// export class ConditioningEvent extends Event {}
|
||||
// ConditioningEvent.config({
|
||||
// zIndex: 2,
|
||||
// size: {
|
||||
// width: 140,
|
||||
// height: 80,
|
||||
// },
|
||||
// markup: [
|
||||
// {
|
||||
// tagName: 'ellipse',
|
||||
// selector: 'body',
|
||||
// },
|
||||
// {
|
||||
// tagName: 'text',
|
||||
// selector: 'label',
|
||||
// },
|
||||
// ],
|
||||
// attrs: {
|
||||
// root: {
|
||||
// title: 'Conditioning Event',
|
||||
// },
|
||||
// body: {
|
||||
// refCx: '50%',
|
||||
// refCy: '50%',
|
||||
// refRx: '50%',
|
||||
// refRy: '50%',
|
||||
// stroke: '#7c68fc',
|
||||
// fill: '#7c68fc',
|
||||
// fillOpacity: 0.2,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
export class Connector extends Edge {
|
||||
static create(event1: Event, event2: Event) {
|
||||
return new Connector({
|
||||
zIndex: 1,
|
||||
source: {
|
||||
cell: event1.id,
|
||||
selector: event1 instanceof IntermediateEvent ? 'gate' : 'body',
|
||||
},
|
||||
target: {
|
||||
cell: event2.id,
|
||||
selector: 'body',
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
// export class Connector extends Edge {
|
||||
// static create(event1: Event, event2: Event) {
|
||||
// return new Connector({
|
||||
// zIndex: 1,
|
||||
// source: {
|
||||
// cell: event1.id,
|
||||
// selector: event1 instanceof IntermediateEvent ? 'gate' : 'body',
|
||||
// },
|
||||
// target: {
|
||||
// cell: event2.id,
|
||||
// selector: 'body',
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
Connector.config({
|
||||
attrs: {
|
||||
line: {
|
||||
connection: true,
|
||||
stroke: '#333333',
|
||||
strokeWidth: 2,
|
||||
strokeLinejoin: 'round',
|
||||
},
|
||||
},
|
||||
markup: [
|
||||
{
|
||||
tagName: 'path',
|
||||
selector: 'line',
|
||||
attrs: {
|
||||
fill: 'none',
|
||||
'pointer-events': 'none',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
// Connector.config({
|
||||
// attrs: {
|
||||
// line: {
|
||||
// connection: true,
|
||||
// stroke: '#333333',
|
||||
// strokeWidth: 2,
|
||||
// strokeLinejoin: 'round',
|
||||
// },
|
||||
// },
|
||||
// markup: [
|
||||
// {
|
||||
// tagName: 'path',
|
||||
// selector: 'line',
|
||||
// attrs: {
|
||||
// fill: 'none',
|
||||
// 'pointer-events': 'none',
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// })
|
||||
|
@ -1,140 +1,140 @@
|
||||
import React from 'react'
|
||||
import { Node, Vector, Graph, Point, Line, Polyline } from '@antv/x6'
|
||||
import { Connector } from '@antv/x6/es/registry/connector'
|
||||
import '../index.less'
|
||||
// import React from 'react'
|
||||
// import { Node, Vector, Graph, Point, Line, Polyline } from '@antv/x6'
|
||||
// import { Connector } from '@antv/x6/es/registry/connector'
|
||||
// import '../index.less'
|
||||
|
||||
function random(max: number, min: number) {
|
||||
return Math.floor(Math.random() * (max - min)) + min
|
||||
}
|
||||
// function random(max: number, min: number) {
|
||||
// return Math.floor(Math.random() * (max - min)) + min
|
||||
// }
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
// export default class Example extends React.Component {
|
||||
// private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: 1,
|
||||
translating: {
|
||||
restrict: {
|
||||
x: 50,
|
||||
y: 50,
|
||||
width: 700,
|
||||
height: 500,
|
||||
},
|
||||
},
|
||||
})
|
||||
// componentDidMount() {
|
||||
// const graph = new Graph({
|
||||
// container: this.container,
|
||||
// width: 800,
|
||||
// height: 600,
|
||||
// grid: 1,
|
||||
// translating: {
|
||||
// restrict: {
|
||||
// x: 50,
|
||||
// y: 50,
|
||||
// width: 700,
|
||||
// height: 500,
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
function createCircle(x: number, y: number, group: 'inner' | 'outer') {
|
||||
const node = graph.addNode({
|
||||
shape: 'circle',
|
||||
size: { width: 20, height: 20 },
|
||||
position: { x: x, y: y },
|
||||
group: group,
|
||||
attrs: {
|
||||
body: {
|
||||
strokeWidth: 3,
|
||||
fill: group === 'inner' ? '#af9bff' : '#31d0c6',
|
||||
stroke: group === 'inner' ? '#7c68fc' : '#009d93',
|
||||
},
|
||||
},
|
||||
})
|
||||
// function createCircle(x: number, y: number, group: 'inner' | 'outer') {
|
||||
// const node = graph.addNode({
|
||||
// shape: 'circle',
|
||||
// size: { width: 20, height: 20 },
|
||||
// position: { x: x, y: y },
|
||||
// group: group,
|
||||
// attrs: {
|
||||
// body: {
|
||||
// strokeWidth: 3,
|
||||
// fill: group === 'inner' ? '#af9bff' : '#31d0c6',
|
||||
// stroke: group === 'inner' ? '#7c68fc' : '#009d93',
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
|
||||
node.on('change:position', updateBoundaries)
|
||||
}
|
||||
// node.on('change:position', updateBoundaries)
|
||||
// }
|
||||
|
||||
function createBoundary(color: string) {
|
||||
var boundary = Vector.create('path').attr({
|
||||
fill: color,
|
||||
'fill-opacity': 0.2,
|
||||
stroke: color,
|
||||
'stroke-width': 3,
|
||||
})
|
||||
// function createBoundary(color: string) {
|
||||
// var boundary = Vector.create('path').attr({
|
||||
// fill: color,
|
||||
// 'fill-opacity': 0.2,
|
||||
// stroke: color,
|
||||
// 'stroke-width': 3,
|
||||
// })
|
||||
|
||||
Vector.create(graph.view.stage).prepend(boundary)
|
||||
// Vector.create(graph.view.stage).prepend(boundary)
|
||||
|
||||
return boundary
|
||||
}
|
||||
// return boundary
|
||||
// }
|
||||
|
||||
function updateBoundaries() {
|
||||
var padding = 10
|
||||
// function updateBoundaries() {
|
||||
// var padding = 10
|
||||
|
||||
var innerPoints = getPointsByGroup('inner', padding)
|
||||
var outerPoints = getPointsByGroup('outer', padding)
|
||||
// var innerPoints = getPointsByGroup('inner', padding)
|
||||
// var outerPoints = getPointsByGroup('outer', padding)
|
||||
|
||||
var innerHullPoints = convexHullAlgorithm(innerPoints)
|
||||
var innerBoundaryPoints = getPaddedPoints(innerHullPoints, padding)
|
||||
var outerHullPoints = convexHullAlgorithm(
|
||||
outerPoints.concat(innerBoundaryPoints),
|
||||
)
|
||||
// var innerHullPoints = convexHullAlgorithm(innerPoints)
|
||||
// var innerBoundaryPoints = getPaddedPoints(innerHullPoints, padding)
|
||||
// var outerHullPoints = convexHullAlgorithm(
|
||||
// outerPoints.concat(innerBoundaryPoints),
|
||||
// )
|
||||
|
||||
innerBoundary.attr('d', createData(innerHullPoints))
|
||||
outerBoundary.attr('d', createData(outerHullPoints))
|
||||
}
|
||||
// innerBoundary.attr('d', createData(innerHullPoints))
|
||||
// outerBoundary.attr('d', createData(outerHullPoints))
|
||||
// }
|
||||
|
||||
function getPointsByGroup(group: 'inner' | 'outer', padding: number) {
|
||||
var node = graph.model.getNodes().filter((node) => {
|
||||
return node.getProp('group') === group
|
||||
})
|
||||
// function getPointsByGroup(group: 'inner' | 'outer', padding: number) {
|
||||
// var node = graph.model.getNodes().filter((node) => {
|
||||
// return node.getProp('group') === group
|
||||
// })
|
||||
|
||||
return node.reduce<Point[]>((memo, el) => {
|
||||
return memo.concat(getNodeCornerPoints(el, padding))
|
||||
}, [])
|
||||
}
|
||||
// return node.reduce<Point[]>((memo, el) => {
|
||||
// return memo.concat(getNodeCornerPoints(el, padding))
|
||||
// }, [])
|
||||
// }
|
||||
|
||||
function getNodeCornerPoints(node: Node, padding: number = 0) {
|
||||
var bbox = node.getBBox().inflate(padding)
|
||||
return [bbox.origin, bbox.bottomLeft, bbox.corner, bbox.topRight]
|
||||
}
|
||||
// function getNodeCornerPoints(node: Node, padding: number = 0) {
|
||||
// var bbox = node.getBBox().inflate(padding)
|
||||
// return [bbox.origin, bbox.bottomLeft, bbox.corner, bbox.topRight]
|
||||
// }
|
||||
|
||||
function getPaddedPoints(points: Point[], padding: number = 0) {
|
||||
return points.reduce<Point[]>((memo, point) => {
|
||||
memo.push(
|
||||
point.clone().translate(padding, padding),
|
||||
point.clone().translate(-padding, padding),
|
||||
point.clone().translate(padding, -padding),
|
||||
point.clone().translate(-padding, -padding),
|
||||
)
|
||||
return memo
|
||||
}, [])
|
||||
}
|
||||
// function getPaddedPoints(points: Point[], padding: number = 0) {
|
||||
// return points.reduce<Point[]>((memo, point) => {
|
||||
// memo.push(
|
||||
// point.clone().translate(padding, padding),
|
||||
// point.clone().translate(-padding, padding),
|
||||
// point.clone().translate(padding, -padding),
|
||||
// point.clone().translate(-padding, -padding),
|
||||
// )
|
||||
// return memo
|
||||
// }, [])
|
||||
// }
|
||||
|
||||
function createData(points: Point[], radius?: number) {
|
||||
var origin = new Line(points[0], points[points.length - 1]).getCenter()
|
||||
return Connector.presets.rounded.call(this, origin, origin, points, {
|
||||
radius: radius || 30,
|
||||
})
|
||||
}
|
||||
// function createData(points: Point[], radius?: number) {
|
||||
// var origin = new Line(points[0], points[points.length - 1]).getCenter()
|
||||
// return Connector.presets.rounded.call(this, origin, origin, points, {
|
||||
// radius: radius || 30,
|
||||
// })
|
||||
// }
|
||||
|
||||
function convexHullAlgorithm(points: Point[]) {
|
||||
return new Polyline(points).toHull().points
|
||||
}
|
||||
// function convexHullAlgorithm(points: Point[]) {
|
||||
// return new Polyline(points).toHull().points
|
||||
// }
|
||||
|
||||
// bootstrap
|
||||
// ---------
|
||||
Array.from({ length: 10 }).forEach((_, i) => {
|
||||
var x = random(100, 700)
|
||||
var y = random(100, 500)
|
||||
createCircle(x, y, i % 3 === 0 ? 'inner' : 'outer')
|
||||
})
|
||||
// // bootstrap
|
||||
// // ---------
|
||||
// Array.from({ length: 10 }).forEach((_, i) => {
|
||||
// var x = random(100, 700)
|
||||
// var y = random(100, 500)
|
||||
// createCircle(x, y, i % 3 === 0 ? 'inner' : 'outer')
|
||||
// })
|
||||
|
||||
// create boundaries around elements
|
||||
var innerBoundary = createBoundary('#fe854f')
|
||||
var outerBoundary = createBoundary('#feb663')
|
||||
// // create boundaries around elements
|
||||
// var innerBoundary = createBoundary('#fe854f')
|
||||
// var outerBoundary = createBoundary('#feb663')
|
||||
|
||||
updateBoundaries()
|
||||
}
|
||||
// updateBoundaries()
|
||||
// }
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
// refContainer = (container: HTMLDivElement) => {
|
||||
// this.container = container
|
||||
// }
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
// render() {
|
||||
// return (
|
||||
// <div className="x6-graph-wrap">
|
||||
// <div ref={this.refContainer} className="x6-graph" />
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
@ -8,6 +8,51 @@ const dataSource = [
|
||||
example: 'animation/transition',
|
||||
description: 'transition 动画',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
example: 'auto-resize',
|
||||
description: '画布大小自适应',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
example: 'case/bpmn',
|
||||
description: 'BPMN 图',
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
example: 'case/class',
|
||||
description: '类图',
|
||||
},
|
||||
{
|
||||
key: '5',
|
||||
example: 'case/dag',
|
||||
description: 'DAG 图',
|
||||
},
|
||||
{
|
||||
key: '6',
|
||||
example: 'case/elk',
|
||||
description: 'ELK 图',
|
||||
},
|
||||
{
|
||||
key: '7',
|
||||
example: 'case/er',
|
||||
description: 'ER 图',
|
||||
},
|
||||
{
|
||||
key: '8',
|
||||
example: 'case/mind',
|
||||
description: '脑图',
|
||||
},
|
||||
{
|
||||
key: '9',
|
||||
example: 'case/swimlane',
|
||||
description: '泳道图',
|
||||
},
|
||||
{
|
||||
key: '10',
|
||||
example: 'snapline',
|
||||
description: '对齐线',
|
||||
},
|
||||
]
|
||||
|
||||
const columns = [
|
||||
|
@ -1,166 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Stencil } from '@antv/x6/es/addon/stencil'
|
||||
import { Rect, Circle } from '@antv/x6/es/shape/basic'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
private stencilContainer: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 800,
|
||||
snapline: {
|
||||
enabled: true,
|
||||
sharp: true,
|
||||
},
|
||||
grid: {
|
||||
visible: true,
|
||||
},
|
||||
history: true,
|
||||
scroller: {
|
||||
enabled: true,
|
||||
width: 600,
|
||||
height: 400,
|
||||
pageVisible: true,
|
||||
pageBreak: false,
|
||||
pannable: true,
|
||||
},
|
||||
})
|
||||
|
||||
graph.centerContent()
|
||||
|
||||
graph.addNode({
|
||||
x: 130,
|
||||
y: 30,
|
||||
width: 100,
|
||||
height: 40,
|
||||
attrs: {
|
||||
label: {
|
||||
text: 'rect',
|
||||
fill: '#6a6c8a',
|
||||
},
|
||||
body: {
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const stencil = new Stencil({
|
||||
target: graph,
|
||||
width: 200,
|
||||
height: 300,
|
||||
search: true,
|
||||
collapsable: true,
|
||||
grid: 1,
|
||||
groups: [
|
||||
{
|
||||
name: 'group1',
|
||||
},
|
||||
{
|
||||
name: 'group2',
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
this.stencilContainer.appendChild(stencil.container)
|
||||
|
||||
var r = new Rect({
|
||||
position: { x: 10, y: 10 },
|
||||
size: { width: 70, height: 40 },
|
||||
attrs: {
|
||||
rect: { fill: '#31D0C6', stroke: '#4B4A67', 'stroke-width': 8 },
|
||||
text: { text: 'rect', fill: 'white' },
|
||||
},
|
||||
})
|
||||
|
||||
var c = new Circle({
|
||||
position: { x: 100, y: 10 },
|
||||
size: { width: 70, height: 40 },
|
||||
attrs: {
|
||||
circle: { fill: '#FE854F', 'stroke-width': 8, stroke: '#4B4A67' },
|
||||
text: { text: 'ellipse', fill: 'white' },
|
||||
},
|
||||
})
|
||||
|
||||
var c2 = new Circle({
|
||||
position: { x: 10, y: 70 },
|
||||
size: { width: 70, height: 40 },
|
||||
attrs: {
|
||||
circle: { fill: '#4B4A67', 'stroke-width': 8, stroke: '#FE854F' },
|
||||
text: { text: 'ellipse', fill: 'white' },
|
||||
},
|
||||
})
|
||||
|
||||
var r2 = new Rect({
|
||||
position: { x: 100, y: 70 },
|
||||
size: { width: 70, height: 40 },
|
||||
attrs: {
|
||||
rect: { fill: '#4B4A67', stroke: '#31D0C6', 'stroke-width': 8 },
|
||||
text: { text: 'rect', fill: 'white' },
|
||||
},
|
||||
})
|
||||
|
||||
var r3 = new Rect({
|
||||
position: { x: 10, y: 130 },
|
||||
size: { width: 70, height: 40 },
|
||||
attrs: {
|
||||
rect: { fill: '#31D0C6', stroke: '#4B4A67', 'stroke-width': 8 },
|
||||
text: { text: 'rect', fill: 'white' },
|
||||
},
|
||||
})
|
||||
|
||||
var c3 = new Circle({
|
||||
position: { x: 100, y: 130 },
|
||||
size: { width: 70, height: 40 },
|
||||
attrs: {
|
||||
circle: { fill: '#FE854F', 'stroke-width': 8, stroke: '#4B4A67' },
|
||||
text: { text: 'ellipse', fill: 'white' },
|
||||
},
|
||||
})
|
||||
|
||||
stencil.load([r, c, c2, r2.clone()], 'group1')
|
||||
stencil.load([c2.clone(), r2, r3, c3], 'group2')
|
||||
|
||||
graph.once('node:added', ({ node }) => {
|
||||
console.log(node)
|
||||
setTimeout(() => {
|
||||
graph.undo()
|
||||
setTimeout(() => {
|
||||
graph.redo()
|
||||
}, 2000)
|
||||
}, 2000)
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
refStencil = (container: HTMLDivElement) => {
|
||||
this.stencilContainer = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<h1>Default Settings</h1>
|
||||
<div
|
||||
ref={this.refStencil}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 32,
|
||||
top: 40,
|
||||
width: 200,
|
||||
height: 300,
|
||||
}}
|
||||
/>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Graph, Shape } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 400,
|
||||
grid: true,
|
||||
connecting: {
|
||||
snap: true,
|
||||
allowBlank: false,
|
||||
allowMulti: true,
|
||||
highlight: true,
|
||||
router: { name: 'manhattan' },
|
||||
connector: { name: 'normal' },
|
||||
connectionPoint: 'boundary',
|
||||
},
|
||||
})
|
||||
|
||||
Shape.Rect.config({
|
||||
width: 100,
|
||||
height: 40,
|
||||
ports: {
|
||||
items: [
|
||||
{ group: 'left', id: '4' },
|
||||
{ group: 'right', id: '2' },
|
||||
{ group: 'top', id: '1' },
|
||||
{ group: 'bottom', id: '3' },
|
||||
],
|
||||
groups: {
|
||||
left: {
|
||||
position: { name: 'left' },
|
||||
attrs: {
|
||||
portBody: {
|
||||
magnet: 'active',
|
||||
r: 4,
|
||||
// cy: -1,
|
||||
fill: 'lightblue',
|
||||
stroke: 'black',
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
z: 0,
|
||||
},
|
||||
right: {
|
||||
position: { name: 'right' },
|
||||
attrs: {
|
||||
portBody: {
|
||||
magnet: 'active',
|
||||
r: 4,
|
||||
// cy: -1,
|
||||
fill: 'lightblue',
|
||||
stroke: 'black',
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
z: 0,
|
||||
},
|
||||
top: {
|
||||
position: { name: 'top' },
|
||||
attrs: {
|
||||
portBody: {
|
||||
magnet: 'active',
|
||||
r: 4,
|
||||
// cy: -1,
|
||||
fill: 'lightblue',
|
||||
stroke: 'black',
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
z: 0,
|
||||
},
|
||||
bottom: {
|
||||
position: { name: 'bottom' },
|
||||
attrs: {
|
||||
portBody: {
|
||||
magnet: 'active',
|
||||
r: 4,
|
||||
// cy: -1,
|
||||
fill: 'lightblue',
|
||||
stroke: 'black',
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
z: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
portMarkup: [
|
||||
{
|
||||
tagName: 'circle',
|
||||
selector: 'portBody',
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
graph.fromJSON({
|
||||
edges: [
|
||||
{
|
||||
source: {
|
||||
cell: 'start',
|
||||
port: '2',
|
||||
},
|
||||
target: {
|
||||
cell: 'create',
|
||||
port: '2',
|
||||
},
|
||||
attrs: {
|
||||
line: {
|
||||
targetMarker: {
|
||||
name: 'classic',
|
||||
offset: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
source: {
|
||||
cell: 'create',
|
||||
port: '1',
|
||||
},
|
||||
target: {
|
||||
cell: 'end',
|
||||
port: '1',
|
||||
},
|
||||
attrs: {
|
||||
line: {
|
||||
targetMarker: {
|
||||
name: 'classic',
|
||||
offset: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
nodes: [
|
||||
{
|
||||
id: 'start',
|
||||
label: 'start',
|
||||
type: 'start',
|
||||
x: 100,
|
||||
y: 100,
|
||||
},
|
||||
{
|
||||
id: 'create',
|
||||
label: 'userTask',
|
||||
type: 'userTask',
|
||||
x: 300,
|
||||
y: 300,
|
||||
},
|
||||
{
|
||||
id: 'end',
|
||||
label: 'end',
|
||||
type: 'end',
|
||||
x: 170,
|
||||
y: 200,
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,256 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Button } from 'antd'
|
||||
import { Graph, Edge } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component<
|
||||
Example.Props,
|
||||
Example.State
|
||||
> {
|
||||
state: Example.State = {
|
||||
canRedo: false,
|
||||
canUndo: false,
|
||||
}
|
||||
|
||||
private container: HTMLDivElement
|
||||
private graph: Graph
|
||||
|
||||
componentDidMount() {
|
||||
const graph = (this.graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
panning: true,
|
||||
history: {
|
||||
enabled: true,
|
||||
beforeAddCommand(event, args: any) {
|
||||
if (args.options.ignoreHistory) {
|
||||
return false
|
||||
}
|
||||
},
|
||||
},
|
||||
connecting: {
|
||||
allowBlank: false,
|
||||
allowNode: false,
|
||||
connector: {
|
||||
name: 'smooth',
|
||||
},
|
||||
createEdge() {
|
||||
return Edge.create({
|
||||
attrs: {
|
||||
line: {
|
||||
strokeDasharray: '5 5',
|
||||
},
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
graph.history.on('change', () => {
|
||||
this.setState({
|
||||
canRedo: graph.canRedo(),
|
||||
canUndo: graph.canUndo(),
|
||||
})
|
||||
})
|
||||
|
||||
graph.on('edge:connected', ({ edge }) => {
|
||||
edge.attr('line/strokeDasharray', null, { ignoreHistory: true })
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
x: 100,
|
||||
y: 80,
|
||||
width: 160,
|
||||
height: 80,
|
||||
label: 'hello',
|
||||
ports: {
|
||||
groups: {
|
||||
top: {
|
||||
position: 'top',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
right: {
|
||||
position: 'right',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
bottom: {
|
||||
position: 'bottom',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
left: {
|
||||
position: 'left',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
items: [
|
||||
{
|
||||
id: 'top',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: 'right',
|
||||
group: 'right',
|
||||
},
|
||||
{
|
||||
id: 'bottom',
|
||||
group: 'bottom',
|
||||
},
|
||||
{
|
||||
id: 'left',
|
||||
group: 'left',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
x: 400,
|
||||
y: 320,
|
||||
width: 160,
|
||||
height: 80,
|
||||
label: 'world',
|
||||
ports: {
|
||||
groups: {
|
||||
top: {
|
||||
position: 'top',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
right: {
|
||||
position: 'right',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
bottom: {
|
||||
position: 'bottom',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
left: {
|
||||
position: 'left',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
items: [
|
||||
{
|
||||
id: 'top',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: 'right',
|
||||
group: 'right',
|
||||
},
|
||||
{
|
||||
id: 'bottom',
|
||||
group: 'bottom',
|
||||
},
|
||||
{
|
||||
id: 'left',
|
||||
group: 'left',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
onUndo = () => {
|
||||
this.graph.undo()
|
||||
}
|
||||
|
||||
onRedo = () => {
|
||||
this.graph.redo()
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div className="x6-graph-tools">
|
||||
<Button onClick={this.onUndo} disabled={!this.state.canUndo}>
|
||||
Undo
|
||||
</Button>
|
||||
<Button onClick={this.onRedo} disabled={!this.state.canRedo}>
|
||||
Redo
|
||||
</Button>
|
||||
</div>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Example {
|
||||
export interface Props {}
|
||||
|
||||
export interface State {
|
||||
canUndo: boolean
|
||||
canRedo: boolean
|
||||
}
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Button } from 'antd'
|
||||
import { Graph } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component<
|
||||
Example.Props,
|
||||
Example.State
|
||||
> {
|
||||
state: Example.State = {
|
||||
canRedo: false,
|
||||
canUndo: false,
|
||||
}
|
||||
|
||||
private graph: Graph
|
||||
private graphContainer: HTMLDivElement
|
||||
private minimapContainer: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = (this.graph = new Graph({
|
||||
container: this.graphContainer,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
history: {
|
||||
enabled: true,
|
||||
beforeAddCommand(event, options) {
|
||||
// 鼠标移入和移除时触发 添加 和 删除 工具,不应该添加到历时记录中
|
||||
if (
|
||||
event === 'cell:change:*' &&
|
||||
options != null &&
|
||||
options.key === 'tools'
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (event === 'cell:removed') {
|
||||
const cell = options && options.cell
|
||||
if (cell) {
|
||||
cell.removeTools()
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
scroller: {
|
||||
enabled: true,
|
||||
pannable: true,
|
||||
},
|
||||
minimap: {
|
||||
enabled: true,
|
||||
container: this.minimapContainer,
|
||||
width: 300,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
graphOptions: {
|
||||
async: true,
|
||||
createCellView(cell) {
|
||||
if (cell.isEdge()) {
|
||||
return null
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
graph.on('cell:mouseenter', function ({ cell }) {
|
||||
if (cell.isNode()) {
|
||||
cell.addTools([
|
||||
{
|
||||
name: 'boundary',
|
||||
args: {
|
||||
attrs: {
|
||||
fill: '#7c68fc',
|
||||
stroke: '#333',
|
||||
'stroke-width': 1,
|
||||
'fill-opacity': 0.2,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'button-remove',
|
||||
args: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
offset: { x: 10, y: 10 },
|
||||
},
|
||||
},
|
||||
])
|
||||
} else {
|
||||
cell.addTools(['vertices', 'segments'])
|
||||
}
|
||||
})
|
||||
|
||||
graph.on('cell:mouseleave', ({ cell }) => {
|
||||
cell.removeTools()
|
||||
})
|
||||
|
||||
graph.history.on('change', () => {
|
||||
this.setState({
|
||||
canRedo: graph.canRedo(),
|
||||
canUndo: graph.canUndo(),
|
||||
})
|
||||
})
|
||||
|
||||
graph.on('node:click', function ({ node }) {
|
||||
node.attr('body/stroke', 'orange')
|
||||
})
|
||||
|
||||
const rect1 = graph.addNode({
|
||||
x: 100,
|
||||
y: 80,
|
||||
width: 100,
|
||||
height: 40,
|
||||
label: 'hello',
|
||||
})
|
||||
|
||||
const rect2 = graph.addNode({
|
||||
x: 400,
|
||||
y: 320,
|
||||
width: 100,
|
||||
height: 40,
|
||||
label: 'world',
|
||||
})
|
||||
|
||||
graph.addEdge({
|
||||
source: rect1,
|
||||
target: rect2,
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.graphContainer = container
|
||||
}
|
||||
|
||||
refMinimap = (container: HTMLDivElement) => {
|
||||
this.minimapContainer = container
|
||||
}
|
||||
|
||||
onUndo = () => {
|
||||
this.graph.undo()
|
||||
}
|
||||
|
||||
onRedo = () => {
|
||||
this.graph.redo()
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<h1>Scroller</h1>
|
||||
<div className="x6-graph-tools">
|
||||
<Button onClick={this.onUndo} disabled={!this.state.canUndo}>
|
||||
Undo
|
||||
</Button>
|
||||
<Button onClick={this.onRedo} disabled={!this.state.canRedo}>
|
||||
Redo
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
ref={this.refMinimap}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: '50%',
|
||||
top: 40,
|
||||
marginRight: -720,
|
||||
width: 300,
|
||||
height: 200,
|
||||
boxShadow: '0 0 10px 1px #e9e9e9',
|
||||
}}
|
||||
/>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Example {
|
||||
export interface Props {}
|
||||
|
||||
export interface State {
|
||||
canUndo: boolean
|
||||
canRedo: boolean
|
||||
}
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
import React from 'react'
|
||||
import ReactDom from 'react-dom'
|
||||
import { Dropdown, Menu } from 'antd'
|
||||
import { Graph, ToolsView, EdgeView } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
class ContextMenuTool extends ToolsView.ToolItem<
|
||||
EdgeView,
|
||||
ContextMenuToolOptions
|
||||
> {
|
||||
private knob: HTMLDivElement
|
||||
|
||||
render() {
|
||||
super.render()
|
||||
this.knob = ToolsView.createElement('div', false) as HTMLDivElement
|
||||
this.knob.style.position = 'absolute'
|
||||
this.container.appendChild(this.knob)
|
||||
this.updatePosition(this.options)
|
||||
setTimeout(() => {
|
||||
this.toggleContextMenu(true)
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
private toggleContextMenu(visible: boolean) {
|
||||
ReactDom.unmountComponentAtNode(this.knob)
|
||||
document.removeEventListener('mousedown', this.onMouseDown)
|
||||
if (visible) {
|
||||
ReactDom.render(
|
||||
<Dropdown
|
||||
visible={true}
|
||||
trigger={['click']}
|
||||
overlay={this.options.menu}
|
||||
>
|
||||
<a href="#" />
|
||||
</Dropdown>,
|
||||
this.knob,
|
||||
() => {
|
||||
document.addEventListener('mousedown', this.onMouseDown)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private updatePosition(pos?: { x: number; y: number }) {
|
||||
const style = this.knob.style
|
||||
if (pos) {
|
||||
style.left = `${pos.x}px`
|
||||
style.top = `${pos.y}px`
|
||||
} else {
|
||||
style.left = '-1000px'
|
||||
style.top = '-1000px'
|
||||
}
|
||||
}
|
||||
|
||||
private onMouseDown = (e: MouseEvent) => {
|
||||
console.log('')
|
||||
|
||||
setTimeout(() => {
|
||||
this.updatePosition()
|
||||
this.toggleContextMenu(false)
|
||||
if (this.options.onHide) {
|
||||
this.options.onHide.call(this)
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
|
||||
ContextMenuTool.config({
|
||||
tagName: 'div',
|
||||
isSVGElement: false,
|
||||
})
|
||||
|
||||
export interface ContextMenuToolOptions extends ToolsView.ToolItem.Options {
|
||||
x: number
|
||||
y: number
|
||||
menu?: Menu | (() => Menu)
|
||||
onHide?: (this: ContextMenuTool) => void
|
||||
}
|
||||
|
||||
Graph.registerEdgeTool('contextmenu', ContextMenuTool, true)
|
||||
Graph.registerNodeTool('contextmenu', ContextMenuTool, true)
|
||||
|
||||
const onMenuClick = (e: any) => {
|
||||
console.log('menu click ', e)
|
||||
}
|
||||
|
||||
const menu = () => (
|
||||
<Menu onClick={onMenuClick}>
|
||||
<Menu.Item key="1">1st menu item</Menu.Item>
|
||||
<Menu.Item key="2">2nd menu item</Menu.Item>
|
||||
<Menu.Item key="3">
|
||||
<a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/">
|
||||
3rd menu item
|
||||
</a>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="4">a danger item</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
panning: true,
|
||||
})
|
||||
|
||||
const source = graph.addNode({
|
||||
x: 40,
|
||||
y: 40,
|
||||
width: 100,
|
||||
height: 40,
|
||||
})
|
||||
|
||||
const target = graph.addNode({
|
||||
x: 240,
|
||||
y: 200,
|
||||
width: 100,
|
||||
height: 40,
|
||||
})
|
||||
|
||||
graph.addEdge({
|
||||
source,
|
||||
target,
|
||||
})
|
||||
|
||||
graph.on('cell:contextmenu', ({ cell, e }) => {
|
||||
const p = graph.clientToGraph(e.clientX, e.clientY)
|
||||
cell.addTools([
|
||||
{
|
||||
name: 'contextmenu',
|
||||
args: {
|
||||
menu,
|
||||
x: p.x,
|
||||
y: p.y,
|
||||
onHide() {
|
||||
this.cell.removeTools()
|
||||
},
|
||||
},
|
||||
},
|
||||
])
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Button } from 'antd'
|
||||
import { Graph, NodeView, DataUri } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
class SimpleNodeView extends NodeView {
|
||||
protected renderMarkup() {
|
||||
return this.renderJSONMarkup({
|
||||
tagName: 'rect',
|
||||
selector: 'body',
|
||||
})
|
||||
}
|
||||
|
||||
protected renderPorts() {}
|
||||
|
||||
update() {
|
||||
super.update({
|
||||
body: {
|
||||
refWidth: '100%',
|
||||
refHeight: '100%',
|
||||
fill: '#31d0c6',
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private graph: Graph
|
||||
private graphContainer: HTMLDivElement
|
||||
private minimapContainer: HTMLDivElement
|
||||
private scroller: any
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.graphContainer,
|
||||
width: 800,
|
||||
height: 500,
|
||||
resizing: true,
|
||||
background: {
|
||||
color: '#f5f5f5',
|
||||
},
|
||||
grid: {
|
||||
visible: true,
|
||||
},
|
||||
selecting: {
|
||||
enabled: true,
|
||||
rubberband: true,
|
||||
modifiers: 'shift',
|
||||
},
|
||||
scroller: {
|
||||
enabled: true,
|
||||
// width: 600,
|
||||
// height: 400,
|
||||
pageVisible: true,
|
||||
pageBreak: true,
|
||||
pannable: true,
|
||||
autoResize: true,
|
||||
// modifiers: 'shift',
|
||||
},
|
||||
minimap: {
|
||||
enabled: true,
|
||||
container: this.minimapContainer,
|
||||
width: 300,
|
||||
height: 200,
|
||||
padding: 10,
|
||||
graphOptions: {
|
||||
async: true,
|
||||
getCellView(cell) {
|
||||
if (cell.isNode()) {
|
||||
return SimpleNodeView
|
||||
}
|
||||
},
|
||||
createCellView(cell) {
|
||||
if (cell.isEdge()) {
|
||||
return null
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
mousewheel: {
|
||||
enabled: true,
|
||||
// fixed: false,
|
||||
modifiers: ['ctrl', 'meta'],
|
||||
minScale: 0.5,
|
||||
maxScale: 2,
|
||||
},
|
||||
})
|
||||
|
||||
this.scroller = graph.scroller.widget
|
||||
|
||||
const rect = graph.addNode({
|
||||
x: 40,
|
||||
y: 40,
|
||||
width: 90,
|
||||
height: 60,
|
||||
})
|
||||
|
||||
rect.on('removed', () => {
|
||||
console.log('rect was removed')
|
||||
})
|
||||
|
||||
const circle = graph.addNode({
|
||||
shape: 'circle',
|
||||
x: 160,
|
||||
y: 160,
|
||||
width: 40,
|
||||
height: 40,
|
||||
})
|
||||
|
||||
graph.addEdge({
|
||||
source: rect,
|
||||
target: circle,
|
||||
})
|
||||
|
||||
this.graph = graph
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.graphContainer = container
|
||||
}
|
||||
|
||||
refMinimap = (container: HTMLDivElement) => {
|
||||
this.minimapContainer = container
|
||||
}
|
||||
|
||||
onResizeClick = () => {
|
||||
this.graph.resizeGraph(200, 150)
|
||||
}
|
||||
|
||||
onCenterClick = () => {
|
||||
this.graph.center()
|
||||
}
|
||||
|
||||
onCenterContentClick = () => {
|
||||
this.graph.centerContent()
|
||||
}
|
||||
|
||||
onZoomOutClick = () => {
|
||||
this.scroller.zoom(-0.2)
|
||||
}
|
||||
|
||||
onZoomInClick = () => {
|
||||
this.scroller.zoom(0.2)
|
||||
}
|
||||
|
||||
onZoomToFitClick = () => {
|
||||
this.scroller.zoomToFit()
|
||||
}
|
||||
|
||||
onDownload = () => {
|
||||
this.graph.toPNG((datauri: string) => {
|
||||
DataUri.downloadDataUri(datauri, 'chart.png')
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<h1>Scroller</h1>
|
||||
<div className="x6-graph-tools">
|
||||
<Button onClick={this.onResizeClick}>Resize</Button>
|
||||
<Button onClick={this.onCenterClick}>Center</Button>
|
||||
<Button onClick={this.onCenterContentClick}>Center Content</Button>
|
||||
<Button onClick={this.onZoomOutClick}>Zoom Out</Button>
|
||||
<Button onClick={this.onZoomInClick}>Zoom In</Button>
|
||||
<Button onClick={this.onZoomToFitClick}>Zoom To Fit</Button>
|
||||
<Button onClick={this.onDownload}>Download</Button>
|
||||
</div>
|
||||
<div
|
||||
ref={this.refMinimap}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: '50%',
|
||||
top: 40,
|
||||
marginRight: -720,
|
||||
width: 300,
|
||||
height: 200,
|
||||
boxShadow: '0 0 10px 1px #e9e9e9',
|
||||
}}
|
||||
/>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
Graph.registerNode(
|
||||
'new-rect',
|
||||
{
|
||||
inherit: 'rect',
|
||||
width: 160,
|
||||
height: 40,
|
||||
attrs: {
|
||||
label: {
|
||||
textAnchor: 'left',
|
||||
refX: 0,
|
||||
textWrap: {
|
||||
width: 160,
|
||||
height: 48,
|
||||
ellipsis: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
)
|
||||
|
||||
const data = {
|
||||
nodes: [
|
||||
{
|
||||
shape: 'new-rect',
|
||||
id: 'node1',
|
||||
x: 40,
|
||||
y: 40,
|
||||
attrs: {
|
||||
label: {
|
||||
text: 'hello-test-foo-bar-count-lint-jsvascriptjsvascriptjsvascript',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
shape: 'new-rect',
|
||||
id: 'node2',
|
||||
x: 220,
|
||||
y: 40,
|
||||
attrs: {
|
||||
label: {
|
||||
text: 'testing测试测试测试thisisaveryveryveryveryveryverylongword jsvascriptjsvascriptjsvascript',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
shape: 'new-rect',
|
||||
id: 'node3',
|
||||
x: 40,
|
||||
y: 100,
|
||||
attrs: {
|
||||
label: {
|
||||
text: '文字文字文字测试测试测试测试',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
shape: 'new-rect',
|
||||
id: 'node4',
|
||||
x: 220,
|
||||
y: 100,
|
||||
attrs: {
|
||||
label: {
|
||||
text: 'asdfghjklasdfghjklasdfghjkl',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 1000,
|
||||
height: 800,
|
||||
grid: true,
|
||||
})
|
||||
|
||||
graph.fromJSON(data)
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Button } from 'antd'
|
||||
import { Graph } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component<
|
||||
Example.Props,
|
||||
Example.State
|
||||
> {
|
||||
private container: HTMLDivElement
|
||||
private history: Graph.HistoryManager
|
||||
|
||||
state: Example.State = {
|
||||
canRedo: false,
|
||||
canUndo: false,
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
history: true,
|
||||
})
|
||||
|
||||
const parent = graph.addNode({
|
||||
x: 100,
|
||||
y: 60,
|
||||
width: 500,
|
||||
height: 140,
|
||||
label: 'Parent Node',
|
||||
})
|
||||
|
||||
this.history = graph.history
|
||||
this.history.on('change', () => {
|
||||
this.setState({
|
||||
canRedo: this.history.canRedo(),
|
||||
canUndo: this.history.canUndo(),
|
||||
})
|
||||
})
|
||||
|
||||
graph.batchUpdate(() => {
|
||||
const child = graph.addNode({
|
||||
x: 160,
|
||||
y: 100,
|
||||
width: 100,
|
||||
height: 40,
|
||||
label: 'Drag Me',
|
||||
})
|
||||
parent.addChild(child)
|
||||
})
|
||||
}
|
||||
|
||||
onUndo = () => {
|
||||
this.history.undo()
|
||||
}
|
||||
|
||||
onRedo = () => {
|
||||
this.history.redo()
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<h1>Default Settings</h1>
|
||||
<div className="x6-graph-tools">
|
||||
<Button.Group>
|
||||
<Button onClick={this.onUndo} disabled={!this.state.canUndo}>
|
||||
Undo
|
||||
</Button>
|
||||
<Button onClick={this.onRedo} disabled={!this.state.canRedo}>
|
||||
Redo
|
||||
</Button>
|
||||
</Button.Group>
|
||||
</div>
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line
|
||||
export namespace Example {
|
||||
export interface Props {}
|
||||
|
||||
export interface State {
|
||||
canUndo: boolean
|
||||
canRedo: boolean
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 400,
|
||||
grid: true,
|
||||
})
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 300, y: 240 },
|
||||
target: { x: 460, y: 240 },
|
||||
attrs: {
|
||||
line: {
|
||||
strokeWidth: 8,
|
||||
// stroke: '#13C2C1',
|
||||
stroke: {
|
||||
type: 'linearGradient',
|
||||
stops: [
|
||||
{ offset: '0%', color: '#13C2C1' },
|
||||
{ offset: '100%', color: '#3366FF' },
|
||||
],
|
||||
},
|
||||
fill: 'none',
|
||||
targetMarker: {
|
||||
name: 'block',
|
||||
size: 15,
|
||||
fill: '#6ED7D8',
|
||||
offset: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
tools: ['target-arrowhead'],
|
||||
})
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 240, y: 40 },
|
||||
target: { x: 40, y: 160 },
|
||||
connector: 'smooth',
|
||||
attrs: {
|
||||
line: {
|
||||
strokeWidth: 8,
|
||||
// stroke: '#13C2C1',
|
||||
stroke: {
|
||||
type: 'linearGradient',
|
||||
stops: [
|
||||
{ offset: '0%', color: '#13C2C1' },
|
||||
{ offset: '100%', color: '#3366FF' },
|
||||
],
|
||||
},
|
||||
fill: 'none',
|
||||
targetMarker: {
|
||||
name: 'block',
|
||||
size: 15,
|
||||
fill: '#6ED7D8',
|
||||
offset: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
tools: ['target-arrowhead'],
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 400,
|
||||
grid: true,
|
||||
})
|
||||
|
||||
graph.addEdge({
|
||||
source: { x: 100, y: 100 },
|
||||
target: { x: 400, y: 100 },
|
||||
vertices: [
|
||||
[160, 160],
|
||||
[340, 160],
|
||||
],
|
||||
attrs: {
|
||||
line: {
|
||||
strokeWidth: 8,
|
||||
// stroke: '#13C2C1',
|
||||
stroke: {
|
||||
type: 'linearGradient',
|
||||
stops: [
|
||||
{ offset: '0%', color: '#13C2C1' },
|
||||
{ offset: '100%', color: '#3366FF' },
|
||||
],
|
||||
},
|
||||
fill: 'none',
|
||||
targetMarker: {
|
||||
name: 'block',
|
||||
size: 15,
|
||||
fill: '#6ED7D8',
|
||||
offset: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
tools: ['button-remove', 'vertices'],
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
rotating: true,
|
||||
resizing: {
|
||||
enabled: true,
|
||||
restricted: true,
|
||||
},
|
||||
translating: {
|
||||
restrict: -20,
|
||||
},
|
||||
scroller: {
|
||||
enabled: true,
|
||||
pannable: true,
|
||||
autoResize: false,
|
||||
pageVisible: true,
|
||||
autoResizeOptions: {
|
||||
border: 20,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
x: 100,
|
||||
y: 80,
|
||||
width: 80,
|
||||
height: 40,
|
||||
angle: 30,
|
||||
})
|
||||
|
||||
graph.addNode({
|
||||
shape: 'ellipse',
|
||||
x: 240,
|
||||
y: 200,
|
||||
width: 80,
|
||||
height: 40,
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Graph, Edge } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 1000,
|
||||
height: 800,
|
||||
grid: true,
|
||||
panning: true,
|
||||
connecting: {
|
||||
allowBlank: false,
|
||||
allowNode: false,
|
||||
// sourceAnchor: 'midSide',
|
||||
// targetAnchor: 'midSide',
|
||||
router: {
|
||||
name: 'er',
|
||||
},
|
||||
connector: {
|
||||
name: 'rounded',
|
||||
args: {
|
||||
radius: 50,
|
||||
},
|
||||
},
|
||||
createEdge({ sourceMagnet }) {
|
||||
const map = {
|
||||
top: 'B',
|
||||
bottom: 'T',
|
||||
left: 'R',
|
||||
right: 'L',
|
||||
}
|
||||
const group = sourceMagnet.getAttribute(
|
||||
'port-group',
|
||||
) as keyof typeof map
|
||||
|
||||
return Edge.create({
|
||||
router: {
|
||||
name: 'er',
|
||||
args: {
|
||||
direction: group ? map[group] : undefined,
|
||||
},
|
||||
},
|
||||
attrs: {
|
||||
line: {
|
||||
strokeDasharray: '5 5',
|
||||
},
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
graph.on('edge:connected', ({ edge }) => {
|
||||
graph.batchUpdate(() => {
|
||||
const { port: sourcePort, ...source } =
|
||||
edge.getSource() as Edge.TerminalCellData
|
||||
const { port: targetPort, ...target } =
|
||||
edge.getTarget() as Edge.TerminalCellData
|
||||
|
||||
edge.removeProp('source')
|
||||
edge.removeProp('target')
|
||||
edge.removeProp('router')
|
||||
edge.attr('line/strokeDasharray', null)
|
||||
|
||||
edge.prop({
|
||||
source,
|
||||
target,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
const rect1 = graph.addNode({
|
||||
x: 100,
|
||||
y: 80,
|
||||
width: 268,
|
||||
height: 100,
|
||||
label: 'hello',
|
||||
ports: {
|
||||
groups: {
|
||||
top: {
|
||||
position: 'top',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
right: {
|
||||
position: 'right',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
bottom: {
|
||||
position: 'bottom',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
left: {
|
||||
position: 'left',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
items: [
|
||||
{
|
||||
id: 'top',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: 'right',
|
||||
group: 'right',
|
||||
},
|
||||
{
|
||||
id: 'bottom',
|
||||
group: 'bottom',
|
||||
},
|
||||
{
|
||||
id: 'left',
|
||||
group: 'left',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
const rect2 = graph.addNode({
|
||||
x: 400,
|
||||
y: 320,
|
||||
width: 268,
|
||||
height: 100,
|
||||
label: 'world',
|
||||
ports: {
|
||||
groups: {
|
||||
top: {
|
||||
position: 'top',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
right: {
|
||||
position: 'right',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
bottom: {
|
||||
position: 'bottom',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
left: {
|
||||
position: 'left',
|
||||
attrs: {
|
||||
circle: {
|
||||
r: 6,
|
||||
magnet: true,
|
||||
stroke: '#31d0c6',
|
||||
strokeWidth: 2,
|
||||
fill: '#fff',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
items: [
|
||||
{
|
||||
id: 'top',
|
||||
group: 'top',
|
||||
},
|
||||
{
|
||||
id: 'right',
|
||||
group: 'right',
|
||||
},
|
||||
{
|
||||
id: 'bottom',
|
||||
group: 'bottom',
|
||||
},
|
||||
{
|
||||
id: 'left',
|
||||
group: 'left',
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
graph.addEdge({
|
||||
source: rect1,
|
||||
target: rect2,
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Graph, Node, NodeView, Point, Angle, Dom, Vector } from '@antv/x6'
|
||||
import { Graph, Node, NodeView } from '@antv/x6'
|
||||
import { Dom, Vector } from '@antv/x6-common'
|
||||
import { Point, Angle } from '@antv/x6-geometry'
|
||||
import '../index.less'
|
||||
|
||||
class ConveyorNode extends Node {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { Graph, Dom, Shape, Node } from '@antv/x6'
|
||||
import { Graph, Shape, Node } from '@antv/x6'
|
||||
import { Dom } from '@antv/x6-common'
|
||||
import { Tooltip } from 'antd'
|
||||
import classnames from 'classnames'
|
||||
import '@antv/x6-react-shape'
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import { Graph, Color } from '@antv/x6'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Color } from '@antv/x6-common'
|
||||
import '@antv/x6-react-shape'
|
||||
import '../index.less'
|
||||
import './ports.less'
|
||||
|
@ -1,5 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Keyboard } from '@antv/x6-plugin-keyboard'
|
||||
import { Selection } from '@antv/x6-plugin-selection'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
@ -11,30 +13,25 @@ export default class Example extends React.Component {
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
keyboard: {
|
||||
enabled: true,
|
||||
global: true,
|
||||
},
|
||||
// resizing: {
|
||||
// enabled: true,
|
||||
// },
|
||||
// rotating: {
|
||||
// enabled: true,
|
||||
// },
|
||||
selecting: {
|
||||
enabled: true,
|
||||
rubberband: true,
|
||||
multiple: true,
|
||||
strict: true,
|
||||
showNodeSelectionBox: true,
|
||||
selectCellOnMoved: false,
|
||||
useCellGeometry: true,
|
||||
filter(cell) {
|
||||
return cell !== a
|
||||
},
|
||||
// content: '123',
|
||||
})
|
||||
|
||||
const keyboard = new Keyboard({
|
||||
enabled: true,
|
||||
})
|
||||
const selection = new Selection({
|
||||
enabled: true,
|
||||
rubberband: true,
|
||||
multiple: true,
|
||||
strict: true,
|
||||
showNodeSelectionBox: true,
|
||||
selectCellOnMoved: false,
|
||||
useCellGeometry: true,
|
||||
filter(cell) {
|
||||
return cell !== a
|
||||
},
|
||||
})
|
||||
graph.use(keyboard)
|
||||
graph.use(selection)
|
||||
|
||||
const a = graph.addNode({
|
||||
x: 50,
|
||||
@ -64,75 +61,12 @@ export default class Example extends React.Component {
|
||||
graph.addEdge({ source: a, target: b })
|
||||
graph.addEdge({ source: b, target: c })
|
||||
|
||||
// graph.toggleMultipleSelection(false)
|
||||
// console.log(graph.isMultipleSelection())
|
||||
|
||||
// graph.on('node:selected', ({ node }) => {
|
||||
// console.log(node)
|
||||
// })
|
||||
|
||||
// graph.on('node:unselected', ({ node }) => {
|
||||
// console.log(node)
|
||||
// })
|
||||
|
||||
// graph.on('selection:changed', ({ selected, added, removed }) => {
|
||||
// console.log(selected, added, removed)
|
||||
// })
|
||||
|
||||
// graph.on('cell:selected', ({ cell }) => {
|
||||
// console.log('selected', cell)
|
||||
// })
|
||||
|
||||
// graph.on('cell:unselected', ({ cell }) => {
|
||||
// console.log('unselected', cell)
|
||||
// })
|
||||
|
||||
// graph.on('node:change:position', ({ node, options }) => {
|
||||
// console.log(node, options)
|
||||
// })
|
||||
|
||||
graph.bindKey('backspace', () => {
|
||||
graph.removeCells(graph.getSelectedCells())
|
||||
keyboard.bindKey('backspace', () => {
|
||||
graph.removeCells(selection.getSelectedCells())
|
||||
})
|
||||
|
||||
// graph.on('blank:mousedown', () => {
|
||||
// console.log('blank:mousedown')
|
||||
// })
|
||||
|
||||
// graph.on('blank:click', () => {
|
||||
// console.log('blank:click')
|
||||
// })
|
||||
|
||||
// graph.on('node:mousedown', args => {
|
||||
// console.log('node:mousedown', args)
|
||||
// })
|
||||
|
||||
// graph.on('node:mousemove', args => {
|
||||
// console.log('node:mousemove', args)
|
||||
// })
|
||||
|
||||
// graph.on('node:mouseup', args => {
|
||||
// console.log('node:mouseup', args)
|
||||
// })
|
||||
|
||||
// graph.on('node:click', args => {
|
||||
// console.log('node:click', args)
|
||||
// })
|
||||
|
||||
// graph.on('node:dblclick', args => {
|
||||
// console.log('node:dblclick', args)
|
||||
// })
|
||||
|
||||
// graph.on('node:contextmenu', args => {
|
||||
// console.log('node:contextmenu', args)
|
||||
// })
|
||||
|
||||
graph.select(a)
|
||||
graph.select([b, c])
|
||||
|
||||
graph.on('cell:removed', (args) => {
|
||||
console.log('cell:removed', args)
|
||||
})
|
||||
selection.select(a)
|
||||
selection.select([b, c])
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
|
@ -1,95 +0,0 @@
|
||||
import React from 'react'
|
||||
import { Graph, Markup, ObjectExt, Dom } from '@antv/x6'
|
||||
import '../index.less'
|
||||
|
||||
Graph.registerNode('xml-node', {}, true)
|
||||
|
||||
const { markup, attrs } = Markup.xml2json(`
|
||||
<g class="rotatable">
|
||||
<g class="scalable">
|
||||
<rect class="card" ref-width="100%" ref-height="100%" rx="10" ry="10" fill="#fff" stroke="#000" stroke-width="0" pointer-events="visiblePainted"/>
|
||||
<image x="16" y="16" width="56" height="56" opacity="0.7"/>
|
||||
</g>
|
||||
<text class="rank" ref-x="0.95" ref-y="0.5" font-family="Courier New" font-size="13" text-anchor="end" text-vertical-anchor="middle"/>
|
||||
<text class="name" ref-x="0.95" ref-y="0.7" font-family="Arial" font-size="14" font-weight="600" text-anchor="end"/>
|
||||
<g class="btn add" ref-dx="-16" ref-y="16" event="node:add">
|
||||
<circle class="add" r="10" fill="transparent" stroke="#333" stroke-width="1"/>
|
||||
<text class="add" x="-5.5" y="7" font-size="20" font-weight="600" font-family="Times New Roman" stroke="#000">+</text>
|
||||
</g>
|
||||
<g class="btn del" ref-dx="-44" ref-y="16" event="node:delete">
|
||||
<circle class="del" r="10" fill="transparent" stroke="#333" stroke-width="1"/>
|
||||
<text class="del" x="-4.5" y="6" font-size="28" font-weight="600" font-family="Times New Roman" stroke="#000">-</text>
|
||||
</g>
|
||||
</g>
|
||||
`)
|
||||
|
||||
const male =
|
||||
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*kUy8SrEDp6YAAAAAAAAAAAAAARQnAQ'
|
||||
const female =
|
||||
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*f6hhT75YjkIAAAAAAAAAAAAAARQnAQ'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
private container: HTMLDivElement
|
||||
|
||||
componentDidMount() {
|
||||
const graph = new Graph({
|
||||
container: this.container,
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
panning: true,
|
||||
})
|
||||
|
||||
console.log(markup, attrs)
|
||||
|
||||
graph.addNode({
|
||||
x: 100,
|
||||
y: 100,
|
||||
width: 260,
|
||||
height: 88,
|
||||
shape: 'xml-node',
|
||||
markup,
|
||||
attrs: ObjectExt.merge(attrs, {
|
||||
'.card': {
|
||||
fill: '#31d0c6',
|
||||
},
|
||||
image: {
|
||||
xlinkHref: Math.random() < 0.5 ? male : female,
|
||||
},
|
||||
'.rank': {
|
||||
text: Dom.breakText('President, Ebay Global Marketplaces', {
|
||||
width: 160,
|
||||
height: 45,
|
||||
}),
|
||||
},
|
||||
'.name': {
|
||||
text: Dom.breakText('Devin Wenig', { width: 160, height: 45 }),
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
||||
graph.on('node:add', () => {
|
||||
alert('add click')
|
||||
})
|
||||
|
||||
graph.on('node:delete', () => {
|
||||
alert('delete click')
|
||||
})
|
||||
|
||||
graph.on('node:click', () => {
|
||||
alert('node click')
|
||||
})
|
||||
}
|
||||
|
||||
refContainer = (container: HTMLDivElement) => {
|
||||
this.container = container
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="x6-graph-wrap">
|
||||
<div ref={this.refContainer} className="x6-graph" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { Snapline } from '@antv/x6-plugin-snapline'
|
||||
import '../index.less'
|
||||
|
||||
export default class Example extends React.Component {
|
||||
@ -11,9 +12,14 @@ export default class Example extends React.Component {
|
||||
width: 800,
|
||||
height: 600,
|
||||
grid: true,
|
||||
snapline: true,
|
||||
})
|
||||
|
||||
const snapline = new Snapline({
|
||||
enabled: true,
|
||||
sharp: true,
|
||||
})
|
||||
graph.use(snapline)
|
||||
|
||||
graph.addNode({
|
||||
shape: 'rect',
|
||||
x: 50,
|
||||
|
10
lerna.json
10
lerna.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2.0.6-beta.7",
|
||||
"version": "2.0.6-beta.22",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
@ -25,11 +25,5 @@
|
||||
"pr(test)": ":white_check_mark: Test Case"
|
||||
}
|
||||
},
|
||||
"packages": [
|
||||
"packages/x6-common",
|
||||
"packages/x6-geometry",
|
||||
"packages/x6",
|
||||
"packages/x6-react-shape",
|
||||
"packages/x6-vue-shape"
|
||||
]
|
||||
"packages": ["packages/*"]
|
||||
}
|
||||
|
@ -26,9 +26,8 @@
|
||||
"package:inherit": "yarn package-inherit update",
|
||||
"prepare": "is-ci || husky install configs/husky-config",
|
||||
"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"
|
||||
"publish:latest": "yarn build:dev && lerna publish --no-private --ignore-scripts",
|
||||
"publish:beta": "yarn build:dev && lerna publish --no-private --ignore-scripts --dist-tag=beta"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*.{js,jsx,tsx,ts,less,md,json}": [
|
||||
|
@ -1 +0,0 @@
|
||||
export * from './src'
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-common",
|
||||
"version": "2.0.6-beta.3",
|
||||
"version": "2.0.6-beta.18",
|
||||
"description": "Basic toolkit for x6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Color } from '../../src/color'
|
||||
import { Color } from '../../color'
|
||||
|
||||
describe('Color', () => {
|
||||
describe('#constructor', () => {
|
@ -3,7 +3,7 @@ import {
|
||||
IDisposable,
|
||||
DisposableSet,
|
||||
DisposableDelegate,
|
||||
} from '../../src/common/disposable'
|
||||
} from '../../common/disposable'
|
||||
|
||||
class TestDisposable implements IDisposable {
|
||||
count = 0
|
@ -1,5 +1,5 @@
|
||||
import sinon from 'sinon'
|
||||
import { DataUri } from '../../src/datauri'
|
||||
import { DataUri } from '../../datauri'
|
||||
|
||||
describe('DataUri', () => {
|
||||
describe('#isDataUrl', () => {
|
@ -1,5 +1,5 @@
|
||||
import sinon from 'sinon'
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
describe('af', () => {
|
||||
describe('#requestAnimationFrame', () => {
|
@ -1,5 +1,5 @@
|
||||
import { Vector } from '../../src/vector'
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Vector } from '../../vector'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
describe('Dom', () => {
|
||||
describe('attr', () => {
|
4
packages/x6-common/__tests__/dom/class.test.ts → packages/x6-common/src/__tests__/dom/class.test.ts
4
packages/x6-common/__tests__/dom/class.test.ts → packages/x6-common/src/__tests__/dom/class.test.ts
@ -1,5 +1,5 @@
|
||||
import { Vector } from '../../src/vector'
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Vector } from '../../vector'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
describe('Dom', () => {
|
||||
describe('class', () => {
|
@ -1,5 +1,5 @@
|
||||
import { Vector } from '../../src/vector'
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Vector } from '../../vector'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
describe('Dom', () => {
|
||||
describe('css', () => {
|
@ -1,6 +1,6 @@
|
||||
import { Vector } from '../../src/vector'
|
||||
import { Dom } from '../../src/dom'
|
||||
import { ObjectExt } from '../../src/object'
|
||||
import { Vector } from '../../vector'
|
||||
import { Dom } from '../../dom'
|
||||
import { ObjectExt } from '../../object'
|
||||
|
||||
describe('Dom', () => {
|
||||
describe('data', () => {
|
@ -1,5 +1,5 @@
|
||||
import { Vector } from '../../src/vector'
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Vector } from '../../vector'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
const wrap = document.createElement('div')
|
||||
const svgContent =
|
7
packages/x6-common/__tests__/dom/event.test.ts → packages/x6-common/src/__tests__/dom/event.test.ts
7
packages/x6-common/__tests__/dom/event.test.ts → packages/x6-common/src/__tests__/dom/event.test.ts
@ -1,6 +1,6 @@
|
||||
import sinon from 'sinon'
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Core } from '../../src/dom/event/core'
|
||||
import { Dom } from '../../dom'
|
||||
import { Core } from '../../dom/event/core'
|
||||
// import { Hook } from './hook'
|
||||
|
||||
describe('EventDom', () => {
|
||||
@ -30,7 +30,7 @@ describe('EventDom', () => {
|
||||
return this
|
||||
}
|
||||
|
||||
once(p1: any, p2?: any, p3?: any, p4?: any, p5?: any) {
|
||||
once(p1: any, p2?: any, p3?: any, p4?: any) {
|
||||
Dom.Event.once(this.node, p1, p2, p3, p4)
|
||||
return this
|
||||
}
|
||||
@ -610,7 +610,6 @@ describe('EventDom', () => {
|
||||
expect(spy2.callCount).toEqual(0)
|
||||
})
|
||||
|
||||
// Todo Error: Expected 2 to equal 1.
|
||||
// it('should apply hook to prevent window to unload', () => {
|
||||
// const win = new EventDom(window as any)
|
||||
// const spy1 = sinon.spy(() => {
|
@ -1,5 +1,5 @@
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Vector } from '../../src/vector'
|
||||
import { Dom } from '../../dom'
|
||||
import { Vector } from '../../vector'
|
||||
|
||||
describe('Dom', () => {
|
||||
describe('matrix', () => {
|
@ -1,5 +1,5 @@
|
||||
import { Vector } from '../../src/vector'
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Vector } from '../../vector'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
describe('Dom', () => {
|
||||
describe('path', () => {
|
@ -1,4 +1,4 @@
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
describe('Dom', () => {
|
||||
describe('#prefix', () => {
|
@ -1,4 +1,4 @@
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
describe('Dom', () => {
|
||||
describe('#clearSelection', () => {
|
2
packages/x6-common/__tests__/dom/style.test.ts → packages/x6-common/src/__tests__/dom/style.test.ts
2
packages/x6-common/__tests__/dom/style.test.ts → packages/x6-common/src/__tests__/dom/style.test.ts
@ -1,4 +1,4 @@
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
describe('Dom', () => {
|
||||
describe('#setPrefixedStyle', () => {
|
@ -1,5 +1,5 @@
|
||||
import { Vector } from '../../src/vector'
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Vector } from '../../vector'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
describe('Dom', () => {
|
||||
describe('#text', () => {
|
@ -1,5 +1,5 @@
|
||||
import { Vector } from '../../src/vector'
|
||||
import { Dom } from '../../src/dom'
|
||||
import { Vector } from '../../vector'
|
||||
import { Dom } from '../../dom'
|
||||
|
||||
describe('Dom', () => {
|
||||
const fixture = document.createElement('div')
|
@ -1,5 +1,5 @@
|
||||
import sinon from 'sinon'
|
||||
import { Events } from '../../src/event'
|
||||
import { Events } from '../../event'
|
||||
|
||||
describe('events', () => {
|
||||
it('should trigger with context', () => {
|
@ -1,4 +1,4 @@
|
||||
import { FunctionExt } from '../../src/function'
|
||||
import { FunctionExt } from '../../function'
|
||||
|
||||
describe('async', () => {
|
||||
describe('#toDeferredBoolean', () => {
|
@ -1,5 +1,5 @@
|
||||
import sinon from 'sinon'
|
||||
import { FunctionExt } from '../../src/function'
|
||||
import { FunctionExt } from '../../function'
|
||||
|
||||
describe('FunctionExt', () => {
|
||||
describe('#call', () => {
|
@ -1,4 +1,4 @@
|
||||
import { JSONArray, JSONExt, JSONObject, JSONPrimitive } from '../../src/json'
|
||||
import { JSONArray, JSONExt, JSONObject, JSONPrimitive } from '../../json'
|
||||
|
||||
describe('JSONExt', () => {
|
||||
describe('isPrimitive()', () => {
|
@ -1,4 +1,4 @@
|
||||
import { NumberExt } from '../../src/number'
|
||||
import { NumberExt } from '../../number'
|
||||
|
||||
describe('NumberExt', () => {
|
||||
describe('#mod', () => {
|
@ -1,4 +1,4 @@
|
||||
import { ObjectExt } from '../../src/object'
|
||||
import { ObjectExt } from '../../object'
|
||||
|
||||
describe('object', () => {
|
||||
class Parent {
|
@ -1,4 +1,4 @@
|
||||
import { ObjectExt } from '../../src/object'
|
||||
import { ObjectExt } from '../../object'
|
||||
|
||||
describe('Ojbect', () => {
|
||||
describe('applyMixins', () => {
|
@ -1,4 +1,4 @@
|
||||
import { ObjectExt } from '../../src/object'
|
||||
import { ObjectExt } from '../../object'
|
||||
|
||||
describe('Object', () => {
|
||||
const obj = {
|
@ -1,4 +1,4 @@
|
||||
import { StringExt } from '../../src/string'
|
||||
import { StringExt } from '../../string'
|
||||
|
||||
describe('String', () => {
|
||||
describe('#format', () => {
|
@ -1,4 +1,4 @@
|
||||
import { StringExt } from '../../src/string'
|
||||
import { StringExt } from '../../string'
|
||||
|
||||
describe('StringExt', () => {
|
||||
describe('#StringExt.hashcode', () => {
|
@ -1,4 +1,4 @@
|
||||
import { StringExt } from '../../src/string'
|
||||
import { StringExt } from '../../string'
|
||||
|
||||
describe('String', () => {
|
||||
describe('#getSpellingSuggestion', () => {
|
@ -1,4 +1,4 @@
|
||||
import { StringExt } from '../../src/string'
|
||||
import { StringExt } from '../../string'
|
||||
|
||||
describe('string', () => {
|
||||
describe('#uuid', () => {
|
@ -1,4 +1,4 @@
|
||||
import { Text } from '../../src/text'
|
||||
import { Text } from '../../text'
|
||||
|
||||
describe('Text', () => {
|
||||
describe('#annotate', () => {
|
@ -1,4 +1,4 @@
|
||||
import { Text } from '../../src/text'
|
||||
import { Text } from '../../text'
|
||||
|
||||
describe('Text', () => {
|
||||
describe('#sanitize', () => {
|
@ -1,4 +1,4 @@
|
||||
import { Unit } from '../../src'
|
||||
import { Unit } from '../..'
|
||||
|
||||
describe('Unit', () => {
|
||||
describe('#toPx', () => {
|
@ -1,4 +1,4 @@
|
||||
import { Vector } from '../../src/vector'
|
||||
import { Vector } from '../../vector'
|
||||
|
||||
describe('Vector', () => {
|
||||
describe('#create', () => {
|
@ -154,9 +154,14 @@ export function contains(parent: Element, child: Element) {
|
||||
)
|
||||
}
|
||||
|
||||
export function remove(elem: Element) {
|
||||
if (elem.parentNode) {
|
||||
elem.parentNode.removeChild(elem)
|
||||
export function remove(elem: Element | Element[] | null) {
|
||||
if (elem) {
|
||||
const elems = Array.isArray(elem) ? elem : [elem]
|
||||
elems.forEach((item) => {
|
||||
if (item.parentNode) {
|
||||
item.parentNode.removeChild(item)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,3 +244,18 @@ export function isHTMLElement(elem: any): elem is HTMLElement {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export function children(parent: Element, className?: string) {
|
||||
const matched: Element[] = []
|
||||
let elem = parent.firstChild
|
||||
|
||||
for (; elem; elem = elem.nextSibling) {
|
||||
if (elem.nodeType === 1) {
|
||||
if (!className || hasClass(elem as Element, className)) {
|
||||
matched.push(elem as Element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matched
|
||||
}
|
||||
|
@ -19,3 +19,6 @@ export * from './transform'
|
||||
// event
|
||||
export * from './event'
|
||||
export * from './mousewheel'
|
||||
|
||||
// postion
|
||||
export * from './position'
|
||||
|
19
packages/x6-common/src/dom/position.ts
Normal file
19
packages/x6-common/src/dom/position.ts
Normal file
@ -0,0 +1,19 @@
|
||||
export function offset(elem: Element) {
|
||||
const rect = elem.getBoundingClientRect()
|
||||
const win = elem.ownerDocument.defaultView!
|
||||
|
||||
return {
|
||||
top: rect.top + win.pageYOffset,
|
||||
left: rect.left + win.pageXOffset,
|
||||
}
|
||||
}
|
||||
|
||||
export function width(elem: Element) {
|
||||
const rect = elem.getBoundingClientRect()
|
||||
return rect.width
|
||||
}
|
||||
|
||||
export function height(elem: Element) {
|
||||
const rect = elem.getBoundingClientRect()
|
||||
return rect.height
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './src'
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2.0.6-beta.2",
|
||||
"version": "2.0.6-beta.18",
|
||||
"name": "@antv/x6-geometry",
|
||||
"description": "Geometry operations for x6.",
|
||||
"main": "lib/index.js",
|
||||
|
5
packages/x6-geometry/__tests__/ellipse.test.ts → packages/x6-geometry/src/__tests__/ellipse.test.ts
5
packages/x6-geometry/__tests__/ellipse.test.ts → packages/x6-geometry/src/__tests__/ellipse.test.ts
@ -1,7 +1,4 @@
|
||||
import { Ellipse } from '../src'
|
||||
import { Line } from '../src'
|
||||
import { Point } from '../src'
|
||||
import { Rectangle } from '../src'
|
||||
import { Ellipse, Line, Point, Rectangle } from '..'
|
||||
|
||||
describe('ellipse', () => {
|
||||
describe('#constructor', () => {
|
@ -1,6 +1,4 @@
|
||||
import { Line } from '../src'
|
||||
import { Point } from '../src'
|
||||
import { Rectangle } from '../src'
|
||||
import { Line, Point, Rectangle } from '..'
|
||||
|
||||
describe('Line', () => {
|
||||
describe('#constructor', () => {
|
@ -1,5 +1,4 @@
|
||||
import { Path } from '../../src/path'
|
||||
import { normalizePathData } from '../../src/path'
|
||||
import { Path, normalizePathData } from '../../path'
|
||||
|
||||
describe('Path', () => {
|
||||
describe('#normalizePathData', () => {
|
@ -1,4 +1,4 @@
|
||||
import { Point } from '../src'
|
||||
import { Point } from '..'
|
||||
|
||||
describe('Point', () => {
|
||||
describe('#constructor', () => {
|
@ -1,6 +1,4 @@
|
||||
import { Line } from '../src'
|
||||
import { Point } from '../src'
|
||||
import { Polyline } from '../src'
|
||||
import { Line, Point, Polyline } from '..'
|
||||
|
||||
describe('Polyline', () => {
|
||||
describe('#constructor', () => {
|
@ -1,7 +1,4 @@
|
||||
import { Ellipse } from '../src'
|
||||
import { Line } from '../src'
|
||||
import { Point } from '../src'
|
||||
import { Rectangle } from '../src'
|
||||
import { Ellipse, Line, Point, Rectangle } from '..'
|
||||
|
||||
describe('rectangle', () => {
|
||||
describe('#constructor', () => {
|
@ -1 +0,0 @@
|
||||
export * from './src'
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-keyboard",
|
||||
"version": "2.0.6-beta.7",
|
||||
"version": "2.0.6-beta.20",
|
||||
"description": "keyboard plugin for X6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -33,6 +33,7 @@
|
||||
"build": "run-p build:dev build:umd",
|
||||
"prebuild": "run-s lint clean",
|
||||
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
|
||||
"test": "echo \"no test case\"",
|
||||
"pretest": "run-p clean:coverage",
|
||||
"prepare": "run-s test build",
|
||||
"precommit": "lint-staged"
|
||||
@ -104,7 +105,7 @@
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/antvis/x6.git",
|
||||
"directory": "packages/x6-common"
|
||||
"directory": "packages/x6-plugin-keyboard"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
@ -3,31 +3,33 @@ import { Graph } from '@antv/x6'
|
||||
import { KeyboardImpl } from './keyboard'
|
||||
|
||||
export class Keyboard extends Disposable {
|
||||
private keyboardImpl: KeyboardImpl
|
||||
public name = 'keyboard'
|
||||
private keyboard: KeyboardImpl
|
||||
|
||||
constructor(public readonly options: KeyboardImpl.Options) {
|
||||
super()
|
||||
}
|
||||
|
||||
public init(graph: Graph) {
|
||||
this.keyboard = new KeyboardImpl({
|
||||
init(graph: Graph) {
|
||||
this.keyboardImpl = new KeyboardImpl({
|
||||
...this.options,
|
||||
graph,
|
||||
})
|
||||
}
|
||||
|
||||
// #region api
|
||||
|
||||
isKeyboardEnabled() {
|
||||
return !this.keyboard.disabled
|
||||
return !this.keyboardImpl.disabled
|
||||
}
|
||||
|
||||
enableKeyboard() {
|
||||
this.keyboard.enable()
|
||||
this.keyboardImpl.enable()
|
||||
return this
|
||||
}
|
||||
|
||||
disableKeyboard() {
|
||||
this.keyboard.disable()
|
||||
this.keyboardImpl.disable()
|
||||
return this
|
||||
}
|
||||
|
||||
@ -53,17 +55,19 @@ export class Keyboard extends Disposable {
|
||||
callback: KeyboardImpl.Handler,
|
||||
action?: KeyboardImpl.Action,
|
||||
) {
|
||||
this.keyboard.on(keys, callback, action)
|
||||
this.keyboardImpl.on(keys, callback, action)
|
||||
return this
|
||||
}
|
||||
|
||||
unbindKey(keys: string | string[], action?: KeyboardImpl.Action) {
|
||||
this.keyboard.off(keys, action)
|
||||
this.keyboardImpl.off(keys, action)
|
||||
return this
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
@Disposable.dispose()
|
||||
dispose() {
|
||||
this.keyboard.dispose()
|
||||
this.keyboardImpl.dispose()
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ export class KeyboardImpl extends Disposable implements IDisablable {
|
||||
}
|
||||
|
||||
protected isGraphEvent(e: KeyboardEvent) {
|
||||
const target = (e.srcElement || e.target) as Element
|
||||
const target = e.target as Element
|
||||
const currentTarget = e.currentTarget as Element
|
||||
if (target) {
|
||||
if (
|
||||
|
@ -1 +0,0 @@
|
||||
export * from './src'
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-scroller",
|
||||
"version": "2.0.6-beta.7",
|
||||
"version": "2.0.6-beta.21",
|
||||
"description": "scroller plugin for X6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -34,6 +34,7 @@
|
||||
"build": "run-p build:dev build:umd",
|
||||
"prebuild": "run-s lint clean",
|
||||
"coveralls": "cat ./test/coverage/lcov.info | coveralls",
|
||||
"test": "echo \"no test case\"",
|
||||
"pretest": "run-p clean:coverage",
|
||||
"prepare": "run-s test build",
|
||||
"precommit": "lint-staged"
|
||||
@ -101,7 +102,7 @@
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/antvis/x6.git",
|
||||
"directory": "packages/x6-common"
|
||||
"directory": "packages/x6-plugin-scroller"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
@ -11,11 +11,11 @@ import { ScrollerImpl } from './scroller'
|
||||
import { content } from './style/raw'
|
||||
|
||||
export class Scroller extends Disposable {
|
||||
public name = 'scroller'
|
||||
private graph: Graph
|
||||
private scrollerImpl: ScrollerImpl
|
||||
public name = 'scroller'
|
||||
|
||||
private get pannable() {
|
||||
public get pannable() {
|
||||
if (this.options) {
|
||||
if (typeof this.options.pannable === 'object') {
|
||||
return this.options.pannable.enabled
|
||||
@ -26,13 +26,18 @@ export class Scroller extends Disposable {
|
||||
return false
|
||||
}
|
||||
|
||||
public get container() {
|
||||
return this.scrollerImpl.container
|
||||
}
|
||||
|
||||
constructor(public readonly options: Scroller.Options) {
|
||||
super()
|
||||
}
|
||||
|
||||
public init(graph: Graph) {
|
||||
this.graph = graph
|
||||
CssLoader.ensure('scroller', content)
|
||||
CssLoader.ensure(this.name, content)
|
||||
|
||||
this.scrollerImpl = new ScrollerImpl({
|
||||
...this.options,
|
||||
graph,
|
||||
@ -42,92 +47,16 @@ export class Scroller extends Disposable {
|
||||
this.scrollerImpl.center()
|
||||
}
|
||||
|
||||
private 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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private 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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private 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))
|
||||
}
|
||||
}
|
||||
|
||||
private 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))
|
||||
}
|
||||
}
|
||||
|
||||
private allowPanning(e: Dom.MouseDownEvent, strict?: boolean) {
|
||||
return (
|
||||
this.pannable && ModifierKey.isMatch(e, this.options.modifiers, strict)
|
||||
)
|
||||
}
|
||||
|
||||
private 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)
|
||||
}
|
||||
}
|
||||
// #region api
|
||||
|
||||
resize(width?: number, height?: number) {
|
||||
this.scrollerImpl.resize(width, height)
|
||||
}
|
||||
|
||||
resizePage(width?: number, height?: number) {
|
||||
this.scrollerImpl.updatePageSize(width, height)
|
||||
}
|
||||
|
||||
zoom(): number
|
||||
zoom(factor: number, options?: TransformManager.ZoomOptions): this
|
||||
zoom(factor?: number, options?: TransformManager.ZoomOptions) {
|
||||
@ -354,11 +283,98 @@ export class Scroller extends Disposable {
|
||||
this.scrollerImpl.disableAutoResize()
|
||||
}
|
||||
|
||||
autoScroll(clientX: number, clientY: number) {
|
||||
return this.scrollerImpl.autoScroll(clientX, clientY)
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
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 = selection && selection.allowRubberband(e, true)
|
||||
if (allowPanning || (this.allowPanning(e) && !allowRubberband)) {
|
||||
this.updateClassName(true)
|
||||
this.scrollerImpl.startPanning(e)
|
||||
this.scrollerImpl.once('pan:stop', () => this.updateClassName(false))
|
||||
}
|
||||
}
|
||||
|
||||
protected 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)
|
||||
}
|
||||
}
|
||||
|
||||
@Disposable.dispose()
|
||||
dispose() {
|
||||
this.scrollerImpl.dispose()
|
||||
this.stopListening()
|
||||
CssLoader.clean('scroller')
|
||||
CssLoader.clean(this.name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ export class ScrollerImpl extends View {
|
||||
super()
|
||||
|
||||
this.options = ScrollerImpl.getOptions(options)
|
||||
this.onUpdate = FunctionExt.debounce(this.onUpdate, 200)
|
||||
|
||||
const scale = this.graph.transform.getScale()
|
||||
this.sx = scale.sx
|
||||
@ -79,31 +80,6 @@ export class ScrollerImpl extends View {
|
||||
Dom.before(graphContainer, this.container)
|
||||
}
|
||||
|
||||
// todo copy style
|
||||
// const style = graphContainer.getAttribute('style')
|
||||
// if (style) {
|
||||
// const obj: { [name: string]: string } = {}
|
||||
// const styles = style.split(';')
|
||||
// styles.forEach((item) => {
|
||||
// const section = item.trim()
|
||||
// if (section) {
|
||||
// const pair = section.split(':')
|
||||
// if (pair.length) {
|
||||
// obj[pair[0].trim()] = pair[1] ? pair[1].trim() : ''
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
// Object.keys(obj).forEach((key: any) => {
|
||||
// if (key === 'width' || key === 'height') {
|
||||
// return
|
||||
// }
|
||||
|
||||
// graphContainer.style[key] = ''
|
||||
// this.container.style[key] = obj[key]
|
||||
// })
|
||||
// }
|
||||
|
||||
this.content = document.createElement('div')
|
||||
Dom.addClass(this.content, this.prefixClassName(ScrollerImpl.contentClass))
|
||||
Dom.css(this.content, {
|
||||
@ -185,11 +161,9 @@ export class ScrollerImpl extends View {
|
||||
}
|
||||
|
||||
protected onUpdate() {
|
||||
if (!this.options.autoResize) {
|
||||
return
|
||||
if (this.options.autoResize) {
|
||||
this.update()
|
||||
}
|
||||
|
||||
this.update()
|
||||
}
|
||||
|
||||
protected delegateBackgroundEvents(events?: View.Events) {
|
||||
@ -381,76 +355,12 @@ export class ScrollerImpl extends View {
|
||||
gridWidth: this.options.pageWidth,
|
||||
gridHeight: this.options.pageHeight,
|
||||
allowNewOrigin: 'negative',
|
||||
contentArea: this.calcContextArea(resizeOptions),
|
||||
...resizeOptions,
|
||||
}
|
||||
|
||||
this.graph.fitToContent(this.getFitToContentOptions(options))
|
||||
}
|
||||
|
||||
protected calcContextArea(
|
||||
resizeOptions:
|
||||
| (TransformManager.FitToContentFullOptions & {
|
||||
direction:
|
||||
| ScrollerImpl.AutoResizeDirection
|
||||
| ScrollerImpl.AutoResizeDirection[]
|
||||
})
|
||||
| undefined,
|
||||
) {
|
||||
const direction = resizeOptions?.direction
|
||||
|
||||
if (!direction) {
|
||||
return this.graph.transform.getContentArea({ useCellGeometry: true })
|
||||
}
|
||||
|
||||
function getCellBBox(cell: Cell) {
|
||||
let rect = cell.getBBox()
|
||||
if (rect) {
|
||||
if (cell.isNode()) {
|
||||
const angle = cell.getAngle()
|
||||
if (angle != null && angle !== 0) {
|
||||
rect = rect.bbox(angle)
|
||||
}
|
||||
}
|
||||
}
|
||||
return rect
|
||||
}
|
||||
|
||||
const gridWidth = this.options.pageWidth || 1
|
||||
const gridHeight = this.options.pageHeight || 1
|
||||
let calculativeCells = this.graph.getCells()
|
||||
|
||||
if (!direction.includes('top')) {
|
||||
calculativeCells = calculativeCells.filter((cell) => {
|
||||
const bbox = getCellBBox(cell)
|
||||
return bbox.y >= 0
|
||||
})
|
||||
}
|
||||
|
||||
if (!direction.includes('left')) {
|
||||
calculativeCells = calculativeCells.filter((cell) => {
|
||||
const bbox = getCellBBox(cell)
|
||||
return bbox.x >= 0
|
||||
})
|
||||
}
|
||||
|
||||
if (!direction.includes('right')) {
|
||||
calculativeCells = calculativeCells.filter((cell) => {
|
||||
const bbox = getCellBBox(cell)
|
||||
return bbox.x + bbox.width <= gridWidth
|
||||
})
|
||||
}
|
||||
|
||||
if (!direction.includes('bottom')) {
|
||||
calculativeCells = calculativeCells.filter((cell) => {
|
||||
const bbox = getCellBBox(cell)
|
||||
return bbox.y + bbox.height <= gridHeight
|
||||
})
|
||||
}
|
||||
|
||||
return this.model.getCellsBBox(calculativeCells) || new Rectangle()
|
||||
}
|
||||
|
||||
protected getFitToContentOptions(
|
||||
options: TransformManager.FitToContentFullOptions,
|
||||
) {
|
||||
|
21
packages/x6-plugin-selection/LICENSE
Normal file
21
packages/x6-plugin-selection/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-selection/README.md
Normal file
5
packages/x6-plugin-selection/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# `x6-plugin-selection`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
112
packages/x6-plugin-selection/package.json
Normal file
112
packages/x6-plugin-selection/package.json
Normal file
@ -0,0 +1,112 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-selection",
|
||||
"version": "2.0.6-beta.22",
|
||||
"description": "selection plugin for X6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"unpkg": "dist/x6-plugin-selection.js",
|
||||
"jsdelivr": "dist/x6-plugin-selection.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"es",
|
||||
"lib"
|
||||
],
|
||||
"keywords": [
|
||||
"plugin",
|
||||
"selection",
|
||||
"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",
|
||||
"test": "echo \"no test case\"",
|
||||
"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": ">=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-plugin-selection"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
}
|
18
packages/x6-plugin-selection/rollup.config.js
Normal file
18
packages/x6-plugin-selection/rollup.config.js
Normal file
@ -0,0 +1,18 @@
|
||||
import config from '../../configs/rollup-config'
|
||||
|
||||
export default config({
|
||||
output: [
|
||||
{
|
||||
name: 'X6PluginSelection',
|
||||
format: 'umd',
|
||||
file: 'dist/x6-plugin-selection.js',
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
'@antv/x6': 'X6',
|
||||
'@antv/x6-common': 'X6Common',
|
||||
'@antv/x6-geometry': 'X6Geometry',
|
||||
},
|
||||
},
|
||||
],
|
||||
external: ['@antv/x6', '@antv/x6-common', '@antv/x6-geometry'],
|
||||
})
|
85
packages/x6-plugin-selection/scripts/style.js
Normal file
85
packages/x6-plugin-selection/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, 'selection.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, 'selection.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()
|
78
packages/x6-plugin-selection/src/index.less
Normal file
78
packages/x6-plugin-selection/src/index.less
Normal file
@ -0,0 +1,78 @@
|
||||
@selection-prefix-cls: ~'x6-widget-selection';
|
||||
|
||||
.@{selection-prefix-cls} {
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
touch-action: none;
|
||||
|
||||
&-rubberband {
|
||||
display: block;
|
||||
overflow: visible;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
&-selected {
|
||||
display: block;
|
||||
}
|
||||
|
||||
&-box {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
&-inner[data-selection-length='0'],
|
||||
&-inner[data-selection-length='1'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-content {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: -20px;
|
||||
left: -20px;
|
||||
margin-top: 30px;
|
||||
padding: 6px;
|
||||
line-height: 14px;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// theme
|
||||
.@{selection-prefix-cls} {
|
||||
&-rubberband {
|
||||
background-color: #3498db;
|
||||
border: 2px solid #2980b9;
|
||||
}
|
||||
|
||||
&-box {
|
||||
box-sizing: content-box !important;
|
||||
margin-top: -4px;
|
||||
margin-left: -4px;
|
||||
padding-right: 4px;
|
||||
padding-bottom: 4px;
|
||||
border: 2px dashed #feb663;
|
||||
box-shadow: 2px 2px 5px #d3d3d3;
|
||||
}
|
||||
|
||||
&-inner {
|
||||
box-sizing: content-box !important;
|
||||
margin-top: -8px;
|
||||
margin-left: -8px;
|
||||
padding-right: 12px;
|
||||
padding-bottom: 12px;
|
||||
border: 2px solid #feb663;
|
||||
box-shadow: 2px 2px 5px #d3d3d3;
|
||||
}
|
||||
|
||||
&-content {
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
background-color: #6a6b8a;
|
||||
}
|
||||
}
|
488
packages/x6-plugin-selection/src/index.ts
Normal file
488
packages/x6-plugin-selection/src/index.ts
Normal file
@ -0,0 +1,488 @@
|
||||
import {
|
||||
Disposable,
|
||||
ModifierKey,
|
||||
CssLoader,
|
||||
Dom,
|
||||
ObjectExt,
|
||||
} from '@antv/x6-common'
|
||||
import { Cell, EventArgs, Graph } from '@antv/x6'
|
||||
import { SelectionImpl } from './selection'
|
||||
import { content } from './style/raw'
|
||||
|
||||
export class Selection extends Disposable {
|
||||
private graph: Graph
|
||||
private selectionImpl: SelectionImpl
|
||||
private readonly options: Selection.Options
|
||||
private movedMap = new WeakMap<Cell, boolean>()
|
||||
private unselectMap = new WeakMap<Cell, boolean>()
|
||||
public name = 'selection'
|
||||
|
||||
private get rubberbandDisabled() {
|
||||
return this.options.enabled !== true || this.options.rubberband !== true
|
||||
}
|
||||
|
||||
public get disabled() {
|
||||
return this.options.enabled !== true
|
||||
}
|
||||
|
||||
public get length() {
|
||||
return this.selectionImpl.length
|
||||
}
|
||||
|
||||
public get cells() {
|
||||
return this.selectionImpl.cells
|
||||
}
|
||||
|
||||
constructor(options: Selection.Options) {
|
||||
super()
|
||||
this.options = ObjectExt.merge({}, Selection.defaultOptions, options)
|
||||
}
|
||||
|
||||
public init(graph: Graph) {
|
||||
this.graph = graph
|
||||
CssLoader.ensure(this.name, content)
|
||||
this.selectionImpl = new SelectionImpl({
|
||||
...this.options,
|
||||
graph,
|
||||
})
|
||||
this.startListening()
|
||||
}
|
||||
|
||||
// #region api
|
||||
|
||||
isSelectionEnabled() {
|
||||
return !this.disabled
|
||||
}
|
||||
|
||||
enableSelection() {
|
||||
this.enable()
|
||||
return this
|
||||
}
|
||||
|
||||
disableSelection() {
|
||||
this.disable()
|
||||
return this
|
||||
}
|
||||
|
||||
toggleSelection(enabled?: boolean) {
|
||||
if (enabled != null) {
|
||||
if (enabled !== this.isSelectionEnabled()) {
|
||||
if (enabled) {
|
||||
this.enableSelection()
|
||||
} else {
|
||||
this.disableSelection()
|
||||
}
|
||||
}
|
||||
} else if (this.isSelectionEnabled()) {
|
||||
this.disableSelection()
|
||||
} else {
|
||||
this.enableSelection()
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
isMultipleSelection() {
|
||||
return this.isMultiple()
|
||||
}
|
||||
|
||||
enableMultipleSelection() {
|
||||
this.enableMultiple()
|
||||
return this
|
||||
}
|
||||
|
||||
disableMultipleSelection() {
|
||||
this.disableMultiple()
|
||||
return this
|
||||
}
|
||||
|
||||
toggleMultipleSelection(multiple?: boolean) {
|
||||
if (multiple != null) {
|
||||
if (multiple !== this.isMultipleSelection()) {
|
||||
if (multiple) {
|
||||
this.enableMultipleSelection()
|
||||
} else {
|
||||
this.disableMultipleSelection()
|
||||
}
|
||||
}
|
||||
} else if (this.isMultipleSelection()) {
|
||||
this.disableMultipleSelection()
|
||||
} else {
|
||||
this.enableMultipleSelection()
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
isSelectionMovable() {
|
||||
return this.options.movable !== false
|
||||
}
|
||||
|
||||
enableSelectionMovable() {
|
||||
this.selectionImpl.options.movable = true
|
||||
return this
|
||||
}
|
||||
|
||||
disableSelectionMovable() {
|
||||
this.selectionImpl.options.movable = false
|
||||
return this
|
||||
}
|
||||
|
||||
toggleSelectionMovable(movable?: boolean) {
|
||||
if (movable != null) {
|
||||
if (movable !== this.isSelectionMovable()) {
|
||||
if (movable) {
|
||||
this.enableSelectionMovable()
|
||||
} else {
|
||||
this.disableSelectionMovable()
|
||||
}
|
||||
}
|
||||
} else if (this.isSelectionMovable()) {
|
||||
this.disableSelectionMovable()
|
||||
} else {
|
||||
this.enableSelectionMovable()
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
isRubberbandEnabled() {
|
||||
return !this.rubberbandDisabled
|
||||
}
|
||||
|
||||
enableRubberband() {
|
||||
if (this.rubberbandDisabled) {
|
||||
this.options.rubberband = true
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
disableRubberband() {
|
||||
if (!this.rubberbandDisabled) {
|
||||
this.options.rubberband = false
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
toggleRubberband(enabled?: boolean) {
|
||||
if (enabled != null) {
|
||||
if (enabled !== this.isRubberbandEnabled()) {
|
||||
if (enabled) {
|
||||
this.enableRubberband()
|
||||
} else {
|
||||
this.disableRubberband()
|
||||
}
|
||||
}
|
||||
} else if (this.isRubberbandEnabled()) {
|
||||
this.disableRubberband()
|
||||
} else {
|
||||
this.enableRubberband()
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
isStrictRubberband() {
|
||||
return this.selectionImpl.options.strict === true
|
||||
}
|
||||
|
||||
enableStrictRubberband() {
|
||||
this.selectionImpl.options.strict = true
|
||||
return this
|
||||
}
|
||||
|
||||
disableStrictRubberband() {
|
||||
this.selectionImpl.options.strict = false
|
||||
return this
|
||||
}
|
||||
|
||||
toggleStrictRubberband(strict?: boolean) {
|
||||
if (strict != null) {
|
||||
if (strict !== this.isStrictRubberband()) {
|
||||
if (strict) {
|
||||
this.enableStrictRubberband()
|
||||
} else {
|
||||
this.disableStrictRubberband()
|
||||
}
|
||||
}
|
||||
} else if (this.isStrictRubberband()) {
|
||||
this.disableStrictRubberband()
|
||||
} else {
|
||||
this.enableStrictRubberband()
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
setRubberbandModifiers(modifiers?: string | ModifierKey[] | null) {
|
||||
this.setModifiers(modifiers)
|
||||
}
|
||||
|
||||
setSelectionFilter(filter?: Selection.Filter) {
|
||||
this.setFilter(filter)
|
||||
return this
|
||||
}
|
||||
|
||||
setSelectionDisplayContent(content?: Selection.Content) {
|
||||
this.setContent(content)
|
||||
return this
|
||||
}
|
||||
|
||||
isSelectionEmpty() {
|
||||
return this.isEmpty()
|
||||
}
|
||||
|
||||
cleanSelection(options?: Selection.SetOptions) {
|
||||
this.clean(options)
|
||||
return this
|
||||
}
|
||||
|
||||
resetSelection(
|
||||
cells?: Cell | string | (Cell | string)[],
|
||||
options?: Selection.SetOptions,
|
||||
) {
|
||||
this.reset(cells, options)
|
||||
return this
|
||||
}
|
||||
|
||||
getSelectedCells() {
|
||||
return this.cells
|
||||
}
|
||||
|
||||
getSelectedCellCount() {
|
||||
return this.length
|
||||
}
|
||||
|
||||
isSelected(cell: Cell | string) {
|
||||
return this.selectionImpl.isSelected(cell)
|
||||
}
|
||||
|
||||
select(
|
||||
cells: Cell | string | (Cell | string)[],
|
||||
options: Selection.AddOptions = {},
|
||||
) {
|
||||
const selected = this.getCells(cells)
|
||||
if (selected.length) {
|
||||
if (this.isMultiple()) {
|
||||
this.selectionImpl.select(selected, options)
|
||||
} else {
|
||||
this.reset(selected.slice(0, 1), options)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
unselect(
|
||||
cells: Cell | string | (Cell | string)[],
|
||||
options: Selection.RemoveOptions = {},
|
||||
) {
|
||||
this.selectionImpl.unselect(this.getCells(cells), options)
|
||||
return this
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
protected startListening() {
|
||||
this.graph.on('blank:mousedown', this.onBlankMouseDown, this)
|
||||
this.graph.on('blank:click', this.onBlankClick, this)
|
||||
this.graph.on('cell:mousemove', this.onCellMouseMove, this)
|
||||
this.graph.on('cell:mouseup', this.onCellMouseUp, this)
|
||||
this.selectionImpl.on('box:mousedown', this.onBoxMouseDown, this)
|
||||
}
|
||||
|
||||
protected stopListening() {
|
||||
this.graph.off('blank:mousedown', this.onBlankMouseDown, this)
|
||||
this.graph.off('blank:click', this.onBlankClick, this)
|
||||
this.graph.off('cell:mousemove', this.onCellMouseMove, this)
|
||||
this.graph.off('cell:mouseup', this.onCellMouseUp, this)
|
||||
this.selectionImpl.off('box:mousedown', this.onBoxMouseDown, this)
|
||||
}
|
||||
|
||||
protected onBlankMouseDown({ e }: EventArgs['blank:mousedown']) {
|
||||
const allowGraphPanning = this.graph.panning.allowPanning(e, true)
|
||||
const scroller = this.graph.getPlugin('scroller') as any
|
||||
const allowScrollerPanning = scroller && scroller.allowPanning(e, true)
|
||||
if (
|
||||
this.allowRubberband(e, true) ||
|
||||
(this.allowRubberband(e) && !allowScrollerPanning && !allowGraphPanning)
|
||||
) {
|
||||
this.startRubberband(e)
|
||||
}
|
||||
}
|
||||
|
||||
protected onBlankClick() {
|
||||
this.clean()
|
||||
}
|
||||
|
||||
protected allowRubberband(e: Dom.MouseDownEvent, strict?: boolean) {
|
||||
return (
|
||||
!this.rubberbandDisabled &&
|
||||
ModifierKey.isMatch(e, this.options.modifiers, strict)
|
||||
)
|
||||
}
|
||||
|
||||
protected allowMultipleSelection(e: Dom.MouseDownEvent | Dom.MouseUpEvent) {
|
||||
return (
|
||||
this.isMultiple() &&
|
||||
ModifierKey.isMatch(e, this.options.multipleSelectionModifiers)
|
||||
)
|
||||
}
|
||||
|
||||
protected onCellMouseMove({ cell }: EventArgs['cell:mousemove']) {
|
||||
this.movedMap.set(cell, true)
|
||||
}
|
||||
|
||||
protected onCellMouseUp({ e, cell }: EventArgs['cell:mouseup']) {
|
||||
const options = this.options
|
||||
let disabled = this.disabled
|
||||
if (!disabled && this.movedMap.has(cell)) {
|
||||
disabled = options.selectCellOnMoved === false
|
||||
|
||||
if (!disabled) {
|
||||
disabled = options.selectNodeOnMoved === false && cell.isNode()
|
||||
}
|
||||
|
||||
if (!disabled) {
|
||||
disabled = options.selectEdgeOnMoved === false && cell.isEdge()
|
||||
}
|
||||
}
|
||||
|
||||
if (!disabled) {
|
||||
if (!this.allowMultipleSelection(e)) {
|
||||
this.reset(cell)
|
||||
} else if (this.unselectMap.has(cell)) {
|
||||
this.unselectMap.delete(cell)
|
||||
} else if (this.isSelected(cell)) {
|
||||
this.unselect(cell)
|
||||
} else {
|
||||
this.select(cell)
|
||||
}
|
||||
}
|
||||
|
||||
this.movedMap.delete(cell)
|
||||
}
|
||||
|
||||
protected onBoxMouseDown({
|
||||
e,
|
||||
cell,
|
||||
}: SelectionImpl.EventArgs['box:mousedown']) {
|
||||
if (!this.disabled) {
|
||||
if (this.allowMultipleSelection(e)) {
|
||||
this.unselect(cell)
|
||||
this.unselectMap.set(cell, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected isEmpty() {
|
||||
return this.length <= 0
|
||||
}
|
||||
|
||||
protected getCells(cells: Cell | string | (Cell | string)[]) {
|
||||
return (Array.isArray(cells) ? cells : [cells])
|
||||
.map((cell) =>
|
||||
typeof cell === 'string' ? this.graph.getCellById(cell) : cell,
|
||||
)
|
||||
.filter((cell) => cell != null)
|
||||
}
|
||||
|
||||
protected reset(
|
||||
cells?: Cell | string | (Cell | string)[],
|
||||
options: Selection.SetOptions = {},
|
||||
) {
|
||||
this.selectionImpl.reset(cells ? this.getCells(cells) : [], options)
|
||||
return this
|
||||
}
|
||||
|
||||
protected clean(options: Selection.SetOptions = {}) {
|
||||
this.selectionImpl.clean(options)
|
||||
return this
|
||||
}
|
||||
|
||||
protected enable() {
|
||||
if (this.disabled) {
|
||||
this.options.enabled = true
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
protected disable() {
|
||||
if (!this.disabled) {
|
||||
this.options.enabled = false
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
protected startRubberband(e: Dom.MouseDownEvent) {
|
||||
if (!this.rubberbandDisabled) {
|
||||
this.selectionImpl.startSelecting(e)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
protected isMultiple() {
|
||||
return this.options.multiple !== false
|
||||
}
|
||||
|
||||
protected enableMultiple() {
|
||||
this.options.multiple = true
|
||||
return this
|
||||
}
|
||||
|
||||
protected disableMultiple() {
|
||||
this.options.multiple = false
|
||||
return this
|
||||
}
|
||||
|
||||
protected setModifiers(modifiers?: string | ModifierKey[] | null) {
|
||||
this.options.modifiers = modifiers
|
||||
return this
|
||||
}
|
||||
|
||||
protected setContent(content?: Selection.Content) {
|
||||
this.selectionImpl.setContent(content)
|
||||
return this
|
||||
}
|
||||
|
||||
protected setFilter(filter?: Selection.Filter) {
|
||||
this.selectionImpl.setFilter(filter)
|
||||
return this
|
||||
}
|
||||
|
||||
@Disposable.dispose()
|
||||
dispose() {
|
||||
this.stopListening()
|
||||
this.selectionImpl.dispose()
|
||||
CssLoader.clean(this.name)
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Selection {
|
||||
export interface Options extends SelectionImpl.CommonOptions {
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
export type Filter = SelectionImpl.Filter
|
||||
export type Content = SelectionImpl.Content
|
||||
|
||||
export type SetOptions = SelectionImpl.SetOptions
|
||||
export type AddOptions = SelectionImpl.AddOptions
|
||||
export type RemoveOptions = SelectionImpl.RemoveOptions
|
||||
|
||||
export const defaultOptions: Partial<SelectionImpl.Options> = {
|
||||
rubberband: false,
|
||||
rubberNode: true,
|
||||
rubberEdge: false, // next version will set to true
|
||||
pointerEvents: 'auto',
|
||||
multiple: true,
|
||||
multipleSelectionModifiers: ['ctrl', 'meta'],
|
||||
movable: true,
|
||||
strict: false,
|
||||
useCellGeometry: false,
|
||||
selectCellOnMoved: false,
|
||||
selectNodeOnMoved: false,
|
||||
selectEdgeOnMoved: false,
|
||||
following: true,
|
||||
content: null,
|
||||
}
|
||||
}
|
1124
packages/x6-plugin-selection/src/selection.ts
Normal file
1124
packages/x6-plugin-selection/src/selection.ts
Normal file
File diff suppressed because it is too large
Load Diff
70
packages/x6-plugin-selection/src/style/raw.ts
Normal file
70
packages/x6-plugin-selection/src/style/raw.ts
Normal file
@ -0,0 +1,70 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* Auto generated file, do not modify it!
|
||||
*/
|
||||
|
||||
export const content = `.x6-widget-selection {
|
||||
position: absolute;
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
touch-action: none;
|
||||
}
|
||||
.x6-widget-selection-rubberband {
|
||||
display: block;
|
||||
overflow: visible;
|
||||
opacity: 0.3;
|
||||
}
|
||||
.x6-widget-selection-selected {
|
||||
display: block;
|
||||
}
|
||||
.x6-widget-selection-box {
|
||||
cursor: move;
|
||||
}
|
||||
.x6-widget-selection-inner[data-selection-length='0'],
|
||||
.x6-widget-selection-inner[data-selection-length='1'] {
|
||||
display: none;
|
||||
}
|
||||
.x6-widget-selection-content {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: -20px;
|
||||
left: -20px;
|
||||
margin-top: 30px;
|
||||
padding: 6px;
|
||||
line-height: 14px;
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.x6-widget-selection-content:empty {
|
||||
display: none;
|
||||
}
|
||||
.x6-widget-selection-rubberband {
|
||||
background-color: #3498db;
|
||||
border: 2px solid #2980b9;
|
||||
}
|
||||
.x6-widget-selection-box {
|
||||
box-sizing: content-box !important;
|
||||
margin-top: -4px;
|
||||
margin-left: -4px;
|
||||
padding-right: 4px;
|
||||
padding-bottom: 4px;
|
||||
border: 2px dashed #feb663;
|
||||
box-shadow: 2px 2px 5px #d3d3d3;
|
||||
}
|
||||
.x6-widget-selection-inner {
|
||||
box-sizing: content-box !important;
|
||||
margin-top: -8px;
|
||||
margin-left: -8px;
|
||||
padding-right: 12px;
|
||||
padding-bottom: 12px;
|
||||
border: 2px solid #feb663;
|
||||
box-shadow: 2px 2px 5px #d3d3d3;
|
||||
}
|
||||
.x6-widget-selection-content {
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
background-color: #6a6b8a;
|
||||
}
|
||||
`
|
3
packages/x6-plugin-selection/tsconfig.json
Normal file
3
packages/x6-plugin-selection/tsconfig.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json"
|
||||
}
|
21
packages/x6-plugin-snapline/LICENSE
Normal file
21
packages/x6-plugin-snapline/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.
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user