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(