From c777896a56a8aa4df25b1323b8c8dfea33ddf511 Mon Sep 17 00:00:00 2001 From: kflemin <2205659+kflemin@users.noreply.github.com> Date: Wed, 6 Nov 2024 23:09:59 -0700 Subject: [PATCH 1/2] update aggregation table --- .../seed/partials/inventory_reports.html | 94 ++++++++++++++----- seed/static/seed/scss/style.scss | 6 ++ seed/views/v3/organizations.py | 37 ++++++-- 3 files changed, 105 insertions(+), 32 deletions(-) diff --git a/seed/static/seed/partials/inventory_reports.html b/seed/static/seed/partials/inventory_reports.html index 8044d5ac2d..f612743d0e 100644 --- a/seed/static/seed/partials/inventory_reports.html +++ b/seed/static/seed/partials/inventory_reports.html @@ -236,28 +236,78 @@

{$ chart2Title | translate $} 

- - - - - - - - - - - - - - - - - - - - - -
AxisAccess Level InstanceSumMin5th Percentile25th PercentileMeanMedian75 Percentile95th PercentileMax
{$ item $}
+

Statistics

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
AxisAccess Level InstanceSumMin5th Percentile25th PercentileMeanMedian75 Percentile95th PercentileMax
{$ key $} + {$ item $} + {$ item | tolerantNumber:2 $} + + + + +
+ + + + + + +
 {$ key2 $} + {$ item $} + {$ item | tolerantNumber:2 $} +
+
+
+
diff --git a/seed/static/seed/scss/style.scss b/seed/static/seed/scss/style.scss index a091629aaf..2367f5af8a 100755 --- a/seed/static/seed/scss/style.scss +++ b/seed/static/seed/scss/style.scss @@ -5683,3 +5683,9 @@ tags-input .tags .tag-item { white-space: normal; min-width: 350px; } + +.no-lr-pad { + padding-left: 0 !important; + padding-right: 0 !important; + padding-top: 0 !important; +} diff --git a/seed/views/v3/organizations.py b/seed/views/v3/organizations.py index 0367424072..8a52d11613 100644 --- a/seed/views/v3/organizations.py +++ b/seed/views/v3/organizations.py @@ -1024,6 +1024,12 @@ def report_aggregated(self, request, pk=None): ys = [building["y"] for datum in data for building in datum["chart_data"] if building["y"] is not None] if ys and isinstance(ys[0], Number): bins = np.histogram_bin_edges(ys, bins=5) + + # special case for year built: make bins integers + # year built is in x axis, but it shows up in y_var variable + if params['y_var'] == 'year_built': + bins = bins.astype(int) + aggregate_data = self.continuous_aggregate_data else: bins = list(set(ys)) @@ -1243,15 +1249,19 @@ def get_axis_stats(self, organization, cycle, axis, axis_var, views, ali): return [axis_var, ali.name, 0, 0, 0, 0, 0, 0, 0, 0, 0] def get_axis_data(self, organization_id, access_level_instance, cycles, x_var, y_var, all_property_views, fields): - axis_data = [] + axis_data = {} axes = {"x": x_var, "y": y_var} organization = Organization.objects.get(pk=organization_id) + # initialize + for cycle in cycles: + axis_data[cycle.name] = {} + for axis in axes: if axes[axis] != "Count": columns = Column.objects.filter(organization_id=organization_id, column_name=axes[axis]) if not columns: - return [] + return {} column = columns[0] if not column.data_type or column.data_type == "None": @@ -1263,22 +1273,29 @@ def get_axis_data(self, organization_id, access_level_instance, cycles, x_var, y serialized_column = ColumnSerializer(column).data add_pint_unit_suffix(organization, serialized_column) for cycle in cycles: + name_to_display = ( serialized_column["display_name"] if serialized_column["display_name"] != "" else serialized_column["column_name"] ) - axis_name = name_to_display + f" ({cycle.name})" + axis_name = name_to_display #+ f" ({cycle.name})" + axis_data[cycle.name][name_to_display] = {} stats = self.get_axis_stats(organization, cycle, axis, axes[axis], all_property_views, access_level_instance) - axis_data.append(self.clean_axis_data(axis_name, data_type, stats)) - for child_ali in access_level_instance.get_children(): - stats = self.get_axis_stats(organization, cycle, axis, axes[axis], all_property_views, child_ali) - axis_data.append(self.clean_axis_data(axis_name, data_type, stats)) + axis_data[cycle.name][name_to_display]['values'] = self.clean_axis_data(data_type, stats) + + children = access_level_instance.get_children() + if len(children): + axis_data[cycle.name][name_to_display]['children'] = {} + for child_ali in children: + stats = self.get_axis_stats(organization, cycle, axis, axes[axis], all_property_views, child_ali) + axis_data[cycle.name][name_to_display]['children'][child_ali.name] = self.clean_axis_data(data_type, stats) + return axis_data - def clean_axis_data(self, column_name, data_type, data): + def clean_axis_data(self, data_type, data): if data_type == "float": - return [column_name] + data[1:3] + np.round(data[3:], decimals=2).tolist() + return data[1:3] + np.round(data[3:], decimals=2).tolist() elif data_type == "integer": - return [column_name] + data[1:3] + np.round(data[3:]).tolist() + return data[1:3] + np.round(data[3:]).tolist() @has_perm_class("requires_member") @ajax_request_class From d0078b2cefe7cc5c42634b0fdfe66717a1815ef0 Mon Sep 17 00:00:00 2001 From: kflemin <2205659+kflemin@users.noreply.github.com> Date: Thu, 7 Nov 2024 09:44:36 -0700 Subject: [PATCH 2/2] precommit --- seed/views/v3/organizations.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/seed/views/v3/organizations.py b/seed/views/v3/organizations.py index 8a52d11613..364ef679b3 100644 --- a/seed/views/v3/organizations.py +++ b/seed/views/v3/organizations.py @@ -1027,7 +1027,7 @@ def report_aggregated(self, request, pk=None): # special case for year built: make bins integers # year built is in x axis, but it shows up in y_var variable - if params['y_var'] == 'year_built': + if params["y_var"] == "year_built": bins = bins.astype(int) aggregate_data = self.continuous_aggregate_data @@ -1273,21 +1273,19 @@ def get_axis_data(self, organization_id, access_level_instance, cycles, x_var, y serialized_column = ColumnSerializer(column).data add_pint_unit_suffix(organization, serialized_column) for cycle in cycles: - name_to_display = ( serialized_column["display_name"] if serialized_column["display_name"] != "" else serialized_column["column_name"] ) - axis_name = name_to_display #+ f" ({cycle.name})" axis_data[cycle.name][name_to_display] = {} stats = self.get_axis_stats(organization, cycle, axis, axes[axis], all_property_views, access_level_instance) - axis_data[cycle.name][name_to_display]['values'] = self.clean_axis_data(data_type, stats) + axis_data[cycle.name][name_to_display]["values"] = self.clean_axis_data(data_type, stats) children = access_level_instance.get_children() if len(children): - axis_data[cycle.name][name_to_display]['children'] = {} + axis_data[cycle.name][name_to_display]["children"] = {} for child_ali in children: stats = self.get_axis_stats(organization, cycle, axis, axes[axis], all_property_views, child_ali) - axis_data[cycle.name][name_to_display]['children'][child_ali.name] = self.clean_axis_data(data_type, stats) + axis_data[cycle.name][name_to_display]["children"][child_ali.name] = self.clean_axis_data(data_type, stats) return axis_data