Added colored markers and filters for distances and prices

This commit is contained in:
Eljakim Herrewijnen 2024-04-01 15:17:38 +02:00
parent f930ebc9ea
commit 26ddbc6c6b
3 changed files with 160 additions and 36 deletions

View File

@ -57,10 +57,6 @@
margin: 5%; margin: 5%;
} }
.priceFilterValue{
}
/*Search Input*/ /*Search Input*/
input.search-locations { input.search-locations {
position: absolute; position: absolute;

View File

@ -26,46 +26,69 @@ class App extends Component {
} }
updatePrice = (maxPrice) => { updatePrice = (maxPrice) => {
this.setState({ price: maxPrice.trim()}) this.setState({ price: parseInt(maxPrice.trim())})
}
updateAfstand = (minuten, naar) => {
if (naar === 'NFI') {
this.setState({ afstandNFI: parseInt(minuten.trim())})
}
if (naar === 'Hoogstraat') {
this.setState({ afstandHoogstraat: parseInt(minuten.trim())})
}
if (naar === 'Korhoen') {
this.setState({ afstandKorhoen: parseInt(minuten.trim())})
}
if (naar === 'Bakkersdijk') {
this.setState({ afstandBakkersdijk: parseInt(minuten.trim())})
}
} }
render() { render() {
const { allLocations, query, price } = this.state const { allLocations, query, price, afstandNFI, afstandHoogstraat, afstandKorhoen, afstandBakkersdijk } = this.state
let showingLocations let showingLocations
if (query || price) { if (query || price || afstandNFI || afstandHoogstraat || afstandKorhoen || afstandBakkersdijk) {
showingLocations = allLocations;
if(query){ if(query){
const match = new RegExp(escapeRegExp(query), 'i') const match = new RegExp(escapeRegExp(query), 'i')
showingLocations = allLocations.filter((location) => showingLocations = showingLocations.filter((location) =>
match.test(location.name) match.test(location.name)
) )
} }
if(price){ if(price){
const maxPrice = parseInt(price) * 1000 const maxPrice = parseInt(price) * 1000
showingLocations = [] showingLocations = showingLocations.filter((location) =>
allLocations.map( house => location.price <= maxPrice
{if(parseInt(house['price'].split(" ")[1] * 1000) <= maxPrice){ )
// showingLocations[house['name']] = house }
showingLocations += house if(afstandNFI){
}} showingLocations = showingLocations.filter((location) =>
location.nfi_location.duration <= (afstandNFI * 60)
)
}
if(afstandHoogstraat){
showingLocations = showingLocations.filter((location) =>
location.hoogstraat_location.duration <= (afstandHoogstraat * 60)
)
}
if(afstandKorhoen){
showingLocations = showingLocations.filter((location) =>
location.korhoen_location.duration <= (afstandKorhoen * 60)
)
}
if(afstandBakkersdijk){
showingLocations = showingLocations.filter((location) =>
location.bakkersdijk_location.duration <= (afstandBakkersdijk * 60)
) )
// console.log(showingLocations)
// const match = new RegExp(escapeRegExp(String((parseInt(price) * 1000))), 'i')
// showingLocations = allLocations.filter((location) =>
// match.test(location.price)
// )
} }
} else { } else {
showingLocations = allLocations showingLocations = allLocations
} }
if (showingLocations.length === 0) {showingLocations = allLocations}
// showingLocations.sort(sortBy('name')); // showingLocations.sort(sortBy('name'));
const position = [51.505, -0.09]; // Latitude and Longitude of the map center const position = [51.505, -0.09]; // Latitude and Longitude of the map center
return ( return (
<div className="App"> <div className="App">
<header className="App-header"> <header className="App-header">
@ -78,12 +101,17 @@ class App extends Component {
query={this.state.query} query={this.state.query}
onUpdateQuery={this.updateQuery} onUpdateQuery={this.updateQuery}
onUpdatePrice={this.updatePrice} onUpdatePrice={this.updatePrice}
onUpdateAfstand={this.updateAfstand}
onListItemClick={this.onListItemClick} onListItemClick={this.onListItemClick}
showDetails={this.state.showDetails} showDetails={this.state.showDetails}
selectedLocation={this.state.selectedLocation} selectedLocation={this.state.selectedLocation}
locationData={this.state.locationData} locationData={this.state.locationData}
maxPrice={this.state.price} maxPrice={this.state.price}
/> afstandNFI={this.state.afstandNFI}
afstandHoogstraat={this.state.afstandHoogstraat}
afstandKorhoen={this.state.afstandKorhoen}
afstandBakkersdijk={this.state.afstandBakkersdijk}
/>
</div> </div>
); );
} }

View File

@ -1,5 +1,5 @@
import React, { Component, useEffect } from 'react'; import React, { Component, useEffect } from 'react';
import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet'; import { MapContainer, TileLayer, Marker, Popup, useMap, Icon } from 'react-leaflet';
import 'leaflet/dist/leaflet.css'; import 'leaflet/dist/leaflet.css';
import LocationDetails from './LocationDetails'; import LocationDetails from './LocationDetails';
import L from 'leaflet'; import L from 'leaflet';
@ -11,8 +11,46 @@ let DefaultIcon = L.icon({
shadowUrl: iconShadow shadowUrl: iconShadow
}); });
const myCustomColour = '#583470'
const markerHtmlStyles = `
background-color: ${myCustomColour};
width: 3rem;
height: 3rem;
display: block;
left: -1.5rem;
top: -1.5rem;
position: relative;
border-radius: 3rem 3rem 0;
transform: rotate(45deg);
border: 1px solid #FFFFFF`
const marker_custom_icon = L.divIcon({
className: "my-custom-pin",
iconAnchor: [0, 24],
labelAnchor: [-6, 0],
popupAnchor: [0, -36],
html: `<span style="${markerHtmlStyles}" />`
})
L.Marker.prototype.options.icon = DefaultIcon; L.Marker.prototype.options.icon = DefaultIcon;
function valueToColor(value) {
// Clamp the value between 2000 and 5000
value = Math.max(2000, Math.min(5000, value));
// Map the value to the range 0 to 255
let green = Math.round(255 * (5000 - value) / 3000);
let red = Math.round(255 * (value - 2000) / 3000);
// Ensure the values are within the RGB range
green = Math.max(0, Math.min(255, green));
red = Math.max(0, Math.min(255, red));
// Return the RGB color
return `rgb(${red}, ${green}, 0)`;
}
class LeafletMap extends Component { class LeafletMap extends Component {
state = { state = {
map: null, map: null,
@ -22,6 +60,29 @@ class LeafletMap extends Component {
showDetails: false, showDetails: false,
selectedLocation: {}, selectedLocation: {},
locationData: {} locationData: {}
}
getCustomIcon = (price_m2) => {
const color = valueToColor(price_m2);
const markerHtmlStyles = `
background-color: ${color};
width: 3rem;
height: 3rem;
display: block;
left: -1.5rem;
top: -1.5rem;
position: relative;
border-radius: 3rem 3rem 0;
transform: rotate(45deg);
border: 1px solid #FFFFFF`
const marker_custom_icon = L.divIcon({
className: "my-custom-pin",
iconAnchor: [0, 24],
labelAnchor: [-6, 0],
popupAnchor: [0, -36],
html: `<span style="${markerHtmlStyles}" />`
})
return marker_custom_icon
} }
mapReady = (props, map) => { mapReady = (props, map) => {
@ -44,13 +105,18 @@ class LeafletMap extends Component {
render() { render() {
let { markers} = this.props let { markers} = this.props
let { maxPrice} = this.props let { maxPrice} = this.props
let { afstandNFI} = this.props
let { activeMarker, activeMarkerProps} = this.state; let { activeMarker, activeMarkerProps} = this.state;
if (markers === undefined || markers.length === 0) {
console.log('No markers')
}
const position = [52.079, 5.09] const position = [52.079, 5.09]
return( return(
<div> <div>
{this.props.toggleMenu && ( {this.props.toggleMenu && (
<div className="list-locations"> <div className="list-locations">
<input {/* <input
className="search-locations" className="search-locations"
type="text" type="text"
placeholder="Filter Locations..." placeholder="Filter Locations..."
@ -59,19 +125,53 @@ class LeafletMap extends Component {
this.props.onUpdateQuery(e.target.value) this.props.onUpdateQuery(e.target.value)
this.setState({ showDetails: false }) this.setState({ showDetails: false })
}} }}
onClick={this.onNewSearch}/> */}
onClick={this.onNewSearch}/>
<div className='priceFilterBlock'> <div className='priceFilterBlock'>
<input type="range" min="100" max="400" onInput={(e) => { <li>Maximale prijs</li>
<input type="range" min="100" max="700" onInput={(e) => {
this.props.onUpdatePrice(e.target.value) this.props.onUpdatePrice(e.target.value)
}}/> }} />
<p className='priceFilterValue'>{maxPrice}</p> <output>{maxPrice}</output>
</div> </div>
<div className='priceFilterBlock'>
<li>Afstand NFI(minuten)</li>
<input type="range" min="10" max="200" onInput={(e) => {
this.props.onUpdateAfstand(e.target.value, "NFI")
}} />
<output>{afstandNFI}</output>
</div>
<div className='priceFilterBlock'>
<li>Afstand Hoogstraat(minuten)</li>
<input type="range" min="10" max="200" onInput={(e) => {
this.props.onUpdateAfstand(e.target.value, "Hoogstraat")
}} />
<output>{afstandNFI}</output>
</div>
<div className='priceFilterBlock'>
<li>Afstand Korhoen(minuten)</li>
<input type="range" min="10" max="200" onInput={(e) => {
this.props.onUpdateAfstand(e.target.value, "Korhoen")
}} />
<output>{afstandNFI}</output>
</div>
<div className='priceFilterBlock'>
<li>Afstand Bakkersdijk(minuten)</li>
<input type="range" min="10" max="200" onInput={(e) => {
this.props.onUpdateAfstand(e.target.value, "Bakkersdijk")
}} />
<output>{afstandNFI}</output>
</div>
<div className="location-list container"> <div className="location-list container">
<ol className="location-list"> <ol className="location-list">
{this.props.locations.map((location) => ( {this.props.query && this.props.locations.length === 0 && (
<li className="location-list-item">
No results found
</li>
)}
{/* {this.props.locations.map((location) => (
<button <button
key={location.name} className="location-list-item" key={location.name} className="location-list-item"
location={location} location={location}
@ -79,7 +179,7 @@ class LeafletMap extends Component {
{location.name} {location.name}
</button> </button>
))} ))} */}
</ol> </ol>
</div> </div>
{this.state.showDetails && ( {this.state.showDetails && (
@ -94,8 +194,8 @@ class LeafletMap extends Component {
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
/> />
{markers && markers.map((marker) => ( {markers && markers.map((marker) => (
// marker.price_m2
<Marker key={marker.house_id} position={{ lng : marker.position[0], lat : marker.position[1]}}> <Marker key={marker.house_id} position={{ lng : marker.position[0], lat : marker.position[1]}} icon={this.getCustomIcon(marker.price_m2)}>
<Popup> <Popup>
Prijs: {marker.price} Per m2: {marker.price_m2} <br/> Prijs: {marker.price} Per m2: {marker.price_m2} <br/>
NFI: {Math.floor(marker.nfi_location.distance / 1000)} km, {Math.floor(marker.nfi_location.duration / 60)} minuten <br/> NFI: {Math.floor(marker.nfi_location.distance / 1000)} km, {Math.floor(marker.nfi_location.duration / 60)} minuten <br/>