Package com.mxgraph.layout

Source Code of com.mxgraph.layout.mxParallelEdgeLayout

package com.mxgraph.layout;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.mxgraph.model.mxCellPath;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.model.mxICell;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.util.mxPoint;
import com.mxgraph.view.mxCellState;
import com.mxgraph.view.mxGraph;
import com.mxgraph.view.mxGraphView;

public class mxParallelEdgeLayout extends mxGraphLayout
{

  /**
   * Specifies the spacing between the edges. Default is 20.
   */
  protected int spacing;

  /**
   * Constructs a new stack layout layout for the specified graph,
   * spacing, orientation and offset.
   */
  public mxParallelEdgeLayout(mxGraph graph)
  {
    this(graph, 20);
  }

  /**
   * Constructs a new stack layout layout for the specified graph,
   * spacing, orientation and offset.
   */
  public mxParallelEdgeLayout(mxGraph graph, int spacing)
  {
    super(graph);
    this.spacing = spacing;
  }

  /*
   * (non-Javadoc)
   * @see com.mxgraph.layout.mxIGraphLayout#execute(java.lang.Object)
   */
  public void execute(Object parent)
  {
    Map<String, List<Object>> lookup = findParallels(parent);

    graph.getModel().beginUpdate();
    try
    {
      Iterator<List<Object>> it = lookup.values().iterator();

      while (it.hasNext())
      {
        List<Object> parallels = it.next();

        if (parallels.size() > 1)
        {
          layout(parallels);
        }
      }
    }
    finally
    {
      graph.getModel().endUpdate();
    }
  }

  /**
   *
   */
  protected Map<String, List<Object>> findParallels(Object parent)
  {
    Map<String, List<Object>> lookup = new Hashtable<String, List<Object>>();
    mxIGraphModel model = graph.getModel();
    int childCount = model.getChildCount(parent);

    for (int i = 0; i < childCount; i++)
    {
      Object child = model.getChildAt(parent, i);

      if (!isEdgeIgnored(child))
      {
        String id = getEdgeId(child);

        if (id != null)
        {
          if (!lookup.containsKey(id))
          {
            lookup.put(id, new ArrayList<Object>());
          }

          lookup.get(id).add(child);
        }
      }
    }

    return lookup;
  }

  /**
   *
   */
  protected String getEdgeId(Object edge)
  {
    mxGraphView view = graph.getView();
    mxCellState state = view.getState(edge);
    Object src = (state != null) ? state.getVisibleTerminal(true) : view
        .getVisibleTerminal(edge, true);
    Object trg = (state != null) ? state.getVisibleTerminal(false) : view
        .getVisibleTerminal(edge, false);

    if (src instanceof mxICell && trg instanceof mxICell)
    {
      String srcId = mxCellPath.create((mxICell) src);
      String trgId = mxCellPath.create((mxICell) trg);

      return (srcId.compareTo(trgId) > 0) ? trgId + "-" + srcId : srcId
          + "-" + trgId;
    }

    return null;
  }

  /**
   *
   */
  protected void layout(List<Object> parallels)
  {
    Object edge = parallels.get(0);
    mxIGraphModel model = graph.getModel();
    mxGeometry src = model.getGeometry(model.getTerminal(edge, true));
    mxGeometry trg = model.getGeometry(model.getTerminal(edge, false));

    // Routes multiple loops
    if (src == trg)
    {
      double x0 = src.getX() + src.getWidth() + this.spacing;
      double y0 = src.getY() + src.getHeight() / 2;

      for (int i = 0; i < parallels.size(); i++)
      {
        route(parallels.get(i), x0, y0);
        x0 += spacing;
      }
    }
    else if (src != null && trg != null)
    {
      // Routes parallel edges
      double scx = src.getX() + src.getWidth() / 2;
      double scy = src.getY() + src.getHeight() / 2;

      double tcx = trg.getX() + trg.getWidth() / 2;
      double tcy = trg.getY() + trg.getHeight() / 2;

      double dx = tcx - scx;
      double dy = tcy - scy;

      double len = Math.sqrt(dx * dx + dy * dy);

      double x0 = scx + dx / 2;
      double y0 = scy + dy / 2;

      double nx = dy * spacing / len;
      double ny = dx * spacing / len;

      x0 += nx * (parallels.size() - 1) / 2;
      y0 -= ny * (parallels.size() - 1) / 2;

      for (int i = 0; i < parallels.size(); i++)
      {
        route(parallels.get(i), x0, y0);
        x0 -= nx;
        y0 += ny;
      }
    }
  }

  /**
   *
   */
  protected void route(Object edge, double x, double y)
  {
    if (graph.isCellMovable(edge))
    {
      setEdgePoints(edge,
          Arrays.asList(new mxPoint[] { new mxPoint(x, y) }));
    }
  }

}
TOP

Related Classes of com.mxgraph.layout.mxParallelEdgeLayout

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.