Package org.gvt.layout

Source Code of org.gvt.layout.LNode

package org.gvt.layout;

import java.util.*;

import org.eclipse.draw2d.geometry.*;
import org.eclipse.jface.util.Assert;
import org.gvt.model.CompoundModel;
import org.gvt.model.NodeModel;
import org.gvt.util.ChsTransform;
import org.gvt.util.ChsRectangle;

/**
* This class represents a node (l-level) for layout purposes.
*
* @author Erhan Giral
* @author Ugur Dogrusoz
* @author Cihan Kucukkececi
*
* Copyright: i-Vis Research Group, Bilkent University, 2007 - present
*/
public class LNode
{
// -----------------------------------------------------------------------------
// Section: Instance variables
// -----------------------------------------------------------------------------
  /**
   * Owner graph manager of this node
   */
  protected LGraphManager graphManager;

  /**
   * Possibly null child graph of this node
   */
  protected LGraph child;

  /**
   * Owner graph of this node; cannot be null
   */
  private LGraph owner;

  /**
   * List of edges incident with this node
   */
  protected List edges;

  /**
   * Geometry of this node
   */
  public ChsRectangle rect;

  protected int estimatedInitialSize = Integer.MIN_VALUE;

  private int inclusionTreeDepth = Integer.MAX_VALUE;

  /**
   * Used by hashing operations in createTopology method of LGraphManager
   */
  protected int LPID;

// -----------------------------------------------------------------------------
// Section: Constructors and Initialization
// -----------------------------------------------------------------------------
  /**
   * Empty constructor
   */
  public LNode()
  {
    this.initialize();
    this.graphManager = null;
    rect = new ChsRectangle();
  }

  /**
   * Constructor
   */
  public LNode(LGraphManager gm)
  {
    this.initialize();
    this.graphManager = gm;
    rect = new ChsRectangle();
  }

  /**
   * Alternative constructor
   */
  public LNode(LGraphManager gm, Point loc, Dimension size)
  {
    this.initialize();

    this.graphManager = gm;
    rect = new ChsRectangle(loc.x, loc.y, size.height, size.width);
  }

  public void initialize()
  {
    this.edges = new LinkedList();
  }

  public List getEdges()
  {
    return this.edges;
  }

  public void setEdges(List edges)
  {
    this.edges = edges;
  }

// -----------------------------------------------------------------------------
// Section: Accessors
// -----------------------------------------------------------------------------
  public LGraph getChild()
  {
    return child;
  }

  public void setChild(LGraph child)
  {
    this.child = child;
  }

  public LGraph getOwner()
  {
    return owner;
  }

  public void setOwner(LGraph owner)
  {
    this.owner = owner;
  }

  public double getWidth()
  {
    return this.rect.width;
  }

  public void setWidth(double width)
  {
    this.rect.width = width;
  }

  public double getHeight()
  {
    return this.rect.height;
  }

  public void setHeight(double height)
  {
    this.rect.height = height;
  }

  public double getLeft()
  {
    return this.rect.x;
  }

  public double getRight()
  {
    return this.rect.x + this.rect.width;
  }

  public double getTop()
  {
    return this.rect.y;
  }

  public double getBottom()
  {
    return this.rect.y + this.rect.height;
  }

  public double getCenterX()
  {
    return this.rect.x + this.rect.width / 2;
  }

  public double getCenterY()
  {
    return this.rect.y + this.rect.height / 2;
  }

  public PrecisionPoint getLocation()
  {
    return new PrecisionPoint(this.rect.x, this.rect.y);
  }

  public ChsRectangle getRect()
  {
    return this.rect;
  }

  public double getDiagonal()
  {
    return(Math.sqrt(this.rect.width * this.rect.width + this.rect.height * this.rect.height));
  }

  public void setRect(Point upperLeft, Dimension dimension)
  {
    this.rect.x = upperLeft.x;
    this.rect.y = upperLeft.y;
    this.rect.width = dimension.width;
    this.rect.height = dimension.height;
  }

  public void setCenter(double cx, double cy)
  {
    this.rect.x = cx - this.rect.width / 2;
    this.rect.y = cy - this.rect.height / 2;
  }

  public void setLocation(double x, double y)
  {
    this.rect.x = x;
    this.rect.y = y;
  }

  public void moveBy(double dx, double dy)
  {
//    if (! (this instanceof CiSEOnCircleNode))
//    System.out.printf("mb\t%s:(%5.1f,%5.1f)\n", new Object [] {this.getText(), dx, dy});

    this.rect.x += dx;
    this.rect.y += dy;
  }

  /*
   * This method returns the name of the corresponding v-level node of this
   * node, if any.
   */
  public String getText()
  {
    NodeModel vNode =
      (NodeModel)this.graphManager.getLayout().viewMapLtoV.get(this);

    if (vNode != null)
    {
      return vNode.getText();
    }
    else
    {
      return null;
    }
  }

// -----------------------------------------------------------------------------
// Section: Remaining Methods
// -----------------------------------------------------------------------------
  public List getEdgeListToNode(LNode to)
  {
    List<LEdge> edgeList = new ArrayList();

    if (edges != null)
    {
      for (int i = 0; i < edges.size(); i++)
      {
        LEdge edge = (LEdge) edges.get(i);

        if (edge.source == this && edge.target == to)
        {
          edgeList.add(edge);
        }
      }
    }

    return edgeList;
  }

  /**
   *  This method returns all edges between this node and the given node.
   */
  public List getEdgesBetween(LNode other)
  {
    List<LEdge> edgeList = new ArrayList();

    if (edges != null)
    {
      for (int i = 0; i < edges.size(); i++)
      {
        LEdge edge = (LEdge) edges.get(i);

        if ((edge.source == this && edge.target == other) ||
            (edge.target == this && edge.source == other))
        {
          edgeList.add(edge);
        }
      }
    }

    return edgeList;
  }

  public boolean isNeighbor(LNode node)
  {
    if (edges != null)
    {
      for (int i = 0; i < edges.size(); i++)
      {
        LEdge edge = (LEdge) edges.get(i);

        if (edge.source == node || edge.target == node)
        {
          return true;
        }
      }
    }

    return false;
  }

  public Set getNeighborsList()
  {
    Set<LNode> neighbors = new HashSet();

    for (int i = 0; i < edges.size(); i++)
    {
      LEdge edge = (LEdge) edges.get(i);

      if (edge.source.equals(this))
      {
        neighbors.add(edge.target);
      }
      else
      {
        neighbors.add(edge.source);
      }
    }

    return neighbors;
  }

  public Set getSuccessors()
  {
    Set<LNode> neighbors = new HashSet();

    for (int i = 0; i < edges.size(); i++)
    {
      LEdge edge = (LEdge) edges.get(i);

      if (edge.source.equals(this))
      {
        neighbors.add(edge.target);
      }
    }

    return neighbors;
  }

  /**
   * This method returns the estimated size of this node, taking into account
   * node margins and whether this node is a compound one containing others.
   */
  public int getEstimatedSize()
  {
    if (this.estimatedInitialSize != Integer.MIN_VALUE)
    {
      return this.estimatedInitialSize;
    }
    if (this.child == null)
    {
      this.estimatedInitialSize = (int)this.rect.width;
      return this.estimatedInitialSize;
    }
    else
    {
      this.estimatedInitialSize = this.child.getEstimatedSize();
      this.rect.width = this.estimatedInitialSize;
      this.rect.height = this.estimatedInitialSize;

      return this.estimatedInitialSize;
    }
  }

  /**
   * This method positions this node randomly in both x and y dimensions.
   */
  protected void scatter()
  {
    // We assume the center to be at (GRAVITY_CENTER_X,GRAVITY_CENTER_Y).

    double randomCenterX;
    double randomCenterY;

    double minX = -AbstractLayout.WORLD_BOUNDARY / 10000;
    double maxX = AbstractLayout.WORLD_BOUNDARY / 10000;
    randomCenterX = AbstractLayout.GRAVITY_CENTER_X +
      (LNode.random.nextDouble() * (maxX - minX)) + minX;

    double minY = -AbstractLayout.WORLD_BOUNDARY / 10000;
    double maxY = AbstractLayout.WORLD_BOUNDARY / 10000;
    randomCenterY = AbstractLayout.GRAVITY_CENTER_Y +
      (LNode.random.nextDouble() * (maxY - minY)) + minY;

    this.rect.x = randomCenterX;
    this.rect.y = randomCenterY;
  }

  /**
   * This method updates the bounds of this compound node.
   */
  public void updateBounds()
  {
    assert this.getChild() != null;

    if (this.getChild().getNodes().size() != 0)
    {
      // wrap the children nodes by re-arranging the boundaries
      LGraph childGraph = this.getChild();
      childGraph.updateBounds();

      this.rect.x =  childGraph.getLeft();
      this.rect.y =  childGraph.getTop();

      this.setWidth(childGraph.getRight() - childGraph.getLeft() +
        2 * compoundNodeMargin);
      this.setHeight(childGraph.getBottom() - childGraph.getTop() +
        2 * compoundNodeMargin + CompoundModel.LABEL_HEIGHT);
    }
  }

  /**
   * This method returns the maximum depth of this node in the inclusion tree.
   */
  public int getInclusionTreeDepth()
  {
    if (this.inclusionTreeDepth == Integer.MAX_VALUE)
    {
      int depth = 0;
      LGraph root = this.owner.getGraphManager().getRoot();
      LGraph parent = this.owner;

      while (true)
      {
        if (parent != root)
        {
          depth++;
        }
        else
        {
          break;
        }

        parent = parent.getParent().getOwner();
      }

      depth++;
      this.inclusionTreeDepth = depth;
    }

    return this.inclusionTreeDepth;
  }

  /**
   * This method returns all parents of this node.
   */
  public Vector getAllParents()
  {
    Vector parents = new Vector();
    LNode rootNode = this.owner.getGraphManager().getRoot().getParent();
    LNode parent = this.owner.getParent();

    while (true)
    {
      if (parent != rootNode)
      {
        parents.add(parent);
      }
      else
      {
        break;
      }

      parent = parent.getOwner().getParent();
    }

    parents.add(rootNode);

    return parents;
  }

  public int getRootGraphIndex()
  {
    return owner.getNodes().indexOf(this);
  }

  /**
   * This method transforms the layout coordinates of this node using input
   * transform.
   */
  public void transform(ChsTransform trans)
  {
    double left = this.rect.x;

    if (left > AbstractLayout.WORLD_BOUNDARY)
    {
      left = AbstractLayout.WORLD_BOUNDARY;
    }
    else if (left < -AbstractLayout.WORLD_BOUNDARY)
    {
      left = -AbstractLayout.WORLD_BOUNDARY;
    }

    double top = this.rect.y;

    if (top > AbstractLayout.WORLD_BOUNDARY)
    {
      top = AbstractLayout.WORLD_BOUNDARY;
    }
    else if (top < -AbstractLayout.WORLD_BOUNDARY)
    {
      top = -AbstractLayout.WORLD_BOUNDARY;
    }

    PrecisionPoint leftTop = new PrecisionPoint(left, top);
    PrecisionPoint vLeftTop = trans.inverseTransformPoint(leftTop);

    this.setLocation(vLeftTop.preciseX, vLeftTop.preciseY);
  }

// -----------------------------------------------------------------------------
// Section: Class Variables
// -----------------------------------------------------------------------------
  /**
   * Compound nodes normally have no margins in Chisio but we'll maintain some
   * safety buffer for node-node overlaps. Labels are accounted for
   * separately. Notice that graph margins are also handled separately!
   */
  public static int compoundNodeMargin  = 5;

  /**
   * Nodes are assumed to have this margin when calculating sizes.
   */
  public static final int NODE_MARGIN = 4;

  /**
   * Used for random initial positioning
   */
  private static Random random = new Random();
}
TOP

Related Classes of org.gvt.layout.LNode

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.