changeset 3015:fe88a9b151ca

client: implemented pdf-generation for waterlevel diagram * implement the export of diagram to pdf * rewrite the diagram styles to include them in generate pdf
author Fadi Abbud <fadi.abbud@intevation.de>
date Thu, 11 Apr 2019 16:43:14 +0200
parents 5a3ac4d3dbbb
children 083cd270bdfd
files client/src/components/gauge/Waterlevel.vue
diffstat 1 files changed, 127 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/components/gauge/Waterlevel.vue	Thu Apr 11 16:34:58 2019 +0200
+++ b/client/src/components/gauge/Waterlevel.vue	Thu Apr 11 16:43:14 2019 +0200
@@ -14,8 +14,18 @@
         <span style="background-color: rgba(0, 255, 0, 0.1)"></span> Navigable
         Range
       </div>
+      <div>
+        <button
+          @click="downloadPDF"
+          type="button"
+          class="btn btn-sm btn-info d-block w-100 mt-2"
+        >
+          <translate>Export to PDF</translate>
+        </button>
+      </div>
     </DiagramLegend>
     <div
+      ref="diagramContainer"
       class="d-flex flex-fill justify-content-center align-items-center diagram-container"
     >
       <div v-if="!waterlevels.length">
@@ -90,7 +100,6 @@
       line
         stroke-dasharray: 5
         stroke: #ccc
-
     .zoom
       cursor: move
       fill: none
@@ -142,6 +151,8 @@
 import { lineChunked } from "d3-line-chunked";
 import { startOfDay, endOfDay } from "date-fns";
 import debounce from "debounce";
+import jsPDF from "jspdf";
+import canvg from "canvg";
 
 // we should load only d3 modules we need but for now we'll go with the lazy way
 // https://www.giacomodebidda.com/how-to-import-d3-plugins-with-webpack/
@@ -168,6 +179,25 @@
     ...mapGetters("gauges", ["selectedGauge"])
   },
   methods: {
+    downloadPDF() {
+      var svg = this.$refs.diagramContainer.innerHTML;
+      console.log(this.svg);
+      if (svg) {
+        svg = svg.replace(/\r?\n|\r/g, "").trim();
+      }
+      var pdf = new jsPDF("p", "pt", "c2");
+      var canvas = document.createElement("canvas");
+      canvas.width = window.innerWidth;
+      canvas.height = 500;
+      canvg(canvas, svg, {
+        ignoreMouse: true,
+        ignoreAnimation: true,
+        ignoreDimensions: true
+      });
+      var imgData = canvas.toDataURL("image/png");
+      pdf.addImage(imgData, "PNG", 50, 200);
+      pdf.save("waterlevel-Diagram.pdf");
+    },
     drawDiagram() {
       // remove old diagram and exit if necessary data is missing
       d3.select(".diagram-container svg").remove();
@@ -276,6 +306,102 @@
 
       this.createZoom(updaters, eventRect);
       this.createTooltips(eventRect);
+      this.setInlineStyles();
+    },
+    //set the styles of the diagrams to include them in the pdf
+    setInlineStyles() {
+      this.svg
+        .selectAll(".line")
+        .attr("clip-path", "url(#clip)")
+        .selectAll("path")
+        .attr("stroke", "steelblue")
+        .attr("stroke-width", 2)
+        .attr("fill", "none");
+      this.svg
+        .selectAll(".line")
+        .selectAll("path.d3-line-chunked-chunk-gap")
+        .attr("stroke-opacity", 0);
+      this.svg
+        .selectAll(".line")
+        .selectAll("circle")
+        .attr("stroke", "steelblue")
+        .attr("stroke-width", 2);
+      this.svg
+        .selectAll(".line")
+        .selectAll("circle.d3-line-chunked-chunk-predicted-point")
+        .attr("fill-opacity", 0.6);
+
+      this.svg
+        .selectAll(".hdc-line, .mw-line, .ldc-line")
+        .attr("stroke-width", 1)
+        .attr("fill", "none")
+        .attr("clip-path", "url(#clip)");
+      this.svg.selectAll(".hdc-line").attr("stroke", "red");
+      this.svg.selectAll(".ldc-line").attr("stroke", "green");
+      this.svg.selectAll(".mw-line").attr("stroke", "grey");
+      this.svg
+        .selectAll(".ref-waterlevel-label")
+        .attr("font-size", "11px")
+        .attr("fill", "#999");
+      this.svg.selectAll(".hdc-ldc-area").attr("fill", "rgba(0, 255, 0, 0.1)");
+      this.svg
+        .selectAll(".now-line")
+        .attr("stroke", "#999")
+        .attr("stroke-width", 1)
+        .attr("stroke-dasharray", "5, 5")
+        .attr("clip-path", "url(#clip)");
+      this.svg
+        .selectAll(".now-line-label")
+        .attr("font-size", "11px")
+        .attr("fill", "#999");
+      this.svg
+        .selectAll(".prediction-area")
+        .attr("fill", "steelblue")
+        .attr("fill-opacity", 0.2)
+        .attr("clip-path", "url(#clip)");
+
+      this.svg
+        .selectAll("path")
+        .selectAll(".nash-sutcliffe")
+        .attr("fill", "none")
+        .attr("stroke", "black")
+        .attr("stroke-width", 1)
+        .attr("clip-path", "url(#clip)");
+      this.svg
+        .selectAll("path")
+        .selectAll(".nash-sutcliffe")
+        .selectAll(".ns72")
+        .attr("fill", "rgba(0, 0, 0, 0.05)");
+      this.svg
+        .selectAll("text")
+        .selectAll(".nash-sutcliffe")
+        .attr("font-size", "10px")
+        .attr("clip-path", "url(#clip)")
+        .selectAll("tspan:last-child")
+        .attr("font-size", "9px")
+        .attr(" fill", "#777");
+
+      this.svg
+        .selectAll(".tick line")
+        .attr("stroke-dasharray", 5)
+        .attr("stroke", "#ccc");
+      this.svg.selectAll(".tick text").attr("fill", "black");
+      this.svg.selectAll(".domain").attr("stroke", "black");
+      this.svg
+        .selectAll(".zoom")
+        .attr("cursor", "move")
+        .attr("fill", "none")
+        .attr("pointer-events", "all");
+      this.svg
+        .selectAll(".brush")
+        .selectAll(".selection")
+        .attr("stroke", "none")
+        .attr("fill-opacity", 0.2);
+      this.svg
+        .selectAll(".brush")
+        .selectAll(".handle")
+        .attr("stroke", "rgba(23, 162, 184, 0.5)")
+        .attr("fill", "rgba(23, 162, 184, 0.5)");
     },
     getDimensions() {
       // dimensions and margins