Added colored markers and filters for distances and prices
This commit is contained in:
parent
f930ebc9ea
commit
26ddbc6c6b
@ -57,10 +57,6 @@
|
||||
margin: 5%;
|
||||
}
|
||||
|
||||
.priceFilterValue{
|
||||
|
||||
}
|
||||
|
||||
/*Search Input*/
|
||||
input.search-locations {
|
||||
position: absolute;
|
||||
|
@ -26,46 +26,69 @@ class App extends Component {
|
||||
}
|
||||
|
||||
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() {
|
||||
const { allLocations, query, price } = this.state
|
||||
const { allLocations, query, price, afstandNFI, afstandHoogstraat, afstandKorhoen, afstandBakkersdijk } = this.state
|
||||
let showingLocations
|
||||
if (query || price) {
|
||||
if (query || price || afstandNFI || afstandHoogstraat || afstandKorhoen || afstandBakkersdijk) {
|
||||
showingLocations = allLocations;
|
||||
if(query){
|
||||
const match = new RegExp(escapeRegExp(query), 'i')
|
||||
showingLocations = allLocations.filter((location) =>
|
||||
showingLocations = showingLocations.filter((location) =>
|
||||
match.test(location.name)
|
||||
)
|
||||
}
|
||||
if(price){
|
||||
const maxPrice = parseInt(price) * 1000
|
||||
showingLocations = []
|
||||
allLocations.map( house =>
|
||||
{if(parseInt(house['price'].split(" ")[1] * 1000) <= maxPrice){
|
||||
// showingLocations[house['name']] = house
|
||||
showingLocations += house
|
||||
}}
|
||||
showingLocations = showingLocations.filter((location) =>
|
||||
location.price <= maxPrice
|
||||
)
|
||||
}
|
||||
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 {
|
||||
showingLocations = allLocations
|
||||
}
|
||||
if (showingLocations.length === 0) {showingLocations = allLocations}
|
||||
// showingLocations.sort(sortBy('name'));
|
||||
|
||||
|
||||
|
||||
const position = [51.505, -0.09]; // Latitude and Longitude of the map center
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
@ -78,11 +101,16 @@ class App extends Component {
|
||||
query={this.state.query}
|
||||
onUpdateQuery={this.updateQuery}
|
||||
onUpdatePrice={this.updatePrice}
|
||||
onUpdateAfstand={this.updateAfstand}
|
||||
onListItemClick={this.onListItemClick}
|
||||
showDetails={this.state.showDetails}
|
||||
selectedLocation={this.state.selectedLocation}
|
||||
locationData={this.state.locationData}
|
||||
maxPrice={this.state.price}
|
||||
afstandNFI={this.state.afstandNFI}
|
||||
afstandHoogstraat={this.state.afstandHoogstraat}
|
||||
afstandKorhoen={this.state.afstandKorhoen}
|
||||
afstandBakkersdijk={this.state.afstandBakkersdijk}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
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 LocationDetails from './LocationDetails';
|
||||
import L from 'leaflet';
|
||||
@ -11,8 +11,46 @@ let DefaultIcon = L.icon({
|
||||
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;
|
||||
|
||||
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 {
|
||||
state = {
|
||||
map: null,
|
||||
@ -24,6 +62,29 @@ class LeafletMap extends Component {
|
||||
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) => {
|
||||
this.setState({map: map})
|
||||
}
|
||||
@ -44,13 +105,18 @@ class LeafletMap extends Component {
|
||||
render() {
|
||||
let { markers} = this.props
|
||||
let { maxPrice} = this.props
|
||||
let { afstandNFI} = this.props
|
||||
let { activeMarker, activeMarkerProps} = this.state;
|
||||
if (markers === undefined || markers.length === 0) {
|
||||
console.log('No markers')
|
||||
}
|
||||
|
||||
const position = [52.079, 5.09]
|
||||
return(
|
||||
<div>
|
||||
{this.props.toggleMenu && (
|
||||
<div className="list-locations">
|
||||
<input
|
||||
{/* <input
|
||||
className="search-locations"
|
||||
type="text"
|
||||
placeholder="Filter Locations..."
|
||||
@ -59,19 +125,53 @@ class LeafletMap extends Component {
|
||||
this.props.onUpdateQuery(e.target.value)
|
||||
this.setState({ showDetails: false })
|
||||
}}
|
||||
|
||||
onClick={this.onNewSearch}/>
|
||||
onClick={this.onNewSearch}/> */}
|
||||
|
||||
|
||||
<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)
|
||||
}} />
|
||||
<p className='priceFilterValue'>{maxPrice}</p>
|
||||
<output>{maxPrice}</output>
|
||||
</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">
|
||||
<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
|
||||
key={location.name} className="location-list-item"
|
||||
location={location}
|
||||
@ -79,7 +179,7 @@ class LeafletMap extends Component {
|
||||
{location.name}
|
||||
</button>
|
||||
|
||||
))}
|
||||
))} */}
|
||||
</ol>
|
||||
</div>
|
||||
{this.state.showDetails && (
|
||||
@ -94,8 +194,8 @@ class LeafletMap extends Component {
|
||||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
/>
|
||||
{markers && markers.map((marker) => (
|
||||
|
||||
<Marker key={marker.house_id} position={{ lng : marker.position[0], lat : marker.position[1]}}>
|
||||
// marker.price_m2
|
||||
<Marker key={marker.house_id} position={{ lng : marker.position[0], lat : marker.position[1]}} icon={this.getCustomIcon(marker.price_m2)}>
|
||||
<Popup>
|
||||
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/>
|
||||
|
Loading…
Reference in New Issue
Block a user