diff options
author | Danijel Andjelkovic <adanijel99@gmail.com> | 2022-05-05 00:46:39 +0000 |
---|---|---|
committer | Danijel Andjelkovic <adanijel99@gmail.com> | 2022-05-05 00:46:39 +0000 |
commit | c77c5289d01f1f02a57a060dc2166b449e597881 (patch) | |
tree | cb64f2775335cdd856e81ec9e8ba0bed93fa0985 /frontend/src/app/_elements/graph | |
parent | 6f48458e058d3e5a8d559adc22adbe78cba9a253 (diff) | |
parent | 15c60cb0c179d2d3c353ab3e19370e16d02176eb (diff) |
Merge branch 'redesign' into 'master'
merge
See merge request igrannonica/neuronstellar!29
Diffstat (limited to 'frontend/src/app/_elements/graph')
-rw-r--r-- | frontend/src/app/_elements/graph/graph.component.css | 20 | ||||
-rw-r--r-- | frontend/src/app/_elements/graph/graph.component.html | 9 | ||||
-rw-r--r-- | frontend/src/app/_elements/graph/graph.component.ts | 85 |
3 files changed, 81 insertions, 33 deletions
diff --git a/frontend/src/app/_elements/graph/graph.component.css b/frontend/src/app/_elements/graph/graph.component.css index e69de29b..456a8df1 100644 --- a/frontend/src/app/_elements/graph/graph.component.css +++ b/frontend/src/app/_elements/graph/graph.component.css @@ -0,0 +1,20 @@ +.node-text { + position: absolute; + width: 100px; + height: 40px; + text-align: center; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + /*border: 1px solid red;*/ + transform: translate(-50%, -50%); +} + +.node-text:not(.inputs) { + color: transparent; +} + +.node-text:not(.inputs):hover { + color: var(--offwhite); +}
\ No newline at end of file diff --git a/frontend/src/app/_elements/graph/graph.component.html b/frontend/src/app/_elements/graph/graph.component.html index 1c21fb6c..35753d40 100644 --- a/frontend/src/app/_elements/graph/graph.component.html +++ b/frontend/src/app/_elements/graph/graph.component.html @@ -1,3 +1,8 @@ -<div #graphWrapper class="w-100" style="height: 16rem;"> - <canvas #graphCanvas class="border"></canvas> +<div #graphWrapper class="w-100 position-relative" style="height: 14rem;"> + <!-- <ng-container *ngFor="let layer of layers; let i = index"> + <div [ngClass]="{'inputs': i==0}" class="node-text" *ngFor="let node of layer; let j = index" [style.left.%]="node.x * 99.4" [style.top.%]="node.y * 100"> + {{ i == 0 ? (inputColumns && inputColumns.length >= j ? inputColumns[j] : 'nepoznato') : (i > 0 && i + < layers.length - 1 ? model!.layers[i-1].activationFunction : (i==layers.length - 1 ? 'out' : '')) }} </div> + </ng-container> --> + <canvas #graphCanvas></canvas> </div>
\ No newline at end of file diff --git a/frontend/src/app/_elements/graph/graph.component.ts b/frontend/src/app/_elements/graph/graph.component.ts index 8051acc3..da2c7767 100644 --- a/frontend/src/app/_elements/graph/graph.component.ts +++ b/frontend/src/app/_elements/graph/graph.component.ts @@ -1,6 +1,7 @@ import { AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; -import Dataset from 'src/app/_data/Dataset'; -import Model from 'src/app/_data/Model'; +import { RgbColor } from '@syncfusion/ej2-angular-heatmap'; +import Dataset, { ColumnInfo } from 'src/app/_data/Dataset'; +import Model, { Layer } from 'src/app/_data/Model'; @Component({ selector: 'app-graph', @@ -15,17 +16,19 @@ export class GraphComponent implements AfterViewInit { canvas!: ElementRef; @Input() model?: Model; - @Input() inputCols: number = 1; + //@Input() inputCols: number = 1; @Input() lineThickness: number = 2; @Input() nodeRadius: number = 15; - @Input() lineColor: string = '#00a8e8'; + @Input() lineColor1: RgbColor = new RgbColor(0, 168, 232); + @Input() lineColor2: RgbColor = new RgbColor(0, 70, 151); @Input() nodeColor: string = '#222277'; @Input() borderColor: string = '#00a8e8'; - @Input() inputNodeColor: string = '#ffdd11'; - @Input() outputNodeColor: string = '#44ee22'; + @Input() inputNodeColor: string = '#00a8e8'; + @Input() outputNodeColor: string = '#dfd7d7'; - private ctx?: CanvasRenderingContext2D; + private ctx!: CanvasRenderingContext2D; + @Input() inputColumns?: string[]; constructor() { } @@ -40,18 +43,19 @@ export class GraphComponent implements AfterViewInit { window.addEventListener('resize', () => { this.resize() }); this.update(); this.resize(); + //console.log(this.layers); } - layers?: Node[][]; + layers: Node[][] = []; update() { - this.layers = []; + this.layers.length = 0; let inputNodeIndex = 0; const inputLayer: Node[] = []; - while (inputNodeIndex < this.inputCols) { + while (this.inputColumns && inputNodeIndex < this.inputColumns.length) { const x = 0.5 / (this.model!.hiddenLayers + 2); - const y = (inputNodeIndex + 0.5) / this.inputCols; + const y = (inputNodeIndex + 0.5) / this.inputColumns.length; const node = new Node(x, y, this.inputNodeColor); inputLayer.push(node); inputNodeIndex += 1; @@ -62,9 +66,9 @@ export class GraphComponent implements AfterViewInit { while (layerIndex < this.model!.hiddenLayers + 1) { const newLayer: Node[] = []; let nodeIndex = 0; - while (nodeIndex < this.model!.hiddenLayerNeurons) { + while (nodeIndex < this.model!.layers[layerIndex - 1].neurons) { const x = (layerIndex + 0.5) / (this.model!.hiddenLayers + 2); - const y = (nodeIndex + 0.5) / this.model!.hiddenLayerNeurons; + const y = (nodeIndex + 0.5) / this.model!.layers[layerIndex - 1].neurons; const node = new Node(x, y, this.nodeColor); newLayer.push(node); nodeIndex += 1; @@ -80,7 +84,7 @@ export class GraphComponent implements AfterViewInit { } draw() { - this.ctx!.clearRect(0, 0, this.canvas.nativeElement.width, this.canvas.nativeElement.height); + this.ctx.clearRect(0, 0, this.canvas.nativeElement.width, this.canvas.nativeElement.height); let index = 0; while (index < this.layers!.length - 1) { @@ -93,29 +97,38 @@ export class GraphComponent implements AfterViewInit { } for (let layer of this.layers!) { - for (let node of layer) { - this.drawNode(node); - } + layer.forEach((node, index) => { + this.drawNode(node, 0.5 / layer.length + 0.5); + }); } } + bezierOffset = 5; + drawLine(node1: Node, node2: Node) { - this.ctx!.strokeStyle = this.lineColor; - this.ctx!.lineWidth = this.lineThickness; - this.ctx!.beginPath(); - this.ctx!.moveTo(node1.x * this.width, node1.y * this.height); - this.ctx!.lineTo(node2.x * this.width, node2.y * this.height); - this.ctx!.stroke(); + const lineColor: RgbColor = this.lerpColor(this.lineColor1, this.lineColor2, node1.y); + this.ctx.strokeStyle = `rgb(${lineColor.R}, ${lineColor.G}, ${lineColor.B})`; + this.ctx.lineWidth = this.lineThickness; + this.ctx.beginPath(); + this.ctx.moveTo(node1.x * this.width, node1.y * this.height); + //this.ctx.lineTo(node2.x * this.width, node2.y * this.height); + const middle = (node1.x + (node2.x - node1.x) / 2) * this.width; + this.ctx.bezierCurveTo( + middle, node1.y * this.height, + middle, node2.y * this.height, + node2.x * this.width, node2.y * this.height); + this.ctx.stroke(); } - drawNode(node: Node) { - this.ctx!.fillStyle = node.color; - this.ctx!.strokeStyle = this.borderColor; - this.ctx!.lineWidth = this.lineThickness; - this.ctx!.beginPath(); - this.ctx!.arc(node.x * this.width, node.y * this.height, this.nodeRadius, 0, 2 * Math.PI); - this.ctx!.fill(); - this.ctx!.stroke(); + drawNode(node: Node, sizeMult: number) { + const lineColor: RgbColor = this.lerpColor(this.lineColor1, this.lineColor2, node.y); + this.ctx.strokeStyle = `rgb(${lineColor.R}, ${lineColor.G}, ${lineColor.B})`; + this.ctx.fillStyle = node.color; + this.ctx.lineWidth = this.lineThickness; + this.ctx.beginPath(); + this.ctx.arc(node.x * this.width, node.y * this.height, this.nodeRadius * sizeMult, 0, 2 * Math.PI); + this.ctx.fill(); + this.ctx.stroke(); } width = 200; @@ -134,6 +147,16 @@ export class GraphComponent implements AfterViewInit { this.draw(); } + + lerpColor(value1: RgbColor, value2: RgbColor, amount: number): RgbColor { + const newColor = new RgbColor(0, 0, 0); + amount = amount < 0 ? 0 : amount; + amount = amount > 1 ? 1 : amount; + newColor.R = value1.R + (value2.R - value1.R) * amount; + newColor.G = value1.G + (value2.G - value1.G) * amount; + newColor.B = value1.B + (value2.B - value1.B) * amount; + return newColor; + }; } class Node { |