import {Component, OnInit, ViewChild} from '@angular/core'; import { CacheService } from '../cache.service'; import zingchart from 'zingchart/es6'; @Component({ selector: 'app-overview-window', templateUrl: './overview-window.component.html', styleUrls: ['./overview-window.component.css'] }) export class OverviewWindowComponent implements OnInit { public config; public graphset = []; public id = "overview"; public markers = []; public series = []; public goodLabels = []; public badLabels = []; @ViewChild('chart') chart; public data; public layout; constructor(private service: CacheService) { } async ngOnInit(): Promise { this.service.onNewData.subscribe(() => this.initializePlot()); this.service.onNewTables.subscribe(() => { if (this.service.queryWindow) { this.updatePlot(); } }); this.service.onNewSlider.subscribe((v) => this.updateCandidates(v)); } async initializePlot() { // Initialize label chart this.graphset.push({ id: 'preview', type: "scatter", x: 0, y: 0, scaleX: { zooming: true, minValue: 0, maxValue: this.service.rawValues[0].length, zoomTo: [0, this.service.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: 20, }, { type: 'scatter', values: [], text: 'Bad labels', marker: { backgroundColor: '#f44336' }, zIndex: 20, }, { type: 'scatter', values: [], text: 'Candidates', marker: { backgroundColor: '#b1a343' }, zIndex: 20, } ] }); // Initialize channels this.service.rawValues.forEach((channel, index) => { const data = []; for (let i = 0; i < channel.length; i++) { data.push([i, channel[i]]); } this.graphset.push({ id: index, x: 0, y: `${75 * index + 50}px`, type: 'line', height: '50px', scaleX: { zooming: true, zoomTo: [0, this.service.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 } }] }); }); zingchart.bind('zingchart-ng-1', 'zoom', (e) => { if (e.graphid !== `zingchart-ng-1-graph-preview`) { return; } for (let i = 1; i < this.graphset.length; i ++) { this.chart.zoomto({ graphid: i, xmin: e.xmin, xmax: e.xmax }); } }); this.config = { layout: `${this.graphset.length}x1`, graphset: this.graphset }; console.log(this.config); console.log("showing plot"); } async clicked(clickData) { if (!this.service.querySelectionMode) { return; } this.service.querySelectionMode = false; const xyInformation = JSON.parse(this.chart.getxyinfo({ x: clickData.x, y: clickData.y })); console.log(xyInformation); const index = Math.floor(xyInformation[8].nodeidx / this.service.stepSize); await this.service.getQueryWindow(this.service.rawValues[0].slice(index, index + this.service.windowSize)); const temp = {}; temp[index] = true; this.service.labels = temp; await this.updatePlot(); } async updatePlot() { console.log('updating plot'); if (!this.service.queryWindow) { return; } this.goodLabels = []; this.badLabels = []; this.markers = []; for (const index in this.service.labels) { if (this.service.labels[index]) { this.goodLabels.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.service.windowSize) / 10], backgroundColor: "#4caf50", }); } else { this.badLabels.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.service.windowSize) / 10], backgroundColor: "#f44336", }); } } 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; } } this.chart.setdata({ data: this.config }); await this.service.getSimilarWindows(); } async updateCandidates(sliderIndex) { console.log("Updating chart"); 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), 0]); markers.push({ type: 'area', // BUG: For some reason the range values are multiplied by 10 range: [Number(index) / 10, (Number(index) + this.service.windowSize) / 10], backgroundColor: "#b1a343", }); } 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; } } this.chart.setdata({ data: this.config }); } zoom(p) { if (!p.ev) { return; } if (p.ev.wheelDelta > 0) { for (let i = 0; i < this.graphset.length; i ++) { this.chart.zoomin({ graphid: i }); } } else if (p.ev.wheelDelta < 0) { for (let i = 0; i < this.graphset.length; i ++) { this.chart.zoomout({ graphid: i }); } } } }