Mercurial > gemma
diff client/src/lib/mixins.js @ 3963:feb53713bc2f diagram-cleanup
client: moved duplicated code to mixins and unified code patterns in diagram components [WIP]
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Fri, 12 Jul 2019 15:14:16 +0200 |
parents | 3c468ed76daf |
children | afc7bca44df4 |
line wrap: on
line diff
--- a/client/src/lib/mixins.js Fri Jul 12 11:58:20 2019 +0200 +++ b/client/src/lib/mixins.js Fri Jul 12 15:14:16 2019 +0200 @@ -16,8 +16,11 @@ import jsPDF from "jspdf-yworks"; import svg2pdf from "svg2pdf.js"; import locale2 from "locale2"; +import debounce from "debounce"; import { mapState } from "vuex"; import { HTTP } from "@/lib/http"; +import { displayError } from "@/lib/errors"; +import { defaultDiagramTemplate } from "@/lib/DefaultDiagramTemplate"; export const sortTable = { data() { @@ -37,25 +40,55 @@ }; export const diagram = { + data() { + return { + resizeListenerFunction: null + }; + }, methods: { - getDimensions({ svgWidth, svgHeight, main, nav }) { - const mainMargin = main || { + getDimensions({ svgWidth, svgHeight, main, nav, DPI }) { + const mainMargin = { top: 20, right: 80, bottom: 60, - left: 80 + left: 80, + ...main }; - const navMargin = nav || { + const navMargin = { top: svgHeight - mainMargin.top - 65, right: 20, bottom: 30, - left: 80 + left: 80, + ...nav }; + if (DPI) { + ["top", "right", "bottom", "left"].forEach(x => { + mainMargin[x] = this.millimeter2pixels(mainMargin[x], DPI); + navMargin[x] = this.millimeter2pixels(navMargin[x], DPI); + }); + } const width = Number(svgWidth) - mainMargin.left - mainMargin.right; const mainHeight = Number(svgHeight) - mainMargin.top - mainMargin.bottom; const navHeight = Number(svgHeight) - navMargin.top - navMargin.bottom; return { width, mainHeight, navHeight, mainMargin, navMargin }; } + }, + created() { + this.resizeListenerFunction = debounce(this.drawDiagram, 100); + window.addEventListener("resize", this.resizeListenerFunction); + }, + mounted() { + // Nasty but necessary if we don't want to use the updated hook to re-draw + // the diagram because this would re-draw it also for irrelevant reasons. + // In this case we need to wait for the child component (DiagramLegend) to + // render. According to the docs (https://vuejs.org/v2/api/#mounted) this + // should be possible with $nextTick() but it doesn't work because it does + // not guarantee that the DOM is not only updated but also re-painted on the + // screen. + setTimeout(this.drawDiagram, 150); + }, + destroyed() { + window.removeEventListener("resize", this.resizeListenerFunction); } }; @@ -129,6 +162,21 @@ }; export const pdfgen = { + data() { + return { + pdf: { + doc: null, + width: null, + height: null + }, + templates: [], + defaultTemplate: defaultDiagramTemplate, + templateData: null, + form: { + template: null + } + }; + }, computed: { ...mapState("application", ["logoForPDF"]), ...mapState("user", ["user"]) @@ -137,8 +185,9 @@ addDiagram(position, offset, width, height) { let x = offset.x, y = offset.y; - const svgWidth = this.millimeter2pixels(width, 80); - const svgHeight = this.millimeter2pixels(height, 80); + const DPI = this.templateData.properties.resoltion || 80; + const svgWidth = this.millimeter2pixels(width, DPI); + const svgHeight = this.millimeter2pixels(height, DPI); // draw the diagram in a separated html element to get the full size const offScreen = document.querySelector("#offScreen"); offScreen.style.width = `${svgWidth}px`; @@ -149,7 +198,8 @@ dimensions: this.getDimensions({ svgWidth: svgWidth, svgHeight: svgHeight, - ...layout + ...layout, + DPI: DPI }) }); var svg = offScreen.querySelector("svg"); @@ -162,7 +212,7 @@ svg2pdf(svg, this.pdf.doc, { xOffset: x, yOffset: y, - scale: 0.354 + scale: this.pixel2millimeter(1, DPI) }); offScreen.removeChild(svg); }, @@ -468,6 +518,58 @@ color, text ); + }, + applyChange() { + if (this.form.template.hasOwnProperty("properties")) { + this.templateData = this.defaultTemplate; + return; + } + if (this.form.template) { + this.loadTemplates("/templates/diagram/" + this.form.template.name) + .then(response => { + this.prepareImages(response.data.template_data.elements).then( + values => { + values.forEach(v => { + response.data.template_data.elements[v.index].url = v.url; + }); + this.templateData = response.data.template_data; + } + ); + }) + .catch(e => { + const { status, data } = e.response; + displayError({ + title: this.$gettext("Backend Error"), + message: `${status}: ${data.message || data}` + }); + }); + } } + }, + mounted() { + 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}` + }); + }); } };