changeset 368:a8a6e8a4ec70

Refactor the curve reshaping stuff to a utility function.
author Lucas Thompson <dev@lucas.im>
date Tue, 30 May 2017 22:15:42 +0100
parents f967cb22a37a
children b77cd48d86a9
files src/app/visualisations/FeatureUtilities.ts src/app/visualisations/curve/curve.component.ts
diffstat 2 files changed, 68 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/src/app/visualisations/FeatureUtilities.ts	Tue May 30 18:19:55 2017 +0100
+++ b/src/app/visualisations/FeatureUtilities.ts	Tue May 30 22:15:42 2017 +0100
@@ -168,3 +168,64 @@
   }
   throwShapeError();
 }
+
+export interface PlotData {
+  cx: number;
+  cy: number;
+}
+
+export interface PlotLayerData {
+  data: PlotData[];
+  yDomain: [number, number];
+  startTime: number;
+  duration: number;
+}
+
+export function generatePlotData(features: VectorFeature[]): PlotLayerData[] {
+
+  const winnowed = features.filter(feature => feature.data.length > 0);
+
+  // First establish a [min,max] range across all of the features
+  let [min, max] = winnowed.reduce((acc, feature) => {
+    return feature.data.reduce((acc, val) => {
+      const [min, max] = acc;
+      return [Math.min(min, val), Math.max(max, val)];
+    }, acc);
+  }, [Infinity, -Infinity]);
+
+  if (min === Infinity) {
+    min = 0;
+    max = 1;
+  }
+
+  if (min !== min || max !== max) {
+    console.warn('WARNING: min or max is NaN');
+    min = 0;
+    max = 1;
+  }
+
+  return winnowed.map(feature => {
+    let duration = 0;
+
+    // Give the plot items positions relative to the start of the
+    // line, rather than relative to absolute time 0. This is
+    // because we'll be setting the layer timeline start property
+    // later on and these will be positioned relative to that
+
+    const plotData = [...feature.data].map((val, i) => {
+      const t = i * feature.stepDuration;
+      duration = t + feature.stepDuration;
+      return {
+        cx: t,
+        cy: val
+      };
+    });
+
+    return {
+      data: plotData,
+      yDomain: [min, max] as [number, number],
+      startTime: feature.startTime,
+      duration: duration
+    };
+  });
+}
--- a/src/app/visualisations/curve/curve.component.ts	Tue May 30 18:19:55 2017 +0100
+++ b/src/app/visualisations/curve/curve.component.ts	Tue May 30 22:15:42 2017 +0100
@@ -12,20 +12,7 @@
 } from "@angular/core";
 import {VectorFeature} from "piper/HigherLevelUtilities";
 import Waves from 'waves-ui-piper';
-
-interface PlotData {
-  cx: number;
-  cy: number;
-}
-
-interface PlotLayerData {
-  data: PlotData[];
-  color: string;
-  height: number;
-  yDomain: [number, number];
-  startTime: number;
-  duration: number;
-}
+import {generatePlotData, PlotLayerData} from "../FeatureUtilities";
 
 @Component({
   selector: 'ugly-curve',
@@ -39,18 +26,21 @@
 
   private mFeature: VectorFeature;
   private currentState: PlotLayerData[];
+  private height: number; // As it stands, height is fixed. Store once onInit.
 
   @Input() set feature(input: VectorFeature) {
     this.mFeature = input;
-    this.currentState = this.generatePlotData([input], '', 'black');
+    this.currentState = generatePlotData([input]);
     this.update();
   }
+  @Input() colour: string;
 
   get feature(): VectorFeature {
     return this.mFeature;
   }
 
   ngAfterViewInit(): void {
+    this.height = this.trackDiv.nativeElement.getBoundingClientRect().height;
     this.renderTimeline(this.trackDiv);
     this.update();
   }
@@ -60,8 +50,8 @@
       this.clearTimeline(this.trackDiv);
       for (const feature of this.currentState) {
         const lineLayer = new Waves.helpers.LineLayer(feature.data, {
-          color: feature.color,
-          height: feature.height,
+          color: this.colour,
+          height: this.height,
           yDomain: feature.yDomain
         });
         this.addLayer(
@@ -77,59 +67,4 @@
       }
     }
   }
-
-  private generatePlotData(features: VectorFeature[],
-                           unit: string,
-                           colour: string): PlotLayerData[] {
-
-    // Winnow out empty features
-    features = features.filter(feature => (feature.data.length > 0));
-
-    // First establish a [min,max] range across all of the features
-    let [min, max] = features.reduce((acc, feature) => {
-      return feature.data.reduce((acc, val) => {
-        const [min, max] = acc;
-        return [Math.min(min, val), Math.max(max, val)];
-      }, acc);
-    }, [Infinity, -Infinity]);
-
-    if (min === Infinity) {
-      min = 0;
-      max = 1;
-    }
-
-    if (min !== min || max !== max) {
-      console.log('WARNING: min or max is NaN');
-      min = 0;
-      max = 1;
-    }
-
-    const height = this.trackDiv.nativeElement.getBoundingClientRect().height;
-    return features.map(feature => {
-      let duration = 0;
-
-      // Give the plot items positions relative to the start of the
-      // line, rather than relative to absolute time 0. This is
-      // because we'll be setting the layer timeline start property
-      // later on and these will be positioned relative to that
-
-      const plotData = [...feature.data].map((val, i) => {
-        const t = i * feature.stepDuration;
-        duration = t + feature.stepDuration;
-        return {
-          cx: t,
-          cy: val
-        };
-      });
-
-      return {
-        data: plotData,
-        color: colour,
-        height: height,
-        yDomain: [min, max] as [number, number],
-        startTime: feature.startTime,
-        duration: duration
-      };
-    });
-  }
 }