From d49a49e74a42b87f9d5f36f8aeb3ede5118f009c Mon Sep 17 00:00:00 2001 From: peterdudfield Date: Wed, 24 Jan 2024 18:54:50 +0000 Subject: [PATCH 1/7] make bubble more dependence on the maximum capacity, just trying this --- .../components/map/sitesMap.tsx | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/apps/nowcasting-app/components/map/sitesMap.tsx b/apps/nowcasting-app/components/map/sitesMap.tsx index a1ecfb0b..d784fcfa 100644 --- a/apps/nowcasting-app/components/map/sitesMap.tsx +++ b/apps/nowcasting-app/components/map/sitesMap.tsx @@ -100,18 +100,8 @@ const SitesMap: React.FC = ({ 1 ]; - const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS) => { - // TODO: this will need to be dynamic depending on user's site capacities - switch (aggregationLevel) { - case AGGREGATION_LEVELS.SITE: - return 10; - case AGGREGATION_LEVELS.GSP: - return 5; - case AGGREGATION_LEVELS.REGION: - return 1.5; - case AGGREGATION_LEVELS.NATIONAL: - return 0.3; - } + const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS, maxCapacity) => { + return 1 / maxCapacity; }; const generateGeoJsonForecastData: ( @@ -277,6 +267,11 @@ const SitesMap: React.FC = ({ addGroupSource(map, groupName, groupFeatureArray); } + // get the maximum capacity in all the FeatureArrays + const maxCapacity = Math.max( + ...groupFeatureArray.map((feature) => feature.properties.capacity) + ); + if (groupName === "regions") { let dnoBoundariesSource = map.getSource("dnoBoundaries") as unknown as | mapboxgl.GeoJSONSource @@ -341,7 +336,7 @@ const SitesMap: React.FC = ({ map.setPaintProperty(`Capacity-${groupName}`, "circle-radius", [ "*", ["to-number", ["get", "capacity"]], - getRingMultiplier(groupAggregationLevel) + getRingMultiplier(groupAggregationLevel, maxCapacity) ]); // const visibility = currentAggregationLevel === groupAggregationLevel ? "visible" : "none"; const visibility = "visible"; @@ -361,7 +356,7 @@ const SitesMap: React.FC = ({ "circle-radius": [ "*", ["to-number", ["get", "capacity"]], - getRingMultiplier(groupAggregationLevel) + getRingMultiplier(groupAggregationLevel, maxCapacity) ], "circle-stroke-color": [ "case", @@ -407,7 +402,7 @@ const SitesMap: React.FC = ({ map.setPaintProperty(`Generation-${groupName}`, "circle-radius", [ "*", ["to-number", ["get", "expectedPV"]], - getRingMultiplier(groupAggregationLevel) + getRingMultiplier(groupAggregationLevel, maxCapacity) ]); // const visibility = currentAggregationLevel === groupAggregationLevel ? "visible" : "none"; const visibility = "visible"; @@ -427,7 +422,7 @@ const SitesMap: React.FC = ({ "circle-radius": [ "*", ["to-number", ["get", "expectedPV"]], - getRingMultiplier(groupAggregationLevel) + getRingMultiplier(groupAggregationLevel, maxCapacity) ], "circle-color": [ "case", From 9487cf0244b2a6c708797dbd2eb33ca1d12dc109 Mon Sep 17 00:00:00 2001 From: peterdudfield Date: Wed, 24 Jan 2024 19:00:19 +0000 Subject: [PATCH 2/7] add typing --- apps/nowcasting-app/components/map/sitesMap.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/nowcasting-app/components/map/sitesMap.tsx b/apps/nowcasting-app/components/map/sitesMap.tsx index d784fcfa..57da4b10 100644 --- a/apps/nowcasting-app/components/map/sitesMap.tsx +++ b/apps/nowcasting-app/components/map/sitesMap.tsx @@ -100,8 +100,8 @@ const SitesMap: React.FC = ({ 1 ]; - const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS, maxCapacity) => { - return 1 / maxCapacity; + const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS, maxCapacity: number) => { + return 4 / maxCapacity; }; const generateGeoJsonForecastData: ( From 295e3dc4ad5a4c811866ddd0f1a8cdf23c2b208b Mon Sep 17 00:00:00 2001 From: peterdudfield Date: Wed, 24 Jan 2024 19:04:30 +0000 Subject: [PATCH 3/7] add backup incase value is not set yet --- apps/nowcasting-app/components/map/sitesMap.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/nowcasting-app/components/map/sitesMap.tsx b/apps/nowcasting-app/components/map/sitesMap.tsx index 57da4b10..6a415d78 100644 --- a/apps/nowcasting-app/components/map/sitesMap.tsx +++ b/apps/nowcasting-app/components/map/sitesMap.tsx @@ -101,7 +101,7 @@ const SitesMap: React.FC = ({ ]; const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS, maxCapacity: number) => { - return 4 / maxCapacity; + return 4000 / maxCapacity; }; const generateGeoJsonForecastData: ( @@ -267,9 +267,9 @@ const SitesMap: React.FC = ({ addGroupSource(map, groupName, groupFeatureArray); } - // get the maximum capacity in all the FeatureArrays + // get the maximum capacity in all the FeatureArrays, but feature.properties might be null, if so us 1 const maxCapacity = Math.max( - ...groupFeatureArray.map((feature) => feature.properties.capacity) + ...groupFeatureArray.map((feature) => feature.properties?.capacity || 1) ); if (groupName === "regions") { From 1c02d4b744f271c90ea54780b1f3ae4b8d72149d Mon Sep 17 00:00:00 2001 From: peterdudfield Date: Wed, 24 Jan 2024 19:15:11 +0000 Subject: [PATCH 4/7] add function description and cases --- .../nowcasting-app/components/map/sitesMap.tsx | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/nowcasting-app/components/map/sitesMap.tsx b/apps/nowcasting-app/components/map/sitesMap.tsx index 6a415d78..07add41f 100644 --- a/apps/nowcasting-app/components/map/sitesMap.tsx +++ b/apps/nowcasting-app/components/map/sitesMap.tsx @@ -101,7 +101,23 @@ const SitesMap: React.FC = ({ ]; const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS, maxCapacity: number) => { - return 4000 / maxCapacity; + + // Get the circle multiplier based, which will times the Expected PV value to get the radius + // We used to use 0.3 for National, 1.5 for DNO, 5 for GSP and 10 for Sites. + // Now we use a multiplier based on the max capacity of the the different sites/regions. + // If a client has 100 3 KW sites. Then the National multipler will be about 0.3. + + switch (aggregationLevel) { + case AGGREGATION_LEVELS.SITE: + return 30 / maxCapacity; + case AGGREGATION_LEVELS.GSP: + return 45 / maxCapacity; + case AGGREGATION_LEVELS.REGION: + return 60 / maxCapacity; + case AGGREGATION_LEVELS.NATIONAL: + return 100 / maxCapacity; + } + }; const generateGeoJsonForecastData: ( From 3b83dbf670e68131ed9c082c87206d68c199aad2 Mon Sep 17 00:00:00 2001 From: peterdudfield Date: Wed, 24 Jan 2024 19:17:34 +0000 Subject: [PATCH 5/7] run prettier --- apps/nowcasting-app/components/map/sitesMap.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/nowcasting-app/components/map/sitesMap.tsx b/apps/nowcasting-app/components/map/sitesMap.tsx index 07add41f..748e9611 100644 --- a/apps/nowcasting-app/components/map/sitesMap.tsx +++ b/apps/nowcasting-app/components/map/sitesMap.tsx @@ -101,7 +101,6 @@ const SitesMap: React.FC = ({ ]; const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS, maxCapacity: number) => { - // Get the circle multiplier based, which will times the Expected PV value to get the radius // We used to use 0.3 for National, 1.5 for DNO, 5 for GSP and 10 for Sites. // Now we use a multiplier based on the max capacity of the the different sites/regions. @@ -117,7 +116,6 @@ const SitesMap: React.FC = ({ case AGGREGATION_LEVELS.NATIONAL: return 100 / maxCapacity; } - }; const generateGeoJsonForecastData: ( From fe709ea7e820b2f01c1aa3a1b031db689ac6273d Mon Sep 17 00:00:00 2001 From: peterdudfield Date: Wed, 24 Jan 2024 19:54:33 +0000 Subject: [PATCH 6/7] refactor and add tests --- .../components/map/sitesMap.tsx | 19 +------------------ .../map/sitesMapFeatures/utils.test.tsx | 16 ++++++++++++++++ .../components/map/sitesMapFeatures/utils.tsx | 19 +++++++++++++++++++ 3 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 apps/nowcasting-app/components/map/sitesMapFeatures/utils.test.tsx create mode 100644 apps/nowcasting-app/components/map/sitesMapFeatures/utils.tsx diff --git a/apps/nowcasting-app/components/map/sitesMap.tsx b/apps/nowcasting-app/components/map/sitesMap.tsx index 748e9611..8e068773 100644 --- a/apps/nowcasting-app/components/map/sitesMap.tsx +++ b/apps/nowcasting-app/components/map/sitesMap.tsx @@ -25,6 +25,7 @@ import { theme } from "../../tailwind.config"; import { Feature, FeatureCollection } from "geojson"; import Slider from "./sitesMapFeatures/sitesZoomSlider"; import SitesLegend from "./sitesMapFeatures/sitesLegend"; +import getRingMultiplier from "./sitesMapFeatures/utils"; import { safelyUpdateMapData } from "../helpers/mapUtils"; const yellow = theme.extend.colors["ocf-yellow"].DEFAULT; @@ -100,24 +101,6 @@ const SitesMap: React.FC = ({ 1 ]; - const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS, maxCapacity: number) => { - // Get the circle multiplier based, which will times the Expected PV value to get the radius - // We used to use 0.3 for National, 1.5 for DNO, 5 for GSP and 10 for Sites. - // Now we use a multiplier based on the max capacity of the the different sites/regions. - // If a client has 100 3 KW sites. Then the National multipler will be about 0.3. - - switch (aggregationLevel) { - case AGGREGATION_LEVELS.SITE: - return 30 / maxCapacity; - case AGGREGATION_LEVELS.GSP: - return 45 / maxCapacity; - case AGGREGATION_LEVELS.REGION: - return 60 / maxCapacity; - case AGGREGATION_LEVELS.NATIONAL: - return 100 / maxCapacity; - } - }; - const generateGeoJsonForecastData: ( forecastData?: FcAllResData, targetTime?: string diff --git a/apps/nowcasting-app/components/map/sitesMapFeatures/utils.test.tsx b/apps/nowcasting-app/components/map/sitesMapFeatures/utils.test.tsx new file mode 100644 index 00000000..e0a82fd5 --- /dev/null +++ b/apps/nowcasting-app/components/map/sitesMapFeatures/utils.test.tsx @@ -0,0 +1,16 @@ +import { describe, expect, test } from "@jest/globals"; +import { getRingMultiplier } from "./utils"; +import { AGGREGATION_LEVELS } from "../../../constant"; + +describe("Check getRingMultiplier", () => { + test("check getRingMultiplier works for different values", () => { + expect(getRingMultiplier(AGGREGATION_LEVELS.SITE, 10)).toBe(3); + expect(getRingMultiplier(AGGREGATION_LEVELS.GSP, 10)).toBe(4.5); + expect(getRingMultiplier(AGGREGATION_LEVELS.REGION, 10)).toBe(6); + expect(getRingMultiplier(AGGREGATION_LEVELS.NATIONAL, 10)).toBe(10); + expect(getRingMultiplier(AGGREGATION_LEVELS.SITE, 20)).toBe(1.5); + expect(getRingMultiplier(AGGREGATION_LEVELS.GSP, 20)).toBe(2.25); + expect(getRingMultiplier(AGGREGATION_LEVELS.REGION, 20)).toBe(3); + expect(getRingMultiplier(AGGREGATION_LEVELS.NATIONAL, 20)).toBe(5); + }); +}); diff --git a/apps/nowcasting-app/components/map/sitesMapFeatures/utils.tsx b/apps/nowcasting-app/components/map/sitesMapFeatures/utils.tsx new file mode 100644 index 00000000..b0f430df --- /dev/null +++ b/apps/nowcasting-app/components/map/sitesMapFeatures/utils.tsx @@ -0,0 +1,19 @@ +import { AGGREGATION_LEVELS } from "../../../constant"; + +export const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS, maxCapacity: number) => { + // Get the circle multiplier based, which will times the Expected PV value to get the radius + // We used to use 0.3 for National, 1.5 for DNO, 5 for GSP and 10 for Sites. + // Now we use a multiplier based on the max capacity of the the different sites/regions. + // If a client has 100 3 KW sites. Then the National multipler will be about 0.3. + + switch (aggregationLevel) { + case AGGREGATION_LEVELS.SITE: + return 30 / maxCapacity; + case AGGREGATION_LEVELS.GSP: + return 45 / maxCapacity; + case AGGREGATION_LEVELS.REGION: + return 60 / maxCapacity; + case AGGREGATION_LEVELS.NATIONAL: + return 100 / maxCapacity; + } +}; From 4a18876189dbd70a35ed85dce812bb1399a3694f Mon Sep 17 00:00:00 2001 From: peterdudfield Date: Wed, 24 Jan 2024 19:56:47 +0000 Subject: [PATCH 7/7] fix --- apps/nowcasting-app/components/map/sitesMap.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/nowcasting-app/components/map/sitesMap.tsx b/apps/nowcasting-app/components/map/sitesMap.tsx index 8e068773..524ff526 100644 --- a/apps/nowcasting-app/components/map/sitesMap.tsx +++ b/apps/nowcasting-app/components/map/sitesMap.tsx @@ -25,7 +25,7 @@ import { theme } from "../../tailwind.config"; import { Feature, FeatureCollection } from "geojson"; import Slider from "./sitesMapFeatures/sitesZoomSlider"; import SitesLegend from "./sitesMapFeatures/sitesLegend"; -import getRingMultiplier from "./sitesMapFeatures/utils"; +import { getRingMultiplier } from "./sitesMapFeatures/utils"; import { safelyUpdateMapData } from "../helpers/mapUtils"; const yellow = theme.extend.colors["ocf-yellow"].DEFAULT;