All Downloads are FREE. Search and download functionalities are using the official Maven repository.

info.scce.addlib.layouter.SimpleLayouter Maven / Gradle / Ivy

Go to download

The Java Library for Algebraic Decision Diagrams, Code Generation, and Layouting

There is a newer version: 3.1.0
Show newest version
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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy