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.withoutview;
15  
16  import y.base.Edge;
17  import y.base.Node;
18  import y.base.NodeMap;
19  import y.base.ListCell;
20  import y.layout.BufferedLayouter;
21  import y.layout.CopiedLayoutGraph;
22  import y.layout.DefaultLayoutGraph;
23  import y.layout.LayoutGraph;
24  import y.layout.hierarchic.IncrementalHierarchicLayouter;
25  import y.layout.hierarchic.incremental.PartitionGrid;
26  import y.layout.hierarchic.incremental.ColumnDescriptor;
27  import y.util.D;
28  import y.util.DataProviders;
29  
30  import java.awt.Graphics2D;
31  import java.awt.Rectangle;
32  import java.awt.Color;
33  import java.awt.EventQueue;
34  import java.awt.geom.Line2D;
35  
36  /**
37   * This demo shows how to use the swim lane feature of IncrementalHierarchicLayouter
38   * without using classes that are only present in the yFiles Viewer Distribution. 
39   * In this demo, nodes will be assigned to certain regions of the diagram,
40   * the so-called swim lanes. The diagram will be arranged using hierarchical layout
41   * style, while nodes remain within the bounds of their lanes.
42   * <br>
43   * This demo displays the calculated coordinates in a simple graph viewer.
44   * Additionally it outputs the calculated coordinates of the graph layout to
45   * the console.
46   *
47   * @see <a href="http://docs.yworks.com/yfiles/doc/developers-guide/incremental_hierarchical_layouter.html">Section Hierarchical Layout Style</a> in the yFiles for Java Developer's Guide
48   */
49  public class SwimlaneLayoutWithoutAView
50  {
51    
52    public static void main(String[] args) {
53      EventQueue.invokeLater(new Runnable() {
54        public void run() {
55          SwimlaneLayoutWithoutAView lwv = new SwimlaneLayoutWithoutAView();
56          lwv.doit();
57        }
58      });
59    }
60  
61    /**
62     * Creates a small graph and applies a swim lane layout to it.
63     */
64    public void doit()
65    {
66      DefaultLayoutGraph graph = new DefaultLayoutGraph();
67      
68      //construct graph. assign sizes to nodes
69      Node v1 = graph.createNode();
70      graph.setSize(v1,30,30);
71      Node v2 = graph.createNode();
72      graph.setSize(v2,30,30);
73      Node v3 = graph.createNode();
74      graph.setSize(v3,30,30);
75      Node v4 = graph.createNode();
76      graph.setSize(v4,30,30);
77  
78      // create some edges...
79      Edge e1 = graph.createEdge(v1,v2);
80      Edge e2 = graph.createEdge(v1,v3);
81      Edge e3 = graph.createEdge(v2,v4);
82      
83      // create a grid that models two swim lanes,
84      // i.e. a grid with two columns and one row
85      final PartitionGrid grid = new PartitionGrid(1, 2);
86  
87      // create a map to store the node to lane mapping
88      NodeMap cellMap = graph.createNodeMap();
89  
90      // assign nodes to lanes
91      // lanes correspond to cells, as the grid has only one row
92      cellMap.set(v1, grid.createCellId(0, 0));
93      cellMap.set(v2, grid.createCellId(0, 1));
94      cellMap.set(v3, grid.createCellId(0, 1));
95      cellMap.set(v4, grid.createCellId(0, 0));
96   
97      // register the information
98      graph.addDataProvider(PartitionGrid.PARTITION_CELL_DPKEY, cellMap);
99      graph.addDataProvider(PartitionGrid.PARTITION_GRID_DPKEY, DataProviders.createConstantDataProvider(grid));
100     
101     // create the layout algorithm
102     IncrementalHierarchicLayouter layouter = new IncrementalHierarchicLayouter();
103     
104     // start the layout
105     new BufferedLayouter(layouter).doLayout(graph);
106     
107     //display result
108     LayoutPreviewPanel lpp1 = new LayoutPreviewPanel(new CopiedLayoutGraph(graph)) {
109       Line2D.Double line = new Line2D.Double();
110       protected void paint( final Graphics2D g, final LayoutGraph graph ) {
111         final Color oldColor = g.getColor();
112         g.setColor(Color.white);
113 
114         final Rectangle bbx = graph.getBoundingBox();
115         line.y1 = Math.floor(bbx.getY()) - 10;
116         line.y2 = Math.ceil(bbx.getMaxY()) + 10;
117         for (ListCell cell = grid.getColumns().firstCell(); cell != null; cell = cell.succ()) {
118           final ColumnDescriptor lane = (ColumnDescriptor) cell.getInfo();
119           line.x1 = lane.getComputedPosition();
120           line.x2 = line.x1;
121           g.draw(line);
122         }
123         {
124           final ColumnDescriptor lane = grid.getColumn(grid.getColumns().size() - 1);
125           line.x1 += lane.getComputedWidth();
126           line.x2 = line.x1;
127           g.draw(line);
128         }
129 
130         g.setColor(oldColor);
131       }
132     };
133     lpp1.createFrame("Swimlanes").setVisible(true);
134     
135     D.bug("\n\nGRAPH LAID OUT HIERARCHICALLY IN SWIMLANES");
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("Column 0 index = " + grid.getColumn(0).getIndex());
144     D.bug("Column 0 position = " + grid.getColumn(0).getComputedPosition());
145     D.bug("Column 0 width = " + grid.getColumn(0).getComputedWidth());
146     D.bug("Column 1 index = " + grid.getColumn(1).getIndex());
147     D.bug("Column 1 position = " + grid.getColumn(1).getComputedPosition());
148     D.bug("Column 1 width = " + grid.getColumn(1).getComputedWidth());
149   }
150 }
151