From 24abdb54b8def7496cb015079ba2715f53342c79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Viktor=20K=C3=B6ves?=
<3187531+vkoves@users.noreply.github.com>
Date: Thu, 24 Sep 2026 19:46:20 -0500
Subject: [PATCH 1/2] Add property types sort toggle
---
src/pages/PropertyTypes.vue | 55 +++++++++++++++++++++++++++++++------
src/scss/global.scss | 38 +++++++++++++++++++++++++
2 files changed, 85 insertions(+), 8 deletions(-)
diff --git a/src/pages/PropertyTypes.vue b/src/pages/PropertyTypes.vue
index 4c677c68..4b417f85 100644
--- a/src/pages/PropertyTypes.vue
+++ b/src/pages/PropertyTypes.vue
@@ -37,6 +37,9 @@ interface IPropertyTypeSummary {
imgUrl: string | null;
}
+/** The fields the property type list can be sorted by */
+type PropertyTypeSortField = 'buildingCount' | 'totalGHGEmissions';
+
/**
* Total emissions across every property type we have stats for, used as the
* denominator for each type's share. This covers a few types that don't have
@@ -69,17 +72,33 @@ export default class PropertyTypes extends Vue {
/** Set by Gridsome to results of the static GraphQL query */
readonly $static!: { allBuilding: { edges: Array } };
+ /** The sort options shown in the toggle, in display order */
+ readonly SortOptions: Array<{ field: PropertyTypeSortField; label: string }> =
+ [
+ { field: 'buildingCount', label: 'Most Buildings' },
+ { field: 'totalGHGEmissions', label: 'Highest Emissions' },
+ ];
+
+ /** All property types that have a generated page, unsorted */
+ propertyTypes: Array = [];
+
/**
- * All property types that have a generated page, sorted by building count
- * descending, since the largest categories are the most useful to browse
+ * The field to sort by, descending. Defaults to building count since the
+ * largest categories are the most useful to browse
*/
- propertyTypes: Array = [];
+ sortField: PropertyTypeSortField = 'buildingCount';
+
+ get sortedPropertyTypes(): Array {
+ return [...this.propertyTypes].sort(
+ (a, b) => b[this.sortField] - a[this.sortField],
+ );
+ }
created(): void {
const featuredBuildings = this.buildFeaturedBuildingMap();
- this.propertyTypes = PropertyTypesConstant.propertyTypes
- .map((propertyType: string) => {
+ this.propertyTypes = PropertyTypesConstant.propertyTypes.map(
+ (propertyType: string) => {
const stats = (
BuildingStatsByPropertyType as Record
)[propertyType] as PropertyTypeStats | undefined;
@@ -103,8 +122,8 @@ export default class PropertyTypes extends Vue {
? (getBuildingImage(featuredBuilding)?.imgUrl ?? null)
: null,
};
- })
- .sort((a, b) => b.buildingCount - a.buildingCount);
+ },
+ );
}
/**
@@ -201,8 +220,24 @@ export default class PropertyTypes extends Vue {
city as a whole is trending.
+
+
+
+
-
+
Date: Thu, 24 Sep 2026 19:59:30 -0500
Subject: [PATCH 2/2] Add emissions share rank
---
src/pages/PropertyTypes.vue | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/pages/PropertyTypes.vue b/src/pages/PropertyTypes.vue
index 4b417f85..d09fd7b3 100644
--- a/src/pages/PropertyTypes.vue
+++ b/src/pages/PropertyTypes.vue
@@ -30,6 +30,8 @@ interface IPropertyTypeSummary {
totalGHGEmissions: number;
/** Share of all benchmarked emissions, as a percent (e.g. 12.4) */
percentOfTotalEmissions: number;
+ /** Rank by total emissions among all property types, 1 being the highest */
+ emissionsRank: number;
avgGHGIntensity: number;
/** The largest building of this type that has a photo, if any */
featuredBuilding: IBuilding | null;
@@ -37,6 +39,9 @@ interface IPropertyTypeSummary {
imgUrl: string | null;
}
+/** Only show a property type's emissions rank if it's at least this high */
+const MaxEmissionsRankShown = 10;
+
/** The fields the property type list can be sorted by */
type PropertyTypeSortField = 'buildingCount' | 'totalGHGEmissions';
@@ -88,6 +93,8 @@ export default class PropertyTypes extends Vue {
*/
sortField: PropertyTypeSortField = 'buildingCount';
+ readonly MaxEmissionsRankShown = MaxEmissionsRankShown;
+
get sortedPropertyTypes(): Array {
return [...this.propertyTypes].sort(
(a, b) => b[this.sortField] - a[this.sortField],
@@ -116,6 +123,8 @@ export default class PropertyTypes extends Vue {
percentOfTotalEmissions: CitywideTotalEmissions
? (totalGHGEmissions / CitywideTotalEmissions) * 100
: 0,
+ // Set below, once we have every type's emissions to compare
+ emissionsRank: 0,
avgGHGIntensity: stats?.GHGIntensity?.mean ?? 0,
featuredBuilding,
imgUrl: featuredBuilding
@@ -124,6 +133,12 @@ export default class PropertyTypes extends Vue {
};
},
);
+
+ [...this.propertyTypes]
+ .sort((a, b) => b.totalGHGEmissions - a.totalGHGEmissions)
+ .forEach((type, index) => {
+ type.emissionsRank = index + 1;
+ });
}
/**
@@ -294,6 +309,14 @@ export default class PropertyTypes extends Vue {
}}
of total benchmarked
+
+
+ #{{ type.emissionsRank }}
+ highest
+
@@ -437,7 +460,8 @@ export default class PropertyTypes extends Vue {
font-size: 1rem;
}
- .type-percent {
+ .type-percent,
+ .type-rank {
display: block;
font-size: 0.875rem;
color: $text-mid-light;