Search in sources :

Example 26 with ElkEdgeSection

use of org.eclipse.elk.graph.ElkEdgeSection in project elk by eclipse.

the class ElkGraphTransformer method applyLayout.

@Override
public void applyLayout() {
    KVector graphDimensions = transformedGraph.getDimensions();
    double newWidth = graphDimensions.x;
    double newHeight = graphDimensions.y;
    double oldWidth = parent.getWidth();
    double oldHeight = parent.getHeight();
    // Adjust size of layout
    parent.setDimensions(graphDimensions.x, graphDimensions.y);
    double xFactor = newWidth / oldWidth;
    double yFactor = newHeight / oldHeight;
    for (ElkLabel label : parent.getLabels()) {
        label.setX(label.getX() * xFactor);
        label.setY(label.getY() * yFactor);
    }
    for (ElkPort port : parent.getPorts()) {
        double px = port.getX();
        double py = port.getY();
        if (px > 0) {
            port.setX(px * xFactor);
        }
        if (py > 0) {
            port.setY(py * yFactor);
        }
    }
    // Apply offsets, whenever necessary.
    elementMapping.forEach(new OffsetApplier());
    List<ElkPort> adjustedPorts = Lists.newArrayList();
    ElkPort portToAdjust;
    for (Entry<ElkEdge, DCExtension> inEntry : incomingExtensionsMapping.entrySet()) {
        ElkEdge edge = inEntry.getKey();
        DCDirection dir = inEntry.getValue().getDirection();
        ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(edge, false, false);
        KVectorChain newPoints = adjustFirstSegment(ElkGraphUtil.getSourceNode(edge), ElkUtil.createVectorChain(edgeSection), dir);
        ElkUtil.applyVectorChain(newPoints, edgeSection);
        portToAdjust = ElkGraphUtil.getSourcePort(edge);
        if (portToAdjust != null && !adjustedPorts.contains(portToAdjust)) {
            adjustedPorts.add(portToAdjust);
            adjustRelatedPort(portToAdjust, newPoints.getFirst(), dir);
        }
    }
    for (Entry<ElkEdge, DCExtension> outEntry : outgoingExtensionsMapping.entrySet()) {
        ElkEdge edge = outEntry.getKey();
        DCDirection dir = outEntry.getValue().getDirection();
        ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(edge, false, false);
        KVectorChain newPoints = adjustFirstSegment(ElkGraphUtil.getTargetNode(edge), KVectorChain.reverse(ElkUtil.createVectorChain(edgeSection)), dir);
        newPoints = KVectorChain.reverse(newPoints);
        ElkUtil.applyVectorChain(newPoints, edgeSection);
        portToAdjust = ElkGraphUtil.getTargetPort(edge);
        if (portToAdjust != null && !adjustedPorts.contains(portToAdjust)) {
            adjustedPorts.add(portToAdjust);
            adjustRelatedPort(portToAdjust, newPoints.getLast(), dir);
        }
    }
}
Also used : ElkLabel(org.eclipse.elk.graph.ElkLabel) ElkPort(org.eclipse.elk.graph.ElkPort) KVectorChain(org.eclipse.elk.core.math.KVectorChain) DCExtension(org.eclipse.elk.alg.disco.graph.DCExtension) DCDirection(org.eclipse.elk.alg.disco.graph.DCDirection) KVector(org.eclipse.elk.core.math.KVector) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 27 with ElkEdgeSection

use of org.eclipse.elk.graph.ElkEdgeSection in project elk by eclipse.

the class ElkGraphTransformer method importElkEdge.

/**
 * Transforms a {@link ElkEdge} into a {@link DCElement} without destroying it. Edges can have their own
 * {@link ElkLabel ElkLabels}, so they will be transformed, too.
 *
 * @param edge
 *            Edge to be transformed into a {@link DCElement}
 * @param newComponent
 *            Collection representing the component the edge and its associated labels (if any) belong to. Newly
 *            generated {@link DCElement DCElements} will be added to it
 * @return {@link DCElement} resulting from the transformation
 */
private DCElement importElkEdge(final ElkEdge edge, final Collection<DCElement> newComponent) {
    ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(edge, false, false);
    List<KVector> points = ElkUtil.createVectorChain(edgeSection);
    double thickness = edge.getProperty(DisCoOptions.EDGE_THICKNESS);
    KVectorChain contour = getContour(points, thickness + componentSpacing);
    DCElement shape = new DCElement(contour);
    shape.copyProperties(edge);
    elementMapping.put(edge, shape);
    newComponent.add(shape);
    // ElkEdges can have labels, too!
    List<ElkLabel> labels = edge.getLabels();
    for (ElkLabel label : labels) {
        // "true" - ElkLabels belonging to an ElkEdge have absolute coordinates and have to be considered when
        // applying
        // changes to the DCGraph back to the original graph.
        DCElement componentLabel = importElkShape(label, true, 0.0f, 0.0f);
        newComponent.add(componentLabel);
    }
    return shape;
}
Also used : ElkLabel(org.eclipse.elk.graph.ElkLabel) KVectorChain(org.eclipse.elk.core.math.KVectorChain) DCElement(org.eclipse.elk.alg.disco.graph.DCElement) KVector(org.eclipse.elk.core.math.KVector) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection)

Example 28 with ElkEdgeSection

use of org.eclipse.elk.graph.ElkEdgeSection in project elk by eclipse.

the class ElkGraphTransformer method importExtension.

/**
 * Transforms a {@link ElkEdge} into a {@link DCElement} without destroying it. Edges can have their own
 * {@link ElkLabel ElkLabels}, so they will be transformed, too.
 *
 * @param edge
 *            Edge to be transformed into a {@link DCElement}
 * @param newComponent
 *            Collection representing the component the edge and its associated labels (if any) belong to. Newly
 *            generated {@link DCElement DCElements} will be added to it
 * @return {@link DCElement} resulting from the transformation
 */
/**
 * Transforms a short hierarchical {@link ElkEdge} into a {@link DCExtension} without destroying it. Edges can have
 * their own {@link ElkLabel ElkLabels}, so they will be transformed, too.
 *
 * @param edge
 *            Edge to be transformed into a {@link DCExtension}
 * @param newComponent
 *            component the extension will belong to
 * @param outgoingExtension
 *            true, if the edge should be handled as an outgoing extension; false, otherwise
 */
private void importExtension(final ElkEdge edge, final Collection<DCElement> newComponent, final boolean outgoingExtension) {
    ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(edge, false, false);
    KVectorChain points = ElkUtil.createVectorChain(edgeSection);
    if (outgoingExtension) {
        points = KVectorChain.reverse(points);
    }
    // Is going to hold the extension
    DCElement shape;
    double thickness = edge.getProperty(DisCoOptions.EDGE_THICKNESS);
    KVector outerPoint = points.getFirst();
    KVector innerPoint = points.get(1);
    if (points.size() > 2) {
        List<KVector> fixedEdgePoints = Lists.newArrayList();
        fixedEdgePoints.addAll(points.subList(1, points.size()));
        KVectorChain contour = getContour(fixedEdgePoints, thickness + componentSpacing);
        shape = new DCElement(contour);
        shape.copyProperties(edge);
        newComponent.add(shape);
    } else {
        if (outgoingExtension) {
            shape = elementMapping.get(ElkGraphUtil.getSourceNode(edge));
        } else {
            shape = elementMapping.get(ElkGraphUtil.getTargetNode(edge));
        }
    }
    // Construct the extension and add to mapping
    ElkNode extParent = ElkGraphUtil.getSourceNode(edge);
    if (outgoingExtension) {
        extParent = ElkGraphUtil.getTargetNode(edge);
    }
    DCDirection dir = nearestSide(outerPoint, extParent);
    double extensionWidth = thickness + componentSpacing;
    KVector middlePos;
    if (dir.isHorizontal()) {
        // West or east extension
        extensionWidth += Math.abs(outerPoint.y - innerPoint.y);
        middlePos = new KVector(innerPoint.x, (innerPoint.y + outerPoint.y) / 2);
    } else {
        extensionWidth += Math.abs(outerPoint.x - innerPoint.x);
        middlePos = new KVector((innerPoint.x + outerPoint.x) / 2, innerPoint.y);
    }
    if (outgoingExtension) {
        outgoingExtensionsMapping.put(edge, new DCExtension(shape, dir, middlePos, extensionWidth));
    } else {
        incomingExtensionsMapping.put(edge, new DCExtension(shape, dir, middlePos, extensionWidth));
    }
    elementMapping.put(edge, shape);
    // ElkEdges can have labels, too!
    List<ElkLabel> labels = edge.getLabels();
    for (ElkLabel label : labels) {
        // "true" - ElkLabels belonging to an ElkEdge have absolute coordinates and have to be considered when
        // applying
        // changes to the DCGraph back to the original graph.
        DCElement componentLabel = importElkShape(label, true, 0.0f, 0.0f);
        newComponent.add(componentLabel);
    }
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) ElkLabel(org.eclipse.elk.graph.ElkLabel) KVectorChain(org.eclipse.elk.core.math.KVectorChain) DCExtension(org.eclipse.elk.alg.disco.graph.DCExtension) DCElement(org.eclipse.elk.alg.disco.graph.DCElement) DCDirection(org.eclipse.elk.alg.disco.graph.DCDirection) KVector(org.eclipse.elk.core.math.KVector) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection)

Example 29 with ElkEdgeSection

use of org.eclipse.elk.graph.ElkEdgeSection in project elk by eclipse.

the class DisCoGraphRenderer method renderEdge.

/**
 * Paints an edge for the given dirty area.
 *
 * @param graph
 *            the top-level node of the graph
 * @param edge
 *            the edge to paint
 * @param graphics
 *            the graphics context used to paint
 * @param area
 *            dirty area that needs painting
 * @param labelAlpha
 *            alpha value for labels
 */
private void renderEdge(final ElkNode graph, final ElkEdge edge, final GC graphics, final Rectangle area, final KVector edgeBaseOffset, final int labelAlpha) {
    if (configurator.getEdgeColor() == null) {
        return;
    }
    if (!ElkGraphUtil.isDescendant(ElkGraphUtil.getSourceNode(edge), graph) || !ElkGraphUtil.isDescendant(ElkGraphUtil.getTargetNode(edge), graph)) {
        // the edge points to some node outside of the rendered subgraph
        return;
    }
    // calculate an offset for edge coordinates
    ElkNode parent = ElkGraphUtil.getSourceNode(edge);
    if (!ElkGraphUtil.isDescendant(ElkGraphUtil.getTargetNode(edge), parent)) {
        parent = parent.getParent();
    }
    ElkNode node = parent;
    KVector offset = new KVector().add(edgeBaseOffset);
    while (node != graph) {
        offset.add(node.getX() * getScale(), node.getY() * getScale());
        node = node.getParent();
    }
    // ElkEdgeLayout edgeLayout = edge.getData(ElkEdgeLayout.class);
    PaintRectangle rect = boundsMap.get(edge);
    if (rect == null) {
        rect = new PaintRectangle(edge, offset, getScale());
        boundsMap.put(edge, rect);
    }
    if (!rect.painted && rect.intersects(area)) {
        // CHECKSTYLEOFF MagicNumber
        graphics.setAlpha(255);
        // CHECKSTYLEON MagicNumber
        // The background color is required to fill the arrow of directed
        // edges
        graphics.setForeground(configurator.getEdgeColor());
        graphics.setBackground(configurator.getEdgeColor());
        ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(edge, false, false);
        KVectorChain bendPoints = ElkUtil.createVectorChain(edgeSection);
        if (edge.getProperty(CoreOptions.EDGE_ROUTING) == EdgeRouting.SPLINES) {
            bendPoints = ElkMath.approximateBezierSpline(bendPoints);
        }
        bendPoints.scale(getScale()).offset(offset);
        KVector point1 = bendPoints.getFirst();
        for (KVector point2 : bendPoints) {
            graphics.drawLine((int) Math.round(point1.x), (int) Math.round(point1.y), (int) Math.round(point2.x), (int) Math.round(point2.y));
            point1 = point2;
        }
        if (edge.getProperty(CoreOptions.EDGE_TYPE) != EdgeType.UNDIRECTED) {
            // draw an arrow at the last segment of the connection
            int[] arrowPoly = makeArrow(bendPoints.get(bendPoints.size() - 2), bendPoints.getLast());
            if (arrowPoly != null) {
                graphics.fillPolygon(arrowPoly);
            }
        }
        rect.painted = true;
    }
    // paint junction points
    KVectorChain vc = edge.getProperty(CoreOptions.JUNCTION_POINTS);
    if (vc != null) {
        for (KVector v : vc) {
            KVector center = v.clone().scale(getScale()).add(offset).sub(2, 2);
            // CHECKSTYLEOFF MagicNumber
            graphics.fillOval((int) center.x, (int) center.y, 6, 6);
        // CHECKSTYLEON MagicNumber
        }
    }
    // paint the edge labels
    if (configurator.getEdgeLabelFont() != null) {
        graphics.setFont(configurator.getEdgeLabelFont());
        for (ElkLabel label : edge.getLabels()) {
            renderLabel(label, graphics, area, offset, labelAlpha);
        }
    }
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) ElkLabel(org.eclipse.elk.graph.ElkLabel) KVectorChain(org.eclipse.elk.core.math.KVectorChain) KVector(org.eclipse.elk.core.math.KVector) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection)

Example 30 with ElkEdgeSection

use of org.eclipse.elk.graph.ElkEdgeSection in project elk by eclipse.

the class ElkGraphImporter method applyLayout.

// /////////////////////////////////////////////////////////////////////////////
// Apply Layout Results
@Override
public void applyLayout(final FGraph fgraph) {
    ElkNode kgraph = (ElkNode) fgraph.getProperty(InternalProperties.ORIGIN);
    // calculate the offset from border spacing and node distribution
    double minXPos = Integer.MAX_VALUE;
    double minYPos = Integer.MAX_VALUE;
    double maxXPos = Integer.MIN_VALUE;
    double maxYPos = Integer.MIN_VALUE;
    for (FNode node : fgraph.getNodes()) {
        KVector pos = node.getPosition();
        KVector size = node.getSize();
        minXPos = Math.min(minXPos, pos.x - size.x / 2);
        minYPos = Math.min(minYPos, pos.y - size.y / 2);
        maxXPos = Math.max(maxXPos, pos.x + size.x / 2);
        maxYPos = Math.max(maxYPos, pos.y + size.y / 2);
    }
    ElkPadding padding = kgraph.getProperty(ForceOptions.PADDING);
    KVector offset = new KVector(padding.getLeft() - minXPos, padding.getTop() - minYPos);
    // process the nodes
    for (FNode fnode : fgraph.getNodes()) {
        Object object = fnode.getProperty(InternalProperties.ORIGIN);
        if (object instanceof ElkNode) {
            // set the node position
            ElkNode knode = (ElkNode) object;
            KVector nodePos = fnode.getPosition().add(offset);
            knode.setLocation(nodePos.x - knode.getWidth() / 2, nodePos.y - knode.getHeight() / 2);
        }
    }
    // process the edges
    for (FEdge fedge : fgraph.getEdges()) {
        ElkEdge kedge = (ElkEdge) fedge.getProperty(InternalProperties.ORIGIN);
        ElkEdgeSection kedgeSection = ElkGraphUtil.firstEdgeSection(kedge, true, true);
        KVector startLocation = fedge.getSourcePoint();
        kedgeSection.setStartLocation(startLocation.x, startLocation.y);
        KVector endLocation = fedge.getTargetPoint();
        kedgeSection.setEndLocation(endLocation.x, endLocation.y);
    }
    // process the labels
    for (FLabel flabel : fgraph.getLabels()) {
        ElkLabel klabel = (ElkLabel) flabel.getProperty(InternalProperties.ORIGIN);
        KVector labelPos = flabel.getPosition().add(offset);
        klabel.setLocation(labelPos.x, labelPos.y);
    }
    // set up the parent node
    double width = (maxXPos - minXPos) + padding.getHorizontal();
    double height = (maxYPos - minYPos) + padding.getVertical();
    ElkUtil.resizeNode(kgraph, width, height, false, true);
}
Also used : FLabel(org.eclipse.elk.alg.force.graph.FLabel) ElkNode(org.eclipse.elk.graph.ElkNode) ElkLabel(org.eclipse.elk.graph.ElkLabel) FNode(org.eclipse.elk.alg.force.graph.FNode) FEdge(org.eclipse.elk.alg.force.graph.FEdge) KVector(org.eclipse.elk.core.math.KVector) ElkPadding(org.eclipse.elk.core.math.ElkPadding) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Aggregations

ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)37 KVector (org.eclipse.elk.core.math.KVector)23 ElkEdge (org.eclipse.elk.graph.ElkEdge)21 ElkNode (org.eclipse.elk.graph.ElkNode)21 ElkLabel (org.eclipse.elk.graph.ElkLabel)14 KVectorChain (org.eclipse.elk.core.math.KVectorChain)13 ElkBendPoint (org.eclipse.elk.graph.ElkBendPoint)11 ElkPort (org.eclipse.elk.graph.ElkPort)10 LinkedList (java.util.LinkedList)6 ElkConnectableShape (org.eclipse.elk.graph.ElkConnectableShape)6 ArrayList (java.util.ArrayList)4 ElkPadding (org.eclipse.elk.core.math.ElkPadding)4 PointList (org.eclipse.draw2d.geometry.PointList)3 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)3 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)3 Test (org.junit.Test)3 ListIterator (java.util.ListIterator)2 Point (org.eclipse.draw2d.geometry.Point)2 DCDirection (org.eclipse.elk.alg.disco.graph.DCDirection)2 DCElement (org.eclipse.elk.alg.disco.graph.DCElement)2