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

Progress window update

parent 1a4dfea3
......@@ -27,7 +27,7 @@
}
.label-button {
width: 100%;
width: 33%;
height: 30px;
}
......
......@@ -7,6 +7,7 @@
<div class="button-holder">
<button class="correct-button label-button" [class.correct-selected]="labels[subplot.index]" (click)="labelCorrect(subplot.index)">&#10004;</button>
<button class="neutral-button label-button" [class.neutral-selected]="labels[subplot.index] == undefined" (click)="labelUndefined(subplot.index)">&#8226;</button>
<button class="incorrect-button label-button" [class.incorrect-selected]="labels[subplot.index] == false" (click)="labelIncorrect(subplot.index)">&#10006;</button>
</div>
<plotly-plot [data]="subplot.data" [layout]="subplot.layout"></plotly-plot>
</div>
......
......@@ -41,21 +41,22 @@ export class LabelingWindowComponent implements OnInit {
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]
const channel = window[channelIndex];
data.push({
x: [...Array(channel.length).keys()],
y: channel,
type: 'line',
xaxis: 'x',
yaxis: `y${index + 2}`,
line: {
color: this.state.colors[channelIndex],
}
});
});
const subplots = [];
......@@ -110,7 +111,7 @@ export class LabelingWindowComponent implements OnInit {
async showSamples() {
this.labels = [];
this.topk = this.state.lshData.samples;
this.topk = this.state.lshData.samples.filter((index) => this.state.labels[index] === undefined);
this.subplots = [];
const values: number[][][] = await this.state.getWindow(this.topk);
......@@ -125,6 +126,9 @@ export class LabelingWindowComponent implements OnInit {
type: 'line',
xaxis: 'x',
yaxis: `y${index + 2}`,
line: {
color: this.state.colors[channelIndex],
}
});
});
const subplots = [];
......
.subplot {
margin-right: 20px;
width: 150px;
margin: 20px;
height: max-content;
border: 2px solid;
border-radius: 25px;
padding: 20px;
}
.good-labels {
......@@ -16,3 +19,12 @@
overflow: auto;
background-color: rgba(244, 67, 54, 0.5);
}
.channel_header {
height: 20px;
padding: 10px;
color: black;
font-weight: 500;
text-align: center;
vertical-align: middle;
}
<div class="good-labels" *ngIf="goodLabels.length > 0">
<div class="subplot" *ngFor="let subplot of goodLabels">
<div class="channel_header">
Index: {{ subplot.index }}
</div>
<plotly-plot [data]="subplot.data" [layout]="subplot.layout"></plotly-plot>
</div>
</div>
<div class="bad-labels" *ngIf="badLabels.length > 0">
<div class="subplot" *ngFor="let subplot of badLabels">
<div class="channel_header">
Index: {{ subplot.index }}
</div>
<plotly-plot [data]="subplot.data" [layout]="subplot.layout"></plotly-plot>
</div>
</div>
......@@ -15,49 +15,76 @@ export class LabelsComponent implements OnInit {
ngOnInit(): void {
this.state.onNewLabels.subscribe(() => { this.createSubplots(); });
this.state.onNewSelection.subscribe(() => { this.createSubplots(); });
}
async createSubplots() {
this.goodLabels = [];
this.badLabels = [];
const labelWindows: number[][][] = await this.state.getWindow(Object.keys(this.state.labels).map(Number));
Object.keys(this.state.labels).forEach((key, i) => {
const index = Number(key);
const plot =
{
index,
data: [{
x: [...Array(this.state.windowSize).keys()],
y: labelWindows[i],
type: 'line'
}],
layout: {
title: `Index: ${index.toString()}`,
hovermode: 'closest',
autosize: true,
margin: {
l: 30,
r: 30,
t: 30,
b: 5,
pad: 4
},
height: 150,
width: 150,
titlefont: {
size: 9
},
xaxis: {
showticklabels: false,
}
for (const idx in Object.keys(this.state.labels).map(Number)) {
const window = labelWindows[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: Object.keys(this.state.labels).map(Number)[idx],
data: data,
layout: {
grid: {
rows: this.state.selection.length,
columns: 1,
subplots: subplots,
},
showlegend: false,
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,
};
if (this.state.labels[key]) {
});
if (this.state.labels[Object.keys(this.state.labels).map(Number)[idx]]) {
this.goodLabels.push(plot);
} else {
this.badLabels.push(plot);
}
});
}
}
}
......@@ -21,7 +21,7 @@
<as-split-area [size]="70">
<as-split direction="horizontal">
<as-split-area [size]="70">
<as-split-area [size]="60">
<div class="channel_header">
Feedback
</div>
......@@ -29,7 +29,7 @@
<app-training-window></app-training-window>
</div>
</as-split-area>
<as-split-area [size]="30">
<as-split-area [size]="40">
<div class="channel_header">
Results
</div>
......
......@@ -25,7 +25,7 @@
overflow: scroll;
}
.container {
.main-container {
height: 100%;
display: flex;
justify-content: space-between;
......@@ -116,3 +116,69 @@ path {
text-align: center;
vertical-align: middle;
}
.container {
display: block;
position: relative;
padding-left: 35px;
margin-bottom: 12px;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* Hide the browser's default checkbox */
.container input {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
/* Create a custom checkbox */
.checkmark {
position: absolute;
top: 0;
left: 0;
height: 25px;
width: 25px;
background-color: #eee;
}
/* On mouse-over, add a grey background color */
.container:hover input ~ .checkmark {
background-color: #ccc;
}
/* When the checkbox is checked, add a blue background */
.container input:checked ~ .checkmark {
background-color: #2196F3;
}
/* Create the checkmark/indicator (hidden when not checked) */
.checkmark:after {
content: "";
position: absolute;
display: none;
}
/* Show the checkmark when checked */
.container input:checked ~ .checkmark:after {
display: block;
}
/* Style the checkmark/indicator */
.container .checkmark:after {
left: 9px;
top: 5px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 3px 3px 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
<div class="container">
<div class="left">
<div class="main-container">
<as-split direction="horizontal">
<as-split-area [size]="10">
<div class="channel_header">
Channels
</div>
<div class="list">
<div class="list-element" *ngFor="let index of allChannels">
<mat-checkbox [checked]="isInSelection(index)"
(change)="changeSelection(index)">
{{ names[index] }}
</mat-checkbox>
<div class="list">
<div class="list-element" *ngFor="let index of allChannels">
<label class="container">{{ names[index] }}
<input type="checkbox" [checked]="isInSelection(index)" (click)="changeSelection(index)">
<span class="checkmark" [ngStyle]="isInSelection(index) && {'background-color': getColor(index)} || {}"></span>
</label>
</div>
</div>
</div>
</div>
<div class="right">
<div class="channel_header">
Overview
</div>
<div class="toolbar">
</as-split-area>
<as-split-area [size]="90">
<div class="channel_header">
Dataset overview
</div>
<div class="toolbar">
<label class="small-margin" for="windowsize">Start</label><br>
<input class="small-margin" id="windowsize" [(ngModel)]="minx">
<label class="small-margin" for="windowsize">Start</label><br>
<input class="small-margin" id="windowsize" [(ngModel)]="minx">
<label class="small-margin" for="hashsize">End</label><br>
<input class="small-margin" [(ngModel)]="maxx" id="hashsize">
<label class="small-margin" for="hashsize">End</label><br>
<input class="small-margin" [(ngModel)]="maxx" id="hashsize">
<button (click)="setquery()">
Set as query
</button>
</div>
<div class="overview">
<zingchart-angular #chart [id]="id" (mousewheel)="zoom($event)" (zoom)="ping()" [height]="height" (complete)="ping()"></zingchart-angular>
</div>
</div>
<button (click)="setquery()">
Set as query
</button>
</div>
<div class="overview">
<zingchart-angular #chart [id]="id" (mousewheel)="zoom($event)" (zoom)="ping()" [height]="height" (complete)="ping()"></zingchart-angular>
</div>
</as-split-area>
</as-split>
</div>
......@@ -36,6 +36,7 @@ export class OverviewWindowComponent implements OnInit {
this.state.onNewData.subscribe(() => this.initializePlot());
this.state.onNewLshData.subscribe(() => this.updatePlot());
this.state.onNewSelection.subscribe(() => this.updateChannels());
this.state.onNewSlider.subscribe(() => this.updateCandidates());
}
dostuff3() {
......@@ -201,6 +202,7 @@ export class OverviewWindowComponent implements OnInit {
values: data,
text: 'Raw Values',
zIndex: 5,
'line-color': this.state.colors[channelIndex],
marker: {
alpha: 0.0,
zIndex: 10
......@@ -243,8 +245,8 @@ export class OverviewWindowComponent implements OnInit {
data: this.config
});
console.log("showing plot");
this.minx = 0;
this.maxx = 120;
this._minx = 0;
this._maxx = this.state.rawData[0].values.length / 10;
// await this.debugClicked();
}
......@@ -255,6 +257,7 @@ export class OverviewWindowComponent implements OnInit {
async updateChannels() {
console.log('updating plot');
console.log(this.state.selection);
this.graphset = this.graphset.slice(0, 1);
this.state.selection.forEach((channelIndex, index) => {
const channel = this.state.rawData[channelIndex];
......@@ -286,6 +289,7 @@ export class OverviewWindowComponent implements OnInit {
values: data,
text: 'Raw Values',
zIndex: 5,
'line-color': this.state.colors[channelIndex],
marker: {
alpha: 0.0,
zIndex: 10
......@@ -316,7 +320,7 @@ export class OverviewWindowComponent implements OnInit {
this.markers = [];
for (const index in this.state.labels) {
if (this.state.labels[index]) {
this.goodLabels.push([Number(index), 0]);
this.goodLabels.push([Number(index), 1]);
this.markers.push({
type: 'area',
// BUG: For some reason the range values are multiplied by 10
......@@ -362,37 +366,37 @@ export class OverviewWindowComponent implements OnInit {
console.log("zoom");
}
async updateCandidates(sliderIndex) {
// 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
// });
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 = [];
this.markers = [];
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 {
channel.series[2].values = this.candidateLabels;
}
}
this.chart.setdata({
data: this.config
});
}
// async clicked(clickData) {
......@@ -439,8 +443,12 @@ export class OverviewWindowComponent implements OnInit {
return this.state.selection.includes(i);
}
getColor(i): string {
return this.state.colors[i];
}
changeSelection(i: number): void {
if (i in this.state.selection) {
if (this.isInSelection(i)) {
this.state.selection = this.state.selection.filter((v) => v !== i);
} else {
const selection = this.state.selection;
......
......@@ -22,13 +22,17 @@
display: none;
}
.main-container {
.info {
overflow-y: scroll;
display: flex;
justify-content: space-around;
}
.main-container {
}
.container {
display: flex;
justify-content: center;
margin-top: 10px;
}
.slider {
......
<!--<svg id="visual" width='500' height='300'></svg>-->
<div class="main-container">
<mat-tab-group animationDuration="0ms">
<mat-tab-group mat-stretch-tabs animationDuration="0ms">
<mat-tab label="Classifier">
<div style="overflow-y: scroll">
<div *ngIf="data" class="histogram">
<div class="slider">
<mat-slider [min]="0" [max]="maxLength" step="1" [value]="sliderValue" (input)="setSliderValue($event)" thumbLabel tickInterval="5"></mat-slider>
</div>
<div *ngIf="data" class="container">
<button (click)="showCandidates()">
Show {{ nrOfCandidates }} similar candidates
</button>
</div>
<div *ngIf="data" class="slider">
<mat-slider [min]="0" [max]="maxLength" step="1" [value]="sliderValue" (input)="setSliderValue($event)" thumbLabel tickInterval="5"></mat-slider>
</div>
<div *ngIf="data" class="info">
<div class="histogram">
<div class="container">
<fieldset>
<legend>Similarity distribution</legend>
<plotly-plot (hover)="onHover($event)" [data]="hist.data" [layout]="hist.layout"></plotly-plot>
</fieldset>
<div class="container">
<fieldset>
<legend>Info</legend>
# Candidates found: {{1000000}}
</fieldset>
</div>
</div>
</div>
<div *ngIf="data" class="container">
......@@ -24,11 +35,6 @@
</fieldset>
</div>
</div>
<div *ngIf="data" class="container">
<button>
Show {{ nrOfCandidates }} similar candidates
</button>
</div>