Mercurial > gemma
comparison client/src/components/fairway/AvailableFairwayDepthLNWL.vue @ 3890:59dba489ec7b improve-fwa-diagrams
Merge with default
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Wed, 10 Jul 2019 14:27:40 +0200 |
parents | d82b5e5868e3 ee0066dcfb93 |
children | 3c095749efb2 |
comparison
equal
deleted
inserted
replaced
3879:20be498adaf7 | 3890:59dba489ec7b |
---|---|
59 * without warranty, see README.md and license for details. | 59 * without warranty, see README.md and license for details. |
60 * | 60 * |
61 * SPDX-License-Identifier: AGPL-3.0-or-later | 61 * SPDX-License-Identifier: AGPL-3.0-or-later |
62 * License-Filename: LICENSES/AGPL-3.0.txt | 62 * License-Filename: LICENSES/AGPL-3.0.txt |
63 * | 63 * |
64 * Copyright (C) 2018 by via donau | 64 * Copyright (C) 2018, 2019 by via donau |
65 * – Österreichische Wasserstraßen-Gesellschaft mbH | 65 * – Österreichische Wasserstraßen-Gesellschaft mbH |
66 * Software engineering by Intevation GmbH | 66 * Software engineering by Intevation GmbH |
67 * | 67 * |
68 * Author(s): | 68 * Author(s): |
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"; | 74 import app from "@/main"; |
75 import debounce from "debounce"; | 75 import debounce from "debounce"; |
76 import { diagram } from "@/lib/mixins"; | |
77 import { mapState } from "vuex"; | 76 import { mapState } from "vuex"; |
77 import svg2pdf from "svg2pdf.js"; | |
78 import filters from "@/lib/filters.js"; | 78 import filters from "@/lib/filters.js"; |
79 import jsPDF from "jspdf"; | 79 import { diagram, pdfgen, templateLoader } from "@/lib/mixins"; |
80 import canvg from "canvg"; | |
81 import { pdfgen } from "@/lib/mixins"; | |
82 import { HTTP } from "@/lib/http"; | 80 import { HTTP } from "@/lib/http"; |
83 import { displayError } from "@/lib/errors"; | 81 import { displayError } from "@/lib/errors"; |
84 | 82 |
85 export default { | 83 export default { |
86 mixins: [diagram, pdfgen], | 84 mixins: [diagram, pdfgen, templateLoader], |
87 components: { | 85 components: { |
88 DiagramLegend: () => import("@/components/DiagramLegend") | 86 DiagramLegend: () => import("@/components/DiagramLegend") |
89 }, | 87 }, |
90 data() { | 88 data() { |
91 return { | 89 return { |
116 }, | 114 }, |
117 elements: [ | 115 elements: [ |
118 { | 116 { |
119 type: "diagram", | 117 type: "diagram", |
120 position: "topleft", | 118 position: "topleft", |
121 offset: { x: 20, y: 60 }, | 119 offset: { x: 20, y: 30 }, |
122 width: 290, | 120 width: 290, |
123 height: 100 | 121 height: 100 |
124 }, | 122 }, |
125 { | 123 { |
126 type: "diagramtitle", | 124 type: "diagramtitle", |
130 color: "steelblue" | 128 color: "steelblue" |
131 }, | 129 }, |
132 { | 130 { |
133 type: "diagramlegend", | 131 type: "diagramlegend", |
134 position: "topleft", | 132 position: "topleft", |
135 offset: { x: 30, y: 160 }, | 133 offset: { x: 30, y: 170 }, |
136 color: "black" | 134 color: "black" |
137 } | 135 } |
138 ] | 136 ] |
139 } | 137 } |
140 }; | 138 }; |
269 if (this.form.template.hasOwnProperty("properties")) { | 267 if (this.form.template.hasOwnProperty("properties")) { |
270 this.templateData = this.defaultTemplate; | 268 this.templateData = this.defaultTemplate; |
271 return; | 269 return; |
272 } | 270 } |
273 if (this.form.template) { | 271 if (this.form.template) { |
274 HTTP.get("/templates/diagram/" + this.form.template.name, { | 272 this.loadTemplates("/templates/diagram/" + this.form.template.name) |
275 headers: { | |
276 "X-Gemma-Auth": localStorage.getItem("token"), | |
277 "Content-type": "text/xml; charset=UTF-8" | |
278 } | |
279 }) | |
280 .then(response => { | 273 .then(response => { |
281 this.templateData = response.data.template_data; | 274 this.prepareImages(response.data.template_data.elements).then( |
275 values => { | |
276 values.forEach(v => { | |
277 response.data.template_data.elements[v.index].url = v.url; | |
278 }); | |
279 this.templateData = response.data.template_data; | |
280 } | |
281 ); | |
282 }) | 282 }) |
283 .catch(e => { | 283 .catch(e => { |
284 const { status, data } = e.response; | 284 const { status, data } = e.response; |
285 displayError({ | 285 displayError({ |
286 title: this.$gettext("Backend Error"), | 286 title: this.$gettext("Backend Error"), |
288 }); | 288 }); |
289 }); | 289 }); |
290 } | 290 } |
291 }, | 291 }, |
292 downloadPDF() { | 292 downloadPDF() { |
293 this.pdf.doc = new jsPDF( | 293 let title = `Available Fairway Depth vs LNWL: ${this.featureName}`; |
294 "l", | 294 this.generatePDF({ |
295 "mm", | 295 templateData: this.templateData, |
296 this.templateData.properties.paperSize | 296 diagramTitle: title |
297 ); | 297 }); |
298 // pdf width and height in millimeter (landscape) | |
299 this.pdf.width = | |
300 this.templateData.properties.paperSize === "a3" ? 420 : 297; | |
301 this.pdf.height = | |
302 this.templateData.properties.paperSize === "a3" ? 297 : 210; | |
303 if (this.templateData) { | |
304 // default values if some are missing in template | |
305 let defaultFontSize = 11, | |
306 defaultColor = "black", | |
307 defaultWidth = 70, | |
308 defaultTextColor = "black", | |
309 defaultBorderColor = "white", | |
310 defaultBgColor = "white", | |
311 defaultRounding = 2, | |
312 defaultPadding = 2, | |
313 defaultOffset = { x: 0, y: 0 }; | |
314 this.templateData.elements.forEach(e => { | |
315 switch (e.type) { | |
316 case "diagram": { | |
317 this.addDiagram( | |
318 e.position, | |
319 e.offset || defaultOffset, | |
320 e.width, | |
321 e.height | |
322 ); | |
323 break; | |
324 } | |
325 case "diagramtitle": { | |
326 let title = `Available Fairway Depth vs LNWL: ${ | |
327 this.featureName | |
328 }`; | |
329 this.addDiagramTitle( | |
330 e.position, | |
331 e.offset || defaultOffset, | |
332 e.fontsize || defaultFontSize, | |
333 e.color || defaultColor, | |
334 title | |
335 ); | |
336 break; | |
337 } | |
338 case "diagramlegend": { | |
339 this.addDiagramLegend( | |
340 e.position, | |
341 e.offset || defaultOffset, | |
342 e.color || defaultColor | |
343 ); | |
344 break; | |
345 } | |
346 case "text": { | |
347 this.addText( | |
348 e.position, | |
349 e.offset || defaultOffset, | |
350 e.width || defaultWidth, | |
351 e.fontsize || defaultFontSize, | |
352 e.color || defaultTextColor, | |
353 e.text || "" | |
354 ); | |
355 break; | |
356 } | |
357 case "image": { | |
358 this.addImage( | |
359 e.url, | |
360 e.format || "", | |
361 e.position, | |
362 e.offset || defaultOffset, | |
363 e.width || 90, | |
364 e.height || 60 | |
365 ); | |
366 break; | |
367 } | |
368 case "box": { | |
369 this.addBox( | |
370 e.position, | |
371 e.offset || defaultOffset, | |
372 e.width || 90, | |
373 e.height || 60, | |
374 e.rounding === 0 || e.rounding ? e.rounding : defaultRounding, | |
375 e.color || defaultBgColor, | |
376 e.brcolor || defaultBorderColor | |
377 ); | |
378 break; | |
379 } | |
380 case "textbox": { | |
381 this.addTextBox( | |
382 e.position, | |
383 e.offset || defaultOffset, | |
384 e.width, | |
385 e.height, | |
386 e.rounding === 0 || e.rounding ? e.rounding : defaultRounding, | |
387 e.padding || defaultPadding, | |
388 e.fontsize || defaultFontSize, | |
389 e.color || defaultTextColor, | |
390 e.background || defaultBgColor, | |
391 e.text || "", | |
392 e.brcolor || defaultBorderColor | |
393 ); | |
394 break; | |
395 } | |
396 } | |
397 }); | |
398 } | |
399 this.pdf.doc.save(`Available Fairway Depth LNWL: ${this.featureName}`); | 298 this.pdf.doc.save(`Available Fairway Depth LNWL: ${this.featureName}`); |
400 }, | 299 }, |
401 addDiagram(position, offset, width, height) { | 300 addDiagram(position, offset, width, height) { |
402 let x = offset.x, | 301 let x = offset.x, |
403 y = offset.y; | 302 y = offset.y; |
404 var svg = this.$refs.diagramContainer.innerHTML; | 303 |
405 if (svg) { | 304 var svgElement = this.$refs.diagramContainer.firstElementChild; |
406 svg = svg.replace(/\r?\n|\r/g, "").trim(); | 305 |
407 } | |
408 // use default width,height if they are missing in the template definition | 306 // use default width,height if they are missing in the template definition |
409 if (!width) { | 307 if (!width) { |
410 width = this.templateData.properties.paperSize === "a3" ? 380 : 290; | 308 width = this.templateData.properties.paperSize === "a3" ? 380 : 290; |
411 } | 309 } |
412 if (!height) { | 310 if (!height) { |
416 x = this.pdf.width - offset.x - width; | 314 x = this.pdf.width - offset.x - width; |
417 } | 315 } |
418 if (["bottomright", "bottomleft"].indexOf(position) !== -1) { | 316 if (["bottomright", "bottomleft"].indexOf(position) !== -1) { |
419 y = this.pdf.height - offset.y - height; | 317 y = this.pdf.height - offset.y - height; |
420 } | 318 } |
421 var canvas = document.createElement("canvas"); | 319 |
422 canvas.width = window.innerWidth; | 320 svg2pdf(svgElement, this.pdf.doc, { |
423 canvas.height = window.innerHeight / 2; | 321 xOffset: x, |
424 canvg(canvas, svg, { | 322 yOffset: y, |
425 ignoreMouse: true, | 323 scale: this.templateData.properties.paperSize === "a3" ? 0.45 : 0.18 // TODO depend on the size and aspect ration on paper |
426 ignoreAnimation: true, | |
427 ignoreDimensions: true | |
428 }); | 324 }); |
429 var imgData = canvas.toDataURL("image/png"); | |
430 this.pdf.doc.addImage(imgData, "PNG", x, y, width, height); | |
431 }, | 325 }, |
432 addDiagramLegend(position, offset, color) { | 326 addDiagramLegend(position, offset, color) { |
433 let x = offset.x, | 327 let x = offset.x, |
434 y = offset.y; | 328 y = offset.y; |
435 this.pdf.doc.setFontSize(10); | 329 this.pdf.doc.setFontSize(10); |
512 drawLabel(date, i) { | 406 drawLabel(date, i) { |
513 this.diagram | 407 this.diagram |
514 .append("text") | 408 .append("text") |
515 .text(date) | 409 .text(date) |
516 .attr("text-anchor", "middle") | 410 .attr("text-anchor", "middle") |
517 .attr("font-size", "smaller") | 411 .attr("font-size", "9") |
518 .attr( | 412 .attr( |
519 "transform", | 413 "transform", |
520 `translate(${this.scalePaddingLeft + | 414 `translate(${this.scalePaddingLeft + |
521 this.widthPerItem * i + | 415 this.widthPerItem * i + |
522 this.widthPerItem / 2} ${this.dimensions.mainHeight - 15})` | 416 this.widthPerItem / 2} ${this.dimensions.mainHeight - 15})` |
625 .append("text") | 519 .append("text") |
626 .text(this.$options.LEGEND) | 520 .text(this.$options.LEGEND) |
627 .attr("text-anchor", "middle") | 521 .attr("text-anchor", "middle") |
628 .attr("x", 0) | 522 .attr("x", 0) |
629 .attr("y", 0) | 523 .attr("y", 0) |
630 .attr("dy", "1em") | 524 .attr("dy", "10") |
631 .attr("transform", `translate(0, ${center}), rotate(-90)`); | 525 // translate a few mm to the right to allow for slightly higher letters |
526 .attr("transform", `translate(2, ${center}), rotate(-90)`); | |
632 }, | 527 }, |
633 drawScale() { | 528 drawScale() { |
634 const yAxisLeft = d3 | 529 const yAxisLeft = d3 |
635 .axisLeft() | 530 .axisLeft() |
636 .tickSizeInner( | 531 .tickSizeInner( |