diff --git a/dm_regional_app/charts.py b/dm_regional_app/charts.py index 6edcf26..df6f3f3 100644 --- a/dm_regional_app/charts.py +++ b/dm_regional_app/charts.py @@ -1,6 +1,9 @@ import plotly.express as px from demand_model.multinomial.predictor import Prediction +from ssda903.datacontainer import DemandModellingDataContainer +from ssda903.population_stats import PopulationStats + def prediction_chart(prediction: Prediction): df_pp = prediction.population.unstack().reset_index() @@ -11,3 +14,24 @@ def prediction_chart(prediction: Prediction): fig.update_layout(title="Prediction") fig_html = fig.to_html(full_html=False) return fig_html + + +def historic_chart(data: PopulationStats): + df_pp = data.stock.unstack().reset_index() + df_pp.columns = ["from", "date", "value"] + df = df_pp[["date", "value"]].groupby(by="date").sum().reset_index() + + # visualise prediction using unstacked dataframe + fig = px.line( + df, + y="value", + x="date", + labels={ + "value": "Number of children", + "date": "Date", + }, + ) + fig.update_layout(title="Historic data") + fig.update_yaxes(rangemode="tozero") + fig_html = fig.to_html(full_html=False) + return fig_html diff --git a/dm_regional_app/forms.py b/dm_regional_app/forms.py index 22453cd..8d333c8 100644 --- a/dm_regional_app/forms.py +++ b/dm_regional_app/forms.py @@ -3,6 +3,7 @@ from crispy_forms.helper import FormHelper from crispy_forms.layout import Column, Layout, Row, Submit from django import forms +from django_select2 import forms as s2forms class PredictFilter(forms.Form): @@ -29,35 +30,58 @@ class HistoricDataFilter(forms.Form): label="End Date", required=True, ) - la = forms.ChoiceField(label="Local Authority", required=False, choices=[]) + la = forms.MultipleChoiceField( + widget=s2forms.Select2MultipleWidget, + label="Local Authority", + required=False, + choices=[], + ) placement_types = forms.MultipleChoiceField( - widget=forms.CheckboxSelectMultiple, + widget=s2forms.Select2MultipleWidget, label="Placement Type", required=False, choices=[], ) + age_bins = forms.MultipleChoiceField( + widget=s2forms.Select2MultipleWidget, + label="Age", + required=False, + choices=[], + ) + uasc = forms.ChoiceField( + label="UASC", + required=False, + choices=[("all", "All"), (True, "UASC only"), (False, "Exclude UASC")], + initial="all", + ) def __init__(self, *args, **kwargs): la_choices = kwargs.pop("la_choices") placement_type_choices = kwargs.pop("placement_type_choices") + age_bin_choices = kwargs.pop("age_bin_choices") super().__init__(*args, **kwargs) - self.fields["la"].choices = [("all", "All")] + [(la, la) for la in la_choices] - self.fields["la"].initial = "all" + self.fields["la"].choices = [(la, la) for la in la_choices] self.fields["placement_types"].choices = [ (placement_type, placement_type) for placement_type in placement_type_choices ] + self.fields["age_bins"].choices = [ + (age_bin, age_bin) for age_bin in age_bin_choices + ] + self.helper = FormHelper() self.helper.layout = Layout( Row( - Column("start_date", css_class="form-group col-md-6 mb-0"), - Column("end_date", css_class="form-group col-md-6 mb-0"), + Column("start_date", css_class="form-group col-md-3 mb-0"), + Column("end_date", css_class="form-group col-md-3 mb-0"), css_class="form-row", ), Row( - Column("la", css_class="form-group col-md-6 mb-0"), - Column("placement_types", css_class="form-group col-md-4 mb-0"), + Column("la", css_class="form-group col-md-3 mb-0"), + Column("placement_types", css_class="form-group col-md-3 mb-0"), + Column("age_bins", css_class="form-group col-md-3 mb-0"), + Column("uasc", css_class="form-group col-md-3 mb-0"), css_class="form-row", ), Submit("submit", "Filter"), @@ -72,8 +96,9 @@ def filter_by_end_date(self, data: pd.DataFrame): return data def filter_by_la(self, data: pd.DataFrame): - if self.cleaned_data["la"] != "all": - data = data.loc[data.LA == self.cleaned_data["la"]] + if self.cleaned_data["la"] != []: + loc = data.LA.astype(str).isin(self.cleaned_data["la"]) + data = data.loc[loc] return data def filter_by_placement_type(self, data: pd.DataFrame): @@ -84,9 +109,24 @@ def filter_by_placement_type(self, data: pd.DataFrame): data = data.loc[loc] return data + def filter_by_age_bin(self, data: pd.DataFrame): + if self.cleaned_data["age_bins"] != []: + loc = data.age_bin.astype(str).isin(self.cleaned_data["age_bins"]) + data = data.loc[loc] + return data + + def filter_by_uasc(self, data: pd.DataFrame): + if self.cleaned_data["uasc"] == "True": + data = data.loc[data.UASC == True] + elif self.cleaned_data["uasc"] == "False": + data = data.loc[data.UASC == True] + return data + def apply_filters(self, data: pd.DataFrame): data = self.filter_by_start_date(data) data = self.filter_by_end_date(data) data = self.filter_by_la(data) data = self.filter_by_placement_type(data) + data = self.filter_by_age_bin(data) + data = self.filter_by_uasc(data) return data diff --git a/dm_regional_app/management/commands/sandbox.py b/dm_regional_app/management/commands/sandbox.py index 9169ee0..636e2a9 100644 --- a/dm_regional_app/management/commands/sandbox.py +++ b/dm_regional_app/management/commands/sandbox.py @@ -22,8 +22,16 @@ class Command(BaseCommand): def handle(self, *args, **kwargs): + """thing = User.objects.all() + for t in thing: + print(t.profile.la)""" datastore = StorageDataStore(default_storage, settings.DATA_SOURCE) config = Config() dc = DemandModellingDataContainer(datastore, config) + pop = PopulationStats(dc.enriched_view, config) - print(dc.enriched_view) + data = dc.enriched_view + print(data.loc[data.UASC == True]) + + # print(pop.stock) + # print(dc.enriched_view) diff --git a/dm_regional_app/templates/dm_regional_app/includes/navbar.html b/dm_regional_app/templates/dm_regional_app/includes/navbar.html index 38ddd0c..e5fcc2f 100644 --- a/dm_regional_app/templates/dm_regional_app/includes/navbar.html +++ b/dm_regional_app/templates/dm_regional_app/includes/navbar.html @@ -14,6 +14,7 @@