mirror of
https://github.com/octoleo/syncthing.git
synced 2025-03-21 10:12:21 +00:00
start of chart component
This commit is contained in:
parent
ad2902b3ee
commit
82f5706350
35
package-lock.json
generated
35
package-lock.json
generated
@ -2776,6 +2776,32 @@
|
|||||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
|
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"chart.js": {
|
||||||
|
"version": "2.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.3.tgz",
|
||||||
|
"integrity": "sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw==",
|
||||||
|
"requires": {
|
||||||
|
"chartjs-color": "^2.1.0",
|
||||||
|
"moment": "^2.10.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chartjs-color": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
|
||||||
|
"requires": {
|
||||||
|
"chartjs-color-string": "^0.6.0",
|
||||||
|
"color-convert": "^1.9.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chartjs-color-string": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
|
||||||
|
"requires": {
|
||||||
|
"color-name": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz",
|
||||||
@ -3040,7 +3066,6 @@
|
|||||||
"version": "1.9.3",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"color-name": "1.1.3"
|
"color-name": "1.1.3"
|
||||||
}
|
}
|
||||||
@ -3048,8 +3073,7 @@
|
|||||||
"color-name": {
|
"color-name": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"color-string": {
|
"color-string": {
|
||||||
"version": "1.5.3",
|
"version": "1.5.3",
|
||||||
@ -8083,6 +8107,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.24.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
|
||||||
|
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
|
||||||
|
},
|
||||||
"move-concurrently": {
|
"move-concurrently": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
"@angular/platform-browser-dynamic": "~9.0.5",
|
"@angular/platform-browser-dynamic": "~9.0.5",
|
||||||
"@angular/router": "~9.0.5",
|
"@angular/router": "~9.0.5",
|
||||||
"angular-in-memory-web-api": "^0.10.0",
|
"angular-in-memory-web-api": "^0.10.0",
|
||||||
|
"chart.js": "^2.9.3",
|
||||||
"component": "^1.1.0",
|
"component": "^1.1.0",
|
||||||
"rxjs": "~6.5.4",
|
"rxjs": "~6.5.4",
|
||||||
"tslib": "^1.10.0",
|
"tslib": "^1.10.0",
|
||||||
|
@ -21,6 +21,7 @@ import { environment } from '../environments/environment';
|
|||||||
import { DashboardComponent } from './dashboard/dashboard.component';
|
import { DashboardComponent } from './dashboard/dashboard.component';
|
||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||||
|
import { DonutChartComponent } from './donut-chart/donut-chart.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -30,6 +31,7 @@ import { FlexLayoutModule } from '@angular/flex-layout';
|
|||||||
DeviceListComponent,
|
DeviceListComponent,
|
||||||
StatusToggleComponent,
|
StatusToggleComponent,
|
||||||
DashboardComponent,
|
DashboardComponent,
|
||||||
|
DonutChartComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -6,13 +6,17 @@
|
|||||||
<div gdArea="folders">
|
<div gdArea="folders">
|
||||||
<mat-card>
|
<mat-card>
|
||||||
<mat-card-title>Folders</mat-card-title>
|
<mat-card-title>Folders</mat-card-title>
|
||||||
<mat-card-content></mat-card-content>
|
<mat-card-content>
|
||||||
|
<app-donut-chart [elementID]="foldersChart"></app-donut-chart>
|
||||||
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
<div gdArea="devices">
|
<div gdArea="devices">
|
||||||
<mat-card>
|
<mat-card>
|
||||||
<mat-card-title>Devices</mat-card-title>
|
<mat-card-title>Devices</mat-card-title>
|
||||||
<mat-card-content></mat-card-content>
|
<mat-card-content>
|
||||||
|
<app-donut-chart [elementID]="devicesChart"></app-donut-chart>
|
||||||
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
<app-status-list gdArea="status-list"></app-status-list>
|
<app-status-list gdArea="status-list"></app-status-list>
|
||||||
|
@ -7,6 +7,9 @@ import { SystemConfigService } from '../system-config.service';
|
|||||||
styleUrls: ['./dashboard.component.scss']
|
styleUrls: ['./dashboard.component.scss']
|
||||||
})
|
})
|
||||||
export class DashboardComponent {
|
export class DashboardComponent {
|
||||||
|
foldersChart = 'foldersChart';
|
||||||
|
devicesChart = 'devicesChart';
|
||||||
|
|
||||||
constructor(private systemConfigService: SystemConfigService) { }
|
constructor(private systemConfigService: SystemConfigService) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
1
src/app/donut-chart/donut-chart.component.html
Normal file
1
src/app/donut-chart/donut-chart.component.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<canvas id={{elementID}} width="200%" height="100%"></canvas>
|
0
src/app/donut-chart/donut-chart.component.scss
Normal file
0
src/app/donut-chart/donut-chart.component.scss
Normal file
25
src/app/donut-chart/donut-chart.component.spec.ts
Normal file
25
src/app/donut-chart/donut-chart.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DonutChartComponent } from './donut-chart.component';
|
||||||
|
|
||||||
|
describe('DonutChartComponent', () => {
|
||||||
|
let component: DonutChartComponent;
|
||||||
|
let fixture: ComponentFixture<DonutChartComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ DonutChartComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(DonutChartComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
48
src/app/donut-chart/donut-chart.component.ts
Normal file
48
src/app/donut-chart/donut-chart.component.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { Component, OnInit, AfterViewInit, Input } from '@angular/core';
|
||||||
|
import { Chart } from 'chart.js'
|
||||||
|
import { flatMap } from 'rxjs/operators';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-donut-chart',
|
||||||
|
templateUrl: './donut-chart.component.html',
|
||||||
|
styleUrls: ['./donut-chart.component.scss']
|
||||||
|
})
|
||||||
|
export class DonutChartComponent implements OnInit {
|
||||||
|
@Input() elementID: string;
|
||||||
|
|
||||||
|
private canvas: any;
|
||||||
|
private ctx: any;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
console.log("elementID?", this.elementID)
|
||||||
|
this.canvas = document.getElementById(this.elementID);
|
||||||
|
this.ctx = this.canvas.getContext('2d');
|
||||||
|
const myChart = new Chart(this.ctx, {
|
||||||
|
type: 'doughnut',
|
||||||
|
data: {
|
||||||
|
labels: ["Up to Date", "Syncing", "Waiting to Sync", "Out of Sync", "Failed Items"],
|
||||||
|
datasets: [{
|
||||||
|
data: [1, 2, 3, 0, 0],
|
||||||
|
backgroundColor: [
|
||||||
|
'#56C568',
|
||||||
|
'rgba(54, 162, 235, 1)',
|
||||||
|
'rgba(255, 206, 86, 1)'
|
||||||
|
],
|
||||||
|
borderWidth: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: false,
|
||||||
|
display: false,
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@ export class SystemConfigService {
|
|||||||
private systemConfigUrl = environment.production ? apiURL + 'rest/system/config' : 'api/config';
|
private systemConfigUrl = environment.production ? apiURL + 'rest/system/config' : 'api/config';
|
||||||
private httpOptions;
|
private httpOptions;
|
||||||
|
|
||||||
private checkInterval: number = 200;
|
private checkInterval: number = 500;
|
||||||
|
|
||||||
constructor(private http: HttpClient, private cookieService: CookieService) {
|
constructor(private http: HttpClient, private cookieService: CookieService) {
|
||||||
this.httpOptions = { headers: new HttpHeaders(this.cookieService.getCSRFHeader()) };
|
this.httpOptions = { headers: new HttpHeaders(this.cookieService.getCSRFHeader()) };
|
||||||
@ -52,19 +52,11 @@ export class SystemConfigService {
|
|||||||
observer.next(this.folders);
|
observer.next(this.folders);
|
||||||
} else {
|
} else {
|
||||||
// create timer to keep checking for folders
|
// create timer to keep checking for folders
|
||||||
let check = (): Boolean => {
|
|
||||||
if (this.folders) {
|
|
||||||
observer.next(this.folders);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
let t = setInterval(() => {
|
let t = setInterval(() => {
|
||||||
if (check())
|
if (check(this.folders))
|
||||||
clearInterval(t);
|
clearInterval(t);
|
||||||
|
observer.next(this.folders);
|
||||||
}, this.checkInterval);
|
}, this.checkInterval);
|
||||||
|
|
||||||
check(); // try right away
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return folderObservable;
|
return folderObservable;
|
||||||
@ -75,22 +67,21 @@ export class SystemConfigService {
|
|||||||
if (this.folders) {
|
if (this.folders) {
|
||||||
observer.next(this.devices);
|
observer.next(this.devices);
|
||||||
} else {
|
} else {
|
||||||
// create timer to keep checking for devices
|
|
||||||
let check = (): Boolean => {
|
|
||||||
if (this.devices) {
|
|
||||||
observer.next(this.devices);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
let t = setInterval(() => {
|
let t = setInterval(() => {
|
||||||
if (check())
|
if (check(this.devices)) {
|
||||||
clearInterval(t);
|
clearInterval(t);
|
||||||
|
observer.next(this.devices);
|
||||||
|
}
|
||||||
}, this.checkInterval);
|
}, this.checkInterval);
|
||||||
|
|
||||||
check() // try right away
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return deviceObserverable;
|
return deviceObserverable;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const check = (target: any): Boolean => {
|
||||||
|
if (target) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user