changeset 3911:e4e496ae7974

fairway_availability: rendering to offscreen element
author Thomas Junk <thomas.junk@intevation.de>
date Thu, 11 Jul 2019 10:58:22 +0200
parents 29b294e77a5c
children b7dfee369f2f
files client/src/components/fairway/AvailableFairwayDepth.vue
diffstat 1 files changed, 47 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/components/fairway/AvailableFairwayDepth.vue	Thu Jul 11 10:39:06 2019 +0200
+++ b/client/src/components/fairway/AvailableFairwayDepth.vue	Thu Jul 11 10:58:22 2019 +0200
@@ -76,7 +76,7 @@
 import { mapState } from "vuex";
 import filters from "@/lib/filters.js";
 import svg2pdf from "svg2pdf.js";
-import { diagram, pdfgen, templateLoader } from "@/lib/mixins";
+import { pdfgen, templateLoader } from "@/lib/mixins";
 import { HTTP } from "@/lib/http";
 import { displayError } from "@/lib/errors";
 import { FREQUENCIES } from "@/store/fairwayavailability";
@@ -84,7 +84,7 @@
 const hoursInDays = x => x / 24;
 
 export default {
-  mixins: [diagram, pdfgen, templateLoader],
+  mixins: [pdfgen, templateLoader],
   components: {
     DiagramLegend: () => import("@/components/DiagramLegend")
   },
@@ -243,6 +243,19 @@
     }
   },
   methods: {
+    getDimensions({ svgHeight, svgWidth }) {
+      const mainMargin = { top: 0, right: 20, bottom: 75, left: 200 };
+      const navMargin = {
+        top: svgHeight - mainMargin.top - 65,
+        right: 20,
+        bottom: 30,
+        left: 80
+      };
+      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 };
+    },
     applyChange() {
       if (this.form.template.hasOwnProperty("properties")) {
         this.templateData = this.defaultTemplate;
@@ -280,27 +293,32 @@
     addDiagram(position, offset, width, height) {
       let x = offset.x,
         y = offset.y;
-      var svgElement = this.$refs.diagramContainer.firstElementChild;
-
-      // use default width,height if they are missing in the template definition
-      if (!width) {
-        width = this.templateData.properties.paperSize === "a3" ? 380 : 290;
-      }
-      if (!height) {
-        height = this.templateData.properties.paperSize === "a3" ? 130 : 100;
-      }
+      const svgWidth = this.millimeter2pixels(width, 80);
+      const svgHeight = this.millimeter2pixels(height, 80);
+      // draw the diagram in a separated html element to get the full size
+      const offScreen = document.querySelector("#offScreen");
+      offScreen.style.width = `${svgWidth}px`;
+      offScreen.style.height = `${svgHeight}px`;
+      this.renderTo({
+        element: offScreen,
+        dimensions: this.getDimensions({
+          svgWidth: svgWidth,
+          svgHeight: svgHeight
+        })
+      });
+      var svg = offScreen.querySelector("svg");
       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;
       }
-
-      svg2pdf(svgElement, this.pdf.doc, {
+      svg2pdf(svg, this.pdf.doc, {
         xOffset: x,
         yOffset: y,
-        scale: this.templateData.properties.paperSize === "a3" ? 0.45 : 0.18 // TODO depend on the size and aspect ration on paper
+        scale: 0.354
       });
+      offScreen.removeChild(svg);
     },
     addDiagramLegend(position, offset, color) {
       let x = offset.x,
@@ -350,28 +368,32 @@
       this.$store.commit("application/paneSetup", "DEFAULT");
     },
     drawDiagram() {
+      const elem = document.querySelector("#" + this.containerId);
+      const svgWidth = elem != null ? elem.clientWidth : 0;
+      const svgHeight = elem != null ? elem.clientHeight : 0;
       const dimensions = this.getDimensions({
-        main: { top: 0, right: 20, bottom: 75, left: 200 }
+        svgHeight,
+        svgWidth
       });
+      d3.select(".diagram-container svg").remove();
+      this.renderTo({ element: ".diagram-container", dimensions });
+    },
+    renderTo({ element, dimensions }) {
+      const diagram = d3
+        .select(element)
+        .append("svg")
+        .attr("width", "100%")
+        .attr("height", "100%");
+      diagram.append("g");
       const yScale = d3
         .scaleLinear()
         .domain(this.frequencyToRange)
         .range([dimensions.mainHeight - 30, 0]);
-      d3.select(".diagram-container svg").remove();
-      const diagram = this.generateDiagramContainer();
       this.drawScaleLabel({ diagram, dimensions });
       this.drawScale({ diagram, dimensions, yScale });
       this.drawBars({ diagram, yScale, dimensions });
       this.drawTooltip(diagram);
     },
-    generateDiagramContainer() {
-      const diagram = d3
-        .select(".diagram-container")
-        .append("svg")
-        .attr("width", "100%")
-        .attr("height", "100%");
-      return diagram.append("g");
-    },
     drawTooltip(diagram) {
       diagram
         .append("text")