2

私の問題は次の写真で最もよく説明されていると思います。

ここに画像の説明を入力してください

JUNGにすべてを表示領域に配置するように指示するにはどうすればよいですか?

これは私の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
  }
})

それを削除すると、小さなデフォルトの円がウィンドウに収まりますが、頂点ラベルはまだウィンドウにありません。

4

2 に答える 2

2

解決策を見つけました。の場合vv: VisualizationViewer[String, String]、次の関数はレイアウタ アルゴリズム (scala コード) を更新します。レイアウターでリラクサーを呼び出し (リラクシングがサポートされている場合)、頂点を再配置します。関数はすべてのlayout.setLocation頂点に対して呼び出され、印刷可能な画面領域にあることを確認します。

  /**
   * 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();
  }
于 2013-03-26T07:47:27.567 に答える
1

JUNG のレイアウト アルゴリズムでは、頂点が半径 1 より大きくなる可能性があること (この場合は大きな楕円) が考慮されていないため、ラベル (および頂点) が切り取られています。したがって、頂点の中央は実際にはビュー画面の内側に配置されますが、楕円のラベルとシェルはそうではありません。

これにより、次の 2 つのオプションが残ります。

  1. サイズを考慮して独自のレイアウトを記述します。

    このオプションは、思ったほど難しくありません。サイズを考慮して、強制指向アルゴリズムの 1 つを変更するだけです。

  2. グラフをレイアウトすると、少しズームアウトします。

    ScalingControl scaler = new CrossoverScalingControl();
    scaler.scale(viewer, 1 / 1.1f, viewer.getCenter());
    
于 2013-03-25T17:21:26.690 に答える