/** * Adjusts the Y coordinate to prevent node overlap. * * <p>Here is a situation where this method is required. <code>EIP_____ EIP 1 ______ edpt * \____ EIP 2 ______ edpt</code> With the single algorithm, EIP 1 and 2 will overlap * vertically. */ private void adjustYCoordinates() { // 1st pass: correct the padding and suppress overlap List<EipNode> zeroNodes = new ArrayList<EipNode>(); Map<AbstractNode, Integer> nodeToNewOffset = new HashMap<AbstractNode, Integer>(); for (ArrayList<AbstractNode> nodes : this.levelToNodes.values()) { int maxY = 0; for (AbstractNode node : nodes) { // Find the original Y int y = this.nodeToCoY.get(node); // The initial offset is inherited from the parent int offset = 0; if (node.getIncomingConnection() != null) offset = nodeToNewOffset.get(node.getIncomingConnection().getSource()); // Prevent overlap if (y <= maxY) offset = maxY - y; // Make sure there is the minimal vertical padding if (maxY != 0 && y - maxY < GRID_PADDING_Y) offset += GRID_PADDING_Y - y + maxY; // Store the new Y y += offset; nodeToNewOffset.put(node, offset); this.nodeToCoY.put(node, y); // Update the maximal Y for this level maxY = y + getFigureSize(node).height; // Something for the next pass? if (offset == 0 && node instanceof EipNode) zeroNodes.add((EipNode) node); } } // 2nd pass: there may be nodes that were not translated (e.g. the root node). // This pass moves them at the middle-Y... for (EipNode eip : zeroNodes) { int y = computeCenteredYCoordinate(eip, getFigureSize(eip)); this.nodeToCoY.put(eip, y); } }
/** * @param node a node * @return the size of the figure associated to this node */ private Dimension getFigureSize(AbstractNode node) { IFigure fig = this.nodeToFigure.get(node); int width, height; if (fig != null) { width = fig.getSize().width; height = fig.getSize().height; } else { width = GRID_CELL_DEFAULT_WIDTH; ; height = GRID_CELL_DEFAULT_HEIGHT; PetalsEipPlugin.log( "No figure was found for the node " + node.getId() + " (EIP chain: " + node.getEipChain().getTitle() + " ).", IStatus.ERROR); } return new Dimension(width, height); }