-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PR] [WIP] remove 'spacing.labelNode', add 'nodeLabels.margin' #621
base: master
Are you sure you want to change the base?
Changes from all commits
aaf32e1
e2bcc04
2402d99
c105e7b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
import org.eclipse.elk.core.options.CoreOptions; | ||
import org.eclipse.elk.core.options.EdgeLabelPlacement; | ||
import org.eclipse.elk.core.options.PortLabelPlacement; | ||
import org.eclipse.elk.core.util.IndividualSpacings; | ||
import org.eclipse.elk.core.util.adapters.GraphAdapters.EdgeAdapter; | ||
import org.eclipse.elk.core.util.adapters.GraphAdapters.GraphAdapter; | ||
import org.eclipse.elk.core.util.adapters.GraphAdapters.LabelAdapter; | ||
|
@@ -109,30 +110,20 @@ public NodeMarginCalculator excludeEdgeHeadTailLabels() { | |
* Calculates and assigns margins to all nodes. | ||
*/ | ||
public void process() { | ||
double spacing = adapter.getProperty(CoreOptions.SPACING_LABEL_NODE); | ||
|
||
// Iterate through all nodes | ||
for (NodeAdapter<?> node : adapter.getNodes()) { | ||
processNode(node, spacing); | ||
processNode(node); | ||
} | ||
} | ||
|
||
/** | ||
* Calculates and assigns margins to the given node. The node is expected to be part of the graph the calculator | ||
* was created for. | ||
* Calculates and assigns margins to the given node. The node is expected to be part of the graph the calculator was | ||
* created for. | ||
*/ | ||
public void processNode(final NodeAdapter<?> node) { | ||
double spacing = adapter.getProperty(CoreOptions.SPACING_LABEL_NODE); | ||
processNode(node, spacing); | ||
} | ||
|
||
/** | ||
* Calculates the margin of the given node. | ||
* | ||
* @param node the node whose margin to calculate. | ||
* @param labelSpacing label spacing set on the layered graph. | ||
*/ | ||
private void processNode(final NodeAdapter<?> node, final double labelSpacing) { | ||
ElkMargin desiredNodeMargin = IndividualSpacings.getIndividualOrInherited(node, CoreOptions.NODE_LABELS_MARGIN); | ||
|
||
// This will be our bounding box. We'll start with one that's the same size | ||
// as our node, and at the same position. | ||
ElkRectangle boundingBox = new ElkRectangle( | ||
|
@@ -185,29 +176,33 @@ private void processNode(final NodeAdapter<?> node, final double labelSpacing) { | |
} | ||
|
||
// End labels of edges connected to the port | ||
// TODO cds: layered calls #excludeEdgeHeadTailLabels, is this ever active? | ||
if (includeEdgeHeadTailLabels) { | ||
KVector requiredPortLabelSpace = new KVector(-labelSpacing, -labelSpacing); | ||
|
||
// TODO: maybe leave space for manually placed ports | ||
KVector requiredPortLabelSpace = new KVector(-desiredNodeMargin.left, -desiredNodeMargin.top); | ||
|
||
// TODO cds: it's not margin but spacing between pairs of labels, right? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, between multiple labels that all belong to the same graph element. |
||
double labelLabelSpacing = | ||
IndividualSpacings.getIndividualOrInherited(node, CoreOptions.SPACING_LABEL_LABEL); | ||
// TODO: maybe leave space for manually placed ports | ||
if (node.getProperty(CoreOptions.PORT_LABELS_PLACEMENT) == PortLabelPlacement.OUTSIDE) { | ||
for (LabelAdapter<?> label : port.getLabels()) { | ||
requiredPortLabelSpace.x += label.getSize().x + labelSpacing; | ||
requiredPortLabelSpace.y += label.getSize().y + labelSpacing; | ||
// TODO cds: why spacing in both directions? Doesn't it depend on the stacking direction? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, this looks wrong. |
||
requiredPortLabelSpace.x += label.getSize().x + labelLabelSpacing; | ||
requiredPortLabelSpace.y += label.getSize().y + labelLabelSpacing; | ||
} | ||
} | ||
|
||
requiredPortLabelSpace.x = Math.max(requiredPortLabelSpace.x, 0.0); | ||
requiredPortLabelSpace.y = Math.max(requiredPortLabelSpace.y, 0.0); | ||
|
||
processEdgeHeadTailLabels(boundingBox, port.getOutgoingEdges(), port.getIncomingEdges(), | ||
node, port, requiredPortLabelSpace, labelSpacing); | ||
processEdgeHeadTailLabels(boundingBox, port.getOutgoingEdges(), port.getIncomingEdges(), node, port, | ||
requiredPortLabelSpace); | ||
} | ||
} | ||
|
||
// Process end labels of edges directly connected to the node | ||
if (includeEdgeHeadTailLabels) { | ||
processEdgeHeadTailLabels(boundingBox, node.getOutgoingEdges(), node.getIncomingEdges(), | ||
node, null, null, labelSpacing); | ||
processEdgeHeadTailLabels(boundingBox, node.getOutgoingEdges(), node.getIncomingEdges(), node, null, null); | ||
} | ||
|
||
// Reset the margin | ||
|
@@ -230,20 +225,18 @@ private void processNode(final NodeAdapter<?> node, final double labelSpacing) { | |
* @param port the port if the edges are connected to one. | ||
* @param portLabelSpace if the edges are connected to a port, this is the space required to | ||
* place the port's labels. | ||
* @param labelSpacing label spacing. | ||
*/ | ||
private void processEdgeHeadTailLabels(final ElkRectangle boundingBox, | ||
final Iterable<EdgeAdapter<?>> outgoingEdges, final Iterable<EdgeAdapter<?>> incomingEdges, | ||
final NodeAdapter<?> node, final PortAdapter<?> port, final KVector portLabelSpace, | ||
final double labelSpacing) { | ||
final NodeAdapter<?> node, final PortAdapter<?> port, final KVector portLabelSpace) { | ||
|
||
ElkRectangle labelBox = new ElkRectangle(); | ||
|
||
// For each edge, the tail labels of outgoing edges ... | ||
for (EdgeAdapter<?> edge : outgoingEdges) { | ||
for (LabelAdapter<?> label : edge.getLabels()) { | ||
if (label.getProperty(CoreOptions.EDGE_LABELS_PLACEMENT) == EdgeLabelPlacement.TAIL) { | ||
computeLabelBox(labelBox, label, false, node, port, portLabelSpace, labelSpacing); | ||
computeLabelBox(labelBox, label, false, node, port, portLabelSpace); | ||
boundingBox.union(labelBox); | ||
} | ||
} | ||
|
@@ -253,7 +246,7 @@ private void processEdgeHeadTailLabels(final ElkRectangle boundingBox, | |
for (EdgeAdapter<?> edge : incomingEdges) { | ||
for (LabelAdapter<?> label : edge.getLabels()) { | ||
if (label.getProperty(CoreOptions.EDGE_LABELS_PLACEMENT) == EdgeLabelPlacement.HEAD) { | ||
computeLabelBox(labelBox, label, true, node, port, portLabelSpace, labelSpacing); | ||
computeLabelBox(labelBox, label, true, node, port, portLabelSpace); | ||
boundingBox.union(labelBox); | ||
} | ||
} | ||
|
@@ -272,11 +265,10 @@ private void processEdgeHeadTailLabels(final ElkRectangle boundingBox, | |
* directly to the node. | ||
* @param portLabelSpace if the edges are connected to a port, this is the space required to | ||
* place the port's labels. | ||
* @param labelSpacing label spacing. | ||
*/ | ||
private void computeLabelBox(final ElkRectangle labelBox, final LabelAdapter<?> label, | ||
final boolean incomingEdge, final NodeAdapter<?> node, final PortAdapter<?> port, | ||
final KVector portLabelSpace, final double labelSpacing) { | ||
final KVector portLabelSpace) { | ||
|
||
labelBox.x = node.getPosition().x; | ||
labelBox.y = node.getPosition().y; | ||
|
@@ -288,48 +280,50 @@ private void computeLabelBox(final ElkRectangle labelBox, final LabelAdapter<?> | |
labelBox.width = label.getSize().x; | ||
labelBox.height = label.getSize().y; | ||
|
||
ElkMargin desiredNodeMargin = IndividualSpacings.getIndividualOrInherited(node, CoreOptions.NODE_LABELS_MARGIN); | ||
|
||
if (port == null) { | ||
// The edge is connected directly to the node | ||
if (incomingEdge) { | ||
// Assume the edge enters the node at its western side | ||
labelBox.x -= labelSpacing + label.getSize().x; | ||
labelBox.x -= desiredNodeMargin.left + label.getSize().x; | ||
} else { | ||
// Assume the edge leaves the node at its eastern side | ||
labelBox.x += node.getSize().x + labelSpacing; | ||
labelBox.x += node.getSize().x + desiredNodeMargin.right; | ||
} | ||
} else { | ||
switch (port.getSide()) { | ||
case UNDEFINED: | ||
case EAST: | ||
labelBox.x += port.getSize().x | ||
+ labelSpacing | ||
+ desiredNodeMargin.left | ||
+ portLabelSpace.x | ||
+ labelSpacing; | ||
+ desiredNodeMargin.right; // TODO cds: I feel this is wrong (same below) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the idea here was that there's the width of the node, then a bit of space between it and the port labels, then the width of the port labels, and then another bit of space between them and the edge end labels. In fact, this might make the node label margin a little strange, perhaps. It needs to be applied between a node and its port labels, and then again between those and the end labels... Hm... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, and outside node labels as well... |
||
break; | ||
|
||
case WEST: | ||
labelBox.x -= labelSpacing | ||
labelBox.x -= desiredNodeMargin.left | ||
+ portLabelSpace.x | ||
+ labelSpacing | ||
+ desiredNodeMargin.right | ||
+ label.getSize().x; | ||
break; | ||
|
||
case NORTH: | ||
labelBox.x += port.getSize().x | ||
+ labelSpacing; | ||
labelBox.y -= labelSpacing | ||
+ desiredNodeMargin.left; | ||
labelBox.y -= desiredNodeMargin.top | ||
+ portLabelSpace.y | ||
+ labelSpacing | ||
+ desiredNodeMargin.bottom | ||
+ label.getSize().y; | ||
break; | ||
|
||
case SOUTH: | ||
labelBox.x += port.getSize().x | ||
+ labelSpacing; | ||
+ desiredNodeMargin.left; | ||
labelBox.y += port.getSize().y | ||
+ labelSpacing | ||
+ desiredNodeMargin.top | ||
+ portLabelSpace.y | ||
+ labelSpacing; | ||
+ desiredNodeMargin.bottom; | ||
break; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -241,12 +241,10 @@ private static void constrainedInsidePortLabelPlacement(final NodeContext nodeCo | |
ElkRectangle labelContainerRect = insidePortLabelContainer.getCellRectangle(); | ||
double leftBorder = labelContainerRect.x + ElkMath.maxd( | ||
insidePortLabelContainer.getPadding().left, | ||
nodeContext.surroundingPortMargins.left, | ||
nodeContext.nodeLabelSpacing); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed this completely here as the code handles ports inside of the node. |
||
nodeContext.surroundingPortMargins.left); | ||
double rightBorder = labelContainerRect.x + labelContainerRect.width - ElkMath.maxd( | ||
insidePortLabelContainer.getPadding().right, | ||
nodeContext.surroundingPortMargins.right, | ||
nodeContext.nodeLabelSpacing); | ||
nodeContext.surroundingPortMargins.right); | ||
|
||
// Obtain a rectangle strip overlap remover, which will actually do most of the work | ||
RectangleStripOverlapRemover overlapRemover = RectangleStripOverlapRemover | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ELK Layered does its own end label processing in
EndLabelPreprocessor
andEndLabelPostprocessor
. I think this code wasmeant for algorithms that do not implement their own sophisticated end label processing.