diff client/src/components/fairway/AvailableFairwayDepth.vue @ 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 7b3935a8d9ee
children afc7bca44df4
line wrap: on
line diff
--- a/client/src/components/fairway/AvailableFairwayDepth.vue	Fri Jul 12 11:58:20 2019 +0200
+++ b/client/src/components/fairway/AvailableFairwayDepth.vue	Fri Jul 12 15:14:16 2019 +0200
@@ -1,7 +1,6 @@
 <template>
   <div class="d-flex flex-column flex-fill">
     <UIBoxHeader icon="chart-area" :title="title" :closeCallback="close" />
-    <UISpinnerOverlay v-if="loading" />
     <div class="d-flex flex-fill">
       <DiagramLegend>
         <div v-for="(entry, index) in legend" :key="index" class="legend">
@@ -44,16 +43,17 @@
         </div>
       </DiagramLegend>
       <div
-        ref="diagramContainer"
+        class="d-flex flex-fill justify-content-center align-items-center"
         :id="containerId"
-        class="diagram-container flex-fill"
-      ></div>
+      >
+        <div v-if="!fwData.length">
+          <translate>No data available.</translate>
+        </div>
+      </div>
     </div>
   </div>
 </template>
 
-<style></style>
-
 <script>
 /* This is Free Software under GNU Affero General Public License v >= 3.0
  * without warranty, see README.md and license for details.
@@ -71,17 +71,19 @@
  * * Fadi Abbud <fadi.abbud@intevation.de>
  */
 import * as d3 from "d3";
-import app from "@/main";
-import debounce from "debounce";
 import { mapState } from "vuex";
-import filters from "@/lib/filters.js";
 import { diagram, pdfgen, templateLoader } from "@/lib/mixins";
-import { HTTP } from "@/lib/http";
-import { displayError } from "@/lib/errors";
 import { FREQUENCIES } from "@/store/fairwayavailability";
-import { defaultDiagramTemplate } from "@/lib/DefaultDiagramTemplate";
+import filters from "@/lib/filters.js";
 
+// hoursInDays is a const instead of component method because it's used where
+// the component context is not available
 const hoursInDays = x => x / 24;
+const COLORS = {
+  LDC: "#cdcdcd",
+  HIGHEST: "#3675ff",
+  REST: ["#782121", "#ff6c6c", "#ffaaaa"]
+};
 
 export default {
   mixins: [diagram, pdfgen, templateLoader],
@@ -91,66 +93,11 @@
   data() {
     return {
       containerId: "availablefairwaydepth-diagram-container",
-      resizeListenerFunction: null,
-      loading: false,
       scalePaddingLeft: 60,
       scalePaddingRight: 0,
-      paddingTop: 25,
-      pdf: {
-        doc: null,
-        width: null,
-        height: null
-      },
-      form: {
-        template: null
-      },
-      templateData: null,
-      templates: [],
-      defaultTemplate: defaultDiagramTemplate
+      paddingTop: 25
     };
   },
-  created() {
-    this.resizeListenerFunction = debounce(this.drawDiagram, 100);
-    window.addEventListener("resize", this.resizeListenerFunction);
-  },
-  destroyed() {
-    window.removeEventListener("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);
-
-    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}`
-        });
-      });
-  },
   computed: {
     ...mapState("fairwayavailability", [
       "selectedFairwayAvailabilityFeature",
@@ -216,32 +163,6 @@
     }
   },
   methods: {
-    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}`
-            });
-          });
-      }
-    },
     downloadPDF() {
       let title = `Available Fairway Depth: ${this.featureName}`;
       this.generatePDF({
@@ -266,60 +187,54 @@
       }
 
       this.pdf.doc.setTextColor(color);
-      this.pdf.doc.setDrawColor(this.$options.COLORS.LDC);
-      this.pdf.doc.setFillColor(this.$options.COLORS.LDC);
+      this.pdf.doc.setDrawColor(COLORS.LDC);
+      this.pdf.doc.setFillColor(COLORS.LDC);
       this.pdf.doc.roundedRect(x, y, 10, 4, 1.5, 1.5, "FD");
       this.pdf.doc.text(this.legend[0], x + 12, y + 3);
 
-      this.pdf.doc.setDrawColor(this.$options.COLORS.REST[0]);
-      this.pdf.doc.setFillColor(this.$options.COLORS.REST[0]);
+      this.pdf.doc.setDrawColor(COLORS.REST[0]);
+      this.pdf.doc.setFillColor(COLORS.REST[0]);
       this.pdf.doc.roundedRect(x, y + 5, 10, 4, 1.5, 1.5, "FD");
       this.pdf.doc.text(this.legend[1], x + 12, y + 8);
 
-      this.pdf.doc.setDrawColor(this.$options.COLORS.REST[1]);
-      this.pdf.doc.setFillColor(this.$options.COLORS.REST[1]);
+      this.pdf.doc.setDrawColor(COLORS.REST[1]);
+      this.pdf.doc.setFillColor(COLORS.REST[1]);
       this.pdf.doc.roundedRect(x, y + 10, 10, 4, 1.5, 1.5, "FD");
       this.pdf.doc.text(this.legend[2], x + 12, y + 13);
 
-      this.pdf.doc.setDrawColor(this.$options.COLORS.HIGHEST);
-      this.pdf.doc.setFillColor(this.$options.COLORS.HIGHEST);
+      this.pdf.doc.setDrawColor(COLORS.HIGHEST);
+      this.pdf.doc.setFillColor(COLORS.HIGHEST);
       this.pdf.doc.roundedRect(x, y + 15, 10, 4, 1.5, 1.5, "FD");
       this.pdf.doc.text(this.legend[3], x + 12, y + 18);
     },
     legendStyle(index) {
       return [
-        `background-color: ${this.$options.COLORS.LDC};`,
-        `background-color: ${this.$options.COLORS.HIGHEST};`,
-        `background-color: ${this.$options.COLORS.REST[1]};`,
-        `background-color: ${this.$options.COLORS.REST[0]};`
+        `background-color: ${COLORS.LDC};`,
+        `background-color: ${COLORS.HIGHEST};`,
+        `background-color: ${COLORS.REST[1]};`,
+        `background-color: ${COLORS.REST[0]};`
       ][index];
     },
     close() {
       this.$store.commit("application/paneSetup", "DEFAULT");
     },
-    getPrintLayout(svgHeight) {
+    getPrintLayout() {
       return {
-        main: { top: 0, right: 20, bottom: 50, left: 20 },
-        nav: {
-          top: svgHeight - 65,
-          right: 20,
-          bottom: 30,
-          left: 80
-        }
+        main: { top: 0, right: 20, bottom: 50, left: 20 }
       };
     },
     drawDiagram() {
       const elem = document.querySelector("#" + this.containerId);
       const svgWidth = elem != null ? elem.clientWidth : 0;
       const svgHeight = elem != null ? elem.clientHeight : 0;
-      const layout = this.getPrintLayout(svgHeight);
+      const layout = this.getPrintLayout();
       const dimensions = this.getDimensions({
         svgHeight,
         svgWidth,
         ...layout
       });
-      d3.select(".diagram-container svg").remove();
-      this.renderTo({ element: ".diagram-container", dimensions });
+      d3.select("#" + this.containerId + " svg").remove();
+      this.renderTo({ element: "#" + this.containerId, dimensions });
     },
     renderTo({ element, dimensions }) {
       const diagram = d3
@@ -440,7 +355,7 @@
         .attr("x", ldcOffset + spaceBetween / 2)
         .attr("width", widthPerItem - ldcOffset - spaceBetween)
         .attr("fill", (d, i) => {
-          return this.$options.COLORS.REST[i];
+          return COLORS.REST[i];
         });
     },
     fnheight({ name, yScale }) {
@@ -479,7 +394,7 @@
           "transform",
           d => `translate(0 ${this.paddingTop + -1 * height(d)})`
         )
-        .attr("fill", this.$options.COLORS.LDC)
+        .attr("fill", COLORS.LDC)
         .attr("id", "ldc");
     },
     drawHighestLevel({
@@ -523,7 +438,7 @@
           "transform",
           d => `translate(0 ${this.paddingTop + -1 * height(d)})`
         )
-        .attr("fill", this.$options.COLORS.HIGHEST);
+        .attr("fill", COLORS.HIGHEST);
     },
     drawLabelPerBar({ everyBar, dimensions, widthPerItem }) {
       everyBar
@@ -537,7 +452,7 @@
     drawScaleLabel({ diagram, dimensions }) {
       diagram
         .append("text")
-        .text(this.$options.LEGEND)
+        .text(this.$gettext("Sum of days"))
         .attr("text-anchor", "middle")
         .attr("x", 0)
         .attr("y", 0)
@@ -615,12 +530,6 @@
     fwData() {
       this.drawDiagram();
     }
-  },
-  LEGEND: app.$gettext("Sum of days"),
-  COLORS: {
-    LDC: "#cdcdcd",
-    HIGHEST: "#3675ff",
-    REST: ["#782121", "#ff6c6c", "#ffaaaa"]
   }
 };
 </script>