Skip to content

Commit

Permalink
Merge pull request #399 from forza-mor-rotterdam/dashboard-taken
Browse files Browse the repository at this point in the history
dashboard: taken aantallen meer dan 2 per melding
  • Loading branch information
mguikema authored Sep 19, 2024
2 parents 32c11c6 + e38a431 commit 6632727
Show file tree
Hide file tree
Showing 6 changed files with 378 additions and 19 deletions.
175 changes: 175 additions & 0 deletions app/apps/dashboard/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,3 +767,178 @@ def tijdsvak_status_gemiddelden(_afgehandeld, wijk, _statussen):
"body": wijken[:aantal],
}
return doorlooptijden_per_wijk


def get_taaktype_aantallen_per_melding_tabs(
taaktype_aantallen_per_melding, ticks=[], onderwerp=None, wijk=None
):
labels = [t.get("label") for t in ticks]

alle_wijken = [wijk.get("wijknaam") for wijk in PDOK_WIJKEN]
wijken = [wijk.get("wijknaam") for wijk in PDOK_WIJKEN]
wijken_noord = [
wijk.get("wijknaam") for wijk in PDOK_WIJKEN if wijk.get("stadsdeel") == "Noord"
]
wijken_zuid = [
wijk.get("wijknaam") for wijk in PDOK_WIJKEN if wijk.get("stadsdeel") == "Zuid"
]
maximum_taaktype_aantal_over_tijdsvakken = sorted(
[
taaktype.get("aantal_per_melding")
for tijdsvak in taaktype_aantallen_per_melding
for taaktype in tijdsvak
],
reverse=True,
)
maximum_taaktype_aantal_over_tijdsvakken = (
maximum_taaktype_aantal_over_tijdsvakken[0] + 1
if maximum_taaktype_aantal_over_tijdsvakken
else 1
)

def get_kleur(i, max):
hr = 7
h = i - 2
max = max - 2
step = h / (max - 1)
ll = hr * step
h = round(hr - ll)
h = hex(h)
h = h.split("x")[1]
h = h.rstrip("L")
k = f"#ff{h}{h}00"
return k

datasets = [
{
"bron": taaktype_aantallen_per_melding,
"aantal": i,
"backgroundColor": get_kleur(i, maximum_taaktype_aantal_over_tijdsvakken),
}
for i in range(2, maximum_taaktype_aantal_over_tijdsvakken)
]
tabs = (
[
{
"wijken": [],
"wijk_not_in": True,
"titel": "Heel Rotterdam",
},
{
"wijken": wijken_noord,
"wijk_not_in": False,
"titel": "Rotterdam noord",
},
{
"wijken": wijken_zuid,
"wijk_not_in": False,
"titel": "Rotterdam zuid",
},
{
"wijken": wijken,
"wijk_not_in": True,
"titel": "Onbekend of buiten Rotterdam",
},
]
if not wijk
else [
{
"wijken": [w for w in alle_wijken if wijk == w],
"wijk_not_in": False,
"titel": wijk,
}
]
)

def tab_aantal(tab):
t = [
round(
(
sum(
[
d.get("melding_aantal")
for d in tijdsvak
if d.get("aantal_per_melding") > 1
and bool(d.get("wijk") in tab.get("wijken"))
!= bool(tab.get("wijk_not_in"))
and (not onderwerp or onderwerp == d.get("onderwerp"))
]
)
/ sum(
[
d.get("melding_aantal")
for d in tijdsvak
if bool(d.get("wijk") in tab.get("wijken"))
!= bool(tab.get("wijk_not_in"))
and (not onderwerp or onderwerp == d.get("onderwerp"))
]
)
)
* 100
)
if sum(
[
d.get("melding_aantal")
for d in tijdsvak
if bool(d.get("wijk") in tab.get("wijken"))
!= bool(tab.get("wijk_not_in"))
and (not onderwerp or onderwerp == d.get("onderwerp"))
]
)
else 0
for tijdsvak in taaktype_aantallen_per_melding
]
return round(average(t))

def tijdsvak_data(tijdsvak, dataset, tab):
totaal_melding_aantallen = sum(
[
d.get("melding_aantal")
for d in tijdsvak
if bool(d.get("wijk") in tab.get("wijken"))
!= bool(tab.get("wijk_not_in"))
and (not onderwerp or onderwerp == d.get("onderwerp"))
]
)
melding_aantallen = sum(
[
d.get("melding_aantal")
for d in tijdsvak
if d.get("aantal_per_melding") == dataset.get("aantal")
and bool(d.get("wijk") in tab.get("wijken"))
!= bool(tab.get("wijk_not_in"))
and (not onderwerp or onderwerp == d.get("onderwerp"))
]
)
return (
round((melding_aantallen / totaal_melding_aantallen) * 100)
if totaal_melding_aantallen
else 0
)

def tijdsvak_label(dataset):
return f'Aantal {dataset.get("aantal")}'

tabs = [
{
"titel": tab.get("titel"),
"labels": labels,
"aantal": tab_aantal(tab),
"datasets": [
{
"type": "bar",
"label": tijdsvak_label(dataset),
"borderColor": "#ffffff",
"fill": True,
"backgroundColor": dataset.get("backgroundColor"),
"data": [
tijdsvak_data(tijdsvak, dataset, tab)
for tijdsvak in dataset.get("bron")
],
}
for dataset in datasets
],
}
for tab in tabs
]
return tabs
4 changes: 3 additions & 1 deletion app/apps/dashboard/templates/charts/base_chart.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ <h4>{{ title }}</h4>
class="{% if forloop.first %} active{% endif %}">
<span class="h3"
{% if data_type %}data-chart-line-target="{{ data_type }}ToHuman" data-duration-to-human-long="true"{% endif %}
data-aantal="{{ tab.aantal }}">{{ tab.aantal }}</span>
data-aantal="{{ tab.aantal }}">{{ tab.aantal }}
{% if eenheid %}{{ eenheid }}{% endif %}
</span>
<span class="decorated">{{ tab.titel }}</span>
</button>
</li>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{% extends "dashboard/base.html" %}
{% load rotterdam_formulier_html %}
{% load l10n %}
{% load humanize %}
{% load tz %}
{% load json_encode from json_tags %}
{% block title %}
Dashboard | PlanR
{% endblock title %}
{% block content %}
<div class="screen-xl">
<section class="section--seperated--l">
<div class="grid-container grid-container--full"
data-controller="chart-utils">
{% include "charts/base_chart.html" with title="Taken aantal 2 of meer per melding" description="Toont taken die meer dan 1 keer zijn aangemaakt in afgehandelde meldingen. Het getal in de popup is het percentage van het totaal aantal meldingen waarin dit gebeurde. In deze grafiek zie je dan ook niet de gevallen waarbij een taak maar 1 keer voorkomt in een melding." period_title=title tabs=taaktype_aantallen_per_melding_tabs options=stacked_bars_options eenheid="%" only %}
</div>
</section>
</div>
<div class="screen-xl--notification">
<p>Deze pagina is alleen te bekijken op een groter scherm.</p>
</div>
<div class="sidesheet sidesheet--dashboardfilter">
<button type="button"
class="btn-close"
aria-label="Sluit"
data-action="sidesheet#toggleFilter">{% include "icons/close.svg" %}</button>
<div class="sidesheet-backdrop sidesheet-exit"
data-action="click->sidesheet#toggleFilter"></div>
<div class="content">{% include "dashboard/form.html" %}</div>
</div>
<div class="sidesheet" data-sidesheet-target="sidesheet">
<button type="button"
class="btn-close"
aria-label="Sluit"
data-action="sidesheet#closeSidesheet">{% include "icons/close.svg" %}</button>
<div class="sidesheet-backdrop sidesheet-exit"
data-action="click->sidesheet#closeSidesheet"></div>
<div class="turboframe-container">
<turbo-frame id="sidesheet" data-sidesheet-target="turboframe"></turbo-frame>
</div>
</div>
{% endblock content %}
108 changes: 91 additions & 17 deletions app/apps/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
get_aantallen_tabs,
get_afgehandeld_tabs,
get_status_veranderingen_tabs,
get_taaktype_aantallen_per_melding_tabs,
top_doorlooptijden_per_onderwerp,
top_doorlooptijden_per_wijk,
top_vijf_aantal_meldingen_onderwerp,
Expand Down Expand Up @@ -324,33 +325,39 @@ def get_periode_type_navigatie(self):
return []

def get_status_navigatie(self):
statussen = {
"nieuw": f"Nieuwe {self.kwargs.get('type')}",
"afgehandeld": f"Afgehandelde {self.kwargs.get('type')}",
}
link_data = [
["meldingen", "nieuw", "Nieuwe meldingen"],
["meldingen", "afgehandeld", "Afgehandelde meldingen"],
["taken", "aantallen", "Taken aantallen"],
]

statussen = {
k: [
v,
reverse(
def get_url(type, status):
try:
return reverse(
"dashboard",
kwargs={
**copy.deepcopy(self.kwargs),
**{
"status": k,
"type": type,
"status": status,
},
},
),
)
except Exception:
return

statussen = [
[
d[2],
""
if self.kwargs.get("status") == d[1] and self.kwargs.get("type") == d[0]
else get_url(d[0], d[1]),
]
for k, v in statussen.items()
}

statussen[self.kwargs.get("status")] = [
statussen[self.kwargs.get("status")][0],
"",
for d in link_data
if get_url(d[0], d[1])
]

return [[v[0], v[1]] for k, v in statussen.items()]
return statussen

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
Expand Down Expand Up @@ -538,3 +545,70 @@ def get_context_data(self, **kwargs):
}
)
return context


@method_decorator(
permission_required("authorisatie.dashboard_bekijken"), name="dispatch"
)
class TaaktypeAantallen(Dashboard):
template_name = "dashboard/taken/taaktype_aantallen.html"

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)

taaktype_aantallen_per_melding = []
meldingen_service = MeldingenService()
for tick in self.x_ticks:
dag = tick.get("start_dt")
days = tick.get("days")
taaktype_aantallen_per_melding_tijdsvak = (
meldingen_service.taaktype_aantallen_per_melding(
datum=dag, days=days, force_cache=False
)
)
taaktype_aantallen_per_melding.append(
taaktype_aantallen_per_melding_tijdsvak
)

taaktype_aantallen_per_melding_tabs = get_taaktype_aantallen_per_melding_tabs(
taaktype_aantallen_per_melding,
ticks=self.x_ticks,
onderwerp=self.onderwerp,
wijk=self.wijk,
)

stacked_bars_options = {
"plugins": {
"legend": {
"display": True,
},
"tooltip": {
"backgroundColor": "#ffffff",
"borderColor": "rgba(0, 0 ,0 , .8)",
"borderWidth": 1,
"bodyAlign": "center",
"bodyColor": "#000000",
"titleColor": "#000000",
"titleAlign": "center",
"displayColors": False,
"borderRadius": 0,
},
},
"scales": {
"x": {"stacked": True},
"y": {
"stacked": True,
"grid": {
"display": False,
},
},
},
}

context.update(
{
"taaktype_aantallen_per_melding_tabs": taaktype_aantallen_per_melding_tabs,
"stacked_bars_options": stacked_bars_options,
}
)
return context
Loading

0 comments on commit 6632727

Please sign in to comment.