Mercurial > gemma
comparison client/src/components/fairway/Fairwayprofile.vue @ 3963:feb53713bc2f diagram-cleanup
client: moved duplicated code to mixins and unified code patterns in diagram components [WIP]
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Fri, 12 Jul 2019 15:14:16 +0200 |
parents | cd8ba6599a99 |
children | afc7bca44df4 |
comparison
equal
deleted
inserted
replaced
3944:0ed8af02d5a9 | 3963:feb53713bc2f |
---|---|
91 <translate>Export to PDF</translate> | 91 <translate>Export to PDF</translate> |
92 </button> | 92 </button> |
93 </div> | 93 </div> |
94 </DiagramLegend> | 94 </DiagramLegend> |
95 <div | 95 <div |
96 ref="pdfContainer" | 96 class="d-flex flex-fill justify-content-center align-items-center position-relative" |
97 id="pdfContainer" | 97 :id="containerId" |
98 class="d-flex flex-fill justify-content-center align-items-center diagram-container position-relative" | |
99 > | 98 > |
100 <div class="direction-indicator"></div> | 99 <div class="direction-indicator"></div> |
101 <div v-if="!fairwayData"> | 100 <div v-if="!fairwayData.length"> |
102 <translate>No data available.</translate> | 101 <translate>No data available.</translate> |
103 </div> | 102 </div> |
104 </div> | 103 </div> |
105 </div> | 104 </div> |
106 </div> | 105 </div> |
146 * Markus Kottländer <markus.kottlaender@intevation.de> | 145 * Markus Kottländer <markus.kottlaender@intevation.de> |
147 * Fadi Abbud <fadi.abbud@intevation.de> | 146 * Fadi Abbud <fadi.abbud@intevation.de> |
148 */ | 147 */ |
149 import * as d3 from "d3"; | 148 import * as d3 from "d3"; |
150 import { mapState, mapGetters } from "vuex"; | 149 import { mapState, mapGetters } from "vuex"; |
151 import debounce from "debounce"; | |
152 import { diagram, pdfgen, templateLoader } from "@/lib/mixins"; | 150 import { diagram, pdfgen, templateLoader } from "@/lib/mixins"; |
153 import { HTTP } from "@/lib/http"; | |
154 import { displayError } from "@/lib/errors"; | |
155 import { defaultDiagramTemplate } from "@/lib/DefaultDiagramTemplate"; | |
156 | 151 |
157 const GROUND_COLOR = "#4A2F06"; | 152 const GROUND_COLOR = "#4A2F06"; |
158 const WATER_COLOR = "#005DFF"; | 153 const WATER_COLOR = "#005DFF"; |
159 | 154 |
160 export default { | 155 export default { |
161 mixins: [diagram, pdfgen, templateLoader], | 156 mixins: [diagram, pdfgen, templateLoader], |
162 name: "fairwayprofile", | |
163 components: { | 157 components: { |
164 DiagramLegend: () => import("@/components/DiagramLegend") | 158 DiagramLegend: () => import("@/components/DiagramLegend") |
165 }, | 159 }, |
166 data() { | 160 data() { |
167 return { | 161 return { |
168 resizeListenerFunction: null, | 162 containerId: "fairwayprofile-diagram-container", |
169 width: null, | 163 width: null, |
170 height: null, | 164 height: null |
171 form: { | |
172 template: null | |
173 }, | |
174 templates: [], | |
175 defaultTemplate: defaultDiagramTemplate, | |
176 pdf: { | |
177 doc: null, | |
178 width: 32, | |
179 height: 297 | |
180 }, | |
181 templateData: null | |
182 }; | 165 }; |
183 }, | 166 }, |
184 computed: { | 167 computed: { |
185 ...mapGetters("map", ["openLayersMap"]), | 168 ...mapGetters("map", ["openLayersMap"]), |
186 ...mapGetters("fairwayprofile", ["totalLength"]), | 169 ...mapGetters("fairwayprofile", ["totalLength"]), |
291 let strokeOpacity = strokeColor.pop(); | 274 let strokeOpacity = strokeColor.pop(); |
292 let strokeDash = style.getStroke().getLineDash(); | 275 let strokeDash = style.getStroke().getLineDash(); |
293 | 276 |
294 return { fillColor, fillOpacity, strokeColor, strokeOpacity, strokeDash }; | 277 return { fillColor, fillOpacity, strokeColor, strokeOpacity, strokeDash }; |
295 }, | 278 }, |
296 applyChange() { | |
297 if (this.form.template.hasOwnProperty("properties")) { | |
298 this.templateData = this.defaultTemplate; | |
299 return; | |
300 } | |
301 if (this.form.template) { | |
302 this.loadTemplates("/templates/diagram/" + this.form.template.name) | |
303 .then(response => { | |
304 this.prepareImages(response.data.template_data.elements).then( | |
305 values => { | |
306 values.forEach(v => { | |
307 response.data.template_data.elements[v.index].url = v.url; | |
308 }); | |
309 this.templateData = response.data.template_data; | |
310 } | |
311 ); | |
312 }) | |
313 .catch(e => { | |
314 const { status, data } = e.response; | |
315 displayError({ | |
316 title: this.$gettext("Backend Error"), | |
317 message: `${status}: ${data.message || data}` | |
318 }); | |
319 }); | |
320 } | |
321 }, | |
322 downloadPDF() { | 279 downloadPDF() { |
323 let fairwayInfo = | 280 let fairwayInfo = |
324 this.selectedBottleneck + " (" + this.selectedSurvey.date_info + ")"; | 281 this.selectedBottleneck + " (" + this.selectedSurvey.date_info + ")"; |
325 | 282 |
326 this.generatePDF({ | 283 this.generatePDF({ |
381 this.pdf.doc.circle(x, y + 25, 2, "FD"); | 338 this.pdf.doc.circle(x, y + 25, 2, "FD"); |
382 this.pdf.doc.text(x + 3, y + 26, "Sediment (Compare)"); | 339 this.pdf.doc.text(x + 3, y + 26, "Sediment (Compare)"); |
383 }, | 340 }, |
384 getPrintLayout() { | 341 getPrintLayout() { |
385 return { | 342 return { |
386 main: { | 343 main: { top: 20, right: 80, bottom: 60, left: 80 } |
387 top: 20, | |
388 right: 80, | |
389 bottom: 60, | |
390 left: 80 | |
391 } | |
392 }; | 344 }; |
393 }, | 345 }, |
394 drawDiagram() { | 346 drawDiagram() { |
395 d3.select(".diagram-container svg").remove(); | 347 d3.select("#" + this.containerId + " svg").remove(); |
396 this.scaleFairwayProfile(); | 348 this.scaleFairwayProfile(); |
397 if (!this.height || !this.width) return; // do not try to render when height and width are unknown | 349 if (!this.height || !this.width) return; // do not try to render when height and width are unknown |
398 const layout = this.getPrintLayout(this.height); | 350 const layout = this.getPrintLayout(this.height); |
399 this.renderTo({ | 351 this.renderTo({ |
400 element: ".diagram-container", | 352 element: "#" + this.containerId, |
401 dimensions: this.getDimensions({ | 353 dimensions: this.getDimensions({ |
402 svgWidth: this.width, | 354 svgWidth: this.width, |
403 svgHeight: this.height, | 355 svgHeight: this.height, |
404 ...layout | 356 ...layout |
405 }) | 357 }) |
672 .attr("fill-opacity", 0) | 624 .attr("fill-opacity", 0) |
673 .attr("d", profileLine); | 625 .attr("d", profileLine); |
674 } | 626 } |
675 }, | 627 }, |
676 scaleFairwayProfile() { | 628 scaleFairwayProfile() { |
677 if (!document.querySelector(".diagram-container")) return; | 629 if (!document.querySelector("#" + this.containerId)) return; |
678 const clientHeight = document.querySelector(".diagram-container") | 630 const clientHeight = document.querySelector("#" + this.containerId) |
679 .clientHeight; | 631 .clientHeight; |
680 const clientWidth = document.querySelector(".diagram-container") | 632 const clientWidth = document.querySelector("#" + this.containerId) |
681 .clientWidth; | 633 .clientWidth; |
682 if (!clientHeight || !clientWidth) return; | 634 if (!clientHeight || !clientWidth) return; |
683 this.height = clientHeight; | 635 this.height = clientHeight; |
684 this.width = clientWidth; | 636 this.width = clientWidth; |
685 } | 637 } |
686 }, | |
687 created() { | |
688 this.resizeListenerFunction = debounce(this.drawDiagram, 100); | |
689 window.addEventListener("resize", this.resizeListenerFunction); | |
690 }, | |
691 mounted() { | |
692 // Nasty but necessary if we don't want to use the updated hook to re-draw | |
693 // the diagram because this would re-draw it also for irrelevant reasons. | |
694 // In this case we need to wait for the child component (DiagramLegend) to | |
695 // render. According to the docs (https://vuejs.org/v2/api/#mounted) this | |
696 // should be possible with $nextTick() but it doesn't work because it does | |
697 // not guarantee that the DOM is not only updated but also re-painted on the | |
698 // screen. | |
699 setTimeout(this.drawDiagram, 150); | |
700 | |
701 this.templates[0] = this.defaultTemplate; | |
702 this.form.template = this.templates[0]; | |
703 this.templateData = this.form.template; | |
704 HTTP.get("/templates/diagram", { | |
705 headers: { | |
706 "X-Gemma-Auth": localStorage.getItem("token"), | |
707 "Content-type": "text/xml; charset=UTF-8" | |
708 } | |
709 }) | |
710 .then(response => { | |
711 if (response.data.length) { | |
712 this.templates = response.data; | |
713 this.form.template = this.templates[0]; | |
714 this.templates[this.templates.length] = this.defaultTemplate; | |
715 this.applyChange(); | |
716 } | |
717 }) | |
718 .catch(e => { | |
719 const { status, data } = e.response; | |
720 displayError({ | |
721 title: this.$gettext("Backend Error"), | |
722 message: `${status}: ${data.message || data}` | |
723 }); | |
724 }); | |
725 }, | |
726 updated() { | |
727 this.drawDiagram(); | |
728 }, | |
729 destroyed() { | |
730 window.removeEventListener("resize", this.resizeListenerFunction); | |
731 } | 638 } |
732 }; | 639 }; |
733 </script> | 640 </script> |