public void updateLayers() {
      final double spacing = 20.0d;
      layers.clear();
      if (graph.N() < 1) {
        return;
      }
      double minX = Double.MAX_VALUE, maxX = -Double.MAX_VALUE;
      for (NodeCursor nc = graph.nodes(); nc.ok(); nc.next()) {
        final Node node = nc.node();
        final int layer = layerIdMap.getInt(node);
        if (layer < 0) {
          continue;
        }
        while (layers.size() - 1 < layer) {
          layers.add(new Rectangle2D.Double(0, 0, -1, -1));
        }
        Rectangle2D.Double layerRect = (Rectangle2D.Double) layers.get(layer);
        final NodeLayout nl = graph.getNodeLayout(node);
        if (layerRect.width < 0) {
          layerRect.setFrame(nl.getX(), nl.getY(), nl.getWidth(), nl.getHeight());
        } else {
          layerRect.add(nl.getX(), nl.getY());
          layerRect.add(nl.getX() + nl.getWidth(), nl.getY() + nl.getHeight());
        }
        minX = Math.min(nl.getX(), minX);
        maxX = Math.max(nl.getX() + nl.getWidth(), maxX);
      }

      double minY = Double.MAX_VALUE;
      double maxY = -Double.MAX_VALUE;
      for (int i = 0; i < layers.size(); i++) {
        Rectangle2D.Double rect = (Rectangle2D.Double) layers.get(i);
        rect.x = minX - spacing;
        rect.width = maxX - minX + spacing * 2;
        if (i == 0) {
          rect.y -= spacing;
          rect.height += spacing;
          minY = rect.y;
        }
        if (i == layers.size() - 1) {
          rect.height += spacing;
          maxY = rect.height + rect.y;
        } else if (i < layers.size() - 1) {
          Rectangle2D.Double nextRect = (Rectangle2D.Double) layers.get(i + 1);
          final double mid = (rect.getY() + rect.getHeight() + nextRect.getY()) * 0.5d;
          rect.height += mid - (rect.y + rect.height);
          final double nextDelta = mid - nextRect.y;
          nextRect.y += nextDelta;
          nextRect.height -= nextDelta;
        }
      }
      bounds.setFrame(minX - spacing, minY, maxX - minX + 2 * spacing, maxY - minY);
      graph.updateViews();
    }