Search code examples
javascalajung

Vertices/Nodes in JUNG are displayed outside of the window


I guess my prolem is best described with the following picture.

enter image description here

How can I tell JUNG to place everything in the visible area?

This is my VertexShapeTransformer (Scala)

vv.getRenderContext().setVertexShapeTransformer(
new org.apache.commons.collections15.Transformer[String,java.awt.Shape]() {
  def transform(label: String): java.awt.Shape = {
    val longest_name = label.length
    val width = longest_name * 10.0 // 12.0 is approx size of letter
    val circle = new java.awt.geom.Ellipse2D.Double(-(width/2), -12.5, width, 25);
    circle
  }
})

When I remove it, the small default circles fit in the window but the vertex label is still not in the window.


Solution

  • I found a solution. For vv: VisualizationViewer[String, String], the following function updates the layouter algorithm (scala code). It calls the relaxer on the layouter (if it supports relaxing) and then rearranges the vertices. The layout.setLocation function is called for every vertex, to make sure that it is in the printable screen area.

      /**
       * change the graph layouter
       * with fancy animation
       */
      def changeJUNGLayout(layout: jung.algorithms.layout.AbstractLayout[String, String]): Unit = 
      {
    
          layout.setSize(vv.getSize())
    
          assert(vv.getModel().getRelaxer() eq null)
          if(layout.isInstanceOf[edu.uci.ics.jung.algorithms.util.IterativeContext]){
              val relaxer: jung.algorithms.layout.util.Relaxer
                = new jung.algorithms.layout.util.VisRunner(
                    layout.asInstanceOf[edu.uci.ics.jung.algorithms.util.IterativeContext])
              relaxer.stop()
              relaxer.prerelax()
          }
    
          {
              import collection.JavaConversions._
              val vs : Iterable[String] = layout.getGraph().getVertices()
              for (v <- vs){
                  //println(v+" "+layout.getX(v)+" "+layout.getY(v))
                  val minX = v.length()*5.0
                  val maxX = vv.getSize().getWidth() - minX
                  val X = layout.getX(v)
                  val newX = if (X < minX) minX else if (X > maxX) maxX else X
                  val minY = 12.5
                  val maxY = vv.getSize().getHeight() - minY
                  val Y = layout.getY(v)
                  val newY = if (Y < minY) minY else if (Y > maxY) maxY else Y
                  layout.setLocation(v, newX, newY)
              }
          }
    
          val staticLayout: jung.algorithms.layout.Layout[String, String] =
            new jung.algorithms.layout.StaticLayout[String, String](jung_graph, layout)
    
          val lt: jung.visualization.layout.LayoutTransition[String,String] =
            new jung.visualization.layout.LayoutTransition[String,String](vv, vv.getGraphLayout(),
                staticLayout)
          val animator = new jung.visualization.util.Animator(lt);
          animator.start();
    
    
          vv.repaint();
      }