info.scce.addlib.layouter.SimpleLayouter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of addlib Show documentation
Show all versions of addlib Show documentation
The Java Library for Algebraic Decision Diagrams, Code Generation, and Layouting
package info.scce.addlib.layouter;
import info.scce.addlib.dd.RegularDD;
import java.util.*;
import static java.lang.Math.max;
public class SimpleLayouter> extends Layouter {
private double anchorX = 0.0;
private double anchorY = 0.0;
private double nodeMarginX = 1.0;
private double nodeMarginY = 1.0;
private double nodeWidth = 0.5;
private double nodeHeight = 0.5;
private double nodeWidthPerCharacter = 0.0;
public SimpleLayouter withAnchorPosition(double anchorX, double anchorY) {
this.anchorX = anchorX;
this.anchorY = anchorY;
return this;
}
public SimpleLayouter withNodeMargin(double nodeMarginX, double nodeMarginY) {
this.nodeMarginX = nodeMarginX;
this.nodeMarginY = nodeMarginY;
return this;
}
public SimpleLayouter withNodeDimension(double nodeWidth, double nodeHeight, double widthPerCharacter) {
this.nodeWidth = nodeWidth;
this.nodeHeight = nodeHeight;
nodeWidthPerCharacter = widthPerCharacter;
return this;
}
@Override
protected Map computeLayout(List roots) {
List> sortedLayers = sortedLayers(roots);
return computeLayoutFromSortedList(sortedLayers);
}
private List> sortedLayers(List roots) {
List> sortedLayers = new ArrayList<>();
List constants = new ArrayList<>();
Set seen = new HashSet<>();
for (D dd : roots)
sortedLayersRecur(dd, sortedLayers, constants, seen);
sortedLayers.add(constants);
return sortedLayers;
}
private void sortedLayersRecur(D dd, List> sortedLayers, List constants, Set seen) {
if (!seen.contains(dd)) {
seen.add(dd);
if (dd.isConstant()) {
constants.add(dd);
} else {
int i = dd.readIndex();
while (sortedLayers.size() <= i)
sortedLayers.add(new ArrayList<>());
sortedLayers.get(i).add(dd);
sortedLayersRecur(dd.t(), sortedLayers, constants, seen);
sortedLayersRecur(dd.e(), sortedLayers, constants, seen);
}
}
}
private Map computeLayoutFromSortedList(List> sortedLayers) {
HashMap layout = new HashMap<>();
double maxLayerWidth = maxLayerWidth(sortedLayers);
double y = anchorY;
for (List layer : sortedLayers) {
double x = layerX(layer, maxLayerWidth);
for (D node : layer) {
double nodeWidth = nodeWidth(node);
layout.put(node, new BoundingBox(x, y, nodeWidth, nodeHeight));
x += nodeWidth + nodeMarginX;
}
if (!layer.isEmpty())
y += nodeHeight + nodeMarginY;
}
return layout;
}
private double maxLayerWidth(List> sortedLayers) {
double maxLayerWidth = 0.0;
for (List layer : sortedLayers)
maxLayerWidth = max(maxLayerWidth, layerWidth(layer));
return maxLayerWidth;
}
private double layerWidth(List layer) {
double width = 0.0;
Iterator it = layer.iterator();
if (it.hasNext())
width += nodeWidth(it.next());
while (it.hasNext())
width += nodeMarginX + nodeWidth(it.next());
return width;
}
private double layerX(List layer, double maxLayerWidth) {
double smallestLayerX = anchorX - maxLayerWidth / 2;
return smallestLayerX + (maxLayerWidth - layerWidth(layer)) / 2;
}
private double nodeWidth(D dd) {
return nodeWidth + dd.toString().length() * nodeWidthPerCharacter;
}
}