comparison client/src/components/fairway/AvailableFairwayDepthLNWL.vue @ 3992:2f024d6189ca

Reverted merge with diagram-cleanup -- its not yet ready.
author Sascha Wilde <wilde@intevation.de>
date Wed, 17 Jul 2019 15:12:23 +0200
parents 2aaa1948b525
children 44060b9027da
comparison
equal deleted inserted replaced
3991:06096a7ce1c5 3992:2f024d6189ca
1 <template> 1 <template>
2 <div class="d-flex flex-column flex-fill"> 2 <div class="d-flex flex-column flex-fill">
3 <UIBoxHeader icon="chart-area" :title="title" :closeCallback="close" /> 3 <UIBoxHeader icon="chart-area" :title="title" :closeCallback="close" />
4 <UISpinnerOverlay v-if="loading" />
4 <div class="d-flex flex-fill"> 5 <div class="d-flex flex-fill">
5 <DiagramLegend> 6 <DiagramLegend>
6 <div v-for="(entry, index) in legendLNWL" :key="index" class="legend"> 7 <div v-for="(entry, index) in legendLNWL" :key="index" class="legend">
7 <span 8 <span
8 :style=" 9 :style="
41 >Download CSV</a 42 >Download CSV</a
42 > 43 >
43 </div> 44 </div>
44 </DiagramLegend> 45 </DiagramLegend>
45 <div 46 <div
46 class="d-flex flex-fill justify-content-center align-items-center" 47 ref="diagramContainer"
47 :id="containerId" 48 :id="containerId"
48 > 49 class="diagram-container flex-fill"
49 <div v-if="!fwLNWLData.length"> 50 ></div>
50 <translate>No data available.</translate>
51 </div>
52 </div>
53 </div> 51 </div>
54 </div> 52 </div>
55 </template> 53 </template>
54
55 <style></style>
56 56
57 <script> 57 <script>
58 /* This is Free Software under GNU Affero General Public License v >= 3.0 58 /* This is Free Software under GNU Affero General Public License v >= 3.0
59 * without warranty, see README.md and license for details. 59 * without warranty, see README.md and license for details.
60 * 60 *
69 * * Thomas Junk <thomas.junk@intevation.de> 69 * * Thomas Junk <thomas.junk@intevation.de>
70 * * Markus Kottländer <markus.kottlaender@intevation.de> 70 * * Markus Kottländer <markus.kottlaender@intevation.de>
71 * * Fadi Abbud <fadi.abbud@intevation.de> 71 * * Fadi Abbud <fadi.abbud@intevation.de>
72 */ 72 */
73 import * as d3 from "d3"; 73 import * as d3 from "d3";
74 import app from "@/main";
75 import debounce from "debounce";
74 import { mapState } from "vuex"; 76 import { mapState } from "vuex";
77 import filters from "@/lib/filters.js";
75 import { diagram, pdfgen, templateLoader } from "@/lib/mixins"; 78 import { diagram, pdfgen, templateLoader } from "@/lib/mixins";
76 import filters from "@/lib/filters.js"; 79 import { HTTP } from "@/lib/http";
80 import { displayError } from "@/lib/errors";
81 import { defaultDiagramTemplate } from "@/lib/DefaultDiagramTemplate";
77 82
78 export default { 83 export default {
79 mixins: [diagram, pdfgen, templateLoader], 84 mixins: [diagram, pdfgen, templateLoader],
85 components: {
86 DiagramLegend: () => import("@/components/DiagramLegend")
87 },
80 data() { 88 data() {
81 return { 89 return {
82 containerId: "availablefairwaydepthlnwl-diagram-container", 90 containerId: "availablefairwaydepthlnwl-diagram-container",
91 resizeListenerFunction: null,
92 loading: false,
83 scalePaddingLeft: 60, 93 scalePaddingLeft: 60,
84 scalePaddingRight: 0, 94 scalePaddingRight: 0,
85 paddingTop: 25, 95 paddingTop: 25,
86 colors: { 96 pdf: {
87 afd: ["#3636ff", "#f49b7f", "#e15472"], 97 doc: null,
88 lnwl: "#97ddf3" 98 width: null,
99 height: null
100 },
101 form: {
102 template: null
103 },
104 templateData: null,
105 templates: [],
106 defaultTemplate: defaultDiagramTemplate
107 };
108 },
109 created() {
110 this.resizeListenerFunction = debounce(this.drawDiagram, 100);
111 window.addEventListener("resize", this.resizeListenerFunction);
112 },
113 destroyed() {
114 window.removeEventListener("resize", this.resizeListenerFunction);
115 },
116 mounted() {
117 // Nasty but necessary if we don't want to use the updated hook to re-draw
118 // the diagram because this would re-draw it also for irrelevant reasons.
119 // In this case we need to wait for the child component (DiagramLegend) to
120 // render. According to the docs (https://vuejs.org/v2/api/#mounted) this
121 // should be possible with $nextTick() but it doesn't work because it does
122 // not guarantee that the DOM is not only updated but also re-painted on the
123 // screen.
124 setTimeout(this.drawDiagram, 150);
125
126 this.templates[0] = this.defaultTemplate;
127 this.form.template = this.templates[0];
128 this.templateData = this.form.template;
129 HTTP.get("/templates/diagram", {
130 headers: {
131 "X-Gemma-Auth": localStorage.getItem("token"),
132 "Content-type": "text/xml; charset=UTF-8"
89 } 133 }
90 }; 134 })
135 .then(response => {
136 if (response.data.length) {
137 this.templates = response.data;
138 this.form.template = this.templates[0];
139 this.templates[this.templates.length] = this.defaultTemplate;
140 this.applyChange();
141 }
142 })
143 .catch(e => {
144 const { status, data } = e.response;
145 displayError({
146 title: this.$gettext("Backend Error"),
147 message: `${status}: ${data.message || data}`
148 });
149 });
91 }, 150 },
92 computed: { 151 computed: {
93 ...mapState("fairwayavailability", [ 152 ...mapState("fairwayavailability", [
94 "selectedFairwayAvailabilityFeature", 153 "selectedFairwayAvailabilityFeature",
95 "fwLNWLData", 154 "fwLNWLData",
146 } 205 }
147 }, 206 },
148 methods: { 207 methods: {
149 legendStyle(index) { 208 legendStyle(index) {
150 const style = { 209 const style = {
151 0: `background-color: ${this.colors.lnwl};`, 210 0: `background-color: ${this.$options.LWNLCOLORS.LDC};`,
152 1: `background-color: ${this.colors.afd[2]};`, 211 1: `background-color: ${this.$options.AFDCOLORS[2]};`,
153 2: `background-color: ${this.colors.afd[1]};`, 212 2: `background-color: ${this.$options.AFDCOLORS[1]};`,
154 3: `background-color: ${this.colors.afd[0]};` 213 3: `background-color: ${this.$options.AFDCOLORS[0]};`
155 }; 214 };
156 return style[index]; 215 return style[index];
216 },
217 applyChange() {
218 if (this.form.template.hasOwnProperty("properties")) {
219 this.templateData = this.defaultTemplate;
220 return;
221 }
222 if (this.form.template) {
223 this.loadTemplates("/templates/diagram/" + this.form.template.name)
224 .then(response => {
225 this.prepareImages(response.data.template_data.elements).then(
226 values => {
227 values.forEach(v => {
228 response.data.template_data.elements[v.index].url = v.url;
229 });
230 this.templateData = response.data.template_data;
231 }
232 );
233 })
234 .catch(e => {
235 const { status, data } = e.response;
236 displayError({
237 title: this.$gettext("Backend Error"),
238 message: `${status}: ${data.message || data}`
239 });
240 });
241 }
242 },
243 downloadPDF() {
244 let title = `Available Fairway Depth vs LNWL: ${this.featureName}`;
245 this.generatePDF({
246 templateData: this.templateData,
247 diagramTitle: title
248 });
249 this.pdf.doc.save(`Available Fairway Depth LNWL: ${this.featureName}`);
157 }, 250 },
158 addDiagramLegend(position, offset, color) { 251 addDiagramLegend(position, offset, color) {
159 let x = offset.x, 252 let x = offset.x,
160 y = offset.y; 253 y = offset.y;
161 this.pdf.doc.setFontSize(10); 254 this.pdf.doc.setFontSize(10);
168 } 261 }
169 if (["bottomright", "bottomleft"].indexOf(position) !== -1) { 262 if (["bottomright", "bottomleft"].indexOf(position) !== -1) {
170 y = this.pdf.height - offset.y - this.getTextHeight(6); 263 y = this.pdf.height - offset.y - this.getTextHeight(6);
171 } 264 }
172 this.pdf.doc.setTextColor(color); 265 this.pdf.doc.setTextColor(color);
173 this.pdf.doc.setDrawColor(this.colors.lnwl); 266 this.pdf.doc.setDrawColor(this.$options.LWNLCOLORS.LDC);
174 this.pdf.doc.setFillColor(this.colors.lnwl); 267 this.pdf.doc.setFillColor(this.$options.LWNLCOLORS.LDC);
175 this.pdf.doc.roundedRect(x, y, 10, 4, 1.5, 1.5, "FD"); 268 this.pdf.doc.roundedRect(x, y, 10, 4, 1.5, 1.5, "FD");
176 this.pdf.doc.text(this.legendLNWL[0], x + 12, y + 3); 269 this.pdf.doc.text(this.legendLNWL[0], x + 12, y + 3);
177 270
178 this.pdf.doc.setDrawColor(this.colors.afd[2]); 271 this.pdf.doc.setDrawColor(this.$options.AFDCOLORS[2]);
179 this.pdf.doc.setFillColor(this.colors.afd[2]); 272 this.pdf.doc.setFillColor(this.$options.AFDCOLORS[2]);
180 this.pdf.doc.roundedRect(x, y + 5, 10, 4, 1.5, 1.5, "FD"); 273 this.pdf.doc.roundedRect(x, y + 5, 10, 4, 1.5, 1.5, "FD");
181 this.pdf.doc.text(this.legendLNWL[1], x + 12, y + 8); 274 this.pdf.doc.text(this.legendLNWL[1], x + 12, y + 8);
182 275
183 this.pdf.doc.setDrawColor(this.colors.afd[1]); 276 this.pdf.doc.setDrawColor(this.$options.AFDCOLORS[1]);
184 this.pdf.doc.setFillColor(this.colors.afd[1]); 277 this.pdf.doc.setFillColor(this.$options.AFDCOLORS[1]);
185 this.pdf.doc.roundedRect(x, y + 10, 10, 4, 1.5, 1.5, "FD"); 278 this.pdf.doc.roundedRect(x, y + 10, 10, 4, 1.5, 1.5, "FD");
186 this.pdf.doc.text(this.legendLNWL[2], x + 12, y + 13); 279 this.pdf.doc.text(this.legendLNWL[2], x + 12, y + 13);
187 280
188 this.pdf.doc.setDrawColor(this.colors.afd[0]); 281 this.pdf.doc.setDrawColor(this.$options.AFDCOLORS[0]);
189 this.pdf.doc.setFillColor(this.colors.afd[0]); 282 this.pdf.doc.setFillColor(this.$options.AFDCOLORS[0]);
190 this.pdf.doc.roundedRect(x, y + 15, 10, 4, 1.5, 1.5, "FD"); 283 this.pdf.doc.roundedRect(x, y + 15, 10, 4, 1.5, 1.5, "FD");
191 this.pdf.doc.text(this.legendLNWL[3], x + 12, y + 18); 284 this.pdf.doc.text(this.legendLNWL[3], x + 12, y + 18);
192 }, 285 },
193 close() { 286 close() {
194 this.$store.commit("application/paneSetup", "DEFAULT"); 287 this.$store.commit("application/paneSetup", "DEFAULT");
195 }, 288 },
196 getPrintLayout() { 289 getPrintLayout(svgHeight) {
197 return { 290 return {
198 main: { top: 0, right: 20, bottom: 50, left: 20 } 291 main: { top: 0, right: 20, bottom: 50, left: 20 },
292 nav: {
293 top: svgHeight - 65,
294 right: 20,
295 bottom: 30,
296 left: 80
297 }
199 }; 298 };
200 }, 299 },
201 drawDiagram() { 300 drawDiagram() {
202 const elem = document.querySelector("#" + this.containerId); 301 const elem = document.querySelector("#" + this.containerId);
203 const svgWidth = elem != null ? elem.clientWidth : 0; 302 const svgWidth = elem != null ? elem.clientWidth : 0;
204 const svgHeight = elem != null ? elem.clientHeight : 0; 303 const svgHeight = elem != null ? elem.clientHeight : 0;
205 const layout = this.getPrintLayout(); 304 const layout = this.getPrintLayout(svgHeight);
206 const dimensions = this.getDimensions({ 305 const dimensions = this.getDimensions({
207 svgHeight, 306 svgHeight,
208 svgWidth, 307 svgWidth,
209 ...layout 308 ...layout
210 }); 309 });
211 d3.select("#" + this.containerId + " svg").remove(); 310 d3.select(".diagram-container svg").remove();
212 this.renderTo({ element: "#" + this.containerId, dimensions }); 311 this.renderTo({ element: ".diagram-container", dimensions });
213 }, 312 },
214 drawTooltip(diagram) { 313 drawTooltip(diagram) {
215 diagram 314 diagram
216 .append("text") 315 .append("text")
217 .text("") 316 .text("")
341 } 440 }
342 }) 441 })
343 .attr("transform", `translate(0 ${this.paddingTop})`) 442 .attr("transform", `translate(0 ${this.paddingTop})`)
344 .attr("width", afdWidth) 443 .attr("width", afdWidth)
345 .attr("fill", (d, i) => { 444 .attr("fill", (d, i) => {
346 return this.colors.afd[i]; 445 return this.$options.AFDCOLORS[i];
347 }); 446 });
348 }, 447 },
349 drawLNWL(data, i, diagram, spaceBetween, widthPerItem, ldcWidth, yScale) { 448 drawLNWL(data, i, diagram, spaceBetween, widthPerItem, ldcWidth, yScale) {
350 let lnwl = diagram 449 let lnwl = diagram
351 .append("g") 450 .append("g")
385 return yScale(d); 484 return yScale(d);
386 }) 485 })
387 .attr("transform", `translate(0 ${this.paddingTop})`) 486 .attr("transform", `translate(0 ${this.paddingTop})`)
388 .attr("width", ldcWidth) 487 .attr("width", ldcWidth)
389 .attr("fill", () => { 488 .attr("fill", () => {
390 return this.colors.lnwl; 489 return this.$options.LWNLCOLORS.LDC;
391 }); 490 });
392 }, 491 },
393 drawScaleLabel({ diagram, dimensions }) { 492 drawScaleLabel({ diagram, dimensions }) {
394 diagram 493 diagram
395 .append("text") 494 .append("text")
396 .text(this.$gettext("Percent")) 495 .text(this.$options.LEGEND)
397 .attr("text-anchor", "middle") 496 .attr("text-anchor", "middle")
398 .attr("x", 0) 497 .attr("x", 0)
399 .attr("y", 0) 498 .attr("y", 0)
400 .attr("dy", "20") 499 .attr("dy", "20")
401 // translate a few mm to the right to allow for slightly higher letters 500 // translate a few mm to the right to allow for slightly higher letters
470 }, 569 },
471 watch: { 570 watch: {
472 fwLNWLData() { 571 fwLNWLData() {
473 this.drawDiagram(); 572 this.drawDiagram();
474 } 573 }
574 },
575 LEGEND: app.$gettext("Percent"),
576 AFDCOLORS: ["#3636ff", "#f49b7f", "#e15472"],
577 LWNLCOLORS: {
578 LDC: "#97ddf3",
579 HDC: "#43FFE1"
475 } 580 }
476 }; 581 };
477 </script> 582 </script>