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  
29  package demo.layout.withoutview;
30  
31  import java.util.HashMap;
32  import java.awt.EventQueue;
33  
34  import y.base.DataMap;
35  import y.geom.YPoint;
36  import y.layout.*;
37  import y.layout.DefaultLayoutGraph;
38  import y.layout.BufferedLayouter;
39  import y.util.D;
40  import y.base.Edge;
41  import y.base.EdgeMap;
42  import y.base.Node;
43  import y.layout.PortConstraint;
44  import y.layout.PortConstraintKeys;
45  import y.layout.hierarchic.IncrementalHierarchicLayouter;
46  import y.layout.hierarchic.incremental.IncrementalHintsFactory;
47  import y.util.Maps;
48  
49  /**
50   * This demo shows how to use the incremental hierarchical layout algorithm
51   * without using classes that are only present in the yFiles Viewer Distribution. 
52   * In this demo, first a graph will be laid out from scratch. Then new graph elements
53   * will be added to the graph structure. Finally, an updated layout for the
54   * grown graph structure will be calculated. The updated layout
55   * will still look similar to the original layout. This feature
56   * is called incremental layout.
57   * <br>
58   * This demo displays the calculated coordinates before and
59   * after the incremental layout step in a simple graph viewer.
60   * Additionally it outputs the calculated coordinates of the graph layout to
61   * the console.
62   *
63   * @see <a href="http://docs.yworks.com/yfiles/doc/api/index.html#/dguide/incremental_hierarchical_layouter" target="_blank">Section Hierarchical Layout Style</a> in the yFiles for Java Developer's Guide
64   */
65  public class IncrementalLayoutWithoutAView
66  {
67    
68    /**
69     * Launcher
70     */
71    public static void main(String[] args) {
72      EventQueue.invokeLater(new Runnable() {
73        public void run() {
74          IncrementalLayoutWithoutAView lwv = new IncrementalLayoutWithoutAView();
75          lwv.doit();
76        }
77      });
78    }
79    
80    /**
81     * Uses IncrementalHierarchicLayouter to perform an incremental layout of a graph.
82     */
83    public void doit()
84    {
85      DefaultLayoutGraph graph = new DefaultLayoutGraph();
86      
87      //construct graph. assign sizes to nodes
88      Node v1 = graph.createNode();
89      graph.setSize(v1,30,30);
90      Node v2 = graph.createNode();
91      graph.setSize(v2,30,30);
92      Node v3 = graph.createNode();
93      graph.setSize(v3,30,30);
94      
95      Edge e1 = graph.createEdge(v1,v2);
96      Edge e2 = graph.createEdge(v1,v3);
97   
98      //optionally setup some port constraints for HierarchicLayouter
99      EdgeMap spc = graph.createEdgeMap();
100     EdgeMap tpc = graph.createEdgeMap();
101     //e1 shall leave and enter the node on the right side
102     spc.set(e1, PortConstraint.create(PortConstraint.EAST));
103     //additionally set a strong port constraint on the target side. 
104     tpc.set(e1, PortConstraint.create(PortConstraint.EAST, true));
105     //ports with strong port constraints will not be reset by the 
106     //layouter.  So we specify the target port right now to connect 
107     //to the upper left corner of the node 
108     graph.setTargetPointRel(e1, new YPoint(15, -15));
109     
110     //e2 shall leave and enter the node on the top side
111     spc.set(e2, PortConstraint.create(PortConstraint.NORTH));
112     tpc.set(e2, PortConstraint.create(PortConstraint.NORTH));
113     
114     graph.addDataProvider(PortConstraintKeys.SOURCE_PORT_CONSTRAINT_KEY, spc);
115     graph.addDataProvider(PortConstraintKeys.TARGET_PORT_CONSTRAINT_KEY, tpc);
116     
117     IncrementalHierarchicLayouter layouter = new IncrementalHierarchicLayouter();
118     layouter.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_FROM_SCRATCH);
119     
120     new BufferedLayouter(layouter).doLayout(graph);
121     
122     //display result
123     LayoutPreviewPanel lpp1 = new LayoutPreviewPanel(new CopiedLayoutGraph(graph));
124     lpp1.createFrame("Hierarchical").setVisible(true);
125     
126     D.bug("\n\nGRAPH LAID OUT HIERARCHICALLY FROM SCRATCH");
127     D.bug("v1 center position = " + graph.getCenter(v1));
128     D.bug("v2 center position = " + graph.getCenter(v2));
129     D.bug("v3 center position = " + graph.getCenter(v3));
130     D.bug("e1 path = " + graph.getPath(e1));
131     D.bug("e2 path = " + graph.getPath(e2));
132 
133     //now add a node and two edges incrementally...
134     Node v4 = graph.createNode();
135     graph.setSize(v4,30,30);
136     
137     Edge e3 = graph.createEdge(v1,v4);
138     Edge e4 = graph.createEdge(v4,v2);
139     
140     IncrementalHintsFactory ihf = layouter.createIncrementalHintsFactory();
141     DataMap map = Maps.createDataMap(new HashMap());
142     
143     map.set(v4, ihf.createLayerIncrementallyHint(v4));
144     map.set(e3, ihf.createSequenceIncrementallyHint(e3));
145     map.set(e4, ihf.createSequenceIncrementallyHint(e4));
146     
147     graph.addDataProvider(IncrementalHierarchicLayouter.INCREMENTAL_HINTS_DPKEY, map);
148     layouter.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_INCREMENTAL);
149     
150     new BufferedLayouter(layouter).doLayout(graph);
151     
152     //display result
153     LayoutPreviewPanel lpp2 = new LayoutPreviewPanel(graph);
154     lpp2.createFrame("Hierarchical with incrementally added elements").setVisible(true);
155 
156     D.bug("\n\nGRAPH AFTER ELEMENTS HAVE BEEN ADDED INCREMENTALLY");
157     D.bug("v1 center position = " + graph.getCenter(v1));
158     D.bug("v2 center position = " + graph.getCenter(v2));
159     D.bug("v3 center position = " + graph.getCenter(v3));
160     D.bug("v4 center position = " + graph.getCenter(v4));
161     D.bug("e1 path = " + graph.getPath(e1));
162     D.bug("e2 path = " + graph.getPath(e2));
163     D.bug("e3 path = " + graph.getPath(e3));
164     D.bug("e4 path = " + graph.getPath(e4));
165   }
166 }
167