diff --git a/src/components/charts/chartController.vue b/src/components/charts/chartController.vue index 06b30a1a..426e35f4 100644 --- a/src/components/charts/chartController.vue +++ b/src/components/charts/chartController.vue @@ -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() @@ -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) @@ -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) { @@ -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 '' } } } diff --git a/src/components/charts/linechart.js b/src/components/charts/linechart.js index 21a0b460..84f9d9fc 100644 --- a/src/components/charts/linechart.js +++ b/src/components/charts/linechart.js @@ -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) { @@ -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') !== '', diff --git a/src/components/extras/heropicture.vue b/src/components/extras/heropicture.vue index 0e762136..a986b394 100644 --- a/src/components/extras/heropicture.vue +++ b/src/components/extras/heropicture.vue @@ -6,9 +6,8 @@
-
1) { this.$router.push({ path: `/compare/${encodeURI(JSON.stringify(this.compareStories))}/2` }) @@ -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 = " " diff --git a/src/components/map/map_compareside.vue b/src/components/map/map_compareside.vue index 790faf20..c5b7bcf6 100644 --- a/src/components/map/map_compareside.vue +++ b/src/components/map/map_compareside.vue @@ -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 @@ -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') + } + } + } } } diff --git a/src/components/map/map_prompt.vue b/src/components/map/map_prompt.vue index 96c33dd0..29df8bce 100644 --- a/src/components/map/map_prompt.vue +++ b/src/components/map/map_prompt.vue @@ -11,19 +11,36 @@ - Select buildings by clicking on map or using building menu search bar.

- NOTE: Only buildings with Electricity data are valid for comparison! + Select buildings by clicking on map or using building menu search bar.

+ Select one building (Any Energy Type) for comparison across multiple time periods

+ Select multiple buildings (Electricity) to be compared across a single time period

- - Compare + + Compare ({{ Math.min(4, compareStories.length) }} Buildings) Quick Compare Compare in FullScreen + + Compare (1 Building) + Cancel @@ -32,6 +49,11 @@