changeset 366:f122bb02c428

Core logic copied over from old waveform.component.ts for drawing curve. Needs refactoring as some logic is used for tracks. No highlight or vertical scale yet.
author Lucas Thompson <dev@lucas.im>
date Tue, 30 May 2017 18:14:05 +0100
parents 9ba7d304a99d
children f967cb22a37a
files src/app/visualisations/curve/curve.component.ts
diffstat 1 files changed, 122 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/app/visualisations/curve/curve.component.ts	Tue May 30 18:13:12 2017 +0100
+++ b/src/app/visualisations/curve/curve.component.ts	Tue May 30 18:14:05 2017 +0100
@@ -2,15 +2,133 @@
  * Created by lucas on 30/05/2017.
  */
 import {WavesComponent} from "../waves-base.component";
-import {ChangeDetectionStrategy, Component} from "@angular/core";
+import {
+  AfterViewInit,
+  ChangeDetectionStrategy,
+  Component,
+  ElementRef,
+  Input,
+  ViewChild
+} 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;
+}
 
 @Component({
   selector: 'ugly-curve',
-  // templateUrl: '../waves-template.html',
-  template: `<div #track class="track"><span>Curve</span></div>`,
+  templateUrl: '../waves-template.html',
   styleUrls: ['../waves-template.css'],
   changeDetection: ChangeDetectionStrategy.OnPush
 })
-export class CurveComponent extends WavesComponent {
+export class CurveComponent extends WavesComponent implements AfterViewInit {
 
+  @ViewChild('track') trackDiv: ElementRef;
+
+  private mFeature: VectorFeature;
+  private currentState: PlotLayerData[];
+
+  @Input() set feature(input: VectorFeature) {
+    this.mFeature = input;
+    this.currentState = this.generatePlotData([input], '', 'black');
+    this.update();
+  }
+
+  get feature(): VectorFeature {
+    return this.mFeature;
+  }
+
+  ngAfterViewInit(): void {
+    this.renderTimeline(this.trackDiv);
+    this.update();
+  }
+
+  update(): void {
+    if (this.waveTrack) {
+      for (const feature of this.currentState) {
+        const lineLayer = new Waves.helpers.LineLayer(feature.data, {
+          color: feature.color,
+          height: feature.height,
+          yDomain: feature.yDomain
+        });
+        this.addLayer(
+          lineLayer,
+          this.waveTrack,
+          this.timeline.timeContext
+        );
+
+        // Set start and duration so that the highlight layer can use
+        // them to determine which line to draw values from
+        lineLayer.start = feature.startTime;
+        lineLayer.duration = feature.duration;
+      }
+    }
+  }
+
+  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
+      };
+    });
+  }
 }