From 16a75aa8d6ec024a2c6f9a69e11edd77b4d84883 Mon Sep 17 00:00:00 2001 From: nat Date: Thu, 26 Mar 2026 13:06:37 -0500 Subject: [PATCH] create dynamic map --- map/serializers.py | 17 ++++++-- map/static/js/RestaurantPermitMap.js | 58 ++++++++++++++++++++++++---- tests/test_views.py | 14 +++++++ 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/map/serializers.py b/map/serializers.py index 03dd912..528a29a 100644 --- a/map/serializers.py +++ b/map/serializers.py @@ -1,3 +1,4 @@ +from django.utils.text import normalize_newlines from rest_framework import serializers from map.models import CommunityArea, RestaurantPermit @@ -12,8 +13,7 @@ class Meta: def get_num_permits(self, obj): """ - TODO: supplement each community area object with the number - of permits issued in the given year. + TODO: supplement each community area object with the number of permits issued in the given year. e.g. The endpoint /map-data/?year=2017 should return something like: [ @@ -31,4 +31,15 @@ def get_num_permits(self, obj): ] """ - pass + # views.py passes the year in the context + year = self.context.get('year') + + if year: + count = RestaurantPermit.objects.filter( + community_area_id=obj.area_id, + issue_date__year=year + ).count() + else: + count = 0 + + return count diff --git a/map/static/js/RestaurantPermitMap.js b/map/static/js/RestaurantPermitMap.js index 57f8ea0..2515237 100644 --- a/map/static/js/RestaurantPermitMap.js +++ b/map/static/js/RestaurantPermitMap.js @@ -44,22 +44,48 @@ export default function RestaurantPermitMap() { const yearlyDataEndpoint = `/map-data/?year=${year}` + const [totalPermits, setTotalPermits] = useState(0) + const [maxNumPermits, setMaxNumPermits] = useState(0) + useEffect(() => { - fetch() + fetch(yearlyDataEndpoint) .then((res) => res.json()) .then((data) => { /** * TODO: Fetch the data needed to supply to map with data */ + setCurrentYearData(data) + setTotalPermits(data.reduce((sum, name) => sum + name.num_permits, 0)) + setMaxNumPermits(Math.max(...data.map(name => name.num_permits))) }) }, [yearlyDataEndpoint]) + // useEffect(() => { + // if (currentYearData.length > 0) { + // setTotalPermits(currentYearData.reduce((sum, name) => sum + name.num_permits, 0)) + // setMaxNumPermits(Math.max(...currentYearData.map(name => name.num_permits))) + // } else { + // setTotalPermits(0) + // setMaxNumPermits(0) + // } + // }, [currentYearData]) + + + function getColor(percentageOfPermits) { /** * TODO: Use this function in setAreaInteraction to set a community * area's color using the communityAreaColors constant above */ + + // percentage of permits = totalPermits / maxNumPermits + + if (percentageOfPermits <= 0.25) return communityAreaColors[0] + if (percentageOfPermits <= 0.50) return communityAreaColors[1] + if (percentageOfPermits <= 0.75) return communityAreaColors[2] + return communityAreaColors[3] + } function setAreaInteraction(feature, layer) { @@ -70,22 +96,40 @@ export default function RestaurantPermitMap() { * 2) On hover, display a popup with the community area's raw * permit count for the year */ - layer.setStyle() - layer.on("", () => { - layer.bindPopup("") + const areaData = currentYearData.find(area => area.name === feature.properties.community) + const numPermits = areaData?.num_permits || 0 + + const percentage = maxNumPermits > 0 ? numPermits / maxNumPermits : 0 + + layer.setStyle({ + fillColor: getColor(percentage), + fillOpacity: 0.75, + }) + + layer.on("mouseover", () => { + layer.bindPopup(`${feature.properties.community}: ${numPermits} permits`) layer.openPopup() }) + + layer.on('mouseout', () => { + layer.closePopup() + }) } return ( <>

- Restaurant permits issued this year: {/* TODO: display this value */} + Restaurant permits issued this year: { + /* TODO: display this value */ + totalPermits + }

- Maximum number of restaurant permits in a single area: - {/* TODO: display this value */} + Maximum number of restaurant permits in a single area: { + /* TODO: display this value */ + maxNumPermits + }