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.ktreemap;
34
35 import java.util.ArrayList;
36 import java.util.List;
37
38 import org.eclipse.swt.graphics.Rectangle;
39
40 /**
41 * The Squarified split strategy
42 *
43 * @author Laurent DUTHEIL
44 */
45 public class SplitSquarified extends SplitStrategy {
46 private int w1, h1;
47 private int x, y, w, h;
48 private int x2, y2, w2, h2;
49
50 @Override
51 public void splitElements(List<TreeMapNode> list, List<TreeMapNode> group1,
52 List<TreeMapNode> group2) {
53 int mid = 0;
54 double weight0 = sumWeight(list);
55 double a = list.get(mid).getWeight() / weight0;
56 double b = a;
57
58 if (this.w < this.h) {
59
60 while (mid < list.size()) {
61 double aspect = normAspect(this.h, this.w, a, b);
62 double q = list.get(mid).getWeight() / weight0;
63 if (normAspect(this.h, this.w, a, b + q) > aspect) {
64 break;
65 }
66 mid++;
67 b += q;
68 }
69 int i = 0;
70 for (; i <= mid && i < list.size(); i++) {
71 group1.add(list.get(i));
72 }
73 for (; i < list.size(); i++) {
74 group2.add(list.get(i));
75 }
76 this.h1 = (int)Math.round(this.h * b);
77 this.w1 = this.w;
78 this.x2 = this.x;
79 this.y2 = (int)Math.round(this.y + this.h * b);
80 this.w2 = this.w;
81 this.h2 = this.h - this.h1;
82 } else {
83
84 while (mid < list.size()) {
85 double aspect = normAspect(this.w, this.h, a, b);
86 double q = list.get(mid).getWeight() / weight0;
87 if (normAspect(this.w, this.h, a, b + q) > aspect) {
88 break;
89 }
90 mid++;
91 b += q;
92 }
93 int i = 0;
94 for (; i <= mid && i < list.size(); i++) {
95 group1.add(list.get(i));
96 }
97 for (; i < list.size(); i++) {
98 group2.add(list.get(i));
99 }
100 this.h1 = this.h;
101 this.w1 = (int)Math.round(this.w * b);
102 this.x2 = (int)Math.round(this.x + this.w * b);
103 this.y2 = this.y;
104 this.w2 = this.w - this.w1;
105 this.h2 = this.h;
106 }
107 }
108
109
110
111
112
113
114
115 @Override
116 protected void calculatePositionsRec(Rectangle bounds, double weight0,
117 List<TreeMapNode> children) {
118 List<TreeMapNode> listClone = new ArrayList<TreeMapNode>(children);
119
120 sortList(listClone);
121
122 if (listClone.size() <= 2) {
123 SplitBySlice.splitInSlice(bounds, listClone, sumWeight(listClone));
124 calculateChildren(listClone);
125 } else {
126 List<TreeMapNode> l1 = new ArrayList<TreeMapNode>();
127 List<TreeMapNode> l2 = new ArrayList<TreeMapNode>();
128 this.x = bounds.x;
129 this.y = bounds.y;
130 this.w = bounds.width;
131 this.h = bounds.height;
132 splitElements(listClone, l1, l2);
133
134 int x2 = this.x2;
135 int y2 = this.y2;
136 int w2 = this.w2;
137 int h2 = this.h2;
138 Rectangle bounds1 = new Rectangle(bounds.x, bounds.y, this.w1, this.h1);
139 SplitBySlice.splitInSlice(bounds1, l1, sumWeight(l1));
140 calculateChildren(l1);
141 Rectangle bounds2 = new Rectangle(x2, y2, w2, h2);
142 calculatePositionsRec(bounds2, sumWeight(l2), l2);
143 }
144
145 }
146
147 private double aspect(double big, double small, double a, double b) {
148 return (big * b) / (small * a / b);
149 }
150
151 /**
152 * Execute the recurence for the children of the elements of the vector.<BR>
153 * Add also the borders if necessary
154 *
155 * @param v Vector with the elements to calculate
156 */
157 private void calculateChildren(List<TreeMapNode> v) {
158 for (TreeMapNode node : v) {
159 if (node.isLeaf()) {
160 node.setX(node.getX() + TreeMapNode.getBorder());
161 node.setY(node.getY() + TreeMapNode.getBorder());
162 int w = node.getWidth() - TreeMapNode.getBorder();
163 if (w < 0) {
164 w = 0;
165 }
166 int h = node.getHeight() - TreeMapNode.getBorder();
167 if (h < 0) {
168 h = 0;
169 }
170 node.setHeight(h);
171 node.setWidth(w);
172 } else {
173
174 int bSub;
175 if (TreeMapNode.getBorder() > 1) {
176 bSub = 2;
177 } else if (TreeMapNode.getBorder() == 1) {
178 bSub = 1;
179 } else {
180 bSub = 0;
181 }
182
183 int w = node.getWidth() - bSub;
184 if (w < 0) {
185 w = 0;
186 }
187 int h = node.getHeight() - bSub;
188 if (h < 0) {
189 h = 0;
190 }
191
192 TreeMapNode.setBorder(TreeMapNode.getBorder() - bSub);
193 Rectangle newBounds = new Rectangle(node.getX() + bSub, node.getY()
194 + bSub, w, h);
195 calculatePositionsRec(newBounds, node.getWeight(), node.getChildren());
196 TreeMapNode.setBorder(TreeMapNode.getBorder() + bSub);
197 }
198
199 }
200 }
201
202 private double normAspect(double big, double small, double a, double b) {
203 double x = aspect(big, small, a, b);
204 if (x < 1) {
205 return 1 / x;
206 }
207 return x;
208 }
209
210 }
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226