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 $}
-
-
-
- Axis |
- Access Level Instance |
- Sum |
- Min |
- 5th Percentile |
- 25th Percentile |
- Mean |
- Median |
- 75 Percentile |
- 95th Percentile |
- Max |
-
-
-
-
- {$ item $} |
-
-
-
+
Statistics
+
+
+
+
+
+
+
+ Axis |
+ Access Level Instance |
+ Sum |
+ Min |
+ 5th Percentile |
+ 25th Percentile |
+ Mean |
+ Median |
+ 75 Percentile |
+ 95th Percentile |
+ Max |
+
+
+
+
+ {$ 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