1   /****************************************************************************
2    * This demo file is part of yFiles for Java 2.14.
3    * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28,
4    * 72070 Tuebingen, Germany. All rights reserved.
5    * 
6    * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution
7    * of demo files in source code or binary form, with or without
8    * modification, is not permitted.
9    * 
10   * Owners of a valid software license for a yFiles for Java version that this
11   * demo is shipped with are allowed to use the demo source code as basis
12   * for their own yFiles for Java powered applications. Use of such programs is
13   * governed by the rights and conditions as set out in the yFiles for Java
14   * license agreement.
15   * 
16   * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED
17   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19   * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21   * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   *
27   ***************************************************************************/
28  package demo.layout.partial;
29  
30  import y.layout.Layouter;
31  import y.layout.hierarchic.IncrementalHierarchicLayouter;
32  import y.layout.organic.SmartOrganicLayouter;
33  import y.layout.partial.PartialLayouter;
34  import y.option.IntOptionItem;
35  import y.option.OptionHandler;
36  
37  import java.awt.EventQueue;
38  import java.util.Locale;
39  
40  
41  /**
42   * This demo shows how to apply the partial layouter to hierarchic layouts. The partial layouter changes the coordinates
43   * for a given set of graph elements (called partial elements). The location or size of the remaining elements (called
44   * fixed elements) is not allowed to be changed. The layout algorithm tries to place the partial elements such that the
45   * resulting drawing (including the fixed elements) has a good quality with respect to common graph drawing aesthetics.
46   * <p/>
47   * Partial node elements can be assigned to so called subgraph components. During the layout process each subgraph
48   * induced by the nodes of a component is first laid out using the specified subgraph layouter. Then, the different
49   * components are placed one-by-one onto the drawing area such that the number of overlaps among graph elements is
50   * small. The user can specify different objectives (placement strategies) for finding 'good' positions for subgraph
51   * components.
52   * <p/>
53   * The demo allows to specify fixed and partial elements. Fixed elements are drawn grey and partial elements orange. To
54   * change the fixed/partial state of elements, select the corresponding elements and click on the "Lock Selected
55   * Elements" or "Unlock Selected Elements" button. The current state of selected elements can be toggled with a
56   * mouse-double-click. To start the partial layouter click on the "Apply Partial Layout" button.
57   *
58   * @see <a href="http://docs.yworks.com/yfiles/doc/api/index.html#/dguide/partial_layout" target="_blank">Section Partial Layout</a> in the yFiles for Java Developer's Guide
59   */
60  public class HierarchicPartialLayoutDemo extends PartialLayoutBase {
61  
62    public HierarchicPartialLayoutDemo() {
63      this(null);
64    }
65  
66    public HierarchicPartialLayoutDemo(final String helpFilePath) {
67      super(helpFilePath);
68    }
69  
70    /**
71     * Loads a graph, which contains fix nodes and nodes, which should be integrated into this graph.
72     */
73    protected void loadInitialGraph() {
74      loadGraph("resource/graphHierarchic.graphml");
75    }
76  
77    protected OptionHandler createOptionHandler() {
78      final OptionHandler layoutOptionHandler = new OptionHandler("Option Table");
79  
80      layoutOptionHandler.addEnum("Subgraph Layout",
81          new Object[]{"Incremental Hierarchic Layout", "Organic Layout", "Unchanged"}, 0);
82      layoutOptionHandler.addEnum("Component Assignment",
83          new Object[]{"Single Nodes", "Connected Graphs"}, 0);
84      layoutOptionHandler.addEnum("Edge Routing Style",
85          new Object[]{"Automatic", "Straight Line", "Orthogonal", "Organic"}, 0);
86      layoutOptionHandler.addBool("Hierarchy Reorganization", false);
87      layoutOptionHandler.addBool("Allow Mirroring", false);
88      layoutOptionHandler.addInt("Minimum Node Distance", 5);
89      layoutOptionHandler.getItem("Minimum Node Distance").setAttribute(
90          IntOptionItem.ATTRIBUTE_MIN_VALUE, new Integer(0));
91      layoutOptionHandler.addEnum("Layout Orientation",
92          new Object[]{"None", "Auto", "Top to Bottom", "Bottom to Top", "Left to Right", "Right to Left"}, 2);
93      return layoutOptionHandler;
94    }
95  
96    protected Layouter createConfiguredPartialLayouter() {
97      final PartialLayouter partialLayouter = new PartialLayouter();
98  
99      if (optionHandler != null) {
100       switch (optionHandler.getEnum("Subgraph Layout")) {
101         default:
102         case 0:
103           final IncrementalHierarchicLayouter ihl = new IncrementalHierarchicLayouter();
104           ihl.setMinimumLayerDistance((double) optionHandler.getInt("Minimum Node Distance"));
105           partialLayouter.setCoreLayouter(ihl);
106           break;
107         case 1:
108           final SmartOrganicLayouter sol = new SmartOrganicLayouter();
109           sol.setMultiThreadingAllowed(true);
110           partialLayouter.setCoreLayouter(sol);
111           break;
112         case 2:
113           // is null per default
114       }
115       switch (optionHandler.getEnum("Component Assignment")) {
116         default:
117         case 0:
118           partialLayouter.setComponentAssignmentStrategy(PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_SINGLE);
119           break;
120         case 1:
121           partialLayouter.setComponentAssignmentStrategy(PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_CONNECTED);
122           break;
123       }
124       switch (optionHandler.getEnum("Edge Routing Style")) {
125         default:
126         case 0:
127           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_AUTOMATIC);
128           break;
129         case 1:
130           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_STRAIGHTLINE);
131           break;
132         case 2:
133           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_ORTHOGONAL);
134           break;
135         case 3:
136           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_ORGANIC);
137           break;
138       }
139       partialLayouter.setOrientationOptimizationEnabled(optionHandler.getBool("Hierarchy Reorganization"));
140       partialLayouter.setMirroringAllowed(optionHandler.getBool("Allow Mirroring"));
141       partialLayouter.setMinimalNodeDistance(optionHandler.getInt("Minimum Node Distance"));
142       switch (optionHandler.getEnum("Layout Orientation")) {
143         default:
144         case 0:
145           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_NONE);
146           break;
147         case 1:
148           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_AUTO_DETECTION);
149           break;
150         case 2:
151           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_TOP_TO_BOTTOM);
152           break;
153         case 3:
154           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_BOTTOM_TO_TOP);
155           break;
156         case 4:
157           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_LEFT_TO_RIGHT);
158           break;
159         case 5:
160           partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_RIGHT_TO_LEFT);
161           break;
162       }
163     }
164     partialLayouter.setPositioningStrategy(PartialLayouter.SUBGRAPH_POSITIONING_STRATEGY_BARYCENTER);
165     partialLayouter.setConsiderNodeAlignment(true);
166     return partialLayouter;
167   }
168 
169   /**
170    * Launches this demo.
171    */
172   public static void main(String[] args) {
173     EventQueue.invokeLater(new Runnable() {
174       public void run() {
175         Locale.setDefault(Locale.ENGLISH);
176         initLnF();
177         (new HierarchicPartialLayoutDemo("resource/hierarchiclayouthelp.html"))
178             .start("Hierarchic Partial Layouter Demo");
179       }
180     });
181   }
182 
183 }
184