use of org.eclipse.elk.alg.layered.options.SplineRoutingMode in project elk by eclipse.
the class SplineEdgeRouter method process.
// ////////////////////////////////////////////////
@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
monitor.begin("Spline edge routing", 1);
if (layeredGraph.getLayers().isEmpty()) {
layeredGraph.getSize().x = 0;
monitor.done();
return;
}
// Retrieve some generic values
final double nodeNodeSpacing = layeredGraph.getProperty(LayeredOptions.SPACING_NODE_NODE_BETWEEN_LAYERS);
final double edgeNodeSpacing = layeredGraph.getProperty(LayeredOptions.SPACING_EDGE_NODE_BETWEEN_LAYERS);
final double edgeEdgeSpacing = layeredGraph.getProperty(LayeredOptions.SPACING_EDGE_EDGE_BETWEEN_LAYERS);
// Find out if splines should be routed thoroughly or sloppy
final SplineRoutingMode mode = layeredGraph.getProperty(LayeredOptions.EDGE_ROUTING_SPLINES_MODE);
final boolean sloppyRouting = mode == SplineRoutingMode.SLOPPY;
final double sloppyLayerSpacingFactor = layeredGraph.getProperty(LayeredOptions.EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR);
lGraph = layeredGraph;
startEdges.clear();
allSplineSegments.clear();
successingEdge.clear();
// check if the first and/or last layer are populated with external port dummies
final Layer firstLayer = layeredGraph.getLayers().get(0);
final boolean isLeftLayerExternal = Iterables.all(firstLayer.getNodes(), PolylineEdgeRouter.PRED_EXTERNAL_WEST_OR_EAST_PORT);
final Layer lastLayer = layeredGraph.getLayers().get(layeredGraph.getLayers().size() - 1);
final boolean isRightLayerExternal = Iterables.all(lastLayer.getNodes(), PolylineEdgeRouter.PRED_EXTERNAL_WEST_OR_EAST_PORT);
final Iterator<Layer> layerIterator = layeredGraph.iterator();
Layer leftLayer = null;
Layer rightLayer;
// initial x position
double xpos = 0.0;
do {
rightLayer = layerIterator.hasNext() ? layerIterator.next() : null;
// fresh start for this pair of layers
clearThenFillMappings(leftLayer, rightLayer);
// creation of the SplineSegments
createSegmentsAndComputeRanking();
// count the number of required slots for vertical segments
// (edges to be drawn straight are assigned a rank but must be omitted here)
final int slotCount = splineSegmentsLayer.stream().filter(e -> !e.isStraight).mapToInt(e -> e.rank + 1).max().orElse(0);
// the code below ensures that at least nodeNodeSpacing is preserved between a pair of layers
// if this spacing is larger than what would be required to route the vertical segments in-between
// a pair of layers, it looks nicer to move the vertical segments halfway between the layers.
// The xSegmentDelta variable holds the required offset
double xSegmentDelta = 0;
double rightLayerPosition = xpos;
boolean isSpecialLeftLayer = leftLayer == null || (isLeftLayerExternal && leftLayer == firstLayer);
boolean isSpecialRightLayer = rightLayer == null || (isRightLayerExternal && rightLayer == lastLayer);
// compute horizontal positions just as for the OrthogonalEdgeRouter
if (slotCount > 0) {
// the space between each pair of edge segments, and between nodes and edges
double increment = 0;
if (leftLayer != null) {
increment += edgeNodeSpacing;
}
increment += (slotCount - 1) * edgeEdgeSpacing;
if (rightLayer != null) {
increment += edgeNodeSpacing;
}
// sloppy routing may want to reserve more space in-between a pair of layers
if (sloppyRouting && rightLayer != null) {
increment = Math.max(increment, computeSloppySpacing(rightLayer, edgeEdgeSpacing, nodeNodeSpacing, sloppyLayerSpacingFactor));
}
// if we are between two layers, make sure their minimal spacing is preserved
if (increment < nodeNodeSpacing && !isSpecialLeftLayer && !isSpecialRightLayer) {
xSegmentDelta = (nodeNodeSpacing - increment) / 2d;
increment = nodeNodeSpacing;
}
rightLayerPosition += increment;
} else if (!isSpecialLeftLayer && !isSpecialRightLayer) {
// If all edges are straight, use the usual spacing
rightLayerPosition += nodeNodeSpacing;
}
// place right layer's nodes
if (rightLayer != null) {
LGraphUtil.placeNodesHorizontally(rightLayer, rightLayerPosition);
}
// are determined by the FinalSplineBendpointsCaluclator
for (final SplineSegment segment : splineSegmentsLayer) {
segment.boundingBox.x = xpos;
segment.boundingBox.width = rightLayerPosition - xpos;
segment.xDelta = xSegmentDelta;
segment.isWestOfInitialLayer = leftLayer == null;
}
allSplineSegments.addAll(splineSegmentsLayer);
// proceed to the next layer
xpos = rightLayerPosition;
if (rightLayer != null) {
xpos += rightLayer.getSize().x;
}
leftLayer = rightLayer;
isSpecialLeftLayer = isSpecialRightLayer;
} while (rightLayer != null);
// control point calculation to be done by a later intermediate processor
for (LEdge edge : startEdges) {
List<LEdge> edgeChain = getEdgeChain(edge);
edge.setProperty(InternalProperties.SPLINE_EDGE_CHAIN, edgeChain);
List<SplineSegment> spline = getSplinePath(edge);
edge.setProperty(InternalProperties.SPLINE_ROUTE_START, spline);
}
// assign final width of the layering and thus the overall graph
layeredGraph.getSize().x = xpos;
lGraph = null;
monitor.done();
}
Aggregations