diff client/src/components/gauge/Waterlevel.vue @ 2684:c4da269238a4

client: waterlevel diagram: visualize data gaps
author Markus Kottlaender <markus@intevation.de>
date Fri, 15 Mar 2019 12:43:30 +0100
parents 7fd47d9641ac
children 8f919fe629f9
line wrap: on
line diff
--- a/client/src/components/gauge/Waterlevel.vue	Fri Mar 15 12:10:47 2019 +0100
+++ b/client/src/components/gauge/Waterlevel.vue	Fri Mar 15 12:43:30 2019 +0100
@@ -5,11 +5,15 @@
 <style lang="sass" scoped>
 .diagram-container
   /deep/
-    .line
-      stroke: steelblue
-      stroke-width: 2
-      fill: transparent
-      clip-path: url(#clip)
+    .main
+      .line
+        clip-path: url(#clip)
+    .nav
+      .line
+        stroke: steelblue
+        stroke-width: 2
+        fill: transparent
+        clip-path: url(#clip)
 
     .hdc-line,
     .ldc-line,
@@ -63,9 +67,14 @@
  */
 
 import { mapState, mapGetters } from "vuex";
-import * as d3 from "d3";
+import * as d3Base from "d3";
+import { lineChunked } from "d3-line-chunked";
 import debounce from "debounce";
 
+// 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/
+const d3 = Object.assign(d3Base, { lineChunked });
+
 export default {
   computed: {
     ...mapState("gauges", ["waterlevels"]),
@@ -145,11 +154,23 @@
       // PREPARING CHART FUNCTIONS
 
       // waterlevel line in big chart
-      let mainLineChart = d3
-        .line()
-        .curve(d3.curveMonotoneX)
+      // d3-line-chunked plugin: https://github.com/pbeshai/d3-line-chunked
+      var mainLineChart = d3
+        .lineChunked()
         .x(d => x(d.date))
-        .y(d => y(d.waterlevel));
+        .y(d => y(d.waterlevel))
+        .curve(d3.curveLinear)
+        .isNext((prev, current) => {
+          // points are "next to each other" when they are exactly 15 minutes apart
+          return current.date - prev.date === 15 * 60 * 1000;
+        })
+        .lineStyles({ stroke: "steelblue" })
+        .gapStyles({
+          stroke: "steelblue",
+          "stroke-opacity": 1,
+          "stroke-dasharray": "3 3",
+          "stroke-width": 1
+        });
       // waterlevel line in small chart
       let navLineChart = d3
         .line()
@@ -176,6 +197,7 @@
 
       let mainChart = svg
         .append("g")
+        .attr("class", "main")
         .attr("transform", `translate(${mainMargin.left}, ${mainMargin.top})`);
 
       // axes
@@ -256,15 +278,18 @@
 
       // waterlevel chart
       mainChart
-        .append("path")
+        .append("g")
+        .attr("class", "line")
         .datum(this.waterlevels)
-        .attr("class", "line")
-        .attr("d", mainLineChart);
+        .transition()
+        .duration(1000)
+        .call(mainLineChart);
 
       // DRAWING NAVCHART
 
       let navChart = svg
         .append("g")
+        .attr("class", "nav")
         .attr("transform", `translate(${navMargin.left}, ${navMargin.top})`);
 
       // axis (nav chart only has y-axis)
@@ -293,7 +318,7 @@
             return; // ignore brush-by-zoom
           let s = d3.event.selection || x2.range();
           x.domain(s.map(x2.invert, x2));
-          mainChart.select(".line").attr("d", mainLineChart);
+          mainChart.select(".line").call(mainLineChart);
           mainChart
             .select(".axis--x")
             .call(xAxis)
@@ -318,7 +343,7 @@
             return; // ignore zoom-by-brush
           let t = d3.event.transform;
           x.domain(t.rescaleX(x2).domain());
-          mainChart.select(".line").attr("d", mainLineChart);
+          mainChart.select(".line").call(mainLineChart);
           mainChart
             .select(".axis--x")
             .call(xAxis)