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

Major changes

parent 69108089
......@@ -85,20 +85,8 @@ export class ApiService {
return await response.json();
}
async getAverageProgressWindows(windows): Promise<number[][]> {
const response = await fetch('http://127.0.0.1:5000/average-progress', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({windows})
});
return await response.json();
}
async getAverageTableWindows(windows): Promise<number[][]> {
const response = await fetch('http://127.0.0.1:5000/average-table', {
async getAverageWindows(windows): Promise<any> {
const response = await fetch('http://127.0.0.1:5000/average', {
method: 'POST',
headers: {
'Accept': 'application/json',
......
......@@ -18,6 +18,7 @@ import {ZingchartAngularModule} from 'zingchart-angular';
import { ProgressViewComponent } from './progress-view/progress-view.component';
import { MainComponent } from './main/main.component';
import { MatProgressBarModule} from '@angular/material/progress-bar';
import {MatSliderModule} from '@angular/material/slider';
PlotlyModule.plotlyjs = PlotlyJS;
......@@ -40,7 +41,8 @@ PlotlyModule.plotlyjs = PlotlyJS;
BrowserAnimationsModule,
MatTabsModule,
MatProgressBarModule,
ZingchartAngularModule
ZingchartAngularModule,
MatSliderModule
],
providers: [],
bootstrap: [AppComponent]
......
......@@ -25,7 +25,7 @@ export class CacheService {
public stepSize = 200;
public querySelectionMode = true;
public distances = [];
public dtwdistances: number[] = [];
public _dtwdistances: number[] = [];
public onNewData: EventEmitter<void> = new EventEmitter<void>();
public onNewSimilarity: EventEmitter<void> = new EventEmitter<void>();
......@@ -71,7 +71,7 @@ export class CacheService {
const output = await this.api.initialize(this._queryWindow);
this.dtwdistances = output.distances;
this.candidates = output.candidates;
this.tables = output.hash_functions;
this.createTable();
this._parameters = output.parameters;
console.log(output);
}
......@@ -81,16 +81,12 @@ export class CacheService {
const output = await this.api.update(this._queryWindow, this.distances, this._parameters);
this.dtwdistances = output.distances;
this.candidates = output.candidates;
this.tables = output.hash_functions;
this.createTable();
console.log(output);
}
async getAverageProgressWindows(windows): Promise<number[][]> {
return await this.api.getAverageProgressWindows(windows);
}
async getAverageTableWindows(windows): Promise<number[][]> {
return await this.api.getAverageTableWindows(windows);
async getAverageWindows(windows): Promise<any> {
return await this.api.getAverageWindows(windows);
}
async getQueryWindow(window): Promise<number[]> {
......@@ -104,6 +100,27 @@ export class CacheService {
return await this.api.getWindow(indices);
}
public createTable() {
const indices = this.dtwdistances.map((x) => x > 500 ? 100 : Math.floor(x / 5));
const table = {};
this.candidates.forEach((candidate, index) => {
if (table[indices[index]] === undefined)
{
table[indices[index]] = [];
}
table[indices[index]].push(candidate);
});
this.tables = table;
}
public set dtwdistances(v) {
this._dtwdistances = v;
}
public get dtwdistances(): number[] {
return this._dtwdistances;
}
public set query(v) {
this._query = v;
}
......
......@@ -9,8 +9,10 @@
</div>
</div>
</div>
<button *ngIf="candidates" (click)="updateQuery()" class="train-button">Update query</button>
<button *ngIf="candidates" (click)="train()" class="train-button">Train</button>
<div class="button-holder">
<button *ngIf="candidates" (click)="updateQuery()" class="train-button">Query</button>
<button *ngIf="candidates" (click)="train()" class="train-button">Train</button>
</div>
</div>
......@@ -43,7 +43,7 @@ export class LabelingWindowComponent implements OnInit {
}
async getTopKSimilar() {
this.topk = this.service.candidates.slice(0, 20);
this.topk = this.service.candidates.slice(0, 12);
await this.createPlots();
}
......
......@@ -31,11 +31,11 @@
}
.left {
width: 80%;
width: 70%;
}
.right {
width: 20%;
width: 30%;
border-left: groove;
}
......
......@@ -32,6 +32,7 @@ export class OverviewWindowComponent implements OnInit {
}
async initializePlot() {
this.debugClicked();
this.service.queryWindow = undefined;
this.data = [];
for (let i = 0; i < this.service.rawValues.length; i++) {
......@@ -169,7 +170,7 @@ export class OverviewWindowComponent implements OnInit {
x: clickData.x,
y: clickData.y
});
const index = 80503;// Math.floor(xyInformation[0].scalenumvalue / (12000 / 6));
const index = Math.floor(xyInformation[0].scalenumvalue / (12000 / 6));
await this.service.getQueryWindow(index);
await this.service.initial();
// const temp = {};
......@@ -177,6 +178,12 @@ export class OverviewWindowComponent implements OnInit {
// this.service.labels = temp;
}
async debugClicked() {
const index = 80503;// Math.floor(xyInformation[0].scalenumvalue / (12000 / 6));
await this.service.getQueryWindow(index);
await this.service.initial();
}
zoom(p) {
if (!p.ev) {
return;
......
......@@ -17,3 +17,15 @@
display: flex;
justify-content: center;
}
.hide {
display: none;
}
.container {
display: flex;
justify-content: center;
}
line { stroke: #5e4646; }
circle { stroke: #fff; stroke-width: 1.5px; }
<div class="container" *ngIf="data">
<span class="title"><b>Training Progress</b></span>
<svg id="visual" width='500' height='300'></svg>
<div *ngIf="data" class="container">
<div class="window">
<div class="plots">
<plotly-plot [data]="data" [layout]="layout" (sliderChange)="setSliderValue($event)"></plotly-plot>
<plotly-plot *ngFor="let data of this.data; index as i;" [class.hide]="i != sliderValue" [data]="data" [layout]="layout"></plotly-plot>
</div>
</div>
<div class="button-holder">
<button class="show-candidates-button" (click)="showCandidates()">Show all {{ amountOfCandidates }} candidates</button>
</div>
<mat-slider vertical min="0" [max]="maxLength" step="1" [(value)]="sliderValue" thumbLabel tickInterval="5"></mat-slider>
</div>
<style>
line { stroke: #999; }
circle { stroke: #fff; stroke-width: 1.5px; }
</style>
<svg width='960' height='500'></svg>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script>
</script>
......@@ -12,14 +12,15 @@ export class ProgressViewComponent implements OnInit {
public data;
public layout;
public amountOfCandidates;
public hover = 0;
private _sliderValue;
private _sliderValue = 0;
constructor(private cache: CacheService) { }
ngOnInit(): void {
this.showgraph();
this.cache.onNewSimilarity.subscribe(() => { this.initializeInfo(); });
// this.cache.onNewSimilarity.subscribe(() => { this.showgraph(); });
this.cache.onNewTables.subscribe(() => { this.showgraph(); });
}
averagePlot(averages) {
......@@ -121,47 +122,113 @@ export class ProgressViewComponent implements OnInit {
};
}
async initializeInfo(): Promise<void> {
console.log('Updating progress view');
console.log(this.similarity);
const allWindows = [];
const keys = Object.keys(this.similarity);
for (let i = this.cache.nrOfTables; i >= 1; i--) {
if (keys.indexOf(i.toString()) === -1) {
allWindows.push([]);
} else {
allWindows.push(this.similarity[i.toString()]);
}
}
const averages = await this.cache.getAverageProgressWindows(allWindows);
this.plot = this.averagePlot(averages);
let candidates = [];
for (let i = this._sliderValue; i < this.cache.nrOfTables; i++) {
candidates = candidates.concat(this.cache.windowSimilarity[i.toString()]);
}
this.amountOfCandidates = candidates.length;
hoverPlot(averages) {
this.data = averages.map((average, i) => {
return [
{
x: [...Array(average.average.length).keys()],
y: average.average,
type: 'line',
line: {
color: 'red',
width: 3
}
},
{
x: [...Array(average.average.length).keys()],
y: average.max,
type: 'scatter',
fill: null,
mode: 'lines',
line: {
color: 'rgb(55, 128, 191)',
width: 3
}
},
{
x: [...Array(average.average.length).keys()],
y: average.min,
type: 'scatter',
fill: 'tonexty',
mode: 'lines',
line: {
color: 'rgb(55, 128, 191)',
width: 3
}
},
];
});
this.layout = {
showlegend: false,
hovermode: 'closest',
autosize: true,
margin: {
l: 50,
r: 30,
t: 30,
pad: 4
},
xaxis: {
showgrid: false,
zeroline: false,
showticklabels: false,
},
yaxis: {
zeroline: false,
showticklabels: false,
},
height: 300,
width: 300,
};
}
public get similarity() {
return this.cache.windowSimilarity;
public set sliderValue(v: number) {
this._sliderValue = v;
d3.selectAll('circle').transition().style('stroke', undefined);
d3.select('#node-' + v).transition().style('stroke', 'black').style('stroke-width', 20);
}
public setSliderValue(v) {
this._sliderValue = v.slider.active;
let candidates = [];
for (let i = this._sliderValue; i < this.cache.nrOfTables; i++) {
candidates = candidates.concat(this.cache.windowSimilarity[i.toString()]);
}
this.amountOfCandidates = candidates.length;
public get sliderValue(): number {
return this._sliderValue;
}
public showCandidates() {
this.cache.sliderValue = this._sliderValue;
public get maxLength(): number {
return Object.keys(this.similarity).length;
}
public get similarity() {
return this.cache.tables;
}
public showgraph() {
async showgraph() {
const nodes = [];
const links = [];
const temp = (await this.cache.getAverageWindows(Object.values(this.similarity)));
const keys = Object.keys(this.similarity);
console.log(temp);
this.hoverPlot(temp.averages);
const distances = temp.distances;
console.log(this.similarity);
for (const key in this.similarity) {
const size = this.similarity[key].length;
nodes.push({id: key, group: Number(key), size: size});
}
for (const key in this.similarity) {
for (const key2 in this.similarity) {
if (key === key2) {
continue;
}
links.push({source: key, target: key2, value: 0.001 * (100 - 5 * distances[keys.indexOf(key)][keys.indexOf(key2)])});
}
}
const graph = {nodes, links};
console.log(graph);
console.log('building');
const svg = d3.select('svg');
const svg = d3.select('#visual');
const width = +svg.attr('width');
const height = +svg.attr('height');
......@@ -171,52 +238,46 @@ export class ProgressViewComponent implements OnInit {
.force('link', d3.forceLink().id((d: any) => d.id))
.force('charge', d3.forceManyBody().strength(100)) // Gravity force
.force('collide', d3.forceCollide().radius(25).iterations(3)) // Repulsion force
.force('center', d3.forceCenter(width / 2, height / 2));// Position force
d3.json('assets/miserables.json')
.catch((error) => {
throw error;
})
.then((graph) => {
const link = svg.append('g')
.selectAll('line')
.data(graph.links)
.enter().append('line')
.attr('stroke', 'blue')
.attr('fill', 'purple')
.attr('stroke-width', (d: any) => d.value * .08);
const node = svg.append('g')
.selectAll('circle')
.data(graph.nodes)
.enter().append('circle')
.attr('r', 5)
.attr('fill', (d: any) => color(d.group))
.call(d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended));
simulation
.nodes(graph.nodes)
.on('tick', ticked);
simulation.force<any>('link')
.links(graph.links);
function ticked() {
link
.attr('x1', (d: any) => d.source.x)
.attr('y1', (d: any) => d.source.y)
.attr('x2', (d: any) => d.target.x)
.attr('y2', (d: any) => d.target.y);
node
.attr('cx', (d: any) => d.x)
.attr('cy', (d: any) => d.y);
}
.force('center', d3.forceCenter(width / 2, height / 2)); // Position force
});
const link = svg.append('g')
.selectAll('line')
.data(graph.links)
.enter().append('line')
.attr('stroke', 'grey')
.attr('stroke-width', (d: any) => d.value);
const node = svg.append('g')
.selectAll('circle')
.data(graph.nodes)
.enter().append('circle')
.attr('r', (d: any) => 5 * Math.log(d.size) / Math.log(10))
.attr('fill', (d: any) => this.getColor(d.group / graph.nodes.length))
.attr('id', (d: any) => 'node-' + d.group)
.on('mouseover', (d: any) => {this.sliderValue = d.group; })
.call(d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended));
simulation
.nodes(graph.nodes as any)
.on('tick', ticked);
simulation.force<any>('link')
.links(graph.links);
function ticked() {
link
.attr('x1', (d: any) => d.source.x)
.attr('y1', (d: any) => d.source.y)
.attr('x2', (d: any) => d.target.x)
.attr('y2', (d: any) => d.target.y);
node
.attr('cx', (d: any) => d.x)
.attr('cy', (d: any) => d.y);
}
function dragstarted(d) {
if (!d3.event.active) {
......@@ -239,4 +300,8 @@ export class ProgressViewComponent implements OnInit {
d.fy = null;
}
}
getColor(value) {
const hue=((1-value)*120).toString(10);
return ["hsl(",hue,",100%,50%)"].join("");
}
}
......@@ -26,19 +26,19 @@ export class QueryWindowComponent implements OnInit {
y: this.service.queryWindow,
type: 'line'
}];
if (this.service.distances.length !== 0) {
const max = this.service.queryWindow.map((num, idx) => {
return num + this.service.distances[idx];
});
const min = this.service.queryWindow.map((num, idx) => {
return num - this.service.distances[idx];
});
data.push({
x: [...Array(this.service.queryWindow.length).keys()],
y: this.service.distances,
type: 'bar'
});
}
// if (this.service.distances.length !== 0) {
// const max = this.service.queryWindow.map((num, idx) => {
// return num + this.service.distances[idx];
// });
// const min = this.service.queryWindow.map((num, idx) => {
// return num - this.service.distances[idx];
// });
// data.push({
// x: [...Array(this.service.queryWindow.length).keys()],
// y: this.service.distances,
// type: 'bar'
// });
// }
this.plot =
{
data,
......
......@@ -71,43 +71,10 @@ export class TableOverviewComponent implements OnInit {
};
}
calculateSignature(hashFunction, window): string {
const output = new Array(hashFunction[0].length);
output.fill(0);
for (const hash of hashFunction) {
for (let i = 0; i < hash.length; i++) {
output[i] += window[i] * hash[i];
}
}
return output.map((x) => x > 0 ? '1' : '0').join('');
}
distanceMetric(hash) {
let sum = 0;
for (let i = 0; i < hash.length; i++) {
if (hash[i] === '1') {
sum++;
}
}
return sum;
}
async createPlots() {
this.subplots = [];
this.averages = [];
let nrOfBuckets = Math.ceil(Math.max(...this.service.dtwdistances) / 50);
const indices = this.service.dtwdistances.map((x) => x > 500 ? 20 : Math.floor(x / 20));
console.log(indices);
const table = {};
this.service.candidates.forEach((candidate, index) => {
if (table[indices[index]] === undefined)
{
console.log('test');
table[indices[index]] = [];
}
table[indices[index]].push(candidate);
});
console.log(table);