From fe2cc875f098e33eacfda25eb8bcaa1c7cb5e037 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:42:34 +0100 Subject: [PATCH 01/40] add component "dashboard" --- src/app/app.module.ts | 4 ++- src/app/dashboard/dashboard.component.css | 0 src/app/dashboard/dashboard.component.html | 1 + src/app/dashboard/dashboard.component.spec.ts | 25 +++++++++++++++++++ src/app/dashboard/dashboard.component.ts | 15 +++++++++++ 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/app/dashboard/dashboard.component.css create mode 100644 src/app/dashboard/dashboard.component.html create mode 100644 src/app/dashboard/dashboard.component.spec.ts create mode 100644 src/app/dashboard/dashboard.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f7197b8..5f6063d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -12,6 +12,7 @@ import { SocketIoConfig, SocketIoModule } from 'ngx-socket-io'; import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from 'src/routes'; import { NotFoundComponent } from './not-found/not-found.component'; +import { DashboardComponent } from './dashboard/dashboard.component'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -22,7 +23,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; PaymentComponent, PayComponent, HelloComponent, - NotFoundComponent + NotFoundComponent, + DashboardComponent ], imports: [ BrowserModule, diff --git a/src/app/dashboard/dashboard.component.css b/src/app/dashboard/dashboard.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html new file mode 100644 index 0000000..9c5fce9 --- /dev/null +++ b/src/app/dashboard/dashboard.component.html @@ -0,0 +1 @@ +

dashboard works!

diff --git a/src/app/dashboard/dashboard.component.spec.ts b/src/app/dashboard/dashboard.component.spec.ts new file mode 100644 index 0000000..5ec4ff8 --- /dev/null +++ b/src/app/dashboard/dashboard.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DashboardComponent } from './dashboard.component'; + +describe('DashboardComponent', () => { + let component: DashboardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ DashboardComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts new file mode 100644 index 0000000..38138a3 --- /dev/null +++ b/src/app/dashboard/dashboard.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: ['./dashboard.component.css'] +}) +export class DashboardComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} From c6e798716f923e5b652deae07a39523c86ca33bb Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:42:34 +0100 Subject: [PATCH 02/40] merge master --- src/app/app.module.ts | 4 ++- src/app/dashboard/dashboard.component.css | 0 src/app/dashboard/dashboard.component.html | 1 + src/app/dashboard/dashboard.component.spec.ts | 25 +++++++++++++++++++ src/app/dashboard/dashboard.component.ts | 15 +++++++++++ 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/app/dashboard/dashboard.component.css create mode 100644 src/app/dashboard/dashboard.component.html create mode 100644 src/app/dashboard/dashboard.component.spec.ts create mode 100644 src/app/dashboard/dashboard.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 06874cd..f14ccd9 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -13,6 +13,7 @@ import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from 'src/routes'; import { NotFoundComponent } from './not-found/not-found.component'; import { CartComponent } from './cart/cart.component'; +import { DashboardComponent } from './dashboard/dashboard.component'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -24,7 +25,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; PayComponent, HelloComponent, NotFoundComponent, - CartComponent + CartComponent, + DashboardComponent ], imports: [ BrowserModule, diff --git a/src/app/dashboard/dashboard.component.css b/src/app/dashboard/dashboard.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html new file mode 100644 index 0000000..9c5fce9 --- /dev/null +++ b/src/app/dashboard/dashboard.component.html @@ -0,0 +1 @@ +

dashboard works!

diff --git a/src/app/dashboard/dashboard.component.spec.ts b/src/app/dashboard/dashboard.component.spec.ts new file mode 100644 index 0000000..5ec4ff8 --- /dev/null +++ b/src/app/dashboard/dashboard.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DashboardComponent } from './dashboard.component'; + +describe('DashboardComponent', () => { + let component: DashboardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ DashboardComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts new file mode 100644 index 0000000..38138a3 --- /dev/null +++ b/src/app/dashboard/dashboard.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: ['./dashboard.component.css'] +}) +export class DashboardComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} From 41d5f95810a69cac766cd99093f6a88ca0ac2ed2 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:57:43 +0100 Subject: [PATCH 03/40] add login subcomponent --- src/app/app.module.ts | 4 ++- src/app/dashboard/login/login.component.css | 0 src/app/dashboard/login/login.component.html | 1 + .../dashboard/login/login.component.spec.ts | 25 +++++++++++++++++++ src/app/dashboard/login/login.component.ts | 15 +++++++++++ 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/app/dashboard/login/login.component.css create mode 100644 src/app/dashboard/login/login.component.html create mode 100644 src/app/dashboard/login/login.component.spec.ts create mode 100644 src/app/dashboard/login/login.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f14ccd9..bd2a24a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -14,6 +14,7 @@ import { AppRoutingModule } from 'src/routes'; import { NotFoundComponent } from './not-found/not-found.component'; import { CartComponent } from './cart/cart.component'; import { DashboardComponent } from './dashboard/dashboard.component'; +import { LoginComponent } from './dashboard/login/login.component'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -26,7 +27,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; HelloComponent, NotFoundComponent, CartComponent, - DashboardComponent + DashboardComponent, + LoginComponent ], imports: [ BrowserModule, diff --git a/src/app/dashboard/login/login.component.css b/src/app/dashboard/login/login.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/login/login.component.html b/src/app/dashboard/login/login.component.html new file mode 100644 index 0000000..147cfc4 --- /dev/null +++ b/src/app/dashboard/login/login.component.html @@ -0,0 +1 @@ +

login works!

diff --git a/src/app/dashboard/login/login.component.spec.ts b/src/app/dashboard/login/login.component.spec.ts new file mode 100644 index 0000000..d2c0e6c --- /dev/null +++ b/src/app/dashboard/login/login.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LoginComponent } from './login.component'; + +describe('LoginComponent', () => { + let component: LoginComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LoginComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts new file mode 100644 index 0000000..4f58421 --- /dev/null +++ b/src/app/dashboard/login/login.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.css'] +}) +export class LoginComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} From 976e3aa797cd90e18027f30d63861178b85b07c4 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 18:55:26 +0100 Subject: [PATCH 04/40] add login with dummy Data add login page add subcomponents --- src/app/app.module.ts | 8 +- src/app/dashboard.service.spec.ts | 16 +++ src/app/dashboard.service.ts | 28 ++++ src/app/dashboard/dashboard.component.html | 3 +- src/app/dashboard/dashboard.component.ts | 3 +- src/app/dashboard/header/header.component.css | 10 ++ .../dashboard/header/header.component.html | 3 + .../dashboard/header/header.component.spec.ts | 25 ++++ src/app/dashboard/header/header.component.ts | 20 +++ src/app/dashboard/login/login.component.css | 133 ++++++++++++++++++ src/app/dashboard/login/login.component.html | 11 +- src/app/dashboard/login/login.component.ts | 22 ++- .../dashboard/overview/overview.component.css | 0 .../overview/overview.component.html | 1 + .../overview/overview.component.spec.ts | 25 ++++ .../dashboard/overview/overview.component.ts | 15 ++ src/assets/history.svg | 1 + src/routes.ts | 11 ++ 18 files changed, 329 insertions(+), 6 deletions(-) create mode 100644 src/app/dashboard.service.spec.ts create mode 100644 src/app/dashboard.service.ts create mode 100644 src/app/dashboard/header/header.component.css create mode 100644 src/app/dashboard/header/header.component.html create mode 100644 src/app/dashboard/header/header.component.spec.ts create mode 100644 src/app/dashboard/header/header.component.ts create mode 100644 src/app/dashboard/overview/overview.component.css create mode 100644 src/app/dashboard/overview/overview.component.html create mode 100644 src/app/dashboard/overview/overview.component.spec.ts create mode 100644 src/app/dashboard/overview/overview.component.ts create mode 100644 src/assets/history.svg diff --git a/src/app/app.module.ts b/src/app/app.module.ts index bd2a24a..2d81c54 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -15,6 +15,9 @@ import { NotFoundComponent } from './not-found/not-found.component'; import { CartComponent } from './cart/cart.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { LoginComponent } from './dashboard/login/login.component'; +import { FormsModule } from '@angular/forms'; +import { OverviewComponent } from './dashboard/overview/overview.component'; +import { DashboardHeaderComponent } from './dashboard/header/header.component'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -28,13 +31,16 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; NotFoundComponent, CartComponent, DashboardComponent, - LoginComponent + LoginComponent, + OverviewComponent, + DashboardHeaderComponent ], imports: [ BrowserModule, QRCodeModule, HttpClientModule, AppRoutingModule, + FormsModule, SocketIoModule.forRoot(config) ], providers: [], diff --git a/src/app/dashboard.service.spec.ts b/src/app/dashboard.service.spec.ts new file mode 100644 index 0000000..79e72a6 --- /dev/null +++ b/src/app/dashboard.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { DashboardService } from './dashboard.service'; + +describe('DashboardService', () => { + let service: DashboardService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(DashboardService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard.service.ts b/src/app/dashboard.service.ts new file mode 100644 index 0000000..3b14b88 --- /dev/null +++ b/src/app/dashboard.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; + +export interface IUser { + username: string; + token: string; +} + +@Injectable({ + providedIn: 'root' +}) +export class DashboardService { + + user: IUser | undefined; + + constructor() { } + + login(username: string, password: string): boolean { + if (username === 'admin' && password === 'password') { + this.user = { + username: 'admin', + token: 'abc' + } + return true; + } else { + return false; + } + } +} diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 9c5fce9..8687f04 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1 +1,2 @@ -

dashboard works!

+ + \ No newline at end of file diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts index 38138a3..b9a91a8 100644 --- a/src/app/dashboard/dashboard.component.ts +++ b/src/app/dashboard/dashboard.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { DashboardService } from '../dashboard.service'; @Component({ selector: 'app-dashboard', @@ -7,7 +8,7 @@ import { Component, OnInit } from '@angular/core'; }) export class DashboardComponent implements OnInit { - constructor() { } + constructor(public dashboard: DashboardService) { } ngOnInit(): void { } diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css new file mode 100644 index 0000000..6f04bdd --- /dev/null +++ b/src/app/dashboard/header/header.component.css @@ -0,0 +1,10 @@ +.header { + position: fixed; + top: 1rem; + left: 5vw; + width: 90vw; + margin: 0 auto; + background-color: #27293D; + z-index: 999; + border-radius: 8px; +} \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html new file mode 100644 index 0000000..d085ff5 --- /dev/null +++ b/src/app/dashboard/header/header.component.html @@ -0,0 +1,3 @@ +
+

HEADER

+
\ No newline at end of file diff --git a/src/app/dashboard/header/header.component.spec.ts b/src/app/dashboard/header/header.component.spec.ts new file mode 100644 index 0000000..381e8e8 --- /dev/null +++ b/src/app/dashboard/header/header.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HeaderComponent } from './header.component'; + +describe('HeaderComponent', () => { + let component: HeaderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ HeaderComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/header/header.component.ts b/src/app/dashboard/header/header.component.ts new file mode 100644 index 0000000..1a76e2e --- /dev/null +++ b/src/app/dashboard/header/header.component.ts @@ -0,0 +1,20 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { DashboardService } from 'src/app/dashboard.service'; + +@Component({ + selector: 'dashboard-header', + templateUrl: './header.component.html', + styleUrls: ['./header.component.css'] +}) +export class DashboardHeaderComponent implements OnInit { + + constructor( + public dashboard: DashboardService, + public router: Router + ) { } + + ngOnInit(): void { + } + +} diff --git a/src/app/dashboard/login/login.component.css b/src/app/dashboard/login/login.component.css index e69de29..7309446 100644 --- a/src/app/dashboard/login/login.component.css +++ b/src/app/dashboard/login/login.component.css @@ -0,0 +1,133 @@ +.frame { + background-color: #1D1D28; + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + overflow: hidden; + font-family: 'Inter', sans-serif; +} + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400&display=swap'); +.btn { + display: inline-block; + *display: inline; + *zoom: 1; + padding: 4px 10px 4px; + margin-bottom: 0; + font-size: 13px; + line-height: 18px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + background-color: #f5f5f5; + background-repeat: repeat-x; + border-color: #e6e6e6 #e6e6e6 #e6e6e6; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border: 1px solid #e6e6e6; + border-radius: 4px; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + cursor: pointer; + *margin-left: .3em; +} + +.btn:hover, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + background-color: #e6e6e6; +} + +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + border-radius: 5px; +} + +.btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + background-position: 0 -15px; + transition: background-position 0.1s linear; + transition: ease 0.5; +} + +.btn-primary, +.btn-primary:hover { + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + color: #ffffff; +} + +.btn-primary.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn-primary { + background-color: #1D1D28; + background-image: linear-gradient(top, #6eb6de, #4a77d4); + background-repeat: repeat-x; + border: 1px solid #3762bc; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.5); + transition: ease; +} + +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + filter: none; + background-color: #4a77d4; +} + +.btn-block { + width: 100%; + display: block; +} + +* { + box-sizing: border-box; +} + +.login { + position: absolute; + top: 50%; + left: 50%; + margin: -150px 0 0 -150px; + width: 300px; + height: 300px; +} + +.login h1 { + color: #fff; + text-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + letter-spacing: 1px; + text-align: center; + font-weight: 200; +} + +input { + width: 100%; + margin-bottom: 10px; + background: #1D1D28; + border: none; + outline: none; + padding: 10px; + font-size: 13px; + color: #fff; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); + border: 1px solid rgb(138, 138, 138); + border-radius: 4px; + box-shadow: inset 0 -5px 45px rgba(100, 100, 100, 0), 0 1px 1px rgba(255, 255, 255, 0.2); + transition: box-shadow .5s ease; +} + +input:focus { + box-shadow: inset 0 -5px 45px rgba(100, 100, 100, 0.4), 0 1px 1px rgba(255, 255, 255, 0.2); +} \ No newline at end of file diff --git a/src/app/dashboard/login/login.component.html b/src/app/dashboard/login/login.component.html index 147cfc4..ac07479 100644 --- a/src/app/dashboard/login/login.component.html +++ b/src/app/dashboard/login/login.component.html @@ -1 +1,10 @@ -

login works!

+
+ +
\ No newline at end of file diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts index 4f58421..e0420ea 100644 --- a/src/app/dashboard/login/login.component.ts +++ b/src/app/dashboard/login/login.component.ts @@ -1,4 +1,6 @@ import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { DashboardService } from 'src/app/dashboard.service'; @Component({ selector: 'app-login', @@ -7,9 +9,25 @@ import { Component, OnInit } from '@angular/core'; }) export class LoginComponent implements OnInit { - constructor() { } + username = ''; + password = ''; + + constructor( + public dashboard: DashboardService, + private router: Router + ) { } ngOnInit(): void { } -} + login() { + const loginStatus = this.dashboard.login(this.username, this.password); + + if (loginStatus) { + this.router.navigate(['dashboard', 'overview']); + } else { + // TODO: Meldung anzeigen + } + } + +} \ No newline at end of file diff --git a/src/app/dashboard/overview/overview.component.css b/src/app/dashboard/overview/overview.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/overview/overview.component.html b/src/app/dashboard/overview/overview.component.html new file mode 100644 index 0000000..57c67df --- /dev/null +++ b/src/app/dashboard/overview/overview.component.html @@ -0,0 +1 @@ +

overview works!

diff --git a/src/app/dashboard/overview/overview.component.spec.ts b/src/app/dashboard/overview/overview.component.spec.ts new file mode 100644 index 0000000..44a847e --- /dev/null +++ b/src/app/dashboard/overview/overview.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OverviewComponent } from './overview.component'; + +describe('OverviewComponent', () => { + let component: OverviewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OverviewComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(OverviewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/overview/overview.component.ts b/src/app/dashboard/overview/overview.component.ts new file mode 100644 index 0000000..6a32601 --- /dev/null +++ b/src/app/dashboard/overview/overview.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-overview', + templateUrl: './overview.component.html', + styleUrls: ['./overview.component.css'] +}) +export class OverviewComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/assets/history.svg b/src/assets/history.svg new file mode 100644 index 0000000..9a422ca --- /dev/null +++ b/src/assets/history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/routes.ts b/src/routes.ts index 74cce43..5dde117 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -1,11 +1,22 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; +import { DashboardComponent } from "./app/dashboard/dashboard.component"; +import { LoginComponent } from "./app/dashboard/login/login.component"; +import { OverviewComponent } from "./app/dashboard/overview/overview.component"; import { HelloComponent } from "./app/hello/hello.component"; import { NotFoundComponent } from "./app/not-found/not-found.component"; import { PayComponent } from "./app/pay/pay.component"; const routes: Routes = [ { path: 'pay/:id', component: PayComponent, data: { title: 'Payment' } }, + { path: 'dashboard', component: DashboardComponent, children: [ + { + path: 'login', component: LoginComponent + }, + { + path: 'overview', component: OverviewComponent + } + ]}, { path: '', component: HelloComponent }, { path: '**', component: NotFoundComponent } ] From c2ef9fe16d330cccd81754e051d513a7672d536e Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 6 Jan 2021 19:12:19 +0100 Subject: [PATCH 05/40] add SVG Images to HeaderBar --- src/app/dashboard/header/header.component.css | 6 ++++++ src/app/dashboard/header/header.component.html | 4 +++- src/app/dashboard/login/login.component.ts | 8 ++++++++ src/assets/admin.svg | 1 + src/assets/dash.svg | 1 + 5 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/assets/admin.svg create mode 100644 src/assets/dash.svg diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css index 6f04bdd..8121253 100644 --- a/src/app/dashboard/header/header.component.css +++ b/src/app/dashboard/header/header.component.css @@ -7,4 +7,10 @@ background-color: #27293D; z-index: 999; border-radius: 8px; +} + +.history-svg {} + +.admin-svg { + fill: white; } \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html index d085ff5..f25c373 100644 --- a/src/app/dashboard/header/header.component.html +++ b/src/app/dashboard/header/header.component.html @@ -1,3 +1,5 @@
-

HEADER

+ + +
\ No newline at end of file diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts index e0420ea..6b0dfe1 100644 --- a/src/app/dashboard/login/login.component.ts +++ b/src/app/dashboard/login/login.component.ts @@ -18,8 +18,16 @@ export class LoginComponent implements OnInit { ) { } ngOnInit(): void { + + const loginStatus = this.dashboard.login("admin", "password"); + if (loginStatus) { + this.router.navigate(['dashboard', 'overview']); + } else { + // TODO: Meldung anzeigen + } } + login() { const loginStatus = this.dashboard.login(this.username, this.password); diff --git a/src/assets/admin.svg b/src/assets/admin.svg new file mode 100644 index 0000000..4adef78 --- /dev/null +++ b/src/assets/admin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/dash.svg b/src/assets/dash.svg new file mode 100644 index 0000000..280d48a --- /dev/null +++ b/src/assets/dash.svg @@ -0,0 +1 @@ + \ No newline at end of file From b409c3c670ee8a4ba8d0d71d4e0a47ba45262781 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:42:34 +0100 Subject: [PATCH 06/40] merge master --- src/app/app.module.ts | 4 ++- src/app/dashboard/dashboard.component.css | 0 src/app/dashboard/dashboard.component.html | 1 + src/app/dashboard/dashboard.component.spec.ts | 25 +++++++++++++++++++ src/app/dashboard/dashboard.component.ts | 15 +++++++++++ 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/app/dashboard/dashboard.component.css create mode 100644 src/app/dashboard/dashboard.component.html create mode 100644 src/app/dashboard/dashboard.component.spec.ts create mode 100644 src/app/dashboard/dashboard.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 2203d4f..8f19381 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -15,6 +15,7 @@ import { NotFoundComponent } from './not-found/not-found.component'; import { CartComponent } from './cart/cart.component'; import { PushNotificationsModule } from 'ng-push-ivy'; import { ClipboardModule } from 'ngx-clipboard'; +import { DashboardComponent } from './dashboard/dashboard.component'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -26,7 +27,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; PayComponent, HelloComponent, NotFoundComponent, - CartComponent + CartComponent, + DashboardComponent ], imports: [ BrowserModule, diff --git a/src/app/dashboard/dashboard.component.css b/src/app/dashboard/dashboard.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html new file mode 100644 index 0000000..9c5fce9 --- /dev/null +++ b/src/app/dashboard/dashboard.component.html @@ -0,0 +1 @@ +

dashboard works!

diff --git a/src/app/dashboard/dashboard.component.spec.ts b/src/app/dashboard/dashboard.component.spec.ts new file mode 100644 index 0000000..5ec4ff8 --- /dev/null +++ b/src/app/dashboard/dashboard.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DashboardComponent } from './dashboard.component'; + +describe('DashboardComponent', () => { + let component: DashboardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ DashboardComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts new file mode 100644 index 0000000..38138a3 --- /dev/null +++ b/src/app/dashboard/dashboard.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: ['./dashboard.component.css'] +}) +export class DashboardComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} From 695dbf9d34ef1b5940cb637001ff7fc19af37a34 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:57:43 +0100 Subject: [PATCH 07/40] add login subcomponent --- src/app/app.module.ts | 4 ++- src/app/dashboard/login/login.component.css | 0 src/app/dashboard/login/login.component.html | 1 + .../dashboard/login/login.component.spec.ts | 25 +++++++++++++++++++ src/app/dashboard/login/login.component.ts | 15 +++++++++++ 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/app/dashboard/login/login.component.css create mode 100644 src/app/dashboard/login/login.component.html create mode 100644 src/app/dashboard/login/login.component.spec.ts create mode 100644 src/app/dashboard/login/login.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 8f19381..91fe33f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -16,6 +16,7 @@ import { CartComponent } from './cart/cart.component'; import { PushNotificationsModule } from 'ng-push-ivy'; import { ClipboardModule } from 'ngx-clipboard'; import { DashboardComponent } from './dashboard/dashboard.component'; +import { LoginComponent } from './dashboard/login/login.component'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -28,7 +29,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; HelloComponent, NotFoundComponent, CartComponent, - DashboardComponent + DashboardComponent, + LoginComponent ], imports: [ BrowserModule, diff --git a/src/app/dashboard/login/login.component.css b/src/app/dashboard/login/login.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/login/login.component.html b/src/app/dashboard/login/login.component.html new file mode 100644 index 0000000..147cfc4 --- /dev/null +++ b/src/app/dashboard/login/login.component.html @@ -0,0 +1 @@ +

login works!

diff --git a/src/app/dashboard/login/login.component.spec.ts b/src/app/dashboard/login/login.component.spec.ts new file mode 100644 index 0000000..d2c0e6c --- /dev/null +++ b/src/app/dashboard/login/login.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LoginComponent } from './login.component'; + +describe('LoginComponent', () => { + let component: LoginComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LoginComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts new file mode 100644 index 0000000..4f58421 --- /dev/null +++ b/src/app/dashboard/login/login.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.css'] +}) +export class LoginComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} From 02f172735895f9ee67f85839899e45e93d9cc186 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 18:55:26 +0100 Subject: [PATCH 08/40] add login with dummy Data add login page add subcomponents --- src/app/app.module.ts | 12 +- src/app/dashboard.service.spec.ts | 16 +++ src/app/dashboard.service.ts | 28 ++++ src/app/dashboard/dashboard.component.html | 3 +- src/app/dashboard/dashboard.component.ts | 3 +- src/app/dashboard/header/header.component.css | 10 ++ .../dashboard/header/header.component.html | 3 + .../dashboard/header/header.component.spec.ts | 25 ++++ src/app/dashboard/header/header.component.ts | 20 +++ src/app/dashboard/login/login.component.css | 133 ++++++++++++++++++ src/app/dashboard/login/login.component.html | 11 +- src/app/dashboard/login/login.component.ts | 22 ++- .../dashboard/overview/overview.component.css | 0 .../overview/overview.component.html | 1 + .../overview/overview.component.spec.ts | 25 ++++ .../dashboard/overview/overview.component.ts | 15 ++ src/assets/history.svg | 1 + src/routes.ts | 11 ++ 18 files changed, 331 insertions(+), 8 deletions(-) create mode 100644 src/app/dashboard.service.spec.ts create mode 100644 src/app/dashboard.service.ts create mode 100644 src/app/dashboard/header/header.component.css create mode 100644 src/app/dashboard/header/header.component.html create mode 100644 src/app/dashboard/header/header.component.spec.ts create mode 100644 src/app/dashboard/header/header.component.ts create mode 100644 src/app/dashboard/overview/overview.component.css create mode 100644 src/app/dashboard/overview/overview.component.html create mode 100644 src/app/dashboard/overview/overview.component.spec.ts create mode 100644 src/app/dashboard/overview/overview.component.ts create mode 100644 src/assets/history.svg diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 91fe33f..71faa70 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -6,7 +6,6 @@ import { HeaderComponent } from './header/header.component'; import { PaymentComponent } from './payment/payment.component'; import { QRCodeModule } from 'angularx-qrcode'; import { PayComponent } from './pay/pay.component'; -import { RouterModule } from '@angular/router'; import { HelloComponent } from './hello/hello.component'; import { SocketIoConfig, SocketIoModule } from 'ngx-socket-io'; import { HttpClientModule } from '@angular/common/http'; @@ -17,6 +16,9 @@ import { PushNotificationsModule } from 'ng-push-ivy'; import { ClipboardModule } from 'ngx-clipboard'; import { DashboardComponent } from './dashboard/dashboard.component'; import { LoginComponent } from './dashboard/login/login.component'; +import { FormsModule } from '@angular/forms'; +import { OverviewComponent } from './dashboard/overview/overview.component'; +import { DashboardHeaderComponent } from './dashboard/header/header.component'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -30,7 +32,9 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; NotFoundComponent, CartComponent, DashboardComponent, - LoginComponent + LoginComponent, + OverviewComponent, + DashboardHeaderComponent ], imports: [ BrowserModule, @@ -39,7 +43,9 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; AppRoutingModule, SocketIoModule.forRoot(config), PushNotificationsModule, - ClipboardModule + ClipboardModule, + FormsModule, + SocketIoModule.forRoot(config) ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/dashboard.service.spec.ts b/src/app/dashboard.service.spec.ts new file mode 100644 index 0000000..79e72a6 --- /dev/null +++ b/src/app/dashboard.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { DashboardService } from './dashboard.service'; + +describe('DashboardService', () => { + let service: DashboardService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(DashboardService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard.service.ts b/src/app/dashboard.service.ts new file mode 100644 index 0000000..3b14b88 --- /dev/null +++ b/src/app/dashboard.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; + +export interface IUser { + username: string; + token: string; +} + +@Injectable({ + providedIn: 'root' +}) +export class DashboardService { + + user: IUser | undefined; + + constructor() { } + + login(username: string, password: string): boolean { + if (username === 'admin' && password === 'password') { + this.user = { + username: 'admin', + token: 'abc' + } + return true; + } else { + return false; + } + } +} diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 9c5fce9..8687f04 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1 +1,2 @@ -

dashboard works!

+ + \ No newline at end of file diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts index 38138a3..b9a91a8 100644 --- a/src/app/dashboard/dashboard.component.ts +++ b/src/app/dashboard/dashboard.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { DashboardService } from '../dashboard.service'; @Component({ selector: 'app-dashboard', @@ -7,7 +8,7 @@ import { Component, OnInit } from '@angular/core'; }) export class DashboardComponent implements OnInit { - constructor() { } + constructor(public dashboard: DashboardService) { } ngOnInit(): void { } diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css new file mode 100644 index 0000000..6f04bdd --- /dev/null +++ b/src/app/dashboard/header/header.component.css @@ -0,0 +1,10 @@ +.header { + position: fixed; + top: 1rem; + left: 5vw; + width: 90vw; + margin: 0 auto; + background-color: #27293D; + z-index: 999; + border-radius: 8px; +} \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html new file mode 100644 index 0000000..d085ff5 --- /dev/null +++ b/src/app/dashboard/header/header.component.html @@ -0,0 +1,3 @@ +
+

HEADER

+
\ No newline at end of file diff --git a/src/app/dashboard/header/header.component.spec.ts b/src/app/dashboard/header/header.component.spec.ts new file mode 100644 index 0000000..381e8e8 --- /dev/null +++ b/src/app/dashboard/header/header.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HeaderComponent } from './header.component'; + +describe('HeaderComponent', () => { + let component: HeaderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ HeaderComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/header/header.component.ts b/src/app/dashboard/header/header.component.ts new file mode 100644 index 0000000..1a76e2e --- /dev/null +++ b/src/app/dashboard/header/header.component.ts @@ -0,0 +1,20 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { DashboardService } from 'src/app/dashboard.service'; + +@Component({ + selector: 'dashboard-header', + templateUrl: './header.component.html', + styleUrls: ['./header.component.css'] +}) +export class DashboardHeaderComponent implements OnInit { + + constructor( + public dashboard: DashboardService, + public router: Router + ) { } + + ngOnInit(): void { + } + +} diff --git a/src/app/dashboard/login/login.component.css b/src/app/dashboard/login/login.component.css index e69de29..7309446 100644 --- a/src/app/dashboard/login/login.component.css +++ b/src/app/dashboard/login/login.component.css @@ -0,0 +1,133 @@ +.frame { + background-color: #1D1D28; + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + overflow: hidden; + font-family: 'Inter', sans-serif; +} + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400&display=swap'); +.btn { + display: inline-block; + *display: inline; + *zoom: 1; + padding: 4px 10px 4px; + margin-bottom: 0; + font-size: 13px; + line-height: 18px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + background-color: #f5f5f5; + background-repeat: repeat-x; + border-color: #e6e6e6 #e6e6e6 #e6e6e6; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border: 1px solid #e6e6e6; + border-radius: 4px; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + cursor: pointer; + *margin-left: .3em; +} + +.btn:hover, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + background-color: #e6e6e6; +} + +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + border-radius: 5px; +} + +.btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + background-position: 0 -15px; + transition: background-position 0.1s linear; + transition: ease 0.5; +} + +.btn-primary, +.btn-primary:hover { + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + color: #ffffff; +} + +.btn-primary.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn-primary { + background-color: #1D1D28; + background-image: linear-gradient(top, #6eb6de, #4a77d4); + background-repeat: repeat-x; + border: 1px solid #3762bc; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.5); + transition: ease; +} + +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + filter: none; + background-color: #4a77d4; +} + +.btn-block { + width: 100%; + display: block; +} + +* { + box-sizing: border-box; +} + +.login { + position: absolute; + top: 50%; + left: 50%; + margin: -150px 0 0 -150px; + width: 300px; + height: 300px; +} + +.login h1 { + color: #fff; + text-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + letter-spacing: 1px; + text-align: center; + font-weight: 200; +} + +input { + width: 100%; + margin-bottom: 10px; + background: #1D1D28; + border: none; + outline: none; + padding: 10px; + font-size: 13px; + color: #fff; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); + border: 1px solid rgb(138, 138, 138); + border-radius: 4px; + box-shadow: inset 0 -5px 45px rgba(100, 100, 100, 0), 0 1px 1px rgba(255, 255, 255, 0.2); + transition: box-shadow .5s ease; +} + +input:focus { + box-shadow: inset 0 -5px 45px rgba(100, 100, 100, 0.4), 0 1px 1px rgba(255, 255, 255, 0.2); +} \ No newline at end of file diff --git a/src/app/dashboard/login/login.component.html b/src/app/dashboard/login/login.component.html index 147cfc4..ac07479 100644 --- a/src/app/dashboard/login/login.component.html +++ b/src/app/dashboard/login/login.component.html @@ -1 +1,10 @@ -

login works!

+
+ +
\ No newline at end of file diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts index 4f58421..e0420ea 100644 --- a/src/app/dashboard/login/login.component.ts +++ b/src/app/dashboard/login/login.component.ts @@ -1,4 +1,6 @@ import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { DashboardService } from 'src/app/dashboard.service'; @Component({ selector: 'app-login', @@ -7,9 +9,25 @@ import { Component, OnInit } from '@angular/core'; }) export class LoginComponent implements OnInit { - constructor() { } + username = ''; + password = ''; + + constructor( + public dashboard: DashboardService, + private router: Router + ) { } ngOnInit(): void { } -} + login() { + const loginStatus = this.dashboard.login(this.username, this.password); + + if (loginStatus) { + this.router.navigate(['dashboard', 'overview']); + } else { + // TODO: Meldung anzeigen + } + } + +} \ No newline at end of file diff --git a/src/app/dashboard/overview/overview.component.css b/src/app/dashboard/overview/overview.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/overview/overview.component.html b/src/app/dashboard/overview/overview.component.html new file mode 100644 index 0000000..57c67df --- /dev/null +++ b/src/app/dashboard/overview/overview.component.html @@ -0,0 +1 @@ +

overview works!

diff --git a/src/app/dashboard/overview/overview.component.spec.ts b/src/app/dashboard/overview/overview.component.spec.ts new file mode 100644 index 0000000..44a847e --- /dev/null +++ b/src/app/dashboard/overview/overview.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OverviewComponent } from './overview.component'; + +describe('OverviewComponent', () => { + let component: OverviewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OverviewComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(OverviewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/overview/overview.component.ts b/src/app/dashboard/overview/overview.component.ts new file mode 100644 index 0000000..6a32601 --- /dev/null +++ b/src/app/dashboard/overview/overview.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-overview', + templateUrl: './overview.component.html', + styleUrls: ['./overview.component.css'] +}) +export class OverviewComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/assets/history.svg b/src/assets/history.svg new file mode 100644 index 0000000..9a422ca --- /dev/null +++ b/src/assets/history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/routes.ts b/src/routes.ts index 74cce43..5dde117 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -1,11 +1,22 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; +import { DashboardComponent } from "./app/dashboard/dashboard.component"; +import { LoginComponent } from "./app/dashboard/login/login.component"; +import { OverviewComponent } from "./app/dashboard/overview/overview.component"; import { HelloComponent } from "./app/hello/hello.component"; import { NotFoundComponent } from "./app/not-found/not-found.component"; import { PayComponent } from "./app/pay/pay.component"; const routes: Routes = [ { path: 'pay/:id', component: PayComponent, data: { title: 'Payment' } }, + { path: 'dashboard', component: DashboardComponent, children: [ + { + path: 'login', component: LoginComponent + }, + { + path: 'overview', component: OverviewComponent + } + ]}, { path: '', component: HelloComponent }, { path: '**', component: NotFoundComponent } ] From 8cc0d96abfba6ee954333c9bd54b24ef885705a5 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:42:34 +0100 Subject: [PATCH 09/40] add component "dashboard" --- src/app/dashboard/dashboard.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 8687f04..51213bf 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,2 +1,2 @@ - \ No newline at end of file + From a3e3eb983bfabaa4d48c8f6dac6539c496e7624d Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 6 Jan 2021 19:12:19 +0100 Subject: [PATCH 10/40] add SVG Images to HeaderBar --- src/app/dashboard/header/header.component.css | 6 ++++++ src/app/dashboard/header/header.component.html | 4 +++- src/app/dashboard/login/login.component.ts | 8 ++++++++ src/assets/admin.svg | 1 + src/assets/dash.svg | 1 + 5 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/assets/admin.svg create mode 100644 src/assets/dash.svg diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css index 6f04bdd..8121253 100644 --- a/src/app/dashboard/header/header.component.css +++ b/src/app/dashboard/header/header.component.css @@ -7,4 +7,10 @@ background-color: #27293D; z-index: 999; border-radius: 8px; +} + +.history-svg {} + +.admin-svg { + fill: white; } \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html index d085ff5..f25c373 100644 --- a/src/app/dashboard/header/header.component.html +++ b/src/app/dashboard/header/header.component.html @@ -1,3 +1,5 @@
-

HEADER

+ + +
\ No newline at end of file diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts index e0420ea..6b0dfe1 100644 --- a/src/app/dashboard/login/login.component.ts +++ b/src/app/dashboard/login/login.component.ts @@ -18,8 +18,16 @@ export class LoginComponent implements OnInit { ) { } ngOnInit(): void { + + const loginStatus = this.dashboard.login("admin", "password"); + if (loginStatus) { + this.router.navigate(['dashboard', 'overview']); + } else { + // TODO: Meldung anzeigen + } } + login() { const loginStatus = this.dashboard.login(this.username, this.password); diff --git a/src/assets/admin.svg b/src/assets/admin.svg new file mode 100644 index 0000000..4adef78 --- /dev/null +++ b/src/assets/admin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/dash.svg b/src/assets/dash.svg new file mode 100644 index 0000000..280d48a --- /dev/null +++ b/src/assets/dash.svg @@ -0,0 +1 @@ + \ No newline at end of file From 2aae14184423771f3a944e4cbbe8ff92216203aa Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 2 Feb 2021 10:59:22 +0100 Subject: [PATCH 11/40] + Added Dashboard Navbar + Added Transitions + Added Shadows + Added LogIn Page --- src/app/backend.service.ts | 8 ++- src/app/dashboard/dashboard.component.css | 8 +++ src/app/dashboard/dashboard.component.html | 3 +- src/app/dashboard/header/header.component.css | 56 ++++++++++++++++++- .../dashboard/header/header.component.html | 19 ++++++- .../dashboard/overview/overview.component.ts | 6 +- src/app/payment/payment.component.ts | 4 +- src/assets/admin.svg | 2 +- src/assets/dash.svg | 2 +- src/assets/dashboard.svg | 3 + src/assets/history.svg | 2 +- src/assets/settings.svg | 4 ++ 12 files changed, 102 insertions(+), 15 deletions(-) create mode 100644 src/assets/dashboard.svg create mode 100644 src/assets/settings.svg diff --git a/src/app/backend.service.ts b/src/app/backend.service.ts index e8c3e35..3981f4b 100644 --- a/src/app/backend.service.ts +++ b/src/app/backend.service.ts @@ -65,7 +65,7 @@ export interface IInvoice { }) export class BackendService { - SERVER_URL = 'http://192.168.178.26:2009'; + SERVER_URL = 'http://localhost:2009'; // Fill with empty data invoice: IInvoice = { @@ -107,7 +107,7 @@ export class BackendService { /** * Subscribe to the real-time status of the selected invoice. */ - subscribeTo(selector: string): void { + subscribeTo(): void { this.socket.on('subscribe', (status: boolean) => { if (status) { this.updateInvoice(); @@ -120,7 +120,7 @@ export class BackendService { this.confirmations = update.count; }); - this.socket.emit('subscribe', { selector }); + this.socket.emit('subscribe', { selector: this.invoice.selector }); } /** @@ -137,6 +137,8 @@ export class BackendService { */ setInvoice(selector: string): Promise { return new Promise(async (resolve, reject) => { + console.log('Sel.:', selector); + if (selector === undefined || selector === 'undefined' || selector === '') { reject('There is no selector. Please set one before calling setInvoice(...)'); return; diff --git a/src/app/dashboard/dashboard.component.css b/src/app/dashboard/dashboard.component.css index e69de29..7f7fce2 100644 --- a/src/app/dashboard/dashboard.component.css +++ b/src/app/dashboard/dashboard.component.css @@ -0,0 +1,8 @@ +.bg { + position: fixed; + background-color: #1D1D28; + top: 0; + left: 0; + height: 100vh; + width: 100vw; +} \ No newline at end of file diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 51213bf..46e1627 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,2 +1,3 @@ - +
+ \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css index 8121253..b2c182a 100644 --- a/src/app/dashboard/header/header.component.css +++ b/src/app/dashboard/header/header.component.css @@ -3,14 +3,64 @@ top: 1rem; left: 5vw; width: 90vw; + height: 100%; + max-height: 35px; + padding: 15px; margin: 0 auto; background-color: #27293D; z-index: 999; border-radius: 8px; + transition: .2s ease; + box-shadow: 0 1.1px 12.5px -23px rgba(0, 0, 0, 0.014), 0 2.4px 23.6px -23px rgba(0, 0, 0, 0.027), 0 4.1px 33.4px -23px rgba(0, 0, 0, 0.038), 0 6.2px 42.1px -23px rgba(0, 0, 0, 0.045), 0 8.9px 49.9px -23px rgba(0, 0, 0, 0.05), 0 12.6px 57.5px -23px rgba(0, 0, 0, 0.054), 0 17.8px 65.8px -23px rgba(0, 0, 0, 0.058), 0 25.9px 76.9px -23px rgba(0, 0, 0, 0.062), 0 39.9px 96.3px -23px rgba(0, 0, 0, 0.066), 0 71px 148px -23px rgba(0, 0, 0, 0.07); } -.history-svg {} +.header:hover { + max-height: 55px; + transition: .2s ease; +} + +.icon::after { + content: ' '; + opacity: 0; +} + +.header:hover .icon::after { + content: "Test"; + color: white; + opacity: 1; + transition: .2s ease; + transition: .5s opacity ease; +} + +.icon:hover { + transform: translateY(-5px); +} + +.grid-container { + display: grid; + grid-template-columns: 32px 32px 1fr 32px 32px; + grid-template-rows: 1fr; + gap: 20px 30px; + grid-template-areas: "dashboard history . settings admin"; +} + +.dashboard { + grid-area: dashboard; +} + +.history { + grid-area: history; +} + +.settings { + grid-area: settings; +} + +.admin { + grid-area: admin; +} -.admin-svg { - fill: white; +.icon { + grid-row: 1; + transition: .2s ease; } \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html index f25c373..8802aea 100644 --- a/src/app/dashboard/header/header.component.html +++ b/src/app/dashboard/header/header.component.html @@ -1,5 +1,18 @@
- - - + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
\ No newline at end of file diff --git a/src/app/dashboard/overview/overview.component.ts b/src/app/dashboard/overview/overview.component.ts index 6a32601..b233b1c 100644 --- a/src/app/dashboard/overview/overview.component.ts +++ b/src/app/dashboard/overview/overview.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { DashboardService } from 'src/app/dashboard.service'; @Component({ selector: 'app-overview', @@ -7,9 +8,12 @@ import { Component, OnInit } from '@angular/core'; }) export class OverviewComponent implements OnInit { - constructor() { } + constructor(private dashboard: DashboardService) { } ngOnInit(): void { + if (this.dashboard.user === undefined) { + this.dashboard.login('admin', 'password'); + } } } diff --git a/src/app/payment/payment.component.ts b/src/app/payment/payment.component.ts index 8a7d498..7f31a53 100644 --- a/src/app/payment/payment.component.ts +++ b/src/app/payment/payment.component.ts @@ -39,7 +39,6 @@ export class PaymentComponent implements OnInit { ngOnInit(): void { this.route.params.subscribe(params => { this.paymentSelector = params.id; - this.backend.subscribeTo(this.paymentSelector); this.get(); }); @@ -126,7 +125,10 @@ export class PaymentComponent implements OnInit { } async get(): Promise { + console.log('Selector:', this.paymentSelector); + const res = await this.backend.setInvoice(this.paymentSelector); + this.backend.subscribeTo(); this.status = this.backend.getStatus(); this.backend.getConfirmation().catch(); this.ready = true; diff --git a/src/assets/admin.svg b/src/assets/admin.svg index 4adef78..5293b19 100644 --- a/src/assets/admin.svg +++ b/src/assets/admin.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/dash.svg b/src/assets/dash.svg index 280d48a..8cfd9d0 100644 --- a/src/assets/dash.svg +++ b/src/assets/dash.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/dashboard.svg b/src/assets/dashboard.svg new file mode 100644 index 0000000..5d89e74 --- /dev/null +++ b/src/assets/dashboard.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/history.svg b/src/assets/history.svg index 9a422ca..10b63fc 100644 --- a/src/assets/history.svg +++ b/src/assets/history.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/settings.svg b/src/assets/settings.svg new file mode 100644 index 0000000..0cf867f --- /dev/null +++ b/src/assets/settings.svg @@ -0,0 +1,4 @@ + + + + From 5e11c8321300ae994de52b881df0c2e61675f303 Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 2 Feb 2021 11:56:14 +0100 Subject: [PATCH 12/40] Add Chart.js --- package-lock.json | 54 +++++++++++++++++++ package.json | 2 + src/app/app.module.ts | 8 ++- src/app/dashboard/chart/chart.component.css | 0 src/app/dashboard/chart/chart.component.html | 2 + .../dashboard/chart/chart.component.spec.ts | 25 +++++++++ src/app/dashboard/chart/chart.component.ts | 15 ++++++ src/app/dashboard/dashboard.component.html | 1 + 8 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/app/dashboard/chart/chart.component.css create mode 100644 src/app/dashboard/chart/chart.component.html create mode 100644 src/app/dashboard/chart/chart.component.spec.ts create mode 100644 src/app/dashboard/chart/chart.component.ts diff --git a/package-lock.json b/package-lock.json index a3eb569..08f49f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1552,6 +1552,14 @@ "semver-intersect": "1.4.0" } }, + "@types/chart.js": { + "version": "2.9.30", + "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.30.tgz", + "integrity": "sha512-EgjxUUZFvf6ls3kW2CwyrnSJhgyKxgwrlp/W5G9wqyPEO9iFatO63zAA7L24YqgMxiDjQ+tG7ODU+2yWH91lPg==", + "requires": { + "moment": "^2.10.2" + } + }, "@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -2817,6 +2825,32 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chart.js": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", + "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==", + "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": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", @@ -6913,6 +6947,11 @@ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, + "lodash-es": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.20.tgz", + "integrity": "sha512-JD1COMZsq8maT6mnuz1UMV0jvYD0E0aUsSOdrr1/nAG3dhqQXwRRgeW0cSqH1U43INKcqxaiVIQNOUDld7gRDA==" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -7432,6 +7471,11 @@ "minimist": "^1.2.5" } }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -7535,6 +7579,16 @@ "tslib": "^2.0.0" } }, + "ng2-charts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-2.4.2.tgz", + "integrity": "sha512-mY3C2uKCaApHCQizS2YxEOqQ7sSZZLxdV6N1uM9u/VvUgVtYvlPtdcXbKpN52ak93ZE22I73DiLWVDnDNG4/AQ==", + "requires": { + "@types/chart.js": "^2.9.24", + "lodash-es": "^4.17.15", + "tslib": "^2.0.0" + } + }, "ngx-clipboard": { "version": "14.0.1", "resolved": "https://registry.npmjs.org/ngx-clipboard/-/ngx-clipboard-14.0.1.tgz", diff --git a/package.json b/package.json index bbf8ef8..241b709 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ "@angular/platform-browser-dynamic": "~11.0.5", "@angular/router": "~11.0.5", "angularx-qrcode": "^10.0.11", + "chart.js": "^2.9.4", "ng-push-ivy": "^1.0.7", + "ng2-charts": "^2.4.2", "ngx-clipboard": "^14.0.1", "ngx-socket-io": "^3.2.0", "rxjs": "~6.6.0", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 71faa70..b54b9af 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -19,6 +19,8 @@ import { LoginComponent } from './dashboard/login/login.component'; import { FormsModule } from '@angular/forms'; import { OverviewComponent } from './dashboard/overview/overview.component'; import { DashboardHeaderComponent } from './dashboard/header/header.component'; +import { ChartComponent } from './dashboard/chart/chart.component'; +import { ChartsModule } from 'ng2-charts'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -34,7 +36,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; DashboardComponent, LoginComponent, OverviewComponent, - DashboardHeaderComponent + DashboardHeaderComponent, + ChartComponent ], imports: [ BrowserModule, @@ -45,7 +48,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; PushNotificationsModule, ClipboardModule, FormsModule, - SocketIoModule.forRoot(config) + SocketIoModule.forRoot(config), + ChartsModule ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/dashboard/chart/chart.component.css b/src/app/dashboard/chart/chart.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html new file mode 100644 index 0000000..90660a1 --- /dev/null +++ b/src/app/dashboard/chart/chart.component.html @@ -0,0 +1,2 @@ + +

Test

\ No newline at end of file diff --git a/src/app/dashboard/chart/chart.component.spec.ts b/src/app/dashboard/chart/chart.component.spec.ts new file mode 100644 index 0000000..6c6d094 --- /dev/null +++ b/src/app/dashboard/chart/chart.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChartComponent } from './chart.component'; + +describe('ChartComponent', () => { + let component: ChartComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ChartComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/chart/chart.component.ts b/src/app/dashboard/chart/chart.component.ts new file mode 100644 index 0000000..30c6b9b --- /dev/null +++ b/src/app/dashboard/chart/chart.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-chart', + templateUrl: './chart.component.html', + styleUrls: ['./chart.component.css'] +}) +export class ChartComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 46e1627..03edc4b 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,3 +1,4 @@ +
\ No newline at end of file From 9cf5be1f3433e8dca29a46a4d576d766a9044165 Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 2 Feb 2021 11:56:14 +0100 Subject: [PATCH 13/40] Add NGX Chart --- package-lock.json | 54 +++++++++++++++++++ package.json | 2 + src/app/app.module.ts | 8 ++- src/app/dashboard/chart/chart.component.css | 0 src/app/dashboard/chart/chart.component.html | 2 + .../dashboard/chart/chart.component.spec.ts | 25 +++++++++ src/app/dashboard/chart/chart.component.ts | 15 ++++++ src/app/dashboard/dashboard.component.html | 1 + 8 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/app/dashboard/chart/chart.component.css create mode 100644 src/app/dashboard/chart/chart.component.html create mode 100644 src/app/dashboard/chart/chart.component.spec.ts create mode 100644 src/app/dashboard/chart/chart.component.ts diff --git a/package-lock.json b/package-lock.json index a3eb569..08f49f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1552,6 +1552,14 @@ "semver-intersect": "1.4.0" } }, + "@types/chart.js": { + "version": "2.9.30", + "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.30.tgz", + "integrity": "sha512-EgjxUUZFvf6ls3kW2CwyrnSJhgyKxgwrlp/W5G9wqyPEO9iFatO63zAA7L24YqgMxiDjQ+tG7ODU+2yWH91lPg==", + "requires": { + "moment": "^2.10.2" + } + }, "@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -2817,6 +2825,32 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chart.js": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", + "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==", + "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": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", @@ -6913,6 +6947,11 @@ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, + "lodash-es": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.20.tgz", + "integrity": "sha512-JD1COMZsq8maT6mnuz1UMV0jvYD0E0aUsSOdrr1/nAG3dhqQXwRRgeW0cSqH1U43INKcqxaiVIQNOUDld7gRDA==" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -7432,6 +7471,11 @@ "minimist": "^1.2.5" } }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -7535,6 +7579,16 @@ "tslib": "^2.0.0" } }, + "ng2-charts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-2.4.2.tgz", + "integrity": "sha512-mY3C2uKCaApHCQizS2YxEOqQ7sSZZLxdV6N1uM9u/VvUgVtYvlPtdcXbKpN52ak93ZE22I73DiLWVDnDNG4/AQ==", + "requires": { + "@types/chart.js": "^2.9.24", + "lodash-es": "^4.17.15", + "tslib": "^2.0.0" + } + }, "ngx-clipboard": { "version": "14.0.1", "resolved": "https://registry.npmjs.org/ngx-clipboard/-/ngx-clipboard-14.0.1.tgz", diff --git a/package.json b/package.json index bbf8ef8..241b709 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ "@angular/platform-browser-dynamic": "~11.0.5", "@angular/router": "~11.0.5", "angularx-qrcode": "^10.0.11", + "chart.js": "^2.9.4", "ng-push-ivy": "^1.0.7", + "ng2-charts": "^2.4.2", "ngx-clipboard": "^14.0.1", "ngx-socket-io": "^3.2.0", "rxjs": "~6.6.0", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 71faa70..b54b9af 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -19,6 +19,8 @@ import { LoginComponent } from './dashboard/login/login.component'; import { FormsModule } from '@angular/forms'; import { OverviewComponent } from './dashboard/overview/overview.component'; import { DashboardHeaderComponent } from './dashboard/header/header.component'; +import { ChartComponent } from './dashboard/chart/chart.component'; +import { ChartsModule } from 'ng2-charts'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -34,7 +36,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; DashboardComponent, LoginComponent, OverviewComponent, - DashboardHeaderComponent + DashboardHeaderComponent, + ChartComponent ], imports: [ BrowserModule, @@ -45,7 +48,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; PushNotificationsModule, ClipboardModule, FormsModule, - SocketIoModule.forRoot(config) + SocketIoModule.forRoot(config), + ChartsModule ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/dashboard/chart/chart.component.css b/src/app/dashboard/chart/chart.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html new file mode 100644 index 0000000..90660a1 --- /dev/null +++ b/src/app/dashboard/chart/chart.component.html @@ -0,0 +1,2 @@ + +

Test

\ No newline at end of file diff --git a/src/app/dashboard/chart/chart.component.spec.ts b/src/app/dashboard/chart/chart.component.spec.ts new file mode 100644 index 0000000..6c6d094 --- /dev/null +++ b/src/app/dashboard/chart/chart.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChartComponent } from './chart.component'; + +describe('ChartComponent', () => { + let component: ChartComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ChartComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/chart/chart.component.ts b/src/app/dashboard/chart/chart.component.ts new file mode 100644 index 0000000..30c6b9b --- /dev/null +++ b/src/app/dashboard/chart/chart.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-chart', + templateUrl: './chart.component.html', + styleUrls: ['./chart.component.css'] +}) +export class ChartComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 46e1627..03edc4b 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,3 +1,4 @@ +
\ No newline at end of file From c6f0ddd996a1363075e6081c2cbd7a128e29838e Mon Sep 17 00:00:00 2001 From: Felix Date: Fri, 26 Mar 2021 15:56:14 +0100 Subject: [PATCH 14/40] add engxCharts add center Header --- package-lock.json | 346 ++++++++++++++++-- package.json | 6 + src/app/app.module.ts | 12 +- src/app/dashboard/chart/chart.component.html | 5 +- src/app/dashboard/chart/chart.component.ts | 24 +- src/app/dashboard/dashboard.component.css | 5 + src/app/dashboard/dashboard.component.html | 5 +- src/app/dashboard/header/header.component.css | 3 +- .../dashboard/summary/summary.component.css | 18 + .../dashboard/summary/summary.component.html | 3 + .../summary/summary.component.spec.ts | 25 ++ .../dashboard/summary/summary.component.ts | 15 + src/assets/js/Chart.min.css | 1 + src/assets/js/Chart.min.js | 7 + src/index.html | 25 +- 15 files changed, 447 insertions(+), 53 deletions(-) create mode 100644 src/app/dashboard/summary/summary.component.css create mode 100644 src/app/dashboard/summary/summary.component.html create mode 100644 src/app/dashboard/summary/summary.component.spec.ts create mode 100644 src/app/dashboard/summary/summary.component.ts create mode 100644 src/assets/js/Chart.min.css create mode 100644 src/assets/js/Chart.min.js diff --git a/package-lock.json b/package-lock.json index 08f49f6..d45d06b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -147,6 +147,23 @@ "tslib": "^2.0.0" } }, + "@angular/cdk": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-11.2.1.tgz", + "integrity": "sha512-d+ERvvWqGykBm5ooWG8TmMjL6q6aOpUd13ha1sx960EfKJqNyideYUfPMp6xprTyxmUIUZ/G9AQ/pxnzrLGnsA==", + "requires": { + "parse5": "^5.0.0", + "tslib": "^2.0.0" + }, + "dependencies": { + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "optional": true + } + } + }, "@angular/cli": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-11.0.5.tgz", @@ -1552,6 +1569,25 @@ "semver-intersect": "1.4.0" } }, + "@swimlane/ngx-charts": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-17.0.0.tgz", + "integrity": "sha512-NsjDBWeizvWrDq6W/ZImBGL9/RERsW+2qLR30xJg/oNbIrSqtLty7Scmah3b9lgyCH00c0pK1DMYUak1QoMBJQ==", + "requires": { + "d3-array": "^2.9.1", + "d3-brush": "^2.1.0", + "d3-color": "^2.0.0", + "d3-format": "^2.0.0", + "d3-hierarchy": "^2.0.0", + "d3-interpolate": "^2.0.1", + "d3-scale": "^3.2.3", + "d3-selection": "^2.0.0", + "d3-shape": "^2.0.0", + "d3-time-format": "^3.0.0", + "d3-transition": "^2.0.0", + "tslib": "^2.0.0" + } + }, "@types/chart.js": { "version": "2.9.30", "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.30.tgz", @@ -3803,6 +3839,128 @@ "type": "^1.0.1" } }, + "d3-array": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz", + "integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==", + "requires": { + "internmap": "^1.0.0" + } + }, + "d3-brush": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-2.1.0.tgz", + "integrity": "sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ==", + "requires": { + "d3-dispatch": "1 - 2", + "d3-drag": "2", + "d3-interpolate": "1 - 2", + "d3-selection": "2", + "d3-transition": "2" + } + }, + "d3-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", + "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" + }, + "d3-dispatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz", + "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==" + }, + "d3-drag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz", + "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==", + "requires": { + "d3-dispatch": "1 - 2", + "d3-selection": "2" + } + }, + "d3-ease": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz", + "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ==" + }, + "d3-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz", + "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==" + }, + "d3-hierarchy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz", + "integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw==" + }, + "d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "requires": { + "d3-color": "1 - 2" + } + }, + "d3-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz", + "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==" + }, + "d3-scale": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.3.tgz", + "integrity": "sha512-8E37oWEmEzj57bHcnjPVOBS3n4jqakOeuv1EDdQSiSrYnMCBdMd3nc4HtKk7uia8DUHcY/CGuJ42xxgtEYrX0g==", + "requires": { + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "1 - 2", + "d3-time-format": "2 - 3" + } + }, + "d3-selection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz", + "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==" + }, + "d3-shape": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz", + "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==", + "requires": { + "d3-path": "1 - 2" + } + }, + "d3-time": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.0.0.tgz", + "integrity": "sha512-2mvhstTFcMvwStWd9Tj3e6CEqtOivtD8AUiHT8ido/xmzrI9ijrUUihZ6nHuf/vsScRBonagOdj0Vv+SEL5G3Q==" + }, + "d3-time-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", + "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", + "requires": { + "d3-time": "1 - 2" + } + }, + "d3-timer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz", + "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==" + }, + "d3-transition": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz", + "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==", + "requires": { + "d3-color": "1 - 2", + "d3-dispatch": "1 - 2", + "d3-ease": "1 - 2", + "d3-interpolate": "1 - 2", + "d3-timer": "1 - 2" + } + }, "damerau-levenshtein": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", @@ -4182,6 +4340,15 @@ "safer-buffer": "^2.1.0" } }, + "echarts": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.0.2.tgz", + "integrity": "sha512-En0VYpc96nw2/2AZoBWPHsGi471zMublttj50kfFpYAeR4geup0Tj9iVgEXh7QYZFPnRiruDJEjcB5PXZ+BYzQ==", + "requires": { + "tslib": "2.0.3", + "zrender": "5.0.4" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4195,24 +4362,24 @@ "dev": true }, "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", + "bn.js": "^4.11.9", + "brorand": "^1.1.0", "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -4265,22 +4432,22 @@ } }, "engine.io": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz", - "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz", + "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==", "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "0.3.1", + "cookie": "~0.4.1", "debug": "~4.1.0", "engine.io-parser": "~2.2.0", - "ws": "^7.1.2" + "ws": "~7.4.2" }, "dependencies": { "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, "debug": { "version": "4.1.1", @@ -4291,9 +4458,9 @@ } }, "ws": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", - "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==" + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", + "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==" } } }, @@ -5964,6 +6131,11 @@ "ipaddr.js": "^1.9.0" } }, + "internmap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.0.tgz", + "integrity": "sha512-SdoDWwNOTE2n4JWUsLn4KXZGuZPjPF9yyOGc8bnfWnBQh7BD/l80rzSznKc/r4Y0aQ7z3RTk9X+tV4tHBpu+dA==" + }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -7598,6 +7770,14 @@ "tslib": "^2.0.0" } }, + "ngx-echarts": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ngx-echarts/-/ngx-echarts-6.0.1.tgz", + "integrity": "sha512-a9MZ8cHC7oD+c6Tl0ABAEM2inD+k4FHhuu7RnH6/34c10TJ7AFeQwrFbP6BgW39M9gViWozAjCRFmrvWOYv2Wg==", + "requires": { + "tslib": "^2.0.0" + } + }, "ngx-socket-io": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ngx-socket-io/-/ngx-socket-io-3.2.0.tgz", @@ -10119,6 +10299,12 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "dev": true + }, "resolve": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", @@ -10898,15 +11084,15 @@ } }, "socket.io": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", - "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.1.tgz", + "integrity": "sha512-Si18v0mMXGAqLqCVpTxBa8MGqriHGQh8ccEOhmsmNS3thNCGBwO8WGrwMibANsWtQQ5NStdZwHqZR3naJVFc3w==", "requires": { "debug": "~4.1.0", - "engine.io": "~3.4.0", + "engine.io": "~3.5.0", "has-binary2": "~1.0.2", "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.3.0", + "socket.io-client": "2.4.0", "socket.io-parser": "~3.4.0" }, "dependencies": { @@ -10917,6 +11103,102 @@ "requires": { "ms": "^2.1.1" } + }, + "engine.io-client": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.0.tgz", + "integrity": "sha512-12wPRfMrugVw/DNyJk34GQ5vIVArEcVMXWugQGGuw2XxUSztFNmJggZmv8IZlLyEdnpO1QB9LkcjeWewO2vxtA==", + "requires": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, + "socket.io-client": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz", + "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==", + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "socket.io-parser": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", + "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", + "requires": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + } + } + }, + "ws": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", + "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==" } } }, @@ -13566,6 +13848,14 @@ "version": "0.10.3", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==" + }, + "zrender": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.0.4.tgz", + "integrity": "sha512-DJpy0yrHYY5CuH6vhb9IINWbjvBUe/56J8aH86Jb7O8rRPAYZ3M2E469Qf5B3EOIfM3o3aUrO5edRQfLJ+l1Qw==", + "requires": { + "tslib": "2.0.3" + } } } } diff --git a/package.json b/package.json index 241b709..d4f915a 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "private": true, "dependencies": { "@angular/animations": "~11.0.5", + "@angular/cdk": "^11.2.1", "@angular/common": "~11.0.5", "@angular/compiler": "~11.0.5", "@angular/core": "~11.0.5", @@ -19,11 +20,15 @@ "@angular/platform-browser": "~11.0.5", "@angular/platform-browser-dynamic": "~11.0.5", "@angular/router": "~11.0.5", + "@swimlane/ngx-charts": "^17.0.0", "angularx-qrcode": "^10.0.11", "chart.js": "^2.9.4", + "d3-shape": "^2.1.0", + "echarts": "^5.0.2", "ng-push-ivy": "^1.0.7", "ng2-charts": "^2.4.2", "ngx-clipboard": "^14.0.1", + "ngx-echarts": "^6.0.1", "ngx-socket-io": "^3.2.0", "rxjs": "~6.6.0", "tslib": "^2.0.0", @@ -44,6 +49,7 @@ "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.5.0", "protractor": "~7.0.0", + "resize-observer-polyfill": "^1.5.1", "ts-node": "~8.3.0", "tslint": "~6.1.0", "typescript": "~4.0.2" diff --git a/src/app/app.module.ts b/src/app/app.module.ts index b54b9af..a607f33 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -20,7 +20,9 @@ import { FormsModule } from '@angular/forms'; import { OverviewComponent } from './dashboard/overview/overview.component'; import { DashboardHeaderComponent } from './dashboard/header/header.component'; import { ChartComponent } from './dashboard/chart/chart.component'; -import { ChartsModule } from 'ng2-charts'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { SummaryComponent } from './dashboard/summary/summary.component'; +import { NgxEchartsModule } from 'ngx-echarts'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -37,7 +39,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; LoginComponent, OverviewComponent, DashboardHeaderComponent, - ChartComponent + ChartComponent, + SummaryComponent ], imports: [ BrowserModule, @@ -49,7 +52,10 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; ClipboardModule, FormsModule, SocketIoModule.forRoot(config), - ChartsModule + BrowserAnimationsModule, + NgxEchartsModule.forRoot({ + echarts: () => import('echarts') + }) ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html index 90660a1..8a42052 100644 --- a/src/app/dashboard/chart/chart.component.html +++ b/src/app/dashboard/chart/chart.component.html @@ -1,2 +1,3 @@ - -

Test

\ No newline at end of file +
+ +

Chart workds

\ No newline at end of file diff --git a/src/app/dashboard/chart/chart.component.ts b/src/app/dashboard/chart/chart.component.ts index 30c6b9b..3345e54 100644 --- a/src/app/dashboard/chart/chart.component.ts +++ b/src/app/dashboard/chart/chart.component.ts @@ -1,15 +1,25 @@ -import { Component, OnInit } from '@angular/core'; +import { Component} from '@angular/core' +import { EChartsOption } from 'echarts'; @Component({ selector: 'app-chart', templateUrl: './chart.component.html', styleUrls: ['./chart.component.css'] }) -export class ChartComponent implements OnInit { - - constructor() { } - - ngOnInit(): void { - } +export class ChartComponent { + chartOption: EChartsOption = { + xAxis: { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + }, + yAxis: { + type: 'value' + }, + series: [{ + data: [820, 932, 901, 934, 1290, 1330, 1320], + type: 'line', + smooth: true + }] + }; } diff --git a/src/app/dashboard/dashboard.component.css b/src/app/dashboard/dashboard.component.css index 7f7fce2..a5c3f4b 100644 --- a/src/app/dashboard/dashboard.component.css +++ b/src/app/dashboard/dashboard.component.css @@ -5,4 +5,9 @@ left: 0; height: 100vh; width: 100vw; + z-index: -1; +} + +.spacer { + height: 100px; } \ No newline at end of file diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 03edc4b..a1c7310 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,4 +1,7 @@ - +
+ +
+ \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css index b2c182a..72a51a6 100644 --- a/src/app/dashboard/header/header.component.css +++ b/src/app/dashboard/header/header.component.css @@ -1,7 +1,8 @@ .header { position: fixed; top: 1rem; - left: 5vw; + left: 0; + right: 0; width: 90vw; height: 100%; max-height: 35px; diff --git a/src/app/dashboard/summary/summary.component.css b/src/app/dashboard/summary/summary.component.css new file mode 100644 index 0000000..ec36ddc --- /dev/null +++ b/src/app/dashboard/summary/summary.component.css @@ -0,0 +1,18 @@ +.header { + background-color: #242635; + margin: 0; + padding: 0; + padding: 2rem; + padding-right: 2rem; + border-radius: 22px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + margin: 0 auto; + width: 80%; +} + +.lower { + background-color: #26283A; + margin: 0; + padding: 6rem; +} \ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.html b/src/app/dashboard/summary/summary.component.html new file mode 100644 index 0000000..eceab7f --- /dev/null +++ b/src/app/dashboard/summary/summary.component.html @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.spec.ts b/src/app/dashboard/summary/summary.component.spec.ts new file mode 100644 index 0000000..0132711 --- /dev/null +++ b/src/app/dashboard/summary/summary.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SummaryComponent } from './summary.component'; + +describe('SummaryComponent', () => { + let component: SummaryComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SummaryComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SummaryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/summary/summary.component.ts b/src/app/dashboard/summary/summary.component.ts new file mode 100644 index 0000000..011993b --- /dev/null +++ b/src/app/dashboard/summary/summary.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-summary', + templateUrl: './summary.component.html', + styleUrls: ['./summary.component.css'] +}) +export class SummaryComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/assets/js/Chart.min.css b/src/assets/js/Chart.min.css new file mode 100644 index 0000000..9dc5ac2 --- /dev/null +++ b/src/assets/js/Chart.min.css @@ -0,0 +1 @@ +@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0} \ No newline at end of file diff --git a/src/assets/js/Chart.min.js b/src/assets/js/Chart.min.js new file mode 100644 index 0000000..a87f614 --- /dev/null +++ b/src/assets/js/Chart.min.js @@ -0,0 +1,7 @@ +/*! + * Chart.js v2.9.4 + * https://www.chartjs.org + * (c) 2020 Chart.js Contributors + * Released under the MIT License + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(function(){try{return require("moment")}catch(t){}}()):"function"==typeof define&&define.amd?define(["require"],(function(t){return e(function(){try{return t("moment")}catch(t){}}())})):(t=t||self).Chart=e(t.moment)}(this,(function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},n=function(t,e){return t(e={exports:{}},e.exports),e.exports}((function(t){var n={};for(var i in e)e.hasOwnProperty(i)&&(n[e[i]]=i);var a=t.exports={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};for(var r in a)if(a.hasOwnProperty(r)){if(!("channels"in a[r]))throw new Error("missing channels property: "+r);if(!("labels"in a[r]))throw new Error("missing channel labels property: "+r);if(a[r].labels.length!==a[r].channels)throw new Error("channel and label counts mismatch: "+r);var o=a[r].channels,s=a[r].labels;delete a[r].channels,delete a[r].labels,Object.defineProperty(a[r],"channels",{value:o}),Object.defineProperty(a[r],"labels",{value:s})}a.rgb.hsl=function(t){var e,n,i=t[0]/255,a=t[1]/255,r=t[2]/255,o=Math.min(i,a,r),s=Math.max(i,a,r),l=s-o;return s===o?e=0:i===s?e=(a-r)/l:a===s?e=2+(r-i)/l:r===s&&(e=4+(i-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),n=(o+s)/2,[e,100*(s===o?0:n<=.5?l/(s+o):l/(2-s-o)),100*n]},a.rgb.hsv=function(t){var e,n,i,a,r,o=t[0]/255,s=t[1]/255,l=t[2]/255,u=Math.max(o,s,l),d=u-Math.min(o,s,l),h=function(t){return(u-t)/6/d+.5};return 0===d?a=r=0:(r=d/u,e=h(o),n=h(s),i=h(l),o===u?a=i-n:s===u?a=1/3+e-i:l===u&&(a=2/3+n-e),a<0?a+=1:a>1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=n[t];if(i)return i;var a,r,o,s=1/0;for(var l in e)if(e.hasOwnProperty(l)){var u=e[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map((function(t){return t+t})).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}}));n.rgb,n.hsl,n.hsv,n.hwb,n.cmyk,n.xyz,n.lab,n.lch,n.hex,n.keyword,n.ansi16,n.ansi256,n.hcg,n.apple,n.gray;function i(t){var e=function(){for(var t={},e=Object.keys(n),i=e.length,a=0;a1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)}))}));var s=o,l={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},u={getRgba:d,getHsla:h,getRgb:function(t){var e=d(t);return e&&e.slice(0,3)},getHsl:function(t){var e=h(t);return e&&e.slice(0,3)},getHwb:c,getAlpha:function(t){var e=d(t);if(e)return e[3];if(e=h(t))return e[3];if(e=c(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+v(t[0])+v(t[1])+v(t[2])+(e>=0&&e<1?v(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return f(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:f,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:g,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return b[t.slice(0,3)]}};function d(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;rn?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new y,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},y.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},y.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},y.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i=0;a--)e.call(n,t[a],a);else for(a=0;a=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-C.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*C.easeInBounce(2*t):.5*C.easeOutBounce(2*t-1)+.5}},P={effects:C};S.easingEffects=C;var A=Math.PI,D=A/180,T=2*A,I=A/2,F=A/4,O=2*A/3,L={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),se.left-1e-6&&t.xe.top-1e-6&&t.y0&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r=n?(H.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},Q=H.options.resolve,tt=["push","pop","shift","splice","unshift"];function et(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(tt.forEach((function(e){delete t[e]})),delete t._chartjs)}}var nt=function(t,e){this.initialize(t,e)};H.extend(nt.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this.getMeta(),e=this.chart,n=e.scales,i=this.getDataset(),a=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||a.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||a.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&et(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;tn&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;na?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function ot(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+at,rt(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=at,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+at,n.startAngle,!0),a=0;as;)a-=at;for(;a=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/at)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+at,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;tt.x&&(e=bt(e,"left","right")):t.basen?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function yt(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&vt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}N._set("global",{elements:{rectangle:{backgroundColor:pt,borderColor:pt,borderSkipped:"bottom",borderWidth:0}}});var _t=K.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=vt(t),n=e.right-e.left,i=e.bottom-e.top,a=xt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return yt(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return mt(n)?yt(n,t,null):yt(n,null,e)},inXRange:function(t){return yt(this._view,t,null)},inYRange:function(t){return yt(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return mt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return mt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),kt={},wt=st,Mt=dt,St=gt,Ct=_t;kt.Arc=wt,kt.Line=Mt,kt.Point=St,kt.Rectangle=Ct;var Pt=H._deprecated,At=H.valueOrDefault;function Dt(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=H.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return H.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}N._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),N._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Tt=it.extend({dataElementType:kt.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;it.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Pt("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Pt("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Pt("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Pt("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Pt("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,n=i.length;e=0&&p.min>=0?p.min:p.max,y=void 0===p.start?p.end:p.max>=0&&p.min>=0?p.max-p.min:p.min-p.max,_=g.length;if(v||void 0===v&&void 0!==b)for(i=0;i<_&&(a=g[i]).index!==t;++i)a.stack===b&&(r=void 0===(u=h._parseValue(f[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(p.min<0&&r<0||p.max>=0&&r>0)&&(x+=r));return o=h.getPixelForValue(x),l=(s=h.getPixelForValue(x+y))-o,void 0!==m&&Math.abs(l)=0&&!c||y<0&&c?o-m:o+m),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t=Rt?-zt:b<-Rt?zt:0)+m,y=Math.cos(b),_=Math.sin(b),k=Math.cos(x),w=Math.sin(x),M=b<=0&&x>=0||x>=zt,S=b<=Nt&&x>=Nt||x>=zt+Nt,C=b<=-Nt&&x>=-Nt||x>=Rt+Nt,P=b===-Rt||x>=Rt?-1:Math.min(y,y*p,k,k*p),A=C?-1:Math.min(_,_*p,w,w*p),D=M?1:Math.max(y,y*p,k,k*p),T=S?1:Math.max(_,_*p,w,w*p);u=(D-P)/2,d=(T-A)/2,h=-(D+P)/2,c=-(T+A)/2}for(i=0,a=g.length;i0&&!isNaN(t)?zt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Lt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Lt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Lt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n0&&Ht(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return ae(t,e,{intersect:!1})},point:function(t,e){return ee(t,Qt(e,t))},nearest:function(t,e,n){var i=Qt(e,t);n.axis=n.axis||"xy";var a=ie(n.axis);return ne(t,i,n.intersect,a)},x:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},oe=H.extend;function se(t,e){return H.where(t,(function(t){return t.pos===e}))}function le(t,e){return t.sort((function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight}))}function ue(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function de(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-ue(o,t,"left","right"),a=e.outerHeight-ue(o,t,"top","bottom"),i!==t.w||a!==t.h){t.w=i,t.h=a;var l=n.horizontal?[i,t.w]:[a,t.h];return!(l[0]===l[1]||isNaN(l[0])&&isNaN(l[1]))}}function he(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach((function(t){i[t]=Math.max(e[t],n[t])})),i}return i(t?["left","right"]:["top","bottom"])}function ce(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;idiv{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&ge.default||ge,ve="$chartjs",be="chartjs-size-monitor",xe="chartjs-render-monitor",ye="chartjs-render-animation",_e=["animationstart","webkitAnimationStart"],ke={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function we(t,e){var n=H.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var Me=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Se(t,e,n){t.addEventListener(e,n,Me)}function Ce(t,e,n){t.removeEventListener(e,n,Me)}function Pe(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Ae(t){var e=document.createElement("div");return e.className=t||"",e}function De(t,e,n){var i,a,r,o,s=t[ve]||(t[ve]={}),l=s.resizer=function(t){var e=Ae(be),n=Ae(be+"-expand"),i=Ae(be+"-shrink");n.appendChild(Ae()),i.appendChild(Ae()),e.appendChild(n),e.appendChild(i),e._reset=function(){n.scrollLeft=1e6,n.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var a=function(){e._reset(),t()};return Se(n,"scroll",a.bind(n,"expand")),Se(i,"scroll",a.bind(i,"shrink")),e}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(Pe("resize",n)),i&&i.clientWidth0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index-1?t.split("\n"):t}function Ve(t){var e=N.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:ze(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:ze(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:ze(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:ze(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:ze(t.titleFontStyle,e.defaultFontStyle),titleFontSize:ze(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:ze(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:ze(t.footerFontStyle,e.defaultFontStyle),footerFontSize:ze(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function He(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function je(t){return Ee([],We(t))}var qe=K.extend({initialize:function(){this._model=Ve(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=Ee(o,We(i)),o=Ee(o,We(a)),o=Ee(o,We(r))},getBeforeBody:function(){return je(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return H.each(t,(function(t){var r={before:[],lines:[],after:[]};Ee(r.before,We(i.beforeLabel.call(n,t,e))),Ee(r.lines,i.label.call(n,t,e)),Ee(r.after,We(i.afterLabel.call(n,t,e))),a.push(r)})),a},getAfterBody:function(){return je(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=Ee(r,We(n)),r=Ee(r,We(i)),r=Ee(r,We(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=Ve(c),p=h._active,m=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},x={width:f.width,height:f.height},y={x:f.caretX,y:f.caretY};if(p.length){g.opacity=1;var _=[],k=[];y=Be[c.position].call(h,p,h._eventPosition);var w=[];for(e=0,n=p.length;ei.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,x,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.yl.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,x),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=x.width,g.height=x.height,g.caretX=y.x,g.caretY=y.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===c)s=g+m/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+p)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+p-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+m)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=Ne(e.rtl,e.x,e.width);for(t.x=He(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=H.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,H.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),H.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!H.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),Ue=Be,Ye=qe;Ye.positioners=Ue;var Ge=H.valueOrDefault;function Xe(){return H.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?H.merge(e[t][a],[Re.getScaleDefaults(r),o]):H.merge(e[t][a],o)}else H._merger(t,e,n,i)}})}function Ke(){return H.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||Object.create(null),r=n[t];"scales"===t?e[t]=Xe(a,r):"scale"===t?e[t]=H.merge(a,[Re.getScaleDefaults(r.type),r]):H._merger(t,e,n,i)}})}function Ze(t){var e=t.options;H.each(t.scales,(function(e){pe.removeBox(t,e)})),e=Ke(N.global,N[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function $e(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(H.findIndex(t,a)>=0);return i}function Je(t){return"top"===t||"bottom"===t}function Qe(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}N._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var tn=function(t,e){return this.construct(t,e),this};H.extend(tn.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||Object.create(null)).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=Ke(N.global,N[t.type],t.options||{}),t}(e);var i=Oe.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=H.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,tn.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Le.notify(t,"beforeInit"),H.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Le.notify(t,"afterInit"),t},clear:function(){return H.canvas.clear(this),this},stop:function(){return J.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(H.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:H.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",H.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Le.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;H.each(e.xAxes,(function(t,n){t.id||(t.id=$e(e.xAxes,"x-axis-",n))})),H.each(e.yAxes,(function(t,n){t.id||(t.id=$e(e.yAxes,"y-axis-",n))})),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce((function(t,e){return t[e]=!1,t}),{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map((function(t){return{options:t,dtype:"category",dposition:"bottom"}})),(e.scales.yAxes||[]).map((function(t){return{options:t,dtype:"linear",dposition:"left"}})))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),H.each(i,(function(e){var i=e.options,r=i.id,o=Ge(i.type,e.dtype);Je(i.position)!==Je(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Re.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)})),H.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Re.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t=0;--n)this.drawDataset(e[n],t);Le.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Le.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Le.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Le.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Le.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return re.modes.single(this,t)},getElementsAtEvent:function(t){return re.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return re.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=re.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return re.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=H.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=H.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(H.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},sn=H.isArray,ln=H.isNullOrUndef,un=H.valueOrDefault,dn=H.valueAtIndexOrDefault;function hn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=rl+1e-6)))return o}function cn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,p,m,v=n.length,b=[],x=[],y=[],_=0,k=0;for(a=0;ae){for(n=0;n=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-fn(l.gridLines)-u.padding-gn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=H.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){H.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){H.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=fn(o)+gn(r)),u?s&&(e.height=fn(o)+gn(r)):e.height=t.maxHeight,a.display&&s){var d=mn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,p=h.highest,m=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,x=H.toRadians(t.labelRotation),y=Math.cos(x),_=Math.sin(x),k=_*g.width+y*(p.height-(b?p.offset:0))+(b?0:m);e.height=Math.min(t.maxHeight,e.height+k+v);var w,M,S=t.getPixelForTick(0)-t.left,C=t.right-t.getPixelForTick(t.getTicks().length-1);b?(w=l?y*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):y*f.width+_*f.offset):(w=c.width/2,M=f.width/2),t.paddingLeft=Math.max((w-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-C)*t.width/(t.width-C),0)+3}else{var P=a.mirror?0:g.width+v+m;e.width=Math.min(t.maxWidth,e.width+P),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){H.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(ln(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map((function(t){return t.value})),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;nn-1?null:this.getPixelForDecimal(t*i+(e?i/2:0))},getPixelForDecimal:function(t){return this._reversePixels&&(t=1-t),this._startPixel+t*this._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,r=this.options.ticks,o=this._length,s=r.maxTicksLimit||o/this._tickSize()+1,l=r.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;es)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;iu)return r;return Math.max(u,1)}(l,t,0,s),u>0){for(e=0,n=u-1;e1?(h-d)/(u-1):null,bn(t,i,H.isNullOrUndef(a)?0:d-a,d),bn(t,i,h,H.isNullOrUndef(a)?t.length:h+a),vn(t)}return bn(t,i),vn(t)},_tickSize:function(){var t=this.options.ticks,e=H.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),a=this._getLabelSizes(),r=t.autoSkipPadding||0,o=a?a.widest.width+r:0,s=a?a.highest.height+r:0;return this.isHorizontal()?s*n>o*i?o/n:s/i:s*i=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this._getLabels(),e=this.minIndex,n=this.maxIndex;this.ticks=0===e&&n===t.length-1?t:t.slice(e,n+1)},getLabelForIndex:function(t,e){var n=this.chart;return n.getDatasetMeta(e).controller._getValueScaleId()===this.id?this.getRightValue(n.data.datasets[e].data[t]):this._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;yn.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return _n(e)||_n(n)||(t=o.chart.data.datasets[n].data[e]),_n(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=H.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange);return Math.min(Math.max(e,0),this.ticks.length-1)},getBasePixel:function(){return this.bottom}}),wn={position:"bottom"};kn._defaults=wn;var Mn=H.noop,Sn=H.isNullOrUndef;var Cn=yn.extend({getRightValue:function(t){return"string"==typeof t?+t:yn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=H.sign(t.min),i=H.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,n=e.stepSize,i=e.maxTicksLimit;return n?t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1:(t=this._computeTickLimit(),i=i||11),i&&(t=Math.min(i,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:Mn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:H.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,p=H.niceNum((g-f)/u/l)*l;if(p<1e-14&&Sn(d)&&Sn(h))return[f,g];(r=Math.ceil(g/p)-Math.floor(f/p))>u&&(p=H.niceNum(r*p/u/l)*l),s||Sn(c)?n=Math.pow(10,H._decimalPlaces(p)):(n=Math.pow(10,c),p=Math.ceil(p*n)/n),i=Math.floor(f/p)*p,a=Math.ceil(g/p)*p,s&&(!Sn(d)&&H.almostWhole(d/p,p/1e3)&&(i=d),!Sn(h)&&H.almostWhole(h/p,p/1e3)&&(a=h)),r=(a-i)/p,r=H.almostEquals(r,Math.round(r),p/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Sn(d)?i:d);for(var m=1;me.length-1?null:this.getPixelForValue(e[t])}}),In=Pn;Tn._defaults=In;var Fn=H.valueOrDefault,On=H.math.log10;var Ln={position:"left",ticks:{callback:on.formatters.logarithmic}};function Rn(t,e){return H.isFinite(t)&&t>=0?t:e}var zn=yn.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t0){var e=H.min(t),n=H.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}}))}else for(t=0;t0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(On(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:Rn(e.min),max:Rn(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=Fn(t.min,Math.pow(10,Math.floor(On(e.min)))),o=Math.floor(On(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(On(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(On(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10===++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(ne.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(On(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;yn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=Fn(t.options.ticks.fontSize,N.global.defaultFontSize)/t._length),t._startValue=On(e),t._valueOffset=n,t._valueRange=(On(t.max)-On(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(On(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),Nn=Ln;zn._defaults=Nn;var Bn=H.valueOrDefault,En=H.valueAtIndexOrDefault,Wn=H.options.resolve,Vn={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:on.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Hn(t){var e=t.ticks;return e.display&&t.display?Bn(e.fontSize,N.global.defaultFontSize)+2*e.backdropPaddingY:0}function jn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:ta?{start:e-n,end:e}:{start:e,end:e+n}}function qn(t){return 0===t||180===t?"center":t<180?"left":"right"}function Un(t,e,n,i){var a,r,o=n.y+i/2;if(H.isArray(e))for(a=0,r=e.length;a270||t<90)&&(n.y-=e.h)}function Gn(t){return H.isNumber(t)?t:0}var Xn=Cn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Hn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;H.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);H.each(a.data,(function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))}))}})),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Hn(this.options))},convertTicksToLabels:function(){var t=this;Cn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=H.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""}))},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,n,i,a=H.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;er.r&&(r.r=f.end,o.r=h),g.startr.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=Gn(a),r=Gn(r),o=Gn(o),s=Gn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(H.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this.min,n=this.max;return this.getPointPositionForValue(t||0,this.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=Bn(s.lineWidth,o.lineWidth),u=Bn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Hn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=H.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=En(i.fontColor,s,N.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=H.toDegrees(h);e.textAlign=qn(c),Yn(c,t._pointLabelSizes[s],u),Un(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&H.each(i.ticks,(function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=En(e.color,i-1),u=En(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=H.options._parseFont(n),s=Bn(n.fontColor,N.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",H.each(t.ticks,(function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))})),e.restore()}},_drawTitle:H.noop}),Kn=Vn;Xn._defaults=Kn;var Zn=H._deprecated,$n=H.options.resolve,Jn=H.valueOrDefault,Qn=Number.MIN_SAFE_INTEGER||-9007199254740991,ti=Number.MAX_SAFE_INTEGER||9007199254740991,ei={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ni=Object.keys(ei);function ii(t,e){return t-e}function ai(t){return H.valueOrDefault(t.time.min,t.ticks.min)}function ri(t){return H.valueOrDefault(t.time.max,t.ticks.max)}function oi(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function si(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),H.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),H.isFinite(o)||(o=n.parse(o))),o)}function li(t,e){if(H.isNullOrUndef(e))return null;var n=t.options.time,i=si(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function ui(t,e,n,i){var a,r,o,s=ni.length;for(a=ni.indexOf(t);a=0&&(e[r].major=!0);return e}(t,r,o,n):r}var hi=yn.extend({initialize:function(){this.mergeTicksOptions(),yn.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new rn._date(e.adapters.date);return Zn("time scale",n.format,"time.format","time.parser"),Zn("time scale",n.min,"time.min","ticks.min"),Zn("time scale",n.max,"time.max","ticks.max"),H.mergeIf(n.displayFormats,i.formats()),yn.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),yn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=ti,f=Qn,g=[],p=[],m=[],v=s._getLabels();for(t=0,n=v.length;t1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?ui(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ni.length-1;r>=ni.indexOf(n);r--)if(o=ni[r],ei[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ni[n?ni.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ni.indexOf(t)+1,n=ni.length;ee&&s=0&&t0?s:1}}),ci={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};hi._defaults=ci;var fi={category:kn,linear:Tn,logarithmic:zn,radialLinear:Xn,time:hi},gi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};rn._date.override("function"==typeof t?{_id:"moment",formats:function(){return gi},parse:function(e,n){return"string"==typeof e&&"string"==typeof n?e=t(e,n):e instanceof t||(e=t(e)),e.isValid()?e.valueOf():null},format:function(e,n){return t(e).format(n)},add:function(e,n,i){return t(e).add(n,i).valueOf()},diff:function(e,n,i){return t(e).diff(t(n),i)},startOf:function(e,n,i){return e=t(e),"isoWeek"===n?e.isoWeekday(i).valueOf():e.startOf(n).valueOf()},endOf:function(e,n){return t(e).endOf(n).valueOf()},_create:function(e){return t(e)}}:{}),N._set("global",{plugins:{filler:{propagate:!0}}});var pi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function vi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a0;--r)H.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function ki(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,p=i.spanGaps,m=[],v=[],b=0,x=0;for(t.beginPath(),o=0,s=g;o=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||N.global.defaultColor,o&&s&&r.length&&(H.canvas.clipArea(u,t.chartArea),ki(u,r,o,a,s,i._loop),H.canvas.unclipArea(u)))}},Mi=H.rtl.getRtlAdapter,Si=H.noop,Ci=H.valueOrDefault;function Pi(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}N._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map((function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}}),this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;el.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding})),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],p=n.padding,m=0,v=0;H.each(t.legendItems,(function(t,e){var i=Pi(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(p+=m+n.padding,f.push(m),g.push(v),m=0,v=0),m=Math.max(m,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),p+=m,f.push(m),g.push(v),l.width+=p}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Si,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=N.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=Mi(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Ci(n.fontColor,i.defaultFontColor),g=H.options._parseFont(n),p=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var m=Pi(n,p),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},x=t.isHorizontal();d=x?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},H.rtl.overrideTextDirection(t.ctx,e.textDirection);var y=p+n.padding;H.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=m+p/2+f,_=d.x,k=d.y;h.setWidth(t.minSize.width),x?i>0&&_+g+n.padding>t.left+t.minSize.width&&(k=d.y+=y,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&k+y>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,k=d.y=t.top+b(o,s[d.line]));var w=h.x(_);!function(t,e,i){if(!(isNaN(m)||m<=0)){c.save();var o=Ci(i.lineWidth,r.borderWidth);if(c.fillStyle=Ci(i.fillStyle,a),c.lineCap=Ci(i.lineCap,r.borderCapStyle),c.lineDashOffset=Ci(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Ci(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Ci(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Ci(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=m*Math.SQRT2/2,l=h.xPlus(t,m/2),u=e+p/2;H.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,m),e,m,p),0!==o&&c.strokeRect(h.leftForLtr(t,m),e,m,p);c.restore()}}(w,k,e),v[i].left=h.leftForLtr(w,v[i].width),v[i].top=k,function(t,e,n,i){var a=p/2,r=h.xPlus(t,m+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(w,k,e,f),x?d.x+=g+n.padding:d.y+=y})),H.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Di(t,e){var n=new Ai({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.legend=n}var Ti={id:"legend",_element:Ai,beforeInit:function(t){var e=t.options.legend;e&&Di(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(H.mergeIf(e,N.global.legend),n?(pe.configure(t,n,e),n.options=e):Di(t,e)):n&&(pe.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ii=H.noop;N._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Fi=K.extend({initialize:function(t){H.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Ii,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Ii,beforeSetDimensions:Ii,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Ii,beforeBuildLabels:Ii,buildLabels:Ii,afterBuildLabels:Ii,beforeFit:Ii,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(H.isArray(n.text)?n.text.length:1)*H.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Ii,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=H.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=H.valueOrDefault(n.fontColor,N.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(H.isArray(g))for(var p=0,m=0;m=0;i--){var a=t[i];if(e(a))return a}},H.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},H.almostEquals=function(t,e,n){return Math.abs(t-e)=t},H.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},H.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},H.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},H.toRadians=function(t){return t*(Math.PI/180)},H.toDegrees=function(t){return t*(180/Math.PI)},H._decimalPlaces=function(t){if(H.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},H.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},H.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},H.aliasPixel=function(t){return t%2==0?0:.5},H._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},H.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},H.EPSILON=Number.EPSILON||1e-14,H.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map((function(t){return{model:t._model,deltaK:0,mK:0}})),h=d.length;for(e=0;e0?d[e-1]:null,(a=e0?d[e-1]:null,a=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},H.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},H.niceNum=function(t,e){var n=Math.floor(H.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},H.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},H.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(H.getStyle(r,"padding-left")),u=parseFloat(H.getStyle(r,"padding-top")),d=parseFloat(H.getStyle(r,"padding-right")),h=parseFloat(H.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},H.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},H.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},H._calculatePadding=function(t,e,n){return(e=H.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},H._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},H.getMaximumWidth=function(t){var e=H._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-H._calculatePadding(e,"padding-left",n)-H._calculatePadding(e,"padding-right",n),a=H.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},H.getMaximumHeight=function(t){var e=H._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-H._calculatePadding(e,"padding-top",n)-H._calculatePadding(e,"padding-bottom",n),a=H.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},H.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},H.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},H.fontString=function(t,e,n){return e+" "+t+"px "+n},H.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;on.length){for(o=0;oi&&(i=r),i},H.numberOfLabelLines=function(t){var e=1;return H.each(t,(function(t){H.isArray(t)&&t.length>e&&(e=t.length)})),e},H.color=_?function(t){return t instanceof CanvasGradient&&(t=N.global.defaultColor),_(t)}:function(t){return console.error("Color.js not found!"),t},H.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:H.color(t).saturate(.5).darken(.1).rgbString()}}(),en._adapters=rn,en.Animation=$,en.animationService=J,en.controllers=Jt,en.DatasetController=it,en.defaults=N,en.Element=K,en.elements=kt,en.Interaction=re,en.layouts=pe,en.platform=Oe,en.plugins=Le,en.Scale=yn,en.scaleService=Re,en.Ticks=on,en.Tooltip=Ye,en.helpers.each(fi,(function(t,e){en.scaleService.registerScaleType(e,t,t._defaults)})),Li)Li.hasOwnProperty(Bi)&&en.plugins.register(Li[Bi]);en.platform.initialize();var Ei=en;return"undefined"!=typeof window&&(window.Chart=en),en.Chart=en,en.Legend=Li.legend._element,en.Title=Li.title._element,en.pluginService=en.plugins,en.PluginBase=en.Element.extend({}),en.canvasHelpers=en.helpers.canvas,en.layoutService=en.layouts,en.LinearScaleBase=Cn,en.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){en[t]=function(e,n){return new en(e,en.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Ei})); diff --git a/src/index.html b/src/index.html index d97dd2c..9346376 100644 --- a/src/index.html +++ b/src/index.html @@ -1,17 +1,20 @@ + - - LibrePay - - - - - - + + LibrePay + + + + + + + - - + + - + + \ No newline at end of file From fd4ae166fe9ea34064c7aa9408f9174153de2b9e Mon Sep 17 00:00:00 2001 From: Felix Date: Fri, 26 Mar 2021 20:09:31 +0100 Subject: [PATCH 15/40] add chart bg add chart dummy data --- src/app/dashboard/chart/chart.component.css | 10 ++++++++ src/app/dashboard/chart/chart.component.html | 4 +++- src/app/dashboard/chart/chart.component.ts | 10 +++++++- .../dashboard/summary/summary.component.css | 23 +++++++++++++++++-- .../dashboard/summary/summary.component.html | 3 ++- 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/app/dashboard/chart/chart.component.css b/src/app/dashboard/chart/chart.component.css index e69de29..9ebdd3b 100644 --- a/src/app/dashboard/chart/chart.component.css +++ b/src/app/dashboard/chart/chart.component.css @@ -0,0 +1,10 @@ +.bg { + background-color: #26283A; + margin: 0; + padding: 0; + padding: 2rem; + padding-right: 2rem; + margin: 0 auto; + width: 80%; + border-radius: 0px 0px 5px 5px; +} \ No newline at end of file diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html index 8a42052..128c50a 100644 --- a/src/app/dashboard/chart/chart.component.html +++ b/src/app/dashboard/chart/chart.component.html @@ -1,3 +1,5 @@ -
+
+
+

Chart workds

\ No newline at end of file diff --git a/src/app/dashboard/chart/chart.component.ts b/src/app/dashboard/chart/chart.component.ts index 3345e54..7eb7df7 100644 --- a/src/app/dashboard/chart/chart.component.ts +++ b/src/app/dashboard/chart/chart.component.ts @@ -8,15 +8,23 @@ import { EChartsOption } from 'echarts'; }) export class ChartComponent { chartOption: EChartsOption = { + color: ["#C61A4E"], xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, + + tooltip: { + trigger: 'item', + showDelay: 0, + transitionDuration: 0.2 + }, + yAxis: { type: 'value' }, series: [{ - data: [820, 932, 901, 934, 1290, 1330, 1320], + data: [820, 932, 901, 934, 1290, 1330, 1320, 654, 68, 846, 987, 846, 874], type: 'line', smooth: true }] diff --git a/src/app/dashboard/summary/summary.component.css b/src/app/dashboard/summary/summary.component.css index ec36ddc..3e52d7b 100644 --- a/src/app/dashboard/summary/summary.component.css +++ b/src/app/dashboard/summary/summary.component.css @@ -1,10 +1,11 @@ .header { - background-color: #242635; + background: #242635; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + border-radius: 8px 8px 0px 0px; margin: 0; padding: 0; padding: 2rem; padding-right: 2rem; - border-radius: 22px; border-bottom-left-radius: 0; border-bottom-right-radius: 0; margin: 0 auto; @@ -15,4 +16,22 @@ background-color: #26283A; margin: 0; padding: 6rem; +} + +.sum { + color: #fff; + line-height: 29px; + font-size: 24px; + font-weight: 800; + font-style: normal; + font-family: 'Inter'; +} + +.stoke { + width: 39px; + height: 0px; + left: 272px; + top: 182px; + border: 1px solid #FFFFFF; + transform: rotate(90deg); } \ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.html b/src/app/dashboard/summary/summary.component.html index eceab7f..7f42f4e 100644 --- a/src/app/dashboard/summary/summary.component.html +++ b/src/app/dashboard/summary/summary.component.html @@ -1,3 +1,4 @@
- + Summary +
\ No newline at end of file From dbf7754e1d6ba537fbc179984f7e52b5e63c3eca Mon Sep 17 00:00:00 2001 From: Felix Date: Sat, 27 Mar 2021 17:40:33 +0100 Subject: [PATCH 16/40] add dropdown add custom css --- package-lock.json | 8 +++++ package.json | 1 + src/app/app.module.ts | 3 ++ src/app/dashboard/chart/chart.component.html | 4 +-- .../dashboard/summary/summary.component.css | 29 ++++++++++++++----- .../dashboard/summary/summary.component.html | 16 ++++++++-- .../dashboard/summary/summary.component.ts | 12 ++++++++ src/styles.css | 8 +++-- 8 files changed, 67 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index d45d06b..30db365 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1488,6 +1488,14 @@ "schema-utils": "^2.7.0" } }, + "@ng-select/ng-select": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-6.1.0.tgz", + "integrity": "sha512-uro/zIjL+TRWzbrzNN9IjIusOeLfhCn9cIr5Bq3AsJyxyU7Gdj9kOD5wVrrQ0NVkaQ1BJMcWmUvmYGBXLI6cnA==", + "requires": { + "tslib": "^2.0.0" + } + }, "@ngtools/webpack": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-11.0.5.tgz", diff --git a/package.json b/package.json index d4f915a..2097f0a 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@angular/platform-browser": "~11.0.5", "@angular/platform-browser-dynamic": "~11.0.5", "@angular/router": "~11.0.5", + "@ng-select/ng-select": "^6.1.0", "@swimlane/ngx-charts": "^17.0.0", "angularx-qrcode": "^10.0.11", "chart.js": "^2.9.4", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index a607f33..9c6a226 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -23,6 +23,8 @@ import { ChartComponent } from './dashboard/chart/chart.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { SummaryComponent } from './dashboard/summary/summary.component'; import { NgxEchartsModule } from 'ngx-echarts'; +import { NgSelectModule } from '@ng-select/ng-select'; + const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -51,6 +53,7 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; PushNotificationsModule, ClipboardModule, FormsModule, + NgSelectModule, SocketIoModule.forRoot(config), BrowserAnimationsModule, NgxEchartsModule.forRoot({ diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html index 128c50a..4db0798 100644 --- a/src/app/dashboard/chart/chart.component.html +++ b/src/app/dashboard/chart/chart.component.html @@ -1,5 +1,3 @@
-
- -

Chart workds

\ No newline at end of file + \ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.css b/src/app/dashboard/summary/summary.component.css index 3e52d7b..621ee61 100644 --- a/src/app/dashboard/summary/summary.component.css +++ b/src/app/dashboard/summary/summary.component.css @@ -27,11 +27,26 @@ font-family: 'Inter'; } -.stoke { - width: 39px; - height: 0px; - left: 272px; - top: 182px; - border: 1px solid #FFFFFF; - transform: rotate(90deg); +.grid-container { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-rows: 1fr 1fr 1fr; + gap: 0px 0px; + grid-template-areas: "sum dropdown void1 void" ". . . ." ". . . ."; +} + +.sum { + grid-area: sum; +} + +.void { + grid-area: void; +} + +.dropdown { + grid-area: dropdown; +} + +.void1 { + grid-area: void1; } \ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.html b/src/app/dashboard/summary/summary.component.html index 7f42f4e..e068754 100644 --- a/src/app/dashboard/summary/summary.component.html +++ b/src/app/dashboard/summary/summary.component.html @@ -1,4 +1,16 @@
- Summary -
+ + +
+
+ Summary +
+ +
+
+
\ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.ts b/src/app/dashboard/summary/summary.component.ts index 011993b..40301bc 100644 --- a/src/app/dashboard/summary/summary.component.ts +++ b/src/app/dashboard/summary/summary.component.ts @@ -7,6 +7,18 @@ import { Component, OnInit } from '@angular/core'; }) export class SummaryComponent implements OnInit { + + summary = 1; + + dates = [ + { id: 1, name: 'Today' }, + { id: 2, name: 'Last 3 days' }, + { id: 3, name: 'One month' }, + { id: 4, name: 'Last 3 months' }, + { id: 5, name: 'One year' }, + { id: 6, name: 'Last 3 years' }, + ]; + constructor() { } ngOnInit(): void { diff --git a/src/styles.css b/src/styles.css index 869a5d1..27b2e12 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,14 +1,18 @@ +@import "~@ng-select/ng-select/themes/default.theme.css"; + /* You can add global styles to this file, and also import other style files */ + * { font-family: 'Inter', sans-serif; } -body, html { +body, +html { margin: 0; padding: 0; } -:host{ +:host { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } From 5c6aab984c4e633597ec4624053e90e9225a1773 Mon Sep 17 00:00:00 2001 From: Felix Date: Sat, 27 Mar 2021 18:02:35 +0100 Subject: [PATCH 17/40] add custom dropdown css --- src/dropdown.css | 335 +++++++++++++++++++++++++++++++++++++++++++++++ src/styles.css | 2 +- 2 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 src/dropdown.css diff --git a/src/dropdown.css b/src/dropdown.css new file mode 100644 index 0000000..9219787 --- /dev/null +++ b/src/dropdown.css @@ -0,0 +1,335 @@ +.ng-select.ng-select-opened>.ng-select-container { + background: #242635; + border-color: #C61A4E #C61A4E #C61A4E +} + +.ng-select.ng-select-opened>.ng-select-container:hover { + box-shadow: none +} + +.ng-select.ng-select-opened>.ng-select-container .ng-arrow { + top: -2px; + border-color: transparent transparent #C61A4E; + border-width: 0 5px 5px +} + +.ng-select.ng-select-opened>.ng-select-container .ng-arrow:hover { + border-color: transparent transparent #333 +} + +.ng-select.ng-select-opened.ng-select-bottom>.ng-select-container { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0 +} + +.ng-select.ng-select-opened.ng-select-top>.ng-select-container { + border-top-right-radius: 0; + border-top-left-radius: 0 +} + +.ng-select.ng-select-focused:not(.ng-select-opened)>.ng-select-container { + border-color: #007eff; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 3px rgba(0, 126, 255, 0.1) +} + +.ng-select.ng-select-disabled>.ng-select-container { + background-color: #C61A4E +} + +.ng-select .ng-has-value .ng-placeholder { + display: none +} + +.ng-select .ng-select-container { + color: #fff; + background-color: #242635; + border-radius: 0px; + border: 1px solid #C61A4E; + min-height: 36px; + align-items: center +} + +.ng-select .ng-select-container:hover { + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06) +} + +.ng-select .ng-select-container .ng-value-container { + align-items: center; + padding-left: 10px +} + +[dir="rtl"] .ng-select .ng-select-container .ng-value-container { + padding-right: 5px; + padding-left: 0 +} + +.ng-select .ng-select-container .ng-value-container .ng-placeholder { + color: #C61A4E; +} + +.ng-select.ng-select-single .ng-select-container { + height: 36px +} + +.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input { + top: 5px; + left: 0; + padding-left: 10px; + padding-right: 50px +} + +[dir="rtl"] .ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input { + padding-right: 10px; + padding-left: 50px +} + +.ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value { + background-color: #242635; + border: 1px solid #242635; +} + +.ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value .ng-value-label { + padding: 0 5px +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container { + padding-top: 5px; + padding-left: 7px +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container { + padding-right: 7px; + padding-left: 0 +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value { + font-size: .9em; + margin-bottom: 5px; + background-color: #242635; + border-radius: 2px; + margin-right: 5px +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value { + margin-right: 0; + margin-left: 5px +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled { + background-color: #242635 +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled .ng-value-label { + padding-left: 5px +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled .ng-value-label { + padding-left: 0; + padding-right: 5px +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-label { + display: inline-block; + padding: 1px 5px +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon { + display: inline-block; + padding: 1px 5px +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon:hover { + background-color: #242635 +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.left { + border-right: 1px solid #242635; +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.left { + border-left: 1px solid #242635; + border-right: none +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.right { + border-left: 1px solid #242635 +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.right { + border-left: 0; + border-right: 1px solid #242635 +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-input { + padding: 0 0 3px 3px +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-input { + padding: 0 3px 3px 0 +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder { + top: 5px; + padding-bottom: 5px; + padding-left: 3px +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder { + padding-right: 3px; + padding-left: 0 +} + +.ng-select .ng-clear-wrapper { + color: #999 +} + +.ng-select .ng-clear-wrapper:hover .ng-clear { + color: #D0021B; + box-shadow: 10px 10px 105px -30px rgba(198, 26, 78, 0.6); +} + +.ng-select .ng-spinner-zone { + padding: 5px 5px 0 0 +} + +[dir="rtl"] .ng-select .ng-spinner-zone { + padding: 5px 0 0 5px +} + +.ng-select .ng-arrow-wrapper { + width: 25px; + padding-right: 5px +} + +[dir="rtl"] .ng-select .ng-arrow-wrapper { + padding-left: 5px; + padding-right: 0 +} + +.ng-select .ng-arrow-wrapper:hover .ng-arrow { + border-top-color: #666 +} + +.ng-select .ng-arrow-wrapper .ng-arrow { + border-color: #C61A4E transparent transparent; + border-style: solid; + border-width: 5px 5px 2.5px +} + +.ng-dropdown-panel { + background-color: #242635; + border: 1px solid #C61A4E; + box-shadow: 10px 10px 105px -30px rgba(198, 26, 78, 0.6); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06); + left: 0 +} + +.ng-dropdown-panel.ng-select-bottom { + top: 100%; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + border-top-color: #C61A4E; + box-shadow: 10px 10px 105px -30px rgba(198, 26, 78, 0.6); + margin-top: -1px +} + +.ng-dropdown-panel.ng-select-bottom .ng-dropdown-panel-items .ng-option:last-child { + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px +} + +.ng-dropdown-panel.ng-select-top { + bottom: 100%; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom-color: #242635; + margin-bottom: -1px +} + +.ng-dropdown-panel.ng-select-top .ng-dropdown-panel-items .ng-option:first-child { + border-top-right-radius: 4px; + border-top-left-radius: 4px +} + +.ng-dropdown-panel .ng-dropdown-header { + border-bottom: 1px solid #242635; + padding: 5px 7px +} + +.ng-dropdown-panel .ng-dropdown-footer { + border-top: 1px solid #242635; + padding: 5px 7px +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup { + user-select: none; + padding: 8px 10px; + font-weight: 500; + color: rgba(0, 0, 0, 0.54); + cursor: pointer +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-disabled { + cursor: default +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-marked { + background-color: #242635; +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-selected, +.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-selected.ng-option-marked { + background-color: #242635; + font-weight: 600 +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option { + background-color: #242635; + color: rgba(255, 255, 255, 0.87); + padding: 8px 10px +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected, +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected.ng-option-marked { + color: rgb(255, 255, 255); + background-color: #242635 +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected .ng-option-label, +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected.ng-option-marked .ng-option-label { + font-weight: 600 +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked { + background-color: #f5faff; + color: #333 +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled { + color: #ccc +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-child { + padding-left: 22px +} + +[dir="rtl"] .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-child { + padding-right: 22px; + padding-left: 0 +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option .ng-tag-label { + font-size: 80%; + font-weight: 400; + padding-right: 5px +} + +[dir="rtl"] .ng-dropdown-panel .ng-dropdown-panel-items .ng-option .ng-tag-label { + padding-left: 5px; + padding-right: 0 +} + +[dir="rtl"] .ng-dropdown-panel { + direction: rtl; + text-align: right +} \ No newline at end of file diff --git a/src/styles.css b/src/styles.css index 27b2e12..fd7b5c8 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,4 +1,4 @@ -@import "~@ng-select/ng-select/themes/default.theme.css"; +@import "dropdown.css"; /* You can add global styles to this file, and also import other style files */ From 07e3f8ca538999939febd47548af1a2923df4301 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 4 Apr 2021 15:05:55 +0200 Subject: [PATCH 18/40] edit chart --- package-lock.json | 52 ++++++++++++++ package.json | 5 ++ src/app/app.module.ts | 8 ++- src/app/dashboard/chart/chart.component.css | 19 ++++- src/app/dashboard/chart/chart.component.html | 11 ++- src/app/dashboard/chart/chart.component.ts | 7 ++ .../dashboard/summary/summary.component.css | 2 +- src/app/dashboard/widget/widget.component.css | 72 +++++++++++++++++++ .../dashboard/widget/widget.component.html | 8 +++ .../dashboard/widget/widget.component.spec.ts | 25 +++++++ src/app/dashboard/widget/widget.component.ts | 21 ++++++ 11 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 src/app/dashboard/widget/widget.component.css create mode 100644 src/app/dashboard/widget/widget.component.html create mode 100644 src/app/dashboard/widget/widget.component.spec.ts create mode 100644 src/app/dashboard/widget/widget.component.ts diff --git a/package-lock.json b/package-lock.json index 30db365..e15e454 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1469,6 +1469,58 @@ "to-fast-properties": "^2.0.0" } }, + "@fortawesome/angular-fontawesome": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@fortawesome/angular-fontawesome/-/angular-fontawesome-0.8.2.tgz", + "integrity": "sha512-K/AiykA4YbHKE6XKEtZ0ZvVRQocUHyk+79HYWIfhGy3teHpzxsUqB/UjDaxivgBd6dF6ihlzgEbgrDMHlGNwGg==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + } + } + }, + "@fortawesome/fontawesome-common-types": { + "version": "0.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz", + "integrity": "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "1.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz", + "integrity": "sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, + "@fortawesome/free-brands-svg-icons": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.3.tgz", + "integrity": "sha512-1hirPcbjj72ZJtFvdnXGPbAbpn3Ox6mH3g5STbANFp3vGSiE5u5ingAKV06mK6ZVqNYxUPlh4DlTnaIvLtF2kw==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, + "@fortawesome/free-regular-svg-icons": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.15.3.tgz", + "integrity": "sha512-q4/p8Xehy9qiVTdDWHL4Z+o5PCLRChePGZRTXkl+/Z7erDVL8VcZUuqzJjs6gUz6czss4VIPBRdCz6wP37/zMQ==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz", + "integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, "@istanbuljs/schema": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", diff --git a/package.json b/package.json index 2097f0a..953c74e 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,11 @@ "@angular/platform-browser": "~11.0.5", "@angular/platform-browser-dynamic": "~11.0.5", "@angular/router": "~11.0.5", + "@fortawesome/angular-fontawesome": "^0.8.2", + "@fortawesome/fontawesome-svg-core": "^1.2.34", + "@fortawesome/free-brands-svg-icons": "^5.15.2", + "@fortawesome/free-regular-svg-icons": "^5.15.2", + "@fortawesome/free-solid-svg-icons": "^5.15.2", "@ng-select/ng-select": "^6.1.0", "@swimlane/ngx-charts": "^17.0.0", "angularx-qrcode": "^10.0.11", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9c6a226..3d75abf 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -24,6 +24,8 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { SummaryComponent } from './dashboard/summary/summary.component'; import { NgxEchartsModule } from 'ngx-echarts'; import { NgSelectModule } from '@ng-select/ng-select'; +import { WidgetComponent } from './dashboard/widget/widget.component'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @@ -42,7 +44,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; OverviewComponent, DashboardHeaderComponent, ChartComponent, - SummaryComponent + SummaryComponent, + WidgetComponent ], imports: [ BrowserModule, @@ -58,7 +61,8 @@ const config: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; BrowserAnimationsModule, NgxEchartsModule.forRoot({ echarts: () => import('echarts') - }) + }), + FontAwesomeModule ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/dashboard/chart/chart.component.css b/src/app/dashboard/chart/chart.component.css index 9ebdd3b..811a203 100644 --- a/src/app/dashboard/chart/chart.component.css +++ b/src/app/dashboard/chart/chart.component.css @@ -7,4 +7,21 @@ margin: 0 auto; width: 80%; border-radius: 0px 0px 5px 5px; -} \ No newline at end of file +} + +.grid-container { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-rows: 1fr; + gap: 0px 0px; + grid-template-areas: + "a b c d"; +} + +.a { grid-area: a; } + +.b { grid-area: b; } + +.c { grid-area: c; } + +.d { grid-area: d; } diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html index 4db0798..0df0ac0 100644 --- a/src/app/dashboard/chart/chart.component.html +++ b/src/app/dashboard/chart/chart.component.html @@ -1,3 +1,10 @@
-
-
\ No newline at end of file + +
+
+
+
+
+
+
+ diff --git a/src/app/dashboard/chart/chart.component.ts b/src/app/dashboard/chart/chart.component.ts index 7eb7df7..ce5acf5 100644 --- a/src/app/dashboard/chart/chart.component.ts +++ b/src/app/dashboard/chart/chart.component.ts @@ -1,5 +1,6 @@ import { Component} from '@angular/core' import { EChartsOption } from 'echarts'; +import {faArrowDown, faCircle, faExclamationCircle, faMoneyBill} from '@fortawesome/free-solid-svg-icons'; @Component({ selector: 'app-chart', @@ -7,6 +8,12 @@ import { EChartsOption } from 'echarts'; styleUrls: ['./chart.component.css'] }) export class ChartComponent { + + failedicon = faExclamationCircle; + crypto = faCircle; + downn = faArrowDown; + money = faMoneyBill; + chartOption: EChartsOption = { color: ["#C61A4E"], xAxis: { diff --git a/src/app/dashboard/summary/summary.component.css b/src/app/dashboard/summary/summary.component.css index 621ee61..2dfd9e4 100644 --- a/src/app/dashboard/summary/summary.component.css +++ b/src/app/dashboard/summary/summary.component.css @@ -30,7 +30,7 @@ .grid-container { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; - grid-template-rows: 1fr 1fr 1fr; + grid-template-rows: 1fr; gap: 0px 0px; grid-template-areas: "sum dropdown void1 void" ". . . ." ". . . ."; } diff --git a/src/app/dashboard/widget/widget.component.css b/src/app/dashboard/widget/widget.component.css new file mode 100644 index 0000000..f00960d --- /dev/null +++ b/src/app/dashboard/widget/widget.component.css @@ -0,0 +1,72 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@500&display=swap'); + +.card{ + + + width: 90%; + filter: drop-shadow(0px 0px 25px rgba(198, 26, 78, 0.3)); + line-height: 0.1; + background: #212131; + border-radius: 7px; +} + + + +.title{ + color: white; + font-size: 10pt; + font-family: 'Inter', sans-serif; + padding-top: 20px; + padding-left: 20px; +} + +.content{ + color: white; + font-size: 20pt; + font-family: 'Inter', sans-serif; + font-weight: bold; + line-height: 1.8; + padding-left: 20px; +} + +.subcontent{ + color: white; + font-family: 'Inter', sans-serif; + padding-left: 20px; + color: chartreuse; + line-height: 1.8; + +} + +.bild{ + color: white; + font-size: 2.5rem; + display: block; + width: 100%; + text-align: center; + margin-top: 50px; + +} + +.grid-container { + display: grid; + grid-template-columns: 0.2fr 1fr; + grid-template-rows: 1fr 1fr 1fr; + gap: 0px 0px; + grid-template-areas: + "ico tit" + "ico con" + "ico sub"; +} + +.ico { + grid-area: ico; + background: #1D1D28; + border-radius: 8px; +} + +.tit { grid-area: tit; } + +.con { grid-area: con; } + +.sub { grid-area: sub; } diff --git a/src/app/dashboard/widget/widget.component.html b/src/app/dashboard/widget/widget.component.html new file mode 100644 index 0000000..7a7b21b --- /dev/null +++ b/src/app/dashboard/widget/widget.component.html @@ -0,0 +1,8 @@ +
+
+
+

{{title}}

+
{{content}}
+
{{subcontent}}
+
+
diff --git a/src/app/dashboard/widget/widget.component.spec.ts b/src/app/dashboard/widget/widget.component.spec.ts new file mode 100644 index 0000000..74af5fd --- /dev/null +++ b/src/app/dashboard/widget/widget.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { WidgetComponent } from './widget.component'; + +describe('WidgetComponent', () => { + let component: WidgetComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ WidgetComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(WidgetComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/widget/widget.component.ts b/src/app/dashboard/widget/widget.component.ts new file mode 100644 index 0000000..1d731ae --- /dev/null +++ b/src/app/dashboard/widget/widget.component.ts @@ -0,0 +1,21 @@ +import { Component, Input, OnInit } from '@angular/core'; +import {faQuestion, IconDefinition} from '@fortawesome/free-solid-svg-icons'; + +@Component({ + selector: 'dashboard-widget', + templateUrl: './widget.component.html', + styleUrls: ['./widget.component.css'] +}) +export class WidgetComponent implements OnInit { + + @Input() title = ''; + @Input() content = ''; + @Input() subcontent = ''; + @Input() icon: IconDefinition = faQuestion; + + constructor() { } + + ngOnInit(): void {} + + +} From 70bed6195e63304f5eb1b793723aa9dce7620b84 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:42:34 +0100 Subject: [PATCH 19/40] merge master --- src/app/app.module.ts | 6 ++++- src/app/dashboard/dashboard.component.css | 0 src/app/dashboard/dashboard.component.html | 1 + src/app/dashboard/dashboard.component.spec.ts | 25 +++++++++++++++++++ src/app/dashboard/dashboard.component.ts | 15 +++++++++++ 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/app/dashboard/dashboard.component.css create mode 100644 src/app/dashboard/dashboard.component.html create mode 100644 src/app/dashboard/dashboard.component.spec.ts create mode 100644 src/app/dashboard/dashboard.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index fd5b031..b1447bf 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -8,6 +8,7 @@ import { QRCodeModule } from 'angularx-qrcode'; import { PayComponent } from './pay/pay.component'; import { RouterModule } from '@angular/router'; import { HelloComponent } from './hello/hello.component'; +import { SocketIoConfig, SocketIoModule } from 'ngx-socket-io'; import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from 'src/routes'; import { NotFoundComponent } from './not-found/not-found.component'; @@ -15,6 +16,7 @@ import { CartComponent } from './cart/cart.component'; import { PushNotificationsModule } from 'ng-push-ivy'; import { ClipboardModule } from 'ngx-clipboard'; import { environment } from '../environments/environment'; +import { DashboardComponent } from './dashboard/dashboard.component'; @NgModule({ declarations: [ @@ -24,13 +26,15 @@ import { environment } from '../environments/environment'; PayComponent, HelloComponent, NotFoundComponent, - CartComponent + CartComponent, + DashboardComponent ], imports: [ BrowserModule, QRCodeModule, HttpClientModule, AppRoutingModule, + SocketIoModule.forRoot(config), PushNotificationsModule, ClipboardModule ], diff --git a/src/app/dashboard/dashboard.component.css b/src/app/dashboard/dashboard.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html new file mode 100644 index 0000000..9c5fce9 --- /dev/null +++ b/src/app/dashboard/dashboard.component.html @@ -0,0 +1 @@ +

dashboard works!

diff --git a/src/app/dashboard/dashboard.component.spec.ts b/src/app/dashboard/dashboard.component.spec.ts new file mode 100644 index 0000000..5ec4ff8 --- /dev/null +++ b/src/app/dashboard/dashboard.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DashboardComponent } from './dashboard.component'; + +describe('DashboardComponent', () => { + let component: DashboardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ DashboardComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(DashboardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts new file mode 100644 index 0000000..38138a3 --- /dev/null +++ b/src/app/dashboard/dashboard.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-dashboard', + templateUrl: './dashboard.component.html', + styleUrls: ['./dashboard.component.css'] +}) +export class DashboardComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} From fb3bec7470d205f18e39a60e664e320e1bb84567 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:57:43 +0100 Subject: [PATCH 20/40] add login subcomponent --- src/app/app.module.ts | 4 ++- src/app/dashboard/login/login.component.css | 0 src/app/dashboard/login/login.component.html | 1 + .../dashboard/login/login.component.spec.ts | 25 +++++++++++++++++++ src/app/dashboard/login/login.component.ts | 15 +++++++++++ 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/app/dashboard/login/login.component.css create mode 100644 src/app/dashboard/login/login.component.html create mode 100644 src/app/dashboard/login/login.component.spec.ts create mode 100644 src/app/dashboard/login/login.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index b1447bf..173ae1f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -17,6 +17,7 @@ import { PushNotificationsModule } from 'ng-push-ivy'; import { ClipboardModule } from 'ngx-clipboard'; import { environment } from '../environments/environment'; import { DashboardComponent } from './dashboard/dashboard.component'; +import { LoginComponent } from './dashboard/login/login.component'; @NgModule({ declarations: [ @@ -27,7 +28,8 @@ import { DashboardComponent } from './dashboard/dashboard.component'; HelloComponent, NotFoundComponent, CartComponent, - DashboardComponent + DashboardComponent, + LoginComponent ], imports: [ BrowserModule, diff --git a/src/app/dashboard/login/login.component.css b/src/app/dashboard/login/login.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/login/login.component.html b/src/app/dashboard/login/login.component.html new file mode 100644 index 0000000..147cfc4 --- /dev/null +++ b/src/app/dashboard/login/login.component.html @@ -0,0 +1 @@ +

login works!

diff --git a/src/app/dashboard/login/login.component.spec.ts b/src/app/dashboard/login/login.component.spec.ts new file mode 100644 index 0000000..d2c0e6c --- /dev/null +++ b/src/app/dashboard/login/login.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LoginComponent } from './login.component'; + +describe('LoginComponent', () => { + let component: LoginComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LoginComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts new file mode 100644 index 0000000..4f58421 --- /dev/null +++ b/src/app/dashboard/login/login.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.css'] +}) +export class LoginComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} From f72be124fd75e2f433844d1ccda25dedf311d2f3 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 18:55:26 +0100 Subject: [PATCH 21/40] add login with dummy Data add login page add subcomponents --- src/app/app.module.ts | 12 +- src/app/dashboard.service.spec.ts | 16 +++ src/app/dashboard.service.ts | 28 ++++ src/app/dashboard/dashboard.component.html | 3 +- src/app/dashboard/dashboard.component.ts | 3 +- src/app/dashboard/header/header.component.css | 10 ++ .../dashboard/header/header.component.html | 3 + .../dashboard/header/header.component.spec.ts | 25 ++++ src/app/dashboard/header/header.component.ts | 20 +++ src/app/dashboard/login/login.component.css | 133 ++++++++++++++++++ src/app/dashboard/login/login.component.html | 11 +- src/app/dashboard/login/login.component.ts | 22 ++- .../dashboard/overview/overview.component.css | 0 .../overview/overview.component.html | 1 + .../overview/overview.component.spec.ts | 25 ++++ .../dashboard/overview/overview.component.ts | 15 ++ src/assets/history.svg | 1 + src/routes.ts | 11 ++ 18 files changed, 331 insertions(+), 8 deletions(-) create mode 100644 src/app/dashboard.service.spec.ts create mode 100644 src/app/dashboard.service.ts create mode 100644 src/app/dashboard/header/header.component.css create mode 100644 src/app/dashboard/header/header.component.html create mode 100644 src/app/dashboard/header/header.component.spec.ts create mode 100644 src/app/dashboard/header/header.component.ts create mode 100644 src/app/dashboard/overview/overview.component.css create mode 100644 src/app/dashboard/overview/overview.component.html create mode 100644 src/app/dashboard/overview/overview.component.spec.ts create mode 100644 src/app/dashboard/overview/overview.component.ts create mode 100644 src/assets/history.svg diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 173ae1f..41febb2 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -6,7 +6,6 @@ import { HeaderComponent } from './header/header.component'; import { PaymentComponent } from './payment/payment.component'; import { QRCodeModule } from 'angularx-qrcode'; import { PayComponent } from './pay/pay.component'; -import { RouterModule } from '@angular/router'; import { HelloComponent } from './hello/hello.component'; import { SocketIoConfig, SocketIoModule } from 'ngx-socket-io'; import { HttpClientModule } from '@angular/common/http'; @@ -18,6 +17,9 @@ import { ClipboardModule } from 'ngx-clipboard'; import { environment } from '../environments/environment'; import { DashboardComponent } from './dashboard/dashboard.component'; import { LoginComponent } from './dashboard/login/login.component'; +import { FormsModule } from '@angular/forms'; +import { OverviewComponent } from './dashboard/overview/overview.component'; +import { DashboardHeaderComponent } from './dashboard/header/header.component'; @NgModule({ declarations: [ @@ -29,7 +31,9 @@ import { LoginComponent } from './dashboard/login/login.component'; NotFoundComponent, CartComponent, DashboardComponent, - LoginComponent + LoginComponent, + OverviewComponent, + DashboardHeaderComponent ], imports: [ BrowserModule, @@ -38,7 +42,9 @@ import { LoginComponent } from './dashboard/login/login.component'; AppRoutingModule, SocketIoModule.forRoot(config), PushNotificationsModule, - ClipboardModule + ClipboardModule, + FormsModule, + SocketIoModule.forRoot(config) ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/dashboard.service.spec.ts b/src/app/dashboard.service.spec.ts new file mode 100644 index 0000000..79e72a6 --- /dev/null +++ b/src/app/dashboard.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { DashboardService } from './dashboard.service'; + +describe('DashboardService', () => { + let service: DashboardService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(DashboardService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard.service.ts b/src/app/dashboard.service.ts new file mode 100644 index 0000000..3b14b88 --- /dev/null +++ b/src/app/dashboard.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; + +export interface IUser { + username: string; + token: string; +} + +@Injectable({ + providedIn: 'root' +}) +export class DashboardService { + + user: IUser | undefined; + + constructor() { } + + login(username: string, password: string): boolean { + if (username === 'admin' && password === 'password') { + this.user = { + username: 'admin', + token: 'abc' + } + return true; + } else { + return false; + } + } +} diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 9c5fce9..8687f04 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1 +1,2 @@ -

dashboard works!

+ + \ No newline at end of file diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts index 38138a3..b9a91a8 100644 --- a/src/app/dashboard/dashboard.component.ts +++ b/src/app/dashboard/dashboard.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { DashboardService } from '../dashboard.service'; @Component({ selector: 'app-dashboard', @@ -7,7 +8,7 @@ import { Component, OnInit } from '@angular/core'; }) export class DashboardComponent implements OnInit { - constructor() { } + constructor(public dashboard: DashboardService) { } ngOnInit(): void { } diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css new file mode 100644 index 0000000..6f04bdd --- /dev/null +++ b/src/app/dashboard/header/header.component.css @@ -0,0 +1,10 @@ +.header { + position: fixed; + top: 1rem; + left: 5vw; + width: 90vw; + margin: 0 auto; + background-color: #27293D; + z-index: 999; + border-radius: 8px; +} \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html new file mode 100644 index 0000000..d085ff5 --- /dev/null +++ b/src/app/dashboard/header/header.component.html @@ -0,0 +1,3 @@ +
+

HEADER

+
\ No newline at end of file diff --git a/src/app/dashboard/header/header.component.spec.ts b/src/app/dashboard/header/header.component.spec.ts new file mode 100644 index 0000000..381e8e8 --- /dev/null +++ b/src/app/dashboard/header/header.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HeaderComponent } from './header.component'; + +describe('HeaderComponent', () => { + let component: HeaderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ HeaderComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/header/header.component.ts b/src/app/dashboard/header/header.component.ts new file mode 100644 index 0000000..1a76e2e --- /dev/null +++ b/src/app/dashboard/header/header.component.ts @@ -0,0 +1,20 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { DashboardService } from 'src/app/dashboard.service'; + +@Component({ + selector: 'dashboard-header', + templateUrl: './header.component.html', + styleUrls: ['./header.component.css'] +}) +export class DashboardHeaderComponent implements OnInit { + + constructor( + public dashboard: DashboardService, + public router: Router + ) { } + + ngOnInit(): void { + } + +} diff --git a/src/app/dashboard/login/login.component.css b/src/app/dashboard/login/login.component.css index e69de29..7309446 100644 --- a/src/app/dashboard/login/login.component.css +++ b/src/app/dashboard/login/login.component.css @@ -0,0 +1,133 @@ +.frame { + background-color: #1D1D28; + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + overflow: hidden; + font-family: 'Inter', sans-serif; +} + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400&display=swap'); +.btn { + display: inline-block; + *display: inline; + *zoom: 1; + padding: 4px 10px 4px; + margin-bottom: 0; + font-size: 13px; + line-height: 18px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + background-color: #f5f5f5; + background-repeat: repeat-x; + border-color: #e6e6e6 #e6e6e6 #e6e6e6; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border: 1px solid #e6e6e6; + border-radius: 4px; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + cursor: pointer; + *margin-left: .3em; +} + +.btn:hover, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + background-color: #e6e6e6; +} + +.btn-large { + padding: 9px 14px; + font-size: 15px; + line-height: normal; + border-radius: 5px; +} + +.btn:hover { + color: #333333; + text-decoration: none; + background-color: #e6e6e6; + background-position: 0 -15px; + transition: background-position 0.1s linear; + transition: ease 0.5; +} + +.btn-primary, +.btn-primary:hover { + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + color: #ffffff; +} + +.btn-primary.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn-primary { + background-color: #1D1D28; + background-image: linear-gradient(top, #6eb6de, #4a77d4); + background-repeat: repeat-x; + border: 1px solid #3762bc; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.4); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.5); + transition: ease; +} + +.btn-primary:hover, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + filter: none; + background-color: #4a77d4; +} + +.btn-block { + width: 100%; + display: block; +} + +* { + box-sizing: border-box; +} + +.login { + position: absolute; + top: 50%; + left: 50%; + margin: -150px 0 0 -150px; + width: 300px; + height: 300px; +} + +.login h1 { + color: #fff; + text-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + letter-spacing: 1px; + text-align: center; + font-weight: 200; +} + +input { + width: 100%; + margin-bottom: 10px; + background: #1D1D28; + border: none; + outline: none; + padding: 10px; + font-size: 13px; + color: #fff; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3); + border: 1px solid rgb(138, 138, 138); + border-radius: 4px; + box-shadow: inset 0 -5px 45px rgba(100, 100, 100, 0), 0 1px 1px rgba(255, 255, 255, 0.2); + transition: box-shadow .5s ease; +} + +input:focus { + box-shadow: inset 0 -5px 45px rgba(100, 100, 100, 0.4), 0 1px 1px rgba(255, 255, 255, 0.2); +} \ No newline at end of file diff --git a/src/app/dashboard/login/login.component.html b/src/app/dashboard/login/login.component.html index 147cfc4..ac07479 100644 --- a/src/app/dashboard/login/login.component.html +++ b/src/app/dashboard/login/login.component.html @@ -1 +1,10 @@ -

login works!

+
+ +
\ No newline at end of file diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts index 4f58421..e0420ea 100644 --- a/src/app/dashboard/login/login.component.ts +++ b/src/app/dashboard/login/login.component.ts @@ -1,4 +1,6 @@ import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { DashboardService } from 'src/app/dashboard.service'; @Component({ selector: 'app-login', @@ -7,9 +9,25 @@ import { Component, OnInit } from '@angular/core'; }) export class LoginComponent implements OnInit { - constructor() { } + username = ''; + password = ''; + + constructor( + public dashboard: DashboardService, + private router: Router + ) { } ngOnInit(): void { } -} + login() { + const loginStatus = this.dashboard.login(this.username, this.password); + + if (loginStatus) { + this.router.navigate(['dashboard', 'overview']); + } else { + // TODO: Meldung anzeigen + } + } + +} \ No newline at end of file diff --git a/src/app/dashboard/overview/overview.component.css b/src/app/dashboard/overview/overview.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/overview/overview.component.html b/src/app/dashboard/overview/overview.component.html new file mode 100644 index 0000000..57c67df --- /dev/null +++ b/src/app/dashboard/overview/overview.component.html @@ -0,0 +1 @@ +

overview works!

diff --git a/src/app/dashboard/overview/overview.component.spec.ts b/src/app/dashboard/overview/overview.component.spec.ts new file mode 100644 index 0000000..44a847e --- /dev/null +++ b/src/app/dashboard/overview/overview.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OverviewComponent } from './overview.component'; + +describe('OverviewComponent', () => { + let component: OverviewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OverviewComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(OverviewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/overview/overview.component.ts b/src/app/dashboard/overview/overview.component.ts new file mode 100644 index 0000000..6a32601 --- /dev/null +++ b/src/app/dashboard/overview/overview.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-overview', + templateUrl: './overview.component.html', + styleUrls: ['./overview.component.css'] +}) +export class OverviewComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/assets/history.svg b/src/assets/history.svg new file mode 100644 index 0000000..9a422ca --- /dev/null +++ b/src/assets/history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/routes.ts b/src/routes.ts index 74cce43..5dde117 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -1,11 +1,22 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; +import { DashboardComponent } from "./app/dashboard/dashboard.component"; +import { LoginComponent } from "./app/dashboard/login/login.component"; +import { OverviewComponent } from "./app/dashboard/overview/overview.component"; import { HelloComponent } from "./app/hello/hello.component"; import { NotFoundComponent } from "./app/not-found/not-found.component"; import { PayComponent } from "./app/pay/pay.component"; const routes: Routes = [ { path: 'pay/:id', component: PayComponent, data: { title: 'Payment' } }, + { path: 'dashboard', component: DashboardComponent, children: [ + { + path: 'login', component: LoginComponent + }, + { + path: 'overview', component: OverviewComponent + } + ]}, { path: '', component: HelloComponent }, { path: '**', component: NotFoundComponent } ] From b2d12b10089d480bf6d75a7b2a590d6b7f8d9aea Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:42:34 +0100 Subject: [PATCH 22/40] add component "dashboard" --- src/app/dashboard/dashboard.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 8687f04..51213bf 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,2 +1,2 @@ - \ No newline at end of file + From 909a2ac9725abb7809a8e21998aec4b8275d2655 Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 6 Jan 2021 19:12:19 +0100 Subject: [PATCH 23/40] add SVG Images to HeaderBar --- src/app/dashboard/header/header.component.css | 6 ++++++ src/app/dashboard/header/header.component.html | 4 +++- src/app/dashboard/login/login.component.ts | 8 ++++++++ src/assets/admin.svg | 1 + src/assets/dash.svg | 1 + 5 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/assets/admin.svg create mode 100644 src/assets/dash.svg diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css index 6f04bdd..8121253 100644 --- a/src/app/dashboard/header/header.component.css +++ b/src/app/dashboard/header/header.component.css @@ -7,4 +7,10 @@ background-color: #27293D; z-index: 999; border-radius: 8px; +} + +.history-svg {} + +.admin-svg { + fill: white; } \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html index d085ff5..f25c373 100644 --- a/src/app/dashboard/header/header.component.html +++ b/src/app/dashboard/header/header.component.html @@ -1,3 +1,5 @@
-

HEADER

+ + +
\ No newline at end of file diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts index e0420ea..6b0dfe1 100644 --- a/src/app/dashboard/login/login.component.ts +++ b/src/app/dashboard/login/login.component.ts @@ -18,8 +18,16 @@ export class LoginComponent implements OnInit { ) { } ngOnInit(): void { + + const loginStatus = this.dashboard.login("admin", "password"); + if (loginStatus) { + this.router.navigate(['dashboard', 'overview']); + } else { + // TODO: Meldung anzeigen + } } + login() { const loginStatus = this.dashboard.login(this.username, this.password); diff --git a/src/assets/admin.svg b/src/assets/admin.svg new file mode 100644 index 0000000..4adef78 --- /dev/null +++ b/src/assets/admin.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/dash.svg b/src/assets/dash.svg new file mode 100644 index 0000000..280d48a --- /dev/null +++ b/src/assets/dash.svg @@ -0,0 +1 @@ + \ No newline at end of file From 9f2076ac3d5d3e8b51382df33d42d26f158dd57d Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:42:34 +0100 Subject: [PATCH 24/40] merge master --- src/app/app.module.ts | 9 ++++----- src/app/dashboard/dashboard.component.html | 5 +++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 41febb2..9faee02 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -6,6 +6,7 @@ import { HeaderComponent } from './header/header.component'; import { PaymentComponent } from './payment/payment.component'; import { QRCodeModule } from 'angularx-qrcode'; import { PayComponent } from './pay/pay.component'; +import { RouterModule } from '@angular/router'; import { HelloComponent } from './hello/hello.component'; import { SocketIoConfig, SocketIoModule } from 'ngx-socket-io'; import { HttpClientModule } from '@angular/common/http'; @@ -14,7 +15,6 @@ import { NotFoundComponent } from './not-found/not-found.component'; import { CartComponent } from './cart/cart.component'; import { PushNotificationsModule } from 'ng-push-ivy'; import { ClipboardModule } from 'ngx-clipboard'; -import { environment } from '../environments/environment'; import { DashboardComponent } from './dashboard/dashboard.component'; import { LoginComponent } from './dashboard/login/login.component'; import { FormsModule } from '@angular/forms'; @@ -33,18 +33,17 @@ import { DashboardHeaderComponent } from './dashboard/header/header.component'; DashboardComponent, LoginComponent, OverviewComponent, - DashboardHeaderComponent + DashboardHeaderComponent, + DashboardComponent ], imports: [ BrowserModule, QRCodeModule, HttpClientModule, AppRoutingModule, - SocketIoModule.forRoot(config), PushNotificationsModule, ClipboardModule, - FormsModule, - SocketIoModule.forRoot(config) + FormsModule ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 51213bf..9c8783f 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,2 +1,7 @@ +
+ + +
+ From b25ddac4488cfbeb5c90ed65f85d7f6d995901e5 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:57:43 +0100 Subject: [PATCH 25/40] add login subcomponent --- src/app/app.module.ts | 1 + src/app/dashboard/login/login.component.html | 2 +- src/app/dashboard/login/login.component.ts | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9faee02..d74e887 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -21,6 +21,7 @@ import { FormsModule } from '@angular/forms'; import { OverviewComponent } from './dashboard/overview/overview.component'; import { DashboardHeaderComponent } from './dashboard/header/header.component'; + @NgModule({ declarations: [ AppComponent, diff --git a/src/app/dashboard/login/login.component.html b/src/app/dashboard/login/login.component.html index ac07479..195bd42 100644 --- a/src/app/dashboard/login/login.component.html +++ b/src/app/dashboard/login/login.component.html @@ -7,4 +7,4 @@

Login

- \ No newline at end of file + diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts index 6b0dfe1..bd0a72c 100644 --- a/src/app/dashboard/login/login.component.ts +++ b/src/app/dashboard/login/login.component.ts @@ -37,5 +37,4 @@ export class LoginComponent implements OnInit { // TODO: Meldung anzeigen } } - -} \ No newline at end of file +} From 51bc14e115820eab5cafd6432d9def0d5b84c4fd Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 18:55:26 +0100 Subject: [PATCH 26/40] add login with dummy Data add login page add subcomponents --- src/app/app.module.ts | 1 - src/app/dashboard/dashboard.component.html | 7 +------ src/app/dashboard/header/header.component.css | 6 ------ src/app/dashboard/header/header.component.html | 4 +--- src/app/dashboard/login/login.component.html | 2 +- src/app/dashboard/login/login.component.ts | 11 ++--------- 6 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index d74e887..9faee02 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -21,7 +21,6 @@ import { FormsModule } from '@angular/forms'; import { OverviewComponent } from './dashboard/overview/overview.component'; import { DashboardHeaderComponent } from './dashboard/header/header.component'; - @NgModule({ declarations: [ AppComponent, diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 9c8783f..8687f04 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,7 +1,2 @@ -
- - -
- - + \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css index 8121253..6f04bdd 100644 --- a/src/app/dashboard/header/header.component.css +++ b/src/app/dashboard/header/header.component.css @@ -7,10 +7,4 @@ background-color: #27293D; z-index: 999; border-radius: 8px; -} - -.history-svg {} - -.admin-svg { - fill: white; } \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html index f25c373..d085ff5 100644 --- a/src/app/dashboard/header/header.component.html +++ b/src/app/dashboard/header/header.component.html @@ -1,5 +1,3 @@
- - - +

HEADER

\ No newline at end of file diff --git a/src/app/dashboard/login/login.component.html b/src/app/dashboard/login/login.component.html index 195bd42..ac07479 100644 --- a/src/app/dashboard/login/login.component.html +++ b/src/app/dashboard/login/login.component.html @@ -7,4 +7,4 @@

Login

- + \ No newline at end of file diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts index bd0a72c..e0420ea 100644 --- a/src/app/dashboard/login/login.component.ts +++ b/src/app/dashboard/login/login.component.ts @@ -18,16 +18,8 @@ export class LoginComponent implements OnInit { ) { } ngOnInit(): void { - - const loginStatus = this.dashboard.login("admin", "password"); - if (loginStatus) { - this.router.navigate(['dashboard', 'overview']); - } else { - // TODO: Meldung anzeigen - } } - login() { const loginStatus = this.dashboard.login(this.username, this.password); @@ -37,4 +29,5 @@ export class LoginComponent implements OnInit { // TODO: Meldung anzeigen } } -} + +} \ No newline at end of file From 9b291eda85f9ce4de1668f5ec419c415b9eaac5e Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 3 Jan 2021 12:42:34 +0100 Subject: [PATCH 27/40] add component "dashboard" --- src/app/app.module.ts | 5 ++--- src/app/dashboard/dashboard.component.html | 3 +-- src/app/dashboard/dashboard.component.ts | 3 +-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9faee02..1d1d067 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -19,7 +19,7 @@ import { DashboardComponent } from './dashboard/dashboard.component'; import { LoginComponent } from './dashboard/login/login.component'; import { FormsModule } from '@angular/forms'; import { OverviewComponent } from './dashboard/overview/overview.component'; -import { DashboardHeaderComponent } from './dashboard/header/header.component'; +import { DashboardHeaderComponent } from './dashboard/header/header.component';g: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; @NgModule({ declarations: [ @@ -33,8 +33,7 @@ import { DashboardHeaderComponent } from './dashboard/header/header.component'; DashboardComponent, LoginComponent, OverviewComponent, - DashboardHeaderComponent, - DashboardComponent + DashboardHeaderComponent ], imports: [ BrowserModule, diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 8687f04..9c5fce9 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,2 +1 @@ - - \ No newline at end of file +

dashboard works!

diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts index b9a91a8..38138a3 100644 --- a/src/app/dashboard/dashboard.component.ts +++ b/src/app/dashboard/dashboard.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit } from '@angular/core'; -import { DashboardService } from '../dashboard.service'; @Component({ selector: 'app-dashboard', @@ -8,7 +7,7 @@ import { DashboardService } from '../dashboard.service'; }) export class DashboardComponent implements OnInit { - constructor(public dashboard: DashboardService) { } + constructor() { } ngOnInit(): void { } From cc1cf01b83ffe15412934e634779c95dd515f938 Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 6 Jan 2021 19:12:19 +0100 Subject: [PATCH 28/40] add SVG Images to HeaderBar --- src/app/dashboard/header/header.component.css | 6 ++++++ src/app/dashboard/header/header.component.html | 4 +++- src/app/dashboard/login/login.component.ts | 8 ++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css index 6f04bdd..8121253 100644 --- a/src/app/dashboard/header/header.component.css +++ b/src/app/dashboard/header/header.component.css @@ -7,4 +7,10 @@ background-color: #27293D; z-index: 999; border-radius: 8px; +} + +.history-svg {} + +.admin-svg { + fill: white; } \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html index d085ff5..f25c373 100644 --- a/src/app/dashboard/header/header.component.html +++ b/src/app/dashboard/header/header.component.html @@ -1,3 +1,5 @@
-

HEADER

+ + +
\ No newline at end of file diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts index e0420ea..6b0dfe1 100644 --- a/src/app/dashboard/login/login.component.ts +++ b/src/app/dashboard/login/login.component.ts @@ -18,8 +18,16 @@ export class LoginComponent implements OnInit { ) { } ngOnInit(): void { + + const loginStatus = this.dashboard.login("admin", "password"); + if (loginStatus) { + this.router.navigate(['dashboard', 'overview']); + } else { + // TODO: Meldung anzeigen + } } + login() { const loginStatus = this.dashboard.login(this.username, this.password); From 7cd03fb40e7d8083446dadf043938871de66ae76 Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 2 Feb 2021 10:59:22 +0100 Subject: [PATCH 29/40] + Added Dashboard Navbar + Added Transitions + Added Shadows + Added LogIn Page --- src/app/dashboard/dashboard.component.css | 8 +++ src/app/dashboard/dashboard.component.html | 4 +- src/app/dashboard/header/header.component.css | 56 ++++++++++++++++++- .../dashboard/header/header.component.html | 19 ++++++- .../dashboard/overview/overview.component.ts | 6 +- src/app/payment/payment.component.ts | 2 + src/assets/admin.svg | 2 +- src/assets/dash.svg | 2 +- src/assets/dashboard.svg | 3 + src/assets/history.svg | 2 +- src/assets/settings.svg | 4 ++ 11 files changed, 97 insertions(+), 11 deletions(-) create mode 100644 src/assets/dashboard.svg create mode 100644 src/assets/settings.svg diff --git a/src/app/dashboard/dashboard.component.css b/src/app/dashboard/dashboard.component.css index e69de29..7f7fce2 100644 --- a/src/app/dashboard/dashboard.component.css +++ b/src/app/dashboard/dashboard.component.css @@ -0,0 +1,8 @@ +.bg { + position: fixed; + background-color: #1D1D28; + top: 0; + left: 0; + height: 100vh; + width: 100vw; +} \ No newline at end of file diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 9c5fce9..f853cdd 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1 +1,3 @@ -

dashboard works!

+ +
+ diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css index 8121253..b2c182a 100644 --- a/src/app/dashboard/header/header.component.css +++ b/src/app/dashboard/header/header.component.css @@ -3,14 +3,64 @@ top: 1rem; left: 5vw; width: 90vw; + height: 100%; + max-height: 35px; + padding: 15px; margin: 0 auto; background-color: #27293D; z-index: 999; border-radius: 8px; + transition: .2s ease; + box-shadow: 0 1.1px 12.5px -23px rgba(0, 0, 0, 0.014), 0 2.4px 23.6px -23px rgba(0, 0, 0, 0.027), 0 4.1px 33.4px -23px rgba(0, 0, 0, 0.038), 0 6.2px 42.1px -23px rgba(0, 0, 0, 0.045), 0 8.9px 49.9px -23px rgba(0, 0, 0, 0.05), 0 12.6px 57.5px -23px rgba(0, 0, 0, 0.054), 0 17.8px 65.8px -23px rgba(0, 0, 0, 0.058), 0 25.9px 76.9px -23px rgba(0, 0, 0, 0.062), 0 39.9px 96.3px -23px rgba(0, 0, 0, 0.066), 0 71px 148px -23px rgba(0, 0, 0, 0.07); } -.history-svg {} +.header:hover { + max-height: 55px; + transition: .2s ease; +} + +.icon::after { + content: ' '; + opacity: 0; +} + +.header:hover .icon::after { + content: "Test"; + color: white; + opacity: 1; + transition: .2s ease; + transition: .5s opacity ease; +} + +.icon:hover { + transform: translateY(-5px); +} + +.grid-container { + display: grid; + grid-template-columns: 32px 32px 1fr 32px 32px; + grid-template-rows: 1fr; + gap: 20px 30px; + grid-template-areas: "dashboard history . settings admin"; +} + +.dashboard { + grid-area: dashboard; +} + +.history { + grid-area: history; +} + +.settings { + grid-area: settings; +} + +.admin { + grid-area: admin; +} -.admin-svg { - fill: white; +.icon { + grid-row: 1; + transition: .2s ease; } \ No newline at end of file diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html index f25c373..8802aea 100644 --- a/src/app/dashboard/header/header.component.html +++ b/src/app/dashboard/header/header.component.html @@ -1,5 +1,18 @@
- - - + +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
\ No newline at end of file diff --git a/src/app/dashboard/overview/overview.component.ts b/src/app/dashboard/overview/overview.component.ts index 6a32601..b233b1c 100644 --- a/src/app/dashboard/overview/overview.component.ts +++ b/src/app/dashboard/overview/overview.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { DashboardService } from 'src/app/dashboard.service'; @Component({ selector: 'app-overview', @@ -7,9 +8,12 @@ import { Component, OnInit } from '@angular/core'; }) export class OverviewComponent implements OnInit { - constructor() { } + constructor(private dashboard: DashboardService) { } ngOnInit(): void { + if (this.dashboard.user === undefined) { + this.dashboard.login('admin', 'password'); + } } } diff --git a/src/app/payment/payment.component.ts b/src/app/payment/payment.component.ts index 86457bb..6b88aa4 100644 --- a/src/app/payment/payment.component.ts +++ b/src/app/payment/payment.component.ts @@ -126,6 +126,8 @@ export class PaymentComponent implements OnInit { } async get(): Promise { + console.log('Selector:', this.paymentSelector); + const res = await this.backend.setInvoice(this.paymentSelector); this.status = this.backend.getStatusString(); this.backend.getConfirmation().catch(); diff --git a/src/assets/admin.svg b/src/assets/admin.svg index 4adef78..5293b19 100644 --- a/src/assets/admin.svg +++ b/src/assets/admin.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/dash.svg b/src/assets/dash.svg index 280d48a..8cfd9d0 100644 --- a/src/assets/dash.svg +++ b/src/assets/dash.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/dashboard.svg b/src/assets/dashboard.svg new file mode 100644 index 0000000..5d89e74 --- /dev/null +++ b/src/assets/dashboard.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/history.svg b/src/assets/history.svg index 9a422ca..10b63fc 100644 --- a/src/assets/history.svg +++ b/src/assets/history.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/settings.svg b/src/assets/settings.svg new file mode 100644 index 0000000..0cf867f --- /dev/null +++ b/src/assets/settings.svg @@ -0,0 +1,4 @@ + + + + From f0bbf19011ef49a54e8f15dd126866e05e81f6b4 Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 2 Feb 2021 11:56:14 +0100 Subject: [PATCH 30/40] Add NGX Chart --- package-lock.json | 54 +++++++++++++++++++ package.json | 2 + src/app/app.module.ts | 12 +++-- src/app/dashboard/chart/chart.component.css | 0 src/app/dashboard/chart/chart.component.html | 2 + .../dashboard/chart/chart.component.spec.ts | 25 +++++++++ src/app/dashboard/chart/chart.component.ts | 15 ++++++ src/app/dashboard/dashboard.component.html | 1 + 8 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 src/app/dashboard/chart/chart.component.css create mode 100644 src/app/dashboard/chart/chart.component.html create mode 100644 src/app/dashboard/chart/chart.component.spec.ts create mode 100644 src/app/dashboard/chart/chart.component.ts diff --git a/package-lock.json b/package-lock.json index a3eb569..08f49f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1552,6 +1552,14 @@ "semver-intersect": "1.4.0" } }, + "@types/chart.js": { + "version": "2.9.30", + "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.30.tgz", + "integrity": "sha512-EgjxUUZFvf6ls3kW2CwyrnSJhgyKxgwrlp/W5G9wqyPEO9iFatO63zAA7L24YqgMxiDjQ+tG7ODU+2yWH91lPg==", + "requires": { + "moment": "^2.10.2" + } + }, "@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -2817,6 +2825,32 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chart.js": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", + "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==", + "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": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", @@ -6913,6 +6947,11 @@ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, + "lodash-es": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.20.tgz", + "integrity": "sha512-JD1COMZsq8maT6mnuz1UMV0jvYD0E0aUsSOdrr1/nAG3dhqQXwRRgeW0cSqH1U43INKcqxaiVIQNOUDld7gRDA==" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -7432,6 +7471,11 @@ "minimist": "^1.2.5" } }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -7535,6 +7579,16 @@ "tslib": "^2.0.0" } }, + "ng2-charts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-2.4.2.tgz", + "integrity": "sha512-mY3C2uKCaApHCQizS2YxEOqQ7sSZZLxdV6N1uM9u/VvUgVtYvlPtdcXbKpN52ak93ZE22I73DiLWVDnDNG4/AQ==", + "requires": { + "@types/chart.js": "^2.9.24", + "lodash-es": "^4.17.15", + "tslib": "^2.0.0" + } + }, "ngx-clipboard": { "version": "14.0.1", "resolved": "https://registry.npmjs.org/ngx-clipboard/-/ngx-clipboard-14.0.1.tgz", diff --git a/package.json b/package.json index 4625926..dc07077 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ "@angular/platform-browser-dynamic": "~11.0.5", "@angular/router": "~11.0.5", "angularx-qrcode": "^10.0.11", + "chart.js": "^2.9.4", "ng-push-ivy": "^1.0.7", + "ng2-charts": "^2.4.2", "ngx-clipboard": "^14.0.1", "rxjs": "~6.6.0", "tslib": "^2.0.0", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 1d1d067..134b64f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -6,9 +6,7 @@ import { HeaderComponent } from './header/header.component'; import { PaymentComponent } from './payment/payment.component'; import { QRCodeModule } from 'angularx-qrcode'; import { PayComponent } from './pay/pay.component'; -import { RouterModule } from '@angular/router'; import { HelloComponent } from './hello/hello.component'; -import { SocketIoConfig, SocketIoModule } from 'ngx-socket-io'; import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from 'src/routes'; import { NotFoundComponent } from './not-found/not-found.component'; @@ -19,7 +17,9 @@ import { DashboardComponent } from './dashboard/dashboard.component'; import { LoginComponent } from './dashboard/login/login.component'; import { FormsModule } from '@angular/forms'; import { OverviewComponent } from './dashboard/overview/overview.component'; -import { DashboardHeaderComponent } from './dashboard/header/header.component';g: SocketIoConfig = { url: 'http://localhost:2009', options: {} }; +import { DashboardHeaderComponent } from './dashboard/header/header.component'; +import { ChartComponent } from './dashboard/chart/chart.component'; +import { ChartsModule } from 'ng2-charts'; @NgModule({ declarations: [ @@ -33,7 +33,8 @@ import { DashboardHeaderComponent } from './dashboard/header/header.component';g DashboardComponent, LoginComponent, OverviewComponent, - DashboardHeaderComponent + DashboardHeaderComponent, + ChartComponent ], imports: [ BrowserModule, @@ -42,7 +43,8 @@ import { DashboardHeaderComponent } from './dashboard/header/header.component';g AppRoutingModule, PushNotificationsModule, ClipboardModule, - FormsModule + FormsModule, + ChartsModule ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/dashboard/chart/chart.component.css b/src/app/dashboard/chart/chart.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html new file mode 100644 index 0000000..90660a1 --- /dev/null +++ b/src/app/dashboard/chart/chart.component.html @@ -0,0 +1,2 @@ + +

Test

\ No newline at end of file diff --git a/src/app/dashboard/chart/chart.component.spec.ts b/src/app/dashboard/chart/chart.component.spec.ts new file mode 100644 index 0000000..6c6d094 --- /dev/null +++ b/src/app/dashboard/chart/chart.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChartComponent } from './chart.component'; + +describe('ChartComponent', () => { + let component: ChartComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ChartComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/chart/chart.component.ts b/src/app/dashboard/chart/chart.component.ts new file mode 100644 index 0000000..30c6b9b --- /dev/null +++ b/src/app/dashboard/chart/chart.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-chart', + templateUrl: './chart.component.html', + styleUrls: ['./chart.component.css'] +}) +export class ChartComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index f853cdd..381f046 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,3 +1,4 @@ +
From a38a83dd95811477666bcb647d23187816b4947c Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 2 Feb 2021 11:56:14 +0100 Subject: [PATCH 31/40] Add Chart.js --- src/app/app.module.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 134b64f..717c1b1 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -7,6 +7,7 @@ import { PaymentComponent } from './payment/payment.component'; import { QRCodeModule } from 'angularx-qrcode'; import { PayComponent } from './pay/pay.component'; import { HelloComponent } from './hello/hello.component'; +import { SocketIoModule } from 'ngx-socket-io'; import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from 'src/routes'; import { NotFoundComponent } from './not-found/not-found.component'; From e1d86d879e730c3d29a1e456245168c4a9026cd3 Mon Sep 17 00:00:00 2001 From: Felix Date: Fri, 26 Mar 2021 15:56:14 +0100 Subject: [PATCH 32/40] add engxCharts add center Header --- package-lock.json | 346 ++++++++++++++++-- package.json | 6 +- src/app/app.module.ts | 12 +- src/app/dashboard/chart/chart.component.html | 5 +- src/app/dashboard/chart/chart.component.ts | 24 +- src/app/dashboard/dashboard.component.css | 5 + src/app/dashboard/dashboard.component.html | 5 +- src/app/dashboard/header/header.component.css | 3 +- .../dashboard/summary/summary.component.css | 18 + .../dashboard/summary/summary.component.html | 3 + .../summary/summary.component.spec.ts | 25 ++ .../dashboard/summary/summary.component.ts | 15 + src/assets/js/Chart.min.css | 1 + src/assets/js/Chart.min.js | 7 + 14 files changed, 432 insertions(+), 43 deletions(-) create mode 100644 src/app/dashboard/summary/summary.component.css create mode 100644 src/app/dashboard/summary/summary.component.html create mode 100644 src/app/dashboard/summary/summary.component.spec.ts create mode 100644 src/app/dashboard/summary/summary.component.ts create mode 100644 src/assets/js/Chart.min.css create mode 100644 src/assets/js/Chart.min.js diff --git a/package-lock.json b/package-lock.json index 08f49f6..d45d06b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -147,6 +147,23 @@ "tslib": "^2.0.0" } }, + "@angular/cdk": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-11.2.1.tgz", + "integrity": "sha512-d+ERvvWqGykBm5ooWG8TmMjL6q6aOpUd13ha1sx960EfKJqNyideYUfPMp6xprTyxmUIUZ/G9AQ/pxnzrLGnsA==", + "requires": { + "parse5": "^5.0.0", + "tslib": "^2.0.0" + }, + "dependencies": { + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "optional": true + } + } + }, "@angular/cli": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-11.0.5.tgz", @@ -1552,6 +1569,25 @@ "semver-intersect": "1.4.0" } }, + "@swimlane/ngx-charts": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@swimlane/ngx-charts/-/ngx-charts-17.0.0.tgz", + "integrity": "sha512-NsjDBWeizvWrDq6W/ZImBGL9/RERsW+2qLR30xJg/oNbIrSqtLty7Scmah3b9lgyCH00c0pK1DMYUak1QoMBJQ==", + "requires": { + "d3-array": "^2.9.1", + "d3-brush": "^2.1.0", + "d3-color": "^2.0.0", + "d3-format": "^2.0.0", + "d3-hierarchy": "^2.0.0", + "d3-interpolate": "^2.0.1", + "d3-scale": "^3.2.3", + "d3-selection": "^2.0.0", + "d3-shape": "^2.0.0", + "d3-time-format": "^3.0.0", + "d3-transition": "^2.0.0", + "tslib": "^2.0.0" + } + }, "@types/chart.js": { "version": "2.9.30", "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.9.30.tgz", @@ -3803,6 +3839,128 @@ "type": "^1.0.1" } }, + "d3-array": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz", + "integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==", + "requires": { + "internmap": "^1.0.0" + } + }, + "d3-brush": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-2.1.0.tgz", + "integrity": "sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ==", + "requires": { + "d3-dispatch": "1 - 2", + "d3-drag": "2", + "d3-interpolate": "1 - 2", + "d3-selection": "2", + "d3-transition": "2" + } + }, + "d3-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", + "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" + }, + "d3-dispatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz", + "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==" + }, + "d3-drag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz", + "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==", + "requires": { + "d3-dispatch": "1 - 2", + "d3-selection": "2" + } + }, + "d3-ease": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz", + "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ==" + }, + "d3-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz", + "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==" + }, + "d3-hierarchy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz", + "integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw==" + }, + "d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "requires": { + "d3-color": "1 - 2" + } + }, + "d3-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz", + "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==" + }, + "d3-scale": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.3.tgz", + "integrity": "sha512-8E37oWEmEzj57bHcnjPVOBS3n4jqakOeuv1EDdQSiSrYnMCBdMd3nc4HtKk7uia8DUHcY/CGuJ42xxgtEYrX0g==", + "requires": { + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "1 - 2", + "d3-time-format": "2 - 3" + } + }, + "d3-selection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz", + "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==" + }, + "d3-shape": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.1.0.tgz", + "integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==", + "requires": { + "d3-path": "1 - 2" + } + }, + "d3-time": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.0.0.tgz", + "integrity": "sha512-2mvhstTFcMvwStWd9Tj3e6CEqtOivtD8AUiHT8ido/xmzrI9ijrUUihZ6nHuf/vsScRBonagOdj0Vv+SEL5G3Q==" + }, + "d3-time-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", + "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", + "requires": { + "d3-time": "1 - 2" + } + }, + "d3-timer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz", + "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==" + }, + "d3-transition": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz", + "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==", + "requires": { + "d3-color": "1 - 2", + "d3-dispatch": "1 - 2", + "d3-ease": "1 - 2", + "d3-interpolate": "1 - 2", + "d3-timer": "1 - 2" + } + }, "damerau-levenshtein": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", @@ -4182,6 +4340,15 @@ "safer-buffer": "^2.1.0" } }, + "echarts": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.0.2.tgz", + "integrity": "sha512-En0VYpc96nw2/2AZoBWPHsGi471zMublttj50kfFpYAeR4geup0Tj9iVgEXh7QYZFPnRiruDJEjcB5PXZ+BYzQ==", + "requires": { + "tslib": "2.0.3", + "zrender": "5.0.4" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4195,24 +4362,24 @@ "dev": true }, "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", + "bn.js": "^4.11.9", + "brorand": "^1.1.0", "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -4265,22 +4432,22 @@ } }, "engine.io": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz", - "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz", + "integrity": "sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA==", "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "0.3.1", + "cookie": "~0.4.1", "debug": "~4.1.0", "engine.io-parser": "~2.2.0", - "ws": "^7.1.2" + "ws": "~7.4.2" }, "dependencies": { "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, "debug": { "version": "4.1.1", @@ -4291,9 +4458,9 @@ } }, "ws": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", - "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==" + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", + "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==" } } }, @@ -5964,6 +6131,11 @@ "ipaddr.js": "^1.9.0" } }, + "internmap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.0.tgz", + "integrity": "sha512-SdoDWwNOTE2n4JWUsLn4KXZGuZPjPF9yyOGc8bnfWnBQh7BD/l80rzSznKc/r4Y0aQ7z3RTk9X+tV4tHBpu+dA==" + }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -7598,6 +7770,14 @@ "tslib": "^2.0.0" } }, + "ngx-echarts": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ngx-echarts/-/ngx-echarts-6.0.1.tgz", + "integrity": "sha512-a9MZ8cHC7oD+c6Tl0ABAEM2inD+k4FHhuu7RnH6/34c10TJ7AFeQwrFbP6BgW39M9gViWozAjCRFmrvWOYv2Wg==", + "requires": { + "tslib": "^2.0.0" + } + }, "ngx-socket-io": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ngx-socket-io/-/ngx-socket-io-3.2.0.tgz", @@ -10119,6 +10299,12 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "dev": true + }, "resolve": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", @@ -10898,15 +11084,15 @@ } }, "socket.io": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", - "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.4.1.tgz", + "integrity": "sha512-Si18v0mMXGAqLqCVpTxBa8MGqriHGQh8ccEOhmsmNS3thNCGBwO8WGrwMibANsWtQQ5NStdZwHqZR3naJVFc3w==", "requires": { "debug": "~4.1.0", - "engine.io": "~3.4.0", + "engine.io": "~3.5.0", "has-binary2": "~1.0.2", "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.3.0", + "socket.io-client": "2.4.0", "socket.io-parser": "~3.4.0" }, "dependencies": { @@ -10917,6 +11103,102 @@ "requires": { "ms": "^2.1.1" } + }, + "engine.io-client": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.0.tgz", + "integrity": "sha512-12wPRfMrugVw/DNyJk34GQ5vIVArEcVMXWugQGGuw2XxUSztFNmJggZmv8IZlLyEdnpO1QB9LkcjeWewO2vxtA==", + "requires": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, + "socket.io-client": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.4.0.tgz", + "integrity": "sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ==", + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "socket.io-parser": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", + "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", + "requires": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + } + } + }, + "ws": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz", + "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA==" } } }, @@ -13566,6 +13848,14 @@ "version": "0.10.3", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.10.3.tgz", "integrity": "sha512-LXVLVEq0NNOqK/fLJo3d0kfzd4sxwn2/h67/02pjCjfKDxgx1i9QqpvtHD8CrBnSSwMw5+dy11O7FRX5mkO7Cg==" + }, + "zrender": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.0.4.tgz", + "integrity": "sha512-DJpy0yrHYY5CuH6vhb9IINWbjvBUe/56J8aH86Jb7O8rRPAYZ3M2E469Qf5B3EOIfM3o3aUrO5edRQfLJ+l1Qw==", + "requires": { + "tslib": "2.0.3" + } } } } diff --git a/package.json b/package.json index dc07077..cdf60b7 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "private": true, "dependencies": { "@angular/animations": "~11.0.5", + "@angular/cdk": "^11.2.1", "@angular/common": "~11.0.5", "@angular/compiler": "~11.0.5", "@angular/core": "~11.0.5", @@ -20,10 +21,12 @@ "@angular/platform-browser-dynamic": "~11.0.5", "@angular/router": "~11.0.5", "angularx-qrcode": "^10.0.11", - "chart.js": "^2.9.4", + "d3-shape": "^2.1.0", + "echarts": "^5.0.2", "ng-push-ivy": "^1.0.7", "ng2-charts": "^2.4.2", "ngx-clipboard": "^14.0.1", + "ngx-echarts": "^6.0.1", "rxjs": "~6.6.0", "tslib": "^2.0.0", "zone.js": "~0.10.2" @@ -43,6 +46,7 @@ "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.5.0", "protractor": "~7.0.0", + "resize-observer-polyfill": "^1.5.1", "ts-node": "~8.3.0", "tslint": "~6.1.0", "typescript": "~4.0.2" diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 717c1b1..3c045d1 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -20,7 +20,9 @@ import { FormsModule } from '@angular/forms'; import { OverviewComponent } from './dashboard/overview/overview.component'; import { DashboardHeaderComponent } from './dashboard/header/header.component'; import { ChartComponent } from './dashboard/chart/chart.component'; -import { ChartsModule } from 'ng2-charts'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { SummaryComponent } from './dashboard/summary/summary.component'; +import { NgxEchartsModule } from 'ngx-echarts'; @NgModule({ declarations: [ @@ -35,7 +37,8 @@ import { ChartsModule } from 'ng2-charts'; LoginComponent, OverviewComponent, DashboardHeaderComponent, - ChartComponent + ChartComponent, + SummaryComponent ], imports: [ BrowserModule, @@ -45,7 +48,10 @@ import { ChartsModule } from 'ng2-charts'; PushNotificationsModule, ClipboardModule, FormsModule, - ChartsModule + BrowserAnimationsModule, + NgxEchartsModule.forRoot({ + echarts: () => import('echarts') + }) ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html index 90660a1..8a42052 100644 --- a/src/app/dashboard/chart/chart.component.html +++ b/src/app/dashboard/chart/chart.component.html @@ -1,2 +1,3 @@ - -

Test

\ No newline at end of file +
+ +

Chart workds

\ No newline at end of file diff --git a/src/app/dashboard/chart/chart.component.ts b/src/app/dashboard/chart/chart.component.ts index 30c6b9b..3345e54 100644 --- a/src/app/dashboard/chart/chart.component.ts +++ b/src/app/dashboard/chart/chart.component.ts @@ -1,15 +1,25 @@ -import { Component, OnInit } from '@angular/core'; +import { Component} from '@angular/core' +import { EChartsOption } from 'echarts'; @Component({ selector: 'app-chart', templateUrl: './chart.component.html', styleUrls: ['./chart.component.css'] }) -export class ChartComponent implements OnInit { - - constructor() { } - - ngOnInit(): void { - } +export class ChartComponent { + chartOption: EChartsOption = { + xAxis: { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + }, + yAxis: { + type: 'value' + }, + series: [{ + data: [820, 932, 901, 934, 1290, 1330, 1320], + type: 'line', + smooth: true + }] + }; } diff --git a/src/app/dashboard/dashboard.component.css b/src/app/dashboard/dashboard.component.css index 7f7fce2..a5c3f4b 100644 --- a/src/app/dashboard/dashboard.component.css +++ b/src/app/dashboard/dashboard.component.css @@ -5,4 +5,9 @@ left: 0; height: 100vh; width: 100vw; + z-index: -1; +} + +.spacer { + height: 100px; } \ No newline at end of file diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 381f046..9c8783f 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,4 +1,7 @@ - +
+ +
+ diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css index b2c182a..72a51a6 100644 --- a/src/app/dashboard/header/header.component.css +++ b/src/app/dashboard/header/header.component.css @@ -1,7 +1,8 @@ .header { position: fixed; top: 1rem; - left: 5vw; + left: 0; + right: 0; width: 90vw; height: 100%; max-height: 35px; diff --git a/src/app/dashboard/summary/summary.component.css b/src/app/dashboard/summary/summary.component.css new file mode 100644 index 0000000..ec36ddc --- /dev/null +++ b/src/app/dashboard/summary/summary.component.css @@ -0,0 +1,18 @@ +.header { + background-color: #242635; + margin: 0; + padding: 0; + padding: 2rem; + padding-right: 2rem; + border-radius: 22px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + margin: 0 auto; + width: 80%; +} + +.lower { + background-color: #26283A; + margin: 0; + padding: 6rem; +} \ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.html b/src/app/dashboard/summary/summary.component.html new file mode 100644 index 0000000..eceab7f --- /dev/null +++ b/src/app/dashboard/summary/summary.component.html @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.spec.ts b/src/app/dashboard/summary/summary.component.spec.ts new file mode 100644 index 0000000..0132711 --- /dev/null +++ b/src/app/dashboard/summary/summary.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SummaryComponent } from './summary.component'; + +describe('SummaryComponent', () => { + let component: SummaryComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SummaryComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SummaryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/summary/summary.component.ts b/src/app/dashboard/summary/summary.component.ts new file mode 100644 index 0000000..011993b --- /dev/null +++ b/src/app/dashboard/summary/summary.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-summary', + templateUrl: './summary.component.html', + styleUrls: ['./summary.component.css'] +}) +export class SummaryComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/assets/js/Chart.min.css b/src/assets/js/Chart.min.css new file mode 100644 index 0000000..9dc5ac2 --- /dev/null +++ b/src/assets/js/Chart.min.css @@ -0,0 +1 @@ +@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0} \ No newline at end of file diff --git a/src/assets/js/Chart.min.js b/src/assets/js/Chart.min.js new file mode 100644 index 0000000..a87f614 --- /dev/null +++ b/src/assets/js/Chart.min.js @@ -0,0 +1,7 @@ +/*! + * Chart.js v2.9.4 + * https://www.chartjs.org + * (c) 2020 Chart.js Contributors + * Released under the MIT License + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(function(){try{return require("moment")}catch(t){}}()):"function"==typeof define&&define.amd?define(["require"],(function(t){return e(function(){try{return t("moment")}catch(t){}}())})):(t=t||self).Chart=e(t.moment)}(this,(function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},n=function(t,e){return t(e={exports:{}},e.exports),e.exports}((function(t){var n={};for(var i in e)e.hasOwnProperty(i)&&(n[e[i]]=i);var a=t.exports={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};for(var r in a)if(a.hasOwnProperty(r)){if(!("channels"in a[r]))throw new Error("missing channels property: "+r);if(!("labels"in a[r]))throw new Error("missing channel labels property: "+r);if(a[r].labels.length!==a[r].channels)throw new Error("channel and label counts mismatch: "+r);var o=a[r].channels,s=a[r].labels;delete a[r].channels,delete a[r].labels,Object.defineProperty(a[r],"channels",{value:o}),Object.defineProperty(a[r],"labels",{value:s})}a.rgb.hsl=function(t){var e,n,i=t[0]/255,a=t[1]/255,r=t[2]/255,o=Math.min(i,a,r),s=Math.max(i,a,r),l=s-o;return s===o?e=0:i===s?e=(a-r)/l:a===s?e=2+(r-i)/l:r===s&&(e=4+(i-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),n=(o+s)/2,[e,100*(s===o?0:n<=.5?l/(s+o):l/(2-s-o)),100*n]},a.rgb.hsv=function(t){var e,n,i,a,r,o=t[0]/255,s=t[1]/255,l=t[2]/255,u=Math.max(o,s,l),d=u-Math.min(o,s,l),h=function(t){return(u-t)/6/d+.5};return 0===d?a=r=0:(r=d/u,e=h(o),n=h(s),i=h(l),o===u?a=i-n:s===u?a=1/3+e-i:l===u&&(a=2/3+n-e),a<0?a+=1:a>1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=n[t];if(i)return i;var a,r,o,s=1/0;for(var l in e)if(e.hasOwnProperty(l)){var u=e[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map((function(t){return t+t})).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}}));n.rgb,n.hsl,n.hsv,n.hwb,n.cmyk,n.xyz,n.lab,n.lch,n.hex,n.keyword,n.ansi16,n.ansi256,n.hcg,n.apple,n.gray;function i(t){var e=function(){for(var t={},e=Object.keys(n),i=e.length,a=0;a1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)}))}));var s=o,l={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},u={getRgba:d,getHsla:h,getRgb:function(t){var e=d(t);return e&&e.slice(0,3)},getHsl:function(t){var e=h(t);return e&&e.slice(0,3)},getHwb:c,getAlpha:function(t){var e=d(t);if(e)return e[3];if(e=h(t))return e[3];if(e=c(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+v(t[0])+v(t[1])+v(t[2])+(e>=0&&e<1?v(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return f(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:f,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:g,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return b[t.slice(0,3)]}};function d(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;rn?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new y,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},y.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},y.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},y.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i=0;a--)e.call(n,t[a],a);else for(a=0;a=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-C.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*C.easeInBounce(2*t):.5*C.easeOutBounce(2*t-1)+.5}},P={effects:C};S.easingEffects=C;var A=Math.PI,D=A/180,T=2*A,I=A/2,F=A/4,O=2*A/3,L={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),se.left-1e-6&&t.xe.top-1e-6&&t.y0&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r=n?(H.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},Q=H.options.resolve,tt=["push","pop","shift","splice","unshift"];function et(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(tt.forEach((function(e){delete t[e]})),delete t._chartjs)}}var nt=function(t,e){this.initialize(t,e)};H.extend(nt.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this.getMeta(),e=this.chart,n=e.scales,i=this.getDataset(),a=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||a.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||a.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&et(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;tn&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;na?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function ot(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+at,rt(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=at,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+at,n.startAngle,!0),a=0;as;)a-=at;for(;a=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/at)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+at,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;tt.x&&(e=bt(e,"left","right")):t.basen?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function yt(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&vt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}N._set("global",{elements:{rectangle:{backgroundColor:pt,borderColor:pt,borderSkipped:"bottom",borderWidth:0}}});var _t=K.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=vt(t),n=e.right-e.left,i=e.bottom-e.top,a=xt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return yt(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return mt(n)?yt(n,t,null):yt(n,null,e)},inXRange:function(t){return yt(this._view,t,null)},inYRange:function(t){return yt(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return mt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return mt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),kt={},wt=st,Mt=dt,St=gt,Ct=_t;kt.Arc=wt,kt.Line=Mt,kt.Point=St,kt.Rectangle=Ct;var Pt=H._deprecated,At=H.valueOrDefault;function Dt(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=H.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return H.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}N._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),N._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Tt=it.extend({dataElementType:kt.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;it.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Pt("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Pt("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Pt("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Pt("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Pt("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,n=i.length;e=0&&p.min>=0?p.min:p.max,y=void 0===p.start?p.end:p.max>=0&&p.min>=0?p.max-p.min:p.min-p.max,_=g.length;if(v||void 0===v&&void 0!==b)for(i=0;i<_&&(a=g[i]).index!==t;++i)a.stack===b&&(r=void 0===(u=h._parseValue(f[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(p.min<0&&r<0||p.max>=0&&r>0)&&(x+=r));return o=h.getPixelForValue(x),l=(s=h.getPixelForValue(x+y))-o,void 0!==m&&Math.abs(l)=0&&!c||y<0&&c?o-m:o+m),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t=Rt?-zt:b<-Rt?zt:0)+m,y=Math.cos(b),_=Math.sin(b),k=Math.cos(x),w=Math.sin(x),M=b<=0&&x>=0||x>=zt,S=b<=Nt&&x>=Nt||x>=zt+Nt,C=b<=-Nt&&x>=-Nt||x>=Rt+Nt,P=b===-Rt||x>=Rt?-1:Math.min(y,y*p,k,k*p),A=C?-1:Math.min(_,_*p,w,w*p),D=M?1:Math.max(y,y*p,k,k*p),T=S?1:Math.max(_,_*p,w,w*p);u=(D-P)/2,d=(T-A)/2,h=-(D+P)/2,c=-(T+A)/2}for(i=0,a=g.length;i0&&!isNaN(t)?zt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Lt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Lt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Lt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n0&&Ht(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return ae(t,e,{intersect:!1})},point:function(t,e){return ee(t,Qt(e,t))},nearest:function(t,e,n){var i=Qt(e,t);n.axis=n.axis||"xy";var a=ie(n.axis);return ne(t,i,n.intersect,a)},x:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},oe=H.extend;function se(t,e){return H.where(t,(function(t){return t.pos===e}))}function le(t,e){return t.sort((function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight}))}function ue(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function de(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-ue(o,t,"left","right"),a=e.outerHeight-ue(o,t,"top","bottom"),i!==t.w||a!==t.h){t.w=i,t.h=a;var l=n.horizontal?[i,t.w]:[a,t.h];return!(l[0]===l[1]||isNaN(l[0])&&isNaN(l[1]))}}function he(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach((function(t){i[t]=Math.max(e[t],n[t])})),i}return i(t?["left","right"]:["top","bottom"])}function ce(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;idiv{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&ge.default||ge,ve="$chartjs",be="chartjs-size-monitor",xe="chartjs-render-monitor",ye="chartjs-render-animation",_e=["animationstart","webkitAnimationStart"],ke={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function we(t,e){var n=H.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var Me=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Se(t,e,n){t.addEventListener(e,n,Me)}function Ce(t,e,n){t.removeEventListener(e,n,Me)}function Pe(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Ae(t){var e=document.createElement("div");return e.className=t||"",e}function De(t,e,n){var i,a,r,o,s=t[ve]||(t[ve]={}),l=s.resizer=function(t){var e=Ae(be),n=Ae(be+"-expand"),i=Ae(be+"-shrink");n.appendChild(Ae()),i.appendChild(Ae()),e.appendChild(n),e.appendChild(i),e._reset=function(){n.scrollLeft=1e6,n.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var a=function(){e._reset(),t()};return Se(n,"scroll",a.bind(n,"expand")),Se(i,"scroll",a.bind(i,"shrink")),e}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(Pe("resize",n)),i&&i.clientWidth0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index-1?t.split("\n"):t}function Ve(t){var e=N.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:ze(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:ze(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:ze(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:ze(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:ze(t.titleFontStyle,e.defaultFontStyle),titleFontSize:ze(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:ze(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:ze(t.footerFontStyle,e.defaultFontStyle),footerFontSize:ze(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function He(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function je(t){return Ee([],We(t))}var qe=K.extend({initialize:function(){this._model=Ve(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=Ee(o,We(i)),o=Ee(o,We(a)),o=Ee(o,We(r))},getBeforeBody:function(){return je(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return H.each(t,(function(t){var r={before:[],lines:[],after:[]};Ee(r.before,We(i.beforeLabel.call(n,t,e))),Ee(r.lines,i.label.call(n,t,e)),Ee(r.after,We(i.afterLabel.call(n,t,e))),a.push(r)})),a},getAfterBody:function(){return je(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=Ee(r,We(n)),r=Ee(r,We(i)),r=Ee(r,We(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=Ve(c),p=h._active,m=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},x={width:f.width,height:f.height},y={x:f.caretX,y:f.caretY};if(p.length){g.opacity=1;var _=[],k=[];y=Be[c.position].call(h,p,h._eventPosition);var w=[];for(e=0,n=p.length;ei.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,x,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.yl.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,x),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=x.width,g.height=x.height,g.caretX=y.x,g.caretY=y.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===c)s=g+m/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+p)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+p-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+m)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=Ne(e.rtl,e.x,e.width);for(t.x=He(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=H.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,H.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),H.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!H.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),Ue=Be,Ye=qe;Ye.positioners=Ue;var Ge=H.valueOrDefault;function Xe(){return H.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?H.merge(e[t][a],[Re.getScaleDefaults(r),o]):H.merge(e[t][a],o)}else H._merger(t,e,n,i)}})}function Ke(){return H.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||Object.create(null),r=n[t];"scales"===t?e[t]=Xe(a,r):"scale"===t?e[t]=H.merge(a,[Re.getScaleDefaults(r.type),r]):H._merger(t,e,n,i)}})}function Ze(t){var e=t.options;H.each(t.scales,(function(e){pe.removeBox(t,e)})),e=Ke(N.global,N[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function $e(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(H.findIndex(t,a)>=0);return i}function Je(t){return"top"===t||"bottom"===t}function Qe(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}N._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var tn=function(t,e){return this.construct(t,e),this};H.extend(tn.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||Object.create(null)).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=Ke(N.global,N[t.type],t.options||{}),t}(e);var i=Oe.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=H.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,tn.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Le.notify(t,"beforeInit"),H.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Le.notify(t,"afterInit"),t},clear:function(){return H.canvas.clear(this),this},stop:function(){return J.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(H.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:H.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",H.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Le.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;H.each(e.xAxes,(function(t,n){t.id||(t.id=$e(e.xAxes,"x-axis-",n))})),H.each(e.yAxes,(function(t,n){t.id||(t.id=$e(e.yAxes,"y-axis-",n))})),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce((function(t,e){return t[e]=!1,t}),{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map((function(t){return{options:t,dtype:"category",dposition:"bottom"}})),(e.scales.yAxes||[]).map((function(t){return{options:t,dtype:"linear",dposition:"left"}})))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),H.each(i,(function(e){var i=e.options,r=i.id,o=Ge(i.type,e.dtype);Je(i.position)!==Je(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Re.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)})),H.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Re.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t=0;--n)this.drawDataset(e[n],t);Le.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Le.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Le.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Le.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Le.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return re.modes.single(this,t)},getElementsAtEvent:function(t){return re.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return re.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=re.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return re.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=H.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=H.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(H.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},sn=H.isArray,ln=H.isNullOrUndef,un=H.valueOrDefault,dn=H.valueAtIndexOrDefault;function hn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=rl+1e-6)))return o}function cn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,p,m,v=n.length,b=[],x=[],y=[],_=0,k=0;for(a=0;ae){for(n=0;n=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-fn(l.gridLines)-u.padding-gn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=H.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){H.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){H.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=fn(o)+gn(r)),u?s&&(e.height=fn(o)+gn(r)):e.height=t.maxHeight,a.display&&s){var d=mn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,p=h.highest,m=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,x=H.toRadians(t.labelRotation),y=Math.cos(x),_=Math.sin(x),k=_*g.width+y*(p.height-(b?p.offset:0))+(b?0:m);e.height=Math.min(t.maxHeight,e.height+k+v);var w,M,S=t.getPixelForTick(0)-t.left,C=t.right-t.getPixelForTick(t.getTicks().length-1);b?(w=l?y*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):y*f.width+_*f.offset):(w=c.width/2,M=f.width/2),t.paddingLeft=Math.max((w-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-C)*t.width/(t.width-C),0)+3}else{var P=a.mirror?0:g.width+v+m;e.width=Math.min(t.maxWidth,e.width+P),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){H.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(ln(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map((function(t){return t.value})),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;nn-1?null:this.getPixelForDecimal(t*i+(e?i/2:0))},getPixelForDecimal:function(t){return this._reversePixels&&(t=1-t),this._startPixel+t*this._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,r=this.options.ticks,o=this._length,s=r.maxTicksLimit||o/this._tickSize()+1,l=r.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;es)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;iu)return r;return Math.max(u,1)}(l,t,0,s),u>0){for(e=0,n=u-1;e1?(h-d)/(u-1):null,bn(t,i,H.isNullOrUndef(a)?0:d-a,d),bn(t,i,h,H.isNullOrUndef(a)?t.length:h+a),vn(t)}return bn(t,i),vn(t)},_tickSize:function(){var t=this.options.ticks,e=H.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),a=this._getLabelSizes(),r=t.autoSkipPadding||0,o=a?a.widest.width+r:0,s=a?a.highest.height+r:0;return this.isHorizontal()?s*n>o*i?o/n:s/i:s*i=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this._getLabels(),e=this.minIndex,n=this.maxIndex;this.ticks=0===e&&n===t.length-1?t:t.slice(e,n+1)},getLabelForIndex:function(t,e){var n=this.chart;return n.getDatasetMeta(e).controller._getValueScaleId()===this.id?this.getRightValue(n.data.datasets[e].data[t]):this._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;yn.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return _n(e)||_n(n)||(t=o.chart.data.datasets[n].data[e]),_n(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=H.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange);return Math.min(Math.max(e,0),this.ticks.length-1)},getBasePixel:function(){return this.bottom}}),wn={position:"bottom"};kn._defaults=wn;var Mn=H.noop,Sn=H.isNullOrUndef;var Cn=yn.extend({getRightValue:function(t){return"string"==typeof t?+t:yn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=H.sign(t.min),i=H.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,n=e.stepSize,i=e.maxTicksLimit;return n?t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1:(t=this._computeTickLimit(),i=i||11),i&&(t=Math.min(i,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:Mn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:H.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,p=H.niceNum((g-f)/u/l)*l;if(p<1e-14&&Sn(d)&&Sn(h))return[f,g];(r=Math.ceil(g/p)-Math.floor(f/p))>u&&(p=H.niceNum(r*p/u/l)*l),s||Sn(c)?n=Math.pow(10,H._decimalPlaces(p)):(n=Math.pow(10,c),p=Math.ceil(p*n)/n),i=Math.floor(f/p)*p,a=Math.ceil(g/p)*p,s&&(!Sn(d)&&H.almostWhole(d/p,p/1e3)&&(i=d),!Sn(h)&&H.almostWhole(h/p,p/1e3)&&(a=h)),r=(a-i)/p,r=H.almostEquals(r,Math.round(r),p/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Sn(d)?i:d);for(var m=1;me.length-1?null:this.getPixelForValue(e[t])}}),In=Pn;Tn._defaults=In;var Fn=H.valueOrDefault,On=H.math.log10;var Ln={position:"left",ticks:{callback:on.formatters.logarithmic}};function Rn(t,e){return H.isFinite(t)&&t>=0?t:e}var zn=yn.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t0){var e=H.min(t),n=H.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}}))}else for(t=0;t0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(On(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:Rn(e.min),max:Rn(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=Fn(t.min,Math.pow(10,Math.floor(On(e.min)))),o=Math.floor(On(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(On(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(On(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10===++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(ne.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(On(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;yn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=Fn(t.options.ticks.fontSize,N.global.defaultFontSize)/t._length),t._startValue=On(e),t._valueOffset=n,t._valueRange=(On(t.max)-On(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(On(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),Nn=Ln;zn._defaults=Nn;var Bn=H.valueOrDefault,En=H.valueAtIndexOrDefault,Wn=H.options.resolve,Vn={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:on.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Hn(t){var e=t.ticks;return e.display&&t.display?Bn(e.fontSize,N.global.defaultFontSize)+2*e.backdropPaddingY:0}function jn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:ta?{start:e-n,end:e}:{start:e,end:e+n}}function qn(t){return 0===t||180===t?"center":t<180?"left":"right"}function Un(t,e,n,i){var a,r,o=n.y+i/2;if(H.isArray(e))for(a=0,r=e.length;a270||t<90)&&(n.y-=e.h)}function Gn(t){return H.isNumber(t)?t:0}var Xn=Cn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Hn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;H.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);H.each(a.data,(function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))}))}})),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Hn(this.options))},convertTicksToLabels:function(){var t=this;Cn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=H.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""}))},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,n,i,a=H.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;er.r&&(r.r=f.end,o.r=h),g.startr.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=Gn(a),r=Gn(r),o=Gn(o),s=Gn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(H.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this.min,n=this.max;return this.getPointPositionForValue(t||0,this.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=Bn(s.lineWidth,o.lineWidth),u=Bn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Hn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=H.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=En(i.fontColor,s,N.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=H.toDegrees(h);e.textAlign=qn(c),Yn(c,t._pointLabelSizes[s],u),Un(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&H.each(i.ticks,(function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=En(e.color,i-1),u=En(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=H.options._parseFont(n),s=Bn(n.fontColor,N.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",H.each(t.ticks,(function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))})),e.restore()}},_drawTitle:H.noop}),Kn=Vn;Xn._defaults=Kn;var Zn=H._deprecated,$n=H.options.resolve,Jn=H.valueOrDefault,Qn=Number.MIN_SAFE_INTEGER||-9007199254740991,ti=Number.MAX_SAFE_INTEGER||9007199254740991,ei={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ni=Object.keys(ei);function ii(t,e){return t-e}function ai(t){return H.valueOrDefault(t.time.min,t.ticks.min)}function ri(t){return H.valueOrDefault(t.time.max,t.ticks.max)}function oi(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function si(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),H.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),H.isFinite(o)||(o=n.parse(o))),o)}function li(t,e){if(H.isNullOrUndef(e))return null;var n=t.options.time,i=si(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function ui(t,e,n,i){var a,r,o,s=ni.length;for(a=ni.indexOf(t);a=0&&(e[r].major=!0);return e}(t,r,o,n):r}var hi=yn.extend({initialize:function(){this.mergeTicksOptions(),yn.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new rn._date(e.adapters.date);return Zn("time scale",n.format,"time.format","time.parser"),Zn("time scale",n.min,"time.min","ticks.min"),Zn("time scale",n.max,"time.max","ticks.max"),H.mergeIf(n.displayFormats,i.formats()),yn.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),yn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=ti,f=Qn,g=[],p=[],m=[],v=s._getLabels();for(t=0,n=v.length;t1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?ui(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ni.length-1;r>=ni.indexOf(n);r--)if(o=ni[r],ei[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ni[n?ni.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ni.indexOf(t)+1,n=ni.length;ee&&s=0&&t0?s:1}}),ci={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};hi._defaults=ci;var fi={category:kn,linear:Tn,logarithmic:zn,radialLinear:Xn,time:hi},gi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};rn._date.override("function"==typeof t?{_id:"moment",formats:function(){return gi},parse:function(e,n){return"string"==typeof e&&"string"==typeof n?e=t(e,n):e instanceof t||(e=t(e)),e.isValid()?e.valueOf():null},format:function(e,n){return t(e).format(n)},add:function(e,n,i){return t(e).add(n,i).valueOf()},diff:function(e,n,i){return t(e).diff(t(n),i)},startOf:function(e,n,i){return e=t(e),"isoWeek"===n?e.isoWeekday(i).valueOf():e.startOf(n).valueOf()},endOf:function(e,n){return t(e).endOf(n).valueOf()},_create:function(e){return t(e)}}:{}),N._set("global",{plugins:{filler:{propagate:!0}}});var pi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function vi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a0;--r)H.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function ki(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,p=i.spanGaps,m=[],v=[],b=0,x=0;for(t.beginPath(),o=0,s=g;o=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||N.global.defaultColor,o&&s&&r.length&&(H.canvas.clipArea(u,t.chartArea),ki(u,r,o,a,s,i._loop),H.canvas.unclipArea(u)))}},Mi=H.rtl.getRtlAdapter,Si=H.noop,Ci=H.valueOrDefault;function Pi(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}N._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map((function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}}),this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;el.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding})),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],p=n.padding,m=0,v=0;H.each(t.legendItems,(function(t,e){var i=Pi(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(p+=m+n.padding,f.push(m),g.push(v),m=0,v=0),m=Math.max(m,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),p+=m,f.push(m),g.push(v),l.width+=p}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Si,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=N.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=Mi(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Ci(n.fontColor,i.defaultFontColor),g=H.options._parseFont(n),p=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var m=Pi(n,p),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},x=t.isHorizontal();d=x?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},H.rtl.overrideTextDirection(t.ctx,e.textDirection);var y=p+n.padding;H.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=m+p/2+f,_=d.x,k=d.y;h.setWidth(t.minSize.width),x?i>0&&_+g+n.padding>t.left+t.minSize.width&&(k=d.y+=y,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&k+y>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,k=d.y=t.top+b(o,s[d.line]));var w=h.x(_);!function(t,e,i){if(!(isNaN(m)||m<=0)){c.save();var o=Ci(i.lineWidth,r.borderWidth);if(c.fillStyle=Ci(i.fillStyle,a),c.lineCap=Ci(i.lineCap,r.borderCapStyle),c.lineDashOffset=Ci(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Ci(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Ci(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Ci(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=m*Math.SQRT2/2,l=h.xPlus(t,m/2),u=e+p/2;H.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,m),e,m,p),0!==o&&c.strokeRect(h.leftForLtr(t,m),e,m,p);c.restore()}}(w,k,e),v[i].left=h.leftForLtr(w,v[i].width),v[i].top=k,function(t,e,n,i){var a=p/2,r=h.xPlus(t,m+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(w,k,e,f),x?d.x+=g+n.padding:d.y+=y})),H.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Di(t,e){var n=new Ai({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.legend=n}var Ti={id:"legend",_element:Ai,beforeInit:function(t){var e=t.options.legend;e&&Di(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(H.mergeIf(e,N.global.legend),n?(pe.configure(t,n,e),n.options=e):Di(t,e)):n&&(pe.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ii=H.noop;N._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Fi=K.extend({initialize:function(t){H.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Ii,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Ii,beforeSetDimensions:Ii,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Ii,beforeBuildLabels:Ii,buildLabels:Ii,afterBuildLabels:Ii,beforeFit:Ii,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(H.isArray(n.text)?n.text.length:1)*H.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Ii,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=H.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=H.valueOrDefault(n.fontColor,N.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(H.isArray(g))for(var p=0,m=0;m=0;i--){var a=t[i];if(e(a))return a}},H.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},H.almostEquals=function(t,e,n){return Math.abs(t-e)=t},H.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},H.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},H.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},H.toRadians=function(t){return t*(Math.PI/180)},H.toDegrees=function(t){return t*(180/Math.PI)},H._decimalPlaces=function(t){if(H.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},H.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},H.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},H.aliasPixel=function(t){return t%2==0?0:.5},H._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},H.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},H.EPSILON=Number.EPSILON||1e-14,H.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map((function(t){return{model:t._model,deltaK:0,mK:0}})),h=d.length;for(e=0;e0?d[e-1]:null,(a=e0?d[e-1]:null,a=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},H.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},H.niceNum=function(t,e){var n=Math.floor(H.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},H.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},H.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(H.getStyle(r,"padding-left")),u=parseFloat(H.getStyle(r,"padding-top")),d=parseFloat(H.getStyle(r,"padding-right")),h=parseFloat(H.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},H.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},H.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},H._calculatePadding=function(t,e,n){return(e=H.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},H._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},H.getMaximumWidth=function(t){var e=H._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-H._calculatePadding(e,"padding-left",n)-H._calculatePadding(e,"padding-right",n),a=H.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},H.getMaximumHeight=function(t){var e=H._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-H._calculatePadding(e,"padding-top",n)-H._calculatePadding(e,"padding-bottom",n),a=H.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},H.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},H.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},H.fontString=function(t,e,n){return e+" "+t+"px "+n},H.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;on.length){for(o=0;oi&&(i=r),i},H.numberOfLabelLines=function(t){var e=1;return H.each(t,(function(t){H.isArray(t)&&t.length>e&&(e=t.length)})),e},H.color=_?function(t){return t instanceof CanvasGradient&&(t=N.global.defaultColor),_(t)}:function(t){return console.error("Color.js not found!"),t},H.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:H.color(t).saturate(.5).darken(.1).rgbString()}}(),en._adapters=rn,en.Animation=$,en.animationService=J,en.controllers=Jt,en.DatasetController=it,en.defaults=N,en.Element=K,en.elements=kt,en.Interaction=re,en.layouts=pe,en.platform=Oe,en.plugins=Le,en.Scale=yn,en.scaleService=Re,en.Ticks=on,en.Tooltip=Ye,en.helpers.each(fi,(function(t,e){en.scaleService.registerScaleType(e,t,t._defaults)})),Li)Li.hasOwnProperty(Bi)&&en.plugins.register(Li[Bi]);en.platform.initialize();var Ei=en;return"undefined"!=typeof window&&(window.Chart=en),en.Chart=en,en.Legend=Li.legend._element,en.Title=Li.title._element,en.pluginService=en.plugins,en.PluginBase=en.Element.extend({}),en.canvasHelpers=en.helpers.canvas,en.layoutService=en.layouts,en.LinearScaleBase=Cn,en.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){en[t]=function(e,n){return new en(e,en.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Ei})); From 29d316a967c289b0242d7f756aed696eaa36ede6 Mon Sep 17 00:00:00 2001 From: Felix Date: Fri, 26 Mar 2021 20:09:31 +0100 Subject: [PATCH 33/40] add chart bg add chart dummy data --- src/app/dashboard/chart/chart.component.css | 10 ++++++++ src/app/dashboard/chart/chart.component.html | 4 +++- src/app/dashboard/chart/chart.component.ts | 10 +++++++- .../dashboard/summary/summary.component.css | 23 +++++++++++++++++-- .../dashboard/summary/summary.component.html | 3 ++- 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/app/dashboard/chart/chart.component.css b/src/app/dashboard/chart/chart.component.css index e69de29..9ebdd3b 100644 --- a/src/app/dashboard/chart/chart.component.css +++ b/src/app/dashboard/chart/chart.component.css @@ -0,0 +1,10 @@ +.bg { + background-color: #26283A; + margin: 0; + padding: 0; + padding: 2rem; + padding-right: 2rem; + margin: 0 auto; + width: 80%; + border-radius: 0px 0px 5px 5px; +} \ No newline at end of file diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html index 8a42052..128c50a 100644 --- a/src/app/dashboard/chart/chart.component.html +++ b/src/app/dashboard/chart/chart.component.html @@ -1,3 +1,5 @@ -
+
+
+

Chart workds

\ No newline at end of file diff --git a/src/app/dashboard/chart/chart.component.ts b/src/app/dashboard/chart/chart.component.ts index 3345e54..7eb7df7 100644 --- a/src/app/dashboard/chart/chart.component.ts +++ b/src/app/dashboard/chart/chart.component.ts @@ -8,15 +8,23 @@ import { EChartsOption } from 'echarts'; }) export class ChartComponent { chartOption: EChartsOption = { + color: ["#C61A4E"], xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, + + tooltip: { + trigger: 'item', + showDelay: 0, + transitionDuration: 0.2 + }, + yAxis: { type: 'value' }, series: [{ - data: [820, 932, 901, 934, 1290, 1330, 1320], + data: [820, 932, 901, 934, 1290, 1330, 1320, 654, 68, 846, 987, 846, 874], type: 'line', smooth: true }] diff --git a/src/app/dashboard/summary/summary.component.css b/src/app/dashboard/summary/summary.component.css index ec36ddc..3e52d7b 100644 --- a/src/app/dashboard/summary/summary.component.css +++ b/src/app/dashboard/summary/summary.component.css @@ -1,10 +1,11 @@ .header { - background-color: #242635; + background: #242635; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + border-radius: 8px 8px 0px 0px; margin: 0; padding: 0; padding: 2rem; padding-right: 2rem; - border-radius: 22px; border-bottom-left-radius: 0; border-bottom-right-radius: 0; margin: 0 auto; @@ -15,4 +16,22 @@ background-color: #26283A; margin: 0; padding: 6rem; +} + +.sum { + color: #fff; + line-height: 29px; + font-size: 24px; + font-weight: 800; + font-style: normal; + font-family: 'Inter'; +} + +.stoke { + width: 39px; + height: 0px; + left: 272px; + top: 182px; + border: 1px solid #FFFFFF; + transform: rotate(90deg); } \ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.html b/src/app/dashboard/summary/summary.component.html index eceab7f..7f42f4e 100644 --- a/src/app/dashboard/summary/summary.component.html +++ b/src/app/dashboard/summary/summary.component.html @@ -1,3 +1,4 @@
- + Summary +
\ No newline at end of file From 2f1eb39f7a2519609089473e23c25803a7eb50bf Mon Sep 17 00:00:00 2001 From: Felix Date: Sat, 27 Mar 2021 17:40:33 +0100 Subject: [PATCH 34/40] add dropdown add custom css --- package-lock.json | 8 +++++ package.json | 2 ++ src/app/app.module.ts | 3 ++ src/app/dashboard/chart/chart.component.html | 4 +-- .../dashboard/summary/summary.component.css | 29 ++++++++++++++----- .../dashboard/summary/summary.component.html | 16 ++++++++-- .../dashboard/summary/summary.component.ts | 12 ++++++++ src/styles.css | 8 +++-- 8 files changed, 68 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index d45d06b..30db365 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1488,6 +1488,14 @@ "schema-utils": "^2.7.0" } }, + "@ng-select/ng-select": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-6.1.0.tgz", + "integrity": "sha512-uro/zIjL+TRWzbrzNN9IjIusOeLfhCn9cIr5Bq3AsJyxyU7Gdj9kOD5wVrrQ0NVkaQ1BJMcWmUvmYGBXLI6cnA==", + "requires": { + "tslib": "^2.0.0" + } + }, "@ngtools/webpack": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-11.0.5.tgz", diff --git a/package.json b/package.json index cdf60b7..cdef68b 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,8 @@ "@angular/platform-browser": "~11.0.5", "@angular/platform-browser-dynamic": "~11.0.5", "@angular/router": "~11.0.5", + "@ng-select/ng-select": "^6.1.0", + "@swimlane/ngx-charts": "^17.0.0", "angularx-qrcode": "^10.0.11", "d3-shape": "^2.1.0", "echarts": "^5.0.2", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 3c045d1..c13305a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -23,6 +23,8 @@ import { ChartComponent } from './dashboard/chart/chart.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { SummaryComponent } from './dashboard/summary/summary.component'; import { NgxEchartsModule } from 'ngx-echarts'; +import { NgSelectModule } from '@ng-select/ng-select'; + @NgModule({ declarations: [ @@ -48,6 +50,7 @@ import { NgxEchartsModule } from 'ngx-echarts'; PushNotificationsModule, ClipboardModule, FormsModule, + NgSelectModule, BrowserAnimationsModule, NgxEchartsModule.forRoot({ echarts: () => import('echarts') diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html index 128c50a..4db0798 100644 --- a/src/app/dashboard/chart/chart.component.html +++ b/src/app/dashboard/chart/chart.component.html @@ -1,5 +1,3 @@
-
- -

Chart workds

\ No newline at end of file + \ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.css b/src/app/dashboard/summary/summary.component.css index 3e52d7b..621ee61 100644 --- a/src/app/dashboard/summary/summary.component.css +++ b/src/app/dashboard/summary/summary.component.css @@ -27,11 +27,26 @@ font-family: 'Inter'; } -.stoke { - width: 39px; - height: 0px; - left: 272px; - top: 182px; - border: 1px solid #FFFFFF; - transform: rotate(90deg); +.grid-container { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-rows: 1fr 1fr 1fr; + gap: 0px 0px; + grid-template-areas: "sum dropdown void1 void" ". . . ." ". . . ."; +} + +.sum { + grid-area: sum; +} + +.void { + grid-area: void; +} + +.dropdown { + grid-area: dropdown; +} + +.void1 { + grid-area: void1; } \ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.html b/src/app/dashboard/summary/summary.component.html index 7f42f4e..e068754 100644 --- a/src/app/dashboard/summary/summary.component.html +++ b/src/app/dashboard/summary/summary.component.html @@ -1,4 +1,16 @@
- Summary -
+ + +
+
+ Summary +
+ +
+
+
\ No newline at end of file diff --git a/src/app/dashboard/summary/summary.component.ts b/src/app/dashboard/summary/summary.component.ts index 011993b..40301bc 100644 --- a/src/app/dashboard/summary/summary.component.ts +++ b/src/app/dashboard/summary/summary.component.ts @@ -7,6 +7,18 @@ import { Component, OnInit } from '@angular/core'; }) export class SummaryComponent implements OnInit { + + summary = 1; + + dates = [ + { id: 1, name: 'Today' }, + { id: 2, name: 'Last 3 days' }, + { id: 3, name: 'One month' }, + { id: 4, name: 'Last 3 months' }, + { id: 5, name: 'One year' }, + { id: 6, name: 'Last 3 years' }, + ]; + constructor() { } ngOnInit(): void { diff --git a/src/styles.css b/src/styles.css index 869a5d1..27b2e12 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,14 +1,18 @@ +@import "~@ng-select/ng-select/themes/default.theme.css"; + /* You can add global styles to this file, and also import other style files */ + * { font-family: 'Inter', sans-serif; } -body, html { +body, +html { margin: 0; padding: 0; } -:host{ +:host { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } From 0641425d079e065bd4e46cd3c03ce8e3860578fb Mon Sep 17 00:00:00 2001 From: Felix Date: Sat, 27 Mar 2021 18:02:35 +0100 Subject: [PATCH 35/40] add custom dropdown css --- src/dropdown.css | 335 +++++++++++++++++++++++++++++++++++++++++++++++ src/styles.css | 2 +- 2 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 src/dropdown.css diff --git a/src/dropdown.css b/src/dropdown.css new file mode 100644 index 0000000..9219787 --- /dev/null +++ b/src/dropdown.css @@ -0,0 +1,335 @@ +.ng-select.ng-select-opened>.ng-select-container { + background: #242635; + border-color: #C61A4E #C61A4E #C61A4E +} + +.ng-select.ng-select-opened>.ng-select-container:hover { + box-shadow: none +} + +.ng-select.ng-select-opened>.ng-select-container .ng-arrow { + top: -2px; + border-color: transparent transparent #C61A4E; + border-width: 0 5px 5px +} + +.ng-select.ng-select-opened>.ng-select-container .ng-arrow:hover { + border-color: transparent transparent #333 +} + +.ng-select.ng-select-opened.ng-select-bottom>.ng-select-container { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0 +} + +.ng-select.ng-select-opened.ng-select-top>.ng-select-container { + border-top-right-radius: 0; + border-top-left-radius: 0 +} + +.ng-select.ng-select-focused:not(.ng-select-opened)>.ng-select-container { + border-color: #007eff; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 3px rgba(0, 126, 255, 0.1) +} + +.ng-select.ng-select-disabled>.ng-select-container { + background-color: #C61A4E +} + +.ng-select .ng-has-value .ng-placeholder { + display: none +} + +.ng-select .ng-select-container { + color: #fff; + background-color: #242635; + border-radius: 0px; + border: 1px solid #C61A4E; + min-height: 36px; + align-items: center +} + +.ng-select .ng-select-container:hover { + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06) +} + +.ng-select .ng-select-container .ng-value-container { + align-items: center; + padding-left: 10px +} + +[dir="rtl"] .ng-select .ng-select-container .ng-value-container { + padding-right: 5px; + padding-left: 0 +} + +.ng-select .ng-select-container .ng-value-container .ng-placeholder { + color: #C61A4E; +} + +.ng-select.ng-select-single .ng-select-container { + height: 36px +} + +.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input { + top: 5px; + left: 0; + padding-left: 10px; + padding-right: 50px +} + +[dir="rtl"] .ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input { + padding-right: 10px; + padding-left: 50px +} + +.ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value { + background-color: #242635; + border: 1px solid #242635; +} + +.ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value .ng-value-label { + padding: 0 5px +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container { + padding-top: 5px; + padding-left: 7px +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container { + padding-right: 7px; + padding-left: 0 +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value { + font-size: .9em; + margin-bottom: 5px; + background-color: #242635; + border-radius: 2px; + margin-right: 5px +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value { + margin-right: 0; + margin-left: 5px +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled { + background-color: #242635 +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled .ng-value-label { + padding-left: 5px +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled .ng-value-label { + padding-left: 0; + padding-right: 5px +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-label { + display: inline-block; + padding: 1px 5px +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon { + display: inline-block; + padding: 1px 5px +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon:hover { + background-color: #242635 +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.left { + border-right: 1px solid #242635; +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.left { + border-left: 1px solid #242635; + border-right: none +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.right { + border-left: 1px solid #242635 +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon.right { + border-left: 0; + border-right: 1px solid #242635 +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-input { + padding: 0 0 3px 3px +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-input { + padding: 0 3px 3px 0 +} + +.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder { + top: 5px; + padding-bottom: 5px; + padding-left: 3px +} + +[dir="rtl"] .ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder { + padding-right: 3px; + padding-left: 0 +} + +.ng-select .ng-clear-wrapper { + color: #999 +} + +.ng-select .ng-clear-wrapper:hover .ng-clear { + color: #D0021B; + box-shadow: 10px 10px 105px -30px rgba(198, 26, 78, 0.6); +} + +.ng-select .ng-spinner-zone { + padding: 5px 5px 0 0 +} + +[dir="rtl"] .ng-select .ng-spinner-zone { + padding: 5px 0 0 5px +} + +.ng-select .ng-arrow-wrapper { + width: 25px; + padding-right: 5px +} + +[dir="rtl"] .ng-select .ng-arrow-wrapper { + padding-left: 5px; + padding-right: 0 +} + +.ng-select .ng-arrow-wrapper:hover .ng-arrow { + border-top-color: #666 +} + +.ng-select .ng-arrow-wrapper .ng-arrow { + border-color: #C61A4E transparent transparent; + border-style: solid; + border-width: 5px 5px 2.5px +} + +.ng-dropdown-panel { + background-color: #242635; + border: 1px solid #C61A4E; + box-shadow: 10px 10px 105px -30px rgba(198, 26, 78, 0.6); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06); + left: 0 +} + +.ng-dropdown-panel.ng-select-bottom { + top: 100%; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + border-top-color: #C61A4E; + box-shadow: 10px 10px 105px -30px rgba(198, 26, 78, 0.6); + margin-top: -1px +} + +.ng-dropdown-panel.ng-select-bottom .ng-dropdown-panel-items .ng-option:last-child { + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px +} + +.ng-dropdown-panel.ng-select-top { + bottom: 100%; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom-color: #242635; + margin-bottom: -1px +} + +.ng-dropdown-panel.ng-select-top .ng-dropdown-panel-items .ng-option:first-child { + border-top-right-radius: 4px; + border-top-left-radius: 4px +} + +.ng-dropdown-panel .ng-dropdown-header { + border-bottom: 1px solid #242635; + padding: 5px 7px +} + +.ng-dropdown-panel .ng-dropdown-footer { + border-top: 1px solid #242635; + padding: 5px 7px +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup { + user-select: none; + padding: 8px 10px; + font-weight: 500; + color: rgba(0, 0, 0, 0.54); + cursor: pointer +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-disabled { + cursor: default +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-marked { + background-color: #242635; +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-selected, +.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup.ng-option-selected.ng-option-marked { + background-color: #242635; + font-weight: 600 +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option { + background-color: #242635; + color: rgba(255, 255, 255, 0.87); + padding: 8px 10px +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected, +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected.ng-option-marked { + color: rgb(255, 255, 255); + background-color: #242635 +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected .ng-option-label, +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected.ng-option-marked .ng-option-label { + font-weight: 600 +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-marked { + background-color: #f5faff; + color: #333 +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-disabled { + color: #ccc +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-child { + padding-left: 22px +} + +[dir="rtl"] .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-child { + padding-right: 22px; + padding-left: 0 +} + +.ng-dropdown-panel .ng-dropdown-panel-items .ng-option .ng-tag-label { + font-size: 80%; + font-weight: 400; + padding-right: 5px +} + +[dir="rtl"] .ng-dropdown-panel .ng-dropdown-panel-items .ng-option .ng-tag-label { + padding-left: 5px; + padding-right: 0 +} + +[dir="rtl"] .ng-dropdown-panel { + direction: rtl; + text-align: right +} \ No newline at end of file diff --git a/src/styles.css b/src/styles.css index 27b2e12..fd7b5c8 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,4 +1,4 @@ -@import "~@ng-select/ng-select/themes/default.theme.css"; +@import "dropdown.css"; /* You can add global styles to this file, and also import other style files */ From 22273b8a5ba880aa7df2da580ce493e61dd0c6f3 Mon Sep 17 00:00:00 2001 From: Felix Date: Sun, 4 Apr 2021 15:05:55 +0200 Subject: [PATCH 36/40] edit chart --- package-lock.json | 52 ++++++++++++++ package.json | 5 ++ src/app/app.module.ts | 8 ++- src/app/dashboard/chart/chart.component.css | 19 ++++- src/app/dashboard/chart/chart.component.html | 11 ++- src/app/dashboard/chart/chart.component.ts | 7 ++ .../dashboard/summary/summary.component.css | 2 +- src/app/dashboard/widget/widget.component.css | 72 +++++++++++++++++++ .../dashboard/widget/widget.component.html | 8 +++ .../dashboard/widget/widget.component.spec.ts | 25 +++++++ src/app/dashboard/widget/widget.component.ts | 21 ++++++ 11 files changed, 224 insertions(+), 6 deletions(-) create mode 100644 src/app/dashboard/widget/widget.component.css create mode 100644 src/app/dashboard/widget/widget.component.html create mode 100644 src/app/dashboard/widget/widget.component.spec.ts create mode 100644 src/app/dashboard/widget/widget.component.ts diff --git a/package-lock.json b/package-lock.json index 30db365..e15e454 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1469,6 +1469,58 @@ "to-fast-properties": "^2.0.0" } }, + "@fortawesome/angular-fontawesome": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@fortawesome/angular-fontawesome/-/angular-fontawesome-0.8.2.tgz", + "integrity": "sha512-K/AiykA4YbHKE6XKEtZ0ZvVRQocUHyk+79HYWIfhGy3teHpzxsUqB/UjDaxivgBd6dF6ihlzgEbgrDMHlGNwGg==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + } + } + }, + "@fortawesome/fontawesome-common-types": { + "version": "0.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz", + "integrity": "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "1.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz", + "integrity": "sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, + "@fortawesome/free-brands-svg-icons": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.3.tgz", + "integrity": "sha512-1hirPcbjj72ZJtFvdnXGPbAbpn3Ox6mH3g5STbANFp3vGSiE5u5ingAKV06mK6ZVqNYxUPlh4DlTnaIvLtF2kw==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, + "@fortawesome/free-regular-svg-icons": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.15.3.tgz", + "integrity": "sha512-q4/p8Xehy9qiVTdDWHL4Z+o5PCLRChePGZRTXkl+/Z7erDVL8VcZUuqzJjs6gUz6czss4VIPBRdCz6wP37/zMQ==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz", + "integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.35" + } + }, "@istanbuljs/schema": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", diff --git a/package.json b/package.json index cdef68b..5cb5c77 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,11 @@ "@angular/platform-browser": "~11.0.5", "@angular/platform-browser-dynamic": "~11.0.5", "@angular/router": "~11.0.5", + "@fortawesome/angular-fontawesome": "^0.8.2", + "@fortawesome/fontawesome-svg-core": "^1.2.34", + "@fortawesome/free-brands-svg-icons": "^5.15.2", + "@fortawesome/free-regular-svg-icons": "^5.15.2", + "@fortawesome/free-solid-svg-icons": "^5.15.2", "@ng-select/ng-select": "^6.1.0", "@swimlane/ngx-charts": "^17.0.0", "angularx-qrcode": "^10.0.11", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c13305a..ab2df73 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -24,6 +24,8 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { SummaryComponent } from './dashboard/summary/summary.component'; import { NgxEchartsModule } from 'ngx-echarts'; import { NgSelectModule } from '@ng-select/ng-select'; +import { WidgetComponent } from './dashboard/widget/widget.component'; +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; @NgModule({ @@ -40,7 +42,8 @@ import { NgSelectModule } from '@ng-select/ng-select'; OverviewComponent, DashboardHeaderComponent, ChartComponent, - SummaryComponent + SummaryComponent, + WidgetComponent ], imports: [ BrowserModule, @@ -54,7 +57,8 @@ import { NgSelectModule } from '@ng-select/ng-select'; BrowserAnimationsModule, NgxEchartsModule.forRoot({ echarts: () => import('echarts') - }) + }), + FontAwesomeModule ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/dashboard/chart/chart.component.css b/src/app/dashboard/chart/chart.component.css index 9ebdd3b..811a203 100644 --- a/src/app/dashboard/chart/chart.component.css +++ b/src/app/dashboard/chart/chart.component.css @@ -7,4 +7,21 @@ margin: 0 auto; width: 80%; border-radius: 0px 0px 5px 5px; -} \ No newline at end of file +} + +.grid-container { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-rows: 1fr; + gap: 0px 0px; + grid-template-areas: + "a b c d"; +} + +.a { grid-area: a; } + +.b { grid-area: b; } + +.c { grid-area: c; } + +.d { grid-area: d; } diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html index 4db0798..0df0ac0 100644 --- a/src/app/dashboard/chart/chart.component.html +++ b/src/app/dashboard/chart/chart.component.html @@ -1,3 +1,10 @@
-
-
\ No newline at end of file + +
+
+
+
+
+
+
+ diff --git a/src/app/dashboard/chart/chart.component.ts b/src/app/dashboard/chart/chart.component.ts index 7eb7df7..ce5acf5 100644 --- a/src/app/dashboard/chart/chart.component.ts +++ b/src/app/dashboard/chart/chart.component.ts @@ -1,5 +1,6 @@ import { Component} from '@angular/core' import { EChartsOption } from 'echarts'; +import {faArrowDown, faCircle, faExclamationCircle, faMoneyBill} from '@fortawesome/free-solid-svg-icons'; @Component({ selector: 'app-chart', @@ -7,6 +8,12 @@ import { EChartsOption } from 'echarts'; styleUrls: ['./chart.component.css'] }) export class ChartComponent { + + failedicon = faExclamationCircle; + crypto = faCircle; + downn = faArrowDown; + money = faMoneyBill; + chartOption: EChartsOption = { color: ["#C61A4E"], xAxis: { diff --git a/src/app/dashboard/summary/summary.component.css b/src/app/dashboard/summary/summary.component.css index 621ee61..2dfd9e4 100644 --- a/src/app/dashboard/summary/summary.component.css +++ b/src/app/dashboard/summary/summary.component.css @@ -30,7 +30,7 @@ .grid-container { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; - grid-template-rows: 1fr 1fr 1fr; + grid-template-rows: 1fr; gap: 0px 0px; grid-template-areas: "sum dropdown void1 void" ". . . ." ". . . ."; } diff --git a/src/app/dashboard/widget/widget.component.css b/src/app/dashboard/widget/widget.component.css new file mode 100644 index 0000000..f00960d --- /dev/null +++ b/src/app/dashboard/widget/widget.component.css @@ -0,0 +1,72 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@500&display=swap'); + +.card{ + + + width: 90%; + filter: drop-shadow(0px 0px 25px rgba(198, 26, 78, 0.3)); + line-height: 0.1; + background: #212131; + border-radius: 7px; +} + + + +.title{ + color: white; + font-size: 10pt; + font-family: 'Inter', sans-serif; + padding-top: 20px; + padding-left: 20px; +} + +.content{ + color: white; + font-size: 20pt; + font-family: 'Inter', sans-serif; + font-weight: bold; + line-height: 1.8; + padding-left: 20px; +} + +.subcontent{ + color: white; + font-family: 'Inter', sans-serif; + padding-left: 20px; + color: chartreuse; + line-height: 1.8; + +} + +.bild{ + color: white; + font-size: 2.5rem; + display: block; + width: 100%; + text-align: center; + margin-top: 50px; + +} + +.grid-container { + display: grid; + grid-template-columns: 0.2fr 1fr; + grid-template-rows: 1fr 1fr 1fr; + gap: 0px 0px; + grid-template-areas: + "ico tit" + "ico con" + "ico sub"; +} + +.ico { + grid-area: ico; + background: #1D1D28; + border-radius: 8px; +} + +.tit { grid-area: tit; } + +.con { grid-area: con; } + +.sub { grid-area: sub; } diff --git a/src/app/dashboard/widget/widget.component.html b/src/app/dashboard/widget/widget.component.html new file mode 100644 index 0000000..7a7b21b --- /dev/null +++ b/src/app/dashboard/widget/widget.component.html @@ -0,0 +1,8 @@ +
+
+
+

{{title}}

+
{{content}}
+
{{subcontent}}
+
+
diff --git a/src/app/dashboard/widget/widget.component.spec.ts b/src/app/dashboard/widget/widget.component.spec.ts new file mode 100644 index 0000000..74af5fd --- /dev/null +++ b/src/app/dashboard/widget/widget.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { WidgetComponent } from './widget.component'; + +describe('WidgetComponent', () => { + let component: WidgetComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ WidgetComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(WidgetComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/widget/widget.component.ts b/src/app/dashboard/widget/widget.component.ts new file mode 100644 index 0000000..1d731ae --- /dev/null +++ b/src/app/dashboard/widget/widget.component.ts @@ -0,0 +1,21 @@ +import { Component, Input, OnInit } from '@angular/core'; +import {faQuestion, IconDefinition} from '@fortawesome/free-solid-svg-icons'; + +@Component({ + selector: 'dashboard-widget', + templateUrl: './widget.component.html', + styleUrls: ['./widget.component.css'] +}) +export class WidgetComponent implements OnInit { + + @Input() title = ''; + @Input() content = ''; + @Input() subcontent = ''; + @Input() icon: IconDefinition = faQuestion; + + constructor() { } + + ngOnInit(): void {} + + +} From 658f7e98bb44b8e5bb0840da2ca2bde487bbe93b Mon Sep 17 00:00:00 2001 From: Felix Date: Mon, 5 Apr 2021 14:40:53 +0200 Subject: [PATCH 37/40] add settings component edit chart add routing --- src/app/app.module.ts | 7 ++-- src/app/dashboard.service.ts | 34 +++++++++++++++++-- src/app/dashboard/chart/chart.component.html | 2 +- src/app/dashboard/dashboard.component.html | 4 +-- src/app/dashboard/dashboard.component.ts | 3 +- src/app/dashboard/header/header.component.css | 4 ++- .../dashboard/header/header.component.html | 6 ++-- .../dashboard/history/history.component.css | 0 .../dashboard/history/history.component.html | 1 + .../history/history.component.spec.ts | 25 ++++++++++++++ .../dashboard/history/history.component.ts | 15 ++++++++ .../overview/overview.component.html | 5 ++- .../dashboard/settings/settings.component.css | 0 .../settings/settings.component.html | 1 + .../settings/settings.component.spec.ts | 25 ++++++++++++++ .../dashboard/settings/settings.component.ts | 15 ++++++++ .../dashboard/summary/summary.component.html | 5 +-- src/app/dashboard/widget/widget.component.css | 7 ++-- src/routes.ts | 26 ++++++++------ 19 files changed, 154 insertions(+), 31 deletions(-) create mode 100644 src/app/dashboard/history/history.component.css create mode 100644 src/app/dashboard/history/history.component.html create mode 100644 src/app/dashboard/history/history.component.spec.ts create mode 100644 src/app/dashboard/history/history.component.ts create mode 100644 src/app/dashboard/settings/settings.component.css create mode 100644 src/app/dashboard/settings/settings.component.html create mode 100644 src/app/dashboard/settings/settings.component.spec.ts create mode 100644 src/app/dashboard/settings/settings.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ab2df73..3307e83 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -7,7 +7,6 @@ import { PaymentComponent } from './payment/payment.component'; import { QRCodeModule } from 'angularx-qrcode'; import { PayComponent } from './pay/pay.component'; import { HelloComponent } from './hello/hello.component'; -import { SocketIoModule } from 'ngx-socket-io'; import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from 'src/routes'; import { NotFoundComponent } from './not-found/not-found.component'; @@ -26,6 +25,8 @@ import { NgxEchartsModule } from 'ngx-echarts'; import { NgSelectModule } from '@ng-select/ng-select'; import { WidgetComponent } from './dashboard/widget/widget.component'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; +import {HistoryComponent} from './dashboard/history/history.component'; +import {SettingsComponent} from './dashboard/settings/settings.component'; @NgModule({ @@ -43,7 +44,9 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; DashboardHeaderComponent, ChartComponent, SummaryComponent, - WidgetComponent + WidgetComponent, + HistoryComponent, + SettingsComponent ], imports: [ BrowserModule, diff --git a/src/app/dashboard.service.ts b/src/app/dashboard.service.ts index 3b14b88..3ecc54a 100644 --- a/src/app/dashboard.service.ts +++ b/src/app/dashboard.service.ts @@ -1,28 +1,58 @@ import { Injectable } from '@angular/core'; +import {HttpClient, HttpHeaders} from '@angular/common/http'; +import {BackendService} from './backend.service'; export interface IUser { username: string; token: string; } +export interface ISearchResponse { + status: number; + _id: string; + selector: string; + currency: string; + totalPrice: number; + createdAt: string; + updatedAt: string; + paymentMethod: string; + receiveAddress: string; + transcationHash: string; +} + @Injectable({ providedIn: 'root' }) + export class DashboardService { user: IUser | undefined; - constructor() { } + constructor( + private http: HttpClient, + private backend: BackendService + ) {} login(username: string, password: string): boolean { if (username === 'admin' && password === 'password') { this.user = { username: 'admin', token: 'abc' - } + }; return true; } else { return false; } } + + getInvoices(): void { + // const headers = new HttpHeaders({ token: this.backend.token }); + this.http.get('http://localhost:2009/invoice', { + observe: 'body', + responseType: 'json' + }).toPromise().then(res => { + console.log('Data:', res); + }); + } + } diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html index 0df0ac0..219d56d 100644 --- a/src/app/dashboard/chart/chart.component.html +++ b/src/app/dashboard/chart/chart.component.html @@ -1,5 +1,5 @@ +
-
diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html index 9c8783f..c1ff6e4 100644 --- a/src/app/dashboard/dashboard.component.html +++ b/src/app/dashboard/dashboard.component.html @@ -1,7 +1,5 @@
- - +
- diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts index 38138a3..849e0b6 100644 --- a/src/app/dashboard/dashboard.component.ts +++ b/src/app/dashboard/dashboard.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import {DashboardService} from '../dashboard.service'; @Component({ selector: 'app-dashboard', @@ -7,7 +8,7 @@ import { Component, OnInit } from '@angular/core'; }) export class DashboardComponent implements OnInit { - constructor() { } + constructor(public dashboard: DashboardService) { } ngOnInit(): void { } diff --git a/src/app/dashboard/header/header.component.css b/src/app/dashboard/header/header.component.css index 72a51a6..30cc304 100644 --- a/src/app/dashboard/header/header.component.css +++ b/src/app/dashboard/header/header.component.css @@ -18,11 +18,13 @@ .header:hover { max-height: 55px; transition: .2s ease; + cursor: pointer; } .icon::after { content: ' '; opacity: 0; + } .header:hover .icon::after { @@ -64,4 +66,4 @@ .icon { grid-row: 1; transition: .2s ease; -} \ No newline at end of file +} diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html index 8802aea..ae232e6 100644 --- a/src/app/dashboard/header/header.component.html +++ b/src/app/dashboard/header/header.component.html @@ -1,13 +1,13 @@
-
+
-
+
@@ -15,4 +15,4 @@
-
\ No newline at end of file +
diff --git a/src/app/dashboard/history/history.component.css b/src/app/dashboard/history/history.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/history/history.component.html b/src/app/dashboard/history/history.component.html new file mode 100644 index 0000000..e91e10e --- /dev/null +++ b/src/app/dashboard/history/history.component.html @@ -0,0 +1 @@ +

history works!

diff --git a/src/app/dashboard/history/history.component.spec.ts b/src/app/dashboard/history/history.component.spec.ts new file mode 100644 index 0000000..be6de9e --- /dev/null +++ b/src/app/dashboard/history/history.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HistoryComponent } from './history.component'; + +describe('HistoryComponent', () => { + let component: HistoryComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ HistoryComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HistoryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/history/history.component.ts b/src/app/dashboard/history/history.component.ts new file mode 100644 index 0000000..0beab7a --- /dev/null +++ b/src/app/dashboard/history/history.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-history', + templateUrl: './history.component.html', + styleUrls: ['./history.component.css'] +}) +export class HistoryComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/dashboard/overview/overview.component.html b/src/app/dashboard/overview/overview.component.html index 57c67df..6d13261 100644 --- a/src/app/dashboard/overview/overview.component.html +++ b/src/app/dashboard/overview/overview.component.html @@ -1 +1,4 @@ -

overview works!

+
+
+
+ diff --git a/src/app/dashboard/settings/settings.component.css b/src/app/dashboard/settings/settings.component.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/settings/settings.component.html b/src/app/dashboard/settings/settings.component.html new file mode 100644 index 0000000..4ab2a41 --- /dev/null +++ b/src/app/dashboard/settings/settings.component.html @@ -0,0 +1 @@ +

settings works!

diff --git a/src/app/dashboard/settings/settings.component.spec.ts b/src/app/dashboard/settings/settings.component.spec.ts new file mode 100644 index 0000000..a3a508b --- /dev/null +++ b/src/app/dashboard/settings/settings.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SettingsComponent } from './settings.component'; + +describe('SettingsComponent', () => { + let component: SettingsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SettingsComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SettingsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/settings/settings.component.ts b/src/app/dashboard/settings/settings.component.ts new file mode 100644 index 0000000..19862fb --- /dev/null +++ b/src/app/dashboard/settings/settings.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-settings', + templateUrl: './settings.component.html', + styleUrls: ['./settings.component.css'] +}) +export class SettingsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/dashboard/summary/summary.component.html b/src/app/dashboard/summary/summary.component.html index e068754..5c1f90b 100644 --- a/src/app/dashboard/summary/summary.component.html +++ b/src/app/dashboard/summary/summary.component.html @@ -1,6 +1,4 @@
- -
Summary @@ -12,5 +10,4 @@
- -
\ No newline at end of file +
diff --git a/src/app/dashboard/widget/widget.component.css b/src/app/dashboard/widget/widget.component.css index f00960d..a577f2c 100644 --- a/src/app/dashboard/widget/widget.component.css +++ b/src/app/dashboard/widget/widget.component.css @@ -25,7 +25,7 @@ font-size: 20pt; font-family: 'Inter', sans-serif; font-weight: bold; - line-height: 1.8; + line-height: 1.5; padding-left: 20px; } @@ -34,7 +34,7 @@ font-family: 'Inter', sans-serif; padding-left: 20px; color: chartreuse; - line-height: 1.8; + line-height: 1.3; } @@ -46,6 +46,9 @@ text-align: center; margin-top: 50px; + padding-right: 20px; + + } .grid-container { diff --git a/src/routes.ts b/src/routes.ts index 5dde117..2691ade 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -1,11 +1,12 @@ -import { NgModule } from "@angular/core"; -import { RouterModule, Routes } from "@angular/router"; -import { DashboardComponent } from "./app/dashboard/dashboard.component"; -import { LoginComponent } from "./app/dashboard/login/login.component"; -import { OverviewComponent } from "./app/dashboard/overview/overview.component"; -import { HelloComponent } from "./app/hello/hello.component"; -import { NotFoundComponent } from "./app/not-found/not-found.component"; -import { PayComponent } from "./app/pay/pay.component"; +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { LoginComponent } from './app/dashboard/login/login.component'; +import { OverviewComponent } from './app/dashboard/overview/overview.component'; +import { HelloComponent } from './app/hello/hello.component'; +import { NotFoundComponent } from './app/not-found/not-found.component'; +import { PayComponent } from './app/pay/pay.component'; +import {SettingsComponent} from './app/dashboard/settings/settings.component'; +import {DashboardComponent} from './app/dashboard/dashboard.component'; const routes: Routes = [ { path: 'pay/:id', component: PayComponent, data: { title: 'Payment' } }, @@ -14,15 +15,18 @@ const routes: Routes = [ path: 'login', component: LoginComponent }, { - path: 'overview', component: OverviewComponent + path: 'overview', component: OverviewComponent + }, + { + path: 'settings', component: SettingsComponent } ]}, { path: '', component: HelloComponent }, { path: '**', component: NotFoundComponent } -] +]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) - export class AppRoutingModule {} \ No newline at end of file + export class AppRoutingModule {} From 83da5954f1aa82499a956f0d059ebd62818be9ee Mon Sep 17 00:00:00 2001 From: Felix <39774898+Blemd@users.noreply.github.com> Date: Sun, 25 Apr 2021 18:12:37 +0200 Subject: [PATCH 38/40] add HTTP Client and interceptor.ts --- src/app/app.module.ts | 18 ++++++++++++++---- src/app/interceptor.ts | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 src/app/interceptor.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 3307e83..492eee7 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -25,8 +25,11 @@ import { NgxEchartsModule } from 'ngx-echarts'; import { NgSelectModule } from '@ng-select/ng-select'; import { WidgetComponent } from './dashboard/widget/widget.component'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; -import {HistoryComponent} from './dashboard/history/history.component'; -import {SettingsComponent} from './dashboard/settings/settings.component'; +import {HistoryComponent } from './dashboard/history/history.component'; +import {SettingsComponent } from './dashboard/settings/settings.component'; +import { HTTP_INTERCEPTORS } from '@angular/common/http'; +import {BackendInterceptor} from './interceptor'; + @NgModule({ @@ -46,7 +49,8 @@ import {SettingsComponent} from './dashboard/settings/settings.component'; SummaryComponent, WidgetComponent, HistoryComponent, - SettingsComponent + SettingsComponent, + ], imports: [ BrowserModule, @@ -63,7 +67,13 @@ import {SettingsComponent} from './dashboard/settings/settings.component'; }), FontAwesomeModule ], - providers: [], + providers: [ + { + provide: HTTP_INTERCEPTORS, + useClass: BackendInterceptor, + multi: true + } + ], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/src/app/interceptor.ts b/src/app/interceptor.ts new file mode 100644 index 0000000..9f64d1b --- /dev/null +++ b/src/app/interceptor.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; +import { + HttpInterceptor, + HttpRequest, + HttpHandler, + HttpEvent +} from '@angular/common/http'; +import {Observable} from 'rxjs'; + + +@Injectable() +export class BackendInterceptor implements HttpInterceptor { + intercept(request: HttpRequest, next: HttpHandler): Observable> { + return next.handle(request); + } +} From 7bd21a8c889f99d48fa32f84b38070f960a3215c Mon Sep 17 00:00:00 2001 From: Felix <39774898+Blemd@users.noreply.github.com> Date: Mon, 26 Apr 2021 13:06:07 +0200 Subject: [PATCH 39/40] add login Backend --- src/app/backend.service.ts | 24 ++++++++++++++++++++++++ src/app/interceptor.ts | 12 +++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/app/backend.service.ts b/src/app/backend.service.ts index b2a815e..42e22e6 100644 --- a/src/app/backend.service.ts +++ b/src/app/backend.service.ts @@ -79,6 +79,9 @@ export class BackendService { redirectTo: '', testnet: false }; + + private token = ''; + invoiceUpdate: BehaviorSubject; events: EventSource | undefined; @@ -339,8 +342,29 @@ export class BackendService { isInvoiceRequested(): boolean { return this.invoice?.status === PaymentStatus.REQUESTED; } + + getToken(): string { + return this.token; + } + + login(username: string, password: string): Promise { + return new Promise((resolve, reject) => { + this.http.post(`${this.SERVER_URL}/user/login`, {username, password}, { + observe: 'body', + responseType: 'json' + }).toPromise().then((res: any) => { + this.token = res.token; + resolve(); + }).catch(err => { + reject(err); + }); + }); + } + } + interface CustomEvent extends Event { data: any; } + diff --git a/src/app/interceptor.ts b/src/app/interceptor.ts index 9f64d1b..5f9ed78 100644 --- a/src/app/interceptor.ts +++ b/src/app/interceptor.ts @@ -6,11 +6,21 @@ import { HttpEvent } from '@angular/common/http'; import {Observable} from 'rxjs'; +import {BackendService} from './backend.service'; @Injectable() export class BackendInterceptor implements HttpInterceptor { + + constructor(private backend: BackendService){} intercept(request: HttpRequest, next: HttpHandler): Observable> { - return next.handle(request); + + if (this.backend.token !== null){ + + const req = request.clone({ + headers: request.headers.set('token', this.backend.token) + }); + return next.handle(req); + } } } From e44c08b3e84cc63f089c3e1098398300ae6522a8 Mon Sep 17 00:00:00 2001 From: Felix <39774898+Blemd@users.noreply.github.com> Date: Mon, 26 Apr 2021 17:21:58 +0200 Subject: [PATCH 40/40] add Dashboard Backend and include Login --- src/app/backend.service.ts | 20 ++++++++-- src/app/dashboard.service.ts | 12 ------ src/app/dashboard/chart/chart.component.html | 6 +-- src/app/dashboard/chart/chart.component.ts | 40 ++++++++++++------- .../dashboard/header/header.component.html | 2 +- src/app/dashboard/header/header.component.ts | 4 +- src/app/dashboard/login/login.component.ts | 27 ++++++------- .../dashboard/overview/overview.component.ts | 17 +++++--- src/app/interceptor.ts | 26 +++++------- src/environments/environment.ts | 2 +- 10 files changed, 86 insertions(+), 70 deletions(-) diff --git a/src/app/backend.service.ts b/src/app/backend.service.ts index 42e22e6..7401218 100644 --- a/src/app/backend.service.ts +++ b/src/app/backend.service.ts @@ -81,6 +81,7 @@ export class BackendService { }; private token = ''; + isLoggedIn = false; invoiceUpdate: BehaviorSubject; events: EventSource | undefined; @@ -347,20 +348,33 @@ export class BackendService { return this.token; } - login(username: string, password: string): Promise { - return new Promise((resolve, reject) => { + login(username: string, password: string): Promise { + return new Promise((resolve, reject) => { this.http.post(`${this.SERVER_URL}/user/login`, {username, password}, { observe: 'body', responseType: 'json' }).toPromise().then((res: any) => { this.token = res.token; - resolve(); + this.isLoggedIn = true; + resolve(true); + }).catch(err => { + resolve(false); + // reject(err); + }); + }); + } + + getSummary(): Promise { + return new Promise((resolve, reject) => { + this.http.get(`${this.SERVER_URL}/data/summary`).toPromise().then((res: any) => { + resolve(res); }).catch(err => { reject(err); }); }); } + } diff --git a/src/app/dashboard.service.ts b/src/app/dashboard.service.ts index 3ecc54a..bc521c4 100644 --- a/src/app/dashboard.service.ts +++ b/src/app/dashboard.service.ts @@ -33,18 +33,6 @@ export class DashboardService { private backend: BackendService ) {} - login(username: string, password: string): boolean { - if (username === 'admin' && password === 'password') { - this.user = { - username: 'admin', - token: 'abc' - }; - return true; - } else { - return false; - } - } - getInvoices(): void { // const headers = new HttpHeaders({ token: this.backend.token }); this.http.get('http://localhost:2009/invoice', { diff --git a/src/app/dashboard/chart/chart.component.html b/src/app/dashboard/chart/chart.component.html index 219d56d..9f96760 100644 --- a/src/app/dashboard/chart/chart.component.html +++ b/src/app/dashboard/chart/chart.component.html @@ -1,9 +1,9 @@
-
-
-
+
+
+
diff --git a/src/app/dashboard/chart/chart.component.ts b/src/app/dashboard/chart/chart.component.ts index ce5acf5..cfbc74a 100644 --- a/src/app/dashboard/chart/chart.component.ts +++ b/src/app/dashboard/chart/chart.component.ts @@ -1,13 +1,20 @@ -import { Component} from '@angular/core' -import { EChartsOption } from 'echarts'; +import {Component, OnInit} from '@angular/core'; +import {EChartsOption} from 'echarts'; import {faArrowDown, faCircle, faExclamationCircle, faMoneyBill} from '@fortawesome/free-solid-svg-icons'; +import {BackendService} from '../../backend.service'; @Component({ selector: 'app-chart', templateUrl: './chart.component.html', styleUrls: ['./chart.component.css'] }) -export class ChartComponent { +export class ChartComponent implements OnInit { + constructor( + private backend: BackendService + ) { + } + + summary: any = {}; failedicon = faExclamationCircle; crypto = faCircle; @@ -15,26 +22,31 @@ export class ChartComponent { money = faMoneyBill; chartOption: EChartsOption = { - color: ["#C61A4E"], + color: ['#C61A4E'], xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] - }, + }, - tooltip: { - trigger: 'item', - showDelay: 0, - transitionDuration: 0.2 - }, + tooltip: { + trigger: 'item', + showDelay: 0, + transitionDuration: 0.2 + }, - yAxis: { + yAxis: { type: 'value' - }, - series: [{ + }, + series: [{ data: [820, 932, 901, 934, 1290, 1330, 1320, 654, 68, 846, 987, 846, 874], type: 'line', smooth: true - }] + }] }; + async ngOnInit(): Promise { + this.summary = await this.backend.getSummary(); + } + + } diff --git a/src/app/dashboard/header/header.component.html b/src/app/dashboard/header/header.component.html index ae232e6..fe2e2a1 100644 --- a/src/app/dashboard/header/header.component.html +++ b/src/app/dashboard/header/header.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/app/dashboard/header/header.component.ts b/src/app/dashboard/header/header.component.ts index 1a76e2e..a734c5e 100644 --- a/src/app/dashboard/header/header.component.ts +++ b/src/app/dashboard/header/header.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { DashboardService } from 'src/app/dashboard.service'; +import {BackendService} from '../../backend.service'; @Component({ selector: 'dashboard-header', @@ -11,7 +12,8 @@ export class DashboardHeaderComponent implements OnInit { constructor( public dashboard: DashboardService, - public router: Router + public router: Router, + public backend: BackendService ) { } ngOnInit(): void { diff --git a/src/app/dashboard/login/login.component.ts b/src/app/dashboard/login/login.component.ts index 6b0dfe1..0877712 100644 --- a/src/app/dashboard/login/login.component.ts +++ b/src/app/dashboard/login/login.component.ts @@ -1,35 +1,34 @@ -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { DashboardService } from 'src/app/dashboard.service'; +import {Component, OnInit} from '@angular/core'; +import {Router} from '@angular/router'; +import {DashboardService} from 'src/app/dashboard.service'; +import {BackendService} from '../../backend.service'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) -export class LoginComponent implements OnInit { +export class LoginComponent { username = ''; password = ''; constructor( public dashboard: DashboardService, - private router: Router - ) { } + private router: Router, + private backend: BackendService + ) { + } + - ngOnInit(): void { + async login(): Promise { - const loginStatus = this.dashboard.login("admin", "password"); + const loginStatus = await this.backend.login(this.username, this.password); if (loginStatus) { this.router.navigate(['dashboard', 'overview']); } else { // TODO: Meldung anzeigen } - } - - - login() { - const loginStatus = this.dashboard.login(this.username, this.password); if (loginStatus) { this.router.navigate(['dashboard', 'overview']); @@ -38,4 +37,4 @@ export class LoginComponent implements OnInit { } } -} \ No newline at end of file +} diff --git a/src/app/dashboard/overview/overview.component.ts b/src/app/dashboard/overview/overview.component.ts index b233b1c..9d74830 100644 --- a/src/app/dashboard/overview/overview.component.ts +++ b/src/app/dashboard/overview/overview.component.ts @@ -1,5 +1,7 @@ -import { Component, OnInit } from '@angular/core'; -import { DashboardService } from 'src/app/dashboard.service'; +import {Component, OnInit} from '@angular/core'; +import {DashboardService} from 'src/app/dashboard.service'; +import {HttpClient} from '@angular/common/http'; +import {BackendService} from '../../backend.service'; @Component({ selector: 'app-overview', @@ -8,12 +10,15 @@ import { DashboardService } from 'src/app/dashboard.service'; }) export class OverviewComponent implements OnInit { - constructor(private dashboard: DashboardService) { } + constructor( + private dashboard: DashboardService, + private backend: BackendService + ) { + } ngOnInit(): void { - if (this.dashboard.user === undefined) { - this.dashboard.login('admin', 'password'); - } + } + } diff --git a/src/app/interceptor.ts b/src/app/interceptor.ts index 5f9ed78..9692401 100644 --- a/src/app/interceptor.ts +++ b/src/app/interceptor.ts @@ -1,10 +1,5 @@ -import { Injectable } from '@angular/core'; -import { - HttpInterceptor, - HttpRequest, - HttpHandler, - HttpEvent -} from '@angular/common/http'; +import {Injectable} from '@angular/core'; +import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http'; import {Observable} from 'rxjs'; import {BackendService} from './backend.service'; @@ -12,15 +7,16 @@ import {BackendService} from './backend.service'; @Injectable() export class BackendInterceptor implements HttpInterceptor { - constructor(private backend: BackendService){} - intercept(request: HttpRequest, next: HttpHandler): Observable> { - - if (this.backend.token !== null){ + constructor(private backend: BackendService) { + } - const req = request.clone({ - headers: request.headers.set('token', this.backend.token) - }); - return next.handle(req); + intercept(request: HttpRequest, next: HttpHandler): Observable> { + if (this.backend.getToken() !== '') { + const req = request.clone({ + headers: request.headers.set('token', this.backend.getToken()) + }); + return next.handle(req); } + return next.handle(request); } } diff --git a/src/environments/environment.ts b/src/environments/environment.ts index ca41250..c742735 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -4,7 +4,7 @@ export const environment = { production: false, - API_URL: 'https://example.com/api/' + API_URL: 'http://localhost:2009' }; /*