Commit 5418572e authored by Kruyff,D.L.W. (Dylan)'s avatar Kruyff,D.L.W. (Dylan)
Browse files

Final experiments + Pseudo feature: channel selection


Former-commit-id: 20cafc25
parent f936c0b6
...@@ -20,6 +20,7 @@ import { MainComponent } from './main/main.component'; ...@@ -20,6 +20,7 @@ import { MainComponent } from './main/main.component';
import { MatProgressBarModule} from '@angular/material/progress-bar'; import { MatProgressBarModule} from '@angular/material/progress-bar';
import {MatSliderModule} from '@angular/material/slider'; import {MatSliderModule} from '@angular/material/slider';
import { TrainingWindowComponent } from './training-window/training-window.component'; import { TrainingWindowComponent } from './training-window/training-window.component';
import {MatCheckboxModule} from '@angular/material/checkbox';
PlotlyModule.plotlyjs = PlotlyJS; PlotlyModule.plotlyjs = PlotlyJS;
...@@ -43,6 +44,7 @@ PlotlyModule.plotlyjs = PlotlyJS; ...@@ -43,6 +44,7 @@ PlotlyModule.plotlyjs = PlotlyJS;
BrowserAnimationsModule, BrowserAnimationsModule,
MatTabsModule, MatTabsModule,
MatProgressBarModule, MatProgressBarModule,
MatCheckboxModule,
ZingchartAngularModule, ZingchartAngularModule,
MatSliderModule MatSliderModule
], ],
......
...@@ -17,6 +17,7 @@ export class LabelingWindowComponent implements OnInit { ...@@ -17,6 +17,7 @@ export class LabelingWindowComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.state.onNewLshData.subscribe(() => this.showSamples()); this.state.onNewLshData.subscribe(() => this.showSamples());
this.state.onNewSelection.subscribe(() => { this.updateChannels(); });
} }
public labelCorrect(index: number) { public labelCorrect(index: number) {
...@@ -36,6 +37,77 @@ export class LabelingWindowComponent implements OnInit { ...@@ -36,6 +37,77 @@ export class LabelingWindowComponent implements OnInit {
this.labelsOutput.emit(this.labels); this.labelsOutput.emit(this.labels);
} }
async updateChannels() {
if (!this.state.lshData) {
return;
}
this.topk = this.state.lshData.samples;
this.subplots = [];
const values: number[][][] = await this.state.getWindow(this.topk);
for (const idx in this.topk) {
const window = values[idx];
const data = [];
this.state.selection.forEach((channelIndex, index) => {
const channel = window[channelIndex]
data.push({
x: [...Array(channel.length).keys()],
y: channel,
type: 'line',
xaxis: 'x',
yaxis: `y${index + 2}`,
});
});
const subplots = [];
this.state.selection.forEach((channelIndex, index) => {
subplots.push([`xy${index + 2}`]);
});
const plot = {
index: this.topk[idx],
data: data,
layout: {
grid: {
rows: this.state.selection.length,
columns: 1,
subplots: subplots,
},
showlegend: false,
title: `Index: ${this.topk[idx].toString()}`,
hovermode: 'closest',
autosize: true,
margin: {
l: 30,
r: 30,
t: 30,
b: 0,
pad: 4
},
height: 100 * this.state.selection.length,
width: 300,
titlefont: {
size: 9
},
xaxis: {
showgrid: false,
zeroline: false,
showticklabels: false,
},
yaxis: {
zeroline: false,
showticklabels: false,
}
}
};
this.state.selection.forEach((channelIndex, index) => {
plot.layout[`yaxis${index + 2}`] = {
zeroline: false,
showticklabels: false,
};
});
this.subplots.push(plot);
}
}
async showSamples() { async showSamples() {
this.labels = []; this.labels = [];
this.topk = this.state.lshData.samples; this.topk = this.state.lshData.samples;
...@@ -45,7 +117,8 @@ export class LabelingWindowComponent implements OnInit { ...@@ -45,7 +117,8 @@ export class LabelingWindowComponent implements OnInit {
for (const idx in this.topk) { for (const idx in this.topk) {
const window = values[idx]; const window = values[idx];
const data = []; const data = [];
window.forEach((channel: number[], index: number) => { this.state.selection.forEach((channelIndex, index) => {
const channel = window[channelIndex];
data.push({ data.push({
x: [...Array(channel.length).keys()], x: [...Array(channel.length).keys()],
y: channel, y: channel,
...@@ -55,7 +128,7 @@ export class LabelingWindowComponent implements OnInit { ...@@ -55,7 +128,7 @@ export class LabelingWindowComponent implements OnInit {
}); });
}); });
const subplots = []; const subplots = [];
window.forEach((channel: number[], index: number) => { this.state.selection.forEach((channelIndex, index) => {
subplots.push([`xy${index + 2}`]); subplots.push([`xy${index + 2}`]);
}); });
const plot = { const plot = {
...@@ -63,7 +136,7 @@ export class LabelingWindowComponent implements OnInit { ...@@ -63,7 +136,7 @@ export class LabelingWindowComponent implements OnInit {
data: data, data: data,
layout: { layout: {
grid: { grid: {
rows: this.state.queryWindow.length, rows: this.state.selection.length,
columns: 1, columns: 1,
subplots: subplots, subplots: subplots,
}, },
...@@ -78,7 +151,7 @@ export class LabelingWindowComponent implements OnInit { ...@@ -78,7 +151,7 @@ export class LabelingWindowComponent implements OnInit {
b: 0, b: 0,
pad: 4 pad: 4
}, },
height: 100 * values[0].length, height: 100 * this.state.selection.length,
width: 300, width: 300,
titlefont: { titlefont: {
size: 9 size: 9
...@@ -94,7 +167,7 @@ export class LabelingWindowComponent implements OnInit { ...@@ -94,7 +167,7 @@ export class LabelingWindowComponent implements OnInit {
} }
} }
}; };
window.forEach((channel: number[], index: number) => { this.state.selection.forEach((channelIndex, index) => {
plot.layout[`yaxis${index + 2}`] = { plot.layout[`yaxis${index + 2}`] = {
zeroline: false, zeroline: false,
showticklabels: false, showticklabels: false,
......
...@@ -39,6 +39,16 @@ ...@@ -39,6 +39,16 @@
border-left: groove; border-left: groove;
} }
.top {
height: 30%;
overflow-y: scroll;
border-bottom: groove;
}
.bot {
height: 70%;
}
.container { .container {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
......
<div class="container"> <div class="container">
<div class="left"> <div class="left">
<div class="top">
<app-overview-window style="z-index: 10"></app-overview-window> <app-overview-window style="z-index: 10"></app-overview-window>
</div>
<div class="bot">
<mat-tab-group animationDuration="0ms" (selectedTabChange)="changeTab($event)"> <mat-tab-group animationDuration="0ms" (selectedTabChange)="changeTab($event)">
<mat-tab label="Training"> <mat-tab label="Training">
<app-training-window></app-training-window> <app-training-window></app-training-window>
...@@ -13,10 +16,15 @@ ...@@ -13,10 +16,15 @@
</mat-tab> </mat-tab>
</mat-tab-group> </mat-tab-group>
</div> </div>
</div>
<div class="right"> <div class="right">
<div class="top">
<app-query-window></app-query-window> <app-query-window></app-query-window>
</div>
<div class="bot">
<app-progress-view></app-progress-view> <app-progress-view></app-progress-view>
</div> </div>
</div>
</div> </div>
<div class="overlay" [class.show]="greyOut" *ngIf="loadingProgress != 100"></div> <div class="overlay" [class.show]="greyOut" *ngIf="loadingProgress != 100"></div>
<div class="loading-progress" *ngIf="loadingProgress != 100"> <div class="loading-progress" *ngIf="loadingProgress != 100">
......
...@@ -6,6 +6,27 @@ ...@@ -6,6 +6,27 @@
box-sizing: border-box; box-sizing: border-box;
} }
.left {
width: 15%;
}
ul {
padding-top: 10px;
margin: 0;
list-style-type: none;
}
.right {
width: 85%;
border-left: groove;
}
.container {
height: 100%;
display: flex;
justify-content: space-between;
}
html, body { html, body {
width: 100%; width: 100%;
height: 100%; height: 100%;
......
<!--<zingchart-angular #chart [id]="id" [config]="config" (mousewheel)="zoom($event)" (click)="clicked($event)" [height]="300"></zingchart-angular>--> <div class="container">
<div class="table-wrapper"> <div class="left">
<div class="table-scroll"> <span class="example-list-section">
<table> <ul>
<thead> <li *ngFor="let index of allChannels">
<th><div>Channel</div></th> <mat-checkbox [checked]="isInSelection(index)"
</thead> (change)="changeSelection(index)">
<tbody></tbody> Channel {{index}}
</table> </mat-checkbox>
</li>
</ul>
</span>
</div>
<div class="right">
<zingchart-angular #chart [id]="id" (mousewheel)="zoom($event)" (click)="clicked($event)" [height]="height" (complete)="ping()"></zingchart-angular>
</div> </div>
</div>
<div class="channels">
</div> </div>
import {Component, OnInit, ViewChild} from '@angular/core'; import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import { StateService } from '../state.service'; import { StateService } from '../state.service';
import zingchart from 'zingchart/es6'; import zingchart from 'zingchart/es6';
import * as d3 from 'd3'; import * as d3 from 'd3';
...@@ -10,6 +10,7 @@ import * as d3 from 'd3'; ...@@ -10,6 +10,7 @@ import * as d3 from 'd3';
}) })
export class OverviewWindowComponent implements OnInit { export class OverviewWindowComponent implements OnInit {
@ViewChild('chart') chart; @ViewChild('chart') chart;
private initialHeight;
public config; public config;
public graphset = []; public graphset = [];
public id = 'overview'; public id = 'overview';
...@@ -19,385 +20,279 @@ export class OverviewWindowComponent implements OnInit { ...@@ -19,385 +20,279 @@ export class OverviewWindowComponent implements OnInit {
public badLabels = []; public badLabels = [];
public candidateLabels = []; public candidateLabels = [];
public pathWidth = 100; public pathWidth = 100;
public allChannels: number[];
public data; public data;
public layout; public layout;
constructor(private state: StateService) { constructor(private state: StateService, private el: ElementRef) {
} }
async ngOnInit(): Promise<void> { async ngOnInit(): Promise<void> {
this.state.onNewData.subscribe(() => this.doStuff()); this.initialHeight = this.el.nativeElement.offsetHeight;
// this.state.onNewData.subscribe(() => this.initializePlot()); // this.state.onNewData.subscribe(() => this.dostuff3());
// this.state.onNewLshData.subscribe(() => this.updatePlot()); this.state.onNewData.subscribe(() => this.initializePlot());
this.state.onNewLshData.subscribe(() => this.updatePlot());
this.state.onNewSelection.subscribe(() => this.updateChannels());
} }
doStuff3() { 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]);
doStuff2() { const line = d3.line()
const x,y,gX, gY, xAxis, yAxis; .x(function(d:any) { return xscale(d.x); })
const idList=1 .y(function(d:any) { return yscale(d.y); })
const color = d3.scaleOrdinal(d3.schemeCategory10);
let mainData = null; const axis = d3.axisBottom(xscale);
const line;
const settings = { const axis_G = svg.append("g")
targets:[], .attr("transform", "translate(0," + height + ")")
detail:{ .call(axis);
type:"line"
} 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);
});
}; };
mainData = data; const zoom = d3.zoom()
const svg = d3.select("svg"); .scaleExtent([1, 10000])
.on('zoom', zoomed);
d3.select("#area")
.insert("div","svg").html(data[0].metric.AREA_NAME+"<BR>"+data[0].metric.IND_NAME
+"<BR>"+data[0].metric.NAME);
const limits = {maxY: null, minY: null, maxX: null, minX: null};
const padding = {top: 20, bottom: 150, left: 100, right: 20};
const width = +svg.attr("width");
const height = +svg.attr("height");
const canvasHeight = height-padding.top-padding.bottom; svg.call(zoom);
const canvasWidth = width-padding.left-padding.right; }
data.forEach(function(e,i) {
const eMaxY = d3.max(e.data,function(d){return +d.VALUE_NUMERIC;});
const eMinY = d3.min(e.data,function(d){return +d.VALUE_NUMERIC;});
const eMaxX = d3.max(e.data,function(d){return new Date(d.DATA_DATE);});
const eMinX = d3.min(e.data,function(d){return new Date(d.DATA_DATE);});
if(limits.maxX == null){ limits.maxX = eMaxX;}
else { if(eMaxX > limits.maxX){ limits.maxX = eMaxX;}}
if(limits.minX == null){ limits.minX = eMinX;}
else { if(eMinX < limits.minX){ limits.minX = eMinX;}}
if(limits.maxY == null){limits.maxY = eMaxY;}
else { if(eMaxY > limits.maxY){limits.maxY = eMaxY;}}
if(limits.minY == null){limits.minY = eMinY;}
else { if(eMinY < limits.minY){limits.minY = eMinY;}}
});
settings.targets.forEach(function(d){ async initializePlot() {
if(limits.maxY < d.value){ this.allChannels = [...Array(this.state.rawData.length).keys()];
limits.maxY = d.value; 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
} }
if(limits.minY > d.value){ },
limits.minY = d.value; 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
console.log(this.state);
console.log(this.state.selection);
const canvas = svg.append("g") this.state.selection.forEach((channelIndex, index) => {
.attr("id","canvas") const channel = this.state.rawData[channelIndex];
.attr("width",canvasWidth) const data = [];
.attr("height",canvasHeight) for (let i = 0; i < channel.values.length; i++) {
.attr("transform","translate("+padding.left+","+padding.top+")")