diff --git a/backend/Makefile b/backend/Makefile index faa8336e..240f1446 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -34,14 +34,13 @@ catalog: coordo add foreignkey inv_bio.year bio_pop.year --package catalog/inventaire_bio # All 4 Trees - Enquête ménage - coordo add kobotoolbox data/all4trees/enquete/20260422_EnqueteMenage_DonneesK.csv --form data/all4trees/enquete/20260519_EnqueteMenage_QuestionnaireK.xlsx --package catalog/enquete - coordo add file data/all4trees/enquete/20260422_EnqueteMenage_DonneesExternes.xlsx --package catalog/enquete - - coordo add foreignkey enquete_menage.proj enq_samp.proj --package catalog/enquete - coordo add foreignkey enquete_menage.typ enq_pop.typ --package catalog/enquete - coordo add foreignkey enquete_menage.loc2 enq_gps.loc2 --package catalog/enquete - coordo add foreignkey enquete_menage.fw_cod enq_fw.fw_cod --package catalog/enquete - coordo add foreignkey enquete_menage.coal_unit enq_coal.coal_unit --package catalog/enquete + coordo add kobotoolbox data/all4trees/enquete/20260709_EnqueteMenage_DonneesK.xlsx --form data/all4trees/enquete/20260519_EnqueteMenage_QuestionnaireK.xlsx --package catalog/enquete + coordo add file data/all4trees/enquete/20260713_EnqueteMenage_DonneesExternes.xlsx --package catalog/enquete + + coordo add foreignkey enquete_menage.proj hh_samp.proj --package catalog/enquete + coordo add foreignkey enquete_menage.loc2 hh_gps.loc2 --package catalog/enquete + coordo add foreignkey enquete_menage.fw_cod hh_fw.fw_cod --package catalog/enquete + coordo add foreignkey enquete_menage.coal_unit hh_coal.coal_unit --package catalog/enquete # Seed - Survey coordo add file data/seed/survey.zip --package catalog/seed diff --git a/backend/configs/all4trees_config.json b/backend/configs/all4trees_config.json index 035acbab..42d66af5 100644 --- a/backend/configs/all4trees_config.json +++ b/backend/configs/all4trees_config.json @@ -132,7 +132,7 @@ "path": "../catalog/enquete", "resource": "enquete_menage", "layerType": "symbol", - "groupby": ["loc2"], + "groupby": ["loc2", "year"], "cluster": { "radius": 50, "maxZoom": 12, @@ -140,11 +140,13 @@ "colors": ["rgba(161,181,245,0.7)", "rgba(20,71,230,0.7)", "rgba(14,50,161,0.7)"] }, "columns": { - "geom": "centroid(merge(point(enq_gps.long, enq_gps.latit)))", + "geom": "centroid(merge(point(hh_gps.long, hh_gps.latit)))", + "project": "first(proj)", + "loc1": "first(loc1)", "household_nb": "count(_id)", "population": "sum(res)", "fuel_sources": "list_aggregate(flatten(list(ener)), 'histogram')", - "wood_fuel_cons": "sum( 12 * ( ifnull(fw_qty * enq_fw.fw_vol * fw_freq, 0) + ifnull(coal_qty * enq_coal.coal_kg * coal_freq * enq_coal.coal_fw, 0) / enq_coal.coal_dens )) / sum(res)", + "wood_fuel_cons": "sum( 12 * ( ifnull(fw_qty * hh_fw.fw_vol * fw_freq, 0) + ifnull(coal_qty * hh_coal.coal_kg * coal_freq * hh_coal.coal_fw, 0) / hh_coal.coal_dens )) / sum(res)", "firewood_collec_time": "avg(ifnull(coll_freq, 0) * ifnull(coll_dur, 0) / 30)", "firewood_satis": "histogram(wf_satis if int(wf_satis) > 0)", "firewood_satis_tot": "count(1 if int(wf_satis) > 0)", @@ -161,15 +163,15 @@ "timber_satis": "histogram(timb_satis if timb_yn = '1')", "timber_satis_tot": "count(1 if timb_yn = '1')", "lean_period": "avg(len(lean) if lean_yn = 1)", + "lean_months": "list_aggregate(flatten(list(lean)), 'histogram')", "food_diversity": "list_aggregate(flatten(list(food_cons)), 'histogram')", "food_diversity_score": "avg(list_unique(food_cons) / int(food_cons_max) * 10)", - "food_self_suff_score": "avg(ifnull(list_unique(food_self), 0) / list_unique(food_cons) * 100)", + "food_self_suff_score": "avg( ((0 if list_contains(food_self, '') else list_unique(food_self)) / list_unique(food_cons) * 100) if list_contains(food_cons, '') != 'true')", "living_cond_perception": "histogram(cond_evol)", "revenue_change": "avg(0 - inc_dif if inc_evol = '2' else ifnull(inc_dif, 0))", "assets_idx_raw": "avg( ( ( int(hous_typ) + int(hous_size)) * int(hous_own) + ifnull(list_unique(ass),0) + int(lvst_yn) * ( int(lvst_s) + int(lvst_l) ) + ( int( land_own ) + int( land_titl ) + int( land_size ) if int(land_own) > 0 else 0) ) if ( ( int(hous_typ) + int(hous_size)) * int(hous_own) + list_unique(ass) + int(lvst_yn) * ( int(lvst_s) + int(lvst_l) ) + int( land_own ) + int( land_titl ) + int( land_size ) ) <= int(ass_tot_max) )", "assets_idx": "10 / int(ass_tot_max) * avg( ( ( int(hous_typ) + int(hous_size)) * int(hous_own) + ifnull(list_unique(ass),0) + int(lvst_yn) * ( int(lvst_s) + int(lvst_l) ) + ( int( land_own ) + int( land_titl ) + int( land_size ) if int(land_own) > 0 else 0) ) if ( ( int(hous_typ) + int(hous_size)) * int(hous_own) + list_unique(ass) + int(lvst_yn) * ( int(lvst_s) + int(lvst_l) ) + int( land_own ) + int( land_titl ) + int( land_size ) ) <= int(ass_tot_max) )", "nb_income_sources" : "avg(int(inc_no))", - "nb_additional_incomes": "'N/A'", "benef_pract1": "count(1 if int(pract1) = 2) / count(1) * 100", "benef_pract2": "count(1 if int(pract2) = 2) / count(1) * 100", "benef_pract3": "count(1 if int(pract3) = 2) / count(1) * 100", diff --git a/webapp/src/entities/data.ts b/webapp/src/entities/data.ts index 157d78b4..b7df6c65 100644 --- a/webapp/src/entities/data.ts +++ b/webapp/src/entities/data.ts @@ -1,6 +1,7 @@ export type ExternalData = { for_label: LabelData[]; bio_label: LabelData[]; + hh_label: LabelData[]; bio_sp: BioSpeciesData[]; for_mf_tax1: any[]; for_mf_tax2: any[]; diff --git a/webapp/src/entities/resources.ts b/webapp/src/entities/resources.ts index cae9ca9a..a77b4ccf 100644 --- a/webapp/src/entities/resources.ts +++ b/webapp/src/entities/resources.ts @@ -6,11 +6,12 @@ export const EXTERNAL_RESOURCES_BY_LAYER = new Map([ ["for_label", "for_mf_tax1", "for_mf_tax2", "for_mf_tax3", "for_score"], ], [LAYERS.INVENTORY_BIO, ["bio_label", "bio_sp"]], - [LAYERS.ENQUETE, [""]], + [LAYERS.ENQUETE, ["hh_label"]], [LAYERS.SEED_POINT, [""]], ]); export const LABEL_DATA = new Map([ [LAYERS.INVENTORY_FOR, "for_label"], [LAYERS.INVENTORY_BIO, "bio_label"], + [LAYERS.ENQUETE, "hh_label"], ]); diff --git a/webapp/src/entities/socio-eco.ts b/webapp/src/entities/socio-eco.ts new file mode 100644 index 00000000..7ede8b47 --- /dev/null +++ b/webapp/src/entities/socio-eco.ts @@ -0,0 +1,8 @@ +export const SOCIO_LABEL_FIELDS = { + BENEFICIAL_PRACTICES: "pract", + ENERGY_SOURCES: "ener", + EVOLUTION: "evol", + FOOD_CONSOMMATION: "food_cons", + LEAN_MONTHS: "lean", + SATISFACTION: "satis", +}; diff --git a/webapp/src/features/charts/biodiversity/chart-relative-abundance.tsx b/webapp/src/features/charts/biodiversity/chart-relative-abundance.tsx index 20bb4b55..7310a2b8 100644 --- a/webapp/src/features/charts/biodiversity/chart-relative-abundance.tsx +++ b/webapp/src/features/charts/biodiversity/chart-relative-abundance.tsx @@ -1,4 +1,4 @@ -import { findLabel } from "@features/indicators/utils"; +import { findLabel } from "@features/indicators/labels"; import type { LabelData } from "@entities/data"; diff --git a/webapp/src/features/charts/bioinventory/chart-species-status.tsx b/webapp/src/features/charts/bioinventory/chart-species-status.tsx index 0c1935d4..822b7ea4 100644 --- a/webapp/src/features/charts/bioinventory/chart-species-status.tsx +++ b/webapp/src/features/charts/bioinventory/chart-species-status.tsx @@ -1,4 +1,4 @@ -import { findStatus } from "@features/indicators/utils"; +import { findStatus } from "@features/indicators/labels"; import type { BioSpeciesData } from "@entities/data"; diff --git a/webapp/src/features/charts/components/bar-chart-benef-control.tsx b/webapp/src/features/charts/components/bar-chart-benef-control.tsx index 1f5d7d94..9de2f698 100644 --- a/webapp/src/features/charts/components/bar-chart-benef-control.tsx +++ b/webapp/src/features/charts/components/bar-chart-benef-control.tsx @@ -1,3 +1,4 @@ +import type { PropsWithChildren } from "react"; import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts"; import { useTranslation } from "@shared/i18n"; @@ -10,14 +11,15 @@ import { import type { ChartComponentType } from "./chart-component"; import { ChartComponent } from "./chart-component"; -type BarChartProps = { +type BarChartProps = PropsWithChildren<{ title: string; chartData: Array<{ indicator: string; benef: unknown; temoin?: unknown }>; legendLabel: string; unit?: string; withTemoin?: boolean; layout?: { chartHeight: number; chartXAxisHeight: number }; -}; + description?: string; +}>; export const BarCharWithBenefAndControl: ChartComponentType = ({ title, @@ -25,6 +27,8 @@ export const BarCharWithBenefAndControl: ChartComponentType = ({ legendLabel, unit = "", withTemoin = false, + description, + children, }) => { const { t } = useTranslation("all4trees"); const chartConfig = { @@ -56,10 +60,14 @@ export const BarCharWithBenefAndControl: ChartComponentType = ({ }; return ( - + + {children} ; + +export const LabeledBarChart: ChartComponentType = ({ + benef, + temoin, + metadata, + project, + labelField, + legendLabel, + title, + description, + children, +}) => { + const { t } = useTranslation("common"); + const lang = i18nInstance.language; + + const chartData = Object.entries(benef).map(([key, value]) => ({ + benef: value, + indicator: + findLabel(metadata, project, lang, labelField, key) || + t("dataManagement.undefined"), + temoin: temoin?.[key as keyof typeof temoin], + })); + + return ( + + {children} + + ); +}; + +LabeledBarChart.isChartComponent = true; diff --git a/webapp/src/features/charts/components/labeled-pie-chart.tsx b/webapp/src/features/charts/components/labeled-pie-chart.tsx new file mode 100644 index 00000000..f09a6f97 --- /dev/null +++ b/webapp/src/features/charts/components/labeled-pie-chart.tsx @@ -0,0 +1,61 @@ +import { findLabel } from "@features/indicators/labels"; + +import type { LabelData } from "@entities/data"; + +import { i18nInstance, useTranslation } from "@shared/i18n"; +import type { ChartConfig } from "@shared/ui/chart"; + +import type { ChartComponentType } from "./chart-component"; +import { PieChartCategorical, renderLabel } from "./pie-chart-categorical"; + +type LabeledPieChartProps = { + project: string; + metadata: LabelData[]; + data: { + [key: string]: number; + }; + title: string; + labelField: string; + colorMap: Map; +}; + +export const LabeledPieChart: ChartComponentType = ({ + data, + metadata, + project, + title, + colorMap, + labelField, +}) => { + const { t } = useTranslation("common"); + const lang = i18nInstance.language; + + const chartData = Object.entries(data).map(([key, value]) => ({ + fill: colorMap.get(key) || "var(--chart-4)", + name: key, + value, + })); + + const chartConfig = chartData.reduce((acc, item) => { + acc[item.name as keyof typeof acc] = { + label: + findLabel(metadata, project, lang, labelField, item.name) || + t("dataManagement.undefined"), + }; + return acc; + }, {} as ChartConfig) satisfies ChartConfig; + + return ( + + renderLabel({ ...props, chartConfig, linebreak: 18 }) + } + /> + ); +}; + +LabeledPieChart.isChartComponent = true; diff --git a/webapp/src/features/charts/components/lib/taxon.ts b/webapp/src/features/charts/components/lib/taxon.ts index c2450ce8..842469d7 100644 --- a/webapp/src/features/charts/components/lib/taxon.ts +++ b/webapp/src/features/charts/components/lib/taxon.ts @@ -1,4 +1,4 @@ -import { findLabel } from "@features/indicators/utils"; +import { findLabel } from "@features/indicators/labels"; import type { LabelData } from "@entities/data"; diff --git a/webapp/src/features/charts/components/pie-chart-categorical.tsx b/webapp/src/features/charts/components/pie-chart-categorical.tsx index c50f6495..d2839217 100644 --- a/webapp/src/features/charts/components/pie-chart-categorical.tsx +++ b/webapp/src/features/charts/components/pie-chart-categorical.tsx @@ -7,8 +7,6 @@ import { lineBreakLabel } from "../utils"; import type { ChartComponentType } from "./chart-component"; import { ChartComponent } from "./chart-component"; -export const description = "A pie chart with a label"; - export type PieChartCategoricalProps = { title: string; chartData: Array<{ name: string; value: number; fill: string }>; diff --git a/webapp/src/features/charts/index.ts b/webapp/src/features/charts/index.ts new file mode 100644 index 00000000..81721df3 --- /dev/null +++ b/webapp/src/features/charts/index.ts @@ -0,0 +1,7 @@ +export { BarCharWithBenefAndControl } from "./components/bar-chart-benef-control"; +export { ChartComponent } from "./components/chart-component"; +export { ChartTaxonAbundance } from "./components/chart-taxon-abundance"; +export { LabeledBarChart } from "./components/labeled-bar-chart"; +export { LabeledPieChart } from "./components/labeled-pie-chart"; +export { PieChartCategorical } from "./components/pie-chart-categorical"; +export { ChartRadarWithBenefAndControl } from "./components/radar-benef-control"; diff --git a/webapp/src/features/charts/socio-eco/chart-beneficial-practices.tsx b/webapp/src/features/charts/socio-eco/chart-beneficial-practices.tsx deleted file mode 100644 index aae67f92..00000000 --- a/webapp/src/features/charts/socio-eco/chart-beneficial-practices.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { useTranslation } from "@shared/i18n"; - -import { BarCharWithBenefAndControl } from "../components/bar-chart-benef-control"; -import type { ChartComponentType } from "../components/chart-component"; - -type Data = { - pract1: number; - pract2: number; - pract3: number; - pract4: number; - pract5: number; -}; - -type ChartBeneficialPracticesProps = { - benef: Data; - temoin?: Data; -}; - -export const ChartBeneficialPractices: ChartComponentType< - ChartBeneficialPracticesProps -> = ({ benef, temoin }) => { - const { t } = useTranslation("all4trees"); - - const chartData = [ - { - benef: benef.pract1, - indicator: t( - "indicators.socioEco.sections.governance.beneficialPractices.pract1", - ), - temoin: temoin?.pract1, - }, - { - benef: benef.pract2, - indicator: t( - "indicators.socioEco.sections.governance.beneficialPractices.pract2", - ), - temoin: temoin?.pract2, - }, - { - benef: benef.pract3, - indicator: t( - "indicators.socioEco.sections.governance.beneficialPractices.pract3", - ), - temoin: temoin?.pract3, - }, - { - benef: benef.pract4, - indicator: t( - "indicators.socioEco.sections.governance.beneficialPractices.pract4", - ), - temoin: temoin?.pract4, - }, - { - benef: benef.pract5, - indicator: t( - "indicators.socioEco.sections.governance.beneficialPractices.pract5", - ), - temoin: temoin?.pract5, - }, - ]; - - return ( - - ); -}; - -ChartBeneficialPractices.isChartComponent = true; diff --git a/webapp/src/features/charts/socio-eco/chart-energy-sources.tsx b/webapp/src/features/charts/socio-eco/chart-energy-sources.tsx deleted file mode 100644 index 9ac64fc6..00000000 --- a/webapp/src/features/charts/socio-eco/chart-energy-sources.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { useTranslation } from "@shared/i18n"; - -import { BarCharWithBenefAndControl } from "../components/bar-chart-benef-control"; -import type { ChartComponentType } from "../components/chart-component"; - -type Data = { - fw_coll: number; - fw_pur: number; - fw_rec: number; - coal: number; - crop: number; - man: number; - gaz: number; - oth: number; -}; - -type ChartEnergySourcesProps = { - benef: Data; - temoin?: Data; -}; - -export const ChartFuelSources: ChartComponentType = ({ - benef, - temoin, -}) => { - const { t } = useTranslation("all4trees"); - - const chartData = [ - { - benef: benef.fw_coll, - indicator: t( - "indicators.socioEco.sections.wood.energySources.collectedWood", - ), - temoin: temoin?.fw_coll, - }, - { - benef: benef.fw_pur, - indicator: t( - "indicators.socioEco.sections.wood.energySources.boughtWood", - ), - temoin: temoin?.fw_pur, - }, - { - benef: benef.fw_rec, - indicator: t("indicators.socioEco.sections.wood.energySources.recWood"), - temoin: temoin?.fw_rec, - }, - { - benef: benef.coal, - indicator: t("indicators.socioEco.sections.wood.energySources.coal"), - temoin: temoin?.coal, - }, - { - benef: benef.crop, - indicator: t( - "indicators.socioEco.sections.wood.energySources.organicWaste", - ), - temoin: temoin?.crop, - }, - { - benef: benef.man, - indicator: t( - "indicators.socioEco.sections.wood.energySources.animalWaste", - ), - temoin: temoin?.man, - }, - { - benef: benef.gaz, - indicator: t("indicators.socioEco.sections.wood.energySources.gas"), - temoin: temoin?.gaz, - }, - { - benef: benef.oth, - indicator: t("indicators.socioEco.sections.wood.energySources.other"), - temoin: temoin?.oth, - }, - ]; - - return ( - - ); -}; - -ChartFuelSources.isChartComponent = true; diff --git a/webapp/src/features/charts/socio-eco/chart-firewood-needs.tsx b/webapp/src/features/charts/socio-eco/chart-firewood-needs.tsx deleted file mode 100644 index a6303378..00000000 --- a/webapp/src/features/charts/socio-eco/chart-firewood-needs.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { useTranslation } from "@shared/i18n"; -import type { ChartConfig } from "@shared/ui/chart"; - -import type { ChartComponentType } from "../components/chart-component"; -import { - PieChartCategorical, - renderLabel, -} from "../components/pie-chart-categorical"; - -type PieChartProps = { - data: { - easyToMeet: number; - moderateToMeet: number; - difficultToMeet: number; - dontKnow: number; - }; -}; - -export const ChartFireWoodNeeds: ChartComponentType = ({ - data, -}) => { - const { t } = useTranslation("all4trees"); - const chartData = [ - { - fill: "var(--chart-1)", - name: "easyToMeet", - value: data.easyToMeet, - }, - { - fill: "var(--chart-3)", - name: "moderateToMeet", - value: data.moderateToMeet, - }, - { - fill: "var(--chart-6)", - name: "difficultToMeet", - value: data.difficultToMeet, - }, - { - fill: "var(--chart-2)", - name: "dontKnow", - value: data.dontKnow, - }, - ]; - - const chartConfig = { - difficultToMeet: { - label: t("indicators.socioEco.sections.wood.needs.difficultToMeet"), - }, - dontKnow: { - label: t("indicators.socioEco.sections.wood.needs.dontKnow"), - }, - easyToMeet: { - label: t("indicators.socioEco.sections.wood.needs.easyToMeet"), - }, - moderateToMeet: { - label: t("indicators.socioEco.sections.wood.needs.moderateToMeet"), - }, - } satisfies ChartConfig; - - return ( - - renderLabel({ ...props, chartConfig, linebreak: 18 }) - } - /> - ); -}; - -ChartFireWoodNeeds.isChartComponent = true; diff --git a/webapp/src/features/charts/socio-eco/chart-food-diversity.tsx b/webapp/src/features/charts/socio-eco/chart-food-diversity.tsx deleted file mode 100644 index 11b94b31..00000000 --- a/webapp/src/features/charts/socio-eco/chart-food-diversity.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { useTranslation } from "@shared/i18n"; - -import { BarCharWithBenefAndControl } from "../components/bar-chart-benef-control"; -import type { ChartComponentType } from "../components/chart-component"; - -type Data = { - cer: number; - egg: number; - fish: number; - fru: number; - tub: number; - meat: number; - puls: number; - veg: number; - dairy: number; -}; - -type ChartFoodDiversityProps = { - benef: Data; - temoin?: Data; -}; - -export const ChartFoodDiversity: ChartComponentType< - ChartFoodDiversityProps -> = ({ benef, temoin }) => { - const { t } = useTranslation("all4trees"); - - const chartData = [ - { - benef: benef.cer, - indicator: t("indicators.socioEco.sections.food.diversity.cereals"), - temoin: temoin?.cer, - }, - { - benef: benef.egg, - indicator: t("indicators.socioEco.sections.food.diversity.eggs"), - temoin: temoin?.egg, - }, - { - benef: benef.fish, - indicator: t("indicators.socioEco.sections.food.diversity.fish"), - temoin: temoin?.fish, - }, - { - benef: benef.meat, - indicator: t("indicators.socioEco.sections.food.diversity.meat"), - temoin: temoin?.meat, - }, - { - benef: benef.fru, - indicator: t("indicators.socioEco.sections.food.diversity.fruits"), - temoin: temoin?.fru, - }, - { - benef: benef.veg, - indicator: t("indicators.socioEco.sections.food.diversity.vegetables"), - temoin: temoin?.veg, - }, - { - benef: benef.tub, - indicator: t("indicators.socioEco.sections.food.diversity.roots"), - temoin: temoin?.tub, - }, - { - benef: benef.puls, - indicator: t("indicators.socioEco.sections.food.diversity.seeds"), - temoin: temoin?.puls, - }, - { - benef: benef.dairy, - indicator: t("indicators.socioEco.sections.food.diversity.dairy"), - temoin: temoin?.dairy, - }, - ]; - - return ( - - ); -}; - -ChartFoodDiversity.isChartComponent = true; diff --git a/webapp/src/features/charts/socio-eco/chart-living-condition.tsx b/webapp/src/features/charts/socio-eco/chart-living-condition.tsx deleted file mode 100644 index ce8203d3..00000000 --- a/webapp/src/features/charts/socio-eco/chart-living-condition.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { useTranslation } from "@shared/i18n"; -import type { ChartConfig } from "@shared/ui/chart"; - -import type { ChartComponentType } from "../components/chart-component"; -import { PieChartCategorical } from "../components/pie-chart-categorical"; - -type PieChartProps = { - data: { - improvement: number; - stable: number; - regression: number; - dontKnow: number; - refuse: number; - }; -}; - -export const ChartLivingCondition: ChartComponentType = ({ - data, -}) => { - const { t } = useTranslation("all4trees"); - const chartData = [ - { - fill: "var(--chart-1)", - name: "improvement", - value: data.improvement, - }, - { - fill: "var(--chart-5)", - name: "stable", - value: data.stable, - }, - { - fill: "var(--chart-6)", - name: "regression", - value: data.regression, - }, - { - fill: "var(--chart-3)", - name: "refuse", - value: data.refuse, - }, - { - fill: "var(--chart-2)", - name: "dontKnow", - value: data.dontKnow, - }, - ]; - - const chartConfig = { - dontKnow: { - label: t( - "indicators.socioEco.sections.economy.livingPerception.dontKnow", - ), - }, - improvement: { - label: t( - "indicators.socioEco.sections.economy.livingPerception.improvement", - ), - }, - refuse: { - label: t("indicators.socioEco.sections.economy.livingPerception.refuse"), - }, - regression: { - label: t( - "indicators.socioEco.sections.economy.livingPerception.regression", - ), - }, - stable: { - label: t("indicators.socioEco.sections.economy.livingPerception.stable"), - }, - } satisfies ChartConfig; - - return ( - - ); -}; - -ChartLivingCondition.isChartComponent = true; diff --git a/webapp/src/features/charts/socio-eco/chart-timber-needs.tsx b/webapp/src/features/charts/socio-eco/chart-timber-needs.tsx deleted file mode 100644 index 47d26a2c..00000000 --- a/webapp/src/features/charts/socio-eco/chart-timber-needs.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { useTranslation } from "@shared/i18n"; -import type { ChartConfig } from "@shared/ui/chart"; - -import type { ChartComponentType } from "../components/chart-component"; -import { - PieChartCategorical, - renderLabel, -} from "../components/pie-chart-categorical"; - -type PieChartProps = { - data: { - easyToMeet: number; - moderateToMeet: number; - difficultToMeet: number; - dontKnow: number; - }; -}; - -export const ChartTimberNeeds: ChartComponentType = ({ - data, -}) => { - const { t } = useTranslation("all4trees"); - const chartData = [ - { - fill: "var(--chart-1)", - name: "easyToMeet", - value: data.easyToMeet, - }, - { - fill: "var(--chart-3)", - name: "moderateToMeet", - value: data.moderateToMeet, - }, - { - fill: "var(--chart-6)", - name: "difficultToMeet", - value: data.difficultToMeet, - }, - { - fill: "var(--chart-2)", - name: "dontKnow", - value: data.dontKnow, - }, - ]; - - const chartConfig = { - difficultToMeet: { - label: t("indicators.socioEco.sections.wood.needs.difficultToMeet"), - }, - dontKnow: { - label: t("indicators.socioEco.sections.wood.needs.dontKnow"), - }, - easyToMeet: { - label: t("indicators.socioEco.sections.wood.needs.easyToMeet"), - }, - moderateToMeet: { - label: t("indicators.socioEco.sections.wood.needs.moderateToMeet"), - }, - } satisfies ChartConfig; - - return ( - - renderLabel({ ...props, chartConfig, linebreak: 18 }) - } - /> - ); -}; - -ChartTimberNeeds.isChartComponent = true; diff --git a/webapp/src/features/charts/socio-eco/constants.ts b/webapp/src/features/charts/socio-eco/constants.ts new file mode 100644 index 00000000..3e85b6a4 --- /dev/null +++ b/webapp/src/features/charts/socio-eco/constants.ts @@ -0,0 +1,15 @@ +export const SATISFACTION_COLOR_MAP = new Map([ + ["1", "var(--chart-1)"], + ["2", "var(--chart-3)"], + ["3", "var(--chart-6)"], + ["98", "var(--chart-2)"], + ["99", "var(--chart-5)"], +]); + +export const EVOLUTION_COLOR_MAP = new Map([ + ["1", "var(--chart-1)"], + ["2", "var(--chart-6)"], + ["3", "var(--chart-5)"], + ["98", "var(--chart-2)"], + ["99", "var(--chart-3)"], +]); diff --git a/webapp/src/features/charts/socio-eco/index.ts b/webapp/src/features/charts/socio-eco/index.ts deleted file mode 100644 index b0f690c9..00000000 --- a/webapp/src/features/charts/socio-eco/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { ChartBeneficialPractices } from "./chart-beneficial-practices"; -export { ChartFuelSources } from "./chart-energy-sources"; -export { ChartFireWoodNeeds } from "./chart-firewood-needs"; -export { ChartFoodDiversity } from "./chart-food-diversity"; -export { ChartLivingCondition } from "./chart-living-condition"; -export { ChartTimberNeeds } from "./chart-timber-needs"; diff --git a/webapp/src/features/indicators/bio-inventory/format-data.ts b/webapp/src/features/indicators/bio-inventory/format-data.ts index 679dcade..937685b1 100644 --- a/webapp/src/features/indicators/bio-inventory/format-data.ts +++ b/webapp/src/features/indicators/bio-inventory/format-data.ts @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; +import { findLabel } from "@features/indicators/labels"; import { - findLabel, formatTaxonAbundance, preciseNumericIndicators, UNITS, diff --git a/webapp/src/features/indicators/bio-inventory/use-bioinventory-indicator-elements.tsx b/webapp/src/features/indicators/bio-inventory/use-bioinventory-indicator-elements.tsx index 6cd90fec..5bbd79cd 100644 --- a/webapp/src/features/indicators/bio-inventory/use-bioinventory-indicator-elements.tsx +++ b/webapp/src/features/indicators/bio-inventory/use-bioinventory-indicator-elements.tsx @@ -1,7 +1,7 @@ import { Gem, PawPrint, Ruler, SearchAlert, VectorSquare } from "lucide-react"; +import { ChartTaxonAbundance } from "@features/charts"; import { ChartSpeciesStatus } from "@features/charts/bioinventory/chart-species-status"; -import { ChartTaxonAbundance } from "@features/charts/components/chart-taxon-abundance"; import type { BioInventoryData } from "@features/popup/bio-inventory/types"; import type { ExternalData } from "@entities/data"; diff --git a/webapp/src/features/indicators/economy/format-data.ts b/webapp/src/features/indicators/economy/format-data.ts index 8e278ce6..e5617ab8 100644 --- a/webapp/src/features/indicators/economy/format-data.ts +++ b/webapp/src/features/indicators/economy/format-data.ts @@ -46,14 +46,12 @@ export const useFormatEconomicData = (data: SocioEcoData) => { economy: { assetsIndex: `${safeData.assets_idx}/10`, incomeSourceNb: safeData.nb_income_sources, - livingConditionsPerception: { - dontKnow: safeData.living_cond_perception[HISTOGRAM_KEYS.DONT_KNOW], - improvement: - safeData.living_cond_perception[HISTOGRAM_KEYS.IMPROVEMENT], - refuse: safeData.living_cond_perception[HISTOGRAM_KEYS.REFUSE], - regression: safeData.living_cond_perception[HISTOGRAM_KEYS.REGRESSION], - stable: safeData.living_cond_perception[HISTOGRAM_KEYS.STABLE], - }, + livingConditionsPerception: Object.fromEntries( + Object.entries(HISTOGRAM_KEYS).map(([_, value]) => [ + value, + safeData.living_cond_perception[value], + ]), + ), revenueChange: `${safeData.revenue_change} %`, }, governance: { diff --git a/webapp/src/features/indicators/economy/use-economic-indicator-elements.tsx b/webapp/src/features/indicators/economy/use-economic-indicator-elements.tsx index e816e870..732862b4 100644 --- a/webapp/src/features/indicators/economy/use-economic-indicator-elements.tsx +++ b/webapp/src/features/indicators/economy/use-economic-indicator-elements.tsx @@ -1,11 +1,12 @@ import { ChartLine, HandCoins, Scroll } from "lucide-react"; -import { - ChartBeneficialPractices, - ChartLivingCondition, -} from "@features/charts/socio-eco"; +import { LabeledBarChart, LabeledPieChart } from "@features/charts"; +import { EVOLUTION_COLOR_MAP } from "@features/charts/socio-eco/constants"; import type { SocioEcoData } from "@features/popup/socio-eco"; +import type { ExternalData } from "@entities/data"; +import { SOCIO_LABEL_FIELDS } from "@entities/socio-eco"; + import { useTranslation } from "@i18n"; import { ICON_SIZE } from "../components/constants"; @@ -15,6 +16,7 @@ import { useFormatEconomicData } from "./format-data"; export const useEconomicIndicatorElements = ( rawData: SocioEcoData, + externalData: ExternalData, ): UseIndicatorReturnType => { const { t } = useTranslation("all4trees"); const data = useFormatEconomicData(rawData); @@ -38,8 +40,15 @@ export const useEconomicIndicatorElements = ( iconStart={} value={data.economy.assetsIndex} /> - ), @@ -49,18 +58,18 @@ export const useEconomicIndicatorElements = ( }, { children: ( - <> - {/* Not implemented yet, waiting for All4Trees to better define this indicator. - */} - - + ), identifier: "indicator-governance", title: t("indicators.socioEco.sections.governance.title"), diff --git a/webapp/src/features/indicators/labels.ts b/webapp/src/features/indicators/labels.ts new file mode 100644 index 00000000..cd0a48eb --- /dev/null +++ b/webapp/src/features/indicators/labels.ts @@ -0,0 +1,86 @@ +import type { LayerMetadata } from "coordo"; + +import type { BioSpeciesData, LabelData } from "@entities/data"; + +export function findCategoricalLabel( + metadata: LayerMetadata, + fieldName: string, + fieldValue: any, +): string | undefined { + // Searching field category in main resource schema + const resourceLabel = metadata?.resource?.schema?.fields + .find((f) => f.name === fieldName) + ?.categories?.find((c) => c.value === fieldValue)?.label; + + if (resourceLabel) { + return resourceLabel; + } + + // Searching field category in main resource's references' schemas + return metadata?.references + ?.find((ref) => + ref.schema.fields + .find((f) => f.name === fieldName) + ?.categories?.some((c) => c.value === fieldValue), + ) + ?.schema.fields.find((f) => f.name === fieldName) + ?.categories?.find((c) => c.value === fieldValue)?.label; +} + +// Find status of corresponding taxon value. +export function findStatus( + resourceData: BioSpeciesData[], + project: string, + lang: string, + taxon: number, +): string | undefined { + if (!resourceData || !Array.isArray(resourceData)) { + return undefined; + } + + // Find the record matching all criteria: project, list_name, and name + const record = resourceData.find((item: BioSpeciesData) => { + return item.proj?.trim() === project.trim() && item.tax3 === taxon; + }); + + return record?.[`stat::${lang}` as keyof BioSpeciesData] as string; +} + +export function findLabel( + resourceData: LabelData[], + project: string, + lang: string, + fieldName: string, + fieldValue: any, +): string | undefined { + return findMatchingRecord(resourceData, project, fieldName, fieldValue)?.[ + `label::${lang}` + ]; +} + +export function findMatchingRecord( + resourceData: LabelData[], + project: string, + fieldName: string, + fieldValue: any, +): any { + if (!resourceData || !Array.isArray(resourceData)) { + return undefined; + } + + // Find the record matching all criteria: project, list_name, and name + const record = resourceData.find((item: LabelData) => { + if (typeof item.name !== typeof fieldValue) { + console.warn( + `Checking field values with different types ! fieldName=${fieldName} fieldValue type=${typeof fieldValue}; item.name type= ${typeof item.name}`, + ); + } + return ( + item.proj?.trim() === project.trim() && + item.list_name?.trim() === fieldName.trim() && + item.name === fieldValue + ); + }); + + return record; +} diff --git a/webapp/src/features/indicators/social/format-data.ts b/webapp/src/features/indicators/social/format-data.ts index ca68e901..c0e48fab 100644 --- a/webapp/src/features/indicators/social/format-data.ts +++ b/webapp/src/features/indicators/social/format-data.ts @@ -30,6 +30,33 @@ const indicatorKeys: NumericKeys[] = [ "food_self_suff_score", ]; +// Lean months order mapping +const monthOrder: Record = { + apr: 3, + aug: 7, + dec: 11, + feb: 1, + jan: 0, + jull: 6, + jun: 5, + mar: 2, + may: 4, + nov: 10, + oct: 9, + sep: 8, +}; + +export const sortByMonth = (monthDict: Record) => { + return Object.keys(monthDict) + .sort((a, b) => monthOrder[a] - monthOrder[b]) + .reduce( + (acc, key) => { + acc[key] = monthDict[key]; + return acc; + }, + {} as Record, + ); +}; /** * Return data in a convenient way for UI rendering, handling units and fixing */ @@ -53,6 +80,9 @@ export const useFormatSocialData = (data: SocioEcoData) => { data.household_nb, "0", ); + safeData.lean_months = sortByMonth( + convertDictToPercentage(safeData.lean_months, data.household_nb, "0"), + ); return { food: { @@ -62,6 +92,7 @@ export const useFormatSocialData = (data: SocioEcoData) => { safeData.food_self_suff_score, UNITS.percentFoodRequirements, ), + leanMonths: safeData.lean_months, leanPeriod: formatWithUnit(safeData.lean_period, UNITS.monthPerYear), }, wood: { @@ -74,19 +105,19 @@ export const useFormatSocialData = (data: SocioEcoData) => { UNITS.m3PerHabPerYear, ), firewoodNeeds: { - difficultToMeet: Number(safeData.firewood_satis3), - dontKnow: Number(safeData.firewood_satis98), - easyToMeet: Number(safeData.firewood_satis1), - moderateToMeet: Number(safeData.firewood_satis2), - refuse: Number(safeData.firewood_satis99), + "1": Number(safeData.firewood_satis1), + "2": Number(safeData.firewood_satis2), + "3": Number(safeData.firewood_satis3), + "98": Number(safeData.firewood_satis98), + "99": Number(safeData.firewood_satis99), }, fuelSources: safeData.fuel_sources, timberNeeds: { - difficultToMeet: Number(safeData.timber_satis3), - dontKnow: Number(safeData.timber_satis98), - easyToMeet: Number(safeData.timber_satis1), - moderateToMeet: Number(safeData.timber_satis2), - refuse: Number(safeData.timber_satis99), + "1": Number(safeData.timber_satis1), + "2": Number(safeData.timber_satis2), + "3": Number(safeData.timber_satis3), + "98": Number(safeData.timber_satis98), + "99": Number(safeData.timber_satis99), }, }, }; diff --git a/webapp/src/features/indicators/social/types.ts b/webapp/src/features/indicators/social/types.ts index ad9baebb..abbc9de8 100644 --- a/webapp/src/features/indicators/social/types.ts +++ b/webapp/src/features/indicators/social/types.ts @@ -13,6 +13,7 @@ export type SocialData = { timber_satis98: number; timber_satis99: number; lean_period: number; + lean_months: any; food_diversity: any; food_diversity_score: number; food_self_suff_score: number; diff --git a/webapp/src/features/indicators/social/use-social-indicator-elements.tsx b/webapp/src/features/indicators/social/use-social-indicator-elements.tsx index bee0574a..00c21d84 100644 --- a/webapp/src/features/indicators/social/use-social-indicator-elements.tsx +++ b/webapp/src/features/indicators/social/use-social-indicator-elements.tsx @@ -1,15 +1,14 @@ import { Calendar, Hourglass, Soup, Wheat, Zap } from "lucide-react"; -import { - ChartFireWoodNeeds, - ChartFoodDiversity, - ChartFuelSources, - ChartTimberNeeds, -} from "@features/charts/socio-eco"; +import { LabeledBarChart, LabeledPieChart } from "@features/charts"; +import { SATISFACTION_COLOR_MAP } from "@features/charts/socio-eco/constants"; import { IndicatorRawValue } from "@features/indicators/components/indicator-raw-value"; import type { UseIndicatorReturnType } from "@features/indicators/components/types"; import type { SocioEcoData } from "@features/popup/socio-eco"; +import type { ExternalData } from "@entities/data"; +import { SOCIO_LABEL_FIELDS } from "@entities/socio-eco"; + import { useTranslation } from "@i18n"; import { ICON_SIZE } from "../components/constants"; @@ -17,6 +16,7 @@ import { useFormatSocialData } from "./format-data"; export const useSocialIndicatorElements = ( rawData: SocioEcoData, + externalData: ExternalData, ): UseIndicatorReturnType => { const { t } = useTranslation("all4trees"); const data = useFormatSocialData(rawData); @@ -25,19 +25,42 @@ export const useSocialIndicatorElements = ( { children: ( <> - + } value={data.wood.energyConsumption} /> - + } value={data.wood.collectionTime} /> - + ), identifier: "indicator-wood", @@ -47,22 +70,42 @@ export const useSocialIndicatorElements = ( { children: ( <> - } - value={data.food.foodDiversityScore} - /> - + + } + value={data.food.foodDiversityScore} + /> + } value={data.food.foodSelfSufficiency} /> - } - value={data.food.leanPeriod} - /> + + } + value={data.food.leanPeriod} + /> + ), identifier: "indicator-food", diff --git a/webapp/src/features/indicators/soil/use-soil-indicator-elements.tsx b/webapp/src/features/indicators/soil/use-soil-indicator-elements.tsx index 6780dfa8..00aa4a1b 100644 --- a/webapp/src/features/indicators/soil/use-soil-indicator-elements.tsx +++ b/webapp/src/features/indicators/soil/use-soil-indicator-elements.tsx @@ -1,6 +1,6 @@ import { Bug, Gem, Sprout } from "lucide-react"; -import { ChartTaxonAbundance } from "@features/charts/components/chart-taxon-abundance"; +import { ChartTaxonAbundance } from "@features/charts"; import { ChartAquaticErosion } from "@features/charts/soil/ui/chart-aquatic-erosion"; import { ChartWindErosion } from "@features/charts/soil/ui/chart-wind-erosion"; import type { UseIndicatorReturnType } from "@features/indicators//components/types"; diff --git a/webapp/src/features/indicators/utils.ts b/webapp/src/features/indicators/utils.ts index fc8d9236..9104a044 100644 --- a/webapp/src/features/indicators/utils.ts +++ b/webapp/src/features/indicators/utils.ts @@ -1,7 +1,4 @@ -import type { BioSpeciesData, LabelData } from "@entities/data"; - import { useTranslation } from "@shared/i18n"; -import type { LayerMetadata } from "@shared/lib/coordo"; import { precise } from "@shared/lib/utils"; import type { NumericKeys } from "@shared/types"; @@ -30,7 +27,7 @@ export const useFormatterWithUnit = () => { function formatWithUnit( value: number | string | null | undefined, unit: Unit, - ): string | null { + ): string { const noDataStr = t("dataManagement.noData", { ns: "common" }); if (value == null || value === noDataStr) { return noDataStr; @@ -170,86 +167,3 @@ export function computeScore(value: number): number { return 4 - Math.floor(Math.log10(value)); } - -export function findCategoricalLabel( - metadata: LayerMetadata, - fieldName: string, - fieldValue: any, -): string | undefined { - // Searching field category in main resource schema - const resourceLabel = metadata?.resource?.schema?.fields - .find((f) => f.name === fieldName) - ?.categories?.find((c) => c.value === fieldValue)?.label; - - if (resourceLabel) { - return resourceLabel; - } - - // Searching field category in main resource's references' schemas - return metadata?.references - ?.find((ref) => - ref.schema.fields - .find((f) => f.name === fieldName) - ?.categories?.some((c) => c.value === fieldValue), - ) - ?.schema.fields.find((f) => f.name === fieldName) - ?.categories?.find((c) => c.value === fieldValue)?.label; -} - -// Find status of corresponding taxon value. -export function findStatus( - resourceData: BioSpeciesData[], - project: string, - lang: string, - taxon: number, -): string | undefined { - if (!resourceData || !Array.isArray(resourceData)) { - return undefined; - } - - // Find the record matching all criteria: project, list_name, and name - const record = resourceData.find((item: BioSpeciesData) => { - return item.proj?.trim() === project.trim() && item.tax3 === taxon; - }); - - return record?.[`stat::${lang}` as keyof BioSpeciesData] as string; -} - -export function findLabel( - resourceData: LabelData[], - project: string, - lang: string, - fieldName: string, - fieldValue: any, -): string | undefined { - return findMatchingRecord(resourceData, project, fieldName, fieldValue)?.[ - `label::${lang}` - ]; -} - -export function findMatchingRecord( - resourceData: LabelData[], - project: string, - fieldName: string, - fieldValue: any, -): any { - if (!resourceData || !Array.isArray(resourceData)) { - return undefined; - } - - // Find the record matching all criteria: project, list_name, and name - const record = resourceData.find((item: LabelData) => { - if (typeof item.name !== typeof fieldValue) { - console.warn( - `Checking field values with different types ! fieldName=${fieldName} fieldValue type=${typeof fieldValue}; item.name type= ${typeof item.name}`, - ); - } - return ( - item.proj?.trim() === project.trim() && - item.list_name?.trim() === fieldName.trim() && - item.name === fieldValue - ); - }); - - return record; -} diff --git a/webapp/src/features/popup/bio-inventory/popup-bio-inventory.tsx b/webapp/src/features/popup/bio-inventory/popup-bio-inventory.tsx index 003ec52b..f2ab5b27 100644 --- a/webapp/src/features/popup/bio-inventory/popup-bio-inventory.tsx +++ b/webapp/src/features/popup/bio-inventory/popup-bio-inventory.tsx @@ -6,7 +6,7 @@ import { useBioInventoryIndicatorElements } from "@features/indicators/bio-inven import { ICON_SIZE_HEADER } from "@features/indicators/components/constants"; import { IndicatorElements } from "@features/indicators/components/indicator-elements"; import { IndicatorScrollContainer } from "@features/indicators/components/indicator-scroll-container"; -import { findLabel } from "@features/indicators/utils"; +import { findLabel } from "@features/indicators/labels"; import { IndicatorPopupHeader } from "@features/popup/components/indicator-popup-header"; import { formatDate } from "@shared/lib/utils"; diff --git a/webapp/src/features/popup/forest-inventory/popup-forest-inventory.tsx b/webapp/src/features/popup/forest-inventory/popup-forest-inventory.tsx index a744a0ca..c8687648 100644 --- a/webapp/src/features/popup/forest-inventory/popup-forest-inventory.tsx +++ b/webapp/src/features/popup/forest-inventory/popup-forest-inventory.tsx @@ -7,8 +7,8 @@ import { useBiodiversityIndicatorElements } from "@features/indicators/biodivers import { ICON_SIZE_HEADER } from "@features/indicators/components/constants"; import { IndicatorElements } from "@features/indicators/components/indicator-elements"; import { IndicatorScrollContainer } from "@features/indicators/components/indicator-scroll-container"; +import { findLabel } from "@features/indicators/labels"; import { useSoilIndicatorElements } from "@features/indicators/soil"; -import { findLabel } from "@features/indicators/utils"; import { i18nInstance } from "@shared/i18n"; import { formatDate } from "@shared/lib/utils"; diff --git a/webapp/src/features/popup/socio-eco/popup-socio-eco.tsx b/webapp/src/features/popup/socio-eco/popup-socio-eco.tsx index 07dac99b..84460dbc 100644 --- a/webapp/src/features/popup/socio-eco/popup-socio-eco.tsx +++ b/webapp/src/features/popup/socio-eco/popup-socio-eco.tsx @@ -1,19 +1,22 @@ import { cx } from "class-variance-authority"; import { UsersIcon } from "lucide-react"; -import { Activity, type FC, useState } from "react"; +import { Activity, type FC, use, useState } from "react"; import { ICON_SIZE_HEADER } from "@features/indicators/components/constants"; import { IndicatorElements } from "@features/indicators/components/indicator-elements"; import { IndicatorScrollContainer } from "@features/indicators/components/indicator-scroll-container"; import { useEconomicIndicatorElements } from "@features/indicators/economy"; +import { findLabel } from "@features/indicators/labels"; import { useSocialIndicatorElements } from "@features/indicators/social/use-social-indicator-elements"; -import { findCategoricalLabel } from "@features/indicators/utils"; import { IndicatorPopupHeader } from "@features/popup/components/indicator-popup-header"; -import type { LayerMetadata } from "@shared/lib/coordo"; +import type { LabelData } from "@entities/data"; +import { LABEL_DATA } from "@entities/resources"; + +import { LAYERS } from "@shared/api/layers"; import { formatDate } from "@shared/lib/utils"; import { GridSelector } from "@shared/ui/grid-selector"; -import { useTranslation } from "@i18n"; +import { i18nInstance, useTranslation } from "@i18n"; import type { RenderPopupProps } from "../renderPopup"; import type { SocioEcoData } from "./types"; @@ -27,36 +30,25 @@ const TABS: Record = { RESOURCES: "resources", } as const; -const exctractVillageName = ( - metadata: LayerMetadata, - data: SocioEcoData, -): string => { - const label = findCategoricalLabel(metadata, "loc2", data.loc2); - - let villageName: string | undefined; - if (label) { - const jsonLabel = JSON.parse(label); - villageName = - jsonLabel["Malagasy(mg)"] ?? jsonLabel["Fran\u00e7ais(fr)"] ?? undefined; - } - - return villageName || data.loc2; -}; - export const SocioEcoIndicator: FC = ({ data, - metadata, + externalDataPromise, className, ...headerProps }) => { const { t } = useTranslation("all4trees"); const [selectedTab, setSelectedTab] = useState(TABS.RESOURCES); + const lang = i18nInstance.language; + + const externalData = use(externalDataPromise); + const labelData = + externalData[LABEL_DATA.get(LAYERS.ENQUETE) || ""] || ([] as LabelData[]); - const socialElements = useSocialIndicatorElements(data); - const economicElements = useEconomicIndicatorElements(data); + const socialElements = useSocialIndicatorElements(data, externalData); + const economicElements = useEconomicIndicatorElements(data, externalData); const title = t("popup.socioEco.title", { - village: exctractVillageName(metadata, data), + village: findLabel(labelData, data.project, lang, "loc2", data.loc2), }); const tabs = { [TABS.RESOURCES]: t("indicators.resources.title"), diff --git a/webapp/src/features/popup/socio-eco/types.ts b/webapp/src/features/popup/socio-eco/types.ts index efd9f65f..77358d8e 100644 --- a/webapp/src/features/popup/socio-eco/types.ts +++ b/webapp/src/features/popup/socio-eco/types.ts @@ -2,8 +2,13 @@ import type { EconomicData } from "@features/indicators/economy/types"; import type { SocialData } from "@features/indicators/social/types"; export type SocioEcoData = { - household_nb: number; - population: number; + project: string; + year: number; + cohort: number; + type: number; + loc1: string; loc2: string; + population: number; + household_nb: number; } & SocialData & EconomicData; diff --git a/webapp/src/shared/i18n/translations/en/all4trees.json b/webapp/src/shared/i18n/translations/en/all4trees.json index c33a3dd1..579ac653 100644 --- a/webapp/src/shared/i18n/translations/en/all4trees.json +++ b/webapp/src/shared/i18n/translations/en/all4trees.json @@ -93,11 +93,6 @@ "assetsIndex": "Material assets index", "incomeSourceNb": "Number of sources of income per household", "livingPerception": { - "dontKnow": "Don't know", - "improvement": "Improvement", - "refuse": "Refuse to respond", - "regression": "Regression", - "stable": "No change", "title": "Perception of changes in living conditions" }, "revenueChange": "Revenue changes", @@ -106,30 +101,20 @@ "food": { "autoConso": "Food self-sufficiency", "diversity": { - "cereals": "Cereals", - "dairy": "Dairy", - "eggs": "Eggs", - "fish": "Fish", - "fruits": "Fruits", "legend": "of households consume this food group", - "meat": "Meat", - "roots": "Roots", - "seeds": "Seeds", - "title": "Food groups consumed", - "vegetables": "Vegetables" + "title": "Food groups consumed" }, "diversityScore": "Dietary diversity score", - "leanPeriod": "Duration of the lean season", + "lean": { + "duration": "Mean duration of the lean season", + "legend": "of households", + "title": "Lean period" + }, "title": "Food resources" }, "governance": { "beneficialPractices": { "legend": "of households adopted this practice", - "pract1": "Tree planting", - "pract2": "Contour farming", - "pract3": "Intercropping", - "pract4": "Crop rotation", - "pract5": "Composting", "title": "Adoption of good practices" }, "conflictIndex": "Conflict Index", @@ -142,23 +127,9 @@ "title": "Satisfaction of wood energy needs" }, "energySources": { - "animalWaste": "Animal waste", - "boughtWood": "Bought wood", - "coal": "Coal", - "collectedWood": "Collected wood", - "gas": "Gas", "legend": "of households use the resource", - "organicWaste": "Organic waste", - "other": "Other", - "recWood": "Received wood", "title": "Energy sources usage" }, - "needs": { - "difficultToMeet": "Difficult to meet", - "dontKnow": "Don't know", - "easyToMeet": "Easy to meet", - "moderateToMeet": "Moderate to meet" - }, "timberNeeds": { "title": "Satisfaction of timber needs" }, diff --git a/webapp/src/shared/i18n/translations/fr/all4trees.json b/webapp/src/shared/i18n/translations/fr/all4trees.json index 762165d8..fe66b6b8 100644 --- a/webapp/src/shared/i18n/translations/fr/all4trees.json +++ b/webapp/src/shared/i18n/translations/fr/all4trees.json @@ -92,11 +92,6 @@ "assetsIndex": "Indice de patrimoine", "incomeSourceNb": "Nombre de sources de revenus par ménage", "livingPerception": { - "dontKnow": "Ne sait pas", - "improvement": "Amélioration", - "refuse": "Refuse de répondre", - "regression": "Dégradation", - "stable": "Pas de changement", "title": "Perception de l’évolution des conditions de vie" }, "revenueChange": "Evolution du montant des revenus", @@ -105,30 +100,20 @@ "food": { "autoConso": "Satisfaction des besoins en auto-consommation", "diversity": { - "cereals": "Céréales", - "dairy": "Produits Laitiers", - "eggs": "Œufs", - "fish": "Poisson", - "fruits": "Fruits", "legend": "des ménages consomment ce groupe alimentaire", - "meat": "Viande", - "roots": "Racines", - "seeds": "Graines", - "title": "Groupes alimentaires consommés", - "vegetables": "Légumes" + "title": "Groupes alimentaires consommés" }, "diversityScore": "Score de diversité alimentaire", - "leanPeriod": "Durée de la pérode de soudure", + "lean": { + "duration": "Durée moyenne de la période de soudure", + "legend": "des ménages", + "title": "Pérode de soudure" + }, "title": "Ressources alimentaires" }, "governance": { "beneficialPractices": { "legend": "des ménages ont adopté cette pratique", - "pract1": "Plantation", - "pract2": "Cultures en courbes de niveau", - "pract3": "Association de cultures", - "pract4": "Rotation des cultures", - "pract5": "Fabrication de compost", "title": "Pratiques bénéfiques adoptées" }, "conflictIndex": "Indice de conflictualité", @@ -141,23 +126,9 @@ "title": "Satisfaction des besoins en bois-énergie" }, "energySources": { - "animalWaste": "Déchets animaux", - "boughtWood": "Bois acheté", - "coal": "Charbon", - "collectedWood": "Bois collecté", - "gas": "Gaz", "legend": "des ménages utilisent la ressource", - "organicWaste": "Déchets végétaux", - "other": "Autres", - "recWood": "Bois offert", "title": "Sources d’énergie utilisées" }, - "needs": { - "difficultToMeet": "Difficile à satisfaire", - "dontKnow": "Ne sait pas", - "easyToMeet": "Facile à satisfaire", - "moderateToMeet": "Moyennement facile à satisfaire" - }, "timberNeeds": { "title": "Satisfaction des besoins en bois d’œuvre" },