Skip to content

Commit 3ae85b2

Browse files
authored
legend for bilans annuels (#178)
* legend for bilans annuels * add colors on map for bilan annuel * add cvm bilan annuel colors
1 parent 20099de commit 3ae85b2

File tree

4 files changed

+325
-49
lines changed

4 files changed

+325
-49
lines changed

webapp/components/PollutionMap.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export default function PollutionMap() {
109109
{showLegend && (
110110
<div className="absolute left-4 bottom-4">
111111
<PollutionMapLegend
112+
period={period}
112113
category={category}
113114
onClose={() => setShowLegend(false)}
114115
/>

webapp/components/PollutionMapLegend.tsx

Lines changed: 81 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,27 @@ import React from "react";
44

55
interface PollutionMapLegendProps {
66
onClose: () => void;
7+
period: string;
78
category: string;
89
}
910

11+
function LegendItem({ color, label }: { color?: string; label: string }) {
12+
return (
13+
<div className="flex items-center gap-3">
14+
<div
15+
className="w-6 h-4 flex-shrink-0"
16+
style={{
17+
backgroundColor: color || undefined,
18+
}}
19+
></div>
20+
<span className="text-gray-900">{label}</span>
21+
</div>
22+
);
23+
}
24+
1025
export default function PollutionMapLegend({
1126
onClose,
27+
period,
1228
category,
1329
}: PollutionMapLegendProps) {
1430
const categoryDetails = getCategoryById(category);
@@ -22,6 +38,70 @@ export default function PollutionMapLegend({
2238
}),
2339
);
2440

41+
let legendContent = null;
42+
43+
if (period === "dernier_prel") {
44+
// dernier_prel
45+
legendContent = (
46+
<>
47+
<div className="space-y-3 text-sm">
48+
{legendItems.map((item) => (
49+
<LegendItem
50+
key={item.color + item.label}
51+
color={item.color}
52+
label={item.label}
53+
/>
54+
))}
55+
</div>
56+
{categoryDetails.detailsLegende && (
57+
<p className="text-gray-500 mt-4 text-sm">
58+
{categoryDetails.detailsLegende?.split("\n").map((line, index) => (
59+
<React.Fragment key={index}>
60+
{index > 0 && <br />}
61+
{line}
62+
</React.Fragment>
63+
))}
64+
</p>
65+
)}
66+
</>
67+
);
68+
} else {
69+
// bilan_annuel
70+
if (!categoryDetails.resultatsAnnuels) {
71+
return null;
72+
}
73+
legendContent = (
74+
<>
75+
<div className="space-y-3 text-sm">
76+
<LegendItem
77+
color={categoryDetails.resultatsAnnuels.nonRechercheCouleur || ""}
78+
label={categoryDetails.resultatsAnnuels.nonRechercheLabel || ""}
79+
/>
80+
<div className="flex items-center gap-3 text-gray-900">
81+
{categoryDetails.resultatsAnnuels.ratioLabel}:
82+
</div>
83+
{categoryDetails.resultatsAnnuels.ratioLimites?.map((item) => (
84+
<LegendItem
85+
key={item.couleur + item.label}
86+
color={item.couleur}
87+
label={item.label}
88+
/>
89+
))}
90+
{categoryDetails.resultatsAnnuels.valeurSanitaireLabel && (
91+
<LegendItem
92+
color={
93+
categoryDetails.resultatsAnnuels.valeurSanitaireCouleur || ""
94+
}
95+
label={
96+
categoryDetails.resultatsAnnuels.valeurSanitaireLabel || ""
97+
}
98+
/>
99+
)}
100+
</div>
101+
</>
102+
);
103+
}
104+
25105
return (
26106
<div className="bg-white rounded-lg shadow-lg p-6 max-w-md transform transition-all">
27107
<div className="flex justify-between items-center mb-4">
@@ -37,33 +117,7 @@ export default function PollutionMapLegend({
37117
</button>
38118
</div>
39119

40-
<div className="space-y-3 text-sm">
41-
{legendItems.map((item) => (
42-
<div
43-
key={item.color + item.label}
44-
className="flex items-center gap-3"
45-
>
46-
<div
47-
className="w-6 h-4 flex-shrink-0"
48-
style={{
49-
backgroundColor: item.color || undefined,
50-
}}
51-
></div>
52-
<span className="text-gray-900">{item.label}</span>
53-
</div>
54-
))}
55-
</div>
56-
57-
{categoryDetails.detailsLegende && (
58-
<p className="text-gray-500 mt-4 text-sm">
59-
{categoryDetails.detailsLegende?.split("\n").map((line, index) => (
60-
<React.Fragment key={index}>
61-
{index > 0 && <br />}
62-
{line}
63-
</React.Fragment>
64-
))}
65-
</p>
66-
)}
120+
{legendContent}
67121
</div>
68122
);
69123
}

webapp/lib/colorMapping.ts

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export function generateColorExpression(
2525
const defaultColor = "#9B9B9B"; // Default color for unmatched cases
2626
const categoryDetails = getCategoryById(category);
2727

28-
if (!categoryDetails || !categoryDetails.resultats) {
28+
if (!categoryDetails) {
2929
return defaultColor;
3030
}
3131

@@ -62,6 +62,10 @@ export function generateColorExpression(
6262
}
6363
// bilan annuel specific logic
6464
else if (period.startsWith("bilan_annuel")) {
65+
if (!categoryDetails.resultatsAnnuels) {
66+
return defaultColor;
67+
}
68+
6569
const ratioProp = getPropertyName(period, category, "ratio");
6670
const nbPrelevementsProp = getPropertyName(
6771
period,
@@ -74,35 +78,34 @@ export function generateColorExpression(
7478
"nb_sup_valeur_sanitaire",
7579
);
7680

77-
// Check if nb_prelevements is 0 or empty
81+
// Check if nb_prelevements is 0 or empty (no research), or ratio is empty
7882
cases.push([
7983
"any",
8084
["==", ["get", nbPrelevementsProp], ""],
8185
["==", ["get", nbPrelevementsProp], 0],
86+
["==", ["get", ratioProp], ""],
8287
]);
83-
cases.push(defaultColor); // Grey for no data/prelevements
88+
cases.push(categoryDetails.resultatsAnnuels.nonRechercheCouleur);
8489

8590
// Check if nb_sup_valeur_sanitaire is > 0 and not empty
86-
cases.push([
87-
"all",
88-
["!=", ["get", nbSupValeurSanitaireProp], ""],
89-
["==", ["typeof", ["get", nbSupValeurSanitaireProp]], "number"],
90-
[">", ["get", nbSupValeurSanitaireProp], 0],
91-
]);
92-
cases.push("#E93E3A"); // Red for cases with sup_valeur_sanitaire
91+
if (
92+
categoryDetails.resultatsAnnuels.valeurSanitaire &&
93+
categoryDetails.resultatsAnnuels.valeurSanitaireCouleur
94+
) {
95+
cases.push([
96+
"all",
97+
["!=", ["get", nbSupValeurSanitaireProp], ""],
98+
["==", ["typeof", ["get", nbSupValeurSanitaireProp]], "number"],
99+
[">", ["get", nbSupValeurSanitaireProp], 0],
100+
]);
101+
cases.push(categoryDetails.resultatsAnnuels.valeurSanitaireCouleur);
102+
}
93103

94-
// Color scale for ratio values between 0 and 1
95-
cases.push(["==", ["get", ratioProp], 0]);
96-
cases.push("#75D3B4"); // Green for ratio = 0
97-
98-
cases.push(["<=", ["get", ratioProp], 0.5]);
99-
cases.push("#AECF00"); // Light green for ratio <= 0.5
100-
101-
cases.push(["<=", ["get", ratioProp], 0.8]);
102-
cases.push("#FBBD6C"); // Orange for ratio <= 0.8
103-
104-
cases.push(["<=", ["get", ratioProp], 1]);
105-
cases.push("#FB726C"); // Red for ratio <= 1
104+
// Color scale for ratio values using ratioLimites
105+
categoryDetails.resultatsAnnuels.ratioLimites.forEach((l) => {
106+
cases.push(["<=", ["get", ratioProp], l.limite]);
107+
cases.push(l.couleur);
108+
});
106109
}
107110

108111
if (cases.length > 0) {

0 commit comments

Comments
 (0)