SquarifiedTreemapLayout.java 2.58 KB
Newer Older
Florian Grabowski's avatar
Florian Grabowski committed
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package de._82grfl1bif.KPI_Visualizer.layouts.TreeMap;

import de._82grfl1bif.KPI_Visualizer.structures.Foundation;
import de._82grfl1bif.KPI_Visualizer.structures.Structure;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class SquarifiedTreemapLayout {

    private ArrayList<Row> rows = new ArrayList<>();

    public ArrayList<Row> getRows() {
        return rows;
    }

    public SquarifiedTreemapLayout() {
        this.rows = new ArrayList<>();
    }

    public void generateLayout(Foundation foundation, Rectangle bounds) {
        rows.addAll(generateSubLayout(foundation, bounds));
        ArrayList<Foundation> foundations = new ArrayList<>();
        foundations.add(foundation);
        do {
            ArrayList<Row> tempRows = new ArrayList<>();
            rows.stream().filter(r -> r.rectangles.containsValue(foundations.get(foundations.size()-1))).forEach(row ->
                    tempRows.addAll(generateSubLayout(foundations.get(foundations.size()-1), new Rectangle(foundations.get(foundations.size()-1).getArea(), row.getWidth(), row.space.getOrigin()))));
            rows.addAll(tempRows);//letztes element bearbeitet und ein subLayout dafür angelegt.

            ArrayList<Foundation> tempFoundations = new ArrayList<>();
            for (Structure s : foundations.get(foundations.size() - 1).getChildren()) {
                if (s.getClass() == Foundation.class) {
                    tempFoundations.add((Foundation) s);
                }
            }
            foundations.remove(foundations.size()-1);
            foundations.addAll(tempFoundations);//alle Kinder(nur Foundations) des letzten Elements in die Liste geschrieben und das Element entfernt.

        } while (!foundations.isEmpty());
    }

    private ArrayList<Row> generateSubLayout(Foundation foundation, Rectangle rectangle) {
        ArrayList<Row> result = new ArrayList<>();
        result.add(new Row(rectangle));
        for (Structure s : foundation.getChildren()) {
            if (!result.get(result.size() - 1).checkInsert(s.getArea())) {//wenn einfügen in die bestehende Reihe das Seitenverhältnis verschlechtern würde.
                Row tempRow = new Row(result.get(result.size() - 1).getLeftover());//erzeige neue Reihe mit dem Rest des alten spaces als space.
                result.add(tempRow);//füge die neue Reihe ans Ende der Sammlung ein.
            }
            result.get(result.size() - 1).addRectangle(s.getArea(), s);//füge das Kind in die letzte Reihe ein, die in der Liste ist.
        }
        return result;
    }
}