Skip to content

Commit

Permalink
Add support for drawing graph vertices with fixed position
Browse files Browse the repository at this point in the history
  • Loading branch information
FeldrinH committed Nov 23, 2023
1 parent a3ce69e commit 20c1d11
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 16 deletions.
4 changes: 2 additions & 2 deletions src/main/java/ee/ut/dendroloj/Dendrologist.java
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public static void drawGraph(int[][] adjacencyMatrix, String[] labels) {
* <b>EXPERIMENTAL API</b>
* <p>
* Draws a graph based on the provided adjacency matrix.
* Infinite values and NaN in the adjacency matrix are treated as missing edges.
* Infinite and NaN values in the adjacency matrix are treated as missing edges.
*
* @param adjacencyMatrix graph adjacency matrix; value at [i][j] is treated as the weight of the edge from vertex i to vertex j
* @param labels string labels for vertices; pass null to use vertex indices as labels
Expand All @@ -199,7 +199,7 @@ public static void drawGraph(double[][] adjacencyMatrix, String[] labels) {
* <b>EXPERIMENTAL API</b>
* <p>
* Draws a graph based on the provided adjacency matrix.
* Infinite values and NaN in the adjacency matrix are treated as missing edges.
* Infinite and NaN values in the adjacency matrix are treated as missing edges.
*
* @param adjacencyMatrix graph adjacency matrix; value at [i][j] is treated as the weight of the edge from vertex i to vertex j
* @param labels string labels for vertices; pass null to use vertex indices as labels
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/ee/ut/dendroloj/GenericGraphLayout.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public static Graph assembleGraph(GraphCanvas<?> graphCanvas) {
for (var vertex : graphCanvas.vertices) {
Node node = graph.addNode(IdHelper.getNodeId(vertex.vertex));
node.setAttribute("label", vertex.label);
if (vertex.fixed) {
node.setAttribute("layout._fixed");
node.setAttribute("layout.frozen");
node.setAttribute("xy", vertex.x, vertex.y);
}
if (vertex.color != null) node.setAttribute("ui.color", vertex.color);
}
for (var edge : graphCanvas.edges) {
Expand Down
60 changes: 54 additions & 6 deletions src/main/java/ee/ut/dendroloj/GraphCanvas.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import java.awt.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* <b>EXPERIMENTAL API</b>
Expand All @@ -14,21 +16,52 @@
*/
public final class GraphCanvas<V> {

private final Set<String> drawnVertices = new HashSet<>();
final List<Vertex<V>> vertices = new ArrayList<>();
final List<Edge<V>> edges = new ArrayList<>();

public void drawVertex(V vertex) {
if (vertex == null) throw new NullPointerException("Vertex must not be null");
drawVertex(vertex, vertex.toString(), null);
}
// TODO: Add overload that allows drawing a vertex with the vertex itself as a default label.
// Note that this will make the order of parameters for drawFixedVertex a little awkward.
// Also note that the default label being the vertex itself converted to a string
// might be non-obvious for reference types (especially ones that don't override toString).

// public void drawVertex(V vertex) {
// if (vertex == null) throw new NullPointerException("Vertex must not be null");
// drawVertex(vertex, vertex.toString(), null);
// }

public void drawVertex(V vertex, String label) {
drawVertex(vertex, label, null);
if (vertex == null) throw new NullPointerException("Vertex must not be null");
addVertex(new Vertex<>(vertex, label, null));
}

public void drawVertex(V vertex, String label, Color color) {
if (vertex == null) throw new NullPointerException("Vertex must not be null");
vertices.add(new Vertex<>(vertex, label, color));
addVertex(new Vertex<>(vertex, label, color));
}

// public void drawFixedVertex(V vertex, double x, double y) {
// if (vertex == null) throw new NullPointerException("Vertex must not be null");
// drawVertex(vertex, vertex.toString(), null);
// }

public void drawFixedVertex(V vertex, String label, double x, double y) {
if (vertex == null) throw new NullPointerException("Vertex must not be null");
addVertex(new Vertex<>(vertex, label, null, x, y));
}

public void drawFixedVertex(V vertex, String label, double x, double y, Color color) {
if (vertex == null) throw new NullPointerException("Vertex must not be null");
addVertex(new Vertex<>(vertex, label, color, x, y));
}

private void addVertex(Vertex<V> vertex) {
String id = IdHelper.getNodeId(vertex.vertex);
if (drawnVertices.contains(id)) {
throw new IllegalArgumentException("Vertex " + vertex.vertex + " (" + vertex.label + ") has already been drawn");
}
drawnVertices.add(id);
vertices.add(vertex);
}

/**
Expand Down Expand Up @@ -79,11 +112,26 @@ static final class Vertex<T> {
public final T vertex;
public final String label;
public final Color color;
public final boolean fixed;
public final double x;
public final double y;

private Vertex(T vertex, String label, Color color) {
this.vertex = vertex;
this.label = label;
this.color = color;
this.fixed = false;
this.x = 0.0;
this.y = 0.0;
}

private Vertex(T vertex, String label, Color color, double x, double y) {
this.vertex = vertex;
this.label = label;
this.color = color;
this.fixed = true;
this.x = x;
this.y = y;
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/main/java/ee/ut/dendroloj/GraphGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.graphstream.graph.Graph;
import org.graphstream.ui.geom.Point2;
import org.graphstream.ui.geom.Point3;
import org.graphstream.ui.graphicGraph.GraphicElement;
import org.graphstream.ui.graphicGraph.GraphicGraph;
import org.graphstream.ui.layout.Layout;
import org.graphstream.ui.swing_viewer.SwingViewer;
Expand Down Expand Up @@ -128,6 +129,16 @@ public void mouseDragged(MouseEvent event) {
}
}
}

@Override
protected void mouseButtonReleaseOffElement(GraphicElement element, MouseEvent event) {
if (!element.hasAttribute("layout._fixed")) {
view.freezeElement(element, false);
}
if (event.getButton() != 3) {
element.removeAttribute("ui.clicked");
}
}
};
view.setMouseManager(restrictedDefaultMouseManager);

Expand Down
20 changes: 12 additions & 8 deletions src/test/java/GraafKatsed.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ public static void main(String[] args) {
// Dendrologist.drawGraph(M, null);

List<Tipp> tipud = new ArrayList<>();
tipud.add(new Tipp("A"));
tipud.add(new Tipp("B"));
tipud.add(new Tipp("C"));
tipud.add(new Tipp("D"));
tipud.add(new Tipp("E"));
tipud.add(new Tipp("A", 1, 0));
tipud.add(new Tipp("B", 2, 5));
tipud.add(new Tipp("C", 0, 1));
tipud.add(new Tipp("D", 1, 1));
tipud.add(new Tipp("E", 0, 0));

tipud.get(0).kaared.add(new Kaar(11, tipud.get(1)));
tipud.get(0).kaared.add(new Kaar(22, tipud.get(2)));
Expand All @@ -40,20 +40,24 @@ public static void main(String[] args) {

GraphCanvas<Tipp> lõuend = new GraphCanvas<>();
for (Tipp tipp : tipud) {
lõuend.drawVertex(tipp, tipp.tähis, Color.GREEN);
lõuend.drawFixedVertex(tipp, tipp.tähis, tipp.x, tipp.y);
for (Kaar kaar : tipp.kaared) {
lõuend.drawEdge(tipp, kaar.lõppTipp, String.valueOf(kaar.kaal), Color.MAGENTA);
lõuend.drawEdge(tipp, kaar.lõppTipp, String.valueOf(kaar.kaal));
}
}
Dendrologist.drawGraph(lõuend);
}

private static class Tipp {
public final String tähis;
public final double x;
public final double y;
public final List<Kaar> kaared;

public Tipp(String tähis) {
public Tipp(String tähis, double x, double y) {
this.tähis = tähis;
this.x = x;
this.y = y;
this.kaared = new ArrayList<>();
}
}
Expand Down

0 comments on commit 20c1d11

Please sign in to comment.