added graph visualization
This commit is contained in:
parent
8548cf0acc
commit
462028e354
@ -8,6 +8,7 @@ import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
|
||||
public class TravelPathOptimizerApplication extends Application {
|
||||
@Override
|
||||
public void start(Stage stage) throws IOException {
|
||||
@ -27,6 +28,7 @@ public class TravelPathOptimizerApplication extends Application {
|
||||
stage.show();
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch();
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
package dev.ksan.travelpathoptimizer.controller;
|
||||
|
||||
import dev.ksan.travelpathoptimizer.app.TransportDataGenerator;
|
||||
import dev.ksan.travelpathoptimizer.graph.Graph;
|
||||
import dev.ksan.travelpathoptimizer.graph.PathResult;
|
||||
import dev.ksan.travelpathoptimizer.graphSimulation.GraphSimulation;
|
||||
import dev.ksan.travelpathoptimizer.graphSimulation.PathResult;
|
||||
import dev.ksan.travelpathoptimizer.model.City;
|
||||
import dev.ksan.travelpathoptimizer.model.Departure;
|
||||
import dev.ksan.travelpathoptimizer.model.Location;
|
||||
import dev.ksan.travelpathoptimizer.service.CityManager;
|
||||
import dev.ksan.travelpathoptimizer.util.JsonParser;
|
||||
import dev.ksan.travelpathoptimizer.util.TicketPrinter;
|
||||
import dev.ksan.travelpathoptimizer.visualize.GraphVisualizer;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
@ -38,9 +40,14 @@ import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import org.graphstream.graph.Graph;
|
||||
import org.graphstream.graph.implementations.MultiGraph;
|
||||
import org.graphstream.graph.implementations.SingleGraph;
|
||||
|
||||
public class MainController {
|
||||
|
||||
|
||||
@FXML private HBox graphPane;
|
||||
@FXML private GridPane map;
|
||||
@FXML private Label welcomeText;
|
||||
@FXML private Text selectedFileText;
|
||||
@ -54,7 +61,7 @@ public class MainController {
|
||||
@FXML private Button startCityButton;
|
||||
@FXML private Button endCityButton;
|
||||
private HashMap<Integer, Departure> departuresMap = new HashMap<>();
|
||||
private Graph graph;
|
||||
private GraphSimulation graphSimulation;
|
||||
private City[][] cities;
|
||||
private File selectedFile;
|
||||
@FXML private Button openFileButton;
|
||||
@ -77,6 +84,67 @@ public class MainController {
|
||||
@FXML private TableColumn<Departure, Double> tabCostCol;
|
||||
@FXML private ChoiceBox<String> pathChoiceBox;
|
||||
|
||||
|
||||
private Graph graph = new MultiGraph("map");
|
||||
|
||||
|
||||
@FXML
|
||||
void showGraph() {
|
||||
graph.clear();
|
||||
|
||||
if (map.isVisible()) {
|
||||
map.setVisible(false);
|
||||
map.setManaged(false);
|
||||
graphPane.setVisible(true);
|
||||
graphPane.setManaged(true);
|
||||
} else {
|
||||
graphPane.setManaged(false);
|
||||
graphPane.setVisible(false);
|
||||
|
||||
map.setManaged(true);
|
||||
map.setVisible(true);
|
||||
}
|
||||
|
||||
for (City[] row : cities) {
|
||||
for (City city : row) {
|
||||
if (city != null) {
|
||||
graph.addNode(city.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (City[] row : cities) {
|
||||
for (City city : row) {
|
||||
if (city != null) {
|
||||
for (Departure dep : city.getDestinations()) {
|
||||
City destinationCity = dep.getDestinationCity();
|
||||
if (destinationCity != null) {
|
||||
if (!city.getName().equals(destinationCity.getName())) {
|
||||
String edgeId = city.getName() + "-" + destinationCity.getName() + "-" + dep.getIdCounter();
|
||||
|
||||
if (graph.getEdge(edgeId) != null) {
|
||||
System.out.println("Edge already exists: " + edgeId);
|
||||
System.out.println("skip");
|
||||
} else {
|
||||
try {
|
||||
graph.addEdge(edgeId, city.getName(), destinationCity.getName(), true);
|
||||
System.out.println("Added directed edge: " + edgeId + " from " + city.getName() + " to " + destinationCity.getName());
|
||||
} catch (org.graphstream.graph.EdgeRejectedException e) {
|
||||
System.out.println("Edge rejected: " + edgeId + " from " + city.getName() + " to " + destinationCity.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GraphVisualizer.showGraph(graph,graphPane);
|
||||
|
||||
}
|
||||
@FXML
|
||||
private void buyTicket() {
|
||||
|
||||
@ -87,7 +155,7 @@ public class MainController {
|
||||
|
||||
@FXML
|
||||
private void findTopPaths() {
|
||||
graph.reset();
|
||||
graphSimulation.reset();
|
||||
updateUiGetList();
|
||||
pathChoiceBox.getItems().clear();
|
||||
startButton.setDisable(true);
|
||||
@ -100,7 +168,7 @@ public class MainController {
|
||||
new Task<Void>() {
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
graph.reset();
|
||||
graphSimulation.reset();
|
||||
if (startCity != null && endCity != null) {
|
||||
List<City> path = new ArrayList<>();
|
||||
List<Integer> departures = new ArrayList<>();
|
||||
@ -108,7 +176,7 @@ public class MainController {
|
||||
double totalCost = 0.0;
|
||||
|
||||
System.out.println(categoryBox.getValue().toString());
|
||||
graph.calculateTopPaths(
|
||||
graphSimulation.calculateTopPaths(
|
||||
startCity,
|
||||
endCity,
|
||||
path,
|
||||
@ -117,16 +185,16 @@ public class MainController {
|
||||
departures,
|
||||
categoryBox.getValue().toString());
|
||||
|
||||
System.out.println(graph.getTopPaths().size());
|
||||
System.out.println(graphSimulation.getTopPaths().size());
|
||||
System.out.println(startCity.getName() + endCity.getName());
|
||||
if (graph.getTopPaths().isEmpty()) return null;
|
||||
if (graphSimulation.getTopPaths().isEmpty()) return null;
|
||||
Platform.runLater(
|
||||
() -> {
|
||||
for (PathResult pathResult : graph.getSortedPaths()) {
|
||||
for (PathResult pathResult : graphSimulation.getSortedPaths()) {
|
||||
pathChoiceBox.getItems().add("Route: " + String.valueOf(pathResult.getId()));
|
||||
}
|
||||
pathChoiceBox.setValue(
|
||||
"Route: " + String.valueOf(graph.getSortedPaths().getFirst().getId()));
|
||||
"Route: " + String.valueOf(graphSimulation.getSortedPaths().getFirst().getId()));
|
||||
updateUiGetList();
|
||||
});
|
||||
}
|
||||
@ -168,9 +236,9 @@ public class MainController {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (graph.getTopPaths().size() > 0) {
|
||||
if (graphSimulation.getTopPaths().size() > 0) {
|
||||
Optional<List<Integer>> departuresOpt =
|
||||
graph.getSortedPaths().stream()
|
||||
graphSimulation.getSortedPaths().stream()
|
||||
.filter(
|
||||
item ->
|
||||
item.getId()
|
||||
@ -467,7 +535,7 @@ public class MainController {
|
||||
}
|
||||
this.cities = map;
|
||||
|
||||
this.graph = new Graph(map);
|
||||
this.graphSimulation = new GraphSimulation(map);
|
||||
}
|
||||
|
||||
@FXML
|
||||
|
@ -1,4 +1,4 @@
|
||||
package dev.ksan.travelpathoptimizer.graph;
|
||||
package dev.ksan.travelpathoptimizer.graphSimulation;
|
||||
|
||||
import dev.ksan.travelpathoptimizer.model.City;
|
||||
import dev.ksan.travelpathoptimizer.model.Departure;
|
||||
@ -9,7 +9,7 @@ import java.time.Duration;
|
||||
import java.time.LocalTime;
|
||||
import java.util.*;
|
||||
|
||||
public class Graph {
|
||||
public class GraphSimulation {
|
||||
private City[][] matrix;
|
||||
private List<PathResult> allPaths = new ArrayList<>();
|
||||
private int pathIdCounter = 1;
|
||||
@ -31,7 +31,7 @@ public class Graph {
|
||||
cities = JsonParser.loadDepartures(cities, departures);
|
||||
City[][] map = JsonParser.loadMap("transport_data.json", "countryMap", cities);
|
||||
|
||||
Graph graph = new Graph(map);
|
||||
GraphSimulation graphSimulation = new GraphSimulation(map);
|
||||
cities = JsonParser.loadDepartures(cities, departures);
|
||||
for (City city : cities) {
|
||||
CityManager.addCity(city);
|
||||
@ -39,7 +39,7 @@ public class Graph {
|
||||
|
||||
System.out.println(cities.getFirst().getName() + " do " + cities.getLast().getName());
|
||||
Map<Location, Double> result =
|
||||
graph.calculateShortestPath(cities.getFirst(), cities.getLast(), "time");
|
||||
graphSimulation.calculateShortestPath(cities.getFirst(), cities.getLast(), "time");
|
||||
System.out.println(
|
||||
cities.get(1).getName() + " = " + result.get(cities.getLast().getLocation()));
|
||||
|
||||
@ -382,7 +382,7 @@ public class Graph {
|
||||
return allPaths;
|
||||
}
|
||||
|
||||
public Graph(City[][] matrix) {
|
||||
public GraphSimulation(City[][] matrix) {
|
||||
this.matrix = matrix;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package dev.ksan.travelpathoptimizer.graph;
|
||||
package dev.ksan.travelpathoptimizer.graphSimulation;
|
||||
|
||||
import dev.ksan.travelpathoptimizer.model.City;
|
||||
import dev.ksan.travelpathoptimizer.model.Departure;
|
||||
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
@ -1,9 +1,8 @@
|
||||
package dev.ksan.travelpathoptimizer.graph;
|
||||
package dev.ksan.travelpathoptimizer.graphSimulation;
|
||||
|
||||
import dev.ksan.travelpathoptimizer.model.City;
|
||||
import dev.ksan.travelpathoptimizer.model.Departure;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PathState {
|
||||
private City city;
|
@ -0,0 +1,32 @@
|
||||
package dev.ksan.travelpathoptimizer.visualize;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javafx.scene.layout.HBox;
|
||||
import org.graphstream.graph.Graph;
|
||||
import org.graphstream.ui.fx_viewer.FxDefaultView;
|
||||
import org.graphstream.ui.fx_viewer.FxViewer;
|
||||
import org.graphstream.ui.view.Viewer;
|
||||
|
||||
public class GraphVisualizer {
|
||||
|
||||
static File cssFile = new File("src/main/resources/dev/ksan/travelpathoptimizer/app/graph.css");
|
||||
|
||||
public static void showGraph(Graph graph, HBox container) {
|
||||
graph.setAttribute("ui.stylesheet", "url('" + cssFile + "')");
|
||||
|
||||
Viewer viewer = new FxViewer(graph, FxViewer.ThreadingModel.GRAPH_IN_GUI_THREAD);
|
||||
viewer.enableAutoLayout();
|
||||
|
||||
FxDefaultView view = (FxDefaultView) viewer.addDefaultView(false);
|
||||
|
||||
|
||||
container.getChildren().clear();
|
||||
|
||||
container.getChildren().add(view);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
node {
|
||||
size: 12px;
|
||||
shape: box;
|
||||
text-alignment: under;
|
||||
fill-color: #4a148c;
|
||||
text-color: #980b0b;
|
||||
text-background-mode: rounded-box;
|
||||
text-background-color: #333;
|
||||
text-padding: 4px;
|
||||
}
|
||||
|
||||
edge {
|
||||
size: 2px;
|
||||
fill-color: #979797;
|
||||
arrow-shape: none;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user