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.circular.CircularLayouter;
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 circular 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 CircularPartialLayoutDemo extends PartialLayoutBase {
45  
46    public CircularPartialLayoutDemo() {
47      this(null);
48    }
49  
50    public CircularPartialLayoutDemo(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/graphCircular.graphml");
59    }
60  
61  
62    protected OptionHandler createOptionHandler() {
63      final OptionHandler layoutOptionHandler = new OptionHandler("Option Table");
64  
65      layoutOptionHandler.addEnum("Subgraph Layout",
66          new Object[]{"Circular Layout", "Unchanged"}, 0);
67      layoutOptionHandler.addEnum("Component Assignment",
68          new Object[]{"Single Nodes", "Connected Graphs"}, 1);
69      layoutOptionHandler.addEnum("Placement Strategy",
70          new Object[]{"Barycenter", "From Sketch"}, 0);
71      layoutOptionHandler.addEnum("Edge Routing Style",
72          new Object[]{"Automatic", "Straight Line", "Organic"}, 0);
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        final int minNodeDist = optionHandler.getInt("Minimum Node Distance");
86        partialLayouter.setMinimalNodeDistance(minNodeDist);
87        switch (optionHandler.getEnum("Subgraph Layout")) {
88          default:
89          case 0:
90            CircularLayouter layouter = new CircularLayouter();
91            layouter.getSingleCycleLayouter().setMinimalNodeDistance(minNodeDist);
92            partialLayouter.setCoreLayouter(layouter);
93            break;
94          case 1:
95            // is null per default
96        }
97        switch (optionHandler.getEnum("Component Assignment")) {
98          default:
99          case 0:
100           partialLayouter.setComponentAssignmentStrategy(PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_SINGLE);
101           break;
102         case 1:
103           partialLayouter.setComponentAssignmentStrategy(PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_CONNECTED);
104           break;
105       }
106       switch (optionHandler.getEnum("Placement Strategy")) {
107         default:
108         case 0:
109           partialLayouter.setPositioningStrategy(PartialLayouter.SUBGRAPH_POSITIONING_STRATEGY_BARYCENTER);
110           break;
111         case 1:
112           partialLayouter.setPositioningStrategy(PartialLayouter.SUBGRAPH_POSITIONING_STRATEGY_FROM_SKETCH);
113           break;
114       }
115       switch (optionHandler.getEnum("Edge Routing Style")) {
116         default:
117         case 0:
118           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_AUTOMATIC);
119           break;
120         case 1:
121           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_STRAIGHTLINE);
122           break;
123         case 2:
124           partialLayouter.setEdgeRoutingStrategy(PartialLayouter.EDGE_ROUTING_STRATEGY_ORGANIC);
125           break;
126       }
127       partialLayouter.setMirroringAllowed(optionHandler.getBool("Allow Mirroring"));
128     }
129     return partialLayouter;
130   }
131 
132   /**
133    * Launches this demo.
134    */
135   public static void main(String[] args) {
136     EventQueue.invokeLater(new Runnable() {
137       public void run() {
138         Locale.setDefault(Locale.ENGLISH);
139         initLnF();
140         (new CircularPartialLayoutDemo("resource/circularlayouthelp.html"))
141             .start("Circular Partial Layouter Demo");
142       }
143     });
144   }
145 }