Skip to content

Commit

Permalink
Added option to copy&paste selected subgraph
Browse files Browse the repository at this point in the history
Added edge width & opacity decay option
Added dynamic background grid
Added smoothed movement option to graph layout algorithm
Added random layout in force-directed layout menu
Changed camera movement to left mouse click on background & drag

Added WalkingAgent class
Added AlgorithmTaskManager class
Removed AntDrawLayer class
Minor changes and bugfixes
  • Loading branch information
Todense committed Feb 27, 2021
1 parent a6beaf5 commit 0e8f624
Show file tree
Hide file tree
Showing 72 changed files with 988 additions and 439 deletions.
12 changes: 9 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<version>4.13.1</version>
<scope>compile</scope>
</dependency>

Expand All @@ -168,6 +168,12 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-swing</artifactId>
<version>11-ea+24</version>
</dependency>

</dependencies>

<build>
Expand All @@ -180,7 +186,7 @@
<source>11</source>
<target>11</target>
<release>11</release>
<mainClass>com.todense.application.Starter2</mainClass>
<mainClass>com.todense.application.StarterInvoker</mainClass>
</configuration>
</plugin>

Expand All @@ -191,7 +197,7 @@
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.todense.application.Starter2</mainClass>
<mainClass>com.todense.application.StarterInvoker</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/todense/application/Starter.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class Starter extends MvvmfxGuiceApplication {

@Override
public void startMvvmfx(Stage stage) {

stage.setTitle("OmniGraph");
final ViewTuple<MainView, MainViewModel> viewTuple = FluentViewLoader.fxmlView(MainView.class).load();
final Parent root = viewTuple.getView();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.todense.application;

public class Starter2 {
public class StarterInvoker {

// This class exist because of some bug with maven javafx plugin
public static void main(String[] args) {
Starter.main(args);
}
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/todense/model/EdgeList.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public Edge getEdge(Node n, Node m){
String id = n.getID() < m.getID() ?
n.getID()+"-"+m.getID() :
m.getID()+"-"+n.getID();
assert edgeMap.get(id) != null : "No edge with id: "+id;
return edgeMap.get(id);
}

Expand Down
44 changes: 39 additions & 5 deletions src/main/java/com/todense/model/graph/Graph.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;

public class Graph {

Expand Down Expand Up @@ -44,7 +45,6 @@ public Node addNode(Point2D pt, int id){
return n;
}


public Edge addEdge(Node n, Node m){
assert !edges.isEdgeBetween(n, m):
"Edge "+edges.getEdge(n, m).toString()+" already exist!";
Expand All @@ -67,13 +67,47 @@ public void removeEdge(Edge e){
edges.remove(e);
}

public void removeAllEdges(){
edges.clear();
for (Node node : nodes) {
node.getNeighbours().clear();
public void removeEdges(List<Node> nodes){
applyToAllPairOfNodes(nodes, (n, m) -> {
if(edges.isEdgeBetween(n, m)){
removeEdge(n, m);
}
});
}

public void applyToAllPairOfNodes(List<Node> nodes, BiConsumer<Node, Node> consumer){
for (int i = 0; i < nodes.size(); i++) {
for (int j = i+1; j < nodes.size(); j++) {
consumer.accept(nodes.get(i), nodes.get(j));
}
}
}

public void applyToAllConnectedPairOfNodes(List<Node> nodes, BiConsumer<Node, Node> consumer){
for (int i = 0; i < nodes.size(); i++) {
for (int j = i+1; j < nodes.size(); j++) {
Node n = nodes.get(i);
Node m = nodes.get(j);
Edge e = getEdge(n, m);
if(e != null){
consumer.accept(nodes.get(i), nodes.get(j));
}
}
}
}

public void applyToAllConnectedPairOfNodes(BiConsumer<Node, Node> consumer){
applyToAllConnectedPairOfNodes(nodes, consumer);
}

public void applyToAllPairOfNodes(BiConsumer<Node, Node> consumer){
applyToAllPairOfNodes(nodes, consumer);
}

public void removeEdges(){
this.removeEdges(this.nodes);
}

public void removeNode(Node n){
//decrement indexes
for (int i = n.getIndex() + 1; i < nodes.size(); i++) {
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/com/todense/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,18 @@ public static boolean isDouble(String strNum) {
}

//calculates rgb values of a color with given opacity over a background color
public static Color getFaintColor(Color color, Color backgroundColor) {
double opacity = 0.3;
public static Color getFaintColor(Color color, Color backgroundColor, double opacity) {
int r = (int) (backgroundColor.getRed() * 255 + (color.getRed() * 255 - backgroundColor.getRed() * 255) * opacity);
int g = (int) (backgroundColor.getGreen() * 255 + (color.getGreen()* 255 - backgroundColor.getGreen()* 255) * opacity);
int b = (int) (backgroundColor.getBlue() * 255 + (color.getBlue()* 255 - backgroundColor.getBlue()* 255) * opacity);

return Color.rgb(r, g, b);
}

public static Color getFaintColor(Color color, Color backgroundColor) {
return getFaintColor(color, backgroundColor, 0.3);
}

public static void bindSliderAndTextField(Slider slider, TextField textField, String pattern){
StringProperty sp = textField.textProperty();
DoubleProperty dp = slider.valueProperty();
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/todense/view/AlgorithmView.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ public void initialize(){

@FXML
private void startAlgorithmAction() {
viewModel.start();
viewModel.startTask();
}

@FXML
private void stopAlgorithmAction() {
viewModel.stop();
viewModel.stopTask();
}

}
4 changes: 2 additions & 2 deletions src/main/java/com/todense/view/AntsView.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,12 @@ private void scaleIncrementAction() {

@FXML
private void startAction() {
viewModel.startAlgorithm();
viewModel.startTask();
}

@FXML
private void stopAction() {
viewModel.stopAlgorithm();
viewModel.stopTask();
}
}

6 changes: 6 additions & 0 deletions src/main/java/com/todense/view/CanvasView.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import javafx.scene.Cursor;
import javafx.scene.canvas.Canvas;
import javafx.scene.layout.Pane;
import javafx.scene.shape.StrokeLineCap;

public class CanvasView implements FxmlView<CanvasViewModel> {

Expand Down Expand Up @@ -49,10 +50,15 @@ public void initialize(){
canvas.setOnScroll(viewModel.getMouseHandler()::onMouseScroll);
canvas.setOnMouseExited(viewModel.getMouseHandler()::onMouseExited);

canvas.getGraphicsContext2D().setLineCap(StrokeLineCap.BUTT);

Platform.runLater(() -> {
viewModel.setCanvasNode(canvas);
viewModel.getPopOverManager().setContext(context);
});
}




}
38 changes: 35 additions & 3 deletions src/main/java/com/todense/view/GraphView.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import org.controlsfx.control.ToggleSwitch;

public class GraphView implements FxmlView<GraphViewModel> {

@FXML private Label nodeSizeLabel, edgeWidthLabel;
@FXML private JFXSlider nodeSizeSlider, edgeWidthSlider;
@FXML private Label nodeSizeLabel, edgeWidthLabel, edgeWidthDecayLabel, edgeOpacityDecayLabel;
@FXML private JFXSlider nodeSizeSlider, edgeWidthSlider, edgeWidthDecaySlider, edgeOpacityDecaySlider;
@FXML private ColorPicker nodeColorPicker, edgeColorPicker, labelColorPicker, weightColorPicker;
@FXML private ChoiceBox<NodeLabelMode> nodeLabelChoiceBox;
@FXML private ChoiceBox<EdgeWeightMode> edgeWeightChoiceBox;
@FXML private ToggleSwitch nodeBorderToggleSwitch, edgeVisibilityToggleSwitch;
@FXML private ToggleSwitch nodeBorderToggleSwitch, edgeVisibilityToggleSwitch, widthDecayToggleSwitch, opacityDecayToggleSwitch;
@FXML private VBox edgeWidthDecayVBox, edgeWidthDecayStrengthVBox, edgeOpacityDecayVBox, edgeOpacityDecayStrengthVBox;

@InjectViewModel
GraphViewModel viewModel;
Expand All @@ -35,8 +37,32 @@ public void initialize(){
edgeWeightChoiceBox.valueProperty().bindBidirectional(viewModel.edgeWeightModeProperty());
nodeSizeSlider.valueProperty().bindBidirectional(viewModel.nodeSizeProperty());
edgeWidthSlider.valueProperty().bindBidirectional(viewModel.edgeWidthProperty());
edgeWidthDecaySlider.valueProperty().bindBidirectional(viewModel.edgeWidthDecayProperty());
edgeOpacityDecaySlider.valueProperty().bindBidirectional(viewModel.edgeOpacityDecayProperty());
nodeBorderToggleSwitch.selectedProperty().bindBidirectional(viewModel.nodeBorderProperty());
edgeVisibilityToggleSwitch.selectedProperty().bindBidirectional(viewModel.edgeVisibilityProperty());
widthDecayToggleSwitch.selectedProperty().bindBidirectional(viewModel.edgeWidthDecayOnProperty());
opacityDecayToggleSwitch.selectedProperty().bindBidirectional(viewModel.edgeOpacityDecayOnProperty());

widthDecayToggleSwitch.selectedProperty().addListener((obs, oldVal, newVal) -> {
if(newVal){
edgeWidthDecayVBox.getChildren().add(edgeWidthDecayStrengthVBox);
}else{
edgeWidthDecayVBox.getChildren().remove(edgeWidthDecayStrengthVBox);
}
});

opacityDecayToggleSwitch.selectedProperty().addListener((obs, oldVal, newVal) -> {
if(newVal){
edgeOpacityDecayVBox.getChildren().add(edgeOpacityDecayStrengthVBox);
}else{
edgeOpacityDecayVBox.getChildren().remove(edgeOpacityDecayStrengthVBox);
}
});

edgeWidthDecayVBox.getChildren().remove(edgeWidthDecayStrengthVBox);
edgeOpacityDecayVBox.getChildren().remove(edgeOpacityDecayStrengthVBox);


nodeSizeLabel.textProperty().bind(Bindings.createStringBinding(() ->
String.format("%.1f", nodeSizeSlider.getValue()), nodeSizeSlider.valueProperty()));
Expand All @@ -45,6 +71,12 @@ public void initialize(){
edgeWidthLabel.textProperty().bind(Bindings.createStringBinding(()->
String.format("%.2f", edgeWidthSlider.getValue()), edgeWidthSlider.valueProperty()));

edgeWidthDecayLabel.textProperty().bind(Bindings.createStringBinding(()->
String.format("%.4f", edgeWidthDecaySlider.getValue()), edgeWidthDecaySlider.valueProperty()));

edgeOpacityDecayLabel.textProperty().bind(Bindings.createStringBinding(()->
String.format("%.4f", edgeOpacityDecaySlider.getValue()), edgeOpacityDecaySlider.valueProperty()));


nodeLabelChoiceBox.getItems().addAll(NodeLabelMode.values());
edgeWeightChoiceBox.getItems().addAll(EdgeWeightMode.values());
Expand Down
19 changes: 15 additions & 4 deletions src/main/java/com/todense/view/LayoutView.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.util.StringConverter;
import javafx.util.converter.NumberStringConverter;
Expand All @@ -23,10 +24,11 @@ public class LayoutView implements FxmlView<LayoutViewModel> {
@FXML private TextField stepTextField, toleranceTextField, optDistTextField,
pullStrengthTextField, coolingFactorTextField;
@FXML private Slider toleranceSlider, stepSlider, coolingFactorSlider, pullStrengthSlider;
@FXML private JFXSlider optDistSlider;
@FXML private ToggleSwitch pullToggleSwitch, coolingToggleSwitch, multilevelToggleSwitch, barnesHutToggleSwitch;
@FXML private JFXSlider optDistSlider, smoothnessSlider;
@FXML private ToggleSwitch pullToggleSwitch, coolingToggleSwitch, multilevelToggleSwitch, barnesHutToggleSwitch, smoothToggleSwitch;
@FXML private Button startButton;
@FXML private VBox coolingVBox, pullVBox;
@FXML private HBox smoothnessHBox;
@FXML private ChoiceBox<LongRangeForce> longRangeChoiceBox;

@InjectViewModel
Expand All @@ -38,11 +40,13 @@ public void initialize(){
optDistSlider.valueProperty().bindBidirectional(viewModel.optDistProperty());
coolingFactorSlider.valueProperty().bindBidirectional(viewModel.coolingStrengthProperty());
pullStrengthSlider.valueProperty().bindBidirectional(viewModel.centerPullStrengthProperty());
smoothnessSlider.valueProperty().bindBidirectional(viewModel.smoothnessProperty());

pullToggleSwitch.selectedProperty().bindBidirectional(viewModel.centerPullOnProperty());
coolingToggleSwitch.selectedProperty().bindBidirectional(viewModel.coolingOnProperty());
multilevelToggleSwitch.selectedProperty().bindBidirectional(viewModel.multilevelOnProperty());
barnesHutToggleSwitch.selectedProperty().bindBidirectional(viewModel.barnesHutOnProperty());
smoothToggleSwitch.selectedProperty().bindBidirectional(viewModel.smoothnessOnProperty());

bindSliderAndTextField(optDistSlider, optDistTextField);
bindSliderAndTextField(stepSlider, stepTextField);
Expand All @@ -52,6 +56,7 @@ public void initialize(){

pullVBox.disableProperty().bind(pullToggleSwitch.selectedProperty().not());
coolingVBox.disableProperty().bind(coolingToggleSwitch.selectedProperty().not());
smoothnessHBox.disableProperty().bind(smoothToggleSwitch.selectedProperty().not());

longRangeChoiceBox.valueProperty().bindBidirectional(viewModel.longRangeForceProperty());
longRangeChoiceBox.getItems().addAll(LongRangeForce.values());
Expand All @@ -75,14 +80,20 @@ private StringBinding createIntBinding(DoubleProperty property){
String.valueOf(property.getValue().intValue()), property);
}


@FXML
private void dynamicLayoutAction() {
viewModel.start();
viewModel.startTask();
}

@FXML
private void stopAlgorithmAction() {
viewModel.stop();
viewModel.stopTask();
}

@FXML
private void randomLayoutAction(){
viewModel.randomLayout();
}

}
2 changes: 1 addition & 1 deletion src/main/java/com/todense/view/MainView.java
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ private void adjustAction() {

@FXML
private void stopAction(){
viewModel.stop();
viewModel.stopAll();
}

@FXML
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/todense/view/NodePopOverView.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;

Expand All @@ -16,6 +17,8 @@ public class NodePopOverView implements FxmlView<NodePopOverViewModel> {
@FXML private TextField nodeLabelTextField;
@FXML private Button startNodeButton;
@FXML private Button goalNodeButton;
@FXML private VBox rotationVBox;
@FXML private Slider rotationSlider;


@InjectViewModel
Expand All @@ -24,8 +27,9 @@ public class NodePopOverView implements FxmlView<NodePopOverViewModel> {
public void initialize(){
this.editNodeColorPicker.valueProperty().bindBidirectional(viewModel.nodeColorProperty());
this.nodeLabelTextField.textProperty().bindBidirectional(viewModel.labelProperty());
this.rotationSlider.valueProperty().bindBidirectional(viewModel.rotationProperty());

//remove buttons if more than one node is selected
//remove components if more than one node is selected
viewModel.subscribe("MULTIPLE", (key, payload) -> {
nodeVBox.getChildren().remove(startNodeButton);
nodeVBox.getChildren().remove(goalNodeButton);
Expand Down
Loading

0 comments on commit 0e8f624

Please sign in to comment.