| LayoutWithoutAView.java |
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 y.geom.YRectangle;
32 import y.geom.YPoint;
33 import y.geom.OrientedRectangle;
34 import y.layout.*;
35 import y.layout.DefaultLayoutGraph;
36 import y.layout.EdgeLabelModel;
37 import y.layout.LayoutGraph;
38 import y.layout.EdgeLabelLayout;
39 import y.layout.FreeEdgeLabelModel;
40 import y.layout.BufferedLayouter;
41 import y.layout.SliderEdgeLabelModel;
42 import y.layout.EdgeLabelLayoutImpl;
43 import y.layout.hierarchic.IncrementalHierarchicLayouter;
44 import y.layout.labeling.GreedyMISLabeling;
45 import y.util.D;
46 import y.base.Edge;
47 import y.base.EdgeMap;
48 import y.base.Node;
49 import y.layout.PortConstraint;
50 import y.layout.PortConstraintKeys;
51
52 import java.awt.EventQueue;
53
54 /**
55 * This class shows how to use layout and labeling algorithms without using classes
56 * that are only present in the yFiles Viewer Distribution. Therefore this demo
57 * only outputs the calculated coordinates of the graph layout to the console and
58 * displays it inside a simple preview panel.
59 * <br>
60 * In this demo HierarchicLayouter is used to layout a small graph.
61 * <br>
62 * First the edge labels of the graph will be laid out using a general labeling
63 * approach that effectively positions the labels after the node and edge positions
64 * have already been fixed.
65 * <br>
66 * Second, a special edge labeling mechanism will be used that is currently only
67 * available in conjunction with HierarchicLayouter. While laying out the graph the
68 * edge labels will be considered as well. Therefore the node and edge positions
69 * can be chosen in such a way that, the labeling does not
70 * introduce overlaps between labels and other entities in the graph.
71 *
72 * @see <a href="http://docs.yworks.com/yfiles/doc/api/index.html#/dguide/layout_advanced_features" target="_blank">Section Advanced Layout Concepts</a> in the yFiles for Java Developer's Guide
73 * @see <a href="http://docs.yworks.com/yfiles/doc/api/index.html#/dguide/labeling" target="_blank">Section Automatic Label Placement</a> in the yFiles for Java Developer's Guide
74 */
75 public class LayoutWithoutAView
76 {
77
78 /**
79 * Launcher
80 */
81 public static void main(String[] args) {
82 EventQueue.invokeLater(new Runnable() {
83 public void run() {
84 LayoutWithoutAView lwv = new LayoutWithoutAView();
85 lwv.doit();
86 }
87 });
88 }
89
90 /**
91 * Creates a small graph and applies an hierarchic layout to it.
92 * Two different kinds of edge labeling mechanisms will be applied
93 * to the graph.
94 * <p>
95 * The output of the calculated coordinates will be displayed in the
96 * console.
97 */
98 public void doit()
99 {
100 DefaultLayoutGraph graph = new DefaultLayoutGraph();
101
102 //construct graph. assign sizes to nodes
103 Node v1 = graph.createNode();
104 graph.setSize(v1,30,30);
105 Node v2 = graph.createNode();
106 graph.setSize(v2,30,30);
107 Node v3 = graph.createNode();
108 graph.setSize(v3,30,30);
109
110 Edge e1 = graph.createEdge(v1,v2);
111 Edge e2 = graph.createEdge(v2,v3);
112 Edge e3 = graph.createEdge(v1,v3);
113
114 //optionally setup some port constraints for HierarchicLayouter
115 EdgeMap spc = graph.createEdgeMap();
116 EdgeMap tpc = graph.createEdgeMap();
117 //e1 shall leave and enter the node on the right side
118 spc.set(e1, PortConstraint.create(PortConstraint.EAST));
119 //additionally set a strong port constraint on the target side.
120 tpc.set(e1, PortConstraint.create(PortConstraint.EAST, true));
121 //ports with strong port constraints will not be reset by the
122 //layouter. So we specify the target port right now to connect
123 //to the upper-right corner of the node
124 graph.setTargetPointRel(e1, new YPoint(15, -15));
125
126 //e2 shall leave and enter the node on the top side
127 spc.set(e2, PortConstraint.create(PortConstraint.NORTH));
128 tpc.set(e2, PortConstraint.create(PortConstraint.NORTH));
129 //e3 uses no port constraints, i.e. layouter will choose best side
130 graph.addDataProvider(PortConstraintKeys.SOURCE_PORT_CONSTRAINT_KEY, spc);
131 graph.addDataProvider(PortConstraintKeys.TARGET_PORT_CONSTRAINT_KEY, tpc);
132
133
134 //setup two edge labels for edge e1. The size of the edge labels will be set to
135 //80x20. Usually the size of the labels will be determined by
136 //calculating the bounding box of a piece text that is displayed
137 //with a specific font.
138 EdgeLabelLayoutImpl ell1 = new EdgeLabelLayoutImpl();
139 ell1.setBox(new YRectangle(0,0,80,20));
140 //use a center slider edge model. the label will be placed on top of the
141 //edge owning the label.
142 ell1.setEdgeLabelModel(new SliderEdgeLabelModel(SliderEdgeLabelModel.CENTER_SLIDER));
143
144 EdgeLabelLayoutImpl ell2 = new EdgeLabelLayoutImpl();
145 ell2.setBox(new YRectangle(0,0,80,20));
146 //use a side slider model. the label will be placed to one of the sides of the
147 //edge owning the label.
148 ell2.setEdgeLabelModel(new SliderEdgeLabelModel(SliderEdgeLabelModel.SIDE_SLIDER));
149
150 EdgeLabelLayout[] ells = new EdgeLabelLayout[]{ell1, ell2};
151 graph.setLabelLayout(e1, ells);
152
153 IncrementalHierarchicLayouter layouter = new IncrementalHierarchicLayouter();
154 layouter.setLabelLayouterEnabled(true);
155 layouter.setLabelLayouter(new GreedyMISLabeling());
156
157 new BufferedLayouter(layouter).doLayout(graph);
158
159 //display result
160 LayoutPreviewPanel lpp1 = new LayoutPreviewPanel(new CopiedLayoutGraph(graph));
161 lpp1.createFrame("Hierarchical with general edge labeling").setVisible(true);
162
163 D.bug("\n\nGRAPH LAID OUT USING GENERAL EDGE LABELING");
164 D.bug("v1 center position = " + graph.getCenter(v1));
165 D.bug("v2 center position = " + graph.getCenter(v2));
166 D.bug("v3 center position = " + graph.getCenter(v3));
167 D.bug("e1 path = " + graph.getPath(e1));
168 D.bug("e2 path = " + graph.getPath(e2));
169 D.bug("e3 path = " + graph.getPath(e3));
170 D.bug("ell1 upper left location = " + getEdgeLabelLocation(graph,e1,ell1).getBoundingBox().getLocation());
171 D.bug("ell2 upper left location = " + getEdgeLabelLocation(graph,e1,ell2).getBoundingBox().getLocation());
172
173 EdgeLabelModel freeModel = new FreeEdgeLabelModel();
174 ell1.setEdgeLabelModel(freeModel);
175 ell1.setModelParameter(freeModel.getDefaultParameter());
176 ell2.setEdgeLabelModel(freeModel);
177 ell2.setModelParameter(freeModel.getDefaultParameter());
178
179 layouter = new IncrementalHierarchicLayouter();
180 layouter.setIntegratedEdgeLabelingEnabled(true);
181
182 new BufferedLayouter(layouter).doLayout(graph);
183
184 //display result
185 LayoutPreviewPanel lpp2 = new LayoutPreviewPanel(graph);
186 lpp2.createFrame("Hierarchical with internal labeling").setVisible(true);
187
188 D.bug("\n\nGRAPH LAID OUT USING HIERARCHIC LAYOUTER WITH INTERNAL EDGE LABELING");
189 D.bug("v1 center position = " + graph.getCenter(v1));
190 D.bug("v2 center position = " + graph.getCenter(v2));
191 D.bug("v3 center position = " + graph.getCenter(v3));
192 D.bug("e1 path = " + graph.getPath(e1));
193 D.bug("e2 path = " + graph.getPath(e2));
194 D.bug("e3 path = " + graph.getPath(e3));
195 D.bug("ell1 upper left location = " + getEdgeLabelLocation(graph,e1,ell1).getBoundingBox().getLocation());
196 D.bug("ell2 upper left location = " + getEdgeLabelLocation(graph,e1,ell2).getBoundingBox().getLocation());
197 }
198
199 /**
200 * Returns the calculated bounds of the edge label.
201 */
202 OrientedRectangle getEdgeLabelLocation(LayoutGraph graph, Edge e, EdgeLabelLayout ell)
203 {
204 OrientedRectangle orientedRectangle = ell.getLabelModel().getLabelPlacement(
205 ell.getOrientedBox().getSize(),
206 graph.getEdgeLayout(e),
207 graph.getNodeLayout(e.source()),
208 graph.getNodeLayout(e.target()),
209 ell.getModelParameter());
210 return orientedRectangle;
211 }
212 }
213