2017-12-25 4 views
0

Ich brauche eine Organigramm-Struktur und ich möchte in der Lage sein, die Knoten auf jeder Ebene zu reduzieren und zu erweitern. Ich bin neu in JGraphX, aber nach dem, was ich gelesen habe, klingt es nach der Art, wie man Faltung implementiert, indem man die Scheitelpunkte gruppiert. Das Problem ist, wenn ich die Gruppe erstelle, setzt sie alle Kindknoten in den Elternknoten.So erstellen Sie eine hierarchische Struktur mit reduzierbaren Knoten in JGraphX ​​

Hier ist ein Beispiel-Code, der eine große Layout gibt aber unterstützen Faltung nicht:

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); 
    } 

} 

Produziert:

First code produces this image

Guter Start, aber kein Zusammenbruch Taste. Der folgende Code zeigt das Problem, das ich habe. Um die Faltung zu unterstützen, versuche ich, eine Gruppe zu erstellen, indem ich das Elternelement der Scheitelpunkte vom Standard-Elternelement in das vDogVertex-Objekt, das die Wurzel des Baums ist, ändere. Dies wird zusammenklappbar, jedoch befinden sich alle untergeordneten Vertices innerhalb von vDogVertex und dies ruiniert das Baumlayout.

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); 
    } 

} 

Produziert: (man beachte den Zusammenbruch Taste)

enter image description here

Wie verhindere ich die Eckpunkte aus dem Inneren der Mutterzelle der Zellgruppe zu sein? Ich möchte, dass die Baumhierarchie beibehalten wird, aber zusammenklappbar ist. Gehe ich mit Zellgruppen auf den richtigen Pfad? Was mache ich falsch?

Ich vermute, ich muss nur die Eltern der Zellgruppe (vDogsRoot) sagen, um Zellen zu erlauben, außerhalb seiner Grenze gezeichnet zu werden, aber ich sehe noch keinen Weg, dies zu tun. Oder vielleicht gehe ich völlig falsch vor. Dies zu denken, sollte eine triviale Sache sein, um zu erreichen, aber ich habe viele verschiedene Dinge ausprobiert und viele Dokumente gegoogelt/gelesen und noch keinen Erfolg.

UPDATE 1:

Gruppen sind nicht das, was ich hier zu benötigen. Ich muss nur den gerichteten Baum durchqueren und die Knoten unter dem ausgewählten Knoten anzeigen lassen. Ein Beispiel für ein Java-Skript namens tree.html im Ordner mxGraph examples gefunden. Sie müssen dieses Beispiel nur von JavaScript in Java konvertieren.

Antwort

0

Huch, nicht sicher, wie ich das empfinde, aber hier ist eine Lösung. Ich habe die tree.html example teilweise von JavaScript in Java konvertiert. Ich habe den gesamten Code nicht in Java konvertiert. Ich habe es nicht einmal versucht, weil es mir egal ist, wo sich der Button zum Einklappen befindet. Ich habe die Funktionalität bekommen, die ich wollte. Ich habe ein paar Codes hinzugefügt, die die Super-Methode ausführt, falls dieser Teil wichtig ist.

Wenn jemand das Beispiel konvertieren und mir das liefern will, gebe ich Ihnen gerne die Antwort, anstatt mir selbst die Antwort zu geben. Andere Wege, um die Antwort zu erhalten - weisen Sie auf einen Fehler in meinem Code hin, verbessern Sie ihn in irgendeiner Form oder bieten Sie einen besseren Ansatz mit Code.

Hier ist mein Java-Code:

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

Hinweis der Baum wird kompakter (die verbleibenden Knoten kommen näher zusammen) im zusammengeklappten Zustand. Dies liegt an dem Handler, der das Layout aufruft, nachdem die Faltung erfolgt ist.Dies reduziert die visuelle Komplexität des Baumes, was gut ist, weil mein echter Baum ziemlich groß sein wird.

enter image description here

enter image description here

Full Collapsed

Verwandte Themen