changeset 3252:fccb28813159

client: wterlevel diagram: improved performance By not rendering points that are outside of the visible area of the chart, performance was significantly improved. But still the chart is not really very responsive and smooth when viewing large data sets.
author Markus Kottlaender <markus@intevation.de>
date Tue, 14 May 2019 12:24:14 +0200
parents b3333311de42
children 3a7b6eb162db
files client/src/components/gauge/Waterlevel.vue
diffstat 1 files changed, 26 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/components/gauge/Waterlevel.vue	Tue May 14 12:10:45 2019 +0200
+++ b/client/src/components/gauge/Waterlevel.vue	Tue May 14 12:24:14 2019 +0200
@@ -762,11 +762,21 @@
       const waterlevelChartDrawer = isNav => {
         return d3
           .lineChunked()
+          .defined(
+            // render only data points that are visible in the current scale
+            d => {
+              let domainLeft = new Date(this.scale.x.domain()[0].getTime());
+              domainLeft.setDate(domainLeft.getDate() - 1);
+              let domainRight = new Date(this.scale.x.domain()[1].getTime());
+              domainRight.setDate(domainRight.getDate() + 1);
+              return d.date > domainLeft && d.date < domainRight;
+            }
+          )
           .x(d => this.scale[isNav ? "x2" : "x"](d.date))
           .y(d => this.scale[isNav ? "y2" : "y"](d.waterlevel))
           .curve(d3.curveLinear)
-          .isNext(this.isNext(900))
-          .pointAttrs({ r: isNav ? 1.7 : 2.2 })
+          .isNext(this.isNext())
+          .pointAttrs({ r: 1.7 })
           .chunk(d => (d.predicted ? "predicted" : "line"))
           .chunkDefinitions({ predicted: {} });
       };
@@ -1159,10 +1169,20 @@
             .attr("height", textBBox.height + tooltipPadding * 2);
         });
     },
-    isNext(seconds) {
-      // helper to check whether points in the chart are "next to each other"
-      // for that they need to be exactly the specified amount of seconds apart.
-      return (prev, current) => current.date - prev.date === seconds * 1000;
+    isNext() {
+      // Check whether points in the chart can be considered "next to each other".
+      // For that they need to be exactly 15 minutes apart (for automatically
+      // imported gauge measurements). If the chart shows more than 15 days then
+      // 1 hour is also valid (for approved gauge measurements).
+      return (prev, current) => {
+        let difference = (current.date - prev.date) / 1000;
+        if (
+          (this.scale.x.domain()[1] - this.scale.x.domain()[0]) / 86400000 >
+          15
+        )
+          return [900, 3600].includes(difference);
+        return difference === 900;
+      };
     }
   },
   created() {