charting, routing and stats

This commit is contained in:
Ben Wilson
2023-06-22 09:06:39 -04:00
parent f547adb550
commit b9337ae636
19 changed files with 443 additions and 22 deletions
@@ -1,5 +1,32 @@
<div class="card">
<pre>
{{clientInfo$ | async | json}}
</pre>
</div>
<ng-container *ngIf="clientInfo$ | async as clientInfo">
<div class="card">
<p-table [rowHover]="true" [value]="clientInfo.workers" [tableStyle]="{ 'min-width': '50rem' }">
<ng-template pTemplate="header">
<tr>
<th>Name</th>
<th>ID</th>
<th>Hash Rate</th>
<th>Best Luck</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-worker>
<tr [routerLink]="[worker.id]">
<td>{{worker.name}}</td>
<td>{{worker.id}}</td>
<td>{{worker.hashRate}}</td>
<td>{{worker.bestDifficulty}}</td>
</tr>
</ng-template>
</p-table>
</div>
</ng-container>
@@ -11,9 +11,13 @@ import { ClientService } from '../../services/client.service';
})
export class DashboardComponent {
public clientInfo$: Observable<any>;
constructor(private clientService: ClientService, private route: ActivatedRoute) {
this.clientInfo$ = this.clientService.getClientInfo(this.route.snapshot.params['address']);
}
}
@@ -0,0 +1,75 @@
<div class="grid">
<ng-container *ngIf="workerInfo$ | async as workerInfo">
<div class="col-12 lg:col-6 xl:col-3">
<div class="card mb-0">
<div class="flex justify-content-between mb-3">
<div>
<span class="block text-500 font-medium mb-3">ID</span>
<div class="text-900 font-medium text-xl">{{workerInfo.name}}</div>
</div>
<div class="flex align-items-center justify-content-center bg-blue-100 border-round"
[ngStyle]="{width: '2.5rem', height: '2.5rem'}">
<i class="pi pi-id-card text-blue-500 text-xl"></i>
</div>
</div>
<!-- <span class="text-green-500 font-medium">24 new </span> -->
<span class="text-500">{{workerInfo.id}}</span>
</div>
</div>
<div class="col-12 lg:col-6 xl:col-3">
<div class="card mb-0">
<div class="flex justify-content-between mb-3">
<div>
<span class="block text-500 font-medium mb-3">Best Luck</span>
<div class="text-900 font-medium text-xl">{{workerInfo.bestDifficulty | numberSuffix}}
</div>
</div>
<div class="flex align-items-center justify-content-center bg-orange-100 border-round"
[ngStyle]="{width: '2.5rem', height: '2.5rem'}">
<i class="pi pi-star text-orange-500 text-xl"></i>
</div>
</div>
<span class="text-green-500 font-medium">{{workerInfo.bestDifficulty | number}}</span>
</div>
</div>
<!-- <div class="col-12 lg:col-6 xl:col-3">
<div class="card mb-0">
<div class="flex justify-content-between mb-3">
<div>
<span class="block text-500 font-medium mb-3">Customers</span>
<div class="text-900 font-medium text-xl">28441</div>
</div>
<div class="flex align-items-center justify-content-center bg-cyan-100 border-round"
[ngStyle]="{width: '2.5rem', height: '2.5rem'}">
<i class="pi pi-inbox text-cyan-500 text-xl"></i>
</div>
</div>
<span class="text-green-500 font-medium">520 </span>
<span class="text-500">newly registered</span>
</div>
</div>
<div class="col-12 lg:col-6 xl:col-3">
<div class="card mb-0">
<div class="flex justify-content-between mb-3">
<div>
<span class="block text-500 font-medium mb-3">Comments</span>
<div class="text-900 font-medium text-xl">152 Unread</div>
</div>
<div class="flex align-items-center justify-content-center bg-purple-100 border-round"
[ngStyle]="{width: '2.5rem', height: '2.5rem'}">
<i class="pi pi-comment text-purple-500 text-xl"></i>
</div>
</div>
<span class="text-green-500 font-medium">85 </span>
<span class="text-500">responded</span>
</div>
</div> -->
</ng-container>
<div class="col-12" *ngIf="chartData$ | async as chartData">
<div class="card">
<p-chart type="line" [data]="chartData" [options]="chartOptions"></p-chart>
</div>
</div>
</div>
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { WorkerComponent } from './worker.component';
describe('WorkerComponent', () => {
let component: WorkerComponent;
let fixture: ComponentFixture<WorkerComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ WorkerComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(WorkerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,121 @@
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { map, Observable, shareReplay } from 'rxjs';
import { WorkerService } from '../../services/worker.service';
@Component({
selector: 'app-worker',
templateUrl: './worker.component.html',
styleUrls: ['./worker.component.scss']
})
export class WorkerComponent {
public workerInfo$: Observable<any>;
public chartData$: Observable<any>;
public chartOptions: any;
constructor(private workerService: WorkerService, private route: ActivatedRoute) {
const documentStyle = getComputedStyle(document.documentElement);
const textColor = documentStyle.getPropertyValue('--text-color');
const textColorSecondary = documentStyle.getPropertyValue('--text-color-secondary');
const surfaceBorder = documentStyle.getPropertyValue('--surface-border');
this.workerInfo$ = this.workerService.getWorkerInfo(this.route.snapshot.params['address'], this.route.snapshot.params['workerId']).pipe(
shareReplay({ bufferSize: 1, refCount: true })
)
this.chartData$ = this.workerInfo$.pipe(
map((workerInfo: any) => {
const GROUP_SIZE = 20;
const slice = workerInfo.hashData.length % GROUP_SIZE == 0 ? workerInfo.hashData : workerInfo.hashData.slice(0, workerInfo.hashData.length - workerInfo.hashData.length % GROUP_SIZE)
const reducedData = ((slice as any[])
.reduce((pre, cur, idx, arr) => {
if (idx % GROUP_SIZE != 0) {
pre[pre.length - 1].difficulty += cur.difficulty;
} else {
pre.push(cur);
}
return pre;
}, []) as any[]);
const labels = reducedData.reduce((pre, cur, idx, arr) => {
if (idx == 0) {
return pre;
}
pre.push(new Date(cur.time));
return pre;
}, []);
const data = reducedData
.reduce((pre, cur, idx, arr) => {
if (idx == 0) {
return pre;
}
//hashrate = (nonce_difficulty * 2^32) / time_to_find
pre.push((cur.difficulty * 4294967296 / (new Date(cur.time).getTime() - new Date(arr[idx - 1].time).getTime())) / 1000000);
return pre;
}, []);
return {
labels,
datasets: [
{
label: workerInfo.name,
data,
fill: false,
backgroundColor: documentStyle.getPropertyValue('--bluegray-700'),
borderColor: documentStyle.getPropertyValue('--bluegray-700'),
tension: .4
}
]
}
})
);
this.chartOptions = {
plugins: {
legend: {
labels: {
color: textColor
}
}
},
scales: {
x: {
type: 'time',
time: {
unit: 'minute', // Set the unit to 'minute'
stepSize: 10, // Set the desired interval between labels in minutes
},
ticks: {
color: textColorSecondary
},
grid: {
color: surfaceBorder,
drawBorder: false
}
},
y: {
ticks: {
color: textColorSecondary,
callback: (value: number) => value + 'GH/s',
},
grid: {
color: surfaceBorder,
drawBorder: false
}
}
}
};
}
}