1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.5.0.1. 
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2000-2007 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.view.layout.tree;
15  
16  import demo.view.DemoBase;
17  import y.base.Edge;
18  import y.base.Node;
19  import y.layout.BufferedLayouter;
20  import y.layout.GraphLayout;
21  import y.layout.tree.DendrogramPlacer;
22  import y.layout.tree.GenericTreeLayouter;
23  import y.view.Arrow;
24  import y.view.CreateChildEdgeMode;
25  import y.view.EdgeRealizer;
26  import y.view.EditMode;
27  import y.view.Graph2D;
28  import y.view.HotSpotMode;
29  import y.view.LayoutMorpher;
30  import y.view.LineType;
31  import y.view.NodeRealizer;
32  import y.view.PolyLineEdgeRealizer;
33  import y.view.PortAssignmentMoveSelectionMode;
34  
35  import java.awt.Color;
36  import java.awt.Cursor;
37  
38  /**
39   * This demo shows how GenericTreeLayouter can be used to layout Dendrogram styles.
40   * @see y.layout.tree.DendrogramPlacer
41   */
42  public class DendrogramLayouterDemo extends DemoBase
43  {
44    private GenericTreeLayouter treeLayouter;
45    private Color[] layerColors = new Color[]{Color.red, Color.orange, Color.yellow, Color.cyan, Color.green, Color.blue};
46  
47    public DendrogramLayouterDemo()
48    {
49      final Graph2D graph = view.getGraph2D();
50      EdgeRealizer defaultER = graph.getDefaultEdgeRealizer();
51      defaultER.setArrow(Arrow.STANDARD);
52      ((PolyLineEdgeRealizer)defaultER).setSmoothedBends(true);
53      defaultER.setLineType(LineType.LINE_2);
54  
55      treeLayouter = new GenericTreeLayouter();
56  
57      DendrogramPlacer dendrogramPlacer = new DendrogramPlacer();
58      treeLayouter.setDefaultNodePlacer(dendrogramPlacer);
59      treeLayouter.setDefaultChildComparator(dendrogramPlacer.createComparator());
60  
61      createSampleGraph(graph);
62    }
63  
64    private void createSampleGraph(Graph2D graph){
65      graph.clear();
66      Node root = graph.createNode();
67      graph.getRealizer(root).setFillColor(layerColors[0]);
68      createChildren(graph, root, 3, 1, 2);
69      calcLayout();
70    }
71  
72    private void createChildren(Graph2D graph, Node root, int children, int layer, int layers){
73      if (graph.nodeCount() % 3 == 2){
74        // do not create nodes for every subtree
75        return;
76      }
77      for (int i = 0; i < children; i++){
78        Node child = graph.createNode();
79        graph.createEdge(root, child);
80        graph.getRealizer(child).setFillColor(layerColors[layer % layerColors.length]);
81        if (layers > 0){
82          createChildren(graph, child, children, layer+1, layers-1);
83        }
84      }
85    }
86  
87    protected boolean isDeletionEnabled(){
88      return false;
89    }
90  
91    protected void registerViewModes() {
92      EditMode editMode = new TreeCreateEditMode();
93      view.addViewMode( editMode );
94    }
95  
96  
97    public void calcLayout(){
98      if (!view.getGraph2D().isEmpty()){
99        Cursor oldCursor = view.getCanvasComponent().getCursor();
100       try {
101         view.getCanvasComponent().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
102         GraphLayout result = new BufferedLayouter(treeLayouter).calcLayout(view.getGraph2D());
103         LayoutMorpher morpher = new LayoutMorpher(view, result);
104         morpher.setSmoothViewTransform(true);
105         morpher.setPreferredDuration(300);
106         morpher.execute();
107       } finally {
108         view.getCanvasComponent().setCursor(oldCursor);
109       }
110     }
111     view.fitContent();
112     view.updateView();
113   }
114 
115   final class TreeCreateChildEdgeMode extends CreateChildEdgeMode {
116     protected void edgeCreated(Edge e){
117       int depth = 1;
118       for (Node n = e.source(); n.inDegree() > 0; n = n.firstInEdge().source()){
119         depth++;
120       }
121       Graph2D g = getGraph2D();
122       g.getRealizer(e.target()).setFillColor(layerColors[depth % layerColors.length]);
123       g.unselectAll();
124       calcLayout();
125       g.setSelected(e.target(), true);
126     }
127 
128     protected NodeRealizer createChildNodeRealizer()
129     {
130       NodeRealizer retValue;
131       retValue = super.createChildNodeRealizer();
132       retValue.setLabelText("");
133       return retValue;
134     }
135 
136   }
137 
138   final class TreeHotSpotMode extends HotSpotMode {
139     public void mouseReleasedLeft(double x, double y)
140     {
141       super.mouseReleasedLeft(x, y);
142       calcLayout();
143     }
144   }
145 
146   final class TreeCreateEditMode extends EditMode {
147     TreeCreateEditMode(){
148       super();
149       setMoveSelectionMode(new TreeMoveSelectionMode());
150       setCreateEdgeMode(new TreeCreateChildEdgeMode());
151       setHotSpotMode(new TreeHotSpotMode());
152     }
153 
154     public boolean doAllowNodeCreation()
155     {
156       return getGraph2D().N() == 0;
157     }
158   }
159 
160   final class TreeMoveSelectionMode extends PortAssignmentMoveSelectionMode {
161     TreeMoveSelectionMode(){
162       super(null, null);
163     }
164 
165     protected void selectionMovedAction(double dx, double dy, double x, double y)
166     {
167       super.selectionMovedAction(dx, dy, x, y);
168       calcLayout();
169     }
170   }
171 
172   /**
173    * Launches this demo.
174    */
175   public static void main(String[] args)
176   {
177     initLnF();
178     DendrogramLayouterDemo demo = new DendrogramLayouterDemo();
179     demo.start("Dendrogram Demo");
180   }
181 }
182