diff --git a/app/src/components/IndicatorData.vue b/app/src/components/IndicatorData.vue index 9d72cca967..156edb1c5e 100644 --- a/app/src/components/IndicatorData.vue +++ b/app/src/components/IndicatorData.vue @@ -117,6 +117,8 @@ export default { data() { return { dataLayerTime: null, + dataLayerTimeFromMap: null, + compareLayerTimeFromMap: null, lineChartIndicators: [ 'E12', 'E12b', 'E8', 'N1b', 'N1', 'NASACustomLineChart', 'N3', 'N3b', 'SST', 'GG', 'E10a', 'E10a9', 'CV', 'OW', 'E10c', 'E10a10', 'OX', @@ -149,7 +151,6 @@ export default { 'REP4_1', 'REP4_4', 'REP4_5', 'REP4_6', 'REP4_2', 'ADO', 'Lakes_SWT'], }; }, - mounted() { const d = this.indicatorObject.time[this.indicatorObject.time.length - 1]; const formatted = d.toFormat('dd. MMM'); @@ -157,6 +158,8 @@ export default { value: formatted, name: formatted, }; + // add event listener for map up + window.addEventListener('message', this.mapTimeUpdatedHandler); }, computed: { ...mapState('config', ['appConfig', 'baseConfig']), @@ -476,6 +479,16 @@ export default { }); }); } + + // datasets.push({ + // label: 'hide_', + // data: [], + // borderColor: 'rgba(0,0,0,0.1)', + // backgroundColor: 'rgba(0,0,0,1)', + // borderWidth: 1, + // pointRadius: 3, + // spanGaps: false, + // }); // Add special points for N3 if (['N3', 'SST'].includes(indicatorCode)) { // Find unique indicator values @@ -1163,6 +1176,15 @@ export default { this.$refs.regenerateButton.$el.style.display = 'none'; } }, + mapTimeUpdatedHandler(event) { + // set listener to highlight points for selected time on map via annotations + if (event.data.command === 'chart:setTime') { + this.dataLayerTimeFromMap = event.data.time; + } + if (event.data.command === 'chart:setCompareTime') { + this.compareLayerTimeFromMap = event.data.time; + } + }, resetLCZoom() { this.extentChanged(false); this.$refs.lineChart._data._chart.resetZoom(); @@ -1218,6 +1240,7 @@ export default { const indicatorCode = this.indicatorObject.indicator; const reference = Number.parseFloat(this.indicatorObject.referenceValue); const annotations = []; + let low = 0; let high = 0; @@ -1728,16 +1751,37 @@ export default { }, }; } - // add event listener for map up - window.addEventListener('message', (event) => { - if (event.data.command === 'chart:setTime' && event.data.time) { - console.log(event.data.time); - } + const defaultTimeAnnotation = { + type: 'line', + mode: 'vertical', + scaleID: 'x-axis-0', + borderColor: 'rgba(0, 0, 0, 0.5)', + borderDash: [4, 4], + borderWidth: 3, + label: { + enabled: true, + content: 'Map layer', + fontSize: 10, + backgroundColor: 'rgba(0,0,0,0.5)', + }, + }; - if (event.data.command === 'chart:setCompareTime' && event.data.time) { - console.log(event.data.time); - } - }); + if (this.dataLayerTimeFromMap) { + annotations.push({ + ...defaultTimeAnnotation, + value: this.dataLayerTimeFromMap, + }); + } + if (this.compareLayerTimeFromMap) { + annotations.push({ + ...defaultTimeAnnotation, + value: this.compareLayerTimeFromMap, + label: { + ...defaultTimeAnnotation.label, + content: 'Compare layer', + }, + }); + } return { ...customSettings, annotation: { @@ -1749,6 +1793,15 @@ export default { }; }, }, + beforeDestroy() { + if (this.mapId === 'centerMap') { + const cluster = getCluster(this.mapId, { vm: this, mapId: this.mapId }); + cluster.setActive(false, this.overlayCallback); + this.ro.unobserve(this.$refs.mapContainer); + getMapInstance(this.mapId).map.removeInteraction(this.queryLink); + } + window.removeEventListener('message', this.mapTimeUpdatedHandler); + }, }; diff --git a/app/src/components/map/Map.vue b/app/src/components/map/Map.vue index 68213529bf..996b6171ca 100644 --- a/app/src/components/map/Map.vue +++ b/app/src/components/map/Map.vue @@ -589,7 +589,15 @@ export default { }); this.$emit('update:datalayertime', timeObj.name); window.postMessage({ - command: 'chart:setTime', time: timeObj.value, + command: 'chart:setTime', + time: timeObj.value.isLuxonDateTime + ? timeObj.value.toISODate() + : timeObj.value, + }); + } else { + window.postMessage({ + command: 'chart:setTime', + time: null, }); } }, @@ -609,13 +617,34 @@ export default { }); } else { this.$emit('update:comparelayertime', enabled ? this.compareLayerTime.name : null); + if (enabled) { + window.postMessage({ + command: 'chart:setCompareTime', + time: this.compareLayerTime.value.isLuxonDateTime + ? this.compareLayerTime.value.toISODate() + : this.compareLayerTime.value, + }); + } else { + window.postMessage({ + command: 'chart:setCompareTime', + time: null, + }); + } } }, compareLayerTime(timeObj) { this.$emit('update:comparelayertime', this.enableCompare ? timeObj.name : null); if (timeObj) { window.postMessage({ - command: 'chart:setCompareTime', time: timeObj.value, + command: 'chart:setCompareTime', + time: timeObj.value.isLuxonDateTime + ? timeObj.value.toISODate() + : timeObj.value, + }); + } else { + window.postMessage({ + command: 'chart:setCompareTime', + time: null, }); } }, @@ -751,8 +780,31 @@ export default { } this.$emit('ready', true); - // Define a function to update the data layer - const updateTime = (time, compare) => { + window.addEventListener('message', this.handleExternalMapMessage); + + this.ro = new ResizeObserver(this.onResize); + this.ro.observe(this.$refs.mapContainer); + // Fetch data for custom chart if the event is fired. + window.addEventListener( + 'fetch-custom-area-chart', + this.onFetchCustomAreaIndicator, + ); + if (this.mapId === 'centerMap') { + this.queryLink = new Link({ replace: true, params: ['x', 'y', 'z'] }); + map.addInteraction(this.queryLink); + } + }, + methods: { + handleSpecialLayerZoom(e) { + this.$emit('update:zoom', e); + this.currentZoom = e; + }, + handleSpecialLayerCenter(e) { + this.$emit('update:center', e); + this.currentCenter = e; + }, + updateTime(time, compare) { + // Define a function to update the data layer // direct match on name let timeEntry = this.availableTimeEntries.find((e) => e.name === time); if (timeEntry === undefined && time.isLuxonDateTime) { @@ -780,28 +832,28 @@ export default { } else { this.dataLayerTime = timeEntry; } - }; - - // Define a function to schedule the data layer update during the next animation frame - const scheduleUpdateTime = (time, compare) => { + }, + scheduleUpdateTime(time, compare) { + // Define a function to schedule the data layer update during the next animation frame // Use requestAnimationFrame to schedule the update during the next animation frame requestAnimationFrame(() => { - updateTime(time, compare); + this.updateTime(time, compare); }); - }; - - window.addEventListener('message', (event) => { + }, + handleExternalMapMessage(event) { if (event.data.command === 'map:setZoom' && event.data.zoom) { // Update the state of the application using the message data + const { map } = getMapInstance(this.mapId); + const view = map.getView(); view.setZoom(event.data.zoom); } if (event.data.command === 'map:setTime' && event.data.time) { - scheduleUpdateTime(event.data.time, false); + this.scheduleUpdateTime(event.data.time, false); } if (event.data.command === 'map:setCompareTime' && event.data.time) { - scheduleUpdateTime(event.data.time, true); + this.scheduleUpdateTime(event.data.time, true); } if (event.data.command === 'map:setPoi' && event.data.poi) { @@ -821,6 +873,7 @@ export default { } if (event.data.command === 'map:enableLayer' && event.data.name) { + const { map } = getMapInstance(this.mapId); map.getLayers().forEach((layer) => { if (layer.get('name') === event.data.name) { layer.setVisible(true); @@ -829,6 +882,7 @@ export default { } if (event.data.command === 'map:disableAllLayers' && event.data.baseLayer) { + const { map } = getMapInstance(this.mapId); map.getLayers().forEach((layer) => { if (layer.get('name') !== event.data.baseLayer) { layer.setVisible(false); @@ -839,6 +893,7 @@ export default { } if (event.data.command === 'map:disableLayer' && event.data.name) { + const { map } = getMapInstance(this.mapId); map.getLayers().forEach((layer) => { if (layer.get('name') === event.data.name) { layer.setVisible(false); @@ -848,6 +903,8 @@ export default { if (event.data.command === 'map:setCenter' && event.data.center) { // Update the state of the application using the message data + const { map } = getMapInstance(this.mapId); + const view = map.getView(); view.setCenter( fromLonLat( event.data.center, @@ -857,6 +914,8 @@ export default { } if (event.data.command === 'map:enableScrolly') { + const { map } = getMapInstance(this.mapId); + const view = map.getView(); this.enableScrollyMode = true; this.onScrollyModeChange(true); view.setProperties({ @@ -869,30 +928,6 @@ export default { } }); } - }); - - this.ro = new ResizeObserver(this.onResize); - this.ro.observe(this.$refs.mapContainer); - // Fetch data for custom chart if the event is fired. - // TODO: Extract fetchData method into helper file since it needs to be used from outside. - window.addEventListener( - 'fetch-custom-area-chart', - () => this.onFetchCustomAreaIndicator(), - false, - ); - if (this.mapId === 'centerMap') { - this.queryLink = new Link({ replace: true, params: ['x', 'y', 'z'] }); - map.addInteraction(this.queryLink); - } - }, - methods: { - handleSpecialLayerZoom(e) { - this.$emit('update:zoom', e); - this.currentZoom = e; - }, - handleSpecialLayerCenter(e) { - this.$emit('update:center', e); - this.currentCenter = e; }, handleSetTimeArray(entries) { this.externallySuppliedTimeEntries = entries.map((item) => { @@ -1018,6 +1053,11 @@ export default { this.ro.unobserve(this.$refs.mapContainer); getMapInstance(this.mapId).map.removeInteraction(this.queryLink); } + window.removeEventListener( + 'fetch-custom-area-chart', + this.onFetchCustomAreaIndicator, + ); + window.removeEventListener('message', this.handleExternalMapMessage); }, };