Package net.wigis.graph.dnv.layout.implementations

Source Code of net.wigis.graph.dnv.layout.implementations.DisjointGraphLayout

/******************************************************************************************************
* Copyright (c) 2010, University of California, Santa Barbara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
*    * Redistributions of source code must retain the above copyright notice, this list of
*      conditions and the following disclaimer.
*    * Redistributions in binary form must reproduce the above copyright notice, this list of
*      conditions and the following disclaimer in the documentation and/or other materials
*      provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************************************/

package net.wigis.graph.dnv.layout.implementations;

import java.io.BufferedWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.wigis.graph.dnv.DNVGraph;
import net.wigis.graph.dnv.DNVNode;
import net.wigis.graph.dnv.clustering.ConnectedClustering;
import net.wigis.graph.dnv.layout.interfaces.SimpleLayoutInterface;
import net.wigis.graph.dnv.utilities.GraphFunctions;
import net.wigis.graph.dnv.utilities.NumberOfSubnodesSort;
import net.wigis.graph.dnv.utilities.Vector2D;
import net.wigis.settings.Settings;

// TODO: Auto-generated Javadoc
/**
* The Class DisjointGraphLayout.
*
* @author Brynjar Gretarsson
*/
public class DisjointGraphLayout implements SimpleLayoutInterface
{
  private BufferedWriter writer;
  @Override
  public void setOutputWriter(BufferedWriter writer) {
    // TODO Auto-generated method stub
    this.writer = writer;
  }
  /**
   * Layout.
   *
   * @param filename
   *            the filename
   */
  public static void runLayout( String filename )
  {
    System.out.println( "Starting layout for " + filename );

    DNVGraph graph = new DNVGraph( filename );

    runLayout( graph );

    graph.writeGraph( filename.substring( 0, filename.length() - 4 ) + "_laid_out.dnv" );

    System.out.println( "Done with layout for " + filename );
  }

  /**
   * Layout.
   *
   * @param graph
   *            the graph
   */
  public static void runLayout( DNVGraph graph )
  {
    DisjointGraphLayout layout = new DisjointGraphLayout();
    layout.runLayout( graph, 0 );
  }

  /**
   * Layout subnodes.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   */
  private static void layoutSubnodes( DNVGraph graph, int level )
  {
    List<DNVNode> supernodes = graph.getNodes( level );
    for( DNVNode supernode : supernodes )
    {
      layoutSubgraph( supernode.getNumberOfSubNodes(), supernode );
    }

  }

  /*
   * private static void layoutSubnodesLargerSpace( DNVGraph graph, int level,
   * float multiplyer ) { List<DNVNode> supernodes = graph.getNodes( level );
   * for( DNVNode supernode : supernodes ) { layoutSubgraph( graph, (float)(
   * graph.getGraphSize( 0 ) * multiplyer ), supernode ); }
   *
   * }
   */
  /**
   * Layout subgraph.
   *
   * @param width
   *            the width
   * @param supernode
   *            the supernode
   */
  private static void layoutSubgraph( float width, DNVNode supernode )
  {
    float minX;
    float maxX;
    float minY;
    float maxY;
    new FruchtermanReingold()
        .runLayout( width, width, supernode.getSubGraph().getNodesList(), supernode.getSubGraph().getEdges().values(), 0.1f, false );

    minX = Integer.MAX_VALUE;
    maxX = Integer.MIN_VALUE;
    minY = Integer.MAX_VALUE;
    maxY = Integer.MIN_VALUE;
    // Tell nodes that they should belong to the original graph and find
    // boundaries
    for( DNVNode subNode : supernode.getSubGraph().getNodesList() )
    {
      if( subNode.getPosition().getX() < minX )
      {
        minX = subNode.getPosition().getX();
      }
      if( subNode.getPosition().getX() > maxX )
      {
        maxX = subNode.getPosition().getX();
      }
      if( subNode.getPosition().getY() < minY )
      {
        minY = subNode.getPosition().getY();
      }
      if( subNode.getPosition().getY() > maxY )
      {
        maxY = subNode.getPosition().getY();
      }
    }

    width = maxX - minX;
    float height = maxY - minY;
    supernode.setDiameterOfSubnodes( Math.max( Math.max( width, height ), 5 ) );
    supernode.setPosition( supernode.getFirstChild().getPosition().getX(), supernode.getFirstChild().getPosition().getY() );
  }

  /** The number of subnodes sort. */
  private static NumberOfSubnodesSort numberOfSubnodesSort = new NumberOfSubnodesSort();

  /**
   * Layout based on number of subnodes.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   */
  public static void layoutBasedOnNumberOfSubnodes( DNVGraph graph, int level )
  {
    List<DNVNode> nodes = new ArrayList<DNVNode>( graph.getNodes( level ) );
    Collections.sort( nodes, numberOfSubnodesSort );
    Vector2D position;
    float radius = 0;
    int lastNumberOfSubnodes = -1;
    Vector2D movement = new Vector2D();
    Vector2D center = new Vector2D( 0, 0 );
    Map<Integer, Integer> histogram = generateHistogramOfSubnodes( graph, level );
    int i = 0;
    // float lastRadius = 0;
    // float allowedWidth = 0;
    int counter = 0;
    for( DNVNode node : nodes )
    {
      counter++;
      if( lastNumberOfSubnodes == node.getNumberOfSubNodes() )
      {
        i++;
      }
      else
      {
        // System.out.println( "number of subnodes " +
        // node.getNumberOfSubNodes() );
        // lastRadius = radius;
        radius += node.getDiameterOfSubnodes();
        lastNumberOfSubnodes = node.getNumberOfSubNodes();
        i = 0;
        // sqrt( (area of outer disk - area of inner disk ) / number of
        // nodes in outer disk )
        // allowedWidth = (float)Math.sqrt( ( Math.PI * radius * radius
        // - Math.PI * lastRadius * lastRadius ) / (float)histogram.get(
        // lastNumberOfSubnodes ) );
        // allowedWidth = radius - lastRadius;
        // System.out.println( "Allowed width for " +
        // lastNumberOfSubnodes + " is " + allowedWidth );
      }

      // System.out.println( "Counter : " + counter +
      // " - lastNumberOfSubnodes : " + lastNumberOfSubnodes +
      // " - numberOfClusters : " + histogram.get( lastNumberOfSubnodes )
      // );

      if( counter == 1 && histogram.get( lastNumberOfSubnodes ) == 1 )
      {
        // System.out.println( "Putting " + lastNumberOfSubnodes +
        // " node cluster in the center." );
        position = new Vector2D( 0, 0 );
      }
      else
      {
        position = getPosition( i, lastNumberOfSubnodes, histogram.get( lastNumberOfSubnodes ), radius, center );
      }
      movement.setX( position.getX() - node.getPosition().getX() );
      movement.setY( position.getY() - node.getPosition().getY() );
      node.move( movement, true, false );
    }
  }

  /**
   * Gets the position.
   *
   * @param i
   *            the i
   * @param startAt
   *            the start at
   * @param size
   *            the size
   * @param bigRadius
   *            the big radius
   * @param center
   *            the center
   * @return the position
   */
  private static Vector2D getPosition( double i, double startAt, int size, double bigRadius, Vector2D center )
  {
    // double radians = 0.2 * i;
    // double radius = size / 10.0;
    float z_pos = (float)( 1.0 * i );

    double bigRadians = 2.0 * Math.PI / size * i;

    float y_pos = 0;// (float)Math.sin( radians );// * bigRadius;
    // float x_pos = (float)Math.cos( radians );// * bigRadius;

    z_pos = (float)( Math.cos( bigRadians ) * bigRadius );
    y_pos += Math.sin( bigRadians ) * bigRadius;

    return new Vector2D( center.getX() + z_pos, center.getY() + y_pos );
  }

  /**
   * Generate histogram of subnodes.
   *
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @return the map
   */
  private static Map<Integer, Integer> generateHistogramOfSubnodes( DNVGraph graph, int level )
  {
    HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>();
    List<DNVNode> nodes = graph.getNodes( level );
    DNVNode tempNode;
    Integer numberOfSubnodes;
    Integer counter;
    for( int i = 0; i < nodes.size(); i++ )
    {
      tempNode = nodes.get( i );
      numberOfSubnodes = tempNode.getNumberOfSubNodes();
      counter = histogram.get( numberOfSubnodes );
      if( counter == null )
      {
        counter = 0;
      }
      counter++;
      histogram.put( numberOfSubnodes, counter );
    }

    return histogram;
  }

  /**
   * The main method.
   *
   * @param args
   *            the arguments
   */
  public static void main( String[] args )
  {
    runLayout( Settings.GRAPHS_PATH + "_bb_al qaeda.dnv" );
    // layout( Settings.GRAPHS_PATH + "authors_graph_50k.dnv" );
  }

  @Override
  public void runLayout( DNVGraph graph, int level )
  {
    // System.out.println( "Clustering..." );
    GraphFunctions.clearHigherLevels( level, graph );
    ConnectedClustering.cluster( graph, level );
    // System.out.println( "Laying out subnodes." );
    layoutSubnodes( graph, level+1 );
    // System.out.println( "Laying out based on subnodes." );
    layoutBasedOnNumberOfSubnodes( graph, level+1 );
  }

  public static final String LABEL = "Disjoint Graph Layout";
 
  @Override
  public String getLabel()
  {
    return LABEL;
  }

}
TOP

Related Classes of net.wigis.graph.dnv.layout.implementations.DisjointGraphLayout

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.