chore(auto-place): factor out deconflict position into method

This commit is contained in:
Nico Rehwaldt 2017-12-15 09:35:18 +01:00
parent ae96f3714d
commit 2e4cd7e0a9
1 changed files with 89 additions and 44 deletions

View File

@ -34,21 +34,14 @@ function getFlowNodePosition(source, element) {
y: sourceMid.y
};
var existingTarget;
var escapeDirection = {
y: {
margin: 30,
rowSize: 80
}
};
// make sure we don't place targets a
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;
return deconflictPosition(source, element, position, escapeDirection);
}
module.exports.getFlowNodePosition = getFlowNodePosition;
@ -153,27 +146,19 @@ function getTextAnnotationPosition(source, element) {
var sourceTrbl = asTRBL(source);
// todo: adaptive
var position = {
x: sourceTrbl.right + 30 + element.width / 2,
y: sourceTrbl.top - 50 - element.height / 2
};
var existingTarget;
var escapeDirection = {
y: {
margin: -30,
rowSize: 30
}
};
while ((existingTarget = getConnectedAtPosition(source, position, element))) {
// escape to top
position = {
x: position.x,
y: Math.min(
existingTarget.y - 30 - element.height / 2,
position.y - 30
)
};
}
return position;
return deconflictPosition(source, element, position, escapeDirection);
}
module.exports.getTextAnnotationPosition = getTextAnnotationPosition;
@ -191,21 +176,14 @@ function getDataElementPosition(source, element) {
y: sourceTrbl.bottom + 40 + element.width / 2
};
var existingTarget;
var escapeDirection = {
x: {
margin: 30,
rowSize: 80
}
};
while ((existingTarget = getConnectedAtPosition(source, position, element))) {
// escape to right
position = {
x: Math.min(
existingTarget.x + existingTarget.width + 30 + element.width / 2,
position.x + 80
),
y: position.y
};
}
return position;
return deconflictPosition(source, element, position, escapeDirection);
}
module.exports.getDataElementPosition = getDataElementPosition;
@ -259,4 +237,71 @@ 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;