overview-window.component.ts 14.7 KB
Newer Older
1
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
2
import { StateService } from '../state.service';
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
3
import zingchart from 'zingchart/es6';
4
import * as d3 from 'd3';
5
6
7
8
9
10

@Component({
  selector: 'app-overview-window',
  templateUrl: './overview-window.component.html',
  styleUrls: ['./overview-window.component.css']
})
11
export class OverviewWindowComponent implements OnInit {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
12
  @ViewChild('chart') chart;
13
  private initialHeight;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
14
  public config;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
15
  public graphset = [];
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
16
  public id = 'overview';
17
18
19
20
  public markers = [];
  public series = [];
  public goodLabels = [];
  public badLabels = [];
21
  public candidateLabels = [];
22
  public pathWidth = 100;
23
  public allChannels: number[];
24
25
  private _minx;
  private _maxx;
26
  public currentSelection;
27
28
29
30

  public data;
  public layout;

31
  constructor(private state: StateService, private el: ElementRef) {
32
    this.currentSelection = this.state.selection;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
33
  }
34
35

  async ngOnInit(): Promise<void> {
36
37
38
39
    this.initialHeight = this.el.nativeElement.offsetHeight;
    // this.state.onNewData.subscribe(() => this.dostuff3());
    this.state.onNewData.subscribe(() => this.initializePlot());
    this.state.onNewLshData.subscribe(() => this.updatePlot());
40
41
42
43
    this.state.onNewSelection.subscribe(() => {
      this.currentSelection = this.state.selection;
      this.updateChannels();
    });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
44
    this.state.onNewSlider.subscribe(() => this.updateCandidates());
45
46
  }

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
  dostuff3() {
    let y_val = 0;
    let N = 200000;
    let values = d3.range(N).map(function(x, i, arr) {
      y_val += Math.random() - 0.5;
      return {x: x, y: y_val, id: i};
    });
    let margin = {top: 30, right: 30, bottom: 30, left: 20 };
    let width = 600 - margin.left - margin.right;
    let height = 150 - margin.top - margin.bottom;

    const svg = d3.select('.test')
      .append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform",
        "translate(" + margin.left + "," + margin.top + ")");

    let xscale = d3.scaleLinear().domain([0, N]).range([0, N]);
    const x2 = xscale.copy(); // reference.
    const yscale = d3.scaleLinear().domain([-10, 10]).range([height, 0]);
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    const line = d3.line()
      .x(function(d:any) { return xscale(d.x); })
      .y(function(d:any) { return yscale(d.y); })

    const axis = d3.axisBottom(xscale);

    const axis_G = svg.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(axis);

    const axis_left = svg.append("g")
      .call(d3.axisLeft(yscale));

    const lines = svg.append('g')
      .data([values])
      .append('path')
      .attr("fill", "none")
      .attr("stroke", "steelblue")
      .attr("stroke-width", 1.5)
      .attr('class', 'data')
      .attr('d', (d: any) => line(d));

    const zoomed = function() {
      const transform = d3.event.transform;
      // lines.attr("transform", d3.event.transform);
      xscale = transform.rescaleX(x2);
      axis.scale(xscale);
      axis_G.call(axis);
      svg.select('.data').attr('d', (d: any) => {
        return d3.line()
          .x(function(d:any) { return transform.applyX(xscale(d.x)); })
          .y(function(d:any) { return yscale(d.y); })(d);
      });
103
104
    };

105
106
107
    const zoom = d3.zoom()
      .scaleExtent([1, 10000])
      .on('zoom', zoomed);
108
109
110
111




112
113
    svg.call(zoom);
  }
114

115
116
117
118
119
120
121
122
123
124
125
126
  async initializePlot() {
    this.allChannels = [...Array(this.state.rawData.length).keys()];
    this.state.queryWindow = undefined;
    // this.debugClicked();
    this.graphset.push({
      id: 'preview',
      type: "scatter",
      x: 0,
      y: 0,
      scaleX: {
        zooming: true,
        minValue: 0,
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
127
        maxValue: this.state.rawData[0].values.length,
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
        'auto-fit': true,
        visible: false,
        guide: {
          visible: false
        }
      },
      height: '30px',
      scaleY: {
        maxValue: 1,
        minValue: -1,
        visible: false,
        guide: {
          visible: false
        }
      },
      preview: {
        x: 50,
        y: 10,
        height: '30px',
      },
      series: [
        {
          type: 'scatter',
          values: [],
          text: 'Good labels',
          marker: {
            backgroundColor: '#4caf50'
          },
          zIndex: 3,
        },
        {
          type: 'scatter',
          values: [],
          text: 'Bad labels',
          marker: {
            backgroundColor: '#f44336'
          },
          zIndex: 2,
        },
        {
          type: 'scatter',
          values: [],
          text: 'Candidates',
          marker: {
            backgroundColor: '#b1a343'
          },
          zIndex: 1,
        }
      ]
    });
    // Initialize channels
179

180
181
182
183
    this.state.selection.forEach((channelIndex, index) => {
      const channel = this.state.rawData[channelIndex];
      const data = [];
      for (let i = 0; i < channel.values.length; i++) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
184
        data.push([i, channel.values[i]]);
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
      }
      this.graphset.push({
        id: index,
        x: 0,
        y: `${75 * index + 50}px`,
        type: 'line',
        height: '50px',
        scaleX: {
          zooming: true,
          markers: []
        },
        'scale-y': {
          zooming: false,
          'auto-fit': true
        },
        plotarea: {
          height: '50px',
          'margin-top': '0px',
          'margin-bot': '0px'
        },
        series: [{
          type: 'line',
          values: data,
          text: 'Raw Values',
          zIndex: 5,
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
210
          'line-color': this.state.colors[channelIndex],
211
212
213
214
215
216
          marker: {
            alpha: 0.0,
            zIndex: 10
          }
        }]
      });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
217
    });
218
    zingchart.bind('zingchart-ng-1', 'zoom', (e) => {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
219
      console.log("zoom");
220
      if (e.stopupdate) {
221
        return;
222
223
224
225
226
227
228
229
230
231
232
      } else {
        this._minx = e.xmin;
        this._maxx = e.xmax;
      }
      if (e.graphid !== `zingchart-ng-1-graph-preview`) {
        this.chart.zoomto({
          graphid: `zingchart-ng-1-graph-preview`,
          xmin: e.xmin,
          xmax: e.xmax,
          stopupdate: true
        });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
233
      }
234
      for (let i = 1; i < this.graphset.length; i ++) {
235
236
237
        if (i === e.graphid) {
          continue;
        }
238
239
240
        this.chart.zoomto({
          graphid: i,
          xmin: e.xmin,
241
242
          xmax: e.xmax,
          stopupdate: true
243
        });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
244
245
      }
    });
246
247
248
249
250
251
252
253
    this.config = {
      layout: `${this.graphset.length}x1`,
      graphset: this.graphset
    };
    this.chart.setdata({
      data: this.config
    });
    console.log("showing plot");
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
254
255
    this._minx = 0;
    this._maxx = this.state.rawData[0].values.length / 10;
256
    // await this.debugClicked();
257
  }
258

259
260
261
  // changeSelection() {
  //   this.state.selection = [0, 1, 2];
  // }
262
263


264
265
  async updateChannels() {
    console.log('updating plot');
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
266
    console.log(this.state.selection);
267
268
269
270
271
    this.graphset = this.graphset.slice(0, 1);
    this.state.selection.forEach((channelIndex, index) => {
      const channel = this.state.rawData[channelIndex];
      const data = [];
      for (let i = 0; i < channel.values.length; i++) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
272
        data.push([i, channel.values[i]]);
273
      }
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
      this.graphset.push({
        id: channelIndex,
        x: 0,
        y: `${75 * index + 50}px`,
        type: 'line',
        height: '50px',
        scaleX: {
          zooming: true,
          markers: []
        },
        'scale-y': {
          zooming: false,
          'auto-fit': true
        },
        plotarea: {
          height: '50px',
          'margin-top': '0px',
          'margin-bot': '0px'
        },
        series: [{
          type: 'line',
          values: data,
          text: 'Raw Values',
          zIndex: 5,
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
298
          'line-color': this.state.colors[channelIndex],
299
300
301
302
303
          marker: {
            alpha: 0.0,
            zIndex: 10
          }
        }]
304
305
      });
    });
306
307
308
309
310
311
    this.config = {
      layout: `${this.graphset.length}x1`,
      graphset: this.graphset
    };
    this.chart.setdata({
      data: this.config
312
    });
313
314
    // this.chart.addgraph(this.graphset[4]);
    console.log("showing plot");
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
315
316
    this.minx = 0;
    this.maxx = 120;
317
318
319
  }

  async updatePlot() {
320
321
322
323
    console.log('updating plot');
    if (!this.state.queryWindow) {
      return;
    }
324
325
326
    this.goodLabels = [];
    this.badLabels = [];
    this.markers = [];
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
327
328
    for (const index in this.state.labels) {
      if (this.state.labels[index]) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
329
        this.goodLabels.push([Number(index), 1]);
330
331
332
        this.markers.push({
          type: 'area',
          // BUG: For some reason the range values are multiplied by 10
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
333
          range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
334
          backgroundColor: "#4caf50",
335
        });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
336
      } else {
337
        this.badLabels.push([Number(index), -1]);
338
339
340
        this.markers.push({
          type: 'area',
          // BUG: For some reason the range values are multiplied by 10
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
341
          range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
342
          backgroundColor: "#f44336",
343
        });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
344
      }
345
    }
346
    for (const index of this.state.lshData.samples) {
347
348
349
350
      this.candidateLabels.push([Number(index), 0]);
      this.markers.push({
        type: 'area',
        // BUG: For some reason the range values are multiplied by 10
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
351
        range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
352
353
354
        backgroundColor: '#b1a343',
      });
    }
355
356
357
358
359
360
361
362
363
364
365
    console.log(this.markers);
    for (const channel of this.config.graphset) {
      if (channel.type === 'line') {
        channel.scaleX.markers = this.markers;
      } else {
        channel.series[0].values = this.goodLabels;
        channel.series[1].values = this.badLabels;
        channel.series[2].values = this.candidateLabels;
      }
    }
    this.chart.setdata({
366
367
      data: this.config
    });
368

369
370
  }

371
  ping() {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
372
    console.log("ping");
373
374
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
375
376
377
378
379
380
381
382
383
  async updateCandidates() {
    let candidates = [];
    for (let i = 0; i <= this.state.sliderValue; i++) {
      candidates = candidates.concat(this.state.lshData.average_table[Object.keys(this.state.lshData.average_table)[i]]);
    }
    console.log('updating candidates');
    console.log(candidates);

    this.candidateLabels = [];
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
384
385
    this.goodLabels = [];
    this.badLabels = [];
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
386
387
    this.markers = [];

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
    for (const index in this.state.labels) {
      if (this.state.labels[index]) {
        this.goodLabels.push([Number(index), 1]);
        this.markers.push({
          type: 'area',
          // BUG: For some reason the range values are multiplied by 10
          range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
          backgroundColor: "#4caf50",
        });
      } else {
        this.badLabels.push([Number(index), -1]);
        this.markers.push({
          type: 'area',
          // BUG: For some reason the range values are multiplied by 10
          range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
          backgroundColor: "#f44336",
        });
      }
    }
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    for (const index of candidates) {
      this.candidateLabels.push([Number(index), 0]);
      this.markers.push({
        type: 'area',
        // BUG: For some reason the range values are multiplied by 10
        range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
        backgroundColor: '#b1a343',
      });
    }

    for (const channel of this.config.graphset) {
      if (channel.type === 'line') {
        channel.scaleX.markers = this.markers;
      } else {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
421
422
        channel.series[0].values = this.goodLabels;
        channel.series[1].values = this.badLabels;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
423
424
425
426
427
428
        channel.series[2].values = this.candidateLabels;
      }
    }
    this.chart.setdata({
      data: this.config
    });
429
  }
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
430

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
  // async clicked(clickData) {
  //   console.log(clickData);
  //   if (!this.state.querySelectionMode) {
  //     return;
  //   }
  //   this.state.querySelectionMode = false;
  //   await this.debugClicked();
  //   return;
  //   const xyInformation = zingchart.exec('zingchart-ng-1', 'getxyinfo', {
  //     x: clickData.x,
  //     y: clickData.y
  //   });
  //   const index = Math.floor(xyInformation[0].scalenumvalue / (12000 / 6));
  //   await this.state.getQueryWindow(index);
  //   await this.state.lshInitial();
  //   const temp = {};
  //   temp[index] = true;
  //   this.state.labels = temp;
  // }
  //
  // async debugClicked() {
  //   const index = 6713;
  //   await this.state.getQueryWindow(index);
  //   await this.state.lshInitial();
  //   const temp = {};
  //   temp[index] = true;
  //   this.state.labels = temp;
  // }
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
459

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
460
461
462
463
464
465
466
467
468
469
470
471
  scroll(p) {
    p.stopPropagation();
    console.log('mousewheel');
    console.log(p);
    console.log(p.deltaY);
    const q = Math.round((this._maxx - this._minx) / 10);
    if (p.deltaY > 0) {
      this._minx = Math.max(this._minx - q, 0);
      this._maxx = Math.max(this._maxx - q, 0);
    } else if (p.deltaY < 0) {
      this._minx = Math.min(this._minx + q, this.state.rawData[0].values.length - 1);
      this._maxx = Math.min(this._maxx + q, this.state.rawData[0].values.length - 1);
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
472
    }
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
473
474
475
476
477
    this.chart.zoomto({
      graphid: `zingchart-ng-1-graph-preview`,
      xmin: this._minx,
      xmax: this._maxx,
    });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
478
  }
479
480

  isInSelection(i): boolean {
481
    return this.currentSelection.includes(i);
482
483
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
484
485
486
487
  getColor(i): string {
    return this.state.colors[i];
  }

488
  changeSelection(i: number): void {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
489
    if (this.isInSelection(i)) {
490
      this.currentSelection = this.currentSelection.filter((v) => v !== i);
491
    } else {
492
      this.currentSelection.push(i);
493
494
495
    }
  }

496
497
498
499
  setSelection(): void {
    this.state.selection = this.currentSelection;
  }

500
501
502
  get height(): number {
    return Math.max(75 * this.state.selection.length + 50, this.initialHeight);
  }
503

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
504
505
506
507
  async setquery() {
    this.state.windowSize = this.maxx - this.minx;
    await this.state.getQueryWindow(null, this.maxx - this.minx, this.minx);
    await this.state.lshInitial();
508
509
510
  }

  get maxx(): number {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
511
    return this._maxx * 10;
512
513
514
  }

  set maxx(max: number) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
515
    this._maxx = max / 10;
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
    this.chart.zoomto({
      graphid: `zingchart-ng-1-graph-preview`,
      xmin: this._minx,
      xmax: this._maxx,
      stopupdate: true
    });
    for (let i = 1; i < this.graphset.length; i ++) {
      this.chart.zoomto({
        graphid: i,
        xmin: this._minx,
        xmax: this._maxx,
        stopupdate: true
      });
    }
  }

  get minx(): number {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
533
    return this._minx * 10;
534
535
536
  }

  set minx(min: number) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
537
    this._minx = min / 10;
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
    this.chart.zoomto({
      graphid: `zingchart-ng-1-graph-preview`,
      xmin: this._minx,
      xmax: this._maxx,
      stopupdate: true
    });
    for (let i = 1; i < this.graphset.length; i ++) {
      this.chart.zoomto({
        graphid: i,
        xmin: this._minx,
        xmax: this._maxx,
        stopupdate: true
      });
    }
  }
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
553
554
555
556

  get names(): string[] {
    return this.state.rawData.map((data, index) => data.name ? data.name : 'Channel ' + index.toString());
  }
557
}