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.module;
15  
16  import y.module.LayoutModule;
17  import y.module.YModule;
18  
19  import y.layout.organic.OrganicLayouter;
20  import y.option.OptionHandler;
21  import y.view.Selections;
22  import y.view.hierarchy.HierarchyManager;
23  
24  /**
25   * This module represents an interactive configurator and launcher for
26   * {@link y.layout.organic.OrganicLayouter}.
27   *
28   */
29  public class OrganicLayoutModule extends LayoutModule
30  {
31    private static final String ACTIVATE_DETERMINISTIC_MODE = "ACTIVATE_DETERMINISTIC_MODE";
32    private static final String ACTIVATE_TREE_BEAUTIFIER = "ACTIVATE_TREE_BEAUTIFIER";
33    private static final String MODE = "MODE";
34    private static final String MAXIMAL_DURATION = "MAXIMAL_DURATION";
35    private static final String ITERATION_FACTOR = "ITERATION_FACTOR";
36    private static final String OBEY_NODE_SIZES = "OBEY_NODE_SIZES";
37    private static final String GRAVITY_FACTOR = "GRAVITY_FACTOR";
38    private static final String SPHERE_OF_ACTION = "SPHERE_OF_ACTION";
39    private static final String INITIAL_PLACEMENT = "INITIAL_PLACEMENT";
40    private static final String PREFERRED_EDGE_LENGTH = "PREFERRED_EDGE_LENGTH";
41    private static final String VISUAL = "VISUAL";
42    private static final String ALGORITHM = "ALGORITHM";
43    private static final String ORGANIC = "ORGANIC";
44    private static final String ONLY_SELECTION = "ONLY_SELECTION";
45    private static final String MAINLY_SELECTION = "MAINLY_SELECTION";
46    private static final String ALL = "ALL";
47    private static final String AS_IS = "AS_IS";
48    private static final String RANDOM = "RANDOM";
49    private static final String AT_ORIGIN = "AT_ORIGIN";
50    private static final String EDGE_LENGTH_DEVIATION = "EDGE_LENGTH_DEVIATION";
51    private static final String REPULSION = "REPULSION";
52    private static final String ATTRACTION = "ATTRACTION";
53    
54    private static final String GROUPING      = "GROUPING";
55    private static final String GROUP_LAYOUT_POLICY = "GROUP_LAYOUT_POLICY";
56    private static final String IGNORE_GROUPS = "IGNORE_GROUPS";
57    private static final String LAYOUT_GROUPS = "LAYOUT_GROUPS";
58    private static final String FIX_GROUPS    = "FIX_GROUPS";
59    private static final String GROUP_NODE_COMPACTNESS = "GROUP_NODE_COMPACTNESS";
60  
61    // for the option handler
62    private final static String[] initialPlacementEnum =
63    { 
64      RANDOM, 
65      AT_ORIGIN,
66      AS_IS 
67    };
68  
69    // for the option handler
70    private final static String[] sphereOfActionEnum =
71    {
72      ALL,
73      MAINLY_SELECTION,
74      ONLY_SELECTION
75    };
76  
77    private OrganicLayouter organic;
78    
79    public OrganicLayoutModule()
80    {
81      super (ORGANIC,
82             "yFiles Layout Team",
83             "Wrapper for OrganicLayouter");
84    }
85  
86    /**
87     * Factory method. Responsible for creating and initializing
88     * the OptionHandler for this module.
89     */
90    protected OptionHandler createOptionHandler()
91    {
92      if (organic == null){
93        createOrganic();
94      }
95      
96      OptionHandler op = new OptionHandler(getModuleName());
97  
98      op.useSection(VISUAL);
99      op.addEnum(SPHERE_OF_ACTION,sphereOfActionEnum,
100                organic.getSphereOfAction());
101     op.addEnum(INITIAL_PLACEMENT,initialPlacementEnum,
102                organic.getInitialPlacement());
103     op.addInt(PREFERRED_EDGE_LENGTH, organic.getPreferredEdgeLength(), 0, 500);
104     op.addBool(OBEY_NODE_SIZES,organic.getObeyNodeSize());
105     op.addInt(ATTRACTION, organic.getAttraction(), 0, 2);
106     op.addInt(REPULSION, organic.getRepulsion(), 0, 2);
107     op.addDouble(GRAVITY_FACTOR,organic.getGravityFactor(),-0.2,2,1);
108     op.addBool(ACTIVATE_TREE_BEAUTIFIER,organic.getActivateTreeBeautifier());
109 
110     op.useSection(ALGORITHM);
111     op.addDouble(ITERATION_FACTOR,organic.getIterationFactor());
112     op.addInt(MAXIMAL_DURATION,(int)(organic.getMaximumDuration()/1000));
113     op.addBool(ACTIVATE_DETERMINISTIC_MODE,organic.getActivateDeterministicMode());
114     
115     op.useSection(GROUPING);
116     String[] gEnum = { LAYOUT_GROUPS, FIX_GROUPS, IGNORE_GROUPS };
117     op.addEnum(GROUP_LAYOUT_POLICY, gEnum, 0);
118     op.addDouble(GROUP_NODE_COMPACTNESS, organic.getGroupNodeCompactness(), 0, 1);
119     return op;
120   }
121 
122   /**
123    * Module initialization routine. Typically this method is used to 
124    * configure the underlying algorithm with the options found in the
125    * options handler of this module.
126    */
127   protected void init()
128   {
129     createOrganic();
130     
131     OptionHandler op = getOptionHandler();
132 
133     organic.setPreferredEdgeLength(op.getInt(VISUAL,PREFERRED_EDGE_LENGTH));
134     organic.setMaximumDuration(1000*op.getInt(ALGORITHM,MAXIMAL_DURATION));
135     organic.setInitialPlacement((byte)OptionHandler.getIndex(initialPlacementEnum,
136                                           op.getString(VISUAL,INITIAL_PLACEMENT)));
137     organic.setSphereOfAction((byte)OptionHandler.getIndex(sphereOfActionEnum,
138                                         op.getString(VISUAL,SPHERE_OF_ACTION)));
139     organic.setGravityFactor(op.getDouble(VISUAL,GRAVITY_FACTOR));
140     organic.setObeyNodeSize(op.getBool(VISUAL,OBEY_NODE_SIZES));
141     organic.setIterationFactor(op.getDouble(ALGORITHM,ITERATION_FACTOR));
142     organic.setActivateTreeBeautifier(op.getBool(VISUAL,ACTIVATE_TREE_BEAUTIFIER));
143     organic.setActivateDeterministicMode(op.getBool(ALGORITHM,ACTIVATE_DETERMINISTIC_MODE));
144     organic.setAttraction(op.getInt(VISUAL,ATTRACTION));
145     organic.setRepulsion(2-op.getInt(VISUAL,REPULSION));
146     organic.setGroupNodeCompactness(op.getDouble(GROUPING, GROUP_NODE_COMPACTNESS));
147   }
148   
149   /**
150    * Main module execution routine. launches the hierarchic layouter.
151    */
152   protected void mainrun()
153   {
154     try{
155       getGraph2D().addDataProvider(OrganicLayouter.SPHERE_OF_ACTION_NODES, 
156                   Selections.createSelectionNodeMap(getGraph2D()));
157 
158       OptionHandler op = getOptionHandler();
159       if(HierarchyManager.containsGroupNodes(getGraph2D()))
160       {
161         if (op.get(GROUPING, GROUP_LAYOUT_POLICY).equals(FIX_GROUPS))
162         {
163           organic.setGroupNodePolicy(OrganicLayouter.FIXED_GROUPS_POLICY);
164         } else if (op.get(GROUPING, GROUP_LAYOUT_POLICY).equals(IGNORE_GROUPS)){
165           organic.setGroupNodePolicy(OrganicLayouter.IGNORE_GROUPS_POLICY);
166         } else {
167           organic.setGroupNodePolicy(OrganicLayouter.LAYOUT_GROUPS_POLICY);
168         }
169       }
170 
171       launchLayouter(organic);
172     } finally {
173       getGraph2D().removeDataProvider(OrganicLayouter.SPHERE_OF_ACTION_NODES);
174     }
175   }
176   
177   /**
178    * clean up the module, clear temporarily bound data providers and
179    * references to the wrapped algorithm.
180    */
181   protected void dispose()
182   {
183     organic = null;
184   }
185   
186   private void createOrganic()
187   {
188     if(organic == null)
189     {
190       organic = new OrganicLayouter();
191     }
192   }
193 }
194 
195