changeset 4792:9412bc2545e8

client: implement exporting of diagram as image (waterlevel)
author Fadi Abbud <fadi.abbud@intevation.de>
date Fri, 25 Oct 2019 13:46:05 +0200
parents 1fef4679b07a
children d6d73ca5496a
files client/src/components/gauge/Waterlevel.vue client/src/lib/mixins.js
diffstat 2 files changed, 41 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/components/gauge/Waterlevel.vue	Fri Oct 25 13:03:50 2019 +0200
+++ b/client/src/components/gauge/Waterlevel.vue	Fri Oct 25 13:46:05 2019 +0200
@@ -64,7 +64,17 @@
           >
             <translate>Export as CSV</translate>
           </a>
-
+          <a
+            @click="downloadImage"
+            id="downloadimage"
+            :class="[
+              'btn btn-sm btn-info d-block w-100 mt-2',
+              { disabled: !waterlevels.length }
+            ]"
+            :download="imageFilename"
+          >
+            <translate>Export as Image</translate>
+          </a>
           <!--
           <button
             @click="downloadSVG"
@@ -128,6 +138,7 @@
 import { displayError } from "@/lib/errors";
 import { defaultDiagramTemplate } from "@/lib/DefaultDiagramTemplate";
 import { localeDateString } from "@/lib/datelocalization";
+
 // 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/
 // d3-line-chunked plugin: https://github.com/pbeshai/d3-line-chunked
@@ -183,6 +194,14 @@
         "data:text/csv;charset=utf-8," + encodeURIComponent(this.waterlevelsCSV)
       );
     },
+    imageFilename() {
+      return (
+        this.downloadFilename(
+          this.$gettext("Waterlevel"),
+          this.selectedGauge.properties.objname
+        ) + ".png"
+      );
+    },
     csvFileName() {
       if (!this.dateFromD || !this.dateToD) return "";
       return (
@@ -222,6 +241,7 @@
           : "DEFAULT"
       );
     },
+
     downloadSVG() {
       let svg = document.getElementById(this.containerId).firstElementChild;
       let svgXML = new XMLSerializer().serializeToString(svg);
@@ -400,6 +420,14 @@
         .append("svg")
         .attr("width", "100%")
         .attr("height", "100%");
+      // add white background in the size of the svg
+      // to solve alpha-channel problem when using canvg to export image
+      svg
+        .append("g")
+        .append("rect")
+        .attr("width", "100%")
+        .attr("height", "100%")
+        .attr("fill", "#ffffff");
 
       // create container for main diagram
       const diagram = svg
--- a/client/src/lib/mixins.js	Fri Oct 25 13:03:50 2019 +0200
+++ b/client/src/lib/mixins.js	Fri Oct 25 13:46:05 2019 +0200
@@ -20,6 +20,7 @@
 import { HTTP } from "@/lib/http";
 import * as d3 from "d3";
 import sanitize from "sanitize-filename";
+import canvg from "canvg";
 
 /*eslint no-unused-vars: ["error", { "varsIgnorePattern": "[debugSVG|_]" }]*/
 const debugSVG = ({ svg, svgWidth, svgHeight }) => {
@@ -167,6 +168,17 @@
     ...mapState("user", ["user"])
   },
   methods: {
+    downloadImage() {
+      const diagramContainer = document.getElementById(this.containerId);
+      const { clientHeight, clientWidth } = diagramContainer;
+      diagramContainer.firstElementChild.setAttribute("width", clientWidth);
+      diagramContainer.firstElementChild.setAttribute("height", clientHeight);
+      const svg = diagramContainer.firstElementChild.outerHTML;
+      const canvas = document.createElement("canvas");
+      canvg(canvas, svg);
+      const imgData = canvas.toDataURL("image/png");
+      document.getElementById("downloadimage").setAttribute("href", imgData);
+    },
     addDiagram(position, offset, width, height) {
       let x = offset.x,
         y = offset.y;