1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 package net.sf.jtreemap.swing;
34
35 import java.util.Vector;
36
37 /**
38 * The Squarified split strategy
39 *
40 * @author Laurent DUTHEIL
41 */
42 public class SplitSquarified extends SplitStrategy {
43 /**
44 *
45 */
46 private static final long serialVersionUID = 1711898915283018450L;
47
48 private int w1;
49
50 private int h1;
51
52 private int x;
53
54 private int y;
55
56 private int w;
57
58 private int h;
59
60 private int x2;
61
62 private int y2;
63
64 private int w2;
65
66 private int h2;
67
68 @Override
69 public void splitElements(final Vector<TreeMapNode> v, final Vector<TreeMapNode> v1, final Vector<TreeMapNode> v2) {
70 int mid = 0;
71 final double weight0 = sumWeight(v);
72 final double a = v.get(mid).getWeight() / weight0;
73 double b = a;
74
75 if (this.w < this.h) {
76
77 while (mid < v.size()) {
78 final double aspect = normAspect(this.h, this.w, a, b);
79 final double q = v.get(mid).getWeight() / weight0;
80 if (normAspect(this.h, this.w, a, b + q) > aspect) {
81 break;
82 }
83 mid++;
84 b += q;
85 }
86 int i = 0;
87 for (; i <= mid && i < v.size(); i++) {
88 v1.add(v.get(i));
89 }
90 for (; i < v.size(); i++) {
91 v2.add(v.get(i));
92 }
93 this.h1 = (int) Math.round(this.h * b);
94 this.w1 = this.w;
95 this.x2 = this.x;
96 this.y2 = (int) Math.round(this.y + this.h * b);
97 this.w2 = this.w;
98 this.h2 = this.h - this.h1;
99 } else {
100
101 while (mid < v.size()) {
102 final double aspect = normAspect(this.w, this.h, a, b);
103 final double q = v.get(mid).getWeight() / weight0;
104 if (normAspect(this.w, this.h, a, b + q) > aspect) {
105 break;
106 }
107 mid++;
108 b += q;
109 }
110 int i = 0;
111 for (; i <= mid && i < v.size(); i++) {
112 v1.add(v.get(i));
113 }
114 for (; i < v.size(); i++) {
115 v2.add(v.get(i));
116 }
117 this.h1 = this.h;
118 this.w1 = (int) Math.round(this.w * b);
119 this.x2 = (int) Math.round(this.x + this.w * b);
120 this.y2 = this.y;
121 this.w2 = this.w - this.w1;
122 this.h2 = this.h;
123 }
124 }
125
126
127
128
129
130
131
132 @Override
133 protected void calculatePositionsRec(final int x0, final int y0, final int w0, final int h0, final double weight0,
134 final Vector<TreeMapNode> v) {
135 final Vector<TreeMapNode> vClone = new Vector<TreeMapNode>(v);
136
137 sortVector(vClone);
138
139 if (vClone.size() <= 2) {
140 SplitBySlice.splitInSlice(x0, y0, w0, h0, vClone, sumWeight(vClone));
141 calculateChildren(vClone);
142 } else {
143 final Vector<TreeMapNode> v1 = new Vector<TreeMapNode>();
144 final Vector<TreeMapNode> v2 = new Vector<TreeMapNode>();
145 this.x = x0;
146 this.y = y0;
147 this.w = w0;
148 this.h = h0;
149 splitElements(vClone, v1, v2);
150
151
152 final int prevX2 = this.x2;
153 final int prevY2 = this.y2;
154 final int prevW2 = this.w2;
155 final int prevH2 = this.h2;
156 SplitBySlice.splitInSlice(x0, y0, this.w1, this.h1, v1, sumWeight(v1));
157 calculateChildren(v1);
158 calculatePositionsRec(prevX2, prevY2, prevW2, prevH2, sumWeight(v2), v2);
159 }
160
161 }
162
163 private double aspect(final double big, final double small, final double a, final double b) {
164 return (big * b) / (small * a / b);
165 }
166
167 /**
168 * Execute the recurence for the children of the elements of the vector.<BR>
169 * Add also the borders if necessary
170 *
171 * @param v
172 * Vector with the elements to calculate
173 */
174 private void calculateChildren(final Vector<TreeMapNode> v) {
175 for (final TreeMapNode node : v) {
176 if (node.isLeaf()) {
177 node.setX(node.getX() + TreeMapNode.getBorder());
178 node.setY(node.getY() + TreeMapNode.getBorder());
179 int width = node.getWidth() - TreeMapNode.getBorder();
180 if (width < 0) {
181 width = 0;
182 }
183 int height = node.getHeight() - TreeMapNode.getBorder();
184 if (height < 0) {
185 height = 0;
186 }
187 node.setHeight(height);
188 node.setWidth(width);
189 } else {
190
191 int bSub;
192 if (TreeMapNode.getBorder() > 1) {
193 bSub = 2;
194 } else if (TreeMapNode.getBorder() == 1) {
195 bSub = 1;
196 } else {
197 bSub = 0;
198 }
199
200 int width = node.getWidth() - bSub;
201 if (width < 0) {
202 width = 0;
203 }
204 int height = node.getHeight() - bSub;
205 if (height < 0) {
206 height = 0;
207 }
208
209 TreeMapNode.setBorder(TreeMapNode.getBorder() - bSub);
210 calculatePositionsRec(node.getX() + bSub, node.getY() + bSub, width, height, node.getWeight(), node.getChildren());
211 TreeMapNode.setBorder(TreeMapNode.getBorder() + bSub);
212 }
213
214 }
215 }
216
217 private double normAspect(final double big, final double small, final double a, final double b) {
218 final double xCalc = aspect(big, small, a, b);
219 if (xCalc < 1) {
220 return 1 / xCalc;
221 }
222 return xCalc;
223 }
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240