Skip to content
Snippets Groups Projects
Commit 95366408 authored by Noah Jefferson Baumann's avatar Noah Jefferson Baumann
Browse files

new frontend design for Type selction

parent d9d735c6
Branches main
No related tags found
No related merge requests found
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import axios from 'axios'; import axios from 'axios';
import { MapContainer, TileLayer, Marker, Popup, Polyline } from 'react-leaflet'; import { MapContainer, TileLayer, Marker, Popup, Polyline } from 'react-leaflet';
import { Button, Container, Typography, Stack, CircularProgress, Box } from '@mui/material'; import { Button, Container, Typography, Stack, CircularProgress, Box, MenuItem, Select, FormControl, InputLabel } from '@mui/material';
import L from 'leaflet'; import L from 'leaflet';
import 'leaflet/dist/leaflet.css'; import 'leaflet/dist/leaflet.css';
import './App.css'; import './App.css';
...@@ -44,14 +44,12 @@ const defaultIcon = new L.Icon({ ...@@ -44,14 +44,12 @@ const defaultIcon = new L.Icon({
// Helper function to parse coordinates from string // Helper function to parse coordinates from string
const parseCoordinates = (node) => { const parseCoordinates = (node) => {
// Ensure node has valid coordinates
if (node && node.x !== undefined && node.y !== undefined) { if (node && node.x !== undefined && node.y !== undefined) {
return [node.y, node.x]; // Leaflet expects [latitude, longitude] return [node.y, node.x]; // Leaflet expects [latitude, longitude]
} }
return null; // Return null if node is invalid return null;
}; };
// Function to determine the correct icon based on node type // Function to determine the correct icon based on node type
const getIconByType = (type) => { const getIconByType = (type) => {
switch (type) { switch (type) {
...@@ -70,40 +68,47 @@ const getIconByType = (type) => { ...@@ -70,40 +68,47 @@ const getIconByType = (type) => {
function App() { function App() {
const [graphData, setGraphData] = useState({ nodes: [], links: [] }); // Initialize with empty arrays const [graphData, setGraphData] = useState({ nodes: [], links: [] }); // Initialize with empty arrays
const [year, setYear] = useState(1946); // Year state const [year, setYear] = useState('1946'); // Year state
const [type, setType] = useState(''); // Selected type
const [loading, setLoading] = useState(false); // Loading state const [loading, setLoading] = useState(false); // Loading state
// Fetch data based on the selected year const availableYears = [1946, 1951, 1956, 1960, 1961, 1964, 1967, 1971, 1976, 1980, 1982, 1984, 1989];
// Available types for dropdown
const availableTypes = ['All', 'u-bahn', 's-bahn', 'bus', 'strassenbahn'];
// Fetch data based on the selected year and type
useEffect(() => { useEffect(() => {
if (year) { if (year) {
axios.get(`https://berlin-mapping-application.onrender.com/nodes?year=${year}`) setLoading(true); // Start loading
const typeQueryParam = type === 'All' ? '' : type;
axios.get(`https://berlin-mapping-application.onrender.com/nodes?year=${year}&type=${typeQueryParam}`)
.then(response => { .then(response => {
const nodes = response.data; console.log('Nodes returned:', response.data.length); // Log number of nodes returned
// Create a mapping of node IDs to their coordinates
const nodeMap = {};
nodes.forEach(node => {
nodeMap[node.id] = [node.y, node.x]; // Store coordinates as [lat, lon]
});
setGraphData(prevData => ({ setGraphData(prevData => ({
...prevData, ...prevData,
nodes: nodes, // Store the nodes nodes: response.data
nodeMap: nodeMap // Store the ID to coordinates map
})); }));
setLoading(false); // Stop loading once data is fetched
})
.catch(error => {
console.error("There was an error fetching the nodes data!", error);
setLoading(false); // Stop loading on error
}); });
axios.get(`https://berlin-mapping-application.onrender.com/edges?year=${year}`) axios.get(`https://berlin-mapping-application.onrender.com/edges?year=${year}&type=${typeQueryParam}`)
.then(response => { .then(response => {
console.log('Edges returned:', response.data.length); // Log number of edges returned
setGraphData(prevData => ({ setGraphData(prevData => ({
...prevData, ...prevData,
links: response.data // Store the edges links: response.data
})); }));
})
.catch(error => {
console.error("Error fetching the edges data!", error);
}); });
} }
}, [year]); // This effect runs whenever the year changes }, [year, type]);
const availableYears = [1946, 1951, 1956, 1960, 1961, 1964, 1967, 1971, 1976, 1980, 1982, 1984, 1989];
if (loading) { if (loading) {
return ( return (
...@@ -115,6 +120,12 @@ function App() { ...@@ -115,6 +120,12 @@ function App() {
); );
} }
// Map nodes to a dictionary by ID for easy lookup
const nodeMap = {};
graphData.nodes.forEach(node => {
nodeMap[node.id] = node;
});
return ( return (
<Container> <Container>
<Box textAlign="center" mb={4}> <Box textAlign="center" mb={4}>
...@@ -127,7 +138,7 @@ function App() { ...@@ -127,7 +138,7 @@ function App() {
color: '#333' color: '#333'
}} }}
> >
Graph Visualization on Map Berlin's Public Transport Visualised
</Typography> </Typography>
</Box> </Box>
...@@ -166,6 +177,7 @@ function App() { ...@@ -166,6 +177,7 @@ function App() {
backgroundColor: '#3f51b5', // Background color for the "Selected Year" label backgroundColor: '#3f51b5', // Background color for the "Selected Year" label
color: 'white', color: 'white',
padding: '8px 12px', padding: '8px 12px',
borderRadius: '4px 0 0 4px', // Rounded only on the left side
}} }}
> >
Selected Year: Selected Year:
...@@ -188,6 +200,32 @@ function App() { ...@@ -188,6 +200,32 @@ function App() {
</Box> </Box>
)} )}
<Box display="flex"
justifyContent="center"
alignItems="center"
mb={3}
sx={{
padding: '16px',
borderRadius: '8px',
maxWidth: '400px',
margin: '0 auto', // Center the box
}}>
<Typography variant="h6"
component="span"
sx={{
fontWeight: 'bold',
backgroundColor: '#3f51b5', // Background color for the "Selected Year" label
color: 'white',
padding: '8px 12px',
borderRadius: '4px 0 0 4px', // Rounded only on the left side
}}>Select Type:</Typography>
<select value={type} onChange={(e) => setType(e.target.value)} style={{ padding: '8px', fontSize: '16px' }}>
{availableTypes.map((typeOption, index) => (
<option key={index} value={typeOption}>{typeOption}</option>
))}
</select>
</Box>
<Box style={{ <Box style={{
height: 'calc(100vh - 80px)', // Adjust height to fit in the viewport minus header/footer height height: 'calc(100vh - 80px)', // Adjust height to fit in the viewport minus header/footer height
width: '100%', width: '100%',
...@@ -200,7 +238,7 @@ function App() { ...@@ -200,7 +238,7 @@ function App() {
{/* Render Nodes with Dynamic Icons and Custom Popup */} {/* Render Nodes with Dynamic Icons and Custom Popup */}
{graphData.nodes && graphData.nodes.map((node, index) => { {graphData.nodes && graphData.nodes.map((node, index) => {
const nodeType = node.station_type; // Adjust based on the actual data key const nodeType = node.type; // Adjust based on the actual data key
const icon = getIconByType(nodeType); // Determine the correct icon const icon = getIconByType(nodeType); // Determine the correct icon
const popupContent = node.node_label; // Adjust based on the actual data key const popupContent = node.node_label; // Adjust based on the actual data key
...@@ -219,28 +257,24 @@ function App() { ...@@ -219,28 +257,24 @@ function App() {
{/* Render Edges (Polylines) */} {/* Render Edges (Polylines) */}
{graphData.links && graphData.links.map((edge, index) => { {graphData.links && graphData.links.map((edge, index) => {
// Look up the coordinates for the source and target nodes using the nodeMap const sourceNode = nodeMap[edge.source];
const sourceCoords = graphData.nodeMap[edge.source]; const targetNode = nodeMap[edge.target];
const targetCoords = graphData.nodeMap[edge.target];
// Validate the coordinates before rendering the Polyline
if (!sourceCoords || !targetCoords) {
console.warn('Skipping edge due to missing node coordinates:', edge);
return null;
}
return ( const sourceCoords = parseCoordinates(sourceNode);
<Polyline const targetCoords = parseCoordinates(targetNode);
key={index}
positions={[sourceCoords, targetCoords]}
color="blue"
weight={3}
/>
);
})}
if (!sourceCoords || !targetCoords) {
console.warn('Skipping edge due to invalid coordinates:', edge);
return null;
}
return (
<Polyline key={index} positions={[sourceCoords, targetCoords]} color="blue" weight={3} />
);
})}
{/* Log number of edges added to the map */}
{console.log('Edges added to the map:', graphData.links.length)}
</MapContainer> </MapContainer>
</Box> </Box>
</Container> </Container>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment