Skip to content

Commit

Permalink
Merge pull request #3149 from SEED-platform/feat/inventory_summary
Browse files Browse the repository at this point in the history
Feat/inventory summary
  • Loading branch information
Ryo committed Mar 14, 2022
2 parents 76b0303 + df19c4c commit a93f8f3
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 68 deletions.
95 changes: 63 additions & 32 deletions seed/static/seed/js/controllers/inventory_summary_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,53 +21,76 @@ angular.module('BE.seed.controller.inventory_summary', [])
cycles_payload,
) {
$scope.inventory_type = $stateParams.inventory_type;
// charts is where we will store references to our charts
const charts = {};

const lastCycleId = inventory_service.get_last_cycle();
$scope.cycle = {
selected_cycle: _.find(cycles_payload.cycles, {id: lastCycleId}) || _.first(cycles_payload.cycles),
cycles: cycles_payload.cycles
};

const draw_charts = function() {
const chartConfigs = [
{ name: 'property_types', x: 'extra_data__Largest Property Use Type', y: 'count', xLabel: 'Property Types'},
{ name: 'year_built', x: 'year_built', y: 'percentage', xLabel: 'Year Built' },
{ name: 'energy', x: 'site_eui', y: 'percentage', xLabel: 'Site EUI' },
{ name: 'square_footage', x: 'gross_floor_area', y: 'percentage' , xLabel: 'Gross Floor Area'},
]
$scope.charts = [
{
name: 'property_types',
chart: null,
x: 'extra_data__Largest Property Use Type',
y: 'count',
xLabel: 'Property Types'
}, {
name: 'year_built',
chart: null,
x: 'year_built',
y: 'percentage',
xLabel:
'Year Built'
}, {
name: 'energy',
chart: null,
x: 'site_eui',
y: 'percentage',
xLabel: 'Site EUI'
}, {
name: 'square_footage',
chart: null,
x: 'gross_floor_area',
y: 'percentage',
xLabel: 'Gross Floor Area'
},
];
let charts_loaded = false;

if (_.isEmpty(charts)) {
// initialize charts
chartConfigs.forEach(config => {
const svg = dimple.newSvg("#chart", 500, 750);
const load_charts = function () {
if (!charts_loaded) {
charts_loaded = true;
$scope.charts.forEach(config => {
const svg = dimple.newSvg("#chart-" + config.name, "100%", 500);
const chart = new dimple.chart(svg, []);
const xaxis = chart.addCategoryAxis('x', config.x);
xaxis.title = config.xLabel;
chart.addMeasureAxis('y', config.y);
chart.addSeries(null, dimple.plot.bar);
charts[config.name] = chart;
})
$scope.charts[config.name] = chart;
});
}

chartConfigs.forEach(config => {
const chart = charts[config.name]
chart.data = $scope.summary_data[config.name]
if ($scope.summary_data[config.name].length > 0) {
chart.svg.select('.missing-data').remove()
} else {
chart.svg
.append('text')
.attr('class', 'missing-data')
.attr('x', 100)
.attr('y', 100)
.attr('dy', '2em')
.text('Insufficient number of properties to summarize')
$scope.charts.forEach(config => {
const chart = $scope.charts[config.name];
if ($scope.summary_data[config.name].length < 1) {
return;
}
chart.draw();
})
}
chart.data = $scope.summary_data[config.name];
chart.svg.select('.missing-data').remove();
$scope.draw_chart(config.name, false);
});
};

$scope.draw_chart = function (chart_name, no_data_change=true) {
if ($scope.summary_data[chart_name].length < 1) {
return;
}
setTimeout(() => {
$scope.charts[chart_name].draw(0, no_data_change);
}, 50);
};

const refresh_data = function () {
$scope.progress = {};
Expand All @@ -91,7 +114,15 @@ angular.module('BE.seed.controller.inventory_summary', [])
}
];

draw_charts();
column_settings_count = data["column_settings fields and counts"];
$scope.column_settings_count = Object.entries(column_settings_count).map(([key, value]) => {
return {
column_settings: key,
count: value
}
});

load_charts();
modalInstance.close()
})
};
Expand Down
3 changes: 1 addition & 2 deletions seed/static/seed/partials/inventory_nav.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@
<a id="reports" ui-sref="reports(::{inventory_type: inventory_type})" ui-sref-active="active" translate>Reports</a>
<a id="inventory-cycles" ui-sref="inventory_cycles(::{inventory_type: inventory_type})" ui-sref-active="active" translate>Cross-Cycles</a>
<a id="inventory-maps" ui-sref="inventory_map(::{inventory_type: inventory_type})" ui-sref-active="active" translate>Map</a>
<!-- disabling this until we can finish polishing this feature -->
<!-- <a id="inventory-summary" ui-sref="inventory_summary(::{inventory_type: inventory_type})" ui-sref-active="active" translate>Summary</a> -->
<a id="inventory-summary" ui-sref="inventory_summary(::{inventory_type: inventory_type})" ui-sref-active="active" translate>Summary</a>
73 changes: 43 additions & 30 deletions seed/static/seed/partials/inventory_summary.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,36 +26,49 @@ <h1>{$:: (inventory_type === 'taxlots' ? 'Tax Lots' : 'Properties') | translate
</div>
</div>

<div class="section inventory-summary">
<div class="section_content_container">
<div class="section_content container-fluid">
<div class="content_block row" style="padding:20px 20px 10px 20px">
<div class="col-md-12">
<div class="row">
<table class="zebra">
<thead>
<tr>
<th>Field</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in table_data">
<td>{$item.text$}</td>
<td>{$item.count$}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="content_block row" style="padding:20px 20px 10px 20px">
<div class="col-md-12">
<div class="row">
<div id="chart"></div>
</div>
</div>
</div>
<div class="inventory-summary columns">
<div class="column">
<div class="row">
<table class="zebra grow">
<thead>
<tr>
<th>Summary</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in table_data">
<td>{$item.text$}</td>
<td>{$item.count$}</td>
</tr>
</tbody>
</table>
</div>
<div class="row">
<table class="zebra grow">
<thead>
<tr>
<th>Field</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in column_settings_count">
<td>{$item.column_settings$}</td>
<td>{$item.count$}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="column">
<div class="row">
<uib-tabset class="grow">
<uib-tab ng-repeat="chart in charts" index="$index" heading="{$:: chart.xLabel $}" ng-click="draw_chart(chart.name)">
<div ng-hide="summary_data[chart.name].length < 1" id="chart-{$:: chart.name $}"></div>
<div ng-hide="summary_data[chart.name].length > 0" style="padding: 10px;">Insufficient number of properties to summarize!</div>
</uib-tab>
</uib-tabset>
</div>
</div>
</div>
58 changes: 56 additions & 2 deletions seed/static/seed/scss/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2330,7 +2330,47 @@ select {

/* Styles for building summary page */

#inventory-summary {
.inventory-summary {
margin: 20px 10px;

table, th, td {
border: 1px solid black;
}

&.columns {
display: flex;
column-gap: 10px;
align-items: start;

.column {
display: flex;
flex-direction: column;
row-gap: 10px;
flex-grow: 1;
}
}

.row {
display: flex;
margin: 0 0;

.grow {
flex-grow: 1;
}
}

.tab-content {
border-width: 0 1px 1px 1px;
border-color: #ddd;
border-style: solid;
}
}

.inventory-summary-controls {
margin: 20px 10px;
}

#column_settings_count {
table, th, td {
border: 1px solid black;
}
Expand Down Expand Up @@ -2781,7 +2821,7 @@ gs-input .tags .tag-item .remove-button {
/* OTHER */

/* Styles for building list controls and table */
.inventory-list-controls, .inventory-summary-controls {
.inventory-list-controls {
padding: 20px 10px;

.form-group {
Expand Down Expand Up @@ -4159,6 +4199,20 @@ iframe.analysis-results {
}
}

.column_settings_count {
table, th, td {
border: 1px solid black;
border-collapse: collapse;
padding: 0.5em;
}
tbody tr:nth-child(odd) {
background: #eee;
}
table {
width: 300px;
}
}

// Inserts an fa-link in front of the element
// Used in the inventory list to identify derived columns
.derived-column-display-name::before {
Expand Down
27 changes: 25 additions & 2 deletions seed/views/v3/analyses.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from seed.analysis_pipelines.pipeline import AnalysisPipeline, AnalysisPipelineException
from seed.decorators import ajax_request_class, require_organization_id_class
from seed.lib.superperms.orgs.decorators import has_perm_class
from seed.models import Analysis, Cycle, PropertyView, PropertyState
from seed.models import Analysis, Cycle, PropertyView, PropertyState, Column
from seed.serializers.analyses import AnalysisSerializer
from seed.utils.api import api_endpoint_class, OrgMixin
from seed.utils.api_schema import AutoSchemaHelper
Expand Down Expand Up @@ -267,6 +267,10 @@ def stats(self, request):

views = PropertyView.objects.filter(state__organization_id=org_id, cycle_id=cycle_id)
states = PropertyState.objects.filter(id__in=views.values_list('state_id', flat=True))
columns = Column.objects.filter(organization_id=org_id)
column_names_extra_data = list(Column.objects.filter(organization_id=org_id, is_extra_data=True).values_list('column_name', flat=True))

col_names = [x for x, y in list(columns.values_list('column_name', 'table_name')) if (y == 'PropertyState')]

def get_counts(field_name):
"""Get aggregated count of each unique value for the field
Expand Down Expand Up @@ -399,12 +403,31 @@ def get_counts(field_name):
g[h['gross_floor_area']] += h['count']
sqftage_list2 = [{'gross_floor_area': gross_floor_area, 'percentage': count / views.count() * 100} for gross_floor_area, count in g.items()]

extra_data_list = []
for data in states.values_list('extra_data', flat=True):
for key, value in data.items():
extra_data_list.append(key)

count_agg = []
for i in col_names:
count_dict = {}
if i in column_names_extra_data:
count_dict[i] = len(list(filter(None, states.values_list('extra_data__' + i, flat=True))))
else:
count_dict[i] = len(list(filter(None, states.values_list(i, flat=True))))
count_agg.append(count_dict)

count_agg_dict = {}
for d in count_agg:
count_agg_dict.update(d)

return JsonResponse({
'status': 'success',
'total_records': views.count(),
'number_extra_data_fields': len(extra_data_count),
'column_settings fields and counts': count_agg_dict,
'existing_extra_data fields and count': extra_data,
'property_types': property_types,
'extra_data fields and count': extra_data,
'year_built': year_built_list,
'energy': energy_list2,
'square_footage': sqftage_list2
Expand Down

0 comments on commit a93f8f3

Please sign in to comment.