2017-12-25 6 views
0

組織図ツリーが必要です。どのレベルでもノードを折りたたんで展開したいと考えています。私はJGraphXを初めて使っていますが、私が読んだところでは、折り畳みを実装する方法のように、頂点をグループ化するように聞こえます。問題は、親頂点の中にすべての子頂点を置くグループを作成するときです。折りたたみ可能なノードを持つ階層ツリーをJGraphXで作成する方法

package com.mxgraph.examples.swing; 

import java.util.ArrayList; 
import java.util.List; 

import javax.swing.JFrame; 
import javax.swing.SwingConstants; 

import com.mxgraph.layout.mxCompactTreeLayout; 
import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; 
import com.mxgraph.model.mxGeometry; 
import com.mxgraph.swing.mxGraphComponent; 
import com.mxgraph.util.mxConstants; 
import com.mxgraph.util.mxPoint; 
import com.mxgraph.util.mxRectangle; 
import com.mxgraph.view.mxGraph; 
import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; 
public class HelloWorld extends JFrame 
{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -2707712944901661771L; 

    public HelloWorld() 
    { 
     super("Hello, puppies!"); 

     mxGraph graph = new mxGraph(); 
     Object parent = graph.getDefaultParent(); 

     graph.getModel().beginUpdate(); 
     try 
     { 
      //Notice that the parent is the default parent... 
      //The hierarchical structure looks great but I cannot collapse/expand the tree. 
      Object vDogsRoot = graph.insertVertex(parent, null, "DOG", 0, 0, 80, 30); 
      Object v2 = graph.insertVertex(parent, null, "Shar Pei", 0, 0, 80, 30); 
      Object v3 = graph.insertVertex(parent, null, "Pug", 0, 0, 80, 30); 
      Object v4 = graph.insertVertex(parent, null, "Cocker Spaniel", 0, 0, 80, 30); 
      Object v5 = graph.insertVertex(parent, null, "Pit Bull", 0, 0, 80, 30); 
      Object v6 = graph.insertVertex(parent, null, "Chihuahua", 0, 0, 80, 30); 

      graph.insertEdge(parent, null, "", vDogsRoot, v2); 
      graph.insertEdge(parent, null, "", vDogsRoot, v3); 
      graph.insertEdge(parent, null, "", vDogsRoot, v4); 
      graph.insertEdge(parent, null, "", vDogsRoot, v5); 
      graph.insertEdge(parent, null, "", vDogsRoot, v6); 

      mxHierarchicalLayout layout = new mxHierarchicalLayout(graph); 
      layout.setUseBoundingBox(false); 

      layout.execute(parent); 
     } 
     finally 
     { 
      graph.getModel().endUpdate(); 
     } 

     mxGraphComponent graphComponent = new mxGraphComponent(graph); 
     getContentPane().add(graphComponent); 
    } 

    public static void main(String[] args) 
    { 
     HelloWorld frame = new HelloWorld(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(400, 320); 
     frame.setVisible(true); 
    } 

} 

が生成されます:

First code produces this image

素晴らしいスタートが、無崩壊ボタンここ

は偉大なレイアウトを与えるが、折りたたみをサポートしていないいくつかのサンプルコードです。次のコードは、私が抱えている問題を示しています。フォールディングをサポートするため、頂点の親をデフォルトの親からツリーのルートであるvDogVertexに変更してグループを作成しようとします。これは折りたたみ可能になりますが、すべての子頂点はvDogVertexの内側にあり、これはツリーのレイアウトを破壊します。

package com.mxgraph.examples.swing; 

import java.util.ArrayList; 
import java.util.List; 

import javax.swing.JFrame; 
import javax.swing.SwingConstants; 

import com.mxgraph.layout.mxCompactTreeLayout; 
import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; 
import com.mxgraph.model.mxGeometry; 
import com.mxgraph.swing.mxGraphComponent; 
import com.mxgraph.util.mxConstants; 
import com.mxgraph.util.mxPoint; 
import com.mxgraph.util.mxRectangle; 
import com.mxgraph.view.mxGraph; 
import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; 
public class HelloWorld extends JFrame 
{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -2707712944901661771L; 

    public HelloWorld() 
    { 
     super("Hello, puppies!"); 

     mxGraph graph = new mxGraph(); 
     Object parent = graph.getDefaultParent(); 

     graph.getModel().beginUpdate(); 
     try 
     { 
      //Notice this time the parent is the vDogsRoot vertex. 
      //This creates a cell group if I understand correctly. 
      Object vDogsRoot = graph.insertVertex(parent, null, "DOG", 0, 0, 80, 30, ""); 
      Object v2 = graph.insertVertex(vDogsRoot, null, "Shar Pei", 0, 0, 80, 30, ""); 
      Object v3 = graph.insertVertex(vDogsRoot, null, "Pug", 0, 0, 80, 30, ""); 
      Object v4 = graph.insertVertex(vDogsRoot, null, "Cocker Spaniel", 0, 0, 80, 30, ""); 
      Object v5 = graph.insertVertex(vDogsRoot, null, "Pit Bull", 0, 0, 80, 30, ""); 
      Object v6 = graph.insertVertex(vDogsRoot, null, "Chihuahua", 0, 0, 80, 30, ""); 

      graph.insertEdge(parent, null, "", vDogsRoot, v2); 
      graph.insertEdge(parent, null, "", vDogsRoot, v3); 
      graph.insertEdge(parent, null, "", vDogsRoot, v4); 
      graph.insertEdge(parent, null, "", vDogsRoot, v5); 
      graph.insertEdge(parent, null, "", vDogsRoot, v6); 

      mxHierarchicalLayout layout = new mxHierarchicalLayout(graph); 
      layout.setUseBoundingBox(false); 

      layout.execute(vDogsRoot); //apply the layout to the root group node. 
      layout.execute(parent); 
     } 
     finally 
     { 
      graph.getModel().endUpdate(); 
     } 

     mxGraphComponent graphComponent = new mxGraphComponent(graph); 
     getContentPane().add(graphComponent); 
    } 

    public static void main(String[] args) 
    { 
     HelloWorld frame = new HelloWorld(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(400, 320); 
     frame.setVisible(true); 
    } 

} 

が生成されます 私はセルグループの親細胞の内部であることから頂点を防ぐに​​はどうすればよい(崩壊ボタンを気づか)

enter image description here

を?私は、ツリー階層を維持して折りたたむ必要があります。セルグループを使用して正しいパスにいますか?私が間違っていることは何ですか?

私はセルグループ(vDogsRoot)の親に、境界線の外にセルを描画できるようにする必要があると思いますが、まだこれを行う方法はありません。あるいは、私はまったく間違ったアプローチを取っています。これを考えるのは簡単なことではありませんが、私はまだ多くのことを試してきました。

更新1:

グループは私がここで必要としているものではありません。私は、指示木をたどり、選択されたノードの下にあるノードを表示するように切り替えるだけです。 mxGraph examplesフォルダにtree.htmlという名前のJavaスクリプトのサンプルが見つかりました。その例をJavaScriptからJavaに変換するだけです。

答えて

0

私はこれについてどのように感じるのかわからないが、ここで解決策がある。私は部分的にtree.html exampleをJavaScriptからJavaに変換しました。私はすべてのコードをJavaに変換しませんでした。私は崩壊ボタンの位置に気にしないので試したこともありませんでした。私が望む機能を手に入れました。私はスーパーメソッドが保持することが重要な場合に実行していたいくつかのコードを追加しました。

例を変換してそれを私に提供したいのであれば、自分自身に答えを与えるのではなく、答えを喜んで授与するでしょう。答えを得るための他の方法 - コード内のバグを指摘し、それを多少改善したり、コードでより良いアプローチを提供したりしてください。ここで

は私のJavaコードです:崩壊したとき

package com.mxgraph.examples.swing; 

import java.util.ArrayList; 
import java.util.List; 

import javax.swing.JFrame; 

import com.mxgraph.layout.mxCompactTreeLayout; 
import com.mxgraph.swing.mxGraphComponent; 
import com.mxgraph.util.mxEvent; 
import com.mxgraph.util.mxEventObject; 
import com.mxgraph.util.mxEventSource.mxIEventListener; 
import com.mxgraph.view.mxGraph; 

/** 
* A foldable directed acyclic graph (DAG) where each child has only one parent. AKA a Tree. 
* 
* @author some programmer 
* 
*/ 
class FoldableTree extends mxGraph 
{ 
    /** 
    * Need to add some conditions that will get us the expand/collapse icon on the vertex. 
    */ 
    @Override 
    public boolean isCellFoldable(Object cell, boolean collapse) 
    { 
     //I want to keep the original behavior for groups in case I use a group someday. 
     boolean result = super.isCellFoldable(cell, collapse); 
     if(!result) 
     { 
      //I also want cells with outgoing edges to be foldable... 
      return this.getOutgoingEdges(cell).length > 0; 
     } 
     return result; 
    } 

    /** 
    * Need to define how to fold cells for our DAG. In this case we want to traverse the tree collecting 
    * all child vertices and then hide/show them and their edges as needed. 
    */ 
    @Override 
    public Object[] foldCells(boolean collapse, boolean recurse, Object[] cells, boolean checkFoldable) 
    { 
     //super.foldCells does this so I will too... 
     if(cells == null) 
     { 
      cells = getFoldableCells(getSelectionCells(), collapse); 
     } 

     this.getModel().beginUpdate(); 

     try 
     {   
      toggleSubtree(this, cells[0], !collapse); 
      this.model.setCollapsed(cells[0], collapse); 
      fireEvent(new mxEventObject(mxEvent.FOLD_CELLS, "cells", cells, "collapse", collapse, "recurse", recurse)); 
     } 
     finally 
     { 
      this.getModel().endUpdate(); 
     } 

     return cells; 
    } 

    // Updates the visible state of a given subtree taking into 
    // account the collapsed state of the traversed branches 
    private void toggleSubtree(mxGraph graph, Object cellSelected, boolean show) 
    { 
     List<Object> cellsAffected = new ArrayList<>(); 
     graph.traverse(cellSelected, true, new mxICellVisitor() {     
        @Override 
        public boolean visit(Object vertex, Object edge) { 
         // We do not want to hide/show the vertex that was clicked by the user to do not 
         // add it to the list of cells affected. 
         if(vertex != cellSelected) 
         { 
          cellsAffected.add(vertex); 
         } 

         // Do not stop recursing when vertex is the cell the user clicked. Need to keep 
         // going because this may be an expand. 
         // Do stop recursing when the vertex is already collapsed. 
         return vertex == cellSelected || !graph.isCellCollapsed(vertex); 
        } 
       }); 

     graph.toggleCells(show, cellsAffected.toArray(), true/*includeEdges*/);  
    } 
} 

public class ChampsTree extends JFrame 
{ 
    private static final long serialVersionUID = -2707712944901661771L; 

    public ChampsTree() 
    { 
     super("Hello, World!"); 

     FoldableTree graph = new FoldableTree(); 

     mxCompactTreeLayout layout = new mxCompactTreeLayout(graph, false);   
     layout.setUseBoundingBox(false); 
     layout.setEdgeRouting(false); 
     layout.setLevelDistance(30); 
     layout.setNodeDistance(10); 

     Object parent = graph.getDefaultParent(); 

     graph.getModel().beginUpdate(); 
     try 
     {   
      Object root = graph.insertVertex(parent, "treeRoot", "Root", 0, 0, 60, 40); 

      Object v1 = graph.insertVertex(parent, "v1", "Child 1", 0, 0, 60, 40); 
      graph.insertEdge(parent, null, "", root, v1); 

      Object v2 = graph.insertVertex(parent, "v2", "Child 2", 0, 0, 60, 40); 
      graph.insertEdge(parent, null, "", root, v2); 

      Object v3 = graph.insertVertex(parent, "v3", "Child 3", 0, 0, 60, 40); 
      graph.insertEdge(parent, null, "", root, v3); 

      Object v11 = graph.insertVertex(parent, "v11", "Child 1.1", 0, 0, 60, 40); 
      graph.insertEdge(parent, null, "", v1, v11); 

      Object v12 = graph.insertVertex(parent, "v12", "Child 1.2", 0, 0, 60, 40); 
      graph.insertEdge(parent, null, "", v1, v12); 

      Object v21 = graph.insertVertex(parent, "v21", "Child 2.1", 0, 0, 60, 40); 
      graph.insertEdge(parent, null, "", v2, v21); 

      Object v22 = graph.insertVertex(parent, "v22", "Child 2.2", 0, 0, 60, 40); 
      graph.insertEdge(parent, null, "", v2, v22); 

      Object v221 = graph.insertVertex(parent, "v221", "Child 2.2.1", 0, 0, 60, 40); 
      graph.insertEdge(parent, null, "", v22, v221); 

      Object v222 = graph.insertVertex(parent, "v222", "Child 2.2.2", 0, 0, 60, 40); 
      graph.insertEdge(parent, null, "", v22, v222); 

      Object v31 = graph.insertVertex(parent, "v31", "Child 3.1", 0, 0, 60, 40); 
      graph.insertEdge(parent, null, "", v3, v31);    

      layout.execute(parent);   
     } 
     finally 
     { 
      graph.getModel().endUpdate(); 
     } 

     graph.addListener(mxEvent.FOLD_CELLS, new mxIEventListener() { 

      @Override 
      public void invoke(Object sender, mxEventObject evt) { 
       layout.execute(graph.getDefaultParent()); 
      } 
     }); 

     mxGraphComponent graphComponent = new mxGraphComponent(graph); 

     getContentPane().add(graphComponent); 
    } 

    public static void main(String[] args) 
    { 
     ChampsTree frame = new ChampsTree(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(400, 320); 
     frame.setVisible(true); 
    } 
} 

Fully Expanded

お知らせツリーには、(残りのノードが互いに接近)よりコンパクトになります。これは、折り畳みが発生した後にレイアウトを呼び出すハンドラが原因です。これにより、ツリーの視覚的な複雑さが軽減されます。これは、実際のツリーがかなり大きくなるためです。

enter image description here

enter image description here

Full Collapsed

関連する問題