| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- import inherits from 'inherits-browser';
- import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
- import { pointsAligned } from 'diagram-js/lib/util/Geometry';
- import { assign } from 'min-dash';
- import { DEFAULT_CONNECT } from '../../config/constants';
- import { NodeUtils } from '../../utils/nodeUtil';
- /**
- * @typedef {import('diagram-js/lib/core/EventBus').default} EventBus
- * @typedef {import('diagram-js/lib/features/grid-snapping/GridSnapping').default} GridSnapping
- * @typedef {import('../../modeling/Modeling').default} Modeling
- *
- * @typedef {import('diagram-js/lib/util/Types').Point} Point
- */
- const HIGH_PRIORITY = 3000;
- export default function GridSnappingLayoutConnectionBehavior(this: any, eventBus: any, gridSnapping: any, modeling: any, jnpfData: any, injector: any) {
- CommandInterceptor.call(this, eventBus);
- this._gridSnapping = gridSnapping;
- this._injector = injector;
- const self = this;
- this.postExecuted(['connection.create', 'connection.layout'], HIGH_PRIORITY, function (event: any) {
- let context = event.context,
- connection = context.connection,
- waypoints = connection.waypoints;
- let target = connection.target,
- source = connection.source;
- // 横向美化
- if (jnpfData.data?.layout?.value === 'horizontal') {
- let x = source.x;
- let y = source.y + source.height / 2;
- let targetX = target.x + target.width / 2;
- if (source.x + source.width <= target.x) {
- // 右侧
- x = source.x + source.width;
- if (y === target.y + target.height / 2) {
- waypoints = [
- { x: x, y: y },
- { x: target.x, y: target.y + target.height / 2 },
- ];
- } else if (y >= target.y + target.height && x + 30 > target.x) {
- waypoints = [
- { x: x, y: y },
- { x: targetX, y: y },
- { x: targetX, y: target.y + target.height },
- ];
- } else if (y - 10 < target.y && x + 30 > target.x) {
- waypoints = [
- { x: x, y: y },
- { x: targetX, y: y },
- { x: targetX, y: target.y },
- ];
- } else {
- if (target.x - source.x - source.width - DEFAULT_CONNECT / 2 > 0) {
- waypoints = [
- { x: x, y: y },
- { x: target.x - DEFAULT_CONNECT / 2, y: y },
- { x: target.x - DEFAULT_CONNECT / 2, y: target.y + target.height / 2 },
- { x: target.x, y: target.y + target.height / 2 },
- ];
- } else {
- waypoints = [
- { x: x, y: y },
- { x: source.x + source.width + (target.x - source.x - source.width) / 2, y: y },
- { x: source.x + source.width + (target.x - source.x - source.width) / 2, y: target.y + target.height / 2 },
- { x: target.x, y: target.y + target.height / 2 },
- ];
- }
- }
- } else if (source.x > target.x + target.width) {
- // 左侧
- x = target.x + target.width;
- if (x + 30 > source.x) {
- if (y - 10 > target.y + target.height) {
- waypoints = [
- { x: source.x, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: target.y + target.height },
- ];
- } else if (y - 10 < target.y + target.height) {
- waypoints = [
- { x: source.x, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: target.y },
- ];
- }
- } else {
- waypoints = [
- { x: source.x, y: source.y + source.height / 2 },
- { x: (source.x - x) / 2 + x, y: source.y + source.height / 2 },
- { x: (source.x - x) / 2 + x, y: target.y + target.height / 2 },
- { x: x, y: target.y + target.height / 2 },
- ];
- }
- } else {
- // 上侧
- if (target.y < source.y) {
- if (source.x + source.width / 2 === target.x + target.width / 2) {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y },
- { x: target.x + target.width / 2, y: target.y + target.height },
- ];
- } else if (target.y + target.height > source.y - 20) {
- if (source.x + source.width / 2 >= target.x + target.width) {
- // 左上
- waypoints = [
- { x: source.x + source.width / 2, y: source.y },
- { x: source.x + source.width / 2, y: target.y + target.height / 2 },
- { x: target.x + target.width, y: target.y + target.height / 2 },
- ];
- } else if (source.x + source.width / 2 <= target.x) {
- // 右上
- waypoints = [
- { x: source.x + source.width / 2, y: source.y },
- { x: source.x + source.width / 2, y: target.y + target.height / 2 },
- { x: target.x, y: target.y + target.height / 2 },
- ];
- } else {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y },
- { x: source.x + source.width / 2, y: source.y - (source.y - target.y - target.height) / 2 },
- { x: target.x + target.width / 2, y: target.y + target.height },
- ];
- }
- } else {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y },
- { x: source.x + source.width / 2, y: source.y - (source.y - target.y - target.height) / 2 },
- { x: target.x + target.width / 2, y: source.y - (source.y - target.y - target.height) / 2 },
- { x: target.x + target.width / 2, y: target.y + target.height },
- ];
- }
- } else if (target.y + target.height > source.y + source.height) {
- // 下侧
- if (source.x + source.width / 2 === target.x + target.width / 2) {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y + source.height },
- { x: target.x + target.width / 2, y: target.y },
- ];
- } else if (target.y - 20 < source.y + source.height) {
- if (source.x + source.width / 2 >= target.x + target.width) {
- // 左下
- waypoints = [
- { x: source.x + source.width / 2, y: source.y + source.height },
- { x: source.x + source.width / 2, y: target.y + target.height / 2 },
- { x: target.x + target.width, y: target.y + target.height / 2 },
- ];
- } else if (source.x + source.width / 2 <= target.x) {
- // 右下
- waypoints = [
- { x: source.x + source.width / 2, y: source.y + source.height },
- { x: source.x + source.width / 2, y: target.y + target.height / 2 },
- { x: target.x, y: target.y + target.height / 2 },
- ];
- } else {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y + source.height },
- { x: source.x + source.width / 2, y: target.y - (target.y - source.y - source.height) / 2 },
- { x: target.x + target.width / 2, y: target.y - (target.y - source.y - source.height) / 2 },
- { x: target.x + target.width / 2, y: target.y },
- ];
- }
- } else {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y + source.height },
- { x: source.x + source.width / 2, y: target.y - (target.y - source.y - source.height) / 2 },
- { x: target.x + target.width / 2, y: target.y - (target.y - source.y - source.height) / 2 },
- { x: target.x + target.width / 2, y: target.y },
- ];
- }
- }
- }
- }
- if (jnpfData.data?.layout?.value === 'vertical') {
- if (source.y + source.height < target.y) {
- if (source.x + source.width / 2 === target.x + target.width / 2) {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y + source.height },
- { x: target.x + target.width / 2, y: target.y },
- ];
- } else {
- if (source.y + source.height + 20 > target.y && source.x + source.width / 2 < target.x) {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y + source.height },
- { x: source.x + source.width / 2, y: target.y + target.height / 2 },
- { x: target.x, y: target.y + target.height / 2 },
- ];
- } else if (source.y + source.height + 20 > target.y && source.x + source.width / 2 > target.x + target.width + 10) {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y + source.height },
- { x: source.x + source.width / 2, y: target.y + target.height / 2 },
- { x: target.x + target.width, y: target.y + target.height / 2 },
- ];
- } else
- waypoints = [
- { x: source.x + source.width / 2, y: source.y + source.height },
- { x: source.x + source.width / 2, y: source.y + source.height + (target.y - source.y - source.height) / 2 },
- { x: target.x + target.width / 2, y: source.y + source.height + (target.y - source.y - source.height) / 2 },
- { x: target.x + target.width / 2, y: target.y },
- ];
- }
- } else if (source.y > target.y + target.height) {
- if (source.x + source.width / 2 === target.x + target.width / 2) {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y },
- { x: target.x + target.width / 2, y: target.y + target.height },
- ];
- } else {
- if (source.y - 20 < target.y + target.height && source.x + source.width / 2 < target.x) {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y },
- { x: source.x + source.width / 2, y: target.y + target.height / 2 },
- { x: target.x, y: target.y + target.height / 2 },
- ];
- } else if (source.y - 20 < target.y + target.height && source.x + source.width / 2 > target.x + target.width + 10) {
- waypoints = [
- { x: source.x + source.width / 2, y: source.y },
- { x: source.x + source.width / 2, y: target.y + target.height / 2 },
- { x: target.x + target.width, y: target.y + target.height / 2 },
- ];
- } else
- waypoints = [
- { x: source.x + source.width / 2, y: source.y },
- { x: source.x + source.width / 2, y: source.y - (source.y - target.y - target.height) / 2 },
- { x: target.x + target.width / 2, y: source.y - (source.y - target.y - target.height) / 2 },
- { x: target.x + target.width / 2, y: target.y + target.height },
- ];
- }
- } else if (source.x + source.width / 2 < target.x - 10) {
- // 右侧
- if (source.x + source.width >= target.x - 10 && source.y + source.height / 2 >= target.y + target.height - 10) {
- waypoints = [
- { x: source.x + source.width, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: target.y + target.height },
- ];
- } else if (source.x + source.width >= target.x - 10 && source.y + source.height / 2 + 10 <= target.y) {
- waypoints = [
- { x: source.x + source.width, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: target.y },
- ];
- } else {
- waypoints = [
- { x: source.x + source.width, y: source.y + source.height / 2 },
- { x: source.x + source.width + (target.x - source.x - source.width) / 2, y: source.y + source.height / 2 },
- { x: source.x + source.width + (target.x - source.x - source.width) / 2, y: target.y + target.height / 2 },
- { x: target.x, y: target.y + target.height / 2 },
- ];
- }
- } else if (source.x + source.width / 2 > target.x + target.width - 10) {
- // 左侧
- if (source.x < target.x + target.width + 20 && source.y + source.height / 2 >= target.y + target.height - 10) {
- waypoints = [
- { x: source.x, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: target.y + target.height },
- ];
- } else if (source.x < target.x + target.width + 20 && source.y + source.height / 2 + 10 <= target.y) {
- waypoints = [
- { x: source.x, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: source.y + source.height / 2 },
- { x: target.x + target.width / 2, y: target.y },
- ];
- } else
- waypoints = [
- { x: source.x, y: source.y + source.height / 2 },
- { x: target.x + target.width + (source.x - target.x - target.width) / 2, y: source.y + source.height / 2 },
- { x: target.x + target.width + (source.x - target.x - target.width) / 2, y: target.y + target.height / 2 },
- { x: target.x + target.width, y: target.y + target.height / 2 },
- ];
- }
- }
- // 判断是横向还是纵向 如果是纵向 需要重新修改坐标
- modeling.updateWaypoints(connection, self.snapMiddleSegments(waypoints));
- let elementRegistry = injector.get('elementRegistry');
- let labelCenter = NodeUtils.updateLabelWaypoints(connection, elementRegistry, jnpfData);
- let connectLabel = connection.label;
- if (connectLabel) {
- let label = elementRegistry.get(connectLabel.id);
- label.x = labelCenter.x;
- label.y = labelCenter.y;
- modeling.updateProperties(label, {});
- }
- });
- }
- GridSnappingLayoutConnectionBehavior.$inject = ['eventBus', 'gridSnapping', 'modeling', 'jnpfData', 'injector'];
- inherits(GridSnappingLayoutConnectionBehavior, CommandInterceptor);
- /**
- * Snap middle segments of a given connection.
- *
- * @param {Point[]} waypoints
- *
- * @return {Point[]}
- */
- GridSnappingLayoutConnectionBehavior.prototype.snapMiddleSegments = function (this: any, waypoints: any[]) {
- const gridSnapping = this._gridSnapping;
- waypoints = waypoints.slice();
- for (let i = 1; i < waypoints.length - 2; i++) {
- const snapped = snapSegment(gridSnapping, waypoints[i], waypoints[i + 1]);
- waypoints[i] = snapped[0];
- waypoints[i + 1] = snapped[1];
- }
- return waypoints;
- };
- /**
- * Check whether a connection has middle segments.
- *
- * @param {Point[]} waypoints
- *
- * @return {boolean}
- */
- function hasMiddleSegments(waypoints: any[]) {
- return waypoints.length > 3;
- }
- /**
- * Check whether an alignment is horizontal.
- *
- * @param {string} aligned
- *
- * @return {boolean}
- */
- function horizontallyAligned(aligned: string) {
- return aligned === 'h';
- }
- /**
- * Check whether an alignment is vertical.
- *
- * @param {string} aligned
- *
- * @return {boolean}
- */
- function verticallyAligned(aligned: string) {
- return aligned === 'v';
- }
- /**
- * Get middle segments from a given connection.
- *
- * @param {Point[]} waypoints
- *
- * @return {Point[]}
- */
- function snapSegment(gridSnapping: any, segmentStart: any, segmentEnd: any) {
- const aligned: any = pointsAligned(segmentStart, segmentEnd);
- const snapped: any = {};
- if (horizontallyAligned(aligned)) {
- snapped.y = gridSnapping.snapValue(segmentStart.y);
- }
- if (verticallyAligned(aligned)) {
- snapped.x = gridSnapping.snapValue(segmentStart.x);
- }
- if ('x' in snapped || 'y' in snapped) {
- segmentStart = assign({}, segmentStart, snapped);
- segmentEnd = assign({}, segmentEnd, snapped);
- }
- return [segmentStart, segmentEnd];
- }
|