chore(auto-place): factor out deconflict position into method
This commit is contained in:
parent
ae96f3714d
commit
2e4cd7e0a9
|
@ -34,21 +34,14 @@ function getFlowNodePosition(source, element) {
|
||||||
y: sourceMid.y
|
y: sourceMid.y
|
||||||
};
|
};
|
||||||
|
|
||||||
var existingTarget;
|
var escapeDirection = {
|
||||||
|
y: {
|
||||||
|
margin: 30,
|
||||||
|
rowSize: 80
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// make sure we don't place targets a
|
return deconflictPosition(source, element, position, escapeDirection);
|
||||||
while ((existingTarget = getConnectedAtPosition(source, position, element))) {
|
|
||||||
|
|
||||||
position = {
|
|
||||||
x: position.x,
|
|
||||||
y: Math.max(
|
|
||||||
existingTarget.y + existingTarget.height + 30 + element.height / 2,
|
|
||||||
position.y + 80
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.getFlowNodePosition = getFlowNodePosition;
|
module.exports.getFlowNodePosition = getFlowNodePosition;
|
||||||
|
@ -153,27 +146,19 @@ function getTextAnnotationPosition(source, element) {
|
||||||
|
|
||||||
var sourceTrbl = asTRBL(source);
|
var sourceTrbl = asTRBL(source);
|
||||||
|
|
||||||
// todo: adaptive
|
|
||||||
var position = {
|
var position = {
|
||||||
x: sourceTrbl.right + 30 + element.width / 2,
|
x: sourceTrbl.right + 30 + element.width / 2,
|
||||||
y: sourceTrbl.top - 50 - element.height / 2
|
y: sourceTrbl.top - 50 - element.height / 2
|
||||||
};
|
};
|
||||||
|
|
||||||
var existingTarget;
|
var escapeDirection = {
|
||||||
|
y: {
|
||||||
|
margin: -30,
|
||||||
|
rowSize: 30
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
while ((existingTarget = getConnectedAtPosition(source, position, element))) {
|
return deconflictPosition(source, element, position, escapeDirection);
|
||||||
|
|
||||||
// escape to top
|
|
||||||
position = {
|
|
||||||
x: position.x,
|
|
||||||
y: Math.min(
|
|
||||||
existingTarget.y - 30 - element.height / 2,
|
|
||||||
position.y - 30
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.getTextAnnotationPosition = getTextAnnotationPosition;
|
module.exports.getTextAnnotationPosition = getTextAnnotationPosition;
|
||||||
|
@ -191,21 +176,14 @@ function getDataElementPosition(source, element) {
|
||||||
y: sourceTrbl.bottom + 40 + element.width / 2
|
y: sourceTrbl.bottom + 40 + element.width / 2
|
||||||
};
|
};
|
||||||
|
|
||||||
var existingTarget;
|
var escapeDirection = {
|
||||||
|
x: {
|
||||||
|
margin: 30,
|
||||||
|
rowSize: 80
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
while ((existingTarget = getConnectedAtPosition(source, position, element))) {
|
return deconflictPosition(source, element, position, escapeDirection);
|
||||||
|
|
||||||
// escape to right
|
|
||||||
position = {
|
|
||||||
x: Math.min(
|
|
||||||
existingTarget.x + existingTarget.width + 30 + element.width / 2,
|
|
||||||
position.x + 80
|
|
||||||
),
|
|
||||||
y: position.y
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.getDataElementPosition = getDataElementPosition;
|
module.exports.getDataElementPosition = getDataElementPosition;
|
||||||
|
@ -260,3 +238,70 @@ function getConnectedAtPosition(source, position, element) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.getConnectedAtPosition = getConnectedAtPosition;
|
module.exports.getConnectedAtPosition = getConnectedAtPosition;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new, position for the given element
|
||||||
|
* based on the given element that is not occupied
|
||||||
|
* by any element connected to source.
|
||||||
|
*
|
||||||
|
* Take into account the escapeDirection (where to move
|
||||||
|
* on positining clashes) in the computation.
|
||||||
|
*
|
||||||
|
* @param {djs.model.Shape} source
|
||||||
|
* @param {djs.model.Shape} element
|
||||||
|
* @param {Point} position
|
||||||
|
* @param {Object} escapeDelta
|
||||||
|
*
|
||||||
|
* @return {Point}
|
||||||
|
*/
|
||||||
|
function deconflictPosition(source, element, position, escapeDelta) {
|
||||||
|
|
||||||
|
function nextPosition(existingElement) {
|
||||||
|
|
||||||
|
var newPosition = {
|
||||||
|
x: position.x,
|
||||||
|
y: position.y
|
||||||
|
};
|
||||||
|
|
||||||
|
[ 'x', 'y' ].forEach(function(axis) {
|
||||||
|
|
||||||
|
var axisDelta = escapeDelta[axis];
|
||||||
|
|
||||||
|
if (!axisDelta) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dimension = axis === 'x' ? 'width' : 'height';
|
||||||
|
|
||||||
|
var margin = axisDelta.margin,
|
||||||
|
rowSize = axisDelta.rowSize;
|
||||||
|
|
||||||
|
if (margin < 0) {
|
||||||
|
newPosition[axis] = Math.min(
|
||||||
|
existingElement[axis] + margin - element[dimension] / 2,
|
||||||
|
position[axis] - rowSize + margin
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
newPosition[axis] = Math.max(
|
||||||
|
existingTarget[axis] + existingTarget[dimension] + margin + element[dimension] / 2,
|
||||||
|
position[axis] + rowSize + margin
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return newPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingTarget;
|
||||||
|
|
||||||
|
|
||||||
|
// deconflict position until free slot is found
|
||||||
|
while ((existingTarget = getConnectedAtPosition(source, position, element))) {
|
||||||
|
position = nextPosition(existingTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.deconflictPosition = deconflictPosition;
|
Loading…
Reference in New Issue