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

Final experiments + Pseudo feature: channel selection

parent 6012e545
......@@ -20,6 +20,7 @@ import { MainComponent } from './main/main.component';
import { MatProgressBarModule} from '@angular/material/progress-bar';
import {MatSliderModule} from '@angular/material/slider';
import { TrainingWindowComponent } from './training-window/training-window.component';
import {MatCheckboxModule} from '@angular/material/checkbox';
PlotlyModule.plotlyjs = PlotlyJS;
......@@ -43,6 +44,7 @@ PlotlyModule.plotlyjs = PlotlyJS;
BrowserAnimationsModule,
MatTabsModule,
MatProgressBarModule,
MatCheckboxModule,
ZingchartAngularModule,
MatSliderModule
],
......
......@@ -17,6 +17,7 @@ export class LabelingWindowComponent implements OnInit {
ngOnInit(): void {
this.state.onNewLshData.subscribe(() => this.showSamples());
this.state.onNewSelection.subscribe(() => { this.updateChannels(); });
}
public labelCorrect(index: number) {
......@@ -36,6 +37,77 @@ export class LabelingWindowComponent implements OnInit {
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() {
this.labels = [];
this.topk = this.state.lshData.samples;
......@@ -45,7 +117,8 @@ export class LabelingWindowComponent implements OnInit {
for (const idx in this.topk) {
const window = values[idx];
const data = [];
window.forEach((channel: number[], index: number) => {
this.state.selection.forEach((channelIndex, index) => {
const channel = window[channelIndex];
data.push({
x: [...Array(channel.length).keys()],
y: channel,
......@@ -55,7 +128,7 @@ export class LabelingWindowComponent implements OnInit {
});
});
const subplots = [];
window.forEach((channel: number[], index: number) => {
this.state.selection.forEach((channelIndex, index) => {
subplots.push([`xy${index + 2}`]);
});
const plot = {
......@@ -63,7 +136,7 @@ export class LabelingWindowComponent implements OnInit {
data: data,
layout: {
grid: {
rows: this.state.queryWindow.length,
rows: this.state.selection.length,
columns: 1,
subplots: subplots,
},
......@@ -78,7 +151,7 @@ export class LabelingWindowComponent implements OnInit {
b: 0,
pad: 4
},
height: 100 * values[0].length,
height: 100 * this.state.selection.length,
width: 300,
titlefont: {
size: 9
......@@ -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}`] = {
zeroline: false,
showticklabels: false,
......
......@@ -39,6 +39,16 @@
border-left: groove;
}
.top {
height: 30%;
overflow-y: scroll;
border-bottom: groove;
}
.bot {
height: 70%;
}
.container {
display: flex;
justify-content: space-between;
......
<div class="container">
<div class="left">
<app-overview-window style="z-index: 10"></app-overview-window>
<mat-tab-group animationDuration="0ms" (selectedTabChange)="changeTab($event)">
<mat-tab label="Training">
<app-training-window></app-training-window>
</mat-tab>
<mat-tab label="Labeled data">
<app-labels></app-labels>
</mat-tab>
<mat-tab label="Settings">
<app-settings></app-settings>
</mat-tab>
</mat-tab-group>
<div class="top">
<app-overview-window style="z-index: 10"></app-overview-window>
</div>
<div class="bot">
<mat-tab-group animationDuration="0ms" (selectedTabChange)="changeTab($event)">
<mat-tab label="Training">
<app-training-window></app-training-window>
</mat-tab>
<mat-tab label="Labeled data">
<app-labels></app-labels>
</mat-tab>
<mat-tab label="Settings">
<app-settings></app-settings>
</mat-tab>
</mat-tab-group>
</div>
</div>
<div class="right">
<div class="top">
<app-query-window></app-query-window>
<app-progress-view></app-progress-view>
</div>
<div class="bot">
<app-progress-view></app-progress-view>
</div>
</div>
</div>
<div class="overlay" [class.show]="greyOut" *ngIf="loadingProgress != 100"></div>
......
......@@ -6,6 +6,27 @@
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 {
width: 100%;
height: 100%;
......
<!--<zingchart-angular #chart [id]="id" [config]="config" (mousewheel)="zoom($event)" (click)="clicked($event)" [height]="300"></zingchart-angular>-->
<div class="table-wrapper">
<div class="table-scroll">
<table>
<thead>
<th><div>Channel</div></th>
</thead>
<tbody></tbody>
</table>
<div class="container">
<div class="left">
<span class="example-list-section">
<ul>
<li *ngFor="let index of allChannels">
<mat-checkbox [checked]="isInSelection(index)"
(change)="changeSelection(index)">
Channel {{index}}
</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 class="channels">
</div>
import {Component, OnInit, ViewChild} from '@angular/core';
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import { StateService } from '../state.service';
import zingchart from 'zingchart/es6';
import * as d3 from 'd3';
......@@ -10,6 +10,7 @@ import * as d3 from 'd3';
})
export class OverviewWindowComponent implements OnInit {
@ViewChild('chart') chart;
private initialHeight;
public config;
public graphset = [];
public id = 'overview';
......@@ -19,385 +20,279 @@ export class OverviewWindowComponent implements OnInit {
public badLabels = [];
public candidateLabels = [];
public pathWidth = 100;
public allChannels: number[];
public data;
public layout;
constructor(private state: StateService) {
constructor(private state: StateService, private el: ElementRef) {
}
async ngOnInit(): Promise<void> {
this.state.onNewData.subscribe(() => this.doStuff());
// this.state.onNewData.subscribe(() => this.initializePlot());
// this.state.onNewLshData.subscribe(() => this.updatePlot());
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());
}
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 x,y,gX, gY, xAxis, yAxis;
const idList=1
const color = d3.scaleOrdinal(d3.schemeCategory10);
let mainData = null;
const line;
const settings = {
targets:[],
detail:{
type:"line"
}
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);
});
};
mainData = data;
const svg = d3.select("svg");
d3.select("#area")
.insert("div","svg").html(data[0].metric.AREA_NAME+"<BR>"+data[0].metric.IND_NAME
+"<BR>"+data[0].metric.NAME);
const zoom = d3.zoom()
.scaleExtent([1, 10000])
.on('zoom', zoomed);
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;
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;}}
svg.call(zoom);
}
if(limits.minX == null){ limits.minX = eMinX;}
else { if(eMinX < limits.minX){ limits.minX = eMinX;}}
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
if(limits.maxY == null){limits.maxY = eMaxY;}
else { if(eMaxY > limits.maxY){limits.maxY = eMaxY;}}
console.log(this.state);
console.log(this.state.selection);
if(limits.minY == null){limits.minY = eMinY;}
else { if(eMinY < limits.minY){limits.minY = eMinY;}}
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
}
}]
});
});
settings.targets.forEach(function(d){
if(limits.maxY < d.value){
limits.maxY = d.value;
zingchart.bind('zingchart-ng-1', 'zoom', (e) => {
if (e.graphid !== `zingchart-ng-1-graph-preview`) {
return;
}
if(limits.minY > d.value){
limits.minY = d.value;
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`,