Mercurial > gemma
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;