Compare commits
2 Commits
v2.0.6-bet
...
v2.0.6-bet
Author | SHA1 | Date | |
---|---|---|---|
12e4ac55d7 | |||
294672b306 |
@ -34,7 +34,6 @@ export default class Example extends React.Component {
|
||||
graph.addEdge({
|
||||
source,
|
||||
target,
|
||||
tools: ['button-remove'],
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,11 @@ const dataSource = [
|
||||
example: 'case/swimlane',
|
||||
description: '泳道图',
|
||||
},
|
||||
{
|
||||
key: '10',
|
||||
example: 'snapline',
|
||||
description: '对齐线',
|
||||
},
|
||||
]
|
||||
|
||||
const columns = [
|
||||
|
@ -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,
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "2.0.6-beta.19",
|
||||
"version": "2.0.6-beta.20",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-keyboard",
|
||||
"version": "2.0.6-beta.18",
|
||||
"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",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-scroller",
|
||||
"version": "2.0.6-beta.19",
|
||||
"version": "2.0.6-beta.20",
|
||||
"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",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-selection",
|
||||
"version": "2.0.6-beta.19",
|
||||
"version": "2.0.6-beta.20",
|
||||
"description": "selection 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"
|
||||
@ -102,7 +103,7 @@
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/antvis/x6.git",
|
||||
"directory": "packages/x6-common"
|
||||
"directory": "packages/x6-plugin-selection"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
@ -22,7 +22,7 @@ function compile(source, target) {
|
||||
|
||||
compile(path.join(src, 'index.less'), path.join(es, 'index.css'))
|
||||
compile(path.join(src, 'index.less'), path.join(lib, 'index.css'))
|
||||
compile(path.join(src, 'index.less'), path.join(dist, 'scroller.css'))
|
||||
compile(path.join(src, 'index.less'), path.join(dist, 'selection.css'))
|
||||
|
||||
function toCSSPath(source) {
|
||||
const dir = path.dirname(source)
|
||||
@ -61,7 +61,7 @@ function processLessInDir(dir) {
|
||||
}
|
||||
|
||||
function makeStyleModule() {
|
||||
const source = path.join(dist, 'scroller.css')
|
||||
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)
|
||||
|
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.
|
5
packages/x6-plugin-snapline/README.md
Normal file
5
packages/x6-plugin-snapline/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# `x6-plugin-snapline`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
112
packages/x6-plugin-snapline/package.json
Normal file
112
packages/x6-plugin-snapline/package.json
Normal file
@ -0,0 +1,112 @@
|
||||
{
|
||||
"name": "@antv/x6-plugin-snapline",
|
||||
"version": "2.0.6-beta.20",
|
||||
"description": "snapline plugin for X6.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"unpkg": "dist/x6-plugin-snapline.js",
|
||||
"jsdelivr": "dist/x6-plugin-snapline.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"es",
|
||||
"lib"
|
||||
],
|
||||
"keywords": [
|
||||
"plugin",
|
||||
"snapline",
|
||||
"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-snapline"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
}
|
||||
}
|
18
packages/x6-plugin-snapline/rollup.config.js
Normal file
18
packages/x6-plugin-snapline/rollup.config.js
Normal file
@ -0,0 +1,18 @@
|
||||
import config from '../../configs/rollup-config'
|
||||
|
||||
export default config({
|
||||
output: [
|
||||
{
|
||||
name: 'X6PluginSnapline',
|
||||
format: 'umd',
|
||||
file: 'dist/x6-plugin-snapline.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-snapline/scripts/style.js
Normal file
85
packages/x6-plugin-snapline/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, 'snapline.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, 'snapline.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()
|
16
packages/x6-plugin-snapline/src/index.less
Normal file
16
packages/x6-plugin-snapline/src/index.less
Normal file
@ -0,0 +1,16 @@
|
||||
@snapline-prefix-cls: ~'x6-widget-snapline';
|
||||
|
||||
.@{snapline-prefix-cls} {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
|
||||
&-vertical,
|
||||
&-horizontal {
|
||||
stroke: #2ecc71;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
}
|
149
packages/x6-plugin-snapline/src/index.ts
Normal file
149
packages/x6-plugin-snapline/src/index.ts
Normal file
@ -0,0 +1,149 @@
|
||||
import { Disposable, CssLoader } from '@antv/x6-common'
|
||||
import { Graph } from '@antv/x6'
|
||||
import { SnaplineImpl } from './snapline'
|
||||
import { content } from './style/raw'
|
||||
|
||||
export class Snapline extends Disposable {
|
||||
private snaplineImpl: SnaplineImpl
|
||||
public name = 'snapline'
|
||||
|
||||
constructor(public readonly options: Snapline.Options) {
|
||||
super()
|
||||
}
|
||||
|
||||
public init(graph: Graph) {
|
||||
CssLoader.ensure(this.name, content)
|
||||
this.snaplineImpl = new SnaplineImpl({
|
||||
...this.options,
|
||||
graph,
|
||||
})
|
||||
}
|
||||
|
||||
// #region api
|
||||
|
||||
isSnaplineEnabled() {
|
||||
return !this.snaplineImpl.disabled
|
||||
}
|
||||
|
||||
enableSnapline() {
|
||||
this.snaplineImpl.enable()
|
||||
return this
|
||||
}
|
||||
|
||||
disableSnapline() {
|
||||
this.snaplineImpl.disable()
|
||||
return this
|
||||
}
|
||||
|
||||
toggleSnapline(enabled?: boolean) {
|
||||
if (enabled != null) {
|
||||
if (enabled !== this.isSnaplineEnabled()) {
|
||||
if (enabled) {
|
||||
this.enableSnapline()
|
||||
} else {
|
||||
this.disableSnapline()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (this.isSnaplineEnabled()) {
|
||||
this.disableSnapline()
|
||||
} else {
|
||||
this.enableSnapline()
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
hideSnapline() {
|
||||
this.snaplineImpl.hide()
|
||||
return this
|
||||
}
|
||||
|
||||
setSnaplineFilter(filter?: SnaplineImpl.Filter) {
|
||||
this.snaplineImpl.setFilter(filter)
|
||||
return this
|
||||
}
|
||||
|
||||
isSnaplineOnResizingEnabled() {
|
||||
return this.snaplineImpl.options.resizing === true
|
||||
}
|
||||
|
||||
enableSnaplineOnResizing() {
|
||||
this.snaplineImpl.options.resizing = true
|
||||
return this
|
||||
}
|
||||
|
||||
disableSnaplineOnResizing() {
|
||||
this.snaplineImpl.options.resizing = false
|
||||
return this
|
||||
}
|
||||
|
||||
toggleSnaplineOnResizing(enableOnResizing?: boolean) {
|
||||
if (enableOnResizing != null) {
|
||||
if (enableOnResizing !== this.isSnaplineOnResizingEnabled()) {
|
||||
if (enableOnResizing) {
|
||||
this.enableSnaplineOnResizing()
|
||||
} else {
|
||||
this.disableSnaplineOnResizing()
|
||||
}
|
||||
}
|
||||
} else if (this.isSnaplineOnResizingEnabled()) {
|
||||
this.disableSnaplineOnResizing()
|
||||
} else {
|
||||
this.enableSnaplineOnResizing()
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
isSharpSnapline() {
|
||||
return this.snaplineImpl.options.sharp === true
|
||||
}
|
||||
|
||||
enableSharpSnapline() {
|
||||
this.snaplineImpl.options.sharp = true
|
||||
return this
|
||||
}
|
||||
|
||||
disableSharpSnapline() {
|
||||
this.snaplineImpl.options.sharp = false
|
||||
return this
|
||||
}
|
||||
|
||||
toggleSharpSnapline(sharp?: boolean) {
|
||||
if (sharp != null) {
|
||||
if (sharp !== this.isSharpSnapline()) {
|
||||
if (sharp) {
|
||||
this.enableSharpSnapline()
|
||||
} else {
|
||||
this.disableSharpSnapline()
|
||||
}
|
||||
}
|
||||
} else if (this.isSharpSnapline()) {
|
||||
this.disableSharpSnapline()
|
||||
} else {
|
||||
this.enableSharpSnapline()
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
getSnaplineTolerance() {
|
||||
return this.snaplineImpl.options.tolerance
|
||||
}
|
||||
|
||||
setSnaplineTolerance(tolerance: number) {
|
||||
this.snaplineImpl.options.tolerance = tolerance
|
||||
return this
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
@Disposable.dispose()
|
||||
dispose() {
|
||||
this.snaplineImpl.dispose()
|
||||
CssLoader.clean(this.name)
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Snapline {
|
||||
export interface Options extends SnaplineImpl.Options {}
|
||||
}
|
695
packages/x6-plugin-snapline/src/snapline.ts
Normal file
695
packages/x6-plugin-snapline/src/snapline.ts
Normal file
@ -0,0 +1,695 @@
|
||||
import { IDisablable, ArrayExt, FunctionExt, Vector } from '@antv/x6-common'
|
||||
import { Angle, Point, Rectangle } from '@antv/x6-geometry'
|
||||
import {
|
||||
Graph,
|
||||
EventArgs,
|
||||
Model,
|
||||
Node,
|
||||
CellView,
|
||||
NodeView,
|
||||
View,
|
||||
} from '@antv/x6'
|
||||
|
||||
export class SnaplineImpl extends View implements IDisablable {
|
||||
public readonly options: SnaplineImpl.Options
|
||||
protected readonly graph: Graph
|
||||
protected filterShapes: { [type: string]: boolean }
|
||||
protected filterCells: { [id: string]: boolean }
|
||||
protected filterFunction: SnaplineImpl.FilterFunction | null
|
||||
protected offset: Point.PointLike
|
||||
protected timer: number | null
|
||||
|
||||
public container: SVGElement
|
||||
protected containerWrapper: Vector
|
||||
protected horizontal: Vector
|
||||
protected vertical: Vector
|
||||
|
||||
protected get model() {
|
||||
return this.graph.model
|
||||
}
|
||||
|
||||
protected get containerClassName() {
|
||||
return this.prefixClassName('widget-snapline')
|
||||
}
|
||||
|
||||
protected get verticalClassName() {
|
||||
return `${this.containerClassName}-vertical`
|
||||
}
|
||||
|
||||
protected get horizontalClassName() {
|
||||
return `${this.containerClassName}-horizontal`
|
||||
}
|
||||
|
||||
constructor(options: SnaplineImpl.Options & { graph: Graph }) {
|
||||
super()
|
||||
|
||||
const { graph, ...others } = options
|
||||
this.graph = graph
|
||||
this.options = { tolerance: 10, ...others }
|
||||
this.offset = { x: 0, y: 0 }
|
||||
this.render()
|
||||
this.parseFilter()
|
||||
if (!this.disabled) {
|
||||
this.startListening()
|
||||
}
|
||||
}
|
||||
|
||||
public get disabled() {
|
||||
return this.options.enabled !== true
|
||||
}
|
||||
|
||||
enable() {
|
||||
if (this.disabled) {
|
||||
this.options.enabled = true
|
||||
this.startListening()
|
||||
}
|
||||
}
|
||||
|
||||
disable() {
|
||||
if (!this.disabled) {
|
||||
this.options.enabled = false
|
||||
this.stopListening()
|
||||
}
|
||||
}
|
||||
|
||||
setFilter(filter?: SnaplineImpl.Filter) {
|
||||
this.options.filter = filter
|
||||
this.parseFilter()
|
||||
}
|
||||
|
||||
protected render() {
|
||||
const container = (this.containerWrapper = new Vector('svg'))
|
||||
const horizontal = (this.horizontal = new Vector('line'))
|
||||
const vertical = (this.vertical = new Vector('line'))
|
||||
|
||||
container.addClass(this.containerClassName)
|
||||
horizontal.addClass(this.horizontalClassName)
|
||||
vertical.addClass(this.verticalClassName)
|
||||
|
||||
container.setAttribute('width', '100%')
|
||||
container.setAttribute('height', '100%')
|
||||
|
||||
horizontal.setAttribute('display', 'none')
|
||||
vertical.setAttribute('display', 'none')
|
||||
|
||||
container.append([horizontal, vertical])
|
||||
|
||||
if (this.options.className) {
|
||||
container.addClass(this.options.className)
|
||||
}
|
||||
|
||||
this.container = this.containerWrapper.node
|
||||
}
|
||||
|
||||
protected startListening() {
|
||||
this.stopListening()
|
||||
this.graph.on('node:mousedown', this.captureCursorOffset, this)
|
||||
this.graph.on('node:mousemove', this.snapOnMoving, this)
|
||||
this.model.on('batch:stop', this.onBatchStop, this)
|
||||
this.delegateDocumentEvents({
|
||||
mouseup: 'hide',
|
||||
touchend: 'hide',
|
||||
})
|
||||
}
|
||||
|
||||
protected stopListening() {
|
||||
this.graph.off('node:mousedown', this.captureCursorOffset, this)
|
||||
this.graph.off('node:mousemove', this.snapOnMoving, this)
|
||||
this.model.off('batch:stop', this.onBatchStop, this)
|
||||
this.undelegateDocumentEvents()
|
||||
}
|
||||
|
||||
protected parseFilter() {
|
||||
this.filterShapes = {}
|
||||
this.filterCells = {}
|
||||
this.filterFunction = null
|
||||
const filter = this.options.filter
|
||||
if (Array.isArray(filter)) {
|
||||
filter.forEach((item) => {
|
||||
if (typeof item === 'string') {
|
||||
this.filterShapes[item] = true
|
||||
} else {
|
||||
this.filterCells[item.id] = true
|
||||
}
|
||||
})
|
||||
} else if (typeof filter === 'function') {
|
||||
this.filterFunction = filter
|
||||
}
|
||||
}
|
||||
|
||||
protected onBatchStop({ name, data }: Model.EventArgs['batch:stop']) {
|
||||
if (name === 'resize') {
|
||||
this.snapOnResizing(data.cell, data as Node.ResizeOptions)
|
||||
}
|
||||
}
|
||||
|
||||
captureCursorOffset({ view, x, y }: EventArgs['node:mousedown']) {
|
||||
const targetView = view.getDelegatedView()
|
||||
if (targetView && this.isNodeMovable(targetView)) {
|
||||
const pos = view.cell.getPosition()
|
||||
this.offset = {
|
||||
x: x - pos.x,
|
||||
y: y - pos.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected isNodeMovable(view: CellView) {
|
||||
return view && view.cell.isNode() && view.can('nodeMovable')
|
||||
}
|
||||
|
||||
protected getRestrictArea(view?: NodeView): Rectangle.RectangleLike | null {
|
||||
const restrict = this.graph.options.translating.restrict
|
||||
const area =
|
||||
typeof restrict === 'function'
|
||||
? FunctionExt.call(restrict, this.graph, view!)
|
||||
: restrict
|
||||
|
||||
if (typeof area === 'number') {
|
||||
return this.graph.transform.getGraphArea().inflate(area)
|
||||
}
|
||||
|
||||
if (area === true) {
|
||||
return this.graph.transform.getGraphArea()
|
||||
}
|
||||
|
||||
return area || null
|
||||
}
|
||||
|
||||
protected snapOnResizing(node: Node, options: Node.ResizeOptions) {
|
||||
if (
|
||||
this.options.resizing &&
|
||||
!options.snapped &&
|
||||
options.ui &&
|
||||
options.direction &&
|
||||
options.trueDirection
|
||||
) {
|
||||
const view = this.graph.renderer.findViewByCell(node) as NodeView
|
||||
if (view && view.cell.isNode()) {
|
||||
const nodeBbox = node.getBBox()
|
||||
const nodeBBoxRotated = nodeBbox.bbox(node.getAngle())
|
||||
const nodeTopLeft = nodeBBoxRotated.getTopLeft()
|
||||
const nodeBottomRight = nodeBBoxRotated.getBottomRight()
|
||||
const angle = Angle.normalize(node.getAngle())
|
||||
const tolerance = this.options.tolerance || 0
|
||||
let verticalLeft: number | undefined
|
||||
let verticalTop: number | undefined
|
||||
let verticalHeight: number | undefined
|
||||
let horizontalTop: number | undefined
|
||||
let horizontalLeft: number | undefined
|
||||
let horizontalWidth: number | undefined
|
||||
|
||||
const snapOrigin = {
|
||||
vertical: 0,
|
||||
horizontal: 0,
|
||||
}
|
||||
|
||||
const direction = options.direction
|
||||
const trueDirection = options.trueDirection
|
||||
const relativeDirection = options.relativeDirection
|
||||
|
||||
if (trueDirection.indexOf('right') !== -1) {
|
||||
snapOrigin.vertical = nodeBottomRight.x
|
||||
} else {
|
||||
snapOrigin.vertical = nodeTopLeft.x
|
||||
}
|
||||
|
||||
if (trueDirection.indexOf('bottom') !== -1) {
|
||||
snapOrigin.horizontal = nodeBottomRight.y
|
||||
} else {
|
||||
snapOrigin.horizontal = nodeTopLeft.y
|
||||
}
|
||||
|
||||
this.model.getNodes().some((cell) => {
|
||||
if (this.isIgnored(node, cell)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const snapBBox = cell.getBBox().bbox(cell.getAngle())
|
||||
const snapTopLeft = snapBBox.getTopLeft()
|
||||
const snapBottomRight = snapBBox.getBottomRight()
|
||||
const groups = {
|
||||
vertical: [snapTopLeft.x, snapBottomRight.x],
|
||||
horizontal: [snapTopLeft.y, snapBottomRight.y],
|
||||
}
|
||||
|
||||
const distances = {} as {
|
||||
vertical: { position: number; distance: number }[]
|
||||
horizontal: { position: number; distance: number }[]
|
||||
}
|
||||
|
||||
Object.keys(groups).forEach((k) => {
|
||||
const key = k as 'vertical' | 'horizontal'
|
||||
const list = groups[key]
|
||||
.map((value) => ({
|
||||
position: value,
|
||||
distance: Math.abs(value - snapOrigin[key]),
|
||||
}))
|
||||
.filter((item) => item.distance <= tolerance)
|
||||
|
||||
distances[key] = ArrayExt.sortBy(list, (item) => item.distance)
|
||||
})
|
||||
|
||||
if (verticalLeft == null && distances.vertical.length > 0) {
|
||||
verticalLeft = distances.vertical[0].position
|
||||
verticalTop = Math.min(nodeBBoxRotated.y, snapBBox.y)
|
||||
verticalHeight =
|
||||
Math.max(nodeBottomRight.y, snapBottomRight.y) - verticalTop
|
||||
}
|
||||
|
||||
if (horizontalTop == null && distances.horizontal.length > 0) {
|
||||
horizontalTop = distances.horizontal[0].position
|
||||
horizontalLeft = Math.min(nodeBBoxRotated.x, snapBBox.x)
|
||||
horizontalWidth =
|
||||
Math.max(nodeBottomRight.x, snapBottomRight.x) - horizontalLeft
|
||||
}
|
||||
|
||||
return verticalLeft != null && horizontalTop != null
|
||||
})
|
||||
|
||||
this.hide()
|
||||
|
||||
let dx = 0
|
||||
let dy = 0
|
||||
if (horizontalTop != null || verticalLeft != null) {
|
||||
if (verticalLeft != null) {
|
||||
dx =
|
||||
trueDirection.indexOf('right') !== -1
|
||||
? verticalLeft - nodeBottomRight.x
|
||||
: nodeTopLeft.x - verticalLeft
|
||||
}
|
||||
|
||||
if (horizontalTop != null) {
|
||||
dy =
|
||||
trueDirection.indexOf('bottom') !== -1
|
||||
? horizontalTop - nodeBottomRight.y
|
||||
: nodeTopLeft.y - horizontalTop
|
||||
}
|
||||
}
|
||||
|
||||
let dWidth = 0
|
||||
let dHeight = 0
|
||||
if (angle % 90 === 0) {
|
||||
if (angle === 90 || angle === 270) {
|
||||
dWidth = dy
|
||||
dHeight = dx
|
||||
} else {
|
||||
dWidth = dx
|
||||
dHeight = dy
|
||||
}
|
||||
} else {
|
||||
const quadrant =
|
||||
angle >= 0 && angle < 90
|
||||
? 1
|
||||
: angle >= 90 && angle < 180
|
||||
? 4
|
||||
: angle >= 180 && angle < 270
|
||||
? 3
|
||||
: 2
|
||||
|
||||
if (horizontalTop != null && verticalLeft != null) {
|
||||
if (dx < dy) {
|
||||
dy = 0
|
||||
horizontalTop = undefined
|
||||
} else {
|
||||
dx = 0
|
||||
verticalLeft = undefined
|
||||
}
|
||||
}
|
||||
|
||||
const rad = Angle.toRad(angle % 90)
|
||||
if (dx) {
|
||||
dWidth = quadrant === 3 ? dx / Math.cos(rad) : dx / Math.sin(rad)
|
||||
}
|
||||
if (dy) {
|
||||
dHeight = quadrant === 3 ? dy / Math.cos(rad) : dy / Math.sin(rad)
|
||||
}
|
||||
|
||||
const quadrant13 = quadrant === 1 || quadrant === 3
|
||||
switch (relativeDirection) {
|
||||
case 'top':
|
||||
case 'bottom':
|
||||
dHeight = dy
|
||||
? dy / (quadrant13 ? Math.cos(rad) : Math.sin(rad))
|
||||
: dx / (quadrant13 ? Math.sin(rad) : Math.cos(rad))
|
||||
break
|
||||
case 'left':
|
||||
case 'right':
|
||||
dWidth = dx
|
||||
? dx / (quadrant13 ? Math.cos(rad) : Math.sin(rad))
|
||||
: dy / (quadrant13 ? Math.sin(rad) : Math.cos(rad))
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
switch (relativeDirection) {
|
||||
case 'top':
|
||||
case 'bottom':
|
||||
dWidth = 0
|
||||
break
|
||||
case 'left':
|
||||
case 'right':
|
||||
dHeight = 0
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
const gridSize = this.graph.getGridSize()
|
||||
let newWidth = Math.max(nodeBbox.width + dWidth, gridSize)
|
||||
let newHeight = Math.max(nodeBbox.height + dHeight, gridSize)
|
||||
|
||||
if (options.minWidth && options.minWidth > gridSize) {
|
||||
newWidth = Math.max(newWidth, options.minWidth)
|
||||
}
|
||||
|
||||
if (options.minHeight && options.minHeight > gridSize) {
|
||||
newHeight = Math.max(newHeight, options.minHeight)
|
||||
}
|
||||
|
||||
if (options.maxWidth) {
|
||||
newWidth = Math.min(newWidth, options.maxWidth)
|
||||
}
|
||||
|
||||
if (options.maxHeight) {
|
||||
newHeight = Math.min(newHeight, options.maxHeight)
|
||||
}
|
||||
|
||||
if (options.preserveAspectRatio) {
|
||||
if (dHeight < dWidth) {
|
||||
newHeight = newWidth * (nodeBbox.height / nodeBbox.width)
|
||||
} else {
|
||||
newWidth = newHeight * (nodeBbox.width / nodeBbox.height)
|
||||
}
|
||||
}
|
||||
|
||||
if (newWidth !== nodeBbox.width || newHeight !== nodeBbox.height) {
|
||||
node.resize(newWidth, newHeight, {
|
||||
direction,
|
||||
relativeDirection,
|
||||
trueDirection,
|
||||
snapped: true,
|
||||
snaplines: this.cid,
|
||||
restrict: this.getRestrictArea(view),
|
||||
})
|
||||
|
||||
if (verticalHeight) {
|
||||
verticalHeight += newHeight - nodeBbox.height
|
||||
}
|
||||
|
||||
if (horizontalWidth) {
|
||||
horizontalWidth += newWidth - nodeBbox.width
|
||||
}
|
||||
}
|
||||
|
||||
const newRotatedBBox = node.getBBox().bbox(angle)
|
||||
if (
|
||||
verticalLeft &&
|
||||
Math.abs(newRotatedBBox.x - verticalLeft) > 1 &&
|
||||
Math.abs(newRotatedBBox.width + newRotatedBBox.x - verticalLeft) > 1
|
||||
) {
|
||||
verticalLeft = undefined
|
||||
}
|
||||
|
||||
if (
|
||||
horizontalTop &&
|
||||
Math.abs(newRotatedBBox.y - horizontalTop) > 1 &&
|
||||
Math.abs(newRotatedBBox.height + newRotatedBBox.y - horizontalTop) > 1
|
||||
) {
|
||||
horizontalTop = undefined
|
||||
}
|
||||
|
||||
this.update({
|
||||
verticalLeft,
|
||||
verticalTop,
|
||||
verticalHeight,
|
||||
horizontalTop,
|
||||
horizontalLeft,
|
||||
horizontalWidth,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snapOnMoving({ view, e, x, y }: EventArgs['node:mousemove']) {
|
||||
const targetView: NodeView = view.getEventData(e).delegatedView || view
|
||||
if (!this.isNodeMovable(targetView)) {
|
||||
return
|
||||
}
|
||||
|
||||
const node = targetView.cell
|
||||
const size = node.getSize()
|
||||
const position = node.getPosition()
|
||||
const cellBBox = new Rectangle(
|
||||
x - this.offset.x,
|
||||
y - this.offset.y,
|
||||
size.width,
|
||||
size.height,
|
||||
)
|
||||
const angle = node.getAngle()
|
||||
const nodeCenter = cellBBox.getCenter()
|
||||
const nodeBBoxRotated = cellBBox.bbox(angle)
|
||||
const nodeTopLeft = nodeBBoxRotated.getTopLeft()
|
||||
const nodeBottomRight = nodeBBoxRotated.getBottomRight()
|
||||
|
||||
const distance = this.options.tolerance || 0
|
||||
let verticalLeft: number | undefined
|
||||
let verticalTop: number | undefined
|
||||
let verticalHeight: number | undefined
|
||||
let horizontalTop: number | undefined
|
||||
let horizontalLeft: number | undefined
|
||||
let horizontalWidth: number | undefined
|
||||
let verticalFix = 0
|
||||
let horizontalFix = 0
|
||||
|
||||
this.model.getNodes().some((targetNode) => {
|
||||
if (this.isIgnored(node, targetNode)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const snapBBox = targetNode.getBBox().bbox(targetNode.getAngle())
|
||||
const snapCenter = snapBBox.getCenter()
|
||||
const snapTopLeft = snapBBox.getTopLeft()
|
||||
const snapBottomRight = snapBBox.getBottomRight()
|
||||
|
||||
if (verticalLeft == null) {
|
||||
if (Math.abs(snapCenter.x - nodeCenter.x) < distance) {
|
||||
verticalLeft = snapCenter.x
|
||||
verticalFix = 0.5
|
||||
} else if (Math.abs(snapTopLeft.x - nodeTopLeft.x) < distance) {
|
||||
verticalLeft = snapTopLeft.x
|
||||
verticalFix = 0
|
||||
} else if (Math.abs(snapTopLeft.x - nodeBottomRight.x) < distance) {
|
||||
verticalLeft = snapTopLeft.x
|
||||
verticalFix = 1
|
||||
} else if (Math.abs(snapBottomRight.x - nodeBottomRight.x) < distance) {
|
||||
verticalLeft = snapBottomRight.x
|
||||
verticalFix = 1
|
||||
} else if (Math.abs(snapBottomRight.x - nodeTopLeft.x) < distance) {
|
||||
verticalLeft = snapBottomRight.x
|
||||
}
|
||||
|
||||
if (verticalLeft != null) {
|
||||
verticalTop = Math.min(nodeBBoxRotated.y, snapBBox.y)
|
||||
verticalHeight =
|
||||
Math.max(nodeBottomRight.y, snapBottomRight.y) - verticalTop
|
||||
}
|
||||
}
|
||||
|
||||
if (horizontalTop == null) {
|
||||
if (Math.abs(snapCenter.y - nodeCenter.y) < distance) {
|
||||
horizontalTop = snapCenter.y
|
||||
horizontalFix = 0.5
|
||||
} else if (Math.abs(snapTopLeft.y - nodeTopLeft.y) < distance) {
|
||||
horizontalTop = snapTopLeft.y
|
||||
} else if (Math.abs(snapTopLeft.y - nodeBottomRight.y) < distance) {
|
||||
horizontalTop = snapTopLeft.y
|
||||
horizontalFix = 1
|
||||
} else if (Math.abs(snapBottomRight.y - nodeBottomRight.y) < distance) {
|
||||
horizontalTop = snapBottomRight.y
|
||||
horizontalFix = 1
|
||||
} else if (Math.abs(snapBottomRight.y - nodeTopLeft.y) < distance) {
|
||||
horizontalTop = snapBottomRight.y
|
||||
}
|
||||
|
||||
if (horizontalTop != null) {
|
||||
horizontalLeft = Math.min(nodeBBoxRotated.x, snapBBox.x)
|
||||
horizontalWidth =
|
||||
Math.max(nodeBottomRight.x, snapBottomRight.x) - horizontalLeft
|
||||
}
|
||||
}
|
||||
|
||||
return verticalLeft != null && horizontalTop != null
|
||||
})
|
||||
|
||||
this.hide()
|
||||
|
||||
if (horizontalTop != null || verticalLeft != null) {
|
||||
if (horizontalTop != null) {
|
||||
nodeBBoxRotated.y =
|
||||
horizontalTop - horizontalFix * nodeBBoxRotated.height
|
||||
}
|
||||
|
||||
if (verticalLeft != null) {
|
||||
nodeBBoxRotated.x = verticalLeft - verticalFix * nodeBBoxRotated.width
|
||||
}
|
||||
|
||||
const newCenter = nodeBBoxRotated.getCenter()
|
||||
const newX = newCenter.x - cellBBox.width / 2
|
||||
const newY = newCenter.y - cellBBox.height / 2
|
||||
const dx = newX - position.x
|
||||
const dy = newY - position.y
|
||||
|
||||
if (dx !== 0 || dy !== 0) {
|
||||
node.translate(dx, dy, {
|
||||
snapped: true,
|
||||
restrict: this.getRestrictArea(targetView),
|
||||
})
|
||||
|
||||
if (horizontalWidth) {
|
||||
horizontalWidth += dx
|
||||
}
|
||||
|
||||
if (verticalHeight) {
|
||||
verticalHeight += dy
|
||||
}
|
||||
}
|
||||
|
||||
this.update({
|
||||
verticalLeft,
|
||||
verticalTop,
|
||||
verticalHeight,
|
||||
horizontalTop,
|
||||
horizontalLeft,
|
||||
horizontalWidth,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
protected isIgnored(snapNode: Node, targetNode: Node) {
|
||||
return (
|
||||
targetNode.id === snapNode.id ||
|
||||
targetNode.isDescendantOf(snapNode) ||
|
||||
this.filterShapes[targetNode.shape] ||
|
||||
this.filterCells[targetNode.id] ||
|
||||
(this.filterFunction &&
|
||||
FunctionExt.call(this.filterFunction, this.graph, targetNode))
|
||||
)
|
||||
}
|
||||
|
||||
protected update(metadata: {
|
||||
verticalLeft?: number
|
||||
verticalTop?: number
|
||||
verticalHeight?: number
|
||||
horizontalTop?: number
|
||||
horizontalLeft?: number
|
||||
horizontalWidth?: number
|
||||
}) {
|
||||
// https://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations
|
||||
if (metadata.horizontalTop) {
|
||||
const start = this.graph.localToGraph(
|
||||
new Point(metadata.horizontalLeft, metadata.horizontalTop),
|
||||
)
|
||||
const end = this.graph.localToGraph(
|
||||
new Point(
|
||||
metadata.horizontalLeft! + metadata.horizontalWidth!,
|
||||
metadata.horizontalTop,
|
||||
),
|
||||
)
|
||||
this.horizontal.setAttributes({
|
||||
x1: this.options.sharp ? `${start.x}` : '0',
|
||||
y1: `${start.y}`,
|
||||
x2: this.options.sharp ? `${end.x}` : '100%',
|
||||
y2: `${end.y}`,
|
||||
display: 'inherit',
|
||||
})
|
||||
} else {
|
||||
this.horizontal.setAttribute('display', 'none')
|
||||
}
|
||||
|
||||
if (metadata.verticalLeft) {
|
||||
const start = this.graph.localToGraph(
|
||||
new Point(metadata.verticalLeft, metadata.verticalTop),
|
||||
)
|
||||
const end = this.graph.localToGraph(
|
||||
new Point(
|
||||
metadata.verticalLeft,
|
||||
metadata.verticalTop! + metadata.verticalHeight!,
|
||||
),
|
||||
)
|
||||
this.vertical.setAttributes({
|
||||
x1: `${start.x}`,
|
||||
y1: this.options.sharp ? `${start.y}` : '0',
|
||||
x2: `${end.x}`,
|
||||
y2: this.options.sharp ? `${end.y}` : '100%',
|
||||
display: 'inherit',
|
||||
})
|
||||
} else {
|
||||
this.vertical.setAttribute('display', 'none')
|
||||
}
|
||||
|
||||
this.show()
|
||||
}
|
||||
|
||||
protected resetTimer() {
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
}
|
||||
|
||||
show() {
|
||||
this.resetTimer()
|
||||
if (this.container.parentNode == null) {
|
||||
this.graph.container.appendChild(this.container)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.resetTimer()
|
||||
this.vertical.setAttribute('display', 'none')
|
||||
this.horizontal.setAttribute('display', 'none')
|
||||
const clean = this.options.clean
|
||||
const delay = typeof clean === 'number' ? clean : clean !== false ? 3000 : 0
|
||||
if (delay > 0) {
|
||||
this.timer = window.setTimeout(() => {
|
||||
if (this.container.parentNode !== null) {
|
||||
this.unmount()
|
||||
}
|
||||
}, delay)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
protected onRemove() {
|
||||
this.stopListening()
|
||||
this.hide()
|
||||
}
|
||||
|
||||
@View.dispose()
|
||||
dispose() {
|
||||
this.remove()
|
||||
}
|
||||
}
|
||||
|
||||
export namespace SnaplineImpl {
|
||||
export interface Options {
|
||||
enabled?: boolean
|
||||
className?: string
|
||||
tolerance?: number
|
||||
sharp?: boolean
|
||||
/**
|
||||
* Specify if snap on node resizing or not.
|
||||
*/
|
||||
resizing?: boolean
|
||||
clean?: boolean | number
|
||||
filter?: Filter
|
||||
}
|
||||
|
||||
export type Filter = null | (string | { id: string })[] | FilterFunction
|
||||
|
||||
export type FilterFunction = (this: Graph, node: Node) => boolean
|
||||
}
|
20
packages/x6-plugin-snapline/src/style/raw.ts
Normal file
20
packages/x6-plugin-snapline/src/style/raw.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* Auto generated file, do not modify it!
|
||||
*/
|
||||
|
||||
export const content = `.x6-widget-snapline {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.x6-widget-snapline-vertical,
|
||||
.x6-widget-snapline-horizontal {
|
||||
stroke: #2ecc71;
|
||||
stroke-width: 1px;
|
||||
}
|
||||
`
|
3
packages/x6-plugin-snapline/tsconfig.json
Normal file
3
packages/x6-plugin-snapline/tsconfig.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json"
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6-vue-shape",
|
||||
"version": "2.0.6-beta.16",
|
||||
"version": "2.0.6-beta.20",
|
||||
"description": "X6 shape for rendering vue components.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
@ -110,7 +110,7 @@
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "ssh://git@github.com/antvis/x6.git",
|
||||
"directory": "packages/x6-react-shape"
|
||||
"directory": "packages/x6-vue-shape"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@antv/x6",
|
||||
"version": "2.0.6-beta.18",
|
||||
"version": "2.0.6-beta.20",
|
||||
"description": "JavaScript diagramming library that uses SVG and HTML for rendering.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
|
@ -3,7 +3,7 @@ import config from '../../configs/rollup-config'
|
||||
export default config({
|
||||
output: [
|
||||
{
|
||||
name: 'X6Next',
|
||||
name: 'X6',
|
||||
format: 'umd',
|
||||
file: 'dist/x6.js',
|
||||
sourcemap: true,
|
||||
|
@ -19,6 +19,7 @@ lerna run build --stream --scope @antv/x6-vue-shape \
|
||||
--scope @antv/x6-react-shape \
|
||||
--scope @antv/x6-plugin-keyboard \
|
||||
--scope @antv/x6-plugin-scroller \
|
||||
--scope @antv/x6-plugin-selection
|
||||
--scope @antv/x6-plugin-selection \
|
||||
--scope @antv/x6-plugin-snapline
|
||||
|
||||
wait
|
||||
|
Reference in New Issue
Block a user