From d68cb2dad8eddaa18655135ae9b8ee299e632e06 Mon Sep 17 00:00:00 2001 From: angevoit Date: Thu, 26 Mar 2026 21:40:52 -0500 Subject: [PATCH 1/5] django start --- map/serializers.py | 14 ++++++++++--- map/static/js/RestaurantPermitMap.js | 31 ++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/map/serializers.py b/map/serializers.py index 03dd912..306b530 100644 --- a/map/serializers.py +++ b/map/serializers.py @@ -1,8 +1,9 @@ from rest_framework import serializers +from django.http import JsonResponse +import logging from map.models import CommunityArea, RestaurantPermit - class CommunityAreaSerializer(serializers.ModelSerializer): class Meta: model = CommunityArea @@ -10,9 +11,11 @@ class Meta: num_permits = serializers.SerializerMethodField() + + def get_num_permits(self, obj): """ - TODO: supplement each community area object with the number + TODO: supplement each community area object with the numbesr of permits issued in the given year. e.g. The endpoint /map-data/?year=2017 should return something like: @@ -30,5 +33,10 @@ def get_num_permits(self, obj): } ] """ + permit_counter = 0 + # TODO add year filtering + for permit in RestaurantPermit.objects.all(): + if permit.community_area_id == self.Meta.model.area_id: + permit_counter += 1 - pass + return permit_counter diff --git a/map/static/js/RestaurantPermitMap.js b/map/static/js/RestaurantPermitMap.js index 57f8ea0..85893bb 100644 --- a/map/static/js/RestaurantPermitMap.js +++ b/map/static/js/RestaurantPermitMap.js @@ -45,14 +45,28 @@ export default function RestaurantPermitMap() { const yearlyDataEndpoint = `/map-data/?year=${year}` useEffect(() => { - fetch() + console.log("ENDPOINT:", yearlyDataEndpoint); + + fetch(yearlyDataEndpoint) .then((res) => res.json()) .then((data) => { - /** - * TODO: Fetch the data needed to supply to map with data - */ - }) - }, [yearlyDataEndpoint]) + console.log(data); + setCurrentYearData(data); + }); + }, [yearlyDataEndpoint]); + + // TODO make this dynamics + const maxNumPermits = 0; + const totalNumPermits = 0; + for (const [key, value] of Object.entries(obj)) { + console.log(`${key}: ${value}`); + if (key === "num_permits") { + if (value > maxNumPermits) { + maxNumPermits = value; + } + totalNumPermits++; + } + } function getColor(percentageOfPermits) { @@ -81,11 +95,10 @@ export default function RestaurantPermitMap() { <>

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

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

Date: Fri, 27 Mar 2026 16:50:53 -0500 Subject: [PATCH 2/5] complete --- map/serializers.py | 15 +++---- map/static/js/RestaurantPermitMap.js | 62 ++++++++++++++++++---------- tests/test_views.py | 10 ++++- 3 files changed, 55 insertions(+), 32 deletions(-) diff --git a/map/serializers.py b/map/serializers.py index 306b530..ac1336f 100644 --- a/map/serializers.py +++ b/map/serializers.py @@ -7,11 +7,13 @@ class CommunityAreaSerializer(serializers.ModelSerializer): class Meta: model = CommunityArea - fields = ["name", "num_permits"] + fields = ["name", "area_id", "num_permits"] + area_id = serializers.SerializerMethodField() num_permits = serializers.SerializerMethodField() - + def get_area_id(self, obj): + return obj.area_id def get_num_permits(self, obj): """ @@ -33,10 +35,5 @@ def get_num_permits(self, obj): } ] """ - permit_counter = 0 - # TODO add year filtering - for permit in RestaurantPermit.objects.all(): - if permit.community_area_id == self.Meta.model.area_id: - permit_counter += 1 - - return permit_counter + year = int(self.context.get("year")) + return RestaurantPermit.objects.filter( community_area_id=str(obj.area_id), issue_date__year=year).count() diff --git a/map/static/js/RestaurantPermitMap.js b/map/static/js/RestaurantPermitMap.js index 85893bb..ef72d5b 100644 --- a/map/static/js/RestaurantPermitMap.js +++ b/map/static/js/RestaurantPermitMap.js @@ -41,39 +41,53 @@ export default function RestaurantPermitMap() { const [currentYearData, setCurrentYearData] = useState([]) const [year, setYear] = useState(2026) - - const yearlyDataEndpoint = `/map-data/?year=${year}` + const [maxNumPermits, setMaxNumPermits] = useState(0) + const [totalNumPermits, setTotalNumPermits] = useState(0) useEffect(() => { - console.log("ENDPOINT:", yearlyDataEndpoint); - - fetch(yearlyDataEndpoint) + fetch(`/map-data/?year=${year}`) .then((res) => res.json()) .then((data) => { - console.log(data); setCurrentYearData(data); }); - }, [yearlyDataEndpoint]); + }, [year]); - // TODO make this dynamics - const maxNumPermits = 0; - const totalNumPermits = 0; - for (const [key, value] of Object.entries(obj)) { - console.log(`${key}: ${value}`); - if (key === "num_permits") { - if (value > maxNumPermits) { - maxNumPermits = value; + useEffect(() => { + var current_maxNumPermits = 0 + var current_totalNumPermits = 0 + currentYearData.forEach(function (area, index) { + if (area['num_permits'] > current_maxNumPermits) { + current_maxNumPermits = area['num_permits']; + console.log(area['name']); } - totalNumPermits++; - } - } - + current_totalNumPermits = current_totalNumPermits + 1; + }); + setMaxNumPermits(current_maxNumPermits); + setTotalNumPermits(current_totalNumPermits); + }, [currentYearData]); function getColor(percentageOfPermits) { /** * TODO: Use this function in setAreaInteraction to set a community * area's color using the communityAreaColors constant above */ + if (percentageOfPermits == 0) { + return communityAreaColors[0]; + } else if (percentageOfPermits < 0.025) { + return communityAreaColors[1]; + } else if (percentageOfPermits < 0.05) { + return communityAreaColors[2]; + } + else { + return communityAreaColors[3]; + } + } + + // Needs performance improvement (I would do the initial data processing differently) + // TODO fix area loop (it's giving me a number rather than an object?) + function findPermitCount(area_id) { + var area = currentYearData.find((element) => element['area_id'].toString() == area_id) + return area ? area['num_permits'] : -1; } function setAreaInteraction(feature, layer) { @@ -84,9 +98,13 @@ 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("") + var permit_count = findPermitCount(feature.properties.area_num_1) + var percentageOfPermits = Boolean(totalNumPermits) ? permit_count / totalNumPermits : 0; + layer.setStyle({fillColor: getColor(percentageOfPermits), strokeWeight: 5, fillOpacity: 0.6}) + layer.on("click", () => { + if (feature.properties.community) { + layer.bindPopup(`${feature.properties.community}: Permit count ${permit_count}`) + } layer.openPopup() }) } diff --git a/tests/test_views.py b/tests/test_views.py index 24cc64e..e9c1164 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -34,8 +34,16 @@ def test_map_data_view(): # Query the map data endpoint client = APIClient() - response = client.get(reverse("map_data", query={"year": 2021})) + response = client.get(reverse("map_data"), {"year": 2021}) # TODO: Complete the test by asserting that the /map-data/ endpoint # returns the correct number of permits for Beverly and Lincoln # Park in 2021 + data = response.data + beverly = next((area for area in data if area["name"] == "Beverly"), None) + lincoln_park = next((area for area in data if area["name"] == "Lincoln Park"), None) + assert beverly is not None + assert lincoln_park is not None + assert beverly['num_permits'] == 2 + assert lincoln_park['num_permits'] == 3 + From e6a845264f3f39edad8d865db45776ca4f517e6e Mon Sep 17 00:00:00 2001 From: angevoit Date: Fri, 27 Mar 2026 17:12:21 -0500 Subject: [PATCH 3/5] minor clean up --- map/serializers.py | 2 -- map/static/js/RestaurantPermitMap.js | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/map/serializers.py b/map/serializers.py index ac1336f..18371f3 100644 --- a/map/serializers.py +++ b/map/serializers.py @@ -1,6 +1,4 @@ from rest_framework import serializers -from django.http import JsonResponse -import logging from map.models import CommunityArea, RestaurantPermit diff --git a/map/static/js/RestaurantPermitMap.js b/map/static/js/RestaurantPermitMap.js index ef72d5b..5820c09 100644 --- a/map/static/js/RestaurantPermitMap.js +++ b/map/static/js/RestaurantPermitMap.js @@ -58,7 +58,6 @@ export default function RestaurantPermitMap() { currentYearData.forEach(function (area, index) { if (area['num_permits'] > current_maxNumPermits) { current_maxNumPermits = area['num_permits']; - console.log(area['name']); } current_totalNumPermits = current_totalNumPermits + 1; }); @@ -103,7 +102,7 @@ export default function RestaurantPermitMap() { layer.setStyle({fillColor: getColor(percentageOfPermits), strokeWeight: 5, fillOpacity: 0.6}) layer.on("click", () => { if (feature.properties.community) { - layer.bindPopup(`${feature.properties.community}: Permit count ${permit_count}`) + layer.bindPopup(`${feature.properties.community}'s permit count ${permit_count}`) } layer.openPopup() }) From 8e80d24d364ccea314e52245224dc9ece3b2e571 Mon Sep 17 00:00:00 2001 From: angevoit Date: Fri, 27 Mar 2026 17:15:25 -0500 Subject: [PATCH 4/5] minor clean up --- map/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/map/serializers.py b/map/serializers.py index 18371f3..abd7a57 100644 --- a/map/serializers.py +++ b/map/serializers.py @@ -15,7 +15,7 @@ def get_area_id(self, obj): def get_num_permits(self, obj): """ - TODO: supplement each community area object with the numbesr + 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: From d3b3da65d4e359381b56012c2ef72c93869fa459 Mon Sep 17 00:00:00 2001 From: angevoit Date: Fri, 27 Mar 2026 17:20:32 -0500 Subject: [PATCH 5/5] adjusted percentage color thresholds --- map/static/js/RestaurantPermitMap.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/map/static/js/RestaurantPermitMap.js b/map/static/js/RestaurantPermitMap.js index 5820c09..e7e84aa 100644 --- a/map/static/js/RestaurantPermitMap.js +++ b/map/static/js/RestaurantPermitMap.js @@ -72,9 +72,9 @@ export default function RestaurantPermitMap() { */ if (percentageOfPermits == 0) { return communityAreaColors[0]; - } else if (percentageOfPermits < 0.025) { + } else if (percentageOfPermits < 0.10) { return communityAreaColors[1]; - } else if (percentageOfPermits < 0.05) { + } else if (percentageOfPermits < 0.25) { return communityAreaColors[2]; } else {