summaryrefslogtreecommitdiff
path: root/src/main/java/com/c2kernel/graph/layout/DefaultGraphLayoutGenerator.java
blob: 253306673db38b8a040534dfef18740ccd8262f6 (plain)
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package com.c2kernel.graph.layout;

import java.util.Vector;

import com.c2kernel.graph.model.DirectedEdge;
import com.c2kernel.graph.model.GraphModel;
import com.c2kernel.graph.model.GraphPoint;
import com.c2kernel.graph.model.Vertex;
import com.c2kernel.utils.Logger;

public class DefaultGraphLayoutGenerator {
    private static int mTopMargin = 100;
    private static int mLeftMargin = 100;
    private static int mHorzGap = 180;
    private static int mVertGap = 100;

    private DefaultGraphLayoutGenerator() {
    }

    public static void layoutGraph(GraphModel graphModel) {
        Vertex start = graphModel.getStartVertex();
        Vector<Vector<Vertex>> rowVector = new Vector<Vector<Vertex>>(10, 10);
        int[] midPoints = null;
        int valueOfLargestMidPoint = 0;
        if (start == null) {
            Logger.msg(1,"Error graph must have a starting vertex to be layed out");
            return;
        }
        graphModel.clearTags(start);
        visitVertex(graphModel, start, 0, rowVector, start);
        midPoints = new int[rowVector.size()];
        valueOfLargestMidPoint = calculateRowMidPoints(rowVector, midPoints, valueOfLargestMidPoint);
        fillInVertexLocations(graphModel, rowVector, valueOfLargestMidPoint, midPoints);
        fillInEdgeLocations(graphModel);
        graphModel.forceNotify();
    }

    private static void visitVertex(GraphModel graphModel, Vertex vertex, int rowIndex, Vector<Vector<Vertex>> rowVector, Object tag) {
        int i = 0;
        Vertex[] children = graphModel.getOutVertices(vertex);
        vertex.setTag(tag);
        addVertexToRow(vertex, rowIndex, rowVector);
        for (i = 0; i < children.length; i++) {
            if (!(children[i].hasTag(tag))) {
                visitVertex(graphModel, children[i], rowIndex + 1, rowVector, tag);
            }
        }
    }

    private static void addVertexToRow(Vertex vertex, int rowIndex, Vector<Vector<Vertex>> rowVector) {
        Vector<Vertex> rowsVertices = null;
        // If there is no vector of vertices already created for this row,
        // then create one
        if (rowVector.size() == rowIndex) {
            rowVector.add(new Vector<Vertex>(10, 10));
        }
        // Add the vertex to the row's vector of vertices
        rowsVertices = rowVector.elementAt(rowIndex);
        rowsVertices.add(vertex);
    }

    private static int calculateRowMidPoints(Vector<Vector<Vertex>> rowVector, int[] midPoints, int valueOfLargestMidPoint) {
        Vector<Vertex> rowsVertices = null;
        int newValueOfLargestMidPoint = valueOfLargestMidPoint;
        int rowsWidth = 0;
        int i = 0;
        for (i = 0; i < midPoints.length; i++) {
            rowsVertices = rowVector.elementAt(i);
            rowsWidth = mHorzGap * (rowsVertices.size() - 1);
            midPoints[i] = rowsWidth / 2;
            if (midPoints[i] > newValueOfLargestMidPoint) {
            	newValueOfLargestMidPoint = midPoints[i];
            }
        }
        return newValueOfLargestMidPoint;
    }

    private static void fillInVertexLocations(GraphModel graphModel, Vector<Vector<Vertex>> rowVector,
        int valueOfLargestMidPoint, int[] midPoints) {
            Vector<Vertex> rowsVertices = null;
            Vertex vertex = null;
            int rowIndex = 0;
            int column = 0;
            int rowsLeftMargin = 0;
            GraphPoint point = new GraphPoint(0, 0);
            for (rowIndex = 0; rowIndex < rowVector.size(); rowIndex++) {
                rowsVertices = rowVector.elementAt(rowIndex);
                rowsLeftMargin = mLeftMargin + valueOfLargestMidPoint - midPoints[rowIndex];
                for (column = 0; column < rowsVertices.size(); column++) {
                    vertex = rowsVertices.elementAt(column);
                    point.x = rowsLeftMargin + column * mHorzGap;
                    point.y = mTopMargin + rowIndex * mVertGap;
                    vertex.moveAbsolute(point);
                    graphModel.checkSize(vertex);
                }
            }
    }

    private static void fillInEdgeLocations(GraphModel graphModel) {
        Vertex[] vertices = graphModel.getVertices();
        GraphPoint centrePoint = null;
        DirectedEdge[] inEdges = null;
        DirectedEdge[] outEdges = null;
        int i = 0;
        int j = 0;
        for (i = 0; i < vertices.length; i++) {
            centrePoint = vertices[i].getCentrePoint();
            inEdges = graphModel.getInEdges(vertices[i]);
            outEdges = graphModel.getOutEdges(vertices[i]);
            for (j = 0; j < inEdges.length; j++) {
                inEdges[j].setTerminusPoint(centrePoint);
            }
            for (j = 0; j < outEdges.length; j++) {
                outEdges[j].setOriginPoint(centrePoint);
            }
        }
    }
}