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