Mercurial > gemma
changeset 3197:9d38df37c1f8
client: implemnt pdf-template for hydrologicalconditions diagram
author | Fadi Abbud <fadi.abbud@intevation.de> |
---|---|
date | Wed, 08 May 2019 15:08:27 +0200 |
parents | 0d76a0476a5b |
children | b0328646e34f |
files | client/src/components/gauge/HydrologicalConditions.vue |
diffstat | 1 files changed, 284 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/client/src/components/gauge/HydrologicalConditions.vue Wed May 08 14:35:40 2019 +0200 +++ b/client/src/components/gauge/HydrologicalConditions.vue Wed May 08 15:08:27 2019 +0200 @@ -25,6 +25,19 @@ <span style="background-color: lightsteelblue"></span> Long-term Amplitude </div> + <select + @change="applyChange" + v-model="form.template" + 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> <div> <button @click="downloadPDF" @@ -69,8 +82,12 @@ import { startOfYear, endOfYear } from "date-fns"; import jsPDF from "jspdf"; import canvg from "canvg"; +import { pdfgen } from "@/lib/mixins"; +import { HTTP } from "@/lib/http"; +import { displayError } from "@/lib/errors"; export default { + mixins: [pdfgen], components: { DiagramLegend: () => import("@/components/DiagramLegend") }, @@ -83,7 +100,47 @@ dimensions: null, extent: null, scale: null, - axes: null + axes: null, + templateData: null, + form: { + template: null, + form: null + }, + templates: [], + defaultTemplate: { + name: "Default", + properties: { + paperSize: "a4", + resolution: 80 + }, + elements: [ + { + type: "diagram", + position: "topleft", + offset: { x: 15, y: 50 }, + width: 290, + height: 100 + }, + { + type: "diagramlegend", + position: "topleft", + offset: { x: 30, y: 150 }, + colot: "black" + }, + { + type: "diagramtitle", + position: "topleft", + offset: { x: 50, y: 26 }, + fontsize: 22, + color: "steelblue" + } + ] + }, + pdf: { + doc: null, + width: 420, + height: 297 + } }; }, computed: { @@ -122,11 +179,115 @@ ); }, 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; + // default values if some are missing in template + let defaultFontSize = 11, + defaultColor = "black", + defaultWidth = 70, + defaultTextColor = "black", + defaultBorderColor = "white", + defaultBgColor = "white", + defaultRounding = 2, + defaultPadding = 2, + defaultOffset = { x: 0, y: 0 }; + this.templateData.elements.forEach(e => { + switch (e.type) { + case "diagram": { + this.addDiagram( + e.position, + e.offset || defaultOffset, + e.width, + e.height + ); + break; + } + case "diagramtitle": { + this.addDiagramTitle(e.position, e.offset, e.fontsize, e.color); + break; + } + case "diagramlegend": { + this.addDiagramLegend( + e.position, + e.offset || defaultOffset, + e.color || defaultColor + ); + break; + } + case "image": { + this.addImage( + e.url, + e.format, + e.position, + e.offset || defaultOffset, + e.width, + e.height + ); + break; + } + case "text": { + this.addText( + e.position, + e.offset || defaultOffset, + e.width || defaultWidth, + e.fontSize || defaultFontSize, + e.color || defaultTextColor, + e.text + ); + break; + } + case "box": { + this.addBox( + e.position, + e.offset, + e.width, + e.height, + e.rounding === 0 || e.rounding ? e.rounding : defaultRounding, + e.color || defaultBgColor, + e.brcolor || defaultBorderColor + ); + break; + } + case "textbox": { + this.addTextBox( + e.position, + e.offset || defaultOffset, + e.width, + e.height, + e.rounding === 0 || e.rounding ? e.rounding : defaultRounding, + e.padding || defaultPadding, + e.fontSize || defaultFontSize, + e.color || defaultTextColor, + e.background || defaultBgColor, + e.text, + e.brcolor || defaultBorderColor + ); + break; + } + } + }); + } + this.pdf.doc.save( + this.selectedGauge.properties.objname + + " Hydrological-condition Diagram.pdf" + ); + }, + addDiagram(position, offset, width, height) { + let x = offset.x, + y = offset.y; var svg = document.getElementById(this.containerId).innerHTML; if (svg) { svg = svg.replace(/\r?\n|\r/g, "").trim(); } - var pdf = new jsPDF("l", "mm", "a3"); var canvas = document.createElement("canvas"); canvas.width = window.innerWidth; canvas.height = window.innerHeight / 2; @@ -136,16 +297,50 @@ ignoreDimensions: true }); var imgData = canvas.toDataURL("image/png"); - pdf.addImage(imgData, "PNG", 40, 60, 380, 130); - this.addDiagramTitle(pdf, 108, 30, 22, "steelblue"); - this.addDiagramLegend(pdf, 60, 190, "black"); - pdf.save( - this.selectedGauge.properties.objname + - " Hydrological-condition Diagram.pdf" - ); + // landscape format is used for both a3,a4 papersize + if (!width) { + width = this.templateData.properties.paperSize === "a3" ? 380 : 290; + } + if (!height) { + height = this.templateData.properties.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; + } + this.pdf.doc.addImage(imgData, "PNG", x, y, width, height); + }, + applyChange() { + if (this.form.template.hasOwnProperty("properties")) { + this.templateData = this.defaultTemplate; + return; + } + if (this.form.template) { + HTTP.get("/templates/print/" + 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; + this.form.paperSize = this.templateData.properties.paperSize; + }) + .catch(e => { + const { status, data } = e.response; + displayError({ + title: this.$gettext("Backend Error"), + message: `${status}: ${data.message || data}` + }); + }); + } }, // Gauge info as title - addDiagramTitle(pdf, x, y, size, color) { + addDiagramTitle(position, offset, size, color) { + let x = offset.x, + y = offset.y; let gaugeInfo = this.selectedGauge.properties.objname + " (" + @@ -155,31 +350,63 @@ .split(",")[3] + "): Hydrological Conditions " + this.longtermInterval.join(" - "); - pdf.setTextColor(color); - pdf.setFontSize(22); - pdf.setFontStyle("bold"); - pdf.text(gaugeInfo, 108, 30); + let width = + (this.pdf.doc.getStringUnitWidth(gaugeInfo) * 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(gaugeInfo, x, y, { baseline: "hanging" }); + }, + getTextHeight(numberOfLines) { + return ( + numberOfLines * + ((this.pdf.doc.getFontSize() * 25.4) / 80) * + this.pdf.doc.getLineHeightFactor() + ); }, // Diagram legend - addDiagramLegend(pdf, x, y, color) { - pdf.setFontSize(10); - pdf.setTextColor(color); - pdf.setDrawColor("white"); - pdf.setFillColor("red"); - pdf.circle(x, y, 2, "FD"); - pdf.text(x + 3, y + 1, "" + this.yearCompare); - pdf.setFillColor("orange"); - pdf.circle(x, y + 5, 2, "FD"); - pdf.text(x + 3, y + 6, "Q25%"); - pdf.setFillColor("black"); - pdf.circle(x, y + 10, 2, "FD"); - pdf.text(x + 3, y + 11, "Median "); - pdf.setFillColor("purple"); - pdf.circle(x, y + 15, 2, "FD"); - pdf.text(x + 3, y + 16, "Q75%"); - pdf.setFillColor("lightsteelblue"); - pdf.circle(x, y + 20, 2, "FD"); - pdf.text(x + 3, y + 21, "Long-term Amplitude"); + addDiagramLegend(position, offset, color) { + let x = offset.x, + y = offset.y; + let width = + (this.pdf.doc.getStringUnitWidth("Long-term Amplitude") * 10) / + (72 / 25.6) + + 5; + // 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(4); + } + this.pdf.doc.setFontSize(10); + this.pdf.doc.setTextColor(color); + this.pdf.doc.setDrawColor("white"); + this.pdf.doc.setFillColor("red"); + this.pdf.doc.circle(x, y, 2, "FD"); + this.pdf.doc.text(x + 3, y + 1, "" + this.yearCompare); + this.pdf.doc.setFillColor("orange"); + this.pdf.doc.circle(x, y + 5, 2, "FD"); + this.pdf.doc.text(x + 3, y + 6, "Q25%"); + this.pdf.doc.setFillColor("black"); + this.pdf.doc.circle(x, y + 10, 2, "FD"); + this.pdf.doc.text(x + 3, y + 11, "Median "); + this.pdf.doc.setFillColor("purple"); + this.pdf.doc.circle(x, y + 15, 2, "FD"); + this.pdf.doc.text(x + 3, y + 16, "Q75%"); + this.pdf.doc.setFillColor("lightsteelblue"); + this.pdf.doc.circle(x, y + 20, 2, "FD"); + this.pdf.doc.text(x + 3, y + 21, "Long-term Amplitude"); }, drawDiagram() { // remove old diagram @@ -847,6 +1074,30 @@ }, mounted() { this.drawDiagram(); + this.templates[0] = this.defaultTemplate; + this.form.template = this.templates[0]; + this.templateData = this.form.template; + HTTP.get("/templates/print", { + 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();