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.organic.SmartOrganicLayouter;
18  import y.layout.partial.PartialLayouter;
19  import y.option.IntOptionItem;
20  import y.option.OptionHandler;
21  
22  import java.awt.EventQueue;
23  import java.util.Locale;
24  
25  /**
26   * This demo shows how to apply the partial layouter to organic layouts. The partial layouter changes the coordinates
27   * for a given set of graph elements (called partial elements). The location or size of the remaining elements (called
28   * fixed elements) is not allowed to be changed. The layout algorithm tries to place the partial elements such that the
29   * resulting drawing (including the fixed elements) has a good quality with respect to common graph drawing aesthetics.
30   * <p/>
31   * Partial node elements can be assigned to so called subgraph components. During the layout process each subgraph
32   * induced by the nodes of a component is first laid out using the specified subgraph layouter. Then, the different
33   * components are placed one-by-one onto the drawing area such that the number of overlaps among graph elements is
34   * small. The user can specify different objectives (placement strategies) for finding 'good' positions for subgraph
35   * components.
36   * <p/>
37   * The demo allows to specify fixed and partial elements. Fixed elements are drawn grey and partial elements orange. To
38   * change the fixed/partial state of elements, select the corresponding elements and click on the "Lock Selected
39   * Elements" or "Unlock Selected Elements" button. The current state of selected elements can be toggled with a
40   * mouse-double-click. To start the partial layouter click on the "Apply Partial Layout" button.
41   *
42   * @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
43   */
44  public class OrganicPartialLayoutDemo extends PartialLayoutBase {
45  
46    public OrganicPartialLayoutDemo() {
47      this(null);
48    }
49  
50    public OrganicPartialLayoutDemo(final String helpFilePath) {
51      super(helpFilePath);
52    }
53  
54    /**
55     * Loads a graph, which contains fix nodes and nodes, which should be integrated into this graph.
56     */
57    protected void loadInitialGraph() {
58      loadGraph("resource/graphOrganic.graphml");
59    }
60  
61    protected OptionHandler createOptionHandler() {
62      final OptionHandler layoutOptionHandler = new OptionHandler("Option Table");
63  
64      layoutOptionHandler.addEnum("Subgraph Layout",
65          new Object[]{"Organic Layout", "Unchanged"}, 0);
66      layoutOptionHandler.addEnum("Component Assignment",
67          new Object[]{"Single Nodes", "Connected Graphs"}, 0);
68      layoutOptionHandler.addEnum("Placement Strategy",
69          new Object[]{"Barycenter", "From Sketch"}, 0);
70      layoutOptionHandler.addEnum("Edge Routing Style",
71          new Object[]{"Automatic", "Straight Line", "Organic"}, 0);
72      layoutOptionHandler.addBool("Snapping", true);
73      layoutOptionHandler.addBool("Allow Mirroring", false);
74      layoutOptionHandler.addInt("Minimum Node Distance", 10);
75      layoutOptionHandler.getItem("Minimum Node Distance").setAttribute(
76          IntOptionItem.ATTRIBUTE_MIN_VALUE, new Integer(0));
77  
78      return layoutOptionHandler;
79    }
80  
81    protected Layouter createConfiguredPartialLayouter() {
82      final PartialLayouter partialLayouter = new PartialLayouter();
83  
84      if (optionHandler != null) {
85        switch (optionHandler.getEnum("Subgraph Layout")) {
86          default:
87          case 0:
88            partialLayouter.setCoreLayouter(new SmartOrganicLayouter());
89            break;
90          case 1:
91            // is null per default
92        }
93        switch (optionHandler.getEnum("Component Assignment")) {
94          default:
95          case 0:
96            partialLayouter.setComponentAssignmentStrategy(PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_SINGLE);
97            break;
98          case 1:
99            partialLayouter.setComponentAssignmentStrategy(PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_CONNECTED);
100           break;
101       }
102       switch (optionHandler.getEnum("Placement Strategy")) {
103         default:
104         case 0:
105           partialLayouter.setPositioningStrategy(PartialLayouter.SUBGRAPH_POSITIONING_STRATEGY_BARYCENTER);
106           break;
107         case 1:
108           partialLayouter.setPositioningStrategy(PartialLayouter.SUBGRAPH_POSITIONING_STRATEGY_FROM_SKETCH);
109           break;
110       }
111       switch (optionHandler.getEnum("Edge Routing Style")) {
112         default:
113         case 0:
114           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_AUTOMATIC);
115           break;
116         case 1:
117           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_STRAIGHTLINE);
118           break;
119         case 2:
120           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_ORGANIC);
121           break;
122       }
123       partialLayouter.setConsiderNodeAlignment(optionHandler.getBool("Snapping"));
124       partialLayouter.setMirroringAllowed(optionHandler.getBool("Allow Mirroring"));
125       partialLayouter.setMinimalNodeDistance(optionHandler.getInt("Minimum Node Distance"));
126     }
127     partialLayouter.setLayoutOrientation(PartialLayouter.ORIENTATION_AUTO_DETECTION);
128     return partialLayouter;
129   }
130 
131   /**
132    * Launches this demo.
133    */
134   public static void main(String[] args) {
135     EventQueue.invokeLater(new Runnable() {
136       public void run() {
137         Locale.setDefault(Locale.ENGLISH);
138         initLnF();
139         (new OrganicPartialLayoutDemo("resource/organiclayouthelp.html"))
140             .start("Organic Partial Layouter Demo");
141       }
142     });
143   }
144 
145 }