Search in sources :

Example 11 with LNode

use of org.eclipse.elk.alg.layered.graph.LNode in project elk by eclipse.

the class LabelDummySwitcher method computeLayerWidthSums.

/**
 * Computes an array in which entry i refers to the combined width of layers [0, i]. The combined width is
 * estimated based on the currently estimated layer width and a wild guess as to the layer spacing.
 */
private double[] computeLayerWidthSums(final LabelDummyInfo labelDummyInfo) {
    // The minimum space that we think will be left between
    LGraph lgraph = labelDummyInfo.labelDummy.getGraph();
    double edgeNodeSpacing = lgraph.getProperty(LayeredOptions.SPACING_EDGE_NODE_BETWEEN_LAYERS) * 2;
    double nodeNodeSpacing = lgraph.getProperty(LayeredOptions.SPACING_NODE_NODE_BETWEEN_LAYERS);
    double minSpaceBetweenLayers = Math.max(edgeNodeSpacing, nodeNodeSpacing);
    // The array that will hold the accumulated widths
    double[] layerWidthSums = new double[labelDummyInfo.totalDummyCount()];
    double currentWidthSum = -minSpaceBetweenLayers;
    int currentIndex = 0;
    for (LNode leftDummy : labelDummyInfo.leftLongEdgeDummies) {
        currentWidthSum += layerWidths[leftDummy.getLayer().id] + minSpaceBetweenLayers;
        layerWidthSums[currentIndex++] = currentWidthSum;
    }
    currentWidthSum += layerWidths[labelDummyInfo.labelDummy.getLayer().id] + minSpaceBetweenLayers;
    layerWidthSums[currentIndex++] = currentWidthSum;
    for (LNode rightDummy : labelDummyInfo.rightLongEdgeDummies) {
        currentWidthSum += layerWidths[rightDummy.getLayer().id] + minSpaceBetweenLayers;
        layerWidthSums[currentIndex++] = currentWidthSum;
    }
    return layerWidthSums;
}
Also used : LNode(org.eclipse.elk.alg.layered.graph.LNode) LGraph(org.eclipse.elk.alg.layered.graph.LGraph)

Example 12 with LNode

use of org.eclipse.elk.alg.layered.graph.LNode 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);
            }
        }
    }
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 13 with LNode

use of org.eclipse.elk.alg.layered.graph.LNode 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;
            }
        }
    }
}
Also used : LLabel(org.eclipse.elk.alg.layered.graph.LLabel) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 14 with LNode

use of org.eclipse.elk.alg.layered.graph.LNode 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);
        }
    }
}
Also used : LNode(org.eclipse.elk.alg.layered.graph.LNode) Layer(org.eclipse.elk.alg.layered.graph.Layer) ArrayDeque(java.util.ArrayDeque)

Example 15 with LNode

use of org.eclipse.elk.alg.layered.graph.LNode 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();
        }
    }
}
Also used : LNode(org.eclipse.elk.alg.layered.graph.LNode) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Aggregations

LNode (org.eclipse.elk.alg.layered.graph.LNode)471 LPort (org.eclipse.elk.alg.layered.graph.LPort)189 Layer (org.eclipse.elk.alg.layered.graph.Layer)185 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)110 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)91 Test (org.junit.Test)85 KVector (org.eclipse.elk.core.math.KVector)38 PortSide (org.eclipse.elk.core.options.PortSide)28 List (java.util.List)23 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)22 GraphInfoHolder (org.eclipse.elk.alg.layered.p3order.GraphInfoHolder)16 TestAfterProcessor (org.eclipse.elk.alg.test.framework.annotations.TestAfterProcessor)16 KVectorChain (org.eclipse.elk.core.math.KVectorChain)15 NodeType (org.eclipse.elk.alg.layered.graph.LNode.NodeType)14 ArrayList (java.util.ArrayList)13 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)13 LayeredOptions (org.eclipse.elk.alg.layered.options.LayeredOptions)13 PortConstraints (org.eclipse.elk.core.options.PortConstraints)13 Set (java.util.Set)12 CrossingsCounter (org.eclipse.elk.alg.layered.p3order.counting.CrossingsCounter)10