Mercurial > gemma
changeset 3240:5240f5440b62
client: implemnt pdf-template for fairwayprofile diagram
author | Fadi Abbud <fadi.abbud@intevation.de> |
---|---|
date | Fri, 10 May 2019 12:09:24 +0200 |
parents | a7d44d1ae57d |
children | ecfa09241437 |
files | client/src/components/fairway/Fairwayprofile.vue |
diffstat | 1 files changed, 211 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/components/fairway/Fairwayprofile.vue Fri May 10 11:56:57 2019 +0200 +++ b/client/src/components/fairway/Fairwayprofile.vue Fri May 10 12:09:24 2019 +0200 @@ -14,6 +14,19 @@ Ground </div> <div> + <select + v-model="form.template" + @change="applyChange" + class="form-control d-block custom-select-sm w-100" + > + <option + v-for="template in templates" + :value="template" + :key="template.name" + > + {{ template.name }} + </option> + </select> <button @click="downloadPDF" type="button" @@ -55,11 +68,15 @@ import debounce from "debounce"; import jsPDF from "jspdf"; import canvg from "canvg"; +import { pdfgen } from "@/lib/mixins"; +import { HTTP } from "@/lib/http"; +import { displayError } from "@/lib/errors"; const GROUND_COLOR = "#4A2F06"; const WATER_COLOR = "#005DFF"; export default { + mixins: [pdfgen], name: "fairwayprofile", components: { DiagramLegend: () => import("@/components/DiagramLegend") @@ -73,7 +90,46 @@ right: 40, bottom: 30, left: 40 - } + }, + form: { + template: null + }, + templates: [], + defaultTemplate: { + name: "default", + properties: { + paperSize: "a4", + format: "lanscape" + }, + elements: [ + { + type: "diagram", + position: "topleft", + offset: { x: 20, y: 60 }, + width: 290, + height: 100 + }, + { + type: "diagramtitle", + position: "topleft", + offset: { x: 90, y: 30 }, + fontsize: 22, + color: "steelblue" + }, + { + type: "diagramlegend", + position: "topleft", + offset: { x: 30, y: 160 }, + color: "black" + } + ] + }, + pdf: { + doc: null, + width: 32, + height: 297 + }, + templateData: null }; }, computed: { @@ -175,12 +231,92 @@ ); this.$store.dispatch("fairwayprofile/clearCurrentProfile"); }, + applyChange() { + if (this.form.template.hasOwnProperty("properties")) { + this.templateData = this.defaultTemplate; + return; + } + if (this.form.template) { + HTTP.get("/templates/diagram/" + this.form.template.name, { + headers: { + "X-Gemma-Auth": localStorage.getItem("token"), + "Content-type": "text/xml; charset=UTF-8" + } + }) + .then(response => { + this.templateData = response.data.template_data; + }) + .catch(e => { + const { status, data } = e.response; + displayError({ + title: this.$gettext("Backend Error"), + message: `${status}: ${data.message || data}` + }); + }); + } + }, downloadPDF() { + if (this.templateData) { + this.pdf.doc = new jsPDF( + "l", + "mm", + this.templateData.properties.paperSize + ); + // pdf width and height in millimeter (landscape) + this.pdf.width = + this.templateData.properties.paperSize === "a3" ? 420 : 297; + this.pdf.height = + this.templateData.properties.paperSize === "a3" ? 297 : 210; + let defaultOffset = { x: 0, Y: 0 }, + defaultColor = "black"; + this.templateData.elements.forEach(e => { + switch (e.type) { + case "diagram": { + this.addDiagram( + e.position, + e.offset || defaultOffset, + e.width, + e.height + ); + break; + } + case "diagramlegend": { + this.addDiagramLegend( + e.position, + e.offset || defaultOffset, + e.color || defaultColor + ); + break; + } + case "diagramtitle": { + this.addDiagramTitle(e.position, e.offset, e.fontsize, e.color); + break; + } + } + }); + } + this.pdf.doc.save("Fairwayprofile diagram"); + }, + addDiagram(position, offset, width, height) { + let x = offset.x, + y = offset.y; var svg = this.$refs.diagramContainer.innerHTML; if (svg) { svg = svg.replace(/\r?\n|\r/g, "").trim(); } - var pdf = new jsPDF("l", "mm", "a3"); + // landscape format is used for both a3,a4 papersize + if (!width) { + width = this.form.paperSize === "a3" ? 380 : 290; + } + if (!height) { + height = this.form.paperSize === "a3" ? 130 : 100; + } + if (["topright", "bottomright"].indexOf(position) !== -1) { + x = this.pdf.width - offset.x - width; + } + if (["bottomright", "bottomleft"].indexOf(position) !== -1) { + y = this.pdf.height - offset.y - height; + } var canvas = document.createElement("canvas"); canvas.width = window.innerWidth; canvas.height = window.innerHeight / 2; @@ -190,34 +326,60 @@ ignoreDimensions: true }); var imgData = canvas.toDataURL("image/png"); - pdf.addImage(imgData, "PNG", 40, 60, 380, 130); - // Fairway profile info for the pdf title - this.addDiagramTitle(pdf, 140, 30, 22, "steelblue"); - this.addDiagramLegend(pdf, 60, 190, "black"); - pdf.save("Fairwayprofile diagram"); + this.pdf.doc.addImage(imgData, "PNG", x, y, width, height); }, - addDiagramTitle(pdf, x, y, size, color) { + addDiagramTitle(position, offset, size, color) { + let x = offset.x, + y = offset.y; let fairwayInfo = this.selectedBottleneck + " (" + this.selectedSurvey.date_info + ")"; - pdf.setTextColor(color); - pdf.setFontSize(22); - pdf.setFontStyle("bold"); - pdf.text(fairwayInfo, x, y); + let width = + (this.pdf.doc.getStringUnitWidth(fairwayInfo) * size) / (72 / 25.6) + + size / 2; + // if position is on the right, x needs to be calculate with pdf width and + // the size of the element + if (["topright", "bottomright"].indexOf(position) !== -1) { + x = this.pdf.width - offset.x - width; + } + if (["bottomright", "bottomleft"].indexOf(position) !== -1) { + y = this.pdf.height - offset.y - this.getTextHeight(1); + } + this.pdf.doc.setTextColor(color); + this.pdf.doc.setFontSize(size); + this.pdf.doc.setFontStyle("bold"); + this.pdf.doc.text(fairwayInfo, x, y, { baseline: "hanging" }); }, // Diagram legend - addDiagramLegend(pdf, x, y, color) { - pdf.setFontSize(10); - pdf.setTextColor(color); - pdf.setDrawColor("white"); - pdf.setFillColor("#5995ff"); - pdf.circle(x, y, 2, "FD"); - pdf.text(x + 3, y + 1, "Water"); - pdf.setFillColor("#1f4fff"); - pdf.circle(x, y + 5, 2, "FD"); - pdf.text(x + 3, y + 6, "Fairway"); - pdf.setFillColor("#4a2f06"); - pdf.circle(x, y + 10, 2, "FD"); - pdf.text(x + 3, y + 11, "Ground"); + addDiagramLegend(position, offset, color) { + let x = offset.x, + y = offset.y; + let width = + (this.pdf.doc.getStringUnitWidth("Ground") * 10) / (72 / 25.6) + 5; + if (["topright", "bottomright"].indexOf(position) !== -1) { + x = this.pdf.width - offset.x - width; + } + if (["bottomright", "bottomleft"].indexOf(position) !== -1) { + y = this.pdf.height - offset.y - this.getTextHeight(3); + } + this.pdf.doc.setFontSize(10); + this.pdf.doc.setTextColor(color); + this.pdf.doc.setDrawColor("white"); + this.pdf.doc.setFillColor("#5995ff"); + this.pdf.doc.circle(x, y, 2, "FD"); + this.pdf.doc.text(x + 3, y + 1, "Water"); + this.pdf.doc.setFillColor("#1f4fff"); + this.pdf.doc.circle(x, y + 5, 2, "FD"); + this.pdf.doc.text(x + 3, y + 6, "Fairway"); + this.pdf.doc.setFillColor("#4a2f06"); + this.pdf.doc.circle(x, y + 10, 2, "FD"); + this.pdf.doc.text(x + 3, y + 11, "Ground"); + }, + getTextHeight(numberOfLines) { + return ( + numberOfLines * + ((this.pdf.doc.getFontSize() * 25.4) / 80) * + this.pdf.doc.getLineHeightFactor() + ); }, calcRelativeDepth(depth) { /* takes a depth value and substracts the delta of the relative waterlevel @@ -460,6 +622,30 @@ }, mounted() { this.drawDiagram(); + this.templates[0] = this.defaultTemplate; + this.form.template = this.templates[0]; + this.templateData = this.form.template; + HTTP.get("/templates/diagram", { + headers: { + "X-Gemma-Auth": localStorage.getItem("token"), + "Content-type": "text/xml; charset=UTF-8" + } + }) + .then(response => { + if (response.data.length) { + this.templates = response.data; + this.form.template = this.templates[0]; + this.templates[this.templates.length] = this.defaultTemplate; + this.applyChange(); + } + }) + .catch(e => { + const { status, data } = e.response; + displayError({ + title: this.$gettext("Backend Error"), + message: `${status}: ${data.message || data}` + }); + }); }, updated() { this.drawDiagram();