use of org.eclipse.elk.alg.layered.graph.Layer in project elk by eclipse.
the class LabelManagementProcessor method manageNonCenterLabels.
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Everything Except Center Edge Labels
/**
* Calls label management on all labels that are not edge center labels.
*/
private void manageNonCenterLabels(final LGraph lGraph, final ILabelManager labelManager, final double labelLabelSpacing) {
boolean verticalLayout = lGraph.getProperty(LayeredOptions.DIRECTION).isVertical();
// Iterate over the layers
for (Layer layer : lGraph) {
// Apply label management to node and port labels
for (LNode node : layer) {
if (node.getType() == NodeType.NORMAL) {
// Handle node labels
doManageLabels(labelManager, node.getLabels(), MIN_WIDTH_NODE_LABELS, labelLabelSpacing, verticalLayout);
// Handle ports
List<LPort> ports = node.getPorts();
for (LPort port : ports) {
doManageLabels(labelManager, port.getLabels(), MIN_WIDTH_PORT_LABELS, labelLabelSpacing, verticalLayout);
}
// Handle attached comments
if (node.hasProperty(InternalProperties.TOP_COMMENTS)) {
doManageAttachedCommentLabels(labelManager, node.getProperty(InternalProperties.TOP_COMMENTS), MIN_WIDTH_NODE_LABELS, verticalLayout);
}
if (node.hasProperty(InternalProperties.BOTTOM_COMMENTS)) {
doManageAttachedCommentLabels(labelManager, node.getProperty(InternalProperties.BOTTOM_COMMENTS), MIN_WIDTH_NODE_LABELS, verticalLayout);
}
}
// point, only head and tail labels remain)
for (LEdge edge : node.getOutgoingEdges()) {
doManageLabels(labelManager, edge.getLabels(), MIN_WIDTH_EDGE_LABELS, 0, verticalLayout);
}
}
}
}
use of org.eclipse.elk.alg.layered.graph.Layer in project elk by eclipse.
the class LabelManagementProcessor method manageCenterLabels.
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Center Edge Labels
/**
* Calls label management on all edge center labels.
*/
private void manageCenterLabels(final LGraph lGraph, final ILabelManager labelManager, final double edgeLabelSpacing, final double labelLabelSpacing) {
boolean verticalLayout = lGraph.getProperty(LayeredOptions.DIRECTION).isVertical();
// Iterate over the layers and find label dummy nodes
for (Layer layer : lGraph) {
// The maximum width is used as the target width for center edge labels
double maxWidth = Math.max(MIN_WIDTH_EDGE_LABELS, LGraphUtil.findMaxNonDummyNodeWidth(layer, false));
for (LNode node : layer) {
if (node.getType() == NodeType.LABEL) {
LEdge edge = node.getConnectedEdges().iterator().next();
double edgeThickness = edge.getProperty(LayeredOptions.EDGE_THICKNESS).doubleValue();
// The list of labels should never be empty (otherwise the label dummy wouldn't have been created
// in the first place)
Iterable<LLabel> labels = node.getProperty(InternalProperties.REPRESENTED_LABELS);
KVector spaceRequiredForLabels = doManageLabels(labelManager, labels, maxWidth, labelLabelSpacing, verticalLayout);
// Apply the space required for labels to the dummy node (we don't bother with the ports here since
// they will be meddled with later by the LabelSideSelector anyway)
node.getSize().x = spaceRequiredForLabels.x;
node.getSize().y = spaceRequiredForLabels.y + edgeThickness + edgeLabelSpacing;
}
}
}
}
use of org.eclipse.elk.alg.layered.graph.Layer in project elk by eclipse.
the class LabelSideSelector method smart.
// //////////////////////////////////////////////////////////////////////////////////////
// Smart Placement Strategy
/**
* Chooses label sides depending on certain patterns. If in doubt, uses the given default side.
*/
private void smart(final LGraph graph, final LabelSide defaultSide) {
// We will collect consecutive runs of certain dummy nodes while we iterate through layers
Deque<LNode> dummyNodeQueue = new ArrayDeque<>();
for (Layer layer : graph) {
// The first call to any method
boolean topGroup = true;
int labelDummiesInQueue = 0;
for (LNode node : layer) {
switch(node.getType()) {
case LABEL:
labelDummiesInQueue++;
// Intended fall-through to add the label dummy to the queue
case LONG_EDGE:
dummyNodeQueue.add(node);
break;
case NORMAL:
smartForRegularNode(node, defaultSide);
default:
// Empty dummy node queue
if (!dummyNodeQueue.isEmpty()) {
smartForConsecutiveDummyNodeRun(dummyNodeQueue, labelDummiesInQueue, topGroup, false, defaultSide);
}
// Reset things
topGroup = false;
labelDummiesInQueue = 0;
}
}
// Do stuff with the nodes in the queue
if (!dummyNodeQueue.isEmpty()) {
smartForConsecutiveDummyNodeRun(dummyNodeQueue, labelDummiesInQueue, topGroup, true, defaultSide);
}
}
}
use of org.eclipse.elk.alg.layered.graph.Layer in project elk by eclipse.
the class LayerConstraintPostprocessor method moveFirstAndLastNodes.
/**
* Moves nodes with {@link LayerConstraint#FIRST} and {@link LayerConstraint#LAST} to their respective layers and
* removes layers that have become empty.
*/
private void moveFirstAndLastNodes(final LGraph layeredGraph, final Layer firstLayer, final Layer lastLayer, final Layer firstLabelLayer, final Layer lastLabelLayer) {
// We'll start by moving FIRST and LAST nodes (as well as connected label dummies) to their proper layers
for (Layer layer : layeredGraph) {
// Iterate through a node array to avoid ConcurrentModificationExceptions
LNode[] nodes = LGraphUtil.toNodeArray(layer.getNodes());
for (LNode node : nodes) {
switch(node.getProperty(LayeredOptions.LAYERING_LAYER_CONSTRAINT)) {
case FIRST:
throwUpUnlessNoIncomingEdges(node);
node.setLayer(firstLayer);
moveLabelsToLabelLayer(node, true, firstLabelLayer);
break;
case LAST:
throwUpUnlessNoOutgoingEdges(node);
node.setLayer(lastLayer);
moveLabelsToLabelLayer(node, false, lastLabelLayer);
break;
}
}
}
// All the movement can cause layers to be empty. Instead of going to great lengths trying to prevent that in
// the code above, we simply iterate over all layers and remove the empty ones
ListIterator<Layer> layerIter = layeredGraph.getLayers().listIterator();
while (layerIter.hasNext()) {
if (layerIter.next().getNodes().isEmpty()) {
layerIter.remove();
}
}
}
use of org.eclipse.elk.alg.layered.graph.Layer in project elk by eclipse.
the class FinalSplineBendpointsCalculator method process.
@Override
public void process(final LGraph graph, final IElkProgressMonitor progressMonitor) {
this.edgeEdgeSpacing = graph.getProperty(LayeredOptions.SPACING_EDGE_EDGE_BETWEEN_LAYERS);
this.edgeNodeSpacing = graph.getProperty(LayeredOptions.SPACING_EDGE_NODE_BETWEEN_LAYERS);
this.splineRoutingMode = graph.getProperty(LayeredOptions.EDGE_ROUTING_SPLINES_MODE);
this.compactionStrategy = graph.getProperty(LayeredOptions.COMPACTION_POST_COMPACTION_STRATEGY);
// assign indices to nodes to efficiently query neighbors within the same layer
indexNodesPerLayer(graph);
// collect all edges that represent the first segment of a spline
List<LEdge> startEdges = graph.getLayers().stream().flatMap(l -> l.getNodes().stream()).flatMap(n -> StreamSupport.stream(n.getOutgoingEdges().spliterator(), false)).filter(e -> !e.isSelfLoop()).filter(e -> e.hasProperty(InternalProperties.SPLINE_ROUTE_START)).collect(Collectors.toList());
// first determine the NUB control points
for (LEdge e : startEdges) {
List<SplineSegment> spline = e.getProperty(InternalProperties.SPLINE_ROUTE_START);
spline.forEach(s -> calculateControlPoints(s));
e.setProperty(InternalProperties.SPLINE_ROUTE_START, null);
}
// ... then convert them to bezier splines
for (LEdge e : startEdges) {
// may be null
LEdge survivingEdge = e.getProperty(InternalProperties.SPLINE_SURVIVING_EDGE);
List<LEdge> edgeChain = e.getProperty(InternalProperties.SPLINE_EDGE_CHAIN);
calculateBezierBendPoints(edgeChain, survivingEdge);
// clear property
e.setProperty(InternalProperties.SPLINE_EDGE_CHAIN, null);
}
}
Aggregations