-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathRestaurantPermitMap.js
More file actions
124 lines (110 loc) · 3.27 KB
/
RestaurantPermitMap.js
File metadata and controls
124 lines (110 loc) · 3.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import React, { useEffect, useState } from "react"
import { MapContainer, TileLayer, GeoJSON } from "react-leaflet"
import "leaflet/dist/leaflet.css"
import RAW_COMMUNITY_AREAS from "../../../data/raw/community-areas.geojson"
function YearSelect({ setFilterVal }) {
// Filter by the permit issue year for each restaurant
const startYear = 2026
const years = [...Array(11).keys()].map((increment) => {
return startYear - increment
})
const options = years.map((year) => {
return (
<option value={year} key={year}>
{year}
</option>
)
})
return (
<>
<label htmlFor="yearSelect" className="fs-3">
Filter by year:{" "}
</label>
<select
id="yearSelect"
className="form-select form-select-lg mb-3"
onChange={(e) => setFilterVal(e.target.value)}
>
{options}
</select>
</>
)
}
export default function RestaurantPermitMap() {
const colors = ["#eff3ff", "#bdd7e7", "#6baed6", "#2171b5"]
const [currentYearData, setCurrentYearData] = useState([])
const [year, setYear] = useState(2026)
const currentUrl = `/map-data/?year=${year}`
const totalPermits = currentYearData.reduce(
(acc, curr) => acc + curr.num_permits,
0
)
const maxNumPermits = Math.max(...currentYearData.map((c) => c.num_permits))
const communityAreaDict = Object.fromEntries(
currentYearData.map((d) => [d.name, d])
)
// Get values for community areas
useEffect(() => {
fetch(currentUrl)
.then((res) => res.json())
.then((data) => setCurrentYearData(data))
}, [currentUrl])
function getColor(pcntPermits) {
if (pcntPermits > .5)
return colors[3]
else if (pcntPermits > .2)
return colors [2]
else if (pcntPermits >= .01)
return colors [1]
else
return colors[0]
}
function setAreaInteraction(feature, layer) {
const thisAreaData = communityAreaDict[feature.properties.community],
numPermits = thisAreaData.num_permits,
pcntPermits = numPermits / maxNumPermits
layer.setStyle({
color: "#000000",
weight: 1,
fillOpacity: 0.7,
fillColor: getColor(pcntPermits)
})
layer.on("mouseover", () => {
layer.bindPopup(`
<strong>${feature.properties.community}</strong><br />
Year: ${year}<br />
Restaurant permits: ${thisAreaData.num_permits}
`)
layer.openPopup()
})
}
return (
<>
<YearSelect filterVal={year} setFilterVal={setYear} />
<p className="fs-4">
Restaurant permits issued this year: {totalPermits || "0"}
</p>
<p className="fs-4">
Maximum number of restaurant permits in a single area:
{" " + (maxNumPermits || "0")}
</p>
<MapContainer
id="restaurant-map"
center={[41.88, -87.62]}
zoom={10}
>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png"
/>
{currentYearData.length > 0 ? (
<GeoJSON
data={RAW_COMMUNITY_AREAS}
onEachFeature={setAreaInteraction}
key={maxNumPermits}
/>
) : null}
</MapContainer>
</>
)
}