Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MEP v8.4.1 #796

Merged
merged 11 commits into from
Dec 17, 2024
13 changes: 12 additions & 1 deletion diagnostic_word/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
from public_data.domain.impermeabilisation.difference.ImpermeabilisationDifferenceService import (
ImpermeabilisationDifferenceService,
)
from public_data.infra.consommation.progression.export.ConsoByDeterminantExportTableMapper import (
ConsoByDeterminantExportTableMapper,
)
from public_data.infra.consommation.progression.export.ConsoComparisonExportTableMapper import (
ConsoComparisonExportTableMapper,
)
Expand Down Expand Up @@ -197,7 +200,15 @@ def get_context_data(self) -> Dict[str, Any]:
series=annual_total_conso_chart.get_series(), line=False
),
"communes_data_table": add_total_line_column(chart_conso_cities.get_series()),
"determinants_data_table": add_total_line_column(det_chart.get_series()),
"determinants_data_table": ConsoByDeterminantExportTableMapper.map(
consommation_progression=PublicDataContainer.consommation_progression_service()
.get_by_land(
land=diagnostic.land_proxy,
start_date=int(diagnostic.analyse_start_date),
end_date=int(diagnostic.analyse_end_date),
)
.consommation
),
# Target 2031
"target_2031_consumed": target_2031_consumption,
"projection_zan_cumulee_ref": round(objective_chart.total_2020, 1),
Expand Down
75 changes: 48 additions & 27 deletions project/charts/AnnualConsoByDeterminantChart.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,67 @@
from project.charts.constants import (
CEREMA_CREDITS,
DEFAULT_VALUE_DECIMALS,
HIGHLIGHT_COLOR,
LEGEND_NAVIGATION_EXPORT,
)
from public_data.domain.containers import PublicDataContainer


class AnnualConsoByDeterminantChart(ProjectChart):
"""
Graphique en barre de consommation annuelle par destination (habitat, activité, mixte etc.)
avec une courbe de consommation totale en pointillés.
"""

name = "determinant per year"

def _get_series(self):
"""
Génère et retourne la liste des séries à utiliser dans le graphique.
"""
consommation_progression = PublicDataContainer.consommation_progression_service().get_by_land(
land=self.project.land_proxy,
start_date=self.project.analyse_start_date,
end_date=self.project.analyse_end_date,
)

category_to_attr = {
"Habitat": "habitat",
"Activité": "activite",
"Mixte": "mixte",
"Route": "route",
"Ferré": "ferre",
"Inconnu": "non_renseigne",
"Total": "total",
}

data = {category: {} for category in category_to_attr.keys()}

for annual_conso in consommation_progression.consommation:
for category, attr in category_to_attr.items():
data[category][annual_conso.year] = getattr(annual_conso, attr)

series = [
{
"name": determinant,
"data": [{"name": year, "y": value} for year, value in data[determinant].items()],
**(
{"id": "main", "type": "column", "zIndex": 0, "stacking": None, "color": "#CFD1E5"}
if determinant == "Total"
else {"type": "column", "stacking": "normal", "zIndex": 1}
),
}
for determinant in data
]

return series

@property
def param(self):
return super().param | {
"chart": {"type": "column"},
"title": {"text": "Par an"},
"yAxis": {
"title": {"text": "Consommation annuelle (en ha)"},
"stackLabels": {"enabled": True, "format": "{total:,.1f}"},
"title": {"text": "Consommation d'espaces NAF (en ha)"},
"stackLabels": {"enabled": True, "format": "{total:,.2f}"},
},
"tooltip": {
"headerFormat": "<b>{point.key}</b><br/>",
Expand All @@ -37,32 +77,13 @@ def param(self):
"align": "right",
"verticalAlign": "middle",
},
"plotOptions": {
"column": {
"stacking": "normal",
"dataLabels": {"enabled": True, "format": "{point.y:,.1f}"},
}
},
"series": [],
"plotOptions": {"series": {"grouping": False, "borderWidth": 0}},
"series": self._get_series(),
}

def get_series(self):
if not self.series:
self.series = self.project.get_determinants(group_name=self.group_name)
return self.series

# To remove after refactoring
def add_series(self):
super().add_series()
if not self.group_name:
self.add_serie(
"Total",
self.project.get_conso_per_year(),
**{
"type": "line",
"color": HIGHLIGHT_COLOR,
"dashStyle": "ShortDash",
},
)
pass


class AnnualConsoByDeterminantChartExport(AnnualConsoByDeterminantChart):
Expand Down
2 changes: 1 addition & 1 deletion project/charts/AnnualTotalConsoChart.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def param(self):
return super().param | {
"chart": {"type": "column"},
"title": {"text": ""},
"yAxis": {"title": {"text": "Consommé (ha)"}},
"yAxis": {"title": {"text": "Consommation d'espaces NAF (ha)"}},
"xAxis": {"type": "category"},
"tooltip": {
"headerFormat": DEFAULT_HEADER_FORMAT,
Expand Down
53 changes: 39 additions & 14 deletions project/charts/ConsoByDeterminantPieChart.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,68 @@
from project.charts.base_project_chart import ProjectChart
from project.charts.constants import CEREMA_CREDITS
from public_data.domain.containers import PublicDataContainer


class ConsoByDeterminantPieChart(ProjectChart):
"""
Graphique en secteurs de consommation totale par destination (habitat, activité, mixte etc.)
"""

name = "determinant overview"

def _get_series(self):
"""
Génère et retourne la liste des séries à utiliser dans le graphique.
"""
consommation_total = PublicDataContainer.consommation_stats_service().get_by_land(
land=self.project.land_proxy,
start_date=self.project.analyse_start_date,
end_date=self.project.analyse_end_date,
)

category_to_attr = {
"Habitat": "habitat",
"Activité": "activite",
"Mixte": "mixte",
"Route": "route",
"Ferré": "ferre",
"Inconnu": "non_renseigne",
}

data = {category: getattr(consommation_total, attr) for category, attr in category_to_attr.items()}

return [
{
"name": "Destinations",
"data": [{"name": category, "y": value} for category, value in data.items()],
}
]

@property
def param(self):
return super().param | {
"chart": {"type": "pie"},
"title": {
"text": "Sur la période",
},
"tooltip": {"enabled": True, "pointFormat": "{point.y:.1f} Ha"},
"tooltip": {"enabled": False},
"plotOptions": {
"pie": {
"allowPointSelect": True,
"cursor": "pointer",
"dataLabels": {
"distance": 15,
"enabled": True,
"format": "{point.name} : {point.y:.1f} Ha",
"format": "{point.name}<br />{point.y:.2f} Ha",
},
}
},
"series": [],
"series": self._get_series(),
}

def __init__(self, *args, **kwargs):
if "series" in kwargs:
self.series = kwargs.pop("series")
super().__init__(*args, **kwargs)

def get_series(self):
if not self.series:
self.series = self.project.get_determinants(group_name=self.group_name)
return {"Destinations": {n: sum(v.values()) for n, v in self.series.items()}}

# To remove after refactoring
def add_series(self):
super().add_series(sliced=True)
pass


class ConsoByDeterminantPieChartExport(ConsoByDeterminantPieChart):
Expand Down
21 changes: 0 additions & 21 deletions project/models/project_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,27 +554,6 @@ def get_look_a_like(self):
self.save(update_fields=["look_a_like"])
return sorted(lands, key=lambda x: x.name)

def get_determinants(self, group_name=None):
from public_data.domain.containers import PublicDataContainer

conso = PublicDataContainer.consommation_progression_service().get_by_land(
land=self.land_proxy,
start_date=self.analyse_start_date,
end_date=self.analyse_end_date,
)
data = {"Habitat": {}, "Activité": {}, "Mixte": {}, "Route": {}, "Ferré": {}, "Inconnu": {}}

for annual_conso in conso.consommation:
year_as_str = str(annual_conso.year)
data["Habitat"][year_as_str] = annual_conso.habitat
data["Activité"][year_as_str] = annual_conso.activite
data["Mixte"][year_as_str] = annual_conso.mixte
data["Route"][year_as_str] = annual_conso.route
data["Ferré"][year_as_str] = annual_conso.ferre
data["Inconnu"][year_as_str] = annual_conso.non_reseigne

return data

def get_bilan_conso(self):
"""Return the space consummed between 2011 and 2020 in hectare"""
from public_data.domain.containers import PublicDataContainer
Expand Down
33 changes: 1 addition & 32 deletions project/templates/project/components/dashboard/consommation.html
Original file line number Diff line number Diff line change
Expand Up @@ -139,38 +139,7 @@ <h6 class="fr-mt-2w">Calcul</h6>
<p class="fr-text--sm">Données brutes, sans calcul</p>

<h6 class="fr-mt-2w">Données</h6>
<div class="fr-table fr-table--bg-whiteed">
<div class="fr-table__wrapper">
<div class="fr-table__container">
<div class="fr-table__content">
<table class="table-last-column-bold table-last-row-bold">
<caption>
Consommation d'espace annuelle sur le territoire par destination (en ha)
</caption>
<thead>
<tr>
<th scope="col" class="fr-cell--fixed">Destination</th>
{% for year in project.years %}
<th scope="col" class="fr-cell--right">{{ year }}</th>
{% endfor %}
<th scope="col" class="fr-cell--right">Total</th>
</tr>
</thead>
<tbody>
{% for determinant_name, data in data_determinant.items %}
<tr>
<th scope="row" class="fr-cell--fixed">{{ determinant_name }}</th>
{% for year, val in data.items %}
<td class="fr-cell--right">+{{ val|floatformat:1 }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{{ determinant_data_table }}
</div>
</div>
</div>
Expand Down
18 changes: 13 additions & 5 deletions project/views/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
from public_data.domain.impermeabilisation.difference.ImperSolTableMapper import (
ImperSolTableMapper,
)
from public_data.infra.consommation.progression.table.ConsoByDeterminantTableMapper import (
ConsoByDeterminantTableMapper,
)
from public_data.infra.consommation.progression.table.ConsoComparisonTableMapper import (
ConsoComparisonMapper,
)
Expand Down Expand Up @@ -104,10 +107,7 @@ def get_context_data(self, **kwargs):

# Déterminants
det_chart = charts.AnnualConsoByDeterminantChart(project)
det_pie_chart = charts.ConsoByDeterminantPieChart(
project,
series=det_chart.get_series(),
)
det_pie_chart = charts.ConsoByDeterminantPieChart(project)

# CONSO
consommation_progression = (
Expand Down Expand Up @@ -174,7 +174,15 @@ def get_context_data(self, **kwargs):
"population_conso_comparison_chart": charts.PopulationConsoComparisonChart(project),
# data tables
"annual_conso_data_table": annual_conso_data_table,
"data_determinant": add_total_line_column(det_chart.get_series()),
"determinant_data_table": ConsoByDeterminantTableMapper.map(
consommation_progression=PublicDataContainer.consommation_progression_service()
.get_by_land(
land=project.land_proxy,
start_date=int(project.analyse_start_date),
end_date=int(project.analyse_end_date),
)
.consommation
),
"comparison_table": ConsoComparisonMapper.map(
consommation_progression=PublicDataContainer.consommation_progression_service().get_by_lands(
lands=project.comparison_lands_and_self_land(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ class AnnualConsommation:
mixte: float
route: float
ferre: float
non_reseigne: float
non_renseigne: float
total: float
per_mille_of_area: float
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ class ConsommationStatistics:
end_date: int
total: float
total_percent: float
activite: float
habitat: float
mixte: float
route: float
ferre: float
non_renseigne: float
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def get_by_land(
mixte=c.mixte / 10000,
route=c.route / 10000,
ferre=c.ferroviaire / 10000,
non_reseigne=c.inconnu / 10000,
non_renseigne=c.inconnu / 10000,
total=c.total / 10000,
per_mille_of_area=c.total / 10000 / land.area * 1000,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from public_data.domain.consommation.entity import ConsommationCollection


class ConsoByDeterminantExportTableMapper:
@staticmethod
def map(consommation_progression: list[ConsommationCollection]):
category_to_attr = {
"Habitat": "habitat",
"Activité": "activite",
"Mixte": "mixte",
"Route": "route",
"Ferré": "ferre",
"Inconnu": "non_renseigne",
"Total": "total",
}

headers = [str(conso.year) for conso in consommation_progression] + ["Total"]

rows = []
for category in category_to_attr:
category_values = [getattr(conso, category_to_attr[category]) for conso in consommation_progression]
category_total = sum(category_values)
# On arrondit ensuite pour ne pas fausser le total
category_values_rounded = [round(value, 2) for value in category_values]
category_total_rounded = round(category_total, 2)
rows.append(
{
"name": category,
"data": category_values_rounded + [category_total_rounded],
}
)

return {
"headers": headers,
"rows": rows,
}
Loading
Loading