Skip to content

Commit

Permalink
Merge pull request #283 from OSU-Sustainability-Office/multiple-time-…
Browse files Browse the repository at this point in the history
…periods

Multiple time periods comparison feature
  • Loading branch information
s-egge authored Jan 18, 2024
2 parents f2cf6cf + 0d670e4 commit 105167b
Show file tree
Hide file tree
Showing 14 changed files with 538 additions and 60 deletions.
76 changes: 76 additions & 0 deletions src/components/charts/chartController.vue
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@ export default {
data.datasets[0].data.length >= 1
) {
this.chart.update()
// format charts if there are multiple time periods
if (this.multipleTimePeriods(data.datasets)) {
this.formatMultipleTimePeriods(data.datasets)
}
let timeDif =
new Date(data.datasets[0].data[data.datasets[0].data.length - 1].x).getTime() -
new Date(data.datasets[0].data[0].x).getTime()
Expand All @@ -252,6 +258,7 @@ export default {
this.chart.options.scales.yAxes[0].ticks.maxTicksLimit = (this.height / 200) * 8 - dif
}
this.chartData = data
console.log(this.path)
this.loading = false
// console.log('done loading!', this.path, data)
Expand Down Expand Up @@ -330,6 +337,12 @@ export default {
}
return point
} else {
// if there are multiple time period charts, don't display a label on the bottom as the time
// periods will be displayed individually on the top
if (this.multipleTimePeriods(this.chartData.datasets)) {
return ' '
}
const date1 = new Date(this.dateStart)
const date2 = new Date(this.dateEnd)
if (date1 && date2) {
Expand All @@ -338,6 +351,69 @@ export default {
return ' '
}
}
},
multipleTimePeriods: function (charts) {
if (charts.length > 1 && charts[0].multStart.length > 1) {
return true
}
return false
},
// this formats a chart with multiple time periods, changing labels, aligning all charts to the left,
// and mapping datasets so that hovering displays the correct date
formatMultipleTimePeriods: function (charts) {
// change the labels to match the time period for each chart
for (let chart of charts) {
chart.label = chart.data[0].x.toDateString() + ' to ' + chart.data[chart.data.length - 1].x.toDateString()
}
// find chart with largest dataset
let largestChart = charts[0]
for (let i in charts) {
if (charts[i].data.length > largestChart.data.length) {
largestChart = charts[i]
}
}
// map all other datasets to the largest dataset
for (let chart of charts) {
// check if current chart is the largest chart, don't map if so
// may need a better way to differentiate charts, but this works for now
// and accounts for have two charts that are the same length
if (chart.backgroundColor !== largestChart.backgroundColor) {
// loop through all data points in current chart and map x-value to largest chart
// also create a datapoint for the original x-value so that we can display it on tooltip hover
for (let i in chart.data) {
if (chart.data[i].y != null) {
chart.data[i].originalX = chart.data[i].x
chart.data[i].x = largestChart.data[i].x
}
}
}
}
},
// this is called when there are multiple time period charts, it returns an array of all the
// chart dates for that index so that they can be displayed on multiple lines
buildXaxisTick (index) {
if (this.chartData.datasets) {
let tick = []
for (let chart of this.chartData.datasets) {
let date = ''
if (chart.data[index]) {
if (chart.data[index].originalX) {
date = chart.data[index].originalX.toLocaleDateString('en-US', { month: 'numeric', day: 'numeric' })
} else {
date = chart.data[index].x.toLocaleDateString('en-US', { month: 'numeric', day: 'numeric' })
}
}
tick.push(date)
}
return tick
}
return ''
}
}
}
Expand Down
16 changes: 14 additions & 2 deletions src/components/charts/linechart.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ export default {
tooltips: {
callbacks: {
title: function (item, data) {
let d = new Date(item[0].xLabel)
let originalXlabel = data.datasets[item[0].datasetIndex].data[item[0].index].originalX
// use originalXlabel if it exists, otherwise use the default xLabel
let d = new Date(originalXlabel || item[0].xLabel)
let meridiem = 'am'
let hours = d.getHours()
if (hours > 12) {
Expand Down Expand Up @@ -142,7 +144,17 @@ export default {
fontFamily: 'Open Sans',
autoSkip: true,
stepSize: 10,
source: 'data'
source: 'data',
// the following three settings change the x-ticks if there are multiple time periods,
// otherwise the default settings are used
autoSkipPadding: this.$parent.multipleTimePeriods(this.$parent.chartData.datasets) ? 10 : 3,
maxRotation: this.$parent.multipleTimePeriods(this.$parent.chartData.datasets) ? 0 : 50,
callback: (val, index) => {
if (this.$parent.multipleTimePeriods(this.$parent.chartData.datasets)) {
return this.$parent.buildXaxisTick(index)
}
return val
}
},
scaleLabel: {
display: this.$parent.buildLabel('y') !== '',
Expand Down
3 changes: 1 addition & 2 deletions src/components/extras/heropicture.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
<div
v-if="this.media[0].length <= 1 || this.media.length <= 1"
:style="`background-image:linear-gradient(to right bottom, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.2)),url(https://osu-energy-images.s3-us-west-2.amazonaws.com/thumbnails/${this.media}); width:calc(100%); height:100%`"
:key="media"
:key="media + 1"
></div>

<div
v-else-if="this.mediaArray.length === 2"
v-for="(media, index) in this.media"
Expand Down
11 changes: 9 additions & 2 deletions src/components/map/map.vue
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,11 @@ export default {
try {
if (this.building_compare_error === false) {
let path = this.$store.getters['map/building'](this.compareStories[0]).path
if (target !== 'q' && this.compareStories.length === 1) {
this.$router.push({
path: `/compare/${encodeURI(JSON.stringify(this.compareStories))}/2`
})
}
let mgId = this.$store.getters[path + '/primaryGroup']('Electricity').id
let blockSpace = this.$store.getters[path + '/block'](mgId).path
await this.$store.dispatch(blockSpace + '/removeAllModifiers')
Expand All @@ -391,7 +396,7 @@ export default {
name: 'map_compare_side',
path: path
})
} else {
} else if (target !== 'q' && this.compareStories.length > 1) {
this.$router.push({
path: `/compare/${encodeURI(JSON.stringify(this.compareStories))}/2`
})
Expand All @@ -410,7 +415,9 @@ export default {
this.showSide = false
this.askingForComparison = true
this.compareStories = []
this.compareStories.push(buildingId)
if (buildingId !== undefined) {
this.compareStories.push(buildingId)
}
const data =
"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'><circle cx='256' cy='256' r='246' fill='#D73F09' stroke='#FFF' stroke-width='20'/> <path transform='scale(0.7 0.7) translate(76.8 86.8)' fill='#FFF' d='M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z'></path></svg>"
Expand Down
26 changes: 26 additions & 0 deletions src/components/map/map_compareside.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ export default {
return buildingIds.map(id => this.$store.getters['map/building'](id))
}
},
buildingBlocks: {
get () {
let buildingBlockArray = []
for (let building of this.buildings) {
// Use spread syntax (...) to create an array of objects, instead of 2d array
buildingBlockArray.push(...this.$store.getters[building.path + '/blocks'])
}
return buildingBlockArray
}
},
mediaArray: {
get () {
if (!this.buildings) return
Expand Down Expand Up @@ -154,6 +164,22 @@ export default {
return 'slantImage'
}
}
},
// Refer to "buildings" and "buildingBlocks" in "computed" section above
// Use buildings > blocks > charts as far as global vuex store getter calls
watch: {
buildings: {
immediate: true,
handler: async function (value) {
for (let buildingBlock of this.buildingBlocks) {
let blockpath = buildingBlock.path
let searchTerm = 'block_'
let chartIndex = blockpath.indexOf(searchTerm)
let blockID = blockpath.slice(chartIndex + searchTerm.length)
this.$store.commit(blockpath + '/chart_' + blockID + '/resetMultTimeStamps')
}
}
}
}
}
</script>
Expand Down
34 changes: 28 additions & 6 deletions src/components/map/map_prompt.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,36 @@
<el-col :span="24">
<el-row>
<el-col class="text">
Select buildings by clicking on map or using building menu search bar. <br /><br />
<el-row>NOTE: Only buildings with Electricity data are valid for comparison!</el-row>
Select buildings by clicking on map or using building menu search bar.<br /><br />
Select one building (Any Energy Type) for comparison across multiple time periods <br /><br />
Select multiple buildings (Electricity) to be compared across a single time period<br /><br />
</el-col>
</el-row>
<el-row>
<el-col>
<el-dropdown split-button type="info" class="button" @click="handle('q')" @command="handle">
Compare
<el-dropdown
split-button
type="info"
class="button"
v-if="compareStories && compareStories.length !== 1"
@click="handle('q')"
@command="handle"
>
Compare ({{ Math.min(4, compareStories.length) }} Buildings)
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="q">Quick Compare</el-dropdown-item>
<el-dropdown-item command="d">Compare in FullScreen</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-button
type="info"
class="button"
v-if="compareStories && compareStories.length === 1"
@click="handle('d')"
@command="handle"
>
Compare (1 Building)
</el-button>
<el-button class="button" type="info" @click="$emit('cancel')">Cancel</el-button>
</el-col>
</el-row>
Expand All @@ -32,6 +49,11 @@
</template>
<script>
export default {
props: {
compareStories: {
type: Array
}
},
methods: {
handle: function (command) {
this.$emit('compare', command)
Expand All @@ -42,7 +64,7 @@ export default {
<style lang="scss" scoped>
.stage_prompt {
width: 400px;
height: 150px;
height: 210px;
position: absolute;
top: 20px;
left: calc(50% - 200px);
Expand Down Expand Up @@ -71,7 +93,7 @@ export default {
top: 100px;
width: 330px;
left: 250px;
height: 200px;
height: 300px;
}
}
</style>
8 changes: 4 additions & 4 deletions src/components/map/prompt_error.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<el-col class="text">
ERROR <br />
<el-row
>You have either not selected any buildings for comparison, or you have included a non-electric
building.</el-row
>You have either not selected any buildings for comparison, or you have included a non-electric building
(for multiple buildings comparison).</el-row
>
</el-col>
</el-row>
Expand All @@ -24,7 +24,7 @@ export default {}
<style lang="scss" scoped>
.stage_prompt {
width: 400px;
height: 150px;
height: 170px;
position: absolute;
top: 20px;
left: calc(50% - 200px);
Expand Down Expand Up @@ -53,7 +53,7 @@ export default {}
top: 80px;
width: 330px;
left: 250px;
height: 180px;
height: 210px;
}
}
</style>
5 changes: 5 additions & 0 deletions src/components/map/sideView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ export default {
this.index = 0
for (let block of this.buildingBlocks) {
await this.$store.dispatch(block.path + '/resetDefault')
let blockpath = block.path
let searchTerm = 'block_'
let chartIndex = blockpath.indexOf(searchTerm)
let blockID = blockpath.slice(chartIndex + searchTerm.length)
this.$store.commit(blockpath + '/chart_' + blockID + '/resetMultTimeStamps')
}
this.$refs.prevArrow.style.display = 'none'
if (this.buildingBlocks.length > 1) {
Expand Down
Loading

0 comments on commit 105167b

Please sign in to comment.