import {Component, OnInit, ViewChild} from '@angular/core'; import {StateService} from '../state.service'; import * as d3 from 'd3'; @Component({ selector: 'app-progress-view', templateUrl: './progress-view.component.html', styleUrls: ['./progress-view.component.css'] }) export class ProgressViewComponent implements OnInit { @ViewChild('chart') chart; public plot; public data; public layout; public hist; public amountOfCandidates; public hover = 0; private _sliderValue = 0; constructor(private state: StateService) { } ngOnInit(): void { this.state.onNewTableInfo.subscribe(() => { this.showgraph(); }); this.state.onNewTableInfo.subscribe(() => { this.showHistogram(); }); } showHistogram() { const table = this.state._averageTable; this.hist = { data: [{ x: Object.keys(table), y: Object.values(table).map((values: number[]) => values.length), // / (this.service.rawValues.length - this.service.windowSize)), type: 'bar', opacity: 0.5, marker: { color: Object.keys(table).map((key) => { return this.getColor(Number(key) / Number(Object.keys(table)[Object.keys(table).length - 1])); }), line: { color: 'black', width: 0, } } }], layout: { hovermode: 'closest', autosize: true, margin: { l: 10, r: 10, t: 10, b: 10, pad: 4 }, xaxis: { showticklabels: false }, yaxis: { showticklabels: false }, height: 200, width: 400, } }; } onHover(data) { console.log(data); this.setSliderValue({value: data.points[0].x}); } hoverPlot(averages) { const subplots = []; this.data = averages.map((prototype) => { const channelData = []; prototype.max.forEach((channel, index) => { channelData.push({ x: [...Array(channel.length).keys()], y: channel, xaxis: 'x', yaxis: `y${index + 2}`, type: 'scatter', fill: null, mode: 'lines', line: { color: 'rgb(55, 128, 191)', width: 3 } }); }); prototype.min.forEach((channel, index) => { channelData.push({ x: [...Array(channel.length).keys()], y: channel, xaxis: 'x', yaxis: `y${index + 2}`, type: 'scatter', fill: 'tonexty', mode: 'lines', line: { color: 'rgb(55, 128, 191)', width: 3 } }); }); prototype.average.forEach((channel, index) => { channelData.push({ x: [...Array(channel.length).keys()], y: channel, xaxis: 'x', yaxis: `y${index + 2}`, type: 'line', line: { color: 'red', width: 3 } }); }); return channelData; }); for (let index = 0; index < this.state.queryWindow.length; index++) { subplots.push([`xy${index + 2}`]); } this.layout = { grid: { rows: this.state.queryWindow.length, columns: 1, subplots: subplots, }, 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: 350, width: 400, }; this.state.queryWindow.forEach((channel: number[], index: number) => { this.layout[`yaxis${index + 2}`] = { zeroline: false, showticklabels: false, }; }); } public setSliderValue(v) { this._sliderValue = v.value; d3.selectAll('circle').transition().style('stroke', undefined); d3.select('#node-' + v.value).transition().style('stroke', 'black').style('stroke-width', 20); const data = this.hist; data.data[0].marker.line.width = Object.keys(this.state._averageTable).map((key) => { return Number(key) === v.value ? 4 : 0; }); this.hist = data; } public get sliderValue(): number { return this._sliderValue; } public get maxLength(): number { return Object.keys(this.table).length - 1; } public get table() { return this.state._averageTable; } async showgraph() { const nodes = []; const links = []; const keys = Object.keys(this.table); this.hoverPlot(this.state.tableInfo.prototypes); const distances = this.state.tableInfo.distances; // for (const key in this.table) { // const size = this.table[key].length; // nodes.push({id: key, group: Number(key), size: size}); // } // for (const key in this.table) { // for (const key2 in this.table) { // 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}; // // const svg = d3.select('#visual'); // const width = +svg.attr('width'); // const height = +svg.attr('height'); // // svg.selectAll('*').remove(); // // const simulation = d3.forceSimulation() // .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 // // 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('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) { // simulation.alphaTarget(0.1).restart(); // } // d.fx = d.x; // d.fy = d.y; // } // // function dragged(d) { // d.fx = d3.event.x; // d.fy = d3.event.y; // } // // function dragended(d) { // if (!d3.event.active) { // simulation.alphaTarget(0); // } // d.fx = null; // d.fy = null; // } } getColor(value) { const hue=((1-value)*120).toString(10); return ["hsl(",hue,",100%,50%)"].join(""); } }