1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.5.0.1. 
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-2007 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  
15  package demo.layout;
16  
17  import java.util.HashMap;
18  import y.base.DataMap;
19  import y.geom.YPoint;
20  import y.layout.*;
21  import y.layout.DefaultLayoutGraph;
22  import y.layout.BufferedLayouter;
23  import y.util.D;
24  import y.base.Edge;
25  import y.base.EdgeMap;
26  import y.base.Node;
27  import y.layout.PortConstraint;
28  import y.layout.PortConstraintKeys;
29  import y.layout.hierarchic.IncrementalHierarchicLayouter;
30  import y.layout.hierarchic.incremental.IncrementalHintsFactory;
31  import y.util.Maps;
32  
33  /**
34   * This demo shows how to use the incremental hierarchical layout algorithm
35   * without using classes that are only present in the yFiles Viewer Distribution. 
36   * In this demo, first a graph will be layouted from scratch. Then new graph elements
37   * will be added to the graph structure. Finally, an updated layout for the
38   * grown graph structure will be calculated. The updated layout
39   * will still look similar to the original layout. This feature
40   * is called incremental layout.
41   * <br>
42   * This demo displays the calculated coordinates before and
43   * after the incremental layout step in a simple graph viewer.
44   * Additionally it outputs the calculated coordinates of the graph layout to
45   * the console.
46   */
47  public class IncrementalLayoutWithoutAView
48  {
49    
50    /**
51     * Launcher
52     */
53    public static void main(String[] args)
54    {
55      IncrementalLayoutWithoutAView lwv = new IncrementalLayoutWithoutAView();
56      lwv.doit();
57    }
58    
59    /**
60     * Uses IncrementalHierarchicLayouter to perform an incremental layout of a graph.
61     */
62    public void doit()
63    {
64      DefaultLayoutGraph graph = new DefaultLayoutGraph();
65      
66      //construct graph. assign sizes to nodes
67      Node v1 = graph.createNode();
68      graph.setSize(v1,30,30);
69      Node v2 = graph.createNode();
70      graph.setSize(v2,30,30);
71      Node v3 = graph.createNode();
72      graph.setSize(v3,30,30);
73      
74      Edge e1 = graph.createEdge(v1,v2);
75      Edge e2 = graph.createEdge(v1,v3);
76   
77      //optionally setup some port constraints for HierarchicLayouter
78      EdgeMap spc = graph.createEdgeMap();
79      EdgeMap tpc = graph.createEdgeMap();
80      //e1 shall leave and enter the node on the right side
81      spc.set(e1, PortConstraint.create(PortConstraint.EAST));
82      //additionally set a strong port constraint on the target side. 
83      tpc.set(e1, PortConstraint.create(PortConstraint.EAST, true));
84      //ports with strong port constraints will not be reset by the 
85      //layouter.  So we specify the target port right now to connect 
86      //to the upper left corner of the node 
87      graph.setTargetPointRel(e1, new YPoint(15, -15));
88      
89      //e2 shall leave and enter the node on the top side
90      spc.set(e2, PortConstraint.create(PortConstraint.NORTH));
91      tpc.set(e2, PortConstraint.create(PortConstraint.NORTH));
92      
93      graph.addDataProvider(PortConstraintKeys.SOURCE_PORT_CONSTRAINT_KEY, spc);
94      graph.addDataProvider(PortConstraintKeys.TARGET_PORT_CONSTRAINT_KEY, tpc);
95      
96      IncrementalHierarchicLayouter layouter = new IncrementalHierarchicLayouter();
97      layouter.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_FROM_SCRATCH);
98      
99      new BufferedLayouter(layouter).doLayout(graph);
100     
101     //display result
102     LayoutPreviewPanel lpp1 = new LayoutPreviewPanel(new CopiedLayoutGraph(graph));
103     lpp1.createFrame("Hierarchical").setVisible(true);
104     
105     D.bug("\n\nGRAPH LAID OUT HIERARCHICALLY FROM SCRATCH");
106     D.bug("v1 center position = " + graph.getCenter(v1));
107     D.bug("v2 center position = " + graph.getCenter(v2));
108     D.bug("v3 center position = " + graph.getCenter(v3));
109     D.bug("e1 path = " + graph.getPath(e1));
110     D.bug("e2 path = " + graph.getPath(e2));
111 
112     //now add a node and two edges incrementally...
113     Node v4 = graph.createNode();
114     graph.setSize(v4,30,30);
115     
116     Edge e3 = graph.createEdge(v1,v4);
117     Edge e4 = graph.createEdge(v4,v2);
118     
119     IncrementalHintsFactory ihf = layouter.createIncrementalHintsFactory();
120     DataMap map = Maps.createDataMap(new HashMap());
121     
122     map.set(v4, ihf.createLayerIncrementallyHint(v4));
123     map.set(e3, ihf.createSequenceIncrementallyHint(e3));
124     map.set(e4, ihf.createSequenceIncrementallyHint(e4));
125     
126     graph.addDataProvider(IncrementalHierarchicLayouter.INCREMENTAL_HINTS_DPKEY, map);
127     layouter.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_INCREMENTAL);
128     
129     new BufferedLayouter(layouter).doLayout(graph);
130     
131     //display result
132     LayoutPreviewPanel lpp2 = new LayoutPreviewPanel(graph);
133     lpp2.createFrame("Hierarchical with incrementally added elements").setVisible(true);
134 
135     D.bug("\n\nGRAPH AFTER ELEMENTS HAVE BEEN ADDED INCREMENTALLY");
136     D.bug("v1 center position = " + graph.getCenter(v1));
137     D.bug("v2 center position = " + graph.getCenter(v2));
138     D.bug("v3 center position = " + graph.getCenter(v3));
139     D.bug("v4 center position = " + graph.getCenter(v4));
140     D.bug("e1 path = " + graph.getPath(e1));
141     D.bug("e2 path = " + graph.getPath(e2));
142     D.bug("e3 path = " + graph.getPath(e3));
143     D.bug("e4 path = " + graph.getPath(e4));
144   }
145 }
146