/** * Outputs layout information on the console. * * @param parentNode parent node representing a graph * @param progressMonitor progress monitor for the layout run */ private static void printLayoutInfo( final KNode parentNode, final IKielerProgressMonitor progressMonitor) { // print execution time of the algorithm run System.out.println("Execution time: " + progressMonitor.getExecutionTime() * 1000 + " ms"); // print position of each node for (KNode childNode : parentNode.getChildren()) { KShapeLayout childLayout = childNode.getData(KShapeLayout.class); System.out.println( childNode.getLabels().get(0).getText() + ": x = " + childLayout.getXpos() + ", y = " + childLayout.getYpos()); System.out.println( "Width: " + childLayout.getWidth() + " Height: " + childLayout.getHeight()); // EList<KEdge> incomingEdgeList = childNode.getIncomingEdges(); System.out.println("Edge To String"); for (KEdge incomingEdge : childNode.getIncomingEdges()) { System.out.println(incomingEdge.toString()); } // for(KEdge incomingEdge :childNode.getIncomingEdges() ){ // System.out.println(incomingEdge.getSourcePort().) // } } }
/** * Process an edge and its labels. * * @param edge an edge * @param edgeRouting the global edge routing setting */ private KVector processEdge(final KEdge edge, final EdgeRouting edgeRouting) { KEdgeLayout edgeLayout = edge.getData(KEdgeLayout.class); boolean sameHierarchy = edge.getSource().getParent() == edge.getTarget().getParent(); KVector maxv = new KVector(); KVectorChain bendPoints = edgeLayout.getProperty(LayoutOptions.BEND_POINTS); // we need at least two bend points, since the source point and target point must be included if (bendPoints != null && bendPoints.size() >= 2) { edgeLayout.applyVectorChain(bendPoints); } // determine maximal coordinates if (sameHierarchy) { for (KPoint point : edgeLayout.getBendPoints()) { maxv.x = Math.max(maxv.x, point.getX()); maxv.y = Math.max(maxv.y, point.getY()); } } // set the fixed position of the edge labels, or leave them as they are for (KLabel label : edge.getLabels()) { KShapeLayout labelLayout = label.getData(KShapeLayout.class); KVector pos = labelLayout.getProperty(LayoutOptions.POSITION); if (pos != null) { labelLayout.applyVector(pos); } if (sameHierarchy) { maxv.x = Math.max(maxv.x, labelLayout.getXpos() + labelLayout.getWidth()); maxv.y = Math.max(maxv.y, labelLayout.getYpos() + labelLayout.getHeight()); } } return maxv; }
/** * Adds layout options to the elements of the given parent node. * * @param parentNode parent node representing a graph */ private static void addLayoutOptions(final KNode parentNode) { // add options for the parent node KShapeLayout parentLayout = parentNode.getData(KShapeLayout.class); // set layout direction to horizontal parentLayout.setProperty(LayoutOptions.DIRECTION, Direction.RIGHT); // add options for the child nodes for (KNode childNode : parentNode.getChildren()) { KShapeLayout childLayout = childNode.getData(KShapeLayout.class); // set some width and height for the child childLayout.setWidth(30.0f); childLayout.setHeight(30.0f); // set fixed size for the child // childLayout.setProperty(LayoutOptions.FIXED_SIZE, Boolean.TRUE); // set port constraints to fixed port positions childLayout.setProperty(LayoutOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_POS); // add options for the ports int i = 0; for (KPort port : childNode.getPorts()) { i++; KShapeLayout portLayout = port.getData(KShapeLayout.class); // set position and side portLayout.setYpos(i * 30.0f / (childNode.getPorts().size() + 1)); if (childNode.getLabels().get(0).getText().equals("node1")) { portLayout.setXpos(30.0f); portLayout.setProperty(LayoutOptions.PORT_SIDE, PortSide.EAST); } else { portLayout.setXpos(0.0f); portLayout.setProperty(LayoutOptions.PORT_SIDE, PortSide.WEST); } } } }
/** {@inheritDoc} */ @Override public void doLayout(final KNode layoutNode, final IKielerProgressMonitor progressMonitor) { progressMonitor.begin("Fixed Layout", 1); KShapeLayout parentLayout = layoutNode.getData(KShapeLayout.class); EdgeRouting edgeRouting = parentLayout.getProperty(LayoutOptions.EDGE_ROUTING); float maxx = 0, maxy = 0; for (KNode node : layoutNode.getChildren()) { KShapeLayout nodeLayout = node.getData(KShapeLayout.class); // set the fixed position of the node, or leave it as it is KVector pos = nodeLayout.getProperty(LayoutOptions.POSITION); if (pos != null) { nodeLayout.applyVector(pos); // set the fixed size of the node // TODO Think about whether this makes sense with the new size constraint options. if (nodeLayout .getProperty(LayoutOptions.SIZE_CONSTRAINT) .contains(SizeConstraint.MINIMUM_SIZE)) { float width = nodeLayout.getProperty(LayoutOptions.MIN_WIDTH); float height = nodeLayout.getProperty(LayoutOptions.MIN_HEIGHT); if (width > 0 && height > 0) { KimlUtil.resizeNode(node, width, height, true, true); } } } maxx = Math.max(maxx, nodeLayout.getXpos() + nodeLayout.getWidth()); maxy = Math.max(maxy, nodeLayout.getYpos() + nodeLayout.getHeight()); // set the fixed position of the node labels, or leave them as they are for (KLabel label : node.getLabels()) { KShapeLayout labelLayout = label.getData(KShapeLayout.class); pos = labelLayout.getProperty(LayoutOptions.POSITION); if (pos != null) { labelLayout.applyVector(pos); } maxx = Math.max(maxx, nodeLayout.getXpos() + labelLayout.getXpos() + labelLayout.getWidth()); maxy = Math.max(maxy, nodeLayout.getYpos() + labelLayout.getYpos() + labelLayout.getHeight()); } // set the fixed position of the ports, or leave them as they are for (KPort port : node.getPorts()) { KShapeLayout portLayout = port.getData(KShapeLayout.class); pos = portLayout.getProperty(LayoutOptions.POSITION); if (pos != null) { portLayout.applyVector(pos); } float portx = nodeLayout.getXpos() + portLayout.getXpos(); float porty = nodeLayout.getYpos() + portLayout.getYpos(); maxx = Math.max(maxx, portx + portLayout.getWidth()); maxy = Math.max(maxy, porty + portLayout.getHeight()); // set the fixed position of the port labels, or leave them as they are for (KLabel label : port.getLabels()) { KShapeLayout labelLayout = label.getData(KShapeLayout.class); pos = labelLayout.getProperty(LayoutOptions.POSITION); if (pos != null) { labelLayout.applyVector(pos); } maxx = Math.max(maxx, portx + labelLayout.getXpos() + labelLayout.getWidth()); maxy = Math.max(maxy, porty + labelLayout.getYpos() + labelLayout.getHeight()); } } // set fixed routing for the connected edges, or leave them as they are for (KEdge edge : node.getOutgoingEdges()) { KVector maxv = processEdge(edge, edgeRouting); maxx = Math.max(maxx, (float) maxv.x); maxy = Math.max(maxy, (float) maxv.y); } for (KEdge edge : node.getIncomingEdges()) { if (edge.getSource().getParent() != layoutNode) { KVector maxv = processEdge(edge, edgeRouting); maxx = Math.max(maxx, (float) maxv.x); maxy = Math.max(maxy, (float) maxv.y); } } } // if orthogonal routing is selected, determine the junction points if (edgeRouting == EdgeRouting.ORTHOGONAL) { for (KNode node : layoutNode.getChildren()) { for (KEdge edge : node.getOutgoingEdges()) { generateJunctionPoints(edge); } } } // set size of the parent node float borderSpacing = parentLayout.getProperty(LayoutOptions.BORDER_SPACING); if (borderSpacing < 0) { borderSpacing = DEF_BORDER_SPACING; } KInsets insets = parentLayout.getInsets(); float newWidth = maxx + borderSpacing + insets.getLeft() + insets.getRight(); float newHeight = maxy + borderSpacing + insets.getTop() + insets.getBottom(); KimlUtil.resizeNode(layoutNode, newWidth, newHeight, true, true); progressMonitor.done(); }