123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- import inherits from 'inherits';
- import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
- import { pointsAligned } from 'diagram-js/lib/util/Geometry';
- import {
- assign
- } from 'min-dash';
- var HIGH_PRIORITY = 3000;
- /**
- * Snaps connections with Manhattan layout.
- */
- export default function LayoutConnectionBehavior(eventBus, gridSnapping, modeling) {
- CommandInterceptor.call(this, eventBus);
- this._gridSnapping = gridSnapping;
- var self = this;
- this.postExecuted([
- 'connection.create',
- 'connection.layout'
- ], HIGH_PRIORITY, function(event) {
- var context = event.context,
- connection = context.connection,
- hints = context.hints || {},
- waypoints = connection.waypoints;
- if (hints.connectionStart || hints.connectionEnd || hints.createElementsBehavior === false) {
- return;
- }
- if (!hasMiddleSegments(waypoints)) {
- return;
- }
- modeling.updateWaypoints(connection, self.snapMiddleSegments(waypoints));
- });
- }
- LayoutConnectionBehavior.$inject = [
- 'eventBus',
- 'gridSnapping',
- 'modeling'
- ];
- inherits(LayoutConnectionBehavior, CommandInterceptor);
- /**
- * Snap middle segments of a given connection.
- *
- * @param {Array<Point>} waypoints
- *
- * @returns {Array<Point>}
- */
- LayoutConnectionBehavior.prototype.snapMiddleSegments = function(waypoints) {
- var gridSnapping = this._gridSnapping,
- snapped;
- waypoints = waypoints.slice();
- for (var i = 1; i < waypoints.length - 2; i++) {
- snapped = snapSegment(gridSnapping, waypoints[i], waypoints[i + 1]);
- waypoints[i] = snapped[0];
- waypoints[i + 1] = snapped[1];
- }
- return waypoints;
- };
- // helpers //////////
- /**
- * Check whether a connection has a middle segments.
- *
- * @param {Array} waypoints
- *
- * @returns {boolean}
- */
- function hasMiddleSegments(waypoints) {
- return waypoints.length > 3;
- }
- /**
- * Check whether an alignment is horizontal.
- *
- * @param {string} aligned
- *
- * @returns {boolean}
- */
- function horizontallyAligned(aligned) {
- return aligned === 'h';
- }
- /**
- * Check whether an alignment is vertical.
- *
- * @param {string} aligned
- *
- * @returns {boolean}
- */
- function verticallyAligned(aligned) {
- return aligned === 'v';
- }
- /**
- * Get middle segments from a given connection.
- *
- * @param {Array} waypoints
- *
- * @returns {Array}
- */
- function snapSegment(gridSnapping, segmentStart, segmentEnd) {
- var aligned = pointsAligned(segmentStart, segmentEnd);
- var snapped = {};
- if (horizontallyAligned(aligned)) {
- // snap horizontally
- snapped.y = gridSnapping.snapValue(segmentStart.y);
- }
- if (verticallyAligned(aligned)) {
- // snap vertically
- snapped.x = gridSnapping.snapValue(segmentStart.x);
- }
- if ('x' in snapped || 'y' in snapped) {
- segmentStart = assign({}, segmentStart, snapped);
- segmentEnd = assign({}, segmentEnd, snapped);
- }
- return [ segmentStart, segmentEnd ];
- }
|