added path highlighting in the graph visual
This commit is contained in:
parent
8b0327aa5e
commit
35d4789088
@ -10,7 +10,6 @@ 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;
|
||||
@ -42,11 +41,9 @@ 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;
|
||||
@ -84,12 +81,12 @@ public class MainController {
|
||||
@FXML private TableColumn<Departure, Double> tabCostCol;
|
||||
@FXML private ChoiceBox<String> pathChoiceBox;
|
||||
|
||||
|
||||
private Graph graph = new MultiGraph("map");
|
||||
private GraphVisualizer visualizer;
|
||||
private List<Departure> tempDepartureList = new ArrayList<>();
|
||||
|
||||
|
||||
@FXML
|
||||
void showGraph() {
|
||||
@FXML
|
||||
void showGraph() {
|
||||
graph.clear();
|
||||
|
||||
if (map.isVisible()) {
|
||||
@ -120,7 +117,8 @@ void showGraph() {
|
||||
City destinationCity = dep.getDestinationCity();
|
||||
if (destinationCity != null) {
|
||||
if (!city.getName().equals(destinationCity.getName())) {
|
||||
String edgeId = city.getName() + "-" + destinationCity.getName() + "-" + dep.getIdCounter();
|
||||
String edgeId =
|
||||
city.getName() + "-" + destinationCity.getName() + "-" + dep.getIdCounter();
|
||||
|
||||
if (graph.getEdge(edgeId) != null) {
|
||||
System.out.println("Edge already exists: " + edgeId);
|
||||
@ -128,9 +126,21 @@ void showGraph() {
|
||||
} else {
|
||||
try {
|
||||
graph.addEdge(edgeId, city.getName(), destinationCity.getName(), true);
|
||||
System.out.println("Added directed edge: " + edgeId + " from " + city.getName() + " to " + destinationCity.getName());
|
||||
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());
|
||||
System.out.println(
|
||||
"Edge rejected: "
|
||||
+ edgeId
|
||||
+ " from "
|
||||
+ city.getName()
|
||||
+ " to "
|
||||
+ destinationCity.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -141,10 +151,10 @@ void showGraph() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GraphVisualizer.showGraph(graph,graphPane);
|
||||
|
||||
visualizer.showGraph();
|
||||
visualizer.highlightPath(tempDepartureList);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void buyTicket() {
|
||||
|
||||
@ -194,7 +204,8 @@ void showGraph() {
|
||||
pathChoiceBox.getItems().add("Route: " + String.valueOf(pathResult.getId()));
|
||||
}
|
||||
pathChoiceBox.setValue(
|
||||
"Route: " + String.valueOf(graphSimulation.getSortedPaths().getFirst().getId()));
|
||||
"Route: "
|
||||
+ String.valueOf(graphSimulation.getSortedPaths().getFirst().getId()));
|
||||
updateUiGetList();
|
||||
});
|
||||
}
|
||||
@ -254,8 +265,10 @@ void showGraph() {
|
||||
System.out.println("No matching PathResult found.");
|
||||
}
|
||||
}
|
||||
System.out.println(departureList.size());
|
||||
// System.out.println(departureList.size());
|
||||
resultTable.setItems(departureList);
|
||||
tempDepartureList.clear();
|
||||
tempDepartureList = departureList;
|
||||
resultTable.refresh();
|
||||
|
||||
double totalTicketPrice = calculateTotalCost(departureList);
|
||||
@ -382,9 +395,16 @@ void showGraph() {
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
visualizer = new GraphVisualizer(graph, graphPane);
|
||||
pathChoiceBox.setOnAction(
|
||||
event -> {
|
||||
updateUiGetList();
|
||||
|
||||
Platform.runLater(
|
||||
() -> {
|
||||
visualizer.highlightPath(tempDepartureList);
|
||||
});
|
||||
// visualizer.highlightPath(tempDepartureList);
|
||||
});
|
||||
|
||||
categoryBox.getItems().addAll("time", "price", "hops");
|
||||
|
@ -17,7 +17,7 @@ public class GraphSimulation {
|
||||
private static Set<String> visitedRoutes = new HashSet<>();
|
||||
public static PriorityQueue<PathResult> topPaths =
|
||||
new PriorityQueue<>(5, Comparator.comparingDouble(PathResult::getCost).reversed());
|
||||
|
||||
/*
|
||||
public static void main(String[] args) {
|
||||
List<City> cities = JsonParser.parseCities("transport_data.json", "stations");
|
||||
List<Departure> departures = JsonParser.getDeparturesList("transport_data.json", "departures");
|
||||
@ -64,7 +64,7 @@ public class GraphSimulation {
|
||||
System.out.println("--------------------------------------------------");
|
||||
}
|
||||
|
||||
*/
|
||||
*\/
|
||||
|
||||
List<City> path = new ArrayList<>();
|
||||
List<Integer> departuress = new ArrayList<>();
|
||||
@ -77,12 +77,13 @@ public class GraphSimulation {
|
||||
// Output the top 5 paths
|
||||
printTopPaths();
|
||||
}
|
||||
|
||||
public List<PathResult> getSortedPaths(){
|
||||
*/
|
||||
public List<PathResult> getSortedPaths() {
|
||||
List<PathResult> pathList = new ArrayList<>(topPaths);
|
||||
pathList.sort(Comparator.comparingDouble(PathResult::getCost));
|
||||
return pathList;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
topPaths.clear();
|
||||
pathIdCounter = 1;
|
||||
@ -156,11 +157,12 @@ public class GraphSimulation {
|
||||
if (type.equals("time")) {
|
||||
// cost += dep.getDuration();
|
||||
cost += duration.toMinutes();
|
||||
cost += dep.getMinTransferTime();
|
||||
} else if (type.equals("price")) {
|
||||
cost += dep.getPrice();
|
||||
} else if (type.equals("hops")) {
|
||||
cost++;
|
||||
if(!topPaths.isEmpty() && totalCost + cost >= topPaths.peek().getCost()) continue;
|
||||
if (!topPaths.isEmpty() && totalCost + cost >= topPaths.peek().getCost()) continue;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
package dev.ksan.travelpathoptimizer.visualize;
|
||||
|
||||
import dev.ksan.travelpathoptimizer.model.Departure;
|
||||
import java.io.File;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javafx.scene.layout.HBox;
|
||||
import org.graphstream.graph.Edge;
|
||||
import org.graphstream.graph.Graph;
|
||||
import org.graphstream.graph.Node;
|
||||
import org.graphstream.ui.fx_viewer.FxDefaultView;
|
||||
import org.graphstream.ui.fx_viewer.FxViewer;
|
||||
import org.graphstream.ui.view.Viewer;
|
||||
@ -11,22 +15,72 @@ import org.graphstream.ui.view.Viewer;
|
||||
public class GraphVisualizer {
|
||||
|
||||
static File cssFile = new File("src/main/resources/dev/ksan/travelpathoptimizer/app/graph.css");
|
||||
private Graph graph;
|
||||
private HBox container;
|
||||
|
||||
public static void showGraph(Graph graph, HBox container) {
|
||||
public GraphVisualizer(Graph graph, HBox container) {
|
||||
this.graph = graph;
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
public void showGraph() {
|
||||
graph.setAttribute("ui.stylesheet", "url('" + cssFile + "')");
|
||||
|
||||
for (Node node : graph) {
|
||||
node.setAttribute("ui.label", node.getId());
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
public synchronized void highlightPath(List<Departure> departures) {
|
||||
List<String> nodes = new ArrayList();
|
||||
List<String> edges = new ArrayList<>();
|
||||
for (Node node : graph) {
|
||||
node.removeAttribute("ui.class");
|
||||
}
|
||||
for (int i = 0; i < graph.getEdgeCount(); i++) {
|
||||
Edge edge = graph.getEdge(i);
|
||||
edge.removeAttribute("ui.class");
|
||||
}
|
||||
for (Departure dep : departures) {
|
||||
|
||||
String from = dep.getFrom();
|
||||
from = from.replaceAll("[A-Z]", "G");
|
||||
if (!nodes.contains(from)) nodes.add(from);
|
||||
|
||||
if (!nodes.contains(dep.getTo())) nodes.add(dep.getTo());
|
||||
edges.add(from + "-" + dep.getTo() + "-" + dep.getIdCounter());
|
||||
}
|
||||
|
||||
for (String s : nodes) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
for (String nodeId : nodes) {
|
||||
Node node = graph.getNode(nodeId);
|
||||
if (node != null) {
|
||||
node.setAttribute("ui.class", "highlighted");
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < edges.size(); i++) {
|
||||
String from = nodes.get(i);
|
||||
String to = nodes.get(i + 1);
|
||||
|
||||
Edge edge = graph.getEdge(edges.get(i));
|
||||
|
||||
if (edge != null) {
|
||||
edge.setAttribute("ui.class", "highlighted");
|
||||
} else {
|
||||
System.out.println("Edge not found between " + from + " and " + to);
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
@ -14,3 +14,11 @@ edge {
|
||||
fill-color: #979797;
|
||||
arrow-shape: none;
|
||||
}
|
||||
|
||||
edge.highlighted {
|
||||
fill-color: green;
|
||||
size: 3px;
|
||||
}
|
||||
node.highlighted {
|
||||
fill-color: green;
|
||||
}
|
@ -41,9 +41,9 @@
|
||||
<children>
|
||||
<Button fx:id="headerButton1" onAction="#showMapSideBar" text="Map Options" />
|
||||
<Label style="-fx-font-size: 20px; -fx-text-fill: gray;" text="|" />
|
||||
<Button fx:id="headerButton2" text="Button" />
|
||||
<Button fx:id="headerButton2" text="Useless Button" />
|
||||
<Label style="-fx-font-size: 20px; -fx-text-fill: gray;" text="|" />
|
||||
<Button fx:id="headerButton3" onAction="#showGraph" text="Button" />
|
||||
<Button fx:id="headerButton3" onAction="#showGraph" text="Show Graph" />
|
||||
</children>
|
||||
</HBox>
|
||||
</children></HBox>
|
||||
|
Loading…
x
Reference in New Issue
Block a user