Mercurial > gemma
changeset 3146:b6cc4838d2c0
client: implemented pane mechanic for diagrams
regressions: diagrams are currently not collapsible anymore, animations were removed
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Fri, 03 May 2019 10:33:51 +0200 |
parents | d33a5c1522dc |
children | 25c0cbfcc515 |
files | client/src/components/Main.vue client/src/components/Pane.vue client/src/components/fairway/Fairwayprofile.vue client/src/components/fairway/Profiles.vue client/src/components/gauge/Gauges.vue client/src/components/gauge/HydrologicalConditions.vue client/src/components/gauge/Waterlevel.vue client/src/components/map/Map.vue client/src/components/paneSetups.js client/src/store/application.js client/src/store/fairway.js |
diffstat | 11 files changed, 365 insertions(+), 318 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/components/Main.vue Fri May 03 10:31:40 2019 +0200 +++ b/client/src/components/Main.vue Fri May 03 10:33:51 2019 +0200 @@ -1,30 +1,33 @@ <template> <div id="panes" :class="'d-flex position-absolute rotate' + paneRotate"> - <Pane :pane="panes[0]" :class="'d-flex ' + pane1Classes" /> - - <template v-if="panes.length === 2"> - <Pane :pane="panes[1]" :class="'d-flex ' + pane2Classes" /> - </template> - - <template v-if="panes.length === 3"> - <Pane :pane="panes[2]" class="d-flex wh-50" /> - <Pane :pane="panes[1]" class="d-flex wh-50" /> - </template> - - <template v-if="panes.length === 4"> - <Pane :pane="panes[1]" class="d-flex wh-50" /> - <Pane :pane="panes[3]" class="d-flex wh-50" /> - <Pane :pane="panes[2]" class="d-flex wh-50" /> - </template> + <Pane :pane="panes[0]" :key="panes[0].id" :class="paneClasses[0]" /> + <Pane + :pane="panes[1]" + :key="panes[1].id" + :class="paneClasses[1]" + v-if="panes.length >= 2" + /> + <Pane + :pane="panes[2]" + :key="panes[2].id" + :class="paneClasses[2]" + v-if="panes.length >= 3" + /> + <Pane + :pane="panes[3]" + :key="panes[3].id" + :class="paneClasses[3]" + v-if="panes.length === 4" + /> </div> </template> <style lang="sass"> #panes - top: -0.5px - right: -0.5px - bottom: -0.5px - left: -0.5px + top: -1px + right: -1px + bottom: -1px + left: -1px z-index: 1 &.rotate1 flex-wrap: wrap @@ -39,7 +42,7 @@ flex-wrap: wrap flex-direction: column-reverse .pane - border: solid 0.5px #fff + border: solid 1px #dee2e6 background: #fff </style> @@ -60,31 +63,54 @@ */ import { mapState } from "vuex"; +import * as paneSetups from "./paneSetups"; export default { components: { Pane: () => import("./Pane") }, computed: { - ...mapState("application", ["panes", "paneRotate"]), - // pane 1 and 2 are the only ones that can have varying size - // thats why tehre is no pane3class or pane4class - pane1Classes() { - if (this.panes.length === 1) return "wh-100"; - if (this.panes.length === 2 || this.panes.length === 3) { - if (this.paneRotate === 1 || this.paneRotate === 3) return "w-100 h-50"; - if (this.paneRotate === 2 || this.paneRotate === 4) return "w-50 h-100"; + ...mapState("application", ["paneSetup", "paneRotate"]), + panes() { + return Object.values(paneSetups[this.paneSetup]); + }, + paneClasses() { + if (this.paneSetup === "DEFAULT") { + return ["wh-100"]; + } + + if (this.paneSetup === "COMPARESURVEYS") { + return [2, 4].includes(this.paneRotate) + ? ["w-100 h-50", "w-100 h-50"] + : ["w-50 h-100", "w-50 h-100"]; + } + + if (this.paneSetup === "FAIRWAYPROFILE") { + return [1, 3].includes(this.paneRotate) + ? ["w-100 h-50", "w-100 h-50"] + : ["w-50 h-100", "w-50 h-100"]; } - if (this.panes.length === 4) { - return "wh-50"; + + if (this.paneSetup === "COMPARESURVEYS_FAIRWAYPROFILE") { + return [1, 3].includes(this.paneRotate) + ? ["wh-50", "wh-50", "w-100 h-50"] + : ["wh-50", "wh-50", "w-50 h-100"]; } - }, - pane2Classes() { - if (this.panes.length === 2) { - if (this.paneRotate === 1 || this.paneRotate === 3) return "w-100 h-50"; - if (this.paneRotate === 2 || this.paneRotate === 4) return "w-50 h-100"; - } else { - return "wh-50"; + + if ( + ["GAUGE_WATERLEVEL", "GAUGE_HYDROLOGICALCONDITIONS"].includes( + this.paneSetup + ) + ) { + return [1, 3].includes(this.paneRotate) + ? ["w-100 h-50", "w-100 h-50"] + : ["w-50 h-100", "w-50 h-100"]; + } + + if (this.paneSetup === "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS") { + return [1, 3].includes(this.paneRotate) + ? ["w-100 h-50", "wh-50", "wh-50"] + : ["h-100 w-50", "wh-50", "wh-50"]; } } }
--- a/client/src/components/Pane.vue Fri May 03 10:31:40 2019 +0200 +++ b/client/src/components/Pane.vue Fri May 03 10:33:51 2019 +0200 @@ -1,13 +1,6 @@ <template> - <div :id="pane.id" class="pane"> - <component - :is="pane.component" - :key="pane.id" - :paneCreated="pane.created" - :paneMounted="pane.mounted" - :paneUpdated="pane.updated" - :paneDestroyed="pane.destroyed" - /> + <div :id="pane.id" class="pane d-flex position-relative"> + <component :is="pane.component" :key="pane.id" /> </div> </template>
--- a/client/src/components/fairway/Fairwayprofile.vue Fri May 03 10:31:40 2019 +0200 +++ b/client/src/components/fairway/Fairwayprofile.vue Fri May 03 10:33:51 2019 +0200 @@ -1,32 +1,35 @@ <template> - <div class="d-flex flex-fill"> - <DiagramLegend> - <div class="legend"> - <span style="background-color: #5995ff"></span> Water - </div> - <div class="legend"> - <span style="background-color: #1f4fff"></span> Fairway - </div> - <div class="legend"> - <span style="background-color: #4a2f06"></span> - Ground - </div> - <div> - <button - @click="downloadPDF" - type="button" - class="btn btn-sm btn-info d-block w-100 mt-2" - > - <translate>Export to PDF</translate> - </button> - </div> - </DiagramLegend> - <div - ref="diagramContainer" - class="d-flex flex-fill justify-content-center align-items-center diagram-container" - > - <div v-if="!fairwayData"> - <translate>No data available.</translate> + <div class="d-flex flex-column flex-fill"> + <UIBoxHeader icon="chart-area" :title="title" :closeCallback="close" /> + <div class="d-flex flex-fill"> + <DiagramLegend> + <div class="legend"> + <span style="background-color: #5995ff"></span> Water + </div> + <div class="legend"> + <span style="background-color: #1f4fff"></span> Fairway + </div> + <div class="legend"> + <span style="background-color: #4a2f06"></span> + Ground + </div> + <div> + <button + @click="downloadPDF" + type="button" + class="btn btn-sm btn-info d-block w-100 mt-2" + > + <translate>Export to PDF</translate> + </button> + </div> + </DiagramLegend> + <div + ref="diagramContainer" + class="d-flex flex-fill justify-content-center align-items-center diagram-container" + > + <div v-if="!fairwayData"> + <translate>No data available.</translate> + </div> </div> </div> </div> @@ -86,6 +89,15 @@ "selectedWaterLevel", "waterLevels" ]), + ...mapState("application", ["paneSetup"]), + title() { + let dates = [this.selectedSurvey.date_info]; + if (this.additionalSurvey) dates.push(this.additionalSurvey.date_info); + dates.map(d => this.$options.filters.dateTime(d, true)); + return `${this.$gettext("Fairwayprofile")}: ${ + this.selectedBottleneck + } (${dates.join(", ")})`; + }, selectedSurvey: { get() { return this.$store.state.bottlenecks.selectedSurvey; @@ -151,6 +163,15 @@ } }, methods: { + close() { + this.$store.commit( + "application/paneSetup", + this.paneSetup === "COMPARESURVEYS_FAIRWAYPROFILE" + ? "COMPARESURVEYS" + : "DEFAULT" + ); + this.$store.dispatch("fairwayprofile/clearCurrentProfile"); + }, downloadPDF() { var svg = this.$refs.diagramContainer.innerHTML; if (svg) {
--- a/client/src/components/fairway/Profiles.vue Fri May 03 10:31:40 2019 +0200 +++ b/client/src/components/fairway/Profiles.vue Fri May 03 10:33:51 2019 +0200 @@ -107,6 +107,7 @@ > </button> <button + v-if="!paneSetup.includes('FAIRWAYPROFILE')" class="btn btn-info btn-xs ml-2" @click="$store.commit('application/paneRotate')" v-tooltip="rotatePanesTooltip" @@ -271,6 +272,7 @@ import LineString from "ol/geom/LineString"; import { displayError, displayInfo } from "@/lib/errors"; import { HTTP } from "@/lib/http"; +import { COMPARESURVEYS } from "@/components/paneSetups"; export default { name: "profiles", @@ -278,12 +280,11 @@ return { coordinatesInput: "", cutLabel: "", - showLabelInput: false, - comparePaneId: "compare-sounding-results" + showLabelInput: false }; }, computed: { - ...mapState("application", ["showProfiles"]), + ...mapState("application", ["showProfiles", "paneSetup"]), ...mapState("map", ["openLayersMaps", "syncedMaps", "cutToolEnabled"]), ...mapState("bottlenecks", [ "bottlenecksList", @@ -296,7 +297,8 @@ "endPoint", "profileLoading", "differencesLoading", - "waterLevels" + "waterLevels", + "currentProfile" ]), ...mapGetters("map", ["openLayersMap"]), orderedBottlenecks() { @@ -400,11 +402,11 @@ }, differencesVisible() { return ( - this.openLayersMap(this.comparePaneId) && - !this.openLayersMap(this.comparePaneId) + this.openLayersMap(COMPARESURVEYS.compare.id) && + !this.openLayersMap(COMPARESURVEYS.compare.id) .getLayer("BOTTLENECKISOLINE") .getVisible() && - this.openLayersMap(this.comparePaneId) + this.openLayersMap(COMPARESURVEYS.compare.id) .getLayer("DIFFERENCES") .getVisible() ); @@ -418,7 +420,7 @@ ); }, mapsAreSynced() { - return this.syncedMaps.includes(this.comparePaneId); + return this.syncedMaps.includes(COMPARESURVEYS.compare.id); } }, watch: { @@ -433,15 +435,18 @@ additionalSurvey(survey) { if (survey) { this.loadDifferences(); - this.$store.commit("map/syncedMaps", [this.comparePaneId]); - this.$store.commit("application/addPane", { - id: this.comparePaneId, - component: "Map" - }); - this.$store.commit("application/paneRotate", 4); + this.$store.commit( + "application/paneSetup", + Object.keys(this.currentProfile).length + ? "COMPARESURVEYS_FAIRWAYPROFILE" + : "COMPARESURVEYS" + ); + this.$store.commit("map/syncedMaps", [COMPARESURVEYS.compare.id]); } else { - this.$store.commit("application/removePane", this.comparePaneId); - this.$store.commit("application/paneRotate", 1); + this.$store.commit( + "application/paneSetup", + Object.keys(this.currentProfile).length ? "FAIRWAYPROFILE" : "DEFAULT" + ); this.$store.commit("map/syncedMaps", []); } this.loadProfile(survey); @@ -457,10 +462,10 @@ if (this.mapsAreSynced) { this.$store.commit( "map/syncedMaps", - this.syncedMaps.filter(m => m !== this.comparePaneId) + this.syncedMaps.filter(m => m !== COMPARESURVEYS.compare.id) ); } else { - this.$store.commit("map/syncedMaps", [this.comparePaneId]); + this.$store.commit("map/syncedMaps", [COMPARESURVEYS.compare.id]); } }, loadDifferences() { @@ -490,18 +495,18 @@ }); }, showDifferences() { - this.openLayersMap(this.comparePaneId) + this.openLayersMap(COMPARESURVEYS.compare.id) .getLayer("BOTTLENECKISOLINE") .setVisible(false); - this.openLayersMap(this.comparePaneId) + this.openLayersMap(COMPARESURVEYS.compare.id) .getLayer("DIFFERENCES") .setVisible(true); }, showSurvey() { - this.openLayersMap(this.comparePaneId) + this.openLayersMap(COMPARESURVEYS.compare.id) .getLayer("BOTTLENECKISOLINE") .setVisible(true); - this.openLayersMap(this.comparePaneId) + this.openLayersMap(COMPARESURVEYS.compare.id) .getLayer("DIFFERENCES") .setVisible(false); }, @@ -511,12 +516,10 @@ loadProfile(survey) { if (survey) { this.$store.commit("fairwayprofile/profileLoading", true); - this.$store.commit("application/splitscreenLoading", true); this.$store .dispatch("fairwayprofile/loadProfile", survey) .finally(() => { this.$store.commit("fairwayprofile/profileLoading", false); - this.$store.commit("application/splitscreenLoading", false); }); } },
--- a/client/src/components/gauge/Gauges.vue Fri May 03 10:31:40 2019 +0200 +++ b/client/src/components/gauge/Gauges.vue Fri May 03 10:33:51 2019 +0200 @@ -113,7 +113,7 @@ }; }, computed: { - ...mapState("application", ["showGauges", "activeSplitscreenId"]), + ...mapState("application", ["showGauges", "paneSetup"]), ...mapState("gauges", ["gauges", "longtermInterval"]), ...mapGetters("gauges", ["selectedGauge"]), gaugesLabel() { @@ -165,12 +165,16 @@ } }, watch: { - selectedGaugeISRS() { - if (this.activeSplitscreenId === "gauge-waterlevel") { - this.showWaterlevelDiagram(); - } - if (this.activeSplitscreenId === "gauge-hydrological-conditions") { - this.showHydrologicalConditionsDiagram(); + selectedGaugeISRS(gauge) { + if (gauge) { + let coordinates = this.selectedGauge.geometry.coordinates; + this.$store.dispatch("map/moveMap", { + coordinates, + zoom: null, + preventZoomOut: true + }); + } else { + this.$store.commit("application/paneSetup", "DEFAULT"); } } }, @@ -187,37 +191,7 @@ }); }, showWaterlevelDiagram() { - // for panning the map to the gauge on opening the diagram: needs to be - // set outside of the expandCallback to not always refer to the currently - // selectedGauge - let coordinates = this.selectedGauge.geometry.coordinates; - - // configure splitscreen - let splitscreenConf = { - id: "gauge-waterlevel", - component: "waterlevel", - title: `${this.gaugeLabel(this.selectedGauge)}: ${this.$gettext( - "Waterlevel" - )} ${this.dateFrom.toLocaleDateString()} - ${this.dateTo.toLocaleDateString()}`, - icon: "ruler-vertical", - closeCallback: () => { - this.$store.commit("gauges/selectedGaugeISRS", null); - this.$store.commit("gauges/waterlevels", []); - }, - expandCallback: () => { - this.$store.dispatch("map/moveMap", { - coordinates, - zoom: null, - preventZoomOut: true - }); - } - }; - this.$store.commit("application/addSplitscreen", splitscreenConf); - this.$store.commit("application/activeSplitscreenId", splitscreenConf.id); - this.$store.commit("application/splitscreenLoading", true); this.loading = true; - this.$store.commit("application/showSplitscreen", true); - Promise.all([ this.$store.dispatch("gauges/loadWaterlevels"), this.$store.dispatch("gauges/loadNashSutcliffe") @@ -230,53 +204,25 @@ }); }) .finally(() => { - this.$store.commit("application/splitscreenLoading", false); + this.$store.commit( + "application/paneSetup", + [ + "GAUGE_HYDROLOGICALCONDITIONS", + "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS" + ].includes(this.paneSetup) + ? "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS" + : "GAUGE_WATERLEVEL" + ); this.loading = false; }); }, showHydrologicalConditionsDiagram() { - // for panning the map to the gauge on opening the diagram: needs to be - // set outside of the expandCallback to not always refer to the currently - // selectedGauge - let coordinates = this.selectedGauge.geometry.coordinates; - - // configure splitscreen - let splitscreenConf = { - id: "gauge-hydrological-conditions", - component: "hydrological-conditions", - title: `${this.gaugeLabel(this.selectedGauge)}: ${this.$gettext( - "Hydrological Conditions" - )}`, - icon: "ruler-vertical", - closeCallback: () => { - this.$store.commit("gauges/selectedGaugeISRS", null); - this.$store.commit("gauges/longtermWaterlevels", []); - this.$store.commit("gauges/yearWaterlevels", []); - }, - expandCallback: () => { - this.$store.dispatch("map/moveMap", { - coordinates, - zoom: null, - preventZoomOut: true - }); - } - }; - this.$store.commit("application/addSplitscreen", splitscreenConf); - this.$store.commit("application/activeSplitscreenId", splitscreenConf.id); - this.$store.commit("application/splitscreenLoading", true); this.loading = true; - this.$store.commit("application/showSplitscreen", true); Promise.all([ this.$store.dispatch("gauges/loadLongtermWaterlevels"), this.$store.dispatch("gauges/loadYearWaterlevels") ]) - .then(() => { - splitscreenConf.title = `${ - splitscreenConf.title - } ${this.longtermInterval.join(" - ")}`; - this.$store.commit("application/addSplitscreen", splitscreenConf); - }) .catch(error => { const { status, data } = error.response; displayError({ @@ -285,7 +231,15 @@ }); }) .finally(() => { - this.$store.commit("application/splitscreenLoading", false); + this.$store.commit( + "application/paneSetup", + [ + "GAUGE_WATERLEVEL", + "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS" + ].includes(this.paneSetup) + ? "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS" + : "GAUGE_HYDROLOGICALCONDITIONS" + ); this.loading = false; }); },
--- a/client/src/components/gauge/HydrologicalConditions.vue Fri May 03 10:31:40 2019 +0200 +++ b/client/src/components/gauge/HydrologicalConditions.vue Fri May 03 10:33:51 2019 +0200 @@ -1,38 +1,47 @@ <template> - <div class="d-flex flex-fill"> - <DiagramLegend> - <div class="legend"> - <span style="background-color: red"></span> - {{ yearCompare }} - </div> - <div class="legend"> - <span style="background-color: orange"></span> Q25% - </div> - <div class="legend"> - <span style="background-color: black"></span> Median - </div> - <div class="legend"> - <span style="background-color: purple"></span> Q75% - </div> - <div class="legend"> - <span style="background-color: lightsteelblue"></span> - Long-term Amplitude - </div> - <div> - <button - @click="downloadPDF" - type="button" - class="btn btn-sm btn-info d-block w-100 mt-2" - > - <translate>Export to PDF</translate> - </button> - </div> - </DiagramLegend> - <div - class="d-flex flex-fill justify-content-center align-items-center diagram-container" - > - <div v-if="!longtermWaterlevels.length"> - <translate>No data available.</translate> + <div class="d-flex flex-column flex-fill"> + <UIBoxHeader + icon="ruler-vertical" + :title="title" + :closeCallback="close" + class="rounded-0" + /> + <div class="d-flex flex-fill"> + <DiagramLegend> + <div class="legend"> + <span style="background-color: red"></span> + {{ yearCompare }} + </div> + <div class="legend"> + <span style="background-color: orange"></span> Q25% + </div> + <div class="legend"> + <span style="background-color: black"></span> Median + </div> + <div class="legend"> + <span style="background-color: purple"></span> Q75% + </div> + <div class="legend"> + <span style="background-color: lightsteelblue"></span> + Long-term Amplitude + </div> + <div> + <button + @click="downloadPDF" + type="button" + class="btn btn-sm btn-info d-block w-100 mt-2" + > + <translate>Export to PDF</translate> + </button> + </div> + </DiagramLegend> + <div + class="d-flex flex-fill justify-content-center align-items-center" + :id="containerId" + > + <div v-if="!longtermWaterlevels.length"> + <translate>No data available.</translate> + </div> </div> </div> </div> @@ -67,6 +76,7 @@ }, data() { return { + containerId: "hydrologicalconditions-diagram-container", svg: null, diagram: null, navigation: null, @@ -77,15 +87,22 @@ }; }, computed: { + ...mapState("application", ["paneSetup"]), ...mapState("gauges", [ "longtermWaterlevels", "yearWaterlevels", "yearCompare", "longtermInterval" ]), - ...mapGetters("gauges", ["selectedGauge"]) + ...mapGetters("gauges", ["selectedGauge"]), + title() { + return this.$gettext("Hydrological Conditions"); + } }, watch: { + paneSetup() { + this.$nextTick(() => this.drawDiagram()); + }, longtermWaterlevels() { this.drawDiagram(); }, @@ -94,8 +111,16 @@ } }, methods: { + close() { + this.$store.commit( + "application/paneSetup", + this.paneSetup === "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS" + ? "GAUGE_WATERLEVEL" + : "DEFAULT" + ); + }, downloadPDF() { - var svg = this.svg._groups[0][0].outerHTML; + var svg = document.getElementById(this.containerId).innerHTML; if (svg) { svg = svg.replace(/\r?\n|\r/g, "").trim(); } @@ -156,9 +181,8 @@ }, drawDiagram() { // remove old diagram - d3.select(".diagram-container svg").remove(); + d3.select("#" + this.containerId + " svg").remove(); if (!this.selectedGauge || !this.longtermWaterlevels.length) return; - // PREPARE HELPERS // HDC/LDC/MW for the selected gauge @@ -182,7 +206,7 @@ // create svg this.svg = d3 - .select(".diagram-container") + .select("#" + this.containerId) .append("svg") .attr("width", "100%") .attr("height", "100%"); @@ -338,8 +362,9 @@ }, getDimensions() { // dimensions and margins - const svgWidth = document.querySelector(".diagram-container").clientWidth; - const svgHeight = document.querySelector(".diagram-container") + const svgWidth = document.querySelector("#" + this.containerId) + .clientWidth; + const svgHeight = document.querySelector("#" + this.containerId) .clientHeight; const mainMargin = { top: 20, right: 20, bottom: 110, left: 80 }; const navMargin = {
--- a/client/src/components/gauge/Waterlevel.vue Fri May 03 10:31:40 2019 +0200 +++ b/client/src/components/gauge/Waterlevel.vue Fri May 03 10:33:51 2019 +0200 @@ -1,48 +1,56 @@ <template> - <div class="d-flex flex-fill"> - <DiagramLegend> - <div class="legend"> - <span style="background-color: steelblue"></span> Waterlevel - </div> - <div class="legend"> - <span - style="width: 4px; height: 4px; background-color: rgba(70, 130, 180, 0.6); border: solid 4px rgba(70, 130, 180, 0.2); background-clip: padding-box; box-sizing: content-box;" - ></span> - Prediction - </div> - <div class="legend"> - <span style="background-color: rgba(0, 255, 0, 0.1)"></span> Navigable - Range - </div> - <div> - <select - @change="applyChange" - v-model="form.template" - class="form-control d-block custom-select-sm w-100" - > - <option - v-for="template in templates" - :value="template" - :key="template.name" + <div class="d-flex flex-column flex-fill"> + <UIBoxHeader + icon="ruler-vertical" + :title="title" + :closeCallback="close" + class="rounded-0" + /> + <div class="d-flex flex-fill"> + <DiagramLegend> + <div class="legend"> + <span style="background-color: steelblue"></span> Waterlevel + </div> + <div class="legend"> + <span + style="width: 4px; height: 4px; background-color: rgba(70, 130, 180, 0.6); border: solid 4px rgba(70, 130, 180, 0.2); background-clip: padding-box; box-sizing: content-box;" + ></span> + Prediction + </div> + <div class="legend"> + <span style="background-color: rgba(0, 255, 0, 0.1)"></span> Navigable + Range + </div> + <div> + <select + @change="applyChange" + v-model="form.template" + class="form-control d-block custom-select-sm w-100" > - {{ template.name }} - </option> - </select> - <button - @click="downloadPDF" - type="button" - class="btn btn-sm btn-info d-block w-100 mt-2" - > - <translate>Export to PDF</translate> - </button> - </div> - </DiagramLegend> - <div - ref="diagramContainer" - class="d-flex flex-fill justify-content-center align-items-center diagram-container" - > - <div v-if="!waterlevels.length"> - <translate>No data available.</translate> + <option + v-for="template in templates" + :value="template" + :key="template.name" + > + {{ template.name }} + </option> + </select> + <button + @click="downloadPDF" + type="button" + class="btn btn-sm btn-info d-block w-100 mt-2" + > + <translate>Export to PDF</translate> + </button> + </div> + </DiagramLegend> + <div + class="d-flex flex-fill justify-content-center align-items-center" + :id="containerId" + > + <div v-if="!waterlevels.length"> + <translate>No data available.</translate> + </div> </div> </div> </div> @@ -86,6 +94,7 @@ }, data() { return { + containerId: "waterlevel-diagram-container", svg: null, diagram: null, navigation: null, @@ -138,9 +147,13 @@ }; }, computed: { + ...mapState("application", ["paneSetup"]), ...mapState("gauges", ["dateFrom", "waterlevels", "nashSutcliffe"]), ...mapGetters("gauges", ["selectedGauge"]), ...mapState("user", ["user"]), + title() { + return this.$gettext("Waterlevel"); + }, dateFrom: { get() { return this.$store.state.gauges.dateFrom; @@ -153,13 +166,24 @@ } }, watch: { + paneSetup() { + this.$nextTick(() => this.drawDiagram()); + }, waterlevels() { this.drawDiagram(); } }, methods: { + close() { + this.$store.commit( + "application/paneSetup", + this.paneSetup === "GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS" + ? "GAUGE_HYDROLOGICALCONDITIONS" + : "DEFAULT" + ); + }, downloadPDF() { - var svg = this.$refs.diagramContainer.innerHTML; + var svg = document.getElementById(this.containerId).innerHTML; if (svg) { svg = svg.replace(/\r?\n|\r/g, "").trim(); } @@ -345,7 +369,7 @@ }, drawDiagram() { // remove old diagram and exit if necessary data is missing - d3.select(".diagram-container svg").remove(); + d3.select("#" + this.containerId + " svg").remove(); if (!this.selectedGauge || !this.waterlevels.length) return; // PREPARE HELPERS @@ -381,7 +405,7 @@ // create svg this.svg = d3 - .select(".diagram-container") + .select("#" + this.containerId) .append("svg") .attr("width", "100%") .attr("height", "100%"); @@ -564,8 +588,9 @@ }, getDimensions() { // dimensions and margins - const svgWidth = document.querySelector(".diagram-container").clientWidth; - const svgHeight = document.querySelector(".diagram-container") + const svgWidth = document.querySelector("#" + this.containerId) + .clientWidth; + const svgHeight = document.querySelector("#" + this.containerId) .clientHeight; const mainMargin = { top: 20, right: 20, bottom: 110, left: 80 }; const navMargin = {
--- a/client/src/components/map/Map.vue Fri May 03 10:31:40 2019 +0200 +++ b/client/src/components/map/Map.vue Fri May 03 10:33:51 2019 +0200 @@ -57,7 +57,7 @@ ...mapState("map", ["initialLoad", "extent", "syncedMaps", "syncedView"]), ...mapState("bottlenecks", ["selectedSurvey"]), ...mapState("fairwayprofile", ["additionalSurvey"]), - ...mapState("application", ["panes", "paneRotate"]), + ...mapState("application", ["paneSetup", "paneRotate"]), ...mapState("imports", ["selectedStretchId"]), layers() { return layers(); @@ -77,7 +77,7 @@ } }, watch: { - panes() { + paneSetup() { this.$nextTick(() => this.map.updateSize()); }, paneRotate() { @@ -107,7 +107,7 @@ } }, additionalSurvey(survey) { - if (this.paneId === "compare-sounding-results") { + if (this.paneId === "compare-survey") { if (survey) { this.updateBottleneckFilter(survey.bottleneck_id, survey.date_info); } else { @@ -244,10 +244,7 @@ this.selectedSurvey.date_info ); } - if ( - this.additionalSurvey && - this.paneId === "compare-sounding-results" - ) { + if (this.additionalSurvey && this.paneId === "compare-survey") { this.updateBottleneckFilter( this.additionalSurvey.bottleneck_id, this.additionalSurvey.date_info
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/components/paneSetups.js Fri May 03 10:33:51 2019 +0200 @@ -0,0 +1,35 @@ +const main = { id: "main", component: "Map" }; + +export const DEFAULT = { main }; +export const COMPARESURVEYS = { + main, + compare: { id: "compare-survey", component: "Map" } +}; +export const FAIRWAYPROFILE = { + main, + fairwayprofile: { id: "fairwayprofile", component: "Fairwayprofile" } +}; +export const COMPARESURVEYS_FAIRWAYPROFILE = { + main, + compare: { id: "compare-survey", component: "Map" }, + fairwayprofile: { id: "fairwayprofile", component: "Fairwayprofile" } +}; +export const GAUGE_WATERLEVEL = { + main, + waterlevel: { id: "gauge-waterlevel", component: "Waterlevel" } +}; +export const GAUGE_HYDROLOGICALCONDITIONS = { + main, + hydrological: { + id: "gauge-hydrologicalconditions", + component: "HydrologicalConditions" + } +}; +export const GAUGE_WATERLEVEL_HYDROLOGICALCONDITIONS = { + main, + waterlevel: { id: "gauge-waterlevel", component: "Waterlevel" }, + hydrological: { + id: "gauge-hydrologicalconditions", + component: "HydrologicalConditions" + } +};
--- a/client/src/store/application.js Fri May 03 10:31:40 2019 +0200 +++ b/client/src/store/application.js Fri May 03 10:33:51 2019 +0200 @@ -24,7 +24,7 @@ secondaryLogo: process.env.VUE_APP_SECONDARY_LOGO_URL, logoForPDF: process.env.VUE_APP_LOGO_FOR_PDF_URL, popup: null, - panes: [{ id: "main", component: "Map" }], + paneSetup: "DEFAULT", paneRotate: 1, splitscreens: [], splitscreenLoading: false, @@ -83,14 +83,8 @@ popup: (state, popup) => { state.popup = popup; }, - addPane: (state, pane) => { - state.panes.push(pane); - }, - removePane: (state, paneId) => { - const index = state.panes.findIndex(p => p.id === paneId); - if (index !== -1) { - state.panes.splice(index, 1); - } + paneSetup: (state, setup) => { + state.paneSetup = setup; }, paneRotate: (state, rotate) => { if (rotate) {
--- a/client/src/store/fairway.js Fri May 03 10:31:40 2019 +0200 +++ b/client/src/store/fairway.js Fri May 03 10:33:51 2019 +0200 @@ -109,7 +109,6 @@ state.fairwayData = []; }, clearCurrentProfile: state => { - state.additionalSurvey = null; state.currentProfile = {}; state.minAlt = null; state.maxAlt = null; @@ -132,8 +131,7 @@ } }, actions: { - clearSelection({ commit, dispatch, rootState }) { - dispatch("bottlenecks/setSelectedBottleneck", null, { root: true }); + clearCurrentProfile({ commit, rootState }) { commit("clearCurrentProfile"); commit("map/cutToolEnabled", false, { root: true }); rootState.map.openLayersMaps.forEach(m => { @@ -213,8 +211,6 @@ ); } - commit("application/showSplitscreen", true, { root: true }); - commit("application/splitscreenLoading", true, { root: true }); commit("profileLoading", true); Promise.all(profileLoaders) .then(() => { @@ -295,40 +291,18 @@ }); }) .finally(() => { - let splitscreenConf = { - id: "fairwayprofile", - component: "fairwayprofile", - title: `${rootState.bottlenecks.selectedBottleneck} (${ - rootState.bottlenecks.selectedSurvey.date_info - })`, - icon: "chart-area", - closeCallback: () => { - dispatch("clearSelection"); - }, - expandCallback: () => { - let bottleneck = rootState.bottlenecks.bottlenecksList.find( - bn => - bn.properties.name === - rootState.bottlenecks.selectedBottleneck - ); - dispatch( - "map/moveToFeauture", - { - feature: bottleneck, - zoom: 17, - preventZoomOut: true - }, - { root: true } - ); - } - }; - commit("application/addSplitscreen", splitscreenConf, { - root: true - }); - commit("application/activeSplitscreenId", "fairwayprofile", { - root: true - }); - commit("application/splitscreenLoading", false, { root: true }); + commit("application/paneRotate", 1, { root: true }); + if (state.additionalSurvey) { + commit( + "application/paneSetup", + "COMPARESURVEYS_FAIRWAYPROFILE", + { root: true } + ); + } else { + commit("application/paneSetup", "FAIRWAYPROFILE", { + root: true + }); + } commit("profileLoading", false); }); }