1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.6. 
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-2008 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.module;
15  
16  import y.base.EdgeMap;
17  import y.layout.BendConverter;
18  import y.layout.CompositeLayoutStage;
19  import y.layout.LayoutGraph;
20  import y.layout.LayoutStage;
21  import y.layout.Layouter;
22  import y.layout.grouping.GroupNodeHider;
23  import y.layout.organic.RemoveOverlapsLayoutStage;
24  import y.layout.router.OrganicEdgeRouter;
25  import y.module.LayoutModule;
26  import y.option.OptionGroup;
27  import y.option.OptionHandler;
28  import y.view.Selections;
29  import y.view.hierarchy.GroupLayoutConfigurator;
30  
31  
32  
33  /**
34   * Module for the Organic Edge Router Algorithm.
35   */
36  public class OrganicEdgeRouterModule extends LayoutModule
37  {
38    private static final String ORGANIC_EDGE_ROUTER = "ORGANIC_EDGE_ROUTER";
39    private static final String MINIMAL_NODE_DISTANCE = "MINIMAL_NODE_DISTANCE";
40    private static final String USE_BENDS = "USE_BENDS";
41    private static final String ROUTE_ONLY_NECESSARY = "ROUTE_ONLY_NECESSARY";
42    private static final String SELECTION_ONLY = "SELECTION_ONLY";
43  
44    private static final String LAYOUT_OPTIONS = "LAYOUT_OPTIONS";
45  
46  
47    /**
48     * Creates a new Instance of this Module.
49     */
50    public OrganicEdgeRouterModule()
51    {
52      super(ORGANIC_EDGE_ROUTER, "Sebastian Mueller", "Routes edges organically");
53    }
54  
55    /**
56     * Creates an option handler for this module that
57     * manages options for the force transfer algorithm.
58     */
59    public OptionHandler createOptionHandler()
60    {
61      OrganicEdgeRouter router = new OrganicEdgeRouter();
62  
63      OptionHandler op = new OptionHandler(getModuleName());
64      OptionGroup og = new OptionGroup();
65      og.setAttribute(OptionGroup.ATTRIBUTE_TITLE, LAYOUT_OPTIONS);
66      og.addItem(op.addBool(SELECTION_ONLY, false));
67      og.addItem(op.addInt(MINIMAL_NODE_DISTANCE, (int)router.getMinimalDistance(), 10, 300));
68      og.addItem(op.addBool(USE_BENDS, router.isUsingBends()));
69      og.addItem(op.addBool(ROUTE_ONLY_NECESSARY, !router.isRoutingAll()));
70      return op;
71    }
72  
73    /**
74     * Launches this module.
75     */
76    protected void mainrun()
77    {
78      final OrganicEdgeRouter router = new OrganicEdgeRouter();
79      OptionHandler op = getOptionHandler();
80      router.setMinimalDistance(op.getInt(MINIMAL_NODE_DISTANCE));
81      router.setUsingBends(op.getBool(USE_BENDS));
82      router.setRoutingAll(!op.getBool(ROUTE_ONLY_NECESSARY));
83  
84      RemoveOverlapsLayoutStage rmos = new RemoveOverlapsLayoutStage(0);
85      LayoutStage nodeEnlarger = router.createNodeEnlargementStage();
86      final CompositeLayoutStage cls = new CompositeLayoutStage();
87      cls.appendStage(nodeEnlarger);
88      cls.appendStage(new BendConverter());
89      cls.appendStage(rmos);
90  
91      Layouter custom = new Layouter(){
92        public boolean canLayout( LayoutGraph graph){
93          return true;
94        }
95        public void doLayout(LayoutGraph graph){
96          cls.doLayout(graph);
97          router.doLayout(graph);
98        }
99      };
100 
101     custom = new GroupNodeHider(custom);
102 
103     // initialize potential grouping information
104     GroupLayoutConfigurator glc = new GroupLayoutConfigurator(getGraph2D());
105     try {
106       // register grouping relevant DataProviders
107       glc.prepareAll();
108       if (op.getBool(SELECTION_ONLY)){
109         EdgeMap nm = Selections.createSelectionEdgeMap(getGraph2D());
110         getGraph2D().addDataProvider(OrganicEdgeRouter.ROUTE_EDGE_DPKEY, nm);
111         launchLayouter(custom, true);
112         getGraph2D().removeDataProvider(OrganicEdgeRouter.ROUTE_EDGE_DPKEY);
113       } else {
114         launchLayouter(custom, true);
115       }
116     } finally {
117       // make sure the DataProviders will always be unregistered
118       glc.restoreAll();
119     }
120   }
121 }
122