dijkstra-frontend/src/components/HomeView.jsx

192 lines
6.1 KiB
React
Raw Normal View History

import React, { useState ,useEffect } from "react";
2020-02-09 23:12:39 +00:00
import { fetchRoads, fetchCities, getShortestPath } from './requests';
import { Select, Button, Icon } from 'antd';
2020-02-10 01:05:34 +00:00
import Graph from "react-graph-vis";
2020-02-09 23:12:39 +00:00
const { Option } = Select;
function HomeView() {
const [startingPoint, setStartingPoint] = useState();
const [destination, setDestination] = useState();
2020-02-09 23:12:39 +00:00
const [errorSelect, setError] = useState({ message: '', flag: false });
const [shortestPath, setShortestPath] = useState();
2020-02-09 23:12:39 +00:00
const [cities, setCities] = useState([]);
useEffect(() => {
2020-02-09 23:12:39 +00:00
fetchCities()
.then(data => setCities(data))
.catch(error => console.log(error))
}, []);
const [roads, setRoads] = useState([]);
useEffect(() => {
fetchRoads()
.then(data => setRoads(data))
.catch(error => console.log(error));
}, []);
2020-02-09 23:12:39 +00:00
const [graph, setGraph] = useState({nodes: [], edges: []});
2020-02-10 01:05:34 +00:00
2020-02-09 23:12:39 +00:00
useEffect(() => {
let nodes = cities.map(node => (
2020-02-10 01:05:34 +00:00
{ id: node.id, label: node.name, title: node.name}
2020-02-09 23:12:39 +00:00
));
let edges = roads.map(edge => (
2020-02-10 01:05:34 +00:00
{ from: edge.start_city_id, to: edge.end_city_id, length: edge.distance }
2020-02-09 23:12:39 +00:00
))
setGraph({nodes, edges})
2020-02-10 01:05:34 +00:00
}, [cities, roads, shortestPath])
function handleStart(city_id) {
// eslint-disable-next-line
let [ startingPoint ] = cities.filter(city => city.id == city_id);
setStartingPoint(startingPoint);
2020-02-09 23:12:39 +00:00
// Check if start and destination are the same
if (startingPoint === destination) {
setError({ message: 'The start and destination must be different.', flag: true });
return
}
// Will reset the error message and shown path
setShortestPath();
setError({ flag: false });
}
function handleDestination(city_id) {
// eslint-disable-next-line
let [ destination ] = cities.filter(city => city.id == city_id);
setDestination(destination);
2020-02-09 23:12:39 +00:00
// Check if start and destination are the same
if (startingPoint === destination) {
setError({ message: 'The start and destination must be different.', flag: true });
return
}
// Will reset the error message and shown path
setShortestPath();
setError({ flag: false });
}
function handleSubmit() {
if (startingPoint === destination) {
return
2020-02-09 23:12:39 +00:00
} else
if (startingPoint && destination) {
getShortestPath(startingPoint.id, destination.id)
.then(data => setShortestPath(data))
.catch(error => console.log(error));
setError({ flag: false });
} else {
2020-02-09 23:12:39 +00:00
setError({ message: 'Please select a start and a destination', flag: true});
}
}
2020-02-10 01:05:34 +00:00
// Graph visualization settings
const options = {
layout: {
hierarchical: false
},
edges: {
color: "#000000"
},
height: "500px"
};
const events = {
select: function(event) {
let { nodes, edges } = event;
}
}
// // TODO Find a solution to trigger a re-render of the map
// // Add dashes to shortest path edges
// let path = test.path;
// let pairs = [];
// for (let i = 0; path.length - 1 > i; i++) {
// let obj = { from: path[i], to: path[i+1]}
// pairs.push(obj);
// }
// let updatedEdges = graph.edges.map(edge => {
// if (pairs.includes(edge)){
// edge['dashes'] = true;
// }
// return edge
// })
// console.log(updatedEdges)
// setGraph({...graph, edges: updatedEdges});
return(
<main>
<section>
<h2>Select Starting Point</h2>
<div>
<Select defaultValue="Belgium" disabled>
</Select>
<Select
defaultValue="Choose a city"
onChange={handleStart}
2020-02-09 23:12:39 +00:00
style={{ width: 139 }}
>
{cities.map(city => (
<Option key={city.id}>{city.name}</Option>
))}
</Select>
</div>
</section>
<section>
<h2>Select Destination</h2>
<div>
<Select defaultValue="Belgium" disabled>
</Select>
<Select
defaultValue="Choose a city"
onChange={handleDestination}
2020-02-09 23:12:39 +00:00
style={{ width: 139 }}
>
{cities.map(city => (
<Option key={city.id}>{city.name}</Option>
))}
</Select>
</div>
</section>
<section>
<Button
type="primary"
onClick={handleSubmit}
>
Get shortest path between the cities
<Icon type="right" />
</Button>
2020-02-09 23:12:39 +00:00
{errorSelect.flag &&
<p>{errorSelect.message}</p>
}
</section>
{
2020-02-09 23:12:39 +00:00
shortestPath &&
<section>
2020-02-09 23:12:39 +00:00
<h2>Shortest path from {startingPoint.name} to {destination.name} ({shortestPath.distance}km)</h2>
<div>{shortestPath.path.map(city => (
<p key={city.id}><Icon type="right" /><span>{city.name}</span></p>
))}
2020-02-09 23:12:39 +00:00
</div>
</section>
}
2020-02-09 23:12:39 +00:00
{ graph.nodes.length > 0 &&
2020-02-10 01:05:34 +00:00
<Graph
graph={graph}
options={options}
events={events}
getNetwork={network => {
// if you want access to vis.js network api you can set the state in a parent component using this property
}}
/>
2020-02-09 23:12:39 +00:00
}
</main>
);
}
export default HomeView