overview-window.component.ts 11.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
26
27

  public data;
  public layout;

28
  constructor(private state: StateService, private el: ElementRef) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
29
  }
30
31

  async ngOnInit(): Promise<void> {
32
33
34
35
36
    this.initialHeight = this.el.nativeElement.offsetHeight;
    // this.state.onNewData.subscribe(() => this.dostuff3());
    this.state.onNewData.subscribe(() => this.initializePlot());
    this.state.onNewLshData.subscribe(() => this.updatePlot());
    this.state.onNewSelection.subscribe(() => this.updateChannels());
37
38
  }

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  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};
    });
    console.log(values);
    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]);
62

63
64
65
66
67
68
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
    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() {
      console.log(d3.event.transform);
      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);
      });
97
98
    };

99
100
101
    const zoom = d3.zoom()
      .scaleExtent([1, 10000])
      .on('zoom', zoomed);
102
103
104
105




106
107
    svg.call(zoom);
  }
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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
  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,
        maxValue: this.state.rawData[0].values.length,
        zoomTo: [0, this.state.windowSize],
        '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
174

175
176
    console.log(this.state);
    console.log(this.state.selection);
177

178
179
180
181
182
183
184
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
210
211
212
213
214
    this.state.selection.forEach((channelIndex, index) => {
      const channel = this.state.rawData[channelIndex];
      const data = [];
      for (let i = 0; i < channel.values.length; i++) {
        data.push([i, channel.values[i]]);
      }
      this.graphset.push({
        id: index,
        x: 0,
        y: `${75 * index + 50}px`,
        type: 'line',
        height: '50px',
        scaleX: {
          zooming: true,
          zoomTo: [0, this.state.windowSize],
          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,
          marker: {
            alpha: 0.0,
            zIndex: 10
          }
        }]
      });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
215
    });
216
217
218
    zingchart.bind('zingchart-ng-1', 'zoom', (e) => {
      if (e.graphid !== `zingchart-ng-1-graph-preview`) {
        return;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
219
      }
220
221
222
223
224
225
      for (let i = 1; i < this.graphset.length; i ++) {
        this.chart.zoomto({
          graphid: i,
          xmin: e.xmin,
          xmax: e.xmax
        });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
226
227
      }
    });
228
229
230
231
232
233
234
235
236
237
238
    this.config = {
      layout: `${this.graphset.length}x1`,
      graphset: this.graphset
    };
    this.chart.setdata({
      data: this.config
    });
    console.log(this.config);
    console.log("showing plot");
    await this.debugClicked();
  }
239

240
241
242
  // changeSelection() {
  //   this.state.selection = [0, 1, 2];
  // }
243
244


245
246
247
248
249
250
251
252
  async updateChannels() {
    console.log('updating plot');
    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++) {
        data.push([i, channel.values[i]]);
253
      }
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
      this.graphset.push({
        id: channelIndex,
        x: 0,
        y: `${75 * index + 50}px`,
        type: 'line',
        height: '50px',
        scaleX: {
          zooming: true,
          zoomTo: [0, this.state.windowSize],
          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,
          marker: {
            alpha: 0.0,
            zIndex: 10
          }
        }]
284
285
      });
    });
286
287
288
289
290
291
    this.config = {
      layout: `${this.graphset.length}x1`,
      graphset: this.graphset
    };
    this.chart.setdata({
      data: this.config
292
    });
293
294
295
    // this.chart.addgraph(this.graphset[4]);
    console.log(this.config);
    console.log("showing plot");
296
297
298
  }

  async updatePlot() {
299
300
301
302
    console.log('updating plot');
    if (!this.state.queryWindow) {
      return;
    }
303
304
305
    this.goodLabels = [];
    this.badLabels = [];
    this.markers = [];
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
306
307
    for (const index in this.state.labels) {
      if (this.state.labels[index]) {
308
        this.goodLabels.push([Number(index), 0]);
309
310
311
        this.markers.push({
          type: 'area',
          // BUG: For some reason the range values are multiplied by 10
312
313
          range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
          backgroundColor: "#4caf50",
314
        });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
315
      } else {
316
        this.badLabels.push([Number(index), -1]);
317
318
319
        this.markers.push({
          type: 'area',
          // BUG: For some reason the range values are multiplied by 10
320
321
          range: [Number(index) / 10, (Number(index) + this.state.windowSize) / 10],
          backgroundColor: "#f44336",
322
        });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
323
      }
324
    }
325
    for (const index of this.state.lshData.samples) {
326
327
328
329
330
331
332
333
      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',
      });
    }
334
335
336
337
338
339
340
341
342
343
344
    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({
345
346
      data: this.config
    });
347

348
349
  }

350
351
352
353
  ping() {
    console.log("ping");
  }

354
  async updateCandidates(sliderIndex) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
    // let candidates = [];
    // for (let i = sliderIndex; i < this.service.nrOfTables; i++) {
    //   candidates = candidates.concat(this.service.windowSimilarity[sliderIndex.toString()]);
    // }
    // const labels = [];
    // const markers = [];
    // for (const index of candidates) {
    //   labels.push([Number(index) * (12000 / 6), 0]);
    //   markers.push({
    //     type: 'area',
    //     // BUG: For some reason the range values are multiplied by 10
    //     range: [Number(index) * (12000 / 6) / 10, (Number(index) * (12000 / 6) + this.state.windowSize) / 10],
    //     backgroundColor: '#b1a343',
    //   });
    // }
    // const newSeries = this.config.series.slice(0, 3);
    // newSeries.push({
    //   type: 'scatter',
    //   values: labels,
    //   text: 'Similar windows',
    //   marker: {
    //     backgroundColor: '#b1a343'
    //   },
    //   zIndex: 20,
    // });
    // this.config.series = newSeries;
    // this.config.scaleX.markers = this.markers.concat(markers);
    // zingchart.exec('zingchart-ng-1', 'setdata', {
    //   data: this.config
    // });
385
  }
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
386

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
387
  async clicked(clickData) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
388
    if (!this.state.querySelectionMode) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
389
390
      return;
    }
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
391
    this.state.querySelectionMode = false;
392
393
    await this.debugClicked();
    return;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
394
    const xyInformation = zingchart.exec('zingchart-ng-1', 'getxyinfo', {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
395
396
397
      x: clickData.x,
      y: clickData.y
    });
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
398
    const index = Math.floor(xyInformation[0].scalenumvalue / (12000 / 6));
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
399
400
401
402
403
    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
404
405
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
406
  async debugClicked() {
407
    const index = 6713;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
408
409
    await this.state.getQueryWindow(index);
    await this.state.lshInitial();
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
410
411
412
    const temp = {};
    temp[index] = true;
    this.state.labels = temp;
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
413
414
  }

Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
415
  zoom(p) {
416
417
418
    if (!p.ev) {
      return;
    }
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
419
    if (p.ev.wheelDelta > 0) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
420
      zingchart.exec("zingchart-ng-1", 'zoomin');
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
421
    } else if (p.ev.wheelDelta < 0) {
Kruyff,D.L.W. (Dylan)'s avatar
Kruyff,D.L.W. (Dylan) committed
422
423
424
      zingchart.exec("zingchart-ng-1", 'zoomout');
    }
  }
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442

  isInSelection(i): boolean {
    return i in this.state.selection;
  }

  changeSelection(i: number): void {
    if (i in this.state.selection) {
      this.state.selection = this.state.selection.filter((v) => v !== i);
    } else {
      const selection = this.state.selection;
      selection.push(i);
      this.state.selection = selection;
    }
  }

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