工作流插件参与进入项目本体

This commit is contained in:
QM303176530
2020-10-24 17:04:04 +08:00
parent cebb9b3002
commit 84e35753cf
97 changed files with 6198 additions and 14 deletions
@@ -0,0 +1,90 @@
export default function(G6){
G6.registerBehavior('clickSelected', {
getDefaultCfg() {
return {
multiple: false,
}
},
getEvents() {
return {
'node:click': 'onClick',
'edge:click': 'onClick',
'edge:mouseover': 'onEdgeMouseOver',
'edge:mouseleave': 'onEdgeMouseLeave',
'canvas:click': 'onCanvasClick',
'node:mouseover': 'onNodeMouseOver',
}
},
onClick(e) {
this._clearSelected();
this.graph.setItemState(e.item, 'selected', true);
let selectedItems = this.graph.get('selectedItems');
if(!selectedItems)
selectedItems = [];
selectedItems = [e.item.get('id')];
this.graph.set('selectedItems',selectedItems);
this.graph.emit('afteritemselected',selectedItems);
},
onNodeMouseOver(e){
if(this.graph.getCurrentMode() === 'edit')
this.graph.setItemState(e.item, 'hover', true);
else
this.graph.setItemState(e.item, 'hover', false);
},
onEdgeMouseOver(e){
if(this.graph.getCurrentMode() === 'edit' && !e.item.hasState('selected'))
this.graph.setItemState(e.item, 'hover', true);
},
onEdgeMouseLeave(e){
if(this.graph.getCurrentMode() === 'edit' && !e.item.hasState('selected'))
this.graph.setItemState(e.item, 'hover', false);
},
onCanvasClick(){
this._clearSelected();
this.graph.emit('afteritemselected',[]);
},
_clearSubProcessSelected() {
const subProcessList = this.graph.findAll('node', (node) => {
if (node.get('model')) {
const clazz = node.get('model').clazz;
return clazz === 'subProcess';
} else {
return false;
}
});
subProcessList.forEach((node) => {
const group = node.getContainer();
const subGroup = group.subGroup;
this._clearGroupSelected(subGroup);
});
},
_clearGroupSelected(group) {
const selected = group.findAll((subGroup) => {
const node = subGroup.get('item');
if (node) {
return node.hasState('selected');
} else {
return false;
}
});
selected.forEach(subGroup => {
const node = subGroup.get('item');
if (node) {
node.setState('selected', false);
}
});
},
_clearSelected(){
let selected = this.graph.findAllByState('node', 'selected');
selected.forEach(node => {
this.graph.setItemState(node, 'selected', false);
});
selected = this.graph.findAllByState('edge', 'selected');
selected.forEach(edge => {
this.graph.setItemState(edge, 'selected', false);
});
this._clearSubProcessSelected();
this.graph.set('selectedItems', []);
}
});
}
@@ -0,0 +1,30 @@
export default function(G6){
G6.registerBehavior('deleteItem', {
getEvents() {
return {
'keydown': 'onKeydown',
'canvas:mouseleave': 'onCanvasLeave',
'canvas:mouseenter': 'onCanvasFocus',
}
},
onKeydown(e){
const items = this.graph.get('selectedItems');
const focus = this.graph.get('focusGraphWrapper');
if(e.keyCode === 8 && items && items.length > 0 && focus){
if(this.graph.executeCommand) {
this.graph.executeCommand('delete', {});
}else{
this.graph.remove(items[0]);
}
this.graph.set('selectedItems',[]);
this.graph.emit('afteritemselected',[]);
}
},
onCanvasLeave(e){
this.graph.set('focusGraphWrapper',false);
},
onCanvasFocus(){
this.graph.set('focusGraphWrapper',true);
}
});
}
@@ -0,0 +1,207 @@
import editorStyle from "../util/defaultStyle";
import { Marker } from '@antv/g-canvas/lib/shape';
export default function (G6) {
G6.registerBehavior('dragEdge', {
getDefaultCfg() {
return {
updateEdge: true,
delegate: true,
delegateStyle: {},
dragEdge: false,
};
},
getEvents() {
return {
'anchor:dragstart': 'onDragStart',
'anchor:drag': 'onDrag',
'anchor:dragend': 'onDragEnd',
'anchor:dragenter': 'onDragEnter',
'anchor:dragleave': 'onDragLeave',
};
},
onDragEnter(e) {
if (!this.origin) {
return;
}
if (!this.sameNode(e)) {
e.item.setHotspotActived(true);
this.origin.targetNode = e.target.getParent().getParent().get('item');
this.origin.targetAnchor = e.item.get('index');
}
},
onDragLeave(e) {
if (!this.origin) {
return;
}
if (!this.sameNode(e)) {
e.item.setHotspotActived(false);
this.origin.targetNode = null;
this.origin.targetAnchor = null;
}
},
onDragStart(e) {
const node = e.target.getParent().getParent().get('item');
const anchorIndex = e.item.get('index');
const point = node.getAnchorPoints()[anchorIndex];
this.target = e.item;
const groupId = node.get('groupId');
if (groupId) {
const subProcessNode = e.target.getParent().getParent().getParent().getParent().get('item');
const subProcessBBox = subProcessNode.getBBox();
this.origin = {
x: point.x + subProcessBBox.x + subProcessBBox.width / 2,
y: point.y + subProcessBBox.y + subProcessBBox.height / 2,
sourceNode: node,
sourceAnchor: anchorIndex
};
this.dragEdgeBeforeShowAnchorBySub(subProcessNode);
} else {
this.origin = {
x: point.x,
y: point.y,
sourceNode: node,
sourceAnchor: anchorIndex
};
this.dragEdgeBeforeShowAnchor(e);
}
this.graph.set('edgeDragging', true);
},
onDrag(e) {
if (!this.origin) {
return;
}
this._updateEdge(this.target, e);
},
onDragEnd(e) {
if (!this.origin) {
return;
}
const delegateShape = e.item.get('edgeDelegate');
if (delegateShape) {
delegateShape.remove();
this.target.set('edgeDelegate', null);
}
this._updateEdge(this.target, e, true);
this.graph.setItemState(this.origin.sourceNode, 'show-anchor', false);
this.target = null;
this.origin = null;
this.graph.set('edgeDragging', false);
},
sameNode(e) {
return e.target instanceof Marker && e.target.getParent() && e.target.getParent().getParent().get('item').get('id') === this.origin.sourceNode.get('id')
},
dragEdgeBeforeShowAnchorBySub(subProcessNode) {
const group = subProcessNode.getContainer();
group.nodes.forEach(a => {
const aGroup = a.getContainer();
aGroup.showAnchor();
aGroup.anchorShapes.forEach(b => b.get('item').showHotpot());
});
},
dragEdgeBeforeShowAnchor(e) {
const sourceGroupId = this.origin.sourceNode.getModel().groupId;
this.graph.getNodes().forEach(node => {
if (node.getModel().clazz === 'start'
|| node.getModel().clazz === 'timerStart'
|| node.getModel().clazz === 'messageStart')
return;
const targetGroupId = node.getModel().groupId;
if (!sourceGroupId && targetGroupId || sourceGroupId && !targetGroupId || sourceGroupId !== targetGroupId)
return;
const group = node.getContainer();
group.showAnchor();
group.anchorShapes.forEach(a => a.get('item').showHotpot())
});
},
_updateEdge(item, e, force) {
const x = e.x;
const y = e.y;
if (this.delegate && !force) {
this._updateEdgeDelegate(item, x, y);
return;
}
const node = e.target.getParent().getParent().get('item');
const groupId = node.get('groupId');
if (groupId) {
this._addSubProcessEdge(node, e);
} else {
this._addEdge(e);
}
this._clearAllAnchor();
this.graph.paint();
},
_updateEdgeDelegate(item, x, y) {
const self = this;
let edgeShape = item.get('edgeDelegate');
if (!edgeShape) {
const parent = self.graph.get('group');
edgeShape = parent.addShape('line', {
attrs: {
x1: this.origin.x,
y1: this.origin.y,
x2: x,
y2: y,
...editorStyle.edgeDelegationStyle,
}
});
edgeShape.set('capture', false);
item.set('edgeDelegate', edgeShape);
}
edgeShape.attr({ x2: x, y2: y });
this.graph.paint();
},
_clearAllAnchor() {
this.graph.getNodes().forEach(node => {
const group = node.getContainer();
group.clearAnchor();
});
},
_addSubProcessEdge(node, e) {
if (this.origin.targetNode) {
const group = node.getContainer().getParent().getParent();
const subProcess = node.getContainer().getParent().getParent().get('item');
const sourceId = this.origin.sourceNode.get('id');
const targetId = this.origin.targetNode.get('id');
const addModel = {
id: sourceId + '_to_' + targetId,
clazz: 'flow',
source: sourceId,
target: targetId,
sourceAnchor: this.origin.sourceAnchor,
targetAnchor: this.origin.targetAnchor,
};
const resultModel = group.addEdgeModel(subProcess, addModel);
if (this.graph.executeCommand) {
this.graph.executeCommand('update', {
itemId: subProcess.get('id'),
updateModel: resultModel
});
} else {
this.graph.updateItem(node, resultModel);
}
}
},
_addEdge() {
if (this.origin.targetNode) {
const timestamp = new Date().getTime();
const addModel = {
id: 'flow' + timestamp,
clazz: 'flow',
source: this.origin.sourceNode.get('id'),
target: this.origin.targetNode.get('id'),
sourceAnchor: this.origin.sourceAnchor,
targetAnchor: this.origin.targetAnchor,
};
if (this.graph.executeCommand) {
this.graph.executeCommand('add', {
type: 'edge',
addModel: addModel
});
} else {
this.graph.add('edge', addModel);
}
}
}
});
}
@@ -0,0 +1,147 @@
import editorStyle from "../util/defaultStyle";
export default function(G6){
G6.registerBehavior('dragNode', {
getDefaultCfg() {
return {
updateEdge: true,
delegate: true,
delegateStyle: {},
align: true,
};
},
getEvents() {
return {
'node:dragstart': 'onDragStart',
'node:drag': 'onDrag',
'node:dragend': 'onDragEnd'
};
},
onDragStart(e) {
if (!this.shouldBegin.call(this, e)) {
return;
}
this.target = e.item;
this.origin = {
x: e.x,
y: e.y
};
},
onDrag(e) {
if (!this.origin) {
return;
}
if (!this.get('shouldUpdate').call(this, e)) {
return;
}
const origin = this.origin;
const groupId = this.target.get('groupId');
const model = this.target.get('model');
if (!this.point) {
this.point = {
x: model.x,
y: model.y
};
}
if (groupId) {
const subProcessNode = this.graph.findById(groupId);
const subProcessBBox = subProcessNode.getBBox();
const x = e.x - origin.x + this.point.x + subProcessBBox.x + subProcessBBox.width / 2;
const y = e.y - origin.y + this.point.y + subProcessBBox.y + subProcessBBox.height / 2;
this.origin = { x: e.x, y: e.y };
this.point = {
x: x - subProcessBBox.x - subProcessBBox.width / 2,
y: y - subProcessBBox.y - subProcessBBox.height / 2
};
if (this.delegate) {
this._updateDelegate(this.target, x, y);
}
} else {
const x = e.x - origin.x + this.point.x;
const y = e.y - origin.y + this.point.y;
this.origin = { x: e.x, y: e.y };
this.point = { x, y };
if (this.delegate) {
this._updateDelegate(this.target, x, y);
}
}
},
onDragEnd(e) {
if (!this.shouldEnd.call(this, e)) {
return;
}
if (!this.origin) {
return;
}
const delegateShape = e.item.get('delegateShape');
const groupId = this.target.get('groupId');
if (groupId) {
if (delegateShape) {
const subProcessNode = this.graph.findById(groupId);
const subProcessBBox = subProcessNode.getBBox();
const bbox = delegateShape.getBBox();
const x = bbox.x + bbox.width / 2 - subProcessBBox.x - subProcessBBox.width / 2;
const y = bbox.y + bbox.height / 2 - subProcessBBox.y - subProcessBBox.height / 2;
delegateShape.remove();
this.target.set('delegateShape', null);
const group = subProcessNode.getContainer();
const id = this.target.get('id');
const resultModel = group.updateNodeModel(subProcessNode, id, { x, y });
this._updateItem(subProcessNode, resultModel);
}
} else {
if (delegateShape) {
const bbox = delegateShape.getBBox();
const x = bbox.x + bbox.width / 2;
const y = bbox.y + bbox.height / 2;
delegateShape.remove();
this.target.set('delegateShape', null);
this._updateItem(this.target, { x, y });
}
}
this.point = null;
this.origin = null;
this.graph.emit('afternodedragend', this.target);
},
_updateItem(item, point) {
if(this.graph.executeCommand) {
this.graph.executeCommand('update', {
itemId: item.get('id'),
updateModel: point
});
}else {
if (this.get('updateEdge')) {
this.graph.updateItem(item, point);
} else {
item.updatePosition(point);
this.graph.paint();
}
}
},
_updateDelegate(item, x, y) {
const self = this;
let shape = item.get('delegateShape');
const bbox = item.get('keyShape').getBBox();
if (!shape) {
const parent = self.graph.get('group');
const attrs = editorStyle.nodeDelegationStyle;
// model上的x, y是相对于图形中心的,delegateShape是g实例,x,y是绝对坐标
shape = parent.addShape('rect', {
attrs: {
width: bbox.width,
height: bbox.height,
x: x - bbox.width / 2,
y: y - bbox.height / 2,
nodeId:item.get('id'),
...attrs
}
});
shape.set('capture', false);
item.set('delegateShape', shape);
}
shape.attr({ x: x - bbox.width / 2, y: y - bbox.height / 2 });
this.graph.paint();
this.graph.emit('afternodedrag',shape);
},
});
}
@@ -0,0 +1,149 @@
import editorStyle from "../util/defaultStyle";
import { getShapeName } from '../util/clazz';
export default function(G6){
G6.registerBehavior('dragPanelItemAddNode', {
getDefaultCfg() {
return {
};
},
getEvents() {
return {
'canvas:mousemove': 'onMouseMove',
'canvas:mouseup': 'onMouseUp',
'canvas:mouseleave': 'onMouseLeave',
}
},
onMouseMove(e){
if(this.graph.get('addNodeDragging')){
let delegateShape = this.graph.get('addDelegateShape');
const addModel = this.graph.get('addModel');
const width = parseInt(addModel.size.split('*')[0]);
const height = parseInt(addModel.size.split('*')[1]);
const point = this.graph.getPointByClient(e.x,e.y);
const x = point.x;
const y = point.y;
if (!delegateShape) {
const parent = this.graph.get('group');
delegateShape = parent.addShape('rect', {
attrs: {
width,
height,
x: x - width / 2,
y: y - height / 2,
...editorStyle.nodeDelegationStyle,
}
});
delegateShape.set('capture', false);
this.graph.set('addDelegateShape', delegateShape);
}
delegateShape.attr({ x: x - width / 2, y: y - height / 2 });
this.graph.paint();
this.graph.emit('afternodedrag',delegateShape);
}
},
onMouseUp(e){
if (this.graph.get('addNodeDragging')) {
const p = this.graph.getPointByClient(e.clientX, e.clientY);
const subProcessNode = this.graph.find('node', (node) => {
if (node.get('model')) {
const clazz = node.get('model').clazz;
if (clazz === 'subProcess') {
const bbox = node.getBBox();
return p.x > bbox.minX && bbox.maxX > p.x
&& p.y > bbox.minY && bbox.maxY > p.y;
}
} else {
return false;
}
});
if (subProcessNode) {
if (p.x > 0 && p.y > 0) {
this._addNodeBySubProcess(p, subProcessNode);
}
} else {
if (p.x > 0 && p.y > 0) {
this._addNode(p);
}
}
}
},
_addNodeBySubProcess(p, node) {
if (this.graph.get('addNodeDragging')) {
const addModel = this.graph.get('addModel');
const { clazz = 'userTask' } = addModel;
addModel.shape = getShapeName(clazz);
addModel.size = addModel.size.split("*");
const timestamp = new Date().getTime();
const id = clazz + timestamp;
const bbox = node.getBBox();
const x = p.x - bbox.x - bbox.width / 2;
const y = p.y - bbox.y - bbox.height / 2;
const nodeCfg = {
...addModel,
x,
y,
id
};
const group = node.getContainer();
const resultModel = group.addNodeModel(node, nodeCfg);
if (this.graph.executeCommand) {
this.graph.executeCommand('update', {
itemId: node.get('id'),
updateModel: resultModel,
});
} else {
this.graph.updateItem(node, resultModel);
}
}
},
onMouseLeave(e){
if (this.graph.get('addNodeDragging')) {
this._clearDelegate();
this.graph.emit('afternodedragend');
}
},
_clearDelegate(){
const delegateShape = this.graph.get('addDelegateShape');
if (delegateShape) {
delegateShape.remove();
this.graph.set('addDelegateShape', null);
this.graph.paint();
}
this.graph.emit('afternodedragend');
},
_addNode(p){
if (this.graph.get('addNodeDragging')) {
const addModel = this.graph.get('addModel');
const { clazz = 'userTask' } = addModel;
//type、shape属性同时存在即兼容之前版本的数据,又兼容g6的升级
addModel.type = getShapeName(clazz);
addModel.shape = getShapeName(clazz);
const timestamp = new Date().getTime();
const id = clazz + timestamp;
const x = p.x;
const y = p.y;
if (this.graph.executeCommand) {
this.graph.executeCommand('add', {
type: 'node',
addModel: {
...addModel,
x: x,
y: y,
id: id,
},
});
} else {
this.graph.add('node', {
...addModel,
x: x,
y: y,
id: id,
});
}
this._clearDelegate();
}
}
});
}
@@ -0,0 +1,97 @@
export default function(G6) {
G6.registerBehavior('dragPoint', {
getDefaultCfg() {
return {
updateEdge: true,
delegate: true,
delegateStyle: {},
dragEdge: false,
};
},
getEvents() {
return {
'controlPoint:dragstart': 'onDragStart',
'controlPoint:drag': 'onDrag',
'controlPoint:dragend': 'onDragEnd',
};
},
onDragStart(e) {
const node = e.target.getParent().getParent().get('item');
const anchorIndex = e.item.get('index');
this.target = e.item;
this.origin = {
x: e.x,
y: e.y,
sourceNode: node,
sourceAnchor: anchorIndex,
};
this.graph.set('edgeDragging', true);
},
onDrag(e) {
if (!this.origin) {
return;
}
const node = e.target.getParent().getParent().get('item');
const anchorIndex = e.item.get('index');
const model = node.getModel();
const currentWidth = model.size[0];
const currentHeight = model.size[1];
const addWidth = e.x - this.origin.x;
const addHeight = e.y - this.origin.y;
let width = currentWidth;
let height = currentHeight;
// 0,0 // 两个都是负的变大
// 1,0 // 一正 一负 变大
// 1,1 // 两个都是负变大
// 0,1 // 一负 一正 变大
const pointIndex = this.origin.sourceAnchor;
if (pointIndex === 0) {
width = currentWidth - addWidth;
height = currentHeight - addHeight;
} else if (pointIndex === 1) {
height = currentHeight - addHeight;
} else if (pointIndex === 2) {
width = currentWidth + addWidth;
height = currentHeight - addHeight;
} else if (pointIndex === 3) {
width = currentWidth + addWidth;
} else if (pointIndex === 4) {
width = currentWidth + addWidth;
height = currentHeight + addHeight;
} else if (pointIndex === 5) {
height = currentHeight + addHeight;
} else if (pointIndex === 6) {
width = currentWidth - addWidth;
height = currentHeight + addHeight;
} else if (pointIndex === 7) {
width = currentWidth - addWidth;
}
const group = node.getContainer();
// 移动过程中的控制点全部隐藏。
group.controlPointShapes.forEach(a => a.hide());
this.graph.updateItem(node, { size: [width, height], });
this.origin = {
x: e.x,
y: e.y,
sourceNode: node,
sourceAnchor: anchorIndex,
};
},
onDragEnd(e) {
if (!this.origin) {
return;
}
const node = e.target.getParent().getParent().get('item');
this.target = null;
this.origin = null;
const group = node.getContainer();
group.clearControlPoints(group);
group.showControlPoints(group);
this.graph.set('edgeDragging', false);
},
});
}
@@ -0,0 +1,23 @@
export default function(G6){
G6.registerBehavior('hoverAnchorActived', {
getEvents() {
return {
'anchor:mouseenter': 'onAnchorEnter',
'anchor:mousemove': 'onAnchorEnter',
'anchor:mouseleave': 'onAnchorLeave',
}
},
onAnchorEnter(e){
if(!this.graph.get('edgeDragging'))
this.graph.setItemState(e.item, 'active-anchor', true);
},
onAnchorLeave(e){
if(!this.graph.get('edgeDragging')) {
let node = e.item.getContainer().getParent();
if(node) {
this.graph.setItemState(e.item, 'active-anchor', false);
}
}
}
});
}
@@ -0,0 +1,29 @@
import { Marker } from '@antv/g-canvas/lib/shape';
export default function(G6){
G6.registerBehavior('hoverNodeActived', {
getEvents() {
return {
'node:mouseenter': 'onNodeEnter',
'node:mouseleave': 'onNodeLeave',
'anchor:mouseleave': 'onAnchorLeave',
}
},
onAnchorLeave(e){
let node = e.item.getContainer().getParent();
if(node && !this.graph.get('edgeDragging')) {
this.graph.setItemState(node.get('item'), 'show-anchor', false);
}
},
onNodeEnter(e){
const clazz = e.item.getModel().clazz;
if(clazz !== 'endEvent' && !this.graph.get('edgeDragging')){
this.graph.setItemState(e.item, 'show-anchor', true);
}
},
onNodeLeave(e){
if(!(e.target instanceof Marker) && !this.graph.get('edgeDragging')) {
this.graph.setItemState(e.item, 'show-anchor', false);
}
},
});
}
@@ -0,0 +1,20 @@
import clickSelected from './clickSelected'
import deleteItem from './deleteItem'
import dragNode from './dragNode'
import dragEdge from './dragEdge'
import dragPanelItemAddNode from './dragPanelItemAddNode'
import hoverAnchorActived from './hoverAnchorActived'
import hoverNodeActived from './hoverNodeActived'
import itemAlign from './itemAlign'
import dragPoint from "./dragPoint";
export default function(G6){
clickSelected(G6);
deleteItem(G6);
dragNode(G6);
dragEdge(G6);
dragPanelItemAddNode(G6);
hoverAnchorActived(G6);
hoverNodeActived(G6);
itemAlign(G6);
dragPoint(G6);
}
@@ -0,0 +1,140 @@
import { each } from '@antv/util';
import { vec2 } from '@antv/matrix-util';
export default function(G6){
const {mix} = G6.Util;
G6.registerBehavior('itemAlign', {
getDefaultCfg() {
return {
alignLineStyle: { stroke: '#FA8C16', lineWidth: 1 },
tolerance: 5,
_alignLines: [],
};
},
getEvents() {
return {
'afternodedrag': 'onDrag',
'afternodedragend': 'onDragEnd',
};
},
onDrag(shape) {
this._clearAlignLine();
this._itemAlign(shape);
},
onDragEnd() {
this._clearAlignLine();
},
_itemAlign(item){
const bbox = item.getBBox();
const ct = { x: bbox.x + bbox.width / 2, y: bbox.y };
const cc = { x: bbox.x + bbox.width / 2, y: bbox.y + bbox.height / 2 };
const cb = { x: bbox.x + bbox.width / 2, y: bbox.y + bbox.height };
const lc = { x: bbox.x, y: bbox.y + bbox.height / 2 };
const rc = { x: bbox.x + bbox.width, y: bbox.y + bbox.height / 2 };
const nodes = this.graph.getNodes();
each(nodes, (node) => {
const horizontalLines = [];
const verticalLines = [];
let p = null;
const bbox1 = node.getBBox();
each(this.getHorizontalLines(bbox1), (line) => {
horizontalLines.push(this.getDistance(line,ct));
horizontalLines.push(this.getDistance(line,cc));
horizontalLines.push(this.getDistance(line,cb));
});
each(this.getVerticalLines(bbox1), (line) => {
verticalLines.push(this.getDistance(line,lc));
verticalLines.push(this.getDistance(line,cc));
verticalLines.push(this.getDistance(line,rc));
});
horizontalLines.sort((a,b)=> a.dis-b.dis);
verticalLines.sort((a,b)=> a.dis-b.dis);
if(horizontalLines.length > 0 && horizontalLines[0].dis < this.tolerance){
item.attr({y: horizontalLines[0].line[1] - horizontalLines[0].point.y + bbox.y });
p = { horizontals: [horizontalLines[0]] };
for (let i = 1; i < 3; i++) horizontalLines[0].dis === horizontalLines[i].dis && p.horizontals.push(horizontalLines[i]);
}
if(verticalLines.length > 0 && verticalLines[0].dis < this.tolerance){
item.attr({ x: verticalLines[0].line[0] - verticalLines[0].point.x + bbox.x });
p ? p.verticals = [verticalLines[0]] : p = { verticals: [verticalLines[0]] };
for (let i = 1; i < 3; i++) verticalLines[0].dis === verticalLines[i].dis && p.verticals.push(verticalLines[i]);
}
if(p){
p.bbox = bbox;
this._addAlignLine(p);
}
})
},
_addAlignLine(p){
const group = this.graph.get('group');
const bbox = p.bbox;
const lineStyle = this.alignLineStyle;
const lineArr = this._alignLines;
if(p.horizontals){
each(p.horizontals, function(lineObj) {
const line = lineObj.line;
const point = lineObj.point;
const lineHalf = (line[0] + line[2]) / 2;
let x1,x2;
if(point.x < lineHalf){
x1 = point.x - bbox.width / 2;
x2 = Math.max(line[0], line[2]);
}else{
x1 = point.x + bbox.width / 2;
x2 = Math.min(line[0], line[2]);
}
const shape = group.addShape('line', { attrs: mix({ x1, y1: line[1], x2, y2: line[1] }, lineStyle), capture: false });
lineArr.push(shape);
})
}
if(p.verticals){
each(p.verticals, function(lineObj) {
const line = lineObj.line;
const point = lineObj.point;
const lineHalf = (line[1] + line[3]) / 2;
let y1,y2;
if(point.y < lineHalf){
y1 = point.y - bbox.height / 2;
y2 = Math.max(line[1], line[3]);
}else{
y1 = point.y + bbox.height / 2;
y2 = Math.min(line[1], line[3]);
}
const shape = group.addShape('line', { attrs: mix({ x1: line[0], y1, x2: line[0], y2 }, lineStyle), capture: false });
lineArr.push(shape);
})
}
},
getHorizontalLines(bbox){
return [
[bbox.minX, bbox.minY, bbox.maxX, bbox.minY], // tltr
[bbox.minX, bbox.centerY, bbox.maxX, bbox.centerY], // lcrc
[bbox.minX, bbox.maxY, bbox.maxX, bbox.maxY], // blbr
]
},
getVerticalLines(bbox){
return [
[bbox.minX, bbox.minY, bbox.minX, bbox.maxY], // tlbl
[bbox.centerX, bbox.minY, bbox.centerX, bbox.maxY], // tcbc
[bbox.maxX, bbox.minY, bbox.maxX, bbox.maxY], // trbr
]
},
getDistance(line, point) {
return { line, point, dis: this.pointLineDistance(line[0], line[1], line[2], line[3], point.x, point.y) };
},
pointLineDistance: function(lineX1, lineY1, lineX2, lineY2, pointX, pointY) {
const lineLength = [lineX2 - lineX1, lineY2 - lineY1];
if (vec2.exactEquals(lineLength, [0, 0])) return NaN;
let s = [-lineLength[1], lineLength[0]];
vec2.normalize(s, s);
return Math.abs(vec2.dot([pointX - lineX1, pointY - lineY1], s));
},
_clearAlignLine(){
each(this._alignLines, (line) => {
line.remove();
});
this._alignLines = [];
this.graph.paint();
},
});
}