use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class NetworkSimplexPlacer method markCrossingEdges.
/**
* Marks the crossings of edges between the two passed layers.
*/
private void markCrossingEdges(final Layer left, final Layer right) {
final List<LEdge> openEdges = Lists.newArrayList();
// add all edges in the order they occur in the left layer
for (LNode node : left) {
for (LPort port : node.getPortSideView(PortSide.EAST)) {
for (LEdge edge : port.getOutgoingEdges()) {
if (edge.isInLayerEdge() || edge.isSelfLoop() || edge.getTarget().getNode().getLayer() != right) {
continue;
}
openEdges.add(edge);
}
}
}
// close the edges one after another, recording edge crossings
for (LNode node : Lists.reverse(right.getNodes())) {
for (LPort port : node.getPortSideView(PortSide.WEST)) {
// don't reverse, bottom up is correct
for (LEdge edge : port.getIncomingEdges()) {
if (edge.isInLayerEdge() || edge.isSelfLoop() || edge.getSource().getNode().getLayer() != left) {
continue;
}
// start at the end
ListIterator<LEdge> openEdgesIt = openEdges.listIterator(openEdges.size());
LEdge last = openEdgesIt.previous();
while (last != edge && openEdgesIt.hasPrevious()) {
// mark both edges as being part of an edge crossing
crossing[last.id] = true;
crossing[edge.id] = true;
last = openEdgesIt.previous();
}
if (openEdgesIt.hasPrevious()) {
openEdgesIt.remove();
}
}
}
}
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class LinearSegmentsNodePlacer method calcDeflection.
/**
* Calculate the force acting on the given linear segment. The force is stored in the segment's
* deflection field.
*
* @param segment the linear segment whose force is to be calculated
* @param incoming whether incoming edges should be considered
* @param outgoing whether outgoing edges should be considered
* @param deflectionDampening factor by which deflections are dampened
*/
private void calcDeflection(final LinearSegment segment, final boolean incoming, final boolean outgoing, final double deflectionDampening) {
double segmentDeflection = 0;
int nodeWeightSum = 0;
for (LNode node : segment.nodes) {
double nodeDeflection = 0;
int edgeWeightSum = 0;
int inputPrio = incoming ? node.getProperty(INPUT_PRIO) : Integer.MIN_VALUE;
int outputPrio = outgoing ? node.getProperty(OUTPUT_PRIO) : Integer.MIN_VALUE;
int minPrio = Math.max(inputPrio, outputPrio);
// Calculate force for every port/edge
for (LPort port : node.getPorts()) {
double portpos = node.getPosition().y + port.getPosition().y + port.getAnchor().y;
if (outgoing) {
for (LEdge edge : port.getOutgoingEdges()) {
LPort otherPort = edge.getTarget();
LNode otherNode = otherPort.getNode();
if (segment != linearSegments[otherNode.id]) {
int otherPrio = Math.max(otherNode.getProperty(INPUT_PRIO), otherNode.getProperty(OUTPUT_PRIO));
int prio = edge.getProperty(LayeredOptions.PRIORITY_STRAIGHTNESS);
if (prio >= minPrio && prio >= otherPrio) {
nodeDeflection += otherNode.getPosition().y + otherPort.getPosition().y + otherPort.getAnchor().y - portpos;
edgeWeightSum++;
}
}
}
}
if (incoming) {
for (LEdge edge : port.getIncomingEdges()) {
LPort otherPort = edge.getSource();
LNode otherNode = otherPort.getNode();
if (segment != linearSegments[otherNode.id]) {
int otherPrio = Math.max(otherNode.getProperty(INPUT_PRIO), otherNode.getProperty(OUTPUT_PRIO));
int prio = edge.getProperty(LayeredOptions.PRIORITY_STRAIGHTNESS);
if (prio >= minPrio && prio >= otherPrio) {
nodeDeflection += otherNode.getPosition().y + otherPort.getPosition().y + otherPort.getAnchor().y - portpos;
edgeWeightSum++;
}
}
}
}
}
// Avoid division by zero
if (edgeWeightSum > 0) {
segmentDeflection += nodeDeflection / edgeWeightSum;
nodeWeightSum++;
}
}
if (nodeWeightSum > 0) {
segment.deflection = deflectionDampening * segmentDeflection / nodeWeightSum;
segment.weight = nodeWeightSum;
} else {
segment.deflection = 0;
segment.weight = 0;
}
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class CuttingUtils method insertDummies.
/**
* Inserts two in-layer dummies and a varying number of long edge dummies for the passed edge.
*
* Let {@code originalEdge = e = (u,v)}. In-layer dummies {@code il_1} and {@code il_2} are inserted into layers
* {@code L(u)} and {@code L(v)}. Long edge dummies {@code d_1, ..., d_m} are inserted into the layers
* {@code L(u)+1, ..., L(v)-1}.
*
* The resulting chain of edges looks as follows (if {@code offsetFirstInLayerDummy} is 1).
*
* <pre>
* v
* î
* il_1 -> d_1 -> ... -> d_m -> il_2
* î
* u
* </pre>
*
* @param layeredGraph
* the underlying graph with a given layering.
* @param originalEdge
* the edge to be split
* @param offsetFirstInLayerDummy
* the dummy nodes are inserted at the end of each layer. For the first in-layer dummy this is not always
* desired and can be modified using this offset.
*/
public static List<LEdge> insertDummies(final LGraph layeredGraph, final LEdge originalEdge, final int offsetFirstInLayerDummy) {
// to visually separate the backward wrapping edges, add some additional spacing
double edgeNodeSpacing = layeredGraph.getProperty(LayeredOptions.SPACING_EDGE_NODE);
double additionalSpacing = layeredGraph.getProperty(LayeredOptions.WRAPPING_ADDITIONAL_EDGE_SPACING);
IndividualSpacings is = new IndividualSpacings();
is.setProperty(LayeredOptions.SPACING_EDGE_NODE, edgeNodeSpacing + additionalSpacing);
LEdge edge = originalEdge;
LPort targetPort = edge.getTarget();
LNode src = edge.getSource().getNode();
LNode tgt = edge.getTarget().getNode();
int srcIndex = src.getLayer().getIndex();
int tgtIndex = tgt.getLayer().getIndex();
List<LEdge> createdEdges = Lists.newArrayList();
for (int i = srcIndex; i <= tgtIndex; i++) {
// Create dummy node
LNode dummyNode = new LNode(layeredGraph);
dummyNode.setType(NodeType.LONG_EDGE);
dummyNode.setProperty(InternalProperties.ORIGIN, edge);
dummyNode.setProperty(LayeredOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_POS);
dummyNode.setProperty(LayeredOptions.SPACING_INDIVIDUAL, is);
Layer nextLayer = layeredGraph.getLayers().get(i);
if (i == srcIndex) {
dummyNode.setLayer(nextLayer.getNodes().size() - offsetFirstInLayerDummy, nextLayer);
} else {
dummyNode.setLayer(nextLayer);
}
// Set thickness of the edge
double thickness = edge.getProperty(LayeredOptions.EDGE_THICKNESS);
if (thickness < 0) {
thickness = 0;
edge.setProperty(LayeredOptions.EDGE_THICKNESS, thickness);
}
dummyNode.getSize().y = thickness;
double portPos = Math.floor(thickness / 2);
// Create dummy input and output ports
LPort dummyInput = new LPort();
dummyInput.setSide(PortSide.WEST);
dummyInput.setNode(dummyNode);
dummyInput.getPosition().y = portPos;
LPort dummyOutput = new LPort();
dummyOutput.setSide(PortSide.EAST);
dummyOutput.setNode(dummyNode);
dummyOutput.getPosition().y = portPos;
edge.setTarget(dummyInput);
// Create a dummy edge
LEdge dummyEdge = new LEdge();
dummyEdge.copyProperties(edge);
dummyEdge.setProperty(LayeredOptions.JUNCTION_POINTS, null);
dummyEdge.setSource(dummyOutput);
dummyEdge.setTarget(targetPort);
setDummyProperties(dummyNode, edge, dummyEdge);
createdEdges.add(dummyEdge);
edge = dummyEdge;
}
return createdEdges;
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class GraphStats method determineLayerHeight.
private double determineLayerHeight(final Layer layer) {
double lH = 0;
for (LNode n : layer.getNodes()) {
lH += n.getSize().y + n.getMargin().bottom + n.getMargin().top + inLayerSpacing;
for (LEdge inc : n.getIncomingEdges()) {
if (inc.getSource().getNode().getType() == NodeType.NORTH_SOUTH_PORT) {
LNode src = inc.getSource().getNode();
LNode origin = (LNode) src.getProperty(InternalProperties.ORIGIN);
lH += origin.getSize().y + origin.getMargin().bottom + origin.getMargin().top;
}
}
}
return lH;
}
use of org.eclipse.elk.alg.layered.graph.LEdge in project elk by eclipse.
the class DepthFirstCycleBreaker method process.
@Override
public void process(final LGraph graph, final IElkProgressMonitor monitor) {
monitor.begin("Depth-first cycle removal", 1);
List<LNode> nodes = graph.getLayerlessNodes();
// initialize values for the algorithm
int nodeCount = nodes.size();
sources = new ArrayList<>();
visited = new boolean[nodeCount];
active = new boolean[nodeCount];
edgesToBeReversed = new ArrayList<>();
int index = 0;
for (LNode node : nodes) {
// The node id is used as index into our arrays
node.id = index;
if (Iterables.isEmpty(node.getIncomingEdges())) {
sources.add(node);
}
index++;
}
// From every source node start a DFS
for (LNode source : sources) {
dfs(source);
}
// are not source nodes
for (int i = 0; i < nodeCount; i++) {
if (!visited[i]) {
LNode n = nodes.get(i);
assert n.id == i;
dfs(n);
}
}
// Reverse "back edges"
for (LEdge edge : edgesToBeReversed) {
edge.reverse(graph, true);
graph.setProperty(InternalProperties.CYCLIC, true);
}
// Cleanup
this.sources = null;
this.visited = null;
this.active = null;
this.edgesToBeReversed = null;
monitor.done();
}
Aggregations