Fix regression with routing overlapping links (culprit: lodash upgrade)
This commit is contained in:
@@ -11,12 +11,16 @@ export class Utils {
|
||||
static fanRoute(graph: dia.Graph, cell: dia.Cell) {
|
||||
if (cell instanceof joint.dia.Element) {
|
||||
|
||||
_.chain(graph.getConnectedLinks(cell)).groupBy((link: dia.Link) => {
|
||||
const links = graph.getConnectedLinks(cell);
|
||||
|
||||
const groupsOfOverlappingLinks = _.groupBy(links, (link: dia.Link) => {
|
||||
// the key of the group is the model id of the link's source or target, but not our cell id.
|
||||
const sourceId = link.get('source').id;
|
||||
const targetId = link.get('target').id;
|
||||
return cell.id !== sourceId ? sourceId : targetId;
|
||||
}).each((group: any, key: string) => {
|
||||
});
|
||||
|
||||
_.each(groupsOfOverlappingLinks, (group: any, key: string) => {
|
||||
// If the member of the group has both source and target model adjust vertices.
|
||||
let toRoute: any = {};
|
||||
if (key !== undefined) {
|
||||
@@ -33,88 +37,88 @@ export class Utils {
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
} else if (cell instanceof joint.dia.Link) {
|
||||
// The cell is a link. Let's find its source and target models.
|
||||
let srcId = cell.get('source').id || cell.previous('source').id;
|
||||
let trgId = cell.get('target').id || cell.previous('target').id;
|
||||
|
||||
// If one of the ends is not a model, the link has no siblings.
|
||||
if (!srcId || !trgId) { return; }
|
||||
|
||||
const siblings: dia.Link[] = graph.getLinks().filter((sibling: dia.Link) => {
|
||||
|
||||
const _srcId = sibling.get('source').id;
|
||||
const _trgId = sibling.get('target').id;
|
||||
const vertices = sibling.get('vertices');
|
||||
const fanRouted = !vertices || vertices.length === 0 || sibling.get('fanRouted');
|
||||
|
||||
return ((_srcId === srcId && _trgId === trgId) || (_srcId === trgId && _trgId === srcId)) && fanRouted;
|
||||
|
||||
});
|
||||
|
||||
switch (siblings.length) {
|
||||
|
||||
case 0:
|
||||
// The link was removed and had no siblings.
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// There is only one link between the source and target. No vertices needed.
|
||||
let vertices = cell.get('vertices');
|
||||
if (vertices && vertices.length && cell.get('fanRouted')) {
|
||||
cell.unset('vertices');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
// There is more than one siblings. We need to create vertices.
|
||||
|
||||
// First of all we'll find the middle point of the link.
|
||||
let source = <dia.Element> graph.getCell(srcId);
|
||||
let target = <dia.Element> graph.getCell(trgId);
|
||||
|
||||
if (!source || !target) {
|
||||
// When clearing the graph it may happen that some nodes are gone and some are left
|
||||
return;
|
||||
}
|
||||
|
||||
let srcCenter = source.getBBox().center();
|
||||
let trgCenter = target.getBBox().center();
|
||||
let midPoint = joint.g.line(srcCenter, trgCenter).midpoint();
|
||||
|
||||
// Then find the angle it forms.
|
||||
let theta = srcCenter.theta(trgCenter);
|
||||
|
||||
// This is the maximum distance between links
|
||||
let gap = 20;
|
||||
|
||||
siblings.forEach((sibling: dia.Link, index: number) => {
|
||||
|
||||
// We want the offset values to be calculated as follows 0, 20, 20, 40, 40, 60, 60 ..
|
||||
let offset = gap * Math.ceil(index / 2);
|
||||
|
||||
// Now we need the vertices to be placed at points which are 'offset' pixels distant
|
||||
// from the first link and forms a perpendicular angle to it. And as index goes up
|
||||
// alternate left and right.
|
||||
//
|
||||
// ^ odd indexes
|
||||
// |
|
||||
// |----> index 0 line (straight line between a source center and a target center.
|
||||
// |
|
||||
// v even indexes
|
||||
let sign = index % 2 ? 1 : -1;
|
||||
let angle = joint.g.toRad(theta + sign * 90);
|
||||
|
||||
// We found the vertex.
|
||||
let vertex = joint.g.point.fromPolar(offset, angle, midPoint);
|
||||
|
||||
sibling.set('fanRouted', true);
|
||||
(<any>sibling).set('vertices', [{ x: vertex.x, y: vertex.y }], {'fanRouted': true});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// The cell is a link. Let's find its source and target models.
|
||||
let srcId = cell.get('source').id || cell.previous('source').id;
|
||||
let trgId = cell.get('target').id || cell.previous('target').id;
|
||||
|
||||
// If one of the ends is not a model, the link has no siblings.
|
||||
if (!srcId || !trgId) { return; }
|
||||
|
||||
const siblings: dia.Link[] = graph.getLinks().filter((sibling: dia.Link) => {
|
||||
|
||||
const _srcId = sibling.get('source').id;
|
||||
const _trgId = sibling.get('target').id;
|
||||
const vertices = sibling.get('vertices');
|
||||
const fanRouted = !vertices || vertices.length === 0 || sibling.get('fanRouted');
|
||||
|
||||
return ((_srcId === srcId && _trgId === trgId) || (_srcId === trgId && _trgId === srcId)) && fanRouted;
|
||||
|
||||
});
|
||||
|
||||
switch (siblings.length) {
|
||||
|
||||
case 0:
|
||||
// The link was removed and had no siblings.
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// There is only one link between the source and target. No vertices needed.
|
||||
let vertices = cell.get('vertices');
|
||||
if (vertices && vertices.length && cell.get('fanRouted')) {
|
||||
cell.unset('vertices');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
// There is more than one siblings. We need to create vertices.
|
||||
|
||||
// First of all we'll find the middle point of the link.
|
||||
let source = <dia.Element> graph.getCell(srcId);
|
||||
let target = <dia.Element> graph.getCell(trgId);
|
||||
|
||||
if (!source || !target) {
|
||||
// When clearing the graph it may happen that some nodes are gone and some are left
|
||||
return;
|
||||
}
|
||||
|
||||
let srcCenter = source.getBBox().center();
|
||||
let trgCenter = target.getBBox().center();
|
||||
let midPoint = joint.g.line(srcCenter, trgCenter).midpoint();
|
||||
|
||||
// Then find the angle it forms.
|
||||
let theta = srcCenter.theta(trgCenter);
|
||||
|
||||
// This is the maximum distance between links
|
||||
let gap = 20;
|
||||
|
||||
siblings.forEach((sibling: dia.Link, index: number) => {
|
||||
|
||||
// We want the offset values to be calculated as follows 0, 20, 20, 40, 40, 60, 60 ..
|
||||
let offset = gap * Math.ceil(index / 2);
|
||||
|
||||
// Now we need the vertices to be placed at points which are 'offset' pixels distant
|
||||
// from the first link and forms a perpendicular angle to it. And as index goes up
|
||||
// alternate left and right.
|
||||
//
|
||||
// ^ odd indexes
|
||||
// |
|
||||
// |----> index 0 line (straight line between a source center and a target center.
|
||||
// |
|
||||
// v even indexes
|
||||
let sign = index % 2 ? 1 : -1;
|
||||
let angle = joint.g.toRad(theta + sign * 90);
|
||||
|
||||
// We found the vertex.
|
||||
let vertex = joint.g.point.fromPolar(offset, angle, midPoint);
|
||||
|
||||
sibling.set('fanRouted', true);
|
||||
(<any>sibling).set('vertices', [{ x: vertex.x, y: vertex.y }], {'fanRouted': true});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static isCustomPaperEvent(args: any): boolean {
|
||||
|
||||
Reference in New Issue
Block a user