1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.9. 
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-2011 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.layout.partial;
15  
16  import y.layout.Layouter;
17  import y.layout.hierarchic.IncrementalHierarchicLayouter;
18  import y.layout.organic.SmartOrganicLayouter;
19  import y.layout.partial.PartialLayouter;
20  import y.option.IntOptionItem;
21  import y.option.OptionHandler;
22  
23  import java.awt.EventQueue;
24  import java.util.Locale;
25  
26  
27  /**
28   * This demo shows how to apply the partial layouter to hierarchic layouts. The partial layouter changes the coordinates
29   * for a given set of graph elements (called partial elements). The location or size of the remaining elements (called
30   * fixed elements) is not allowed to be changed. The layout algorithm tries to place the partial elements such that the
31   * resulting drawing (including the fixed elements) has a good quality with respect to common graph drawing aesthetics.
32   * <p/>
33   * Partial node elements can be assigned to so called subgraph components. During the layout process each subgraph
34   * induced by the nodes of a component is first laid out using the specified subgraph layouter. Then, the different
35   * components are placed one-by-one onto the drawing area such that the number of overlaps among graph elements is
36   * small. The user can specify different objectives (placement strategies) for finding 'good' positions for subgraph
37   * components.
38   * <p/>
39   * The demo allows to specify fixed and partial elements. Fixed elements are drawn grey and partial elements orange. To
40   * change the fixed/partial state of elements, select the corresponding elements and click on the "Lock Selected
41   * Elements" or "Unlock Selected Elements" button. The current state of selected elements can be toggled with a
42   * mouse-double-click. To start the partial layouter click on the "Apply Partial Layout" button.
43   *
44   * @see <a href="http://docs.yworks.com/yfiles/doc/developers-guide/partial_layout.html">Section Partial Layout</a> in the yFiles for Java Developer's Guide
45   */
46  public class HierarchicPartialLayoutDemo extends PartialLayoutBase {
47  
48    public HierarchicPartialLayoutDemo() {
49      this(null);
50    }
51  
52    public HierarchicPartialLayoutDemo(final String helpFilePath) {
53      super(helpFilePath);
54    }
55  
56    /**
57     * Loads a graph, which contains fix nodes and nodes, which should be integrated into this graph.
58     */
59    protected void loadInitialGraph() {
60      loadGraph("resource/graphHierarchic.graphml");
61    }
62  
63    protected OptionHandler createOptionHandler() {
64      final OptionHandler layoutOptionHandler = new OptionHandler("Option Table");
65  
66      layoutOptionHandler.addEnum("Subgraph Layout",
67          new Object[]{"Incremental Hierarchic Layout", "Organic Layout", "Unchanged"}, 0);
68      layoutOptionHandler.addEnum("Component Assignment",
69          new Object[]{"Single Nodes", "Connected Graphs"}, 0);
70      layoutOptionHandler.addEnum("Edge Routing Style",
71          new Object[]{"Automatic", "Straight Line", "Orthogonal", "Organic"}, 0);
72      layoutOptionHandler.addBool("Hierarchy Reorganization", false);
73      layoutOptionHandler.addBool("Allow Mirroring", false);
74      layoutOptionHandler.addInt("Minimum Node Distance", 5);
75      layoutOptionHandler.getItem("Minimum Node Distance").setAttribute(
76          IntOptionItem.ATTRIBUTE_MIN_VALUE, new Integer(0));
77      layoutOptionHandler.addEnum("Layout Orientation",
78          new Object[]{"None", "Auto", "Top to Bottom", "Bottom to Top", "Left to Right", "Right to Left"}, 2);
79      return layoutOptionHandler;
80    }
81  
82    protected Layouter createConfiguredPartialLayouter() {
83      final PartialLayouter partialLayouter = new PartialLayouter();
84  
85      if (optionHandler != null) {
86        switch (optionHandler.getEnum("Subgraph Layout")) {
87          default:
88          case 0:
89            final IncrementalHierarchicLayouter ihl = new IncrementalHierarchicLayouter();
90            ihl.setMinimumLayerDistance((double) optionHandler.getInt("Minimum Node Distance"));
91            partialLayouter.setCoreLayouter(ihl);
92            break;
93          case 1:
94            partialLayouter.setCoreLayouter(new SmartOrganicLayouter());
95            break;
96          case 2:
97            // is null per default
98        }
99        switch (optionHandler.getEnum("Component Assignment")) {
100         default:
101         case 0:
102           partialLayouter.setComponentAssignmentStrategy(PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_SINGLE);
103           break;
104         case 1:
105           partialLayouter.setComponentAssignmentStrategy(PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_CONNECTED);
106           break;
107       }
108       switch (optionHandler.getEnum("Edge Routing Style")) {
109         default:
110         case 0:
111           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_AUTOMATIC);
112           break;
113         case 1:
114           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_STRAIGHTLINE);
115           break;
116         case 2:
117           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_ORTHOGONAL);
118           break;
119         case 3:
120           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_ORGANIC);
121           break;
122       }
123       partialLayouter.setOrientationOptimizationEnabled(optionHandler.getBool("Hierarchy Reorganization"));
124       partialLayouter.setMirroringAllowed(optionHandler.getBool("Allow Mirroring"));
125       partialLayouter.setMinimalNodeDistance(optionHandler.getInt("Minimum Node Distance"));
126       switch (optionHandler.getEnum("Layout Orientation")) {
127         default:
128         case 0:
129           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_NONE);
130           break;
131         case 1:
132           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_AUTO_DETECTION);
133           break;
134         case 2:
135           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_TOP_TO_BOTTOM);
136           break;
137         case 3:
138           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_BOTTOM_TO_TOP);
139           break;
140         case 4:
141           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_LEFT_TO_RIGHT);
142           break;
143         case 5:
144           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_RIGHT_TO_LEFT);
145           break;
146       }
147     }
148     partialLayouter.setPositioningStrategy(PartialLayouter.SUBGRAPH_POSITIONING_STRATEGY_BARYCENTER);
149     partialLayouter.setConsiderNodeAlignment(true);
150     return partialLayouter;
151   }
152 
153   /**
154    * Launches this demo.
155    */
156   public static void main(String[] args) {
157     EventQueue.invokeLater(new Runnable() {
158       public void run() {
159         Locale.setDefault(Locale.ENGLISH);
160         initLnF();
161         (new HierarchicPartialLayoutDemo("resource/hierarchiclayouthelp.html"))
162             .start("Hierarchic Partial Layouter Demo");
163       }
164     });
165   }
166 
167 }