@antv/x6
Version:
JavaScript diagramming library that uses SVG and HTML for rendering
119 lines • 5.18 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.loop = void 0;
const geometry_1 = require("../../geometry");
function rollup(points, merge) {
if (merge != null && merge !== false) {
const amount = typeof merge === 'boolean' ? 0 : merge;
if (amount > 0) {
const center1 = geometry_1.Point.create(points[1]).move(points[2], amount);
const center2 = geometry_1.Point.create(points[1]).move(points[0], amount);
return [center1.toJSON(), ...points, center2.toJSON()];
}
{
const center = points[1];
return [Object.assign({}, center), ...points, Object.assign({}, center)];
}
}
return points;
}
const loop = (vertices, options, edgeView) => {
const width = options.width || 50;
const height = options.height || 80;
const halfHeight = height / 2;
const angle = options.angle || 'auto';
const sourceAnchor = edgeView.sourceAnchor;
const targetAnchor = edgeView.targetAnchor;
const sourceBBox = edgeView.sourceBBox;
const targetBBox = edgeView.targetBBox;
if (sourceAnchor.equals(targetAnchor)) {
const getVertices = (angle) => {
const rad = (0, geometry_1.toRad)(angle);
const sin = Math.sin(rad);
const cos = Math.cos(rad);
const center = new geometry_1.Point(sourceAnchor.x + cos * width, sourceAnchor.y + sin * width);
const ref = new geometry_1.Point(center.x - cos * halfHeight, center.y - sin * halfHeight);
const p1 = ref.clone().rotate(-90, center);
const p2 = ref.clone().rotate(90, center);
return [p1.toJSON(), center.toJSON(), p2.toJSON()];
};
const validate = (end) => {
const start = sourceAnchor.clone().move(end, -1);
const line = new geometry_1.Line(start, end);
return (!sourceBBox.containsPoint(end) && !sourceBBox.intersectsWithLine(line));
};
const angles = [0, 90, 180, 270, 45, 135, 225, 315];
if (typeof angle === 'number') {
return rollup(getVertices(angle), options.merge);
}
const center = sourceBBox.getCenter();
if (center.equals(sourceAnchor)) {
return rollup(getVertices(0), options.merge);
}
const deg = center.angleBetween(sourceAnchor, center.clone().translate(1, 0));
let ret = getVertices(deg);
if (validate(ret[1])) {
return rollup(ret, options.merge);
}
// return the best vertices
for (let i = 1, l = angles.length; i < l; i += 1) {
ret = getVertices(deg + angles[i]);
if (validate(ret[1])) {
return rollup(ret, options.merge);
}
}
return rollup(ret, options.merge);
}
{
const line = new geometry_1.Line(sourceAnchor, targetAnchor);
let parallel = line.parallel(-width);
let center = parallel.getCenter();
let p1 = parallel.start.clone().move(parallel.end, halfHeight);
let p2 = parallel.end.clone().move(parallel.start, halfHeight);
const ref = line.parallel(-1);
const line1 = new geometry_1.Line(ref.start, center);
const line2 = new geometry_1.Line(ref.end, center);
if (sourceBBox.containsPoint(center) ||
targetBBox.containsPoint(center) ||
sourceBBox.intersectsWithLine(line1) ||
sourceBBox.intersectsWithLine(line2) ||
targetBBox.intersectsWithLine(line1) ||
targetBBox.intersectsWithLine(line2)) {
parallel = line.parallel(width);
center = parallel.getCenter();
p1 = parallel.start.clone().move(parallel.end, halfHeight);
p2 = parallel.end.clone().move(parallel.start, halfHeight);
}
if (options.merge) {
const line = new geometry_1.Line(sourceAnchor, targetAnchor);
const normal = new geometry_1.Line(center, line.center).setLength(Number.MAX_SAFE_INTEGER);
const intersects1 = sourceBBox.intersectsWithLine(normal);
const intersects2 = targetBBox.intersectsWithLine(normal);
const intersects = intersects1
? Array.isArray(intersects1)
? intersects1
: [intersects1]
: [];
if (intersects2) {
if (Array.isArray(intersects2)) {
intersects.push(...intersects2);
}
else {
intersects.push(intersects2);
}
}
const anchor = line.center.closest(intersects);
if (anchor) {
edgeView.sourceAnchor = anchor.clone();
edgeView.targetAnchor = anchor.clone();
}
else {
edgeView.sourceAnchor = line.center.clone();
edgeView.targetAnchor = line.center.clone();
}
}
return rollup([p1.toJSON(), center.toJSON(), p2.toJSON()], options.merge);
}
};
exports.loop = loop;
//# sourceMappingURL=loop.js.map