From aa44cd66f30a1839301a1065eead703dc8ac8679 Mon Sep 17 00:00:00 2001 From: solderq35 Date: Sat, 23 Dec 2023 20:34:46 -0800 Subject: [PATCH] working proof of concept with edit menu ui --- src/components/extras/heropicture.vue | 4 +- src/components/view/modals/edit_card.vue | 61 ++++++++++++- src/components/view/view.vue | 49 ++++++++-- src/store/block.module.js | 33 ++++++- .../block_modifiers/building_compare.mod.js | 13 ++- src/store/chart.module.js | 91 +++++++++++++++++-- 6 files changed, 228 insertions(+), 23 deletions(-) diff --git a/src/components/extras/heropicture.vue b/src/components/extras/heropicture.vue index 0e762136..edbb726b 100644 --- a/src/components/extras/heropicture.vue +++ b/src/components/extras/heropicture.vue @@ -6,9 +6,9 @@
- +
Ok - Cancel + + Save Time Period {{ this.form.tempMultStart.length + 1 }} + + Cancel + @@ -268,7 +279,9 @@ export default { end: '', intUnit: 1, graphType: 1, - sets: [] + sets: [], + tempMultStart: [], + tempMultEnd: [] } } }, @@ -289,6 +302,12 @@ export default { return this.$route.path.includes('compare') } }, + // Check only one building is in comparison, e.g. for "save time period" button + compareOneBuildingView: { + get () { + return this.$route.path.includes('compare') && JSON.parse(JSON.stringify(this.form.sets)).length === 1 + } + }, personalView: { get () { let viewPath = this.$store.getters['modalController/data'].path @@ -352,6 +371,7 @@ export default { intervalUnit: this.interval(this.form.intUnit) }) } else { + console.log(this.form.start) this.$store.dispatch(blockPath + '/update', { dateStart: this.form.start, dateEnd: this.form.end, @@ -368,7 +388,12 @@ export default { for (let index in this.form.sets) { if (index < charts.length) { const chartPath = charts[index].path + // console.log(chartPath) + this.form.sets[0].multStart = this.form.tempMultStart + this.form.sets[0].multEnd = this.form.tempMultEnd + // console.log(this.form.sets[0]) this.$store.dispatch(chartPath + '/update', this.form.sets[index]) + // console.log(this.$store.getters[blockPath + '/charts']) // update legend name // line below is what "resets" the chart name, maybe comment it out but needs more testing this.$store.commit(chartPath + '/name', this.$store.getters[chartPath + '/pointString']) @@ -385,6 +410,18 @@ export default { this.visible = false }, + timeSave: function () { + // Made a dummy temporary state array because directly pushing to this.form.sets[0].multStart caused + // issues with state.getters updating too soon, inconsistencies with converting Unix to English in chart.module.js + this.form.tempMultStart.push(this.form.start) + this.form.tempMultEnd.push(this.form.end) + }, + + cancelTimeSave: function () { + this.form.tempMultStart = [] + this.form.tempMultEnd = [] + }, + deleteChart: function () { this.form.sets.splice(this.currentIndex, 1) this.currentIndex = 0 @@ -406,12 +443,30 @@ export default { this.form.sets = [] for (let chart of this.$store.getters[blockPath + '/charts']) { - const chartSet = { + console.log(chart) + let chartSet = { name: chart.name, building: this.$store.getters[chart.meterGroupPath + '/building'], meter: chart.meterGroupPath, point: chart.point } + if (this.compareOneBuildingView) { + let blockpath = this.$store.getters['modalController/data'].path + // console.log(blockpath) + let searchTerm = 'block_' + let chartIndex = blockpath.indexOf(searchTerm) + // console.log(blockpath.slice(chartIndex + searchTerm.length)) + let blockID = blockpath.slice(chartIndex + searchTerm.length) + // console.log(this.$store.getters[blockpath + '/chart_' + blockID + '/multStart']) + chartSet = { + name: chart.name, + building: this.$store.getters[chart.meterGroupPath + '/building'], + meter: chart.meterGroupPath, + point: chart.point, + multStart: this.$store.getters[blockpath + '/chart_' + blockID + '/multStart'], + multEnd: this.$store.getters[blockpath + '/chart_' + blockID + '/multEnd'] + } + } this.form.sets.push(chartSet) } } else { diff --git a/src/components/view/view.vue b/src/components/view/view.vue index e2b39d6f..71b2f895 100644 --- a/src/components/view/view.vue +++ b/src/components/view/view.vue @@ -75,6 +75,23 @@ export default { this.$store.commit(card.path + '/intervalUnit', this.intervalUnit) } } + // Reset multStart and multEnd variables whenever you are on a comparison page for just 1 building + let buildingComparisonNumber = JSON.parse(decodeURI(this.$route.params.buildings)).length + if (this.$route.path.includes('compare') && buildingComparisonNumber === 1) { + for (let card of this.cards) { + if (!card.path) return + this.$nextTick(() => { + let blockpath = this.cards[0].path + let searchTerm = 'block_' + let chartIndex = blockpath.indexOf(searchTerm) + // console.log(blockpath.slice(chartIndex + searchTerm.length)) + let blockID = blockpath.slice(chartIndex + searchTerm.length) + // console.log(blockpath + '/chart_' + blockID + '/multStart') + this.$store.commit(blockpath + '/chart_' + blockID + '/clearAndSetMultStart', [this.dateStart]) + this.$store.commit(blockpath + '/chart_' + blockID + '/clearAndSetMultEnd', [this.dateEnd]) + }) + } + } } }, compareBuildings: { @@ -83,7 +100,8 @@ export default { if (this.$route.path.includes('compare')) { // this.cards array only has one element in it if (this.cards.length > 0 && this.cards[0]) { - console.log(buildings.map(building => building.id)) + // console.log(buildings.map(building => building.id)) + // console.log(this.cards[0].path) await this.$store.dispatch(this.cards[0].path + '/removeAllModifiers') // addModifier and updateModifier below call block.module.js, which then calls building_compare.mod.js await this.$store.dispatch(this.cards[0].path + '/addModifier', 'building_compare') @@ -95,7 +113,7 @@ export default { // view.vue's compareBuildings() > block.module.js's updateModifier > building_compare.mod.js's updateData() > // building_compare.mod.js's removeOldCharts() > block.module.js's unloadChart() - console.log(this.cards[0].path) + // console.log(this.cards[0].path) // Example this.cards[0].path: map/building_29/block_79 // Example call order: map.module.js's map() getter > building.module.js's building() getter > @@ -115,6 +133,7 @@ export default { view: { immediate: true, handler: async function (value) { + console.log(this.cards) if (this.$route.path.includes('building')) { for (let card of this.cards) { if (!card.path) return @@ -134,13 +153,31 @@ export default { for (let card of this.cards) { if (!card.path) return this.$nextTick(() => { - console.log(card) this.$store.commit(card.path + '/dateStart', this.dateStart) this.$store.commit(card.path + '/dateEnd', this.dateEnd) this.$store.commit(card.path + '/dateInterval', this.dateInterval) this.$store.commit(card.path + '/intervalUnit', this.intervalUnit) }) } + // Reset multStart and multEnd variables whenever you are on a comparison page for just 1 building + let buildingComparisonNumber = JSON.parse(decodeURI(this.$route.params.buildings)).length + // console.log(buildingComparisonNumber) + if (this.$route.path.includes('compare') && buildingComparisonNumber === 1) { + for (let card of this.cards) { + if (!card.path) return + this.$nextTick(() => { + let blockpath = this.cards[0].path + let searchTerm = 'block_' + let chartIndex = blockpath.indexOf(searchTerm) + // console.log(blockpath.slice(chartIndex + searchTerm.length)) + let blockID = blockpath.slice(chartIndex + searchTerm.length) + // console.log(blockpath + '/chart_' + blockID + '/multStart') + this.$store.commit(blockpath + '/chart_' + blockID + '/clearAndSetMultStart', [this.dateStart]) + this.$store.commit(blockpath + '/chart_' + blockID + '/clearAndSetMultEnd', [this.dateEnd]) + // console.log(this.$store.getters) + }) + } + } } } } @@ -200,7 +237,7 @@ export default { compareBuildings: { get () { if (!this.$route.path.includes('compare')) return null - console.log(this.$route.params.buildings) + // console.log(this.$route.params.buildings) return JSON.parse(decodeURI(this.$route.params.buildings)).map(id => this.$store.getters['map/building'](id)) } }, @@ -212,9 +249,9 @@ export default { } // unintuituively, this.compareBuildings[0].block_ has all the comparison charts in it, and // every other element in this.compareBuildings is ignored - console.log(this.compareBuildings) + // console.log(this.compareBuildings) let building = this.$store.getters['map/building'](this.compareBuildings[0].id) - console.log(building) + // console.log(building) if (!building) return [] let group = this.$store.getters[building.path + '/primaryGroup']('Electricity') let block = this.$store.getters[building.path + '/block'](group.id) diff --git a/src/store/block.module.js b/src/store/block.module.js index 3e0d5b31..fa5ca3ce 100644 --- a/src/store/block.module.js +++ b/src/store/block.module.js @@ -102,6 +102,7 @@ const actions = { async loadCharts (store, charts) { for (let chart of charts) { + // 12/23/2023 edit: We can bypass the chartSpace issue by using block.module.js's getData() function. // Duplicate chartSpace values trigger VueX getter error, need to fix this to support multiple charts let chartSpace = 'chart_' + chart.id let moduleSpace = store.getters.path + '/' + chartSpace @@ -132,6 +133,8 @@ const actions = { }, async update (store, payload) { + console.log(payload) + console.log(store.getters) if ( payload.name === store.getters.name && payload.dateInterval === store.getters.dateInterval && @@ -153,6 +156,8 @@ const actions = { store.commit('graphType', payload.graphType) store.commit('dateStart', payload.dateStart) store.commit('dateEnd', payload.dateEnd) + console.log(payload) + console.log(store.getters) if (user && user === this.getters['user/onid']) { payload.id = store.getters.id payload.dateStart = new Date(store.getters.dateStart).toISOString() @@ -295,7 +300,7 @@ const actions = { labels: [], datasets: [] } - const reqPayload = { + let reqPayload = { dateStart: parseInt(store.getters.dateStart / 1000), dateEnd: parseInt(store.getters.dateEnd / 1000), intervalUnit: store.getters.intervalUnit, @@ -307,10 +312,34 @@ const actions = { for (let mod of store.getters.modifiers) { await mod.preData(this, store, reqPayload) } + console.log(store.getters) for (let chart of store.getters.charts) { if (!chart.path) continue - chartDataPromises.push(this.dispatch(chart.path + '/getData', reqPayload)) + // Section below is called whenever you press "Ok" on the Edit Menu or whenever + // you load / reload a page with a graph on it. + // This allows putting multiple graphs on the same screen without worrying about the + // chartSpace issue + let multStartArray = JSON.parse(JSON.stringify(chart.multStart)) + let multEndArray = JSON.parse(JSON.stringify(chart.multEnd)) + if (multStartArray.length > 1 && multEndArray.length > 1) { + for (let i in multStartArray) { + reqPayload = { + dateStart: parseInt(multStartArray[i] / 1000), + dateEnd: parseInt(multEndArray[i] / 1000), + intervalUnit: store.getters.intervalUnit, + dateInterval: store.getters.dateInterval, + graphType: store.getters.graphType, + timeZoneOffset: store.getters.timeZoneOffset, + // See chart.module.js file for rest of color stuff. Might be a better way to do this + color: store.getters.chartColors[parseInt(i) + 1] + } + chartDataPromises.push(this.dispatch(chart.path + '/getData', reqPayload)) + } + } else { + chartDataPromises.push(this.dispatch(chart.path + '/getData', reqPayload)) + } } + console.log(chartDataPromises) let chartData = await Promise.all(chartDataPromises) if (store.getters.graphType !== 100) { if (store.getters.graphType === 3 || store.getters.graphType === 4) { diff --git a/src/store/block_modifiers/building_compare.mod.js b/src/store/block_modifiers/building_compare.mod.js index e32ab7c0..487e7b34 100644 --- a/src/store/block_modifiers/building_compare.mod.js +++ b/src/store/block_modifiers/building_compare.mod.js @@ -64,6 +64,7 @@ export default class CompareModifier { // Also, see block.module's unloadChart (this function calls unloadChart) // Consider moving await out of for loop + console.log(mod.getters) for (let i in ids) { if (parseInt(i) !== 0) { let id = ids[i] @@ -75,7 +76,7 @@ export default class CompareModifier { async addCharts (store, mod, ids) { // where adding new charts for comparison is handled. Either here or maybe in view.vue we need to rework // to handle multiple charts of the same building via different chartname or something - console.log(mod.getters) + // console.log(mod.getters) let charts = [] for (let i in ids) { // they ignore index of 0 here due to loadDefault function in block.module.js ("Total Electricity" default block), @@ -125,8 +126,14 @@ export default class CompareModifier { if (this.data.buildingIds[0]) { data.datasets[0].label = this.buildingName(store, this.data.buildingIds[0]) } - // along with the section in edit_card.vue, this also controls how the chart name is updated. - // comment it out for now just in case + // 12/23/2023 EDIT: The below commented out code as is will throw errors, as one building with multiple time periods + // means that this.datasets and this.data.buildingIDs will be different lengths. + // Need to handle: multiple buildings same timestamps, one building multiple timestamps, one building same timestamps + // Need to add: energy labels (e.g. "Net Energy"), timestamp labels (Date X to Date Y) + // For energy labels, you can alter chart.module's chartData object in getData(), to change what is sent to data.datatsets + // For timestamp labels, to convert Unix timestamp to English, see chartController toDateString() + // Also don't know why block.module.js's loadDefault uses "Total Electricity", which is the same thing as + // "Net Energy", but named different. /* for (let i = 0; i < data.datasets.length;) { if (this.data.buildingIds[i]) { diff --git a/src/store/chart.module.js b/src/store/chart.module.js index 79f2fd26..e99b98a9 100644 --- a/src/store/chart.module.js +++ b/src/store/chart.module.js @@ -12,6 +12,8 @@ const state = () => { building: null, // String buildingId id: null, // Integer DB ID meterGroupPath: null, + multStart: [], + multEnd: [], path: null, color: '#000000', promise: null, @@ -35,13 +37,18 @@ const actions = { ...payload, ...store.getters.modifierData } - console.log(store.getters.name) + // console.log(store.getters) // Reference: https://www.unixtimestamp.com/index.php // Reference: https://playcode.io/1457582 let oct = 1697587199 let nov = 1700265599 - let dec = 1702857599 + // let dec = 1702857599 + + // UPDATE (12/23/2023) + + // Need to update stuff below. Just changing the chart dates can now be done via + // the Edit Menu UI, but need to update function for aligning the charts / shift charts left // Grab the default value. Building page URL = `http://localhost:8080/#/compare/["16","29"] > building 16 is default // Need a better way of doing this in future @@ -49,6 +56,8 @@ const actions = { // As noted in edit_card.vue line 371 ish, the chart name will change after editing the timeframe via the edit card // web UI component. So we need a better way of distinguishing charts from each other, or rework how the rename // system works. + + /* if (store.getters.name === 'Total Electricity') { reqPayload.dateStart = nov reqPayload.dateEnd = dec @@ -57,7 +66,8 @@ const actions = { reqPayload.dateEnd = nov } console.log(reqPayload) - + */ + console.log(reqPayload) const chartModifier = ChartModifiers(payload.graphType, reqPayload.point) await chartModifier.preGetData(reqPayload, this, store) @@ -81,18 +91,28 @@ const actions = { console.log(data) + let colorPayload = store.getters.color + + if (reqPayload.color) { + colorPayload = reqPayload.color + } + let chartData = { label: store.getters.name, - backgroundColor: store.getters.color, - borderColor: store.getters.color, + backgroundColor: colorPayload, + borderColor: colorPayload, fill: false, showLine: true, spanGaps: false, - data: data + data: data, + multStart: store.getters.multStart, + multEnd: store.getters.multEnd } await chartModifier.postGetData(chartData, reqPayload, this, store) + console.log(chartData) + return chartData }, @@ -108,11 +128,15 @@ const actions = { }, async update (store, payload) { + console.log(payload) + console.log(store.getters) if ( payload.name === store.getters.name && payload.point === store.getters.point && payload.building === store.getters.building && - payload.meter === store.getters.meterGroupPath + payload.meter === store.getters.meterGroupPath && + payload.multStart === store.getters.multStart && + payload.multEnd === store.getters.multEnd ) { return } @@ -137,6 +161,8 @@ const actions = { store.commit('point', payload.point) store.commit('building', payload.building) store.commit('meterGroupPath', payload.meter) + store.commit('multStart', payload.multStart) + store.commit('multEnd', payload.multEnd) } } @@ -178,6 +204,49 @@ const mutations = { meterGroupPath (state, meterGroupPath) { state.meterGroupPath = meterGroupPath + }, + + // Function to convert plain text date format from Edit Form to Unix Timestamps + // See similar dateStart / dateEnd mutation functions in block.module.js + multStart (state, multStart) { + for (let i in multStart) { + if (typeof multStart[i] === 'string') { + console.log('helloooo') + state.multStart[i] = new Date(multStart[i]).getTime() + } else if (typeof multStart[i] === 'number') { + state.multStart[i] = multStart[i] + } else if (multStart[i] instanceof Date) { + state.multStart[i] = multStart[i].getTime() + } else { + throw new Error('Unrecognized format sent to multStart') + } + } + }, + + // Function to remove all elements from VueX state array and insert a placeholder value + // You only need a mutation for this when you are dealing with global state (state.commit, this.store.getters, etc) + clearAndSetMultStart (state, payload) { + state.multStart = [] + state.multStart.push(...payload) + }, + + multEnd (state, multEnd) { + for (let i in multEnd) { + if (typeof multEnd[i] === 'string') { + state.multEnd[i] = new Date(multEnd[i]).getTime() + } else if (typeof multEnd[i] === 'number') { + state.multEnd[i] = multEnd[i] + } else if (multEnd[i] instanceof Date) { + state.multEnd[i] = multEnd[i].getTime() + } else { + throw new Error('Unrecognized format sent to multEnd') + } + } + }, + + clearAndSetMultEnd (state, payload) { + state.multEnd = [] + state.multEnd.push(...payload) } } @@ -218,6 +287,14 @@ const getters = { return state.meterGroupPath }, + multStart (state) { + return state.multStart + }, + + multEnd (state) { + return state.multEnd + }, + pointString (state) { if (state.point) { const map = {