1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dishevelled.piccolo.venn;
25
26 import java.awt.BasicStroke;
27 import java.awt.Color;
28 import java.awt.Paint;
29 import java.awt.Stroke;
30 import java.awt.geom.AffineTransform;
31 import java.awt.geom.Area;
32 import java.awt.geom.Ellipse2D;
33 import java.awt.geom.Point2D;
34 import java.awt.geom.Rectangle2D;
35 import java.util.Arrays;
36 import java.util.List;
37 import java.util.Set;
38 import java.util.concurrent.Executors;
39 import java.util.concurrent.ExecutorService;
40
41 import javax.swing.SwingWorker;
42
43 import org.piccolo2d.PNode;
44 import org.piccolo2d.nodes.PArea;
45 import org.piccolo2d.nodes.PPath;
46 import org.piccolo2d.nodes.PText;
47 import org.dishevelled.venn.QuaternaryVennModel;
48
49
50
51
52
53
54
55
56 public class QuaternaryVennNode<E>
57 extends AbstractQuaternaryVennNode<E>
58 {
59
60 private final PPath first = new PPath.Double(STROKE);
61
62
63 private final PArea firstOnly = new PArea(AREA_STROKE);
64
65
66 private final PText firstOnlySize = new PText();
67
68
69 private final PPath second = new PPath.Double(STROKE);
70
71
72 private final PArea secondOnly = new PArea(AREA_STROKE);
73
74
75 private final PText secondOnlySize = new PText();
76
77
78 private final PPath third = new PPath.Double(STROKE);
79
80
81 private final PArea thirdOnly = new PArea(AREA_STROKE);
82
83
84 private final PText thirdOnlySize = new PText();
85
86
87 private final PPath fourth = new PPath.Double(STROKE);
88
89
90 private final PArea fourthOnly = new PArea(AREA_STROKE);
91
92
93 private final PText fourthOnlySize = new PText();
94
95
96 private final PArea firstSecond = new PArea(AREA_STROKE);
97
98
99 private final PText firstSecondSize = new PText();
100
101
102 private final PArea firstThird = new PArea(AREA_STROKE);
103
104
105 private final PText firstThirdSize = new PText();
106
107
108 private final PArea secondThird = new PArea(AREA_STROKE);
109
110
111 private final PText secondThirdSize = new PText();
112
113
114 private final PArea firstFourth = new PArea(AREA_STROKE);
115
116
117 private final PText firstFourthSize = new PText();
118
119
120 private final PArea secondFourth = new PArea(AREA_STROKE);
121
122
123 private final PText secondFourthSize = new PText();
124
125
126 private final PArea thirdFourth = new PArea(AREA_STROKE);
127
128
129 private final PText thirdFourthSize = new PText();
130
131
132 private final PArea firstSecondThird = new PArea(AREA_STROKE);
133
134
135 private final PText firstSecondThirdSize = new PText();
136
137
138 private final PArea firstSecondFourth = new PArea(AREA_STROKE);
139
140
141 private final PText firstSecondFourthSize = new PText();
142
143
144 private final PArea firstThirdFourth = new PArea(AREA_STROKE);
145
146
147 private final PText firstThirdFourthSize = new PText();
148
149
150 private final PArea secondThirdFourth = new PArea(AREA_STROKE);
151
152
153 private final PText secondThirdFourthSize = new PText();
154
155
156 private final PArea intersection = new PArea(AREA_STROKE);
157
158
159 private final PText intersectionSize = new PText();
160
161
162 private final List<PNode> nodes = Arrays.asList(new PNode[] { firstOnly, secondOnly, thirdOnly, fourthOnly,
163 firstSecond, firstThird, secondThird, firstFourth,
164 secondFourth, thirdFourth, firstSecondThird,
165 firstSecondFourth, firstThirdFourth,
166 secondThirdFourth, intersection });
167
168
169 private final List<PText> sizeLabels = Arrays.asList(new PText[] { firstOnlySize, secondOnlySize, thirdOnlySize, fourthOnlySize,
170 firstSecondSize, firstThirdSize, secondThirdSize, firstFourthSize,
171 secondFourthSize, thirdFourthSize, firstSecondThirdSize,
172 firstSecondFourthSize, firstThirdFourthSize,
173 secondThirdFourthSize, intersectionSize });
174
175
176 private Area f;
177
178
179 private Area s;
180
181
182 private Area t;
183
184
185 private Area r;
186
187
188 private Rectangle2D a = new Rectangle2D.Double();
189
190
191 private Rectangle2D b = new Rectangle2D.Double();
192
193
194 private Point2D c = new Point2D.Double();
195
196
197 private static final double LABEL_GAP = 8.0d;
198
199
200 private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(2);
201
202
203 private static final long MS = 2000L;
204
205
206 private static final Paint FIRST_PAINT = new Color(30, 30, 30, 50);
207
208
209 private static final Paint SECOND_PAINT = new Color(5, 37, 255, 50);
210
211
212 private static final Paint THIRD_PAINT = new Color(255, 100, 5, 50);
213
214
215 private static final Paint FOURTH_PAINT = new Color(11, 255, 5, 50);
216
217
218 private static final Stroke STROKE = new BasicStroke(0.5f);
219
220
221 private static final Paint STROKE_PAINT = new Color(20, 20, 20);
222
223
224 private static final Paint AREA_PAINT = new Color(0, 0, 0, 0);
225
226
227 private static final Stroke AREA_STROKE = null;
228
229
230
231
232
233 public QuaternaryVennNode()
234 {
235 super();
236 initNodes();
237 updateContents();
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251
252 public QuaternaryVennNode(final String firstLabelText, final Set<? extends E> first,
253 final String secondLabelText, final Set<? extends E> second,
254 final String thirdLabelText, final Set<? extends E> third,
255 final String fourthLabelText, final Set<? extends E> fourth)
256 {
257 super(firstLabelText, first, secondLabelText, second, thirdLabelText, third, fourthLabelText, fourth);
258 initNodes();
259 updateContents();
260 }
261
262
263
264
265
266
267 public QuaternaryVennNode(final QuaternaryVennModel<E> model)
268 {
269 super(model);
270 initNodes();
271 updateContents();
272 }
273
274
275
276
277
278 private void initNodes()
279 {
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294 Ellipse2D ellipse = new Ellipse2D.Double(0.0d, 0.0d, 376.0d, 234.0d);
295 c.setLocation(ellipse.getBounds2D().getCenterX(), ellipse.getBounds2D().getCenterY());
296
297 f = new Area(ellipse);
298 f = f.createTransformedArea(AffineTransform.getRotateInstance((2.0d * Math.PI) / 9.0d, c.getX(), c.getY()));
299 first.append(f, false);
300 first.setPaint(FIRST_PAINT);
301 first.setStrokePaint(STROKE_PAINT);
302
303 s = new Area(ellipse);
304 s = s.createTransformedArea(AffineTransform.getRotateInstance((2.0d * Math.PI) / 9.0d, c.getX(), c.getY()));
305 s = s.createTransformedArea(AffineTransform.getTranslateInstance(72.0d, -85.0d));
306 second.append(s, false);
307 second.setPaint(SECOND_PAINT);
308 second.setStrokePaint(STROKE_PAINT);
309
310 t = new Area(ellipse);
311 t = t.createTransformedArea(AffineTransform.getRotateInstance((-2.0d * Math.PI) / 9.0d, c.getX(), c.getY()));
312 t = t.createTransformedArea(AffineTransform.getTranslateInstance(72.0d, -85.0d));
313 third.append(t, false);
314 third.setPaint(THIRD_PAINT);
315 third.setStrokePaint(STROKE_PAINT);
316
317 r = new Area(ellipse);
318 r = r.createTransformedArea(AffineTransform.getRotateInstance((-2.0d * Math.PI) / 9.0d, c.getX(), c.getY()));
319 r = r.createTransformedArea(AffineTransform.getTranslateInstance(144.0d, 0.0d));
320 fourth.append(r, false);
321 fourth.setPaint(FOURTH_PAINT);
322 fourth.setStrokePaint(STROKE_PAINT);
323
324 firstOnly.setPaint(AREA_PAINT);
325 secondOnly.setPaint(AREA_PAINT);
326 thirdOnly.setPaint(AREA_PAINT);
327 fourthOnly.setPaint(AREA_PAINT);
328 firstSecond.setPaint(AREA_PAINT);
329 firstThird.setPaint(AREA_PAINT);
330 secondThird.setPaint(AREA_PAINT);
331 firstFourth.setPaint(AREA_PAINT);
332 secondFourth.setPaint(AREA_PAINT);
333 thirdFourth.setPaint(AREA_PAINT);
334 firstSecondThird.setPaint(AREA_PAINT);
335 firstSecondFourth.setPaint(AREA_PAINT);
336 firstThirdFourth.setPaint(AREA_PAINT);
337 secondThirdFourth.setPaint(AREA_PAINT);
338 intersection.setPaint(AREA_PAINT);
339
340 addChild(first);
341 addChild(second);
342 addChild(third);
343 addChild(fourth);
344 addChild(firstOnlySize);
345 addChild(secondOnlySize);
346 addChild(thirdOnlySize);
347 addChild(fourthOnlySize);
348 addChild(firstSecondSize);
349 addChild(firstThirdSize);
350 addChild(secondThirdSize);
351 addChild(firstFourthSize);
352 addChild(secondFourthSize);
353 addChild(thirdFourthSize);
354 addChild(firstSecondThirdSize);
355 addChild(firstSecondFourthSize);
356 addChild(firstThirdFourthSize);
357 addChild(secondThirdFourthSize);
358 addChild(intersectionSize);
359 addChild(firstOnly);
360 addChild(secondOnly);
361 addChild(thirdOnly);
362 addChild(fourthOnly);
363 addChild(firstSecond);
364 addChild(firstThird);
365 addChild(secondThird);
366 addChild(firstFourth);
367 addChild(secondFourth);
368 addChild(thirdFourth);
369 addChild(firstSecondThird);
370 addChild(firstSecondFourth);
371 addChild(firstThirdFourth);
372 addChild(secondThirdFourth);
373 addChild(intersection);
374 addChild(getFirstLabel());
375 addChild(getSecondLabel());
376 addChild(getThirdLabel());
377 addChild(getFourthLabel());
378 }
379
380 @Override
381 protected void updateLabels()
382 {
383 super.updateLabels();
384
385 if (firstOnlySize != null)
386 {
387 firstOnlySize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstOnly().isEmpty()));
388 secondOnlySize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().secondOnly().isEmpty()));
389 thirdOnlySize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().thirdOnly().isEmpty()));
390 fourthOnlySize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().thirdOnly().isEmpty()));
391 firstSecondSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstSecond().isEmpty()));
392 firstThirdSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstThird().isEmpty()));
393 secondThirdSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().secondThird().isEmpty()));
394 firstFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstFourth().isEmpty()));
395 secondFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().secondFourth().isEmpty()));
396 thirdFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().thirdFourth().isEmpty()));
397 firstSecondThirdSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstSecondThird().isEmpty()));
398 firstSecondFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstSecondFourth().isEmpty()));
399 firstThirdFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstThirdFourth().isEmpty()));
400 secondThirdFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().secondThirdFourth().isEmpty()));
401 intersectionSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().intersection().isEmpty()));
402 }
403 }
404
405 @Override
406 protected void updateContents()
407 {
408 firstOnlySize.setText(String.valueOf(getModel().firstOnly().size()));
409 secondOnlySize.setText(String.valueOf(getModel().secondOnly().size()));
410 thirdOnlySize.setText(String.valueOf(getModel().thirdOnly().size()));
411 fourthOnlySize.setText(String.valueOf(getModel().fourthOnly().size()));
412 firstSecondSize.setText(String.valueOf(getModel().firstSecond().size()));
413 firstThirdSize.setText(String.valueOf(getModel().firstThird().size()));
414 secondThirdSize.setText(String.valueOf(getModel().secondThird().size()));
415 firstFourthSize.setText(String.valueOf(getModel().firstFourth().size()));
416 secondFourthSize.setText(String.valueOf(getModel().secondFourth().size()));
417 thirdFourthSize.setText(String.valueOf(getModel().thirdFourth().size()));
418 firstSecondThirdSize.setText(String.valueOf(getModel().firstSecondThird().size()));
419 firstSecondFourthSize.setText(String.valueOf(getModel().firstSecondFourth().size()));
420 firstThirdFourthSize.setText(String.valueOf(getModel().firstThirdFourth().size()));
421 secondThirdFourthSize.setText(String.valueOf(getModel().secondThirdFourth().size()));
422 intersectionSize.setText(String.valueOf(getModel().intersection().size()));
423
424 firstOnlySize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstOnly().isEmpty()));
425 secondOnlySize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().secondOnly().isEmpty()));
426 thirdOnlySize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().thirdOnly().isEmpty()));
427 fourthOnlySize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().thirdOnly().isEmpty()));
428 firstSecondSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstSecond().isEmpty()));
429 firstThirdSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstThird().isEmpty()));
430 secondThirdSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().secondThird().isEmpty()));
431 firstFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstFourth().isEmpty()));
432 secondFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().secondFourth().isEmpty()));
433 thirdFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().thirdFourth().isEmpty()));
434 firstSecondThirdSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstSecondThird().isEmpty()));
435 firstSecondFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstSecondFourth().isEmpty()));
436 firstThirdFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().firstThirdFourth().isEmpty()));
437 secondThirdFourthSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().secondThirdFourth().isEmpty()));
438 intersectionSize.setVisible(getDisplaySizeLabels() && (getDisplaySizesForEmptyAreas() || !getModel().intersection().isEmpty()));
439
440 layoutNodes();
441 }
442
443
444
445
446
447 private void layoutNodes()
448 {
449 f = new Area(first.getPathReference());
450 s = new Area(second.getPathReference());
451 t = new Area(third.getPathReference());
452 r = new Area(fourth.getPathReference());
453
454 firstOnly.reset();
455 firstOnly.add(f);
456 firstOnly.subtract(s);
457 firstOnly.subtract(t);
458 firstOnly.subtract(r);
459
460 secondOnly.reset();
461 secondOnly.add(s);
462 secondOnly.subtract(f);
463 secondOnly.subtract(t);
464 secondOnly.subtract(r);
465
466 thirdOnly.reset();
467 thirdOnly.add(t);
468 thirdOnly.subtract(f);
469 thirdOnly.subtract(s);
470 thirdOnly.subtract(r);
471
472 fourthOnly.reset();
473 fourthOnly.add(r);
474 fourthOnly.subtract(f);
475 fourthOnly.subtract(s);
476 fourthOnly.subtract(t);
477
478 firstSecond.reset();
479 firstSecond.add(f);
480 firstSecond.intersect(s);
481 firstSecond.subtract(t);
482 firstSecond.subtract(r);
483
484 firstThird.reset();
485 firstThird.add(f);
486 firstThird.intersect(t);
487 firstThird.subtract(s);
488 firstThird.subtract(r);
489
490 firstFourth.reset();
491 firstFourth.add(f);
492 firstFourth.intersect(r);
493 firstFourth.subtract(s);
494 firstFourth.subtract(t);
495
496 secondThird.reset();
497 secondThird.add(s);
498 secondThird.intersect(t);
499 secondThird.subtract(f);
500 secondThird.subtract(r);
501
502 secondFourth.reset();
503 secondFourth.add(s);
504 secondFourth.intersect(r);
505 secondFourth.subtract(f);
506 secondFourth.subtract(t);
507
508 thirdFourth.reset();
509 thirdFourth.add(t);
510 thirdFourth.intersect(r);
511 thirdFourth.subtract(f);
512 thirdFourth.subtract(s);
513
514 firstSecondThird.reset();
515 firstSecondThird.add(f);
516 firstSecondThird.intersect(s);
517 firstSecondThird.intersect(t);
518 firstSecondThird.subtract(r);
519
520 firstSecondFourth.reset();
521 firstSecondFourth.add(f);
522 firstSecondFourth.intersect(s);
523 firstSecondFourth.intersect(r);
524 firstSecondFourth.subtract(t);
525
526 firstThirdFourth.reset();
527 firstThirdFourth.add(f);
528 firstThirdFourth.intersect(t);
529 firstThirdFourth.intersect(r);
530 firstThirdFourth.subtract(s);
531
532 secondThirdFourth.reset();
533 secondThirdFourth.add(s);
534 secondThirdFourth.intersect(t);
535 secondThirdFourth.intersect(r);
536 secondThirdFourth.subtract(f);
537
538 intersection.reset();
539 intersection.add(f);
540 intersection.intersect(s);
541 intersection.intersect(t);
542 intersection.intersect(r);
543
544
545 offset(firstOnly.getAreaReference(), firstOnlySize);
546 offset(secondOnly.getAreaReference(), secondOnlySize);
547 offset(thirdOnly.getAreaReference(), thirdOnlySize);
548 offset(fourthOnly.getAreaReference(), fourthOnlySize);
549 offset(firstSecond.getAreaReference(), firstSecondSize);
550 offset(firstThird.getAreaReference(), firstThirdSize);
551 offset(secondThird.getAreaReference(), secondThirdSize);
552 offset(firstFourth.getAreaReference(), firstFourthSize);
553 offset(secondFourth.getAreaReference(), secondFourthSize);
554 offset(thirdFourth.getAreaReference(), thirdFourthSize);
555 offset(firstSecondThird.getAreaReference(), firstSecondThirdSize);
556 offset(firstSecondFourth.getAreaReference(), firstSecondFourthSize);
557 offset(firstThirdFourth.getAreaReference(), firstThirdFourthSize);
558 offset(secondThirdFourth.getAreaReference(), secondThirdFourthSize);
559 offset(intersection.getAreaReference(), intersectionSize);
560
561
562 EXECUTOR_SERVICE.submit(new LayoutWorker(firstOnly.getAreaReference(), firstOnlySize));
563 EXECUTOR_SERVICE.submit(new LayoutWorker(secondOnly.getAreaReference(), secondOnlySize));
564 EXECUTOR_SERVICE.submit(new LayoutWorker(thirdOnly.getAreaReference(), thirdOnlySize));
565 EXECUTOR_SERVICE.submit(new LayoutWorker(fourthOnly.getAreaReference(), fourthOnlySize));
566 EXECUTOR_SERVICE.submit(new LayoutWorker(firstSecond.getAreaReference(), firstSecondSize));
567 EXECUTOR_SERVICE.submit(new LayoutWorker(firstThird.getAreaReference(), firstThirdSize));
568 EXECUTOR_SERVICE.submit(new LayoutWorker(secondThird.getAreaReference(), secondThirdSize));
569 EXECUTOR_SERVICE.submit(new LayoutWorker(firstFourth.getAreaReference(), firstFourthSize));
570 EXECUTOR_SERVICE.submit(new LayoutWorker(secondFourth.getAreaReference(), secondFourthSize));
571 EXECUTOR_SERVICE.submit(new LayoutWorker(thirdFourth.getAreaReference(), thirdFourthSize));
572 EXECUTOR_SERVICE.submit(new LayoutWorker(firstSecondThird.getAreaReference(), firstSecondThirdSize));
573 EXECUTOR_SERVICE.submit(new LayoutWorker(firstSecondFourth.getAreaReference(), firstSecondFourthSize));
574 EXECUTOR_SERVICE.submit(new LayoutWorker(firstThirdFourth.getAreaReference(), firstThirdFourthSize));
575 EXECUTOR_SERVICE.submit(new LayoutWorker(secondThirdFourth.getAreaReference(), secondThirdFourthSize));
576 EXECUTOR_SERVICE.submit(new LayoutWorker(intersection.getAreaReference(), intersectionSize));
577
578 labelFarLeft(firstOnly.getAreaReference(), secondOnly.getAreaReference(), getFirstLabel());
579 labelLeft(secondOnly.getAreaReference(), getSecondLabel());
580 labelRight(thirdOnly.getAreaReference(), getThirdLabel());
581 labelFarRight(fourthOnly.getAreaReference(), thirdOnly.getAreaReference(), getFourthLabel());
582 }
583
584
585
586
587
588
589
590 private void offset(final Area area, final PText size)
591 {
592 b = size.getFullBoundsReference();
593 c = Centers.centerOf(area, c);
594 size.setOffset(c.getX() - (b.getWidth() / 2.0d), c.getY() - (b.getHeight() / 2.0d));
595 }
596
597
598
599
600
601
602
603 private void labelLeft(final Area area, final PText label)
604 {
605 a = area.getBounds2D();
606 b = label.getFullBoundsReference();
607 c = Centers.centerOf(area, c);
608 label.setOffset(c.getX() - ((2.0d * b.getWidth()) / 3.0d), a.getY() - b.getHeight() - LABEL_GAP);
609 }
610
611
612
613
614
615
616
617 private void labelRight(final Area area, final PText label)
618 {
619 a = area.getBounds2D();
620 b = label.getFullBoundsReference();
621 c = Centers.centerOf(area, c);
622 label.setOffset(c.getX() - (b.getWidth() / 3.0d), a.getY() - b.getHeight() - LABEL_GAP);
623 }
624
625
626
627
628
629
630
631
632
633 private void labelFarLeft(final Area area0, final Area area1, final PText label)
634 {
635 a = area0.getBounds2D();
636 b = label.getFullBoundsReference();
637 c = Centers.centerOf(area0, c);
638 double y = a.getY() - b.getHeight() - LABEL_GAP;
639 a = area1.getBounds2D();
640 double left = c.getX() - ((2.0d * b.getWidth()) / 3.0d);
641 double farLeft = a.getX() - b.getWidth() - LABEL_GAP;
642 label.setOffset(Math.min(left, farLeft), y);
643 }
644
645
646
647
648
649
650
651
652
653 private void labelFarRight(final Area area0, final Area area1, final PText label)
654 {
655 a = area0.getBounds2D();
656 b = label.getFullBoundsReference();
657 c = Centers.centerOf(area0, c);
658 double y = a.getY() - b.getHeight() - LABEL_GAP;
659 a = area1.getBounds2D();
660 double right = c.getX() - ((2.0d * b.getWidth()) / 3.0d);
661 double farRight = a.getX() + a.getWidth() + LABEL_GAP;
662 label.setOffset(Math.max(right, farRight), y);
663 }
664
665
666
667
668
669
670 public PPath getFirst()
671 {
672 return first;
673 }
674
675
676
677
678
679
680 public PPath getSecond()
681 {
682 return second;
683 }
684
685
686
687
688
689
690 public PPath getThird()
691 {
692 return third;
693 }
694
695
696
697
698
699
700 public PPath getFourth()
701 {
702 return fourth;
703 }
704
705
706
707
708
709
710 public PArea getFirstOnly()
711 {
712 return firstOnly;
713 }
714
715
716
717
718
719
720 public PArea getSecondOnly()
721 {
722 return secondOnly;
723 }
724
725
726
727
728
729
730 public PArea getThirdOnly()
731 {
732 return thirdOnly;
733 }
734
735
736
737
738
739
740 public PArea getFourthOnly()
741 {
742 return fourthOnly;
743 }
744
745
746
747
748
749
750 public PArea getFirstSecond()
751 {
752 return firstSecond;
753 }
754
755
756
757
758
759
760 public PArea getFirstThird()
761 {
762 return firstThird;
763 }
764
765
766
767
768
769
770 public PArea getSecondThird()
771 {
772 return secondThird;
773 }
774
775
776
777
778
779
780 public PArea getFirstFourth()
781 {
782 return firstFourth;
783 }
784
785
786
787
788
789
790 public PArea getSecondFourth()
791 {
792 return secondFourth;
793 }
794
795
796
797
798
799
800 public PArea getThirdFourth()
801 {
802 return thirdFourth;
803 }
804
805
806
807
808
809
810 public PArea getFirstSecondThird()
811 {
812 return firstSecondThird;
813 }
814
815
816
817
818
819
820 public PArea getFirstSecondFourth()
821 {
822 return firstSecondFourth;
823 }
824
825
826
827
828
829
830 public PArea getFirstThirdFourth()
831 {
832 return firstThirdFourth;
833 }
834
835
836
837
838
839
840 public PArea getSecondThirdFourth()
841 {
842 return secondThirdFourth;
843 }
844
845
846
847
848
849
850 public PArea getIntersection()
851 {
852 return intersection;
853 }
854
855 @Override
856 public Iterable<PNode> nodes()
857 {
858 return nodes;
859 }
860
861 @Override
862 public PText labelForNode(final PNode node)
863 {
864 if (firstOnly.equals(node))
865 {
866 return getFirstOnlyLabel();
867 }
868 else if (secondOnly.equals(node))
869 {
870 return getSecondOnlyLabel();
871 }
872 else if (thirdOnly.equals(node))
873 {
874 return getThirdOnlyLabel();
875 }
876 else if (fourthOnly.equals(node))
877 {
878 return getFourthOnlyLabel();
879 }
880 else if (firstSecond.equals(node))
881 {
882 return getFirstSecondLabel();
883 }
884 else if (firstThird.equals(node))
885 {
886 return getFirstThirdLabel();
887 }
888 else if (secondThird.equals(node))
889 {
890 return getSecondThirdLabel();
891 }
892 else if (firstFourth.equals(node))
893 {
894 return getFirstFourthLabel();
895 }
896 else if (secondFourth.equals(node))
897 {
898 return getSecondFourthLabel();
899 }
900 else if (thirdFourth.equals(node))
901 {
902 return getThirdFourthLabel();
903 }
904 else if (firstSecondThird.equals(node))
905 {
906 return getFirstSecondThirdLabel();
907 }
908 else if (firstSecondFourth.equals(node))
909 {
910 return getFirstSecondFourthLabel();
911 }
912 else if (firstThirdFourth.equals(node))
913 {
914 return getFirstThirdFourthLabel();
915 }
916 else if (secondThirdFourth.equals(node))
917 {
918 return getSecondThirdFourthLabel();
919 }
920 else if (intersection.equals(node))
921 {
922 return getIntersectionLabel();
923 }
924 return null;
925 }
926
927 @Override
928 public String labelTextForNode(final PNode node)
929 {
930 if (firstOnly.equals(node))
931 {
932 return getFirstOnlyLabelText();
933 }
934 else if (secondOnly.equals(node))
935 {
936 return getSecondOnlyLabelText();
937 }
938 else if (thirdOnly.equals(node))
939 {
940 return getThirdOnlyLabelText();
941 }
942 else if (fourthOnly.equals(node))
943 {
944 return getFourthOnlyLabelText();
945 }
946 else if (firstSecond.equals(node))
947 {
948 return getFirstSecondLabelText();
949 }
950 else if (firstThird.equals(node))
951 {
952 return getFirstThirdLabelText();
953 }
954 else if (secondThird.equals(node))
955 {
956 return getSecondThirdLabelText();
957 }
958 else if (firstFourth.equals(node))
959 {
960 return getFirstFourthLabelText();
961 }
962 else if (secondFourth.equals(node))
963 {
964 return getSecondFourthLabelText();
965 }
966 else if (thirdFourth.equals(node))
967 {
968 return getThirdFourthLabelText();
969 }
970 else if (firstSecondThird.equals(node))
971 {
972 return getFirstSecondThirdLabelText();
973 }
974 else if (firstSecondFourth.equals(node))
975 {
976 return getFirstSecondFourthLabelText();
977 }
978 else if (firstThirdFourth.equals(node))
979 {
980 return getFirstThirdFourthLabelText();
981 }
982 else if (secondThirdFourth.equals(node))
983 {
984 return getSecondThirdFourthLabelText();
985 }
986 else if (intersection.equals(node))
987 {
988 return getIntersectionLabelText();
989 }
990 return null;
991 }
992
993 @Override
994 public Iterable<PText> sizeLabels()
995 {
996 return sizeLabels;
997 }
998
999 @Override
1000 public Set<E> viewForNode(final PNode node)
1001 {
1002 if (firstOnly.equals(node))
1003 {
1004 return getModel().firstOnly();
1005 }
1006 else if (secondOnly.equals(node))
1007 {
1008 return getModel().secondOnly();
1009 }
1010 else if (thirdOnly.equals(node))
1011 {
1012 return getModel().thirdOnly();
1013 }
1014 else if (fourthOnly.equals(node))
1015 {
1016 return getModel().fourthOnly();
1017 }
1018 else if (firstSecond.equals(node))
1019 {
1020 return getModel().firstSecond();
1021 }
1022 else if (firstThird.equals(node))
1023 {
1024 return getModel().firstThird();
1025 }
1026 else if (secondThird.equals(node))
1027 {
1028 return getModel().secondThird();
1029 }
1030 else if (firstFourth.equals(node))
1031 {
1032 return getModel().firstFourth();
1033 }
1034 else if (secondFourth.equals(node))
1035 {
1036 return getModel().secondFourth();
1037 }
1038 else if (thirdFourth.equals(node))
1039 {
1040 return getModel().thirdFourth();
1041 }
1042 else if (firstSecondThird.equals(node))
1043 {
1044 return getModel().firstSecondThird();
1045 }
1046 else if (firstSecondFourth.equals(node))
1047 {
1048 return getModel().firstSecondFourth();
1049 }
1050 else if (firstThirdFourth.equals(node))
1051 {
1052 return getModel().firstThirdFourth();
1053 }
1054 else if (secondThirdFourth.equals(node))
1055 {
1056 return getModel().secondThirdFourth();
1057 }
1058 else if (intersection.equals(node))
1059 {
1060 return getModel().intersection();
1061 }
1062 return null;
1063 }
1064
1065
1066
1067
1068
1069 private final class LayoutWorker
1070 extends SwingWorker<Point2D, Object>
1071 {
1072
1073 private Area area;
1074
1075
1076 private PText size;
1077
1078
1079
1080
1081
1082
1083
1084
1085 private LayoutWorker(final Area area, final PText size)
1086 {
1087 this.area = area;
1088 this.size = size;
1089 }
1090
1091
1092 @Override
1093 public Point2D doInBackground()
1094 {
1095 return Centers.centroidOf(area);
1096 }
1097
1098 @Override
1099 protected void done()
1100 {
1101 try
1102 {
1103 Rectangle2D bounds = size.getFullBoundsReference();
1104 Point2D centroid = get();
1105 size.animateToPositionScaleRotation(centroid.getX() - (bounds.getWidth() / 2.0d),
1106 centroid.getY() - (bounds.getHeight() / 2.0d), 1.0d, 0.0d, MS);
1107 }
1108 catch (Exception e)
1109 {
1110
1111 }
1112 }
1113 }
1114 }