refactor to simplify

This commit is contained in:
Mutasem 2021-11-15 15:05:09 +01:00
parent 6a080a1ac5
commit 2db0ed504c

View file

@ -1,9 +1,90 @@
(function () { (function () {
"use strict"; "use strict";
var root = this, _jp = root.jsPlumb, _ju = root.jsPlumbUtil, _jg = root.Biltong; const root = this, _jp = root.jsPlumb, _ju = root.jsPlumbUtil, _jg = root.Biltong;
var STRAIGHT = "Straight"; const STRAIGHT = "Straight";
var ARC = "Arc"; const ARC = "Arc";
const _prepareCompute = function (params, overrideTargetEndpoint) {
let { targetPos, targetEndpoint, getEndpointOffset } = params;
const gap = params.gap || 0;
const sourceGap = _ju.isArray(gap) ? gap[0] : gap;
const targetGap = _ju.isArray(gap) ? gap[1] : gap;
const stub = params.stub || 0;
const sourceStub = _ju.isArray(stub) ? stub[0] : stub;
const targetStub = _ju.isArray(stub) ? stub[1] : stub;
// if has override, use override
if (
overrideTargetEndpoint
) {
const target = overrideTargetEndpoint.anchor.lastReturnValue;
targetPos = [target[0], target[1]];
targetEndpoint = overrideTargetEndpoint;
}
// this.strokeWidth = params.strokeWidth;
var segment = _jg.quadrant(params.sourcePos, targetPos),
swapX = targetPos[0] < params.sourcePos[0],
swapY = targetPos[1] < params.sourcePos[1],
lw = params.strokeWidth || 1,
so = params.sourceEndpoint.anchor.getOrientation(params.sourceEndpoint), // source orientation
to = targetEndpoint.anchor.getOrientation(targetEndpoint), // target orientation
x = swapX ? targetPos[0] : params.sourcePos[0],
y = swapY ? targetPos[1] : params.sourcePos[1],
w = Math.abs(targetPos[0] - params.sourcePos[0]),
h = Math.abs(targetPos[1] - params.sourcePos[1]);
// if either anchor does not have an orientation set, we derive one from their relative
// positions. we fix the axis to be the one in which the two elements are further apart, and
// point each anchor at the other element. this is also used when dragging a new connection.
if (so[0] === 0 && so[1] === 0 || to[0] === 0 && to[1] === 0) {
var index = w > h ? 0 : 1, oIndex = [1, 0][index];
so = [];
to = [];
so[index] = params.sourcePos[index] > targetPos[index] ? -1 : 1;
to[index] = params.sourcePos[index] > targetPos[index] ? 1 : -1;
so[oIndex] = 0;
to[oIndex] = 0;
}
const sx = swapX ? w + (sourceGap * so[0]) : sourceGap * so[0],
sy = swapY ? h + (sourceGap * so[1]) : sourceGap * so[1],
tx = swapX ? targetGap * to[0] : w + (targetGap * to[0]),
ty = swapY ? targetGap * to[1] : h + (targetGap * to[1]),
oProduct = ((so[0] * to[0]) + (so[1] * to[1]));
const sourceStubWithOffset = sourceStub + (getEndpointOffset && params.sourceEndpoint ? getEndpointOffset(params.sourceEndpoint) : 0);
const targetStubWithOffset = targetStub + (getEndpointOffset && targetEndpoint ? getEndpointOffset(targetEndpoint) : 0);
var result = {
sx: sx, sy: sy, tx: tx, ty: ty, lw: lw,
xSpan: Math.abs(tx - sx),
ySpan: Math.abs(ty - sy),
mx: (sx + tx) / 2,
my: (sy + ty) / 2,
so: so, to: to, x: x, y: y, w: w, h: h,
segment: segment,
startStubX: sx + (so[0] * sourceStubWithOffset),
startStubY: sy + (so[1] * sourceStubWithOffset),
endStubX: tx + (to[0] * targetStubWithOffset),
endStubY: ty + (to[1] * targetStubWithOffset),
isXGreaterThanStubTimes2: Math.abs(sx - tx) > (sourceStubWithOffset + targetStubWithOffset),
isYGreaterThanStubTimes2: Math.abs(sy - ty) > (sourceStubWithOffset + targetStubWithOffset),
opposite: oProduct === -1,
perpendicular: oProduct === 0,
orthogonal: oProduct === 1,
sourceAxis: so[0] === 0 ? "y" : "x",
points: [x, y, w, h, sx, sy, tx, ty ],
stubs:[sourceStubWithOffset, targetStubWithOffset],
sourceEndpoint: params.sourceEndpoint,
targetEndpoint: targetEndpoint,
sourcePos: params.sourcePos,
targetPos: targetEndpoint.anchor.getCurrentLocation(),
};
result.anchorOrientation = result.opposite ? "opposite" : result.orthogonal ? "orthogonal" : "perpendicular";
return result;
};
const _findControlPoint = function (point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint, soo, too, majorAnchor, minorAnchor) { const _findControlPoint = function (point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint, soo, too, majorAnchor, minorAnchor) {
// determine if the two anchors are perpendicular to each other in their orientation. we swap the control // determine if the two anchors are perpendicular to each other in their orientation. we swap the control
@ -45,210 +126,20 @@
return p; return p;
}; };
/* const N8nCustom = function (params) {
Class: UIComponent params = params || {};
Superclass for Connector and AbstractEndpoint. this.type = "N8nCustom";
*/
const AbstractComponent = function () {
this.resetBounds = function () {
this.bounds = { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity };
};
this.resetBounds();
};
/* var _super = _jp.Connectors.AbstractConnector.apply(this, arguments),
* Class: Connector majorAnchor = params.curviness || 150,
* Superclass for all Connectors; here is where Segments are managed. This is exposed on jsPlumb just so it minorAnchor = 10;
* can be accessed from other files. You should not try to instantiate one of these directly.
*
* When this class is asked for a pointOnPath, or gradient etc, it must first figure out which segment to dispatch
* that request to. This is done by keeping track of the total connector length as segments are added, and also
* their cumulative ratios to the total length. Then when the right segment is found it is a simple case of dispatching
* the request to it (and adjusting 'location' so that it is relative to the beginning of that segment.)
*/
_jp.Connectors.N8nAbstractConnector = function (params) {
AbstractComponent.apply(this, arguments);
var segments = [],
totalLength = 0,
segmentProportions = [],
segmentProportionalLengths = [],
getEndpointOffset = params.getEndpointOffset,
stub = params.stub || 0,
sourceStub = _ju.isArray(stub) ? stub[0] : stub,
targetStub = _ju.isArray(stub) ? stub[1] : stub,
gap = params.gap || 0,
sourceGap = _ju.isArray(gap) ? gap[0] : gap,
targetGap = _ju.isArray(gap) ? gap[1] : gap,
userProvidedSegments = null,
paintInfo = null;
this.getPathData = function() {
var p = "";
for (var i = 0; i < segments.length; i++) {
p += _jp.SegmentRenderer.getPath(segments[i], i === 0);
p += " ";
}
return p;
};
/**
* Function: findSegmentForPoint
* Returns the segment that is closest to the given [x,y],
* null if nothing found. This function returns a JS
* object with:
*
* d - distance from segment
* l - proportional location in segment
* x - x point on the segment
* y - y point on the segment
* s - the segment itself.
* connectorLocation - the location on the connector of the point, expressed as a decimal between 0 and 1 inclusive.
*/
this.findSegmentForPoint = function (x, y) {
var out = { d: Infinity, s: null, x: null, y: null, l: null };
for (var i = 0; i < segments.length; i++) {
var _s = segments[i].findClosestPointOnPath(x, y);
if (_s.d < out.d) {
out.d = _s.d;
out.l = _s.l;
out.x = _s.x;
out.y = _s.y;
out.s = segments[i];
out.x1 = _s.x1;
out.x2 = _s.x2;
out.y1 = _s.y1;
out.y2 = _s.y2;
out.index = i;
out.connectorLocation = segmentProportions[i][0] + (_s.l * (segmentProportions[i][1] - segmentProportions[i][0]));
}
}
return out;
};
this.lineIntersection = function(x1, y1, x2, y2) {
var out = [];
for (var i = 0; i < segments.length; i++) {
out.push.apply(out, segments[i].lineIntersection(x1, y1, x2, y2));
}
return out;
};
this.boxIntersection = function(x, y, w, h) {
var out = [];
for (var i = 0; i < segments.length; i++) {
out.push.apply(out, segments[i].boxIntersection(x, y, w, h));
}
return out;
};
this.boundingBoxIntersection = function(box) {
var out = [];
for (var i = 0; i < segments.length; i++) {
out.push.apply(out, segments[i].boundingBoxIntersection(box));
}
return out;
};
var _updateSegmentProportions = function () {
var curLoc = 0;
for (var i = 0; i < segments.length; i++) {
var sl = segments[i].getLength();
segmentProportionalLengths[i] = sl / totalLength;
segmentProportions[i] = [curLoc, (curLoc += (sl / totalLength)) ];
}
},
/**
* returns [segment, proportion of travel in segment, segment index] for the segment
* that contains the point which is 'location' distance along the entire path, where
* 'location' is a decimal between 0 and 1 inclusive. in this connector type, paths
* are made up of a list of segments, each of which contributes some fraction to
* the total length.
* From 1.3.10 this also supports the 'absolute' property, which lets us specify a location
* as the absolute distance in pixels, rather than a proportion of the total path.
*/
_findSegmentForLocation = function (location, absolute) {
var idx, i, inSegmentProportion;
if (absolute) {
location = location > 0 ? location / totalLength : (totalLength + location) / totalLength;
}
// if location 1 we know its the last segment
if (location === 1) {
idx = segments.length - 1;
inSegmentProportion = 1;
} else if (location === 0) {
// if location 0 we know its the first segment
inSegmentProportion = 0;
idx = 0;
} else {
// if location >= 0.5, traverse backwards (of course not exact, who knows the segment proportions. but
// an educated guess at least)
if (location >= 0.5) {
idx = 0;
inSegmentProportion = 0;
for (i = segmentProportions.length - 1; i > -1; i--) {
if (segmentProportions[i][1] >= location && segmentProportions[i][0] <= location) {
idx = i;
inSegmentProportion = (location - segmentProportions[i][0]) / segmentProportionalLengths[i];
break;
}
}
} else {
idx = segmentProportions.length - 1;
inSegmentProportion = 1;
for (i = 0; i < segmentProportions.length; i++) {
if (segmentProportions[i][1] >= location) {
idx = i;
inSegmentProportion = (location - segmentProportions[i][0]) / segmentProportionalLengths[i];
break;
}
}
}
}
return { segment: segments[idx], proportion: inSegmentProportion, index: idx };
},
_addSegment = function (conn, type, params) {
if (params.x1 === params.x2 && params.y1 === params.y2) {
return;
}
var s = new _jp.Segments[type](params);
segments.push(s);
totalLength += s.getLength();
conn.updateBounds(s);
},
_clearSegments = function () {
totalLength = segments.length = segmentProportions.length = segmentProportionalLengths.length = 0;
};
this.setSegments = function (_segs) {
userProvidedSegments = [];
totalLength = 0;
for (var i = 0; i < _segs.length; i++) {
userProvidedSegments.push(_segs[i]);
totalLength += _segs[i].getLength();
}
};
this.getLength = function() {
return totalLength;
};
/** /**
* Set target endpoint * Set target endpoint
* (to override default behavior tracking mouse when dragging mouse) * (to override default behavior tracking mouse when dragging mouse)
* @param {Endpoint} endpoint * @param {Endpoint} endpoint
*/ */
this.setTargetEndpoint = function (endpoint) { this.setTargetEndpoint = function (endpoint) {
this.overrideTargetEndpoint = endpoint; this.overrideTargetEndpoint = endpoint;
}; };
@ -259,151 +150,8 @@
this.overrideTargetEndpoint = null; this.overrideTargetEndpoint = null;
}; };
var _prepareCompute = function (params) { this._compute = function (_, params) {
let { targetPos, targetEndpoint } = params; const paintInfo = _prepareCompute(params, this.overrideTargetEndpoint);
// if has override, use override
if (
this.overrideTargetEndpoint
) {
const target = this.overrideTargetEndpoint.anchor.lastReturnValue;
targetPos = [target[0], target[1]];
targetEndpoint = this.overrideTargetEndpoint;
}
this.strokeWidth = params.strokeWidth;
var segment = _jg.quadrant(params.sourcePos, targetPos),
swapX = targetPos[0] < params.sourcePos[0],
swapY = targetPos[1] < params.sourcePos[1],
lw = params.strokeWidth || 1,
so = params.sourceEndpoint.anchor.getOrientation(params.sourceEndpoint), // source orientation
to = targetEndpoint.anchor.getOrientation(targetEndpoint), // target orientation
x = swapX ? targetPos[0] : params.sourcePos[0],
y = swapY ? targetPos[1] : params.sourcePos[1],
w = Math.abs(targetPos[0] - params.sourcePos[0]),
h = Math.abs(targetPos[1] - params.sourcePos[1]);
// if either anchor does not have an orientation set, we derive one from their relative
// positions. we fix the axis to be the one in which the two elements are further apart, and
// point each anchor at the other element. this is also used when dragging a new connection.
if (so[0] === 0 && so[1] === 0 || to[0] === 0 && to[1] === 0) {
var index = w > h ? 0 : 1, oIndex = [1, 0][index];
so = [];
to = [];
so[index] = params.sourcePos[index] > targetPos[index] ? -1 : 1;
to[index] = params.sourcePos[index] > targetPos[index] ? 1 : -1;
so[oIndex] = 0;
to[oIndex] = 0;
}
const sx = swapX ? w + (sourceGap * so[0]) : sourceGap * so[0],
sy = swapY ? h + (sourceGap * so[1]) : sourceGap * so[1],
tx = swapX ? targetGap * to[0] : w + (targetGap * to[0]),
ty = swapY ? targetGap * to[1] : h + (targetGap * to[1]),
oProduct = ((so[0] * to[0]) + (so[1] * to[1]));
const sourceStubWithOffset = sourceStub + (getEndpointOffset && params.sourceEndpoint ? getEndpointOffset(params.sourceEndpoint) : 0);
const targetStubWithOffset = targetStub + (getEndpointOffset && targetEndpoint ? getEndpointOffset(targetEndpoint) : 0);
var result = {
sx: sx, sy: sy, tx: tx, ty: ty, lw: lw,
xSpan: Math.abs(tx - sx),
ySpan: Math.abs(ty - sy),
mx: (sx + tx) / 2,
my: (sy + ty) / 2,
so: so, to: to, x: x, y: y, w: w, h: h,
segment: segment,
startStubX: sx + (so[0] * sourceStubWithOffset),
startStubY: sy + (so[1] * sourceStubWithOffset),
endStubX: tx + (to[0] * targetStubWithOffset),
endStubY: ty + (to[1] * targetStubWithOffset),
isXGreaterThanStubTimes2: Math.abs(sx - tx) > (sourceStubWithOffset + targetStubWithOffset),
isYGreaterThanStubTimes2: Math.abs(sy - ty) > (sourceStubWithOffset + targetStubWithOffset),
opposite: oProduct === -1,
perpendicular: oProduct === 0,
orthogonal: oProduct === 1,
sourceAxis: so[0] === 0 ? "y" : "x",
points: [x, y, w, h, sx, sy, tx, ty ],
stubs:[sourceStubWithOffset, targetStubWithOffset],
sourceEndpoint: params.sourceEndpoint,
targetEndpoint: targetEndpoint,
sourcePos: params.sourcePos,
targetPos: targetEndpoint.anchor.getCurrentLocation(),
};
result.anchorOrientation = result.opposite ? "opposite" : result.orthogonal ? "orthogonal" : "perpendicular";
return result;
};
this.getSegments = function () {
return segments;
};
this.updateBounds = function (segment) {
var segBounds = segment.getBounds();
this.bounds.minX = Math.min(this.bounds.minX, segBounds.minX);
this.bounds.maxX = Math.max(this.bounds.maxX, segBounds.maxX);
this.bounds.minY = Math.min(this.bounds.minY, segBounds.minY);
this.bounds.maxY = Math.max(this.bounds.maxY, segBounds.maxY);
};
// var dumpSegmentsToConsole = function () {
// console.log("SEGMENTS:");
// for (var i = 0; i < segments.length; i++) {
// console.log(segments[i].type, segments[i].getLength(), segmentProportions[i]);
// }
// };
this.pointOnPath = function (location, absolute) {
var seg = _findSegmentForLocation(location, absolute);
return seg.segment && seg.segment.pointOnPath(seg.proportion, false) || [0, 0];
};
this.gradientAtPoint = function (location, absolute) {
var seg = _findSegmentForLocation(location, absolute);
return seg.segment && seg.segment.gradientAtPoint(seg.proportion, false) || 0;
};
this.pointAlongPathFrom = function (location, distance, absolute) {
var seg = _findSegmentForLocation(location, absolute);
// TODO what happens if this crosses to the next segment?
return seg.segment && seg.segment.pointAlongPathFrom(seg.proportion, distance, false) || [0, 0];
};
this.compute = function (params) {
paintInfo = _prepareCompute.call(this, params);
_clearSegments();
this._compute(paintInfo);
this.x = paintInfo.points[0];
this.y = paintInfo.points[1];
this.w = paintInfo.points[2];
this.h = paintInfo.points[3];
this.segment = paintInfo.segment;
_updateSegmentProportions();
};
return {
addSegment: _addSegment,
prepareCompute: _prepareCompute,
sourceStub: sourceStub,
targetStub: targetStub,
maxStub: Math.max(sourceStub, targetStub),
sourceGap: sourceGap,
targetGap: targetGap,
maxGap: Math.max(sourceGap, targetGap),
};
};
_ju.extend(_jp.Connectors.N8nAbstractConnector, AbstractComponent);
var N8nCustom = function (params) {
params = params || {};
this.type = "N8nCustom";
var _super = _jp.Connectors.N8nAbstractConnector.apply(this, arguments),
majorAnchor = params.curviness || 150,
minorAnchor = 10;
this._compute = function (paintInfo) {
var sp = paintInfo.sourcePos, var sp = paintInfo.sourcePos,
tp = paintInfo.targetPos, tp = paintInfo.targetPos,
_w = Math.abs(sp[0] - tp[0]), _w = Math.abs(sp[0] - tp[0]),
@ -429,8 +177,8 @@
}; };
}; };
_jp.Connectors.N8nCustom= N8nCustom; _jp.Connectors.N8nCustom = N8nCustom;
_ju.extend(_jp.Connectors.N8nCustom, _jp.Connectors.N8nAbstractConnector); _ju.extend(_jp.Connectors.N8nCustom, _jp.Connectors.AbstractConnector);
}).call(typeof window !== 'undefined' ? window : this); }).call(typeof window !== 'undefined' ? window : this);