Compare commits

..

12 Commits

Author SHA1 Message Date
Chris Chen
70aa8adbba WIP 2025-11-02 09:13:42 -08:00
Chris Chen
cd9021d9c0 WIP 2024-04-08 16:48:41 -07:00
Chris Chen
0ee2e7e545 Update angular.json 2024-04-07 09:59:09 -07:00
Chris Chen
8961490ff8 Update _units.scss 2024-04-07 09:50:56 -07:00
Chris Chen
d1039a409b Upgrade to Angular 17 2024-04-06 17:45:52 -07:00
Chris Chen
cca0de9812 Update libs 2024-04-06 16:55:21 -07:00
Chris Chen
3b37d7d798 Remove pages 2024-04-06 10:04:16 -07:00
Chris Chen
e2f55f0b8b Upgrade to angular 16 2024-04-06 09:47:55 -07:00
Chris Chen
56d2bd17e4 Upgrade to Angular 15 2024-04-06 09:42:44 -07:00
Chris Chen
c68d9ba749 Upgrade to angular 14 2024-04-06 09:35:41 -07:00
Chris Chen
dc49c0a958 Upgrade to angular 13 2024-04-06 09:30:39 -07:00
Chris Chen
853b7069f9 Remove tslint-language-service 2024-04-06 09:16:06 -07:00
373 changed files with 42325 additions and 62998 deletions

1
.gitignore vendored
View File

@ -23,6 +23,7 @@
!.vscode/extensions.json !.vscode/extensions.json
# misc # misc
/.angular/cache
/.sass-cache /.sass-cache
/connect.lock /connect.lock
/coverage /coverage

View File

@ -24,8 +24,8 @@
"src/web.config", "src/web.config",
{ {
"glob": "**/*", "glob": "**/*",
"input": "node_modules/leaflet/dist/images", "input": "node_modules/tinymce",
"output": "/assets/img/markers" "output": "/tinymce/"
} }
], ],
"styles": [ "styles": [
@ -44,10 +44,6 @@
"scripts": [ "scripts": [
"node_modules/pace-js/pace.min.js", "node_modules/pace-js/pace.min.js",
"node_modules/tinymce/tinymce.min.js", "node_modules/tinymce/tinymce.min.js",
"node_modules/tinymce/themes/modern/theme.min.js",
"node_modules/tinymce/plugins/link/plugin.min.js",
"node_modules/tinymce/plugins/paste/plugin.min.js",
"node_modules/tinymce/plugins/table/plugin.min.js",
"node_modules/echarts/dist/echarts.min.js", "node_modules/echarts/dist/echarts.min.js",
"node_modules/echarts/dist/extension/bmap.min.js", "node_modules/echarts/dist/extension/bmap.min.js",
"node_modules/chart.js/dist/Chart.min.js" "node_modules/chart.js/dist/Chart.min.js"
@ -57,7 +53,10 @@
"echarts", "echarts",
"lodash", "lodash",
"zrender/lib/svg/svg", "zrender/lib/svg/svg",
"zrender/lib/vml/vml" "zrender/lib/vml/vml",
"file-saver",
"eva-icons",
"rxjs-compat"
], ],
"vendorChunk": true, "vendorChunk": true,
"extractLicenses": false, "extractLicenses": false,
@ -94,18 +93,18 @@
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular-devkit/build-angular:dev-server",
"options": { "options": {
"browserTarget": "ngx-admin-demo:build" "buildTarget": "ngx-admin-demo:build"
}, },
"configurations": { "configurations": {
"production": { "production": {
"browserTarget": "ngx-admin-demo:build:production" "buildTarget": "ngx-admin-demo:build:production"
} }
} }
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n", "builder": "@angular-devkit/build-angular:extract-i18n",
"options": { "options": {
"browserTarget": "ngx-admin-demo:build" "buildTarget": "ngx-admin-demo:build"
} }
}, },
"test": { "test": {
@ -118,10 +117,6 @@
"scripts": [ "scripts": [
"node_modules/pace-js/pace.min.js", "node_modules/pace-js/pace.min.js",
"node_modules/tinymce/tinymce.min.js", "node_modules/tinymce/tinymce.min.js",
"node_modules/tinymce/themes/modern/theme.min.js",
"node_modules/tinymce/plugins/link/plugin.min.js",
"node_modules/tinymce/plugins/paste/plugin.min.js",
"node_modules/tinymce/plugins/table/plugin.min.js",
"node_modules/echarts/dist/echarts.min.js", "node_modules/echarts/dist/echarts.min.js",
"node_modules/echarts/dist/extension/bmap.min.js", "node_modules/echarts/dist/extension/bmap.min.js",
"node_modules/chart.js/dist/Chart.min.js" "node_modules/chart.js/dist/Chart.min.js"
@ -144,50 +139,15 @@
"src/web.config", "src/web.config",
{ {
"glob": "**/*", "glob": "**/*",
"input": "node_modules/leaflet/dist/images", "input": "node_modules/tinymce",
"output": "/assets/img/markers" "output": "/tinymce/"
} }
] ]
} }
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"typeCheck": true,
"exclude": []
}
}
}
},
"ngx-admin-demo-e2e": {
"root": "",
"sourceRoot": "",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "./protractor.conf.js",
"devServerTarget": "ngx-admin-demo:serve"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"e2e/tsconfig.e2e.json"
],
"exclude": []
}
} }
} }
} }
}, },
"defaultProject": "ngx-admin-demo",
"schematics": { "schematics": {
"@schematics/angular:component": { "@schematics/angular:component": {
"prefix": "ngx", "prefix": "ngx",

88002
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,120 +1,111 @@
{ {
"name": "ngx-admin", "name": "ngx-admin",
"version": "8.0.0", "version": "8.0.0",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/akveo/ngx-admin.git" "url": "git+https://github.com/akveo/ngx-admin.git"
}, },
"bugs": { "bugs": {
"url": "https://github.com/akveo/ngx-admin/issues" "url": "https://github.com/akveo/ngx-admin/issues"
}, },
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"conventional-changelog": "conventional-changelog", "conventional-changelog": "conventional-changelog",
"start": "ng serve", "start": "ng serve --host=127.0.0.1",
"build": "ng build --output-path \\\\ArkNAS\\docker\\nginx-proxy\\data\\ChurchAngular --configuration production", "build": "ng build --output-path \\\\ArkNAS\\docker\\nginx-proxy\\data\\ChurchAngular --configuration production",
"build:prod": "npm run build -- --configuration production --aot", "build:prod": "npm run build -- --configuration production --aot",
"test": "ng test", "test": "ng test",
"test:coverage": "rimraf coverage && npm run test -- --code-coverage", "test:coverage": "rimraf coverage && npm run test -- --code-coverage",
"lint": "ng lint", "lint": "ng lint",
"lint:fix": "ng lint ngx-admin-demo --fix", "lint:fix": "ng lint ngx-admin-demo --fix",
"lint:styles": "stylelint ./src/**/*.scss", "lint:styles": "stylelint ./src/**/*.scss",
"lint:ci": "npm run lint && npm run lint:styles", "lint:ci": "npm run lint && npm run lint:styles",
"pree2e": "webdriver-manager update --standalone false --gecko false", "pree2e": "webdriver-manager update --standalone false --gecko false",
"e2e": "ng e2e", "e2e": "ng e2e",
"docs": "compodoc -p src/tsconfig.app.json -d docs", "docs": "compodoc -p src/tsconfig.app.json -d docs",
"docs:serve": "compodoc -p src/tsconfig.app.json -d docs -s", "docs:serve": "compodoc -p src/tsconfig.app.json -d docs -s",
"prepush": "npm run lint:ci", "prepush": "npm run lint:ci",
"release:changelog": "npm run conventional-changelog -- -p angular -i CHANGELOG.md -s", "release:changelog": "npm run conventional-changelog -- -p angular -i CHANGELOG.md -s"
"postinstall": "ngcc --properties es2015 es5 browser module main --first-only --create-ivy-entry-points --tsconfig \"./src/tsconfig.app.json\"" },
}, "dependencies": {
"dependencies": { "@angular/animations": "^17.3.3",
"@angular/animations": "^12.2.16", "@angular/cdk": "17.3.3",
"@angular/cdk": "12.1.0", "@angular/common": "^17.3.3",
"@angular/common": "^12.2.16", "@angular/compiler": "^17.3.3",
"@angular/compiler": "^12.2.16", "@angular/core": "^17.3.3",
"@angular/core": "^12.2.16", "@angular/forms": "^17.3.3",
"@angular/forms": "^12.2.16", "@angular/platform-browser": "^17.3.3",
"@angular/google-maps": "^12.2.13", "@angular/platform-browser-dynamic": "^17.3.3",
"@angular/platform-browser": "^12.2.16", "@angular/router": "^17.3.3",
"@angular/platform-browser-dynamic": "^12.2.16", "@asymmetrik/ngx-leaflet": "3.0.1",
"@angular/router": "^12.2.16", "@microsoft/signalr": "^6.0.8",
"@asymmetrik/ngx-leaflet": "3.0.1", "@nebular/auth": "13.0.0",
"@microsoft/signalr": "^6.0.8", "@nebular/date-fns": "^13.0.0",
"@nebular/auth": "8.0.0", "@nebular/eva-icons": "13.0.0",
"@nebular/date-fns": "^9.0.3", "@nebular/security": "13.0.0",
"@nebular/eva-icons": "8.0.0", "@nebular/theme": "13.0.0",
"@nebular/security": "8.0.0", "@tinymce/tinymce-angular": "^7.0.0",
"@nebular/theme": "8.0.0", "angular2-chartjs": "0.4.1",
"@swimlane/ngx-charts": "^14.0.0", "angular2-qrcode": "^2.0.3",
"angular2-chartjs": "0.4.1", "bootstrap": "4.3.1",
"angular2-qrcode": "^2.0.3", "chart.js": "2.7.1",
"bootstrap": "4.3.1", "core-js": "2.5.1",
"chart.js": "2.7.1", "echarts": "^4.9.0",
"ckeditor": "4.7.3", "eva-icons": "^1.1.3",
"classlist.js": "1.1.20150312", "file-saver": "^2.0.5",
"core-js": "2.5.1", "intl": "1.2.5",
"echarts": "^4.9.0", "ionicons": "2.0.1",
"eva-icons": "^1.1.3", "leaflet": "1.2.0",
"file-saver": "^2.0.5", "nebular-icons": "1.1.0",
"intl": "1.2.5", "ng-in-viewport": "^13.0.1",
"ionicons": "2.0.1", "ng2-completer": "^9.0.1",
"leaflet": "1.2.0", "ngx-echarts": "^4.2.2",
"nebular-icons": "1.1.0", "ngx-infinite-scroll": "^17.0.0",
"ng-in-viewport": "^13.0.1", "ngx-mask": "^12.0.0",
"ng2-ckeditor": "~1.2.9", "node-sass": "^4.14.1",
"ng2-completer": "^9.0.1", "normalize.css": "6.0.0",
"ng2-smart-table": "^1.6.0", "pace-js": "1.0.2",
"ngx-echarts": "^4.2.2", "roboto-fontface": "0.8.0",
"ngx-infinite-scroll": "^13.0.2", "rxjs": "6.6.2",
"ngx-mask": "^12.0.0", "rxjs-compat": "6.3.0",
"node-sass": "^4.14.1", "socicon": "3.0.5",
"normalize.css": "6.0.0", "style-loader": "^1.3.0",
"pace-js": "1.0.2", "tinymce": "^7.0.0",
"roboto-fontface": "0.8.0", "tslib": "^2.3.1",
"rxjs": "6.6.2", "typeface-exo": "0.0.22",
"rxjs-compat": "6.3.0", "typeit": "^8.7.0",
"socicon": "3.0.5", "zone.js": "~0.14.4"
"style-loader": "^1.3.0", },
"tinymce": "4.5.7", "devDependencies": {
"tslib": "^2.3.1", "@angular-devkit/build-angular": "^17.3.3",
"typeface-exo": "0.0.22", "@angular/cli": "^17.3.3",
"typeit": "^8.7.0", "@angular/compiler-cli": "^17.3.3",
"web-animations-js": "^2.3.2", "@angular/language-service": "17.3.3",
"zone.js": "~0.11.4" "@compodoc/compodoc": "1.0.1",
}, "@fortawesome/fontawesome-free": "^5.2.0",
"devDependencies": { "@schematics/angular": "^14.1.3",
"@angular-devkit/build-angular": "^12.1.4", "@types/d3-color": "1.0.5",
"@angular/cli": "^12.2.17", "@types/jasmine": "~3.3.0",
"@angular/compiler-cli": "^12.2.16", "@types/jasminewd2": "2.0.3",
"@angular/language-service": "12.1.0", "@types/leaflet": "1.2.3",
"@compodoc/compodoc": "1.0.1", "@types/node": "^18.19.30",
"@fortawesome/fontawesome-free": "^5.2.0", "codelyzer": "^6.0.2",
"@schematics/angular": "^14.1.3", "conventional-changelog-cli": "1.3.4",
"@types/d3-color": "1.0.5", "husky": "0.13.3",
"@types/jasmine": "~3.3.0", "jasmine-core": "~5.1.2",
"@types/jasminewd2": "2.0.3", "jasmine-spec-reporter": "~5.0.0",
"@types/leaflet": "1.2.3", "karma": "~6.3.19",
"@types/node": "^12.12.70", "karma-chrome-launcher": "~3.1.1",
"codelyzer": "^6.0.2", "karma-cli": "1.0.1",
"conventional-changelog-cli": "1.3.4", "karma-coverage-istanbul-reporter": "~3.0.2",
"husky": "0.13.3", "karma-jasmine": "~5.1.0",
"jasmine-core": "~3.6.0", "karma-jasmine-html-reporter": "^2.1.0",
"jasmine-spec-reporter": "~5.0.0", "npm-run-all": "4.0.2",
"karma": "~6.3.19", "protractor": "~7.0.0",
"karma-chrome-launcher": "~3.1.1", "rimraf": "2.6.1",
"karma-cli": "1.0.1", "stylelint": "7.13.0",
"karma-coverage-istanbul-reporter": "~3.0.2", "ts-node": "3.2.2",
"karma-jasmine": "~4.0.2", "typescript": "~5.4.4"
"karma-jasmine-html-reporter": "^1.7.0", }
"npm-run-all": "4.0.2",
"protractor": "~7.0.0",
"rimraf": "2.6.1",
"stylelint": "7.13.0",
"ts-node": "3.2.2",
"tslint": "~6.1.0",
"tslint-language-service": "^0.9.9",
"typescript": "~4.2.3||~4.3.0"
}
} }

View File

@ -1,6 +1,6 @@
@import '../../styles/themes'; @import "../../styles/themes";
@import '~@nebular/theme/styles/global/breakpoints'; @import "@nebular/theme/styles/global/breakpoints";
@import '~bootstrap/scss/mixins/breakpoints'; @import "bootstrap/scss/mixins/breakpoints";
@include nb-install-component() { @include nb-install-component() {
width: 100%; width: 100%;

View File

@ -1,6 +1,6 @@
@import '~bootstrap/scss/mixins/breakpoints'; @import "bootstrap/scss/mixins/breakpoints";
@import '~@nebular/theme/styles/global/breakpoints'; @import "@nebular/theme/styles/global/breakpoints";
@import '../../styles/themes'; @import "../../styles/themes";
@include nb-install-component() { @include nb-install-component() {
display: flex; display: flex;
@ -24,7 +24,7 @@
} }
::ng-deep nb-search button { ::ng-deep nb-search button {
padding: 0!important; padding: 0 !important;
} }
.header-container { .header-container {

View File

@ -1,6 +1,6 @@
@import '../../styles/themes'; @import "../../styles/themes";
@import '~bootstrap/scss/mixins/breakpoints'; @import "bootstrap/scss/mixins/breakpoints";
@import '~@nebular/theme/styles/global/breakpoints'; @import "@nebular/theme/styles/global/breakpoints";
@include nb-install-component() { @include nb-install-component() {
.menu-sidebar ::ng-deep .scrollable { .menu-sidebar ::ng-deep .scrollable {

View File

@ -1,6 +1,6 @@
@import '../../styles/themes'; @import "../../styles/themes";
@import '~bootstrap/scss/mixins/breakpoints'; @import "bootstrap/scss/mixins/breakpoints";
@import '~@nebular/theme/styles/global/breakpoints'; @import "@nebular/theme/styles/global/breakpoints";
@include nb-install-component() { @include nb-install-component() {
.menu-sidebar ::ng-deep .scrollable { .menu-sidebar ::ng-deep .scrollable {

View File

@ -1,6 +1,6 @@
@import '../../styles/themes'; @import "../../styles/themes";
@import '~bootstrap/scss/mixins/breakpoints'; @import "bootstrap/scss/mixins/breakpoints";
@import '~@nebular/theme/styles/global/breakpoints'; @import "@nebular/theme/styles/global/breakpoints";
@include nb-install-component() { @include nb-install-component() {
.menu-sidebar ::ng-deep .scrollable { .menu-sidebar ::ng-deep .scrollable {

View File

@ -1,6 +1,6 @@
@import '../../styles/themes'; @import "../../styles/themes";
@import '~bootstrap/scss/mixins/breakpoints'; @import "bootstrap/scss/mixins/breakpoints";
@import '~@nebular/theme/styles/global/breakpoints'; @import "@nebular/theme/styles/global/breakpoints";
@include nb-install-component() { @include nb-install-component() {
.menu-sidebar ::ng-deep .scrollable { .menu-sidebar ::ng-deep .scrollable {

View File

@ -1,26 +1,25 @@
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,600,700&display=swap'); @import url("https://fonts.googleapis.com/css?family=Open+Sans:400,600,700&display=swap");
// themes - our custom or/and out of the box themes // themes - our custom or/and out of the box themes
@import 'themes'; @import "themes";
// framework component themes (styles tied to theme variables) // framework component themes (styles tied to theme variables)
@import '~@nebular/theme/styles/globals'; @import "@nebular/theme/styles/globals";
@import '~@nebular/auth/styles/globals'; @import "@nebular/auth/styles/globals";
@import '~bootstrap/scss/functions'; @import "bootstrap/scss/functions";
@import '~bootstrap/scss/variables'; @import "bootstrap/scss/variables";
@import '~bootstrap/scss/mixins'; @import "bootstrap/scss/mixins";
@import '~bootstrap/scss/grid'; @import "bootstrap/scss/grid";
// loading progress bar theme // loading progress bar theme
@import './pace.theme'; @import "./pace.theme";
@import './layout'; @import "./layout";
@import './overrides'; @import "./overrides";
// install the framework and custom global styles // install the framework and custom global styles
@include nb-install() { @include nb-install() {
// framework global styles // framework global styles
@include nb-theme-global(); @include nb-theme-global();
@include nb-auth-global(); @include nb-auth-global();
@ -30,4 +29,4 @@
@include ngx-pace-theme(); @include ngx-pace-theme();
@include nb-overrides(); @include nb-overrides();
}; } ;

View File

@ -1,88 +1,104 @@
// @nebular theming framework // @nebular theming framework
@import '~@nebular/theme/styles/theming'; @import "@nebular/theme/styles/theming";
// @nebular out of the box themes // @nebular out of the box themes
@import '~@nebular/theme/styles/themes'; @import "@nebular/theme/styles/themes";
$nb-themes: nb-register-theme(( $nb-themes: nb-register-theme(
layout-padding-top: 2.25rem, (
layout-padding-top: 2.25rem,
menu-item-icon-margin: 0 0.5rem 0 0, menu-item-icon-margin: 0 0.5rem 0 0,
card-height-tiny: 13.5rem, card-height-tiny: 13.5rem,
card-height-small: 21.1875rem, card-height-small: 21.1875rem,
card-height-medium: 28.875rem, card-height-medium: 28.875rem,
card-height-large: 36.5625rem, card-height-large: 36.5625rem,
card-height-giant: 44.25rem, card-height-giant: 44.25rem,
card-margin-bottom: 1.875rem, card-margin-bottom: 1.875rem,
card-header-with-select-padding-top: 0.5rem, card-header-with-select-padding-top: 0.5rem,
card-header-with-select-padding-bottom: 0.5rem, card-header-with-select-padding-bottom: 0.5rem,
select-min-width: 6rem, select-min-width: 6rem,
slide-out-background: #f7f9fc, slide-out-background: #f7f9fc,
slide-out-shadow-color: 0 4px 14px 0 #8f9bb3, slide-out-shadow-color: 0 4px 14px 0 #8f9bb3,
slide-out-shadow-color-rtl: 0 4px 14px 0 #8f9bb3, slide-out-shadow-color-rtl: 0 4px 14px 0 #8f9bb3,
), default, default); ),
default,
default
);
$nb-themes: nb-register-theme(( $nb-themes: nb-register-theme(
layout-padding-top: 2.25rem, (
layout-padding-top: 2.25rem,
menu-item-icon-margin: 0 0.5rem 0 0, menu-item-icon-margin: 0 0.5rem 0 0,
card-height-tiny: 13.5rem, card-height-tiny: 13.5rem,
card-height-small: 21.1875rem, card-height-small: 21.1875rem,
card-height-medium: 28.875rem, card-height-medium: 28.875rem,
card-height-large: 36.5625rem, card-height-large: 36.5625rem,
card-height-giant: 44.25rem, card-height-giant: 44.25rem,
card-margin-bottom: 1.875rem, card-margin-bottom: 1.875rem,
card-header-with-select-padding-top: 0.5rem, card-header-with-select-padding-top: 0.5rem,
card-header-with-select-padding-bottom: 0.5rem, card-header-with-select-padding-bottom: 0.5rem,
select-min-width: 6rem, select-min-width: 6rem,
slide-out-background: #252547, slide-out-background: #252547,
slide-out-shadow-color: 2px 0 3px #29157a, slide-out-shadow-color: 2px 0 3px #29157a,
slide-out-shadow-color-rtl: -2px 0 3px #29157a, slide-out-shadow-color-rtl: -2px 0 3px #29157a,
), cosmic, cosmic); ),
cosmic,
cosmic
);
$nb-themes: nb-register-theme(( $nb-themes: nb-register-theme(
layout-padding-top: 2.25rem, (
layout-padding-top: 2.25rem,
menu-item-icon-margin: 0 0.5rem 0 0, menu-item-icon-margin: 0 0.5rem 0 0,
card-height-tiny: 13.5rem, card-height-tiny: 13.5rem,
card-height-small: 21.1875rem, card-height-small: 21.1875rem,
card-height-medium: 28.875rem, card-height-medium: 28.875rem,
card-height-large: 36.5625rem, card-height-large: 36.5625rem,
card-height-giant: 44.25rem, card-height-giant: 44.25rem,
card-margin-bottom: 1.875rem, card-margin-bottom: 1.875rem,
card-header-with-select-padding-top: 0.5rem, card-header-with-select-padding-top: 0.5rem,
card-header-with-select-padding-bottom: 0.5rem, card-header-with-select-padding-bottom: 0.5rem,
select-min-width: 6rem, select-min-width: 6rem,
slide-out-background: linear-gradient(270deg, #edf1f7 0%, #e4e9f2 100%), slide-out-background: linear-gradient(270deg, #edf1f7 0%, #e4e9f2 100%),
slide-out-shadow-color: 0 4px 14px 0 #8f9bb3, slide-out-shadow-color: 0 4px 14px 0 #8f9bb3,
slide-out-shadow-color-rtl: 0 4px 14px 0 #8f9bb3, slide-out-shadow-color-rtl: 0 4px 14px 0 #8f9bb3,
), corporate, corporate); ),
corporate,
corporate
);
$nb-themes: nb-register-theme(( $nb-themes: nb-register-theme(
layout-padding-top: 2.25rem, (
layout-padding-top: 2.25rem,
menu-item-icon-margin: 0 0.5rem 0 0, menu-item-icon-margin: 0 0.5rem 0 0,
card-height-tiny: 13.5rem, card-height-tiny: 13.5rem,
card-height-small: 21.1875rem, card-height-small: 21.1875rem,
card-height-medium: 28.875rem, card-height-medium: 28.875rem,
card-height-large: 36.5625rem, card-height-large: 36.5625rem,
card-height-giant: 44.25rem, card-height-giant: 44.25rem,
card-margin-bottom: 1.875rem, card-margin-bottom: 1.875rem,
card-header-with-select-padding-top: 0.5rem, card-header-with-select-padding-top: 0.5rem,
card-header-with-select-padding-bottom: 0.5rem, card-header-with-select-padding-bottom: 0.5rem,
select-min-width: 6rem, select-min-width: 6rem,
slide-out-background: linear-gradient(270deg, #222b45 0%, #151a30 100%), slide-out-background: linear-gradient(270deg, #222b45 0%, #151a30 100%),
slide-out-shadow-color: 0 4px 14px 0 #8f9bb3, slide-out-shadow-color: 0 4px 14px 0 #8f9bb3,
slide-out-shadow-color-rtl: 0 4px 14px 0 #8f9bb3, slide-out-shadow-color-rtl: 0 4px 14px 0 #8f9bb3,
), dark, dark); ),
dark,
dark
);

View File

@ -12,7 +12,6 @@ import { FancyTableModule } from '../ui/fancy-table/fancy-table.module';
import { FamilyMembersComponent } from './family-members/family-members.component'; import { FamilyMembersComponent } from './family-members/family-members.component';
import { FamilyMemberEditorComponent } from './family-members/family-member-editor/family-member-editor.component'; import { FamilyMemberEditorComponent } from './family-members/family-member-editor/family-member-editor.component';
import { DropDownListModule } from '../ui/drop-down-list/drop-down-list.module'; import { DropDownListModule } from '../ui/drop-down-list/drop-down-list.module';
import { NgxMaskModule } from 'ngx-mask';
import { PastoralDomainsComponent } from './pastoral-domains/pastoral-domains.component'; import { PastoralDomainsComponent } from './pastoral-domains/pastoral-domains.component';
import { PastoralDomainEditorComponent } from './pastoral-domains/pastoral-domain-editor/pastoral-domain-editor.component'; import { PastoralDomainEditorComponent } from './pastoral-domains/pastoral-domain-editor/pastoral-domain-editor.component';
import { AssignMemberCellGroupComponent } from './family-members/assign-member-cell-group/assign-member-cell-group.component'; import { AssignMemberCellGroupComponent } from './family-members/assign-member-cell-group/assign-member-cell-group.component';
@ -61,7 +60,6 @@ import { LineMessagingAccountEditorComponent } from './lines/line-messaging-acco
AlertDlgModule, AlertDlgModule,
FancyTableModule, FancyTableModule,
DropDownListModule, DropDownListModule,
NgxMaskModule,
CurrencyInputModule, CurrencyInputModule,
MaskDirectiveModule, MaskDirectiveModule,
DateInputModule DateInputModule

View File

@ -2,7 +2,6 @@ import { Component, OnInit } from '@angular/core';
import { NbDialogRef } from '@nebular/theme'; import { NbDialogRef } from '@nebular/theme';
import { DropDownOption } from '../../../entity/dropDownOption'; import { DropDownOption } from '../../../entity/dropDownOption';
import { DomainMemberRelationship, PastoralDomain } from '../../../entity/PastoralDomain'; import { DomainMemberRelationship, PastoralDomain } from '../../../entity/PastoralDomain';
import { DialogComponent } from '../../../pages/modal-overlays/dialog/dialog.component';
import { ArrayUtils } from '../../../utilities/array-utils'; import { ArrayUtils } from '../../../utilities/array-utils';
import { first } from "rxjs/operators" import { first } from "rxjs/operators"
import { FamilyMember } from '../../../entity/Member'; import { FamilyMember } from '../../../entity/Member';

View File

@ -17,11 +17,6 @@ export const routes: Routes = [
loadChildren: () => import('./invitation/invitation.module') loadChildren: () => import('./invitation/invitation.module')
.then(m => m.InvitationModule), .then(m => m.InvitationModule),
}, },
{
path: 'pages',
loadChildren: () => import('./pages/pages.module')
.then(m => m.PagesModule),
},
{ {
path: 'auth', path: 'auth',
component: NbAuthComponent, component: NbAuthComponent,

View File

@ -74,7 +74,6 @@ const socialLinks = [
closeOnBackdropClick: false, closeOnBackdropClick: false,
closeOnEsc: false closeOnEsc: false
}), }),
NgxMaskModule.forRoot(maskConfig),
NbDateFnsDateModule.forRoot({ format: 'MM/dd/yyyy' }), NbDateFnsDateModule.forRoot({ format: 'MM/dd/yyyy' }),
CoreModule.forRoot(), CoreModule.forRoot(),
ThemeModule.forRoot(), ThemeModule.forRoot(),

View File

@ -95,7 +95,7 @@ export class PrayerComponent extends MyAppBase {
// message += "\n======= 備註 =======" + "\n" + comment; // message += "\n======= 備註 =======" + "\n" + comment;
// } // }
// message += "\n請使用方舟晚宴系統新增菜單唷!" + "\n" + "https://happiness.tours/CellGroup/dinner?openExternalBrowser=1" // message += "\n請使用方舟晚宴系統新增菜單唷!" + "\n" + "https://golife.love/CellGroup/dinner?openExternalBrowser=1"
// this.lineService.pushLineMessage(message); // this.lineService.pushLineMessage(message);
}); });
} }

View File

@ -8,15 +8,12 @@ import { ContextMenuModule } from '../../ui/context-menu/context-menu.module';
const components = [RightClickMenuDirective,]; const components = [RightClickMenuDirective,];
@NgModule({ @NgModule({
declarations: [...components], declarations: [...components],
entryComponents: [ imports: [
ContextMenuComponent CommonModule,
], NbDialogModule,
imports: [ ContextMenuModule
CommonModule, ],
NbDialogModule, exports: [...components]
ContextMenuModule
],
exports: [...components],
}) })
export class RightClickMenuModule { } export class RightClickMenuModule { }

View File

@ -30,7 +30,7 @@ const teamSize: number[][] = [
const fourthQuestNeed2Failed = 7; const fourthQuestNeed2Failed = 7;
const SIGNAL_R_URL = (id: string = null) => { return `${environment.signalRUrl}/${id}Hub` } const SIGNAL_R_URL = (id: string = null) => { return `${environment.signalRUrl}/${id}Hub` }
//const SIGNAL_R_URL = (id: string = null) => { return `http://localhost:12071/hub` } //const SIGNAL_R_URL = (id: string = null) => { return `http://localhost:12071/hub` }
//const SIGNAL_R_URL = (id: string = null) => { return `http://happiness.tours:8088/${id}hub` } //const SIGNAL_R_URL = (id: string = null) => { return `http://golife.love:8088/${id}hub` }
@Component({ @Component({
selector: 'ngx-avalon', selector: 'ngx-avalon',

View File

@ -26,5 +26,5 @@
<ng-template #WaitingMessage> <ng-template #WaitingMessage>
<h1>等待遊戲開始中...</h1> <h1>等待遊戲開始中...</h1>
<qr-code *ngIf="isHost" [size]="qrCodeWidth" [value]="'http://happiness.tours/games/avalon'"></qr-code> <qr-code *ngIf="isHost" [size]="qrCodeWidth" [value]="'http://golife.love/games/avalon'"></qr-code>
</ng-template> </ng-template>

View File

@ -1,6 +1,5 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { QRCodeModule } from 'angular2-qrcode';
import { GamesRoutingModule } from './games-routing.module'; import { GamesRoutingModule } from './games-routing.module';
import { GamesComponent } from './games.component'; import { GamesComponent } from './games.component';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
@ -33,6 +32,9 @@ import { MobAttackInfoComponent } from './massive-darkness2/mobs/mob-detail-info
import { MobDefInfoComponent } from './massive-darkness2/mobs/mob-detail-info/mob-def-info/mob-def-info.component'; import { MobDefInfoComponent } from './massive-darkness2/mobs/mob-detail-info/mob-def-info/mob-def-info.component';
import { MobCombatInfoComponent } from './massive-darkness2/mobs/mob-detail-info/mob-combat-info/mob-combat-info.component'; import { MobCombatInfoComponent } from './massive-darkness2/mobs/mob-detail-info/mob-combat-info/mob-combat-info.component';
import { MobStandInfoComponent } from './massive-darkness2/mobs/mob-stand-info/mob-stand-info.component'; import { MobStandInfoComponent } from './massive-darkness2/mobs/mob-stand-info/mob-stand-info.component';
import { HtmlEditorModule } from '../ui/html-editor/html-editor.module';
import { EditorModule } from '@tinymce/tinymce-angular';
import { MD2HtmlEditorComponent } from './massive-darkness2/md2-html-editor/md2-html-editor.component';
@NgModule({ @NgModule({
@ -60,7 +62,8 @@ import { MobStandInfoComponent } from './massive-darkness2/mobs/mob-stand-info/m
MobAttackInfoComponent, MobAttackInfoComponent,
MobDefInfoComponent, MobDefInfoComponent,
MobCombatInfoComponent, MobCombatInfoComponent,
MobStandInfoComponent MobStandInfoComponent,
MD2HtmlEditorComponent
], ],
imports: [ imports: [
CommonModule, CommonModule,
@ -90,8 +93,9 @@ import { MobStandInfoComponent } from './massive-darkness2/mobs/mob-stand-info/m
CurrencyInputModule, CurrencyInputModule,
NbDialogModule.forRoot(), NbDialogModule.forRoot(),
AlertDlgModule, AlertDlgModule,
QRCodeModule, DropDownListModule,
DropDownListModule HtmlEditorModule,
EditorModule
] ]
}) })
export class GamesModule { } export class GamesModule { }

View File

@ -8,6 +8,7 @@ export class MD2Clone {
let cloneObj = null; let cloneObj = null;
switch (type) { switch (type) {
case "TreasureItem": case "TreasureItem":
//let copy = structuredClone(obj);
return new TreasureItem(obj['type'], 1); return new TreasureItem(obj['type'], 1);
break; break;
case "MobInfo": case "MobInfo":

View File

@ -83,7 +83,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
} }
public get allowAttack(): boolean { public get allowAttack(): boolean {
return this.hero.uiBossFight || (!!this.md2Service.mobs && this.md2Service.mobs.length > 0) || (!!this.md2Service.roamingMonsters && this.md2Service.roamingMonsters.length > 0); return this.hero.uiBossFight || this.md2Service.mobs?.length > 0 || this.md2Service.roamingMonsters?.length > 0;
} }
ngOnInit(): void { ngOnInit(): void {

View File

@ -10,7 +10,12 @@
</nb-accordion-item-body> </nb-accordion-item-body>
</nb-accordion-item> </nb-accordion-item>
</nb-accordion> </nb-accordion>
</div> --> </div>
<div class="col-12">
<md2-html-editor></md2-html-editor>
</div>
-->
<div class="col-12 col-md-5"> <div class="col-12 col-md-5">
<nb-card> <nb-card>

View File

@ -0,0 +1 @@
<!-- <editor [init]="htmlEditorSetting"></editor> -->

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MD2HtmlEditorComponent } from './md2-html-editor.component';
describe('MD2HtmlEditorComponent', () => {
let component: MD2HtmlEditorComponent;
let fixture: ComponentFixture<MD2HtmlEditorComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MD2HtmlEditorComponent]
})
.compileComponents();
fixture = TestBed.createComponent(MD2HtmlEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,97 @@
import { Component, ElementRef, EventEmitter, Inject, Input, NgZone, Output, PLATFORM_ID, Renderer2 } from '@angular/core';
import { ControlValueAccessor, Validator, AbstractControl, ValidationErrors } from '@angular/forms';
import { MsgBoxService } from '../../../services/msg-box.service';
import { DropDownOption } from '../../../entity/dropDownOption';
import { MD2Icon } from '../massive-darkness2.model';
import { first } from 'rxjs/operators';
import { HtmlEditorSettings } from '../../../ui/html-editor/html-editor.model';
import { EditorComponent } from '@tinymce/tinymce-angular';
import { Editor } from 'tinymce';
@Component({
selector: 'md2-html-editor',
templateUrl: './md2-html-editor.component.html',
styleUrl: './md2-html-editor.component.scss'
})
export class MD2HtmlEditorComponent extends EditorComponent implements ControlValueAccessor {
htmlEditorSetting: HtmlEditorSettings = {};
constructor(
private msgBoxService: MsgBoxService,
elementRef: ElementRef, ngZone: NgZone, @Inject(PLATFORM_ID) platformId: Object) {
super(elementRef, ngZone, platformId);
// this.elementRef is private. Need a duplicate
this._elementRef2 = elementRef;
this.htmlEditorSetting.base_url = '/tinymce';
this.htmlEditorSetting.suffix = '.min';
this.htmlEditorSetting['parentComponent'] = this;
this.htmlEditorSetting.plugins = [
'noneditable', 'lists', 'link', 'image', 'table', 'code'];
this.htmlEditorSetting.toolbar = ['undo redo | blocks | bold italic | alignleft aligncentre alignright alignjustify | indent outdent | bullist numlist | code customInsertButton'];
this.htmlEditorSetting.content_style = '.MD2Icon{font-family: "Massive Darkness 2", sans-serif !important; font-size: 40px; margin-left:5px} body{font-size: 30px; }';
this.htmlEditorSetting.noneditable_noneditable_class = 'MD2Icon';
//this.htmlEditorSetting.o = this.htmlEditorSetup;
this.htmlEditorSetting.setup = (editor) => this.htmlEditorSetup(editor)
}
htmlEditorSetup(editor: Editor) {
if (editor) {
let component = this.htmlEditorSetting['parentComponent'] as MD2HtmlEditorComponent;
editor.ui.registry.addButton('customInsertButton', {
icon: 'code-sample',
text: 'MD2 Icon',
onAction: (_) => component.showInsertMD2Icon(this.editor as any)
});
}
}
showInsertMD2Icon(editor: Editor) {
var iconKeys = Object.keys(MD2Icon);
iconKeys = iconKeys.slice(iconKeys.length / 2, iconKeys.length - 1);
this.ngZone.run(_ => {
this.msgBoxService.showInputbox('Insert MD2 Icon', '', { inputType: 'dropdown', dropDownOptions: iconKeys.map((k, i) => new DropDownOption(i, k)) })
.pipe(first()).subscribe(result => {
editor.insertContent(`<span class="MD2Icon mceNonEditable">${String.fromCharCode(65 + result)}</span>`);
this.writeValue(editor.getContent());
});
});
}
private _elementRef2: ElementRef;
writeValue(value: string | null): void {
super.writeValue(value);
}
registerOnChange(fn: (value: string) => void): void {
super.registerOnChange(fn);
}
registerOnTouched(fn: any): void {
super.registerOnTouched(fn);
}
setDisabledState(isDisabled: boolean): void {
super.setDisabledState(isDisabled);
}
checkDomAttachment(): boolean {
// check if component has been attached to DOM yet
return document.body.contains(this._elementRef2.nativeElement);
}
ngAfterViewInit() {
this.init = this.htmlEditorSetting;
//this.htmlEditorSetup();
super.ngAfterViewInit();
}
private InitializeEditor() {
this.init = new HtmlEditorSettings({});
//super.initialise();
}
}

View File

@ -54,7 +54,6 @@ import { AddNewCostDlgComponent } from './week-task-editor/add-new-cost-dlg/add-
AlertDlgModule, AlertDlgModule,
FancyTableModule, FancyTableModule,
DropDownListModule, DropDownListModule,
NgxMaskModule,
CurrencyInputModule, CurrencyInputModule,
MaskDirectiveModule, MaskDirectiveModule,
DateInputModule, DateInputModule,

View File

@ -1,85 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-chartjs-bar-horizontal',
template: `
<chart type="horizontalBar" [data]="data" [options]="options"></chart>
`,
})
export class ChartjsBarHorizontalComponent implements OnDestroy {
data: any;
options: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const chartjs: any = config.variables.chartjs;
this.data = {
labels: ['January', 'February', 'March', 'April', 'May', 'June'],
datasets: [{
label: 'Dataset 1',
backgroundColor: colors.infoLight,
borderWidth: 1,
data: [this.random(), this.random(), this.random(), this.random(), this.random(), this.random()],
}, {
label: 'Dataset 2',
backgroundColor: colors.successLight,
data: [this.random(), this.random(), this.random(), this.random(), this.random(), this.random()],
},
],
};
this.options = {
responsive: true,
maintainAspectRatio: false,
elements: {
rectangle: {
borderWidth: 2,
},
},
scales: {
xAxes: [
{
gridLines: {
display: true,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
yAxes: [
{
gridLines: {
display: false,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
},
legend: {
position: 'right',
labels: {
fontColor: chartjs.textColor,
},
},
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
private random() {
return Math.round(Math.random() * 100);
}
}

View File

@ -1,73 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService, NbColorHelper } from '@nebular/theme';
@Component({
selector: 'ngx-chartjs-bar',
template: `
<chart type="bar" [data]="data" [options]="options"></chart>
`,
})
export class ChartjsBarComponent implements OnDestroy {
data: any;
options: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const chartjs: any = config.variables.chartjs;
this.data = {
labels: ['2006', '2007', '2008', '2009', '2010', '2011', '2012'],
datasets: [{
data: [65, 59, 80, 81, 56, 55, 40],
label: 'Series A',
backgroundColor: NbColorHelper.hexToRgbA(colors.primaryLight, 0.8),
}, {
data: [28, 48, 40, 19, 86, 27, 90],
label: 'Series B',
backgroundColor: NbColorHelper.hexToRgbA(colors.infoLight, 0.8),
}],
};
this.options = {
maintainAspectRatio: false,
responsive: true,
legend: {
labels: {
fontColor: chartjs.textColor,
},
},
scales: {
xAxes: [
{
gridLines: {
display: false,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
yAxes: [
{
gridLines: {
display: true,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
},
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,81 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService, NbColorHelper } from '@nebular/theme';
@Component({
selector: 'ngx-chartjs-line',
template: `
<chart type="line" [data]="data" [options]="options"></chart>
`,
})
export class ChartjsLineComponent implements OnDestroy {
data: any;
options: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const chartjs: any = config.variables.chartjs;
this.data = {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
data: [65, 59, 80, 81, 56, 55, 40],
label: 'Series A',
backgroundColor: NbColorHelper.hexToRgbA(colors.primary, 0.3),
borderColor: colors.primary,
}, {
data: [28, 48, 40, 19, 86, 27, 90],
label: 'Series B',
backgroundColor: NbColorHelper.hexToRgbA(colors.danger, 0.3),
borderColor: colors.danger,
}, {
data: [18, 48, 77, 9, 100, 27, 40],
label: 'Series C',
backgroundColor: NbColorHelper.hexToRgbA(colors.info, 0.3),
borderColor: colors.info,
},
],
};
this.options = {
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [
{
gridLines: {
display: true,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
yAxes: [
{
gridLines: {
display: true,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
},
legend: {
labels: {
fontColor: chartjs.textColor,
},
},
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,117 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-chartjs-multiple-xaxis',
template: `
<chart type="line" [data]="data" [options]="options"></chart>
`,
})
export class ChartjsMultipleXaxisComponent implements OnDestroy {
data: {};
options: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const chartjs: any = config.variables.chartjs;
this.data = {
labels: ['January', 'February', 'March', 'April', 'May', 'June'],
datasets: [{
label: 'dataset - big points',
data: [this.random(), this.random(), this.random(), this.random(), this.random(), this.random()],
borderColor: colors.primary,
backgroundColor: colors.primary,
fill: false,
borderDash: [5, 5],
pointRadius: 8,
pointHoverRadius: 10,
}, {
label: 'dataset - individual point sizes',
data: [this.random(), this.random(), this.random(), this.random(), this.random(), this.random()],
borderColor: colors.dangerLight,
backgroundColor: colors.dangerLight,
fill: false,
borderDash: [5, 5],
pointRadius: 8,
pointHoverRadius: 10,
}, {
label: 'dataset - large pointHoverRadius',
data: [this.random(), this.random(), this.random(), this.random(), this.random(), this.random()],
borderColor: colors.info,
backgroundColor: colors.info,
fill: false,
pointRadius: 8,
pointHoverRadius: 10,
}, {
label: 'dataset - large pointHitRadius',
data: [this.random(), this.random(), this.random(), this.random(), this.random(), this.random()],
borderColor: colors.success,
backgroundColor: colors.success,
fill: false,
pointRadius: 8,
pointHoverRadius: 10,
}],
};
this.options = {
responsive: true,
maintainAspectRatio: false,
legend: {
position: 'bottom',
labels: {
fontColor: chartjs.textColor,
},
},
hover: {
mode: 'index',
},
scales: {
xAxes: [
{
display: true,
scaleLabel: {
display: true,
labelString: 'Month',
},
gridLines: {
display: true,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
yAxes: [
{
display: true,
scaleLabel: {
display: true,
labelString: 'Value',
},
gridLines: {
display: true,
color: chartjs.axisLineColor,
},
ticks: {
fontColor: chartjs.textColor,
},
},
],
},
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
private random() {
return Math.round(Math.random() * 100);
}
}

View File

@ -1,56 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-chartjs-pie',
template: `
<chart type="pie" [data]="data" [options]="options"></chart>
`,
})
export class ChartjsPieComponent implements OnDestroy {
data: any;
options: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const chartjs: any = config.variables.chartjs;
this.data = {
labels: ['Download Sales', 'In-Store Sales', 'Mail Sales'],
datasets: [{
data: [300, 500, 100],
backgroundColor: [colors.primaryLight, colors.infoLight, colors.successLight],
}],
};
this.options = {
maintainAspectRatio: false,
responsive: true,
scales: {
xAxes: [
{
display: false,
},
],
yAxes: [
{
display: false,
},
],
},
legend: {
labels: {
fontColor: chartjs.textColor,
},
},
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,64 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService, NbColorHelper } from '@nebular/theme';
@Component({
selector: 'ngx-chartjs-radar',
template: `
<chart type="radar" [data]="data" [options]="options"></chart>
`,
})
export class ChartjsRadarComponent implements OnDestroy {
options: any;
data: {};
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const chartjs: any = config.variables.chartjs;
this.data = {
labels: ['Eating', 'Drinking', 'Sleeping', 'Designing', 'Coding', 'Cycling', 'Running'],
datasets: [{
data: [65, 59, 90, 81, 56, 55, 40],
label: 'Series A',
borderColor: colors.danger,
backgroundColor: NbColorHelper.hexToRgbA(colors.dangerLight, 0.5),
}, {
data: [28, 48, 40, 19, 96, 27, 100],
label: 'Series B',
borderColor: colors.warning,
backgroundColor: NbColorHelper.hexToRgbA(colors.warningLight, 0.5),
}],
};
this.options = {
responsive: true,
maintainAspectRatio: false,
scaleFontColor: 'white',
legend: {
labels: {
fontColor: chartjs.textColor,
},
},
scale: {
pointLabels: {
fontSize: 14,
fontColor: chartjs.textColor,
},
gridLines: {
color: chartjs.axisLineColor,
},
angleLines: {
color: chartjs.axisLineColor,
},
},
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,50 +0,0 @@
<div class="row">
<div class="col-lg-6">
<nb-card>
<nb-card-header>Pie</nb-card-header>
<nb-card-body>
<ngx-chartjs-pie></ngx-chartjs-pie>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Bar</nb-card-header>
<nb-card-body>
<ngx-chartjs-bar></ngx-chartjs-bar>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Line</nb-card-header>
<nb-card-body>
<ngx-chartjs-line></ngx-chartjs-line>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Multiple x-axis</nb-card-header>
<nb-card-body>
<ngx-chartjs-multiple-xaxis></ngx-chartjs-multiple-xaxis>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Bar Horizontal</nb-card-header>
<nb-card-body>
<ngx-chartjs-bar-horizontal></ngx-chartjs-bar-horizontal>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Radar</nb-card-header>
<nb-card-body>
<ngx-chartjs-radar></ngx-chartjs-radar>
</nb-card-body>
</nb-card>
</div>
</div>

View File

@ -1,20 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
ngx-chartjs-pie,
ngx-chartjs-bar,
ngx-chartjs-line,
ngx-chartjs-multiple-xaxis,
ngx-chartjs-bar-horizontal,
ngx-chartjs-radar {
display: block;
height: nb-theme(card-height-medium);
width: 100%;
::ng-deep chart {
display: block;
height: 100%;
width: 100%;
}
}
}

View File

@ -1,8 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-chartjs',
styleUrls: ['./chartjs.component.scss'],
templateUrl: './chartjs.component.html',
})
export class ChartjsComponent {}

View File

@ -1,35 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ChartsComponent } from './charts.component';
import { EchartsComponent } from './echarts/echarts.component';
import { D3Component } from './d3/d3.component';
import { ChartjsComponent } from './chartjs/chartjs.component';
const routes: Routes = [{
path: '',
component: ChartsComponent,
children: [{
path: 'echarts',
component: EchartsComponent,
}, {
path: 'd3',
component: D3Component,
}, {
path: 'chartjs',
component: ChartjsComponent,
}],
}];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ChartsRoutingModule { }
export const routedComponents = [
ChartsComponent,
EchartsComponent,
D3Component,
ChartjsComponent,
];

View File

@ -1,10 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-charts',
template: `
<router-outlet></router-outlet>
`,
})
export class ChartsComponent {
}

View File

@ -1,63 +0,0 @@
import { NgModule } from '@angular/core';
import { NgxEchartsModule } from 'ngx-echarts';
import { NgxChartsModule } from '@swimlane/ngx-charts';
import { ChartModule } from 'angular2-chartjs';
import { NbCardModule } from '@nebular/theme';
import { ThemeModule } from '../../@theme/theme.module';
import { ChartsRoutingModule, routedComponents } from './charts-routing.module';
import { ChartjsBarComponent } from './chartjs/chartjs-bar.component';
import { ChartjsLineComponent } from './chartjs/chartjs-line.component';
import { ChartjsPieComponent } from './chartjs/chartjs-pie.component';
import { ChartjsMultipleXaxisComponent } from './chartjs/chartjs-multiple-xaxis.component';
import { ChartjsBarHorizontalComponent } from './chartjs/chartjs-bar-horizontal.component';
import { ChartjsRadarComponent } from './chartjs/chartjs-radar.component';
import { D3BarComponent } from './d3/d3-bar.component';
import { D3LineComponent } from './d3/d3-line.component';
import { D3PieComponent } from './d3/d3-pie.component';
import { D3AreaStackComponent } from './d3/d3-area-stack.component';
import { D3PolarComponent } from './d3/d3-polar.component';
import { D3AdvancedPieComponent } from './d3/d3-advanced-pie.component';
import { EchartsLineComponent } from './echarts/echarts-line.component';
import { EchartsPieComponent } from './echarts/echarts-pie.component';
import { EchartsBarComponent } from './echarts/echarts-bar.component';
import { EchartsMultipleXaxisComponent } from './echarts/echarts-multiple-xaxis.component';
import { EchartsAreaStackComponent } from './echarts/echarts-area-stack.component';
import { EchartsBarAnimationComponent } from './echarts/echarts-bar-animation.component';
import { EchartsRadarComponent } from './echarts/echarts-radar.component';
const components = [
ChartjsBarComponent,
ChartjsLineComponent,
ChartjsPieComponent,
ChartjsMultipleXaxisComponent,
ChartjsBarHorizontalComponent,
ChartjsRadarComponent,
D3BarComponent,
D3LineComponent,
D3PieComponent,
D3AreaStackComponent,
D3PolarComponent,
D3AdvancedPieComponent,
EchartsLineComponent,
EchartsPieComponent,
EchartsBarComponent,
EchartsMultipleXaxisComponent,
EchartsAreaStackComponent,
EchartsBarAnimationComponent,
EchartsRadarComponent,
];
@NgModule({
imports: [
ThemeModule,
ChartsRoutingModule,
NgxEchartsModule,
NgxChartsModule,
ChartModule,
NbCardModule,
],
declarations: [...routedComponents, ...components],
})
export class ChartsModule {}

View File

@ -1,43 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-d3-advanced-pie',
template: `
<ngx-charts-advanced-pie-chart
[scheme]="colorScheme"
[results]="single">
</ngx-charts-advanced-pie-chart>
`,
})
export class D3AdvancedPieComponent implements OnDestroy {
single = [
{
name: 'Germany',
value: 8940000,
},
{
name: 'USA',
value: 5000000,
},
{
name: 'France',
value: 7200000,
},
];
colorScheme: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
this.colorScheme = {
domain: [colors.primaryLight, colors.infoLight, colors.successLight, colors.warningLight, colors.dangerLight],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,73 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-d3-area-stack',
template: `
<ngx-charts-area-chart
[scheme]="colorScheme"
[results]="multi"
[xAxis]="showXAxis"
[yAxis]="showYAxis"
[legend]="showLegend"
[showXAxisLabel]="showXAxisLabel"
[showYAxisLabel]="showYAxisLabel"
[xAxisLabel]="xAxisLabel"
[yAxisLabel]="yAxisLabel"
[autoScale]="autoScale">
</ngx-charts-area-chart>
`,
})
export class D3AreaStackComponent implements OnDestroy {
multi = [{
name: 'Germany',
series: [{
name: '2010',
value: 7300000,
}, {
name: '2011',
value: 8940000,
}],
}, {
name: 'USA',
series: [{
name: '2010',
value: 7870000,
}, {
name: '2011',
value: 8270000,
}],
}, {
name: 'France',
series: [{
name: '2010',
value: 5000002,
}, {
name: '2011',
value: 5800000,
}],
}];
showLegend = true;
autoScale = true;
showXAxis = true;
showYAxis = true;
showXAxisLabel = true;
showYAxisLabel = true;
xAxisLabel = 'Country';
yAxisLabel = 'Population';
colorScheme: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
this.colorScheme = {
domain: [colors.primaryLight, colors.infoLight, colors.successLight, colors.warningLight, colors.dangerLight],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,45 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-d3-bar',
template: `
<ngx-charts-bar-vertical
[scheme]="colorScheme"
[results]="results"
[xAxis]="showXAxis"
[yAxis]="showYAxis"
[legend]="showLegend"
[xAxisLabel]="xAxisLabel"
[yAxisLabel]="yAxisLabel">
</ngx-charts-bar-vertical>
`,
})
export class D3BarComponent implements OnDestroy {
results = [
{ name: 'Germany', value: 8940 },
{ name: 'USA', value: 5000 },
{ name: 'France', value: 7200 },
];
showLegend = true;
showXAxis = true;
showYAxis = true;
xAxisLabel = 'Country';
yAxisLabel = 'Population';
colorScheme: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
this.colorScheme = {
domain: [colors.primaryLight, colors.infoLight, colors.successLight, colors.warningLight, colors.dangerLight],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,84 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-d3-line',
template: `
<ngx-charts-line-chart
[scheme]="colorScheme"
[results]="multi"
[xAxis]="showXAxis"
[yAxis]="showYAxis"
[legend]="showLegend"
[showXAxisLabel]="showXAxisLabel"
[showYAxisLabel]="showYAxisLabel"
[xAxisLabel]="xAxisLabel"
[yAxisLabel]="yAxisLabel">
</ngx-charts-line-chart>
`,
})
export class D3LineComponent implements OnDestroy {
multi = [
{
name: 'Germany',
series: [
{
name: '2010',
value: 7300,
},
{
name: '2011',
value: 8940,
},
],
},
{
name: 'USA',
series: [
{
name: '2010',
value: 7870,
},
{
name: '2011',
value: 8270,
},
],
},
{
name: 'France',
series: [
{
name: '2010',
value: 5002,
},
{
name: '2011',
value: 5800,
},
],
},
];
showLegend = true;
showXAxis = true;
showYAxis = true;
showXAxisLabel = true;
xAxisLabel = 'Country';
showYAxisLabel = true;
yAxisLabel = 'Population';
colorScheme: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
this.colorScheme = {
domain: [colors.primaryLight, colors.infoLight, colors.successLight, colors.warningLight, colors.dangerLight],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,38 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-d3-pie',
template: `
<ngx-charts-pie-chart
[scheme]="colorScheme"
[results]="results"
[legend]="showLegend"
[labels]="showLabels">
</ngx-charts-pie-chart>
`,
})
export class D3PieComponent implements OnDestroy {
results = [
{ name: 'Germany', value: 8940 },
{ name: 'USA', value: 5000 },
{ name: 'France', value: 7200 },
];
showLegend = true;
showLabels = true;
colorScheme: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
this.colorScheme = {
domain: [colors.primaryLight, colors.infoLight, colors.successLight, colors.warningLight, colors.dangerLight],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,98 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-d3-polar',
template: `
<ngx-charts-polar-chart
[scheme]="colorScheme"
[results]="multi"
[xAxis]="showXAxis"
[yAxis]="showYAxis"
[legend]="showLegend"
[showXAxisLabel]="showXAxisLabel"
[showYAxisLabel]="showYAxisLabel"
[xAxisLabel]="xAxisLabel"
[yAxisLabel]="yAxisLabel"
[autoScale]="autoScale">
</ngx-charts-polar-chart>
`,
})
export class D3PolarComponent implements OnDestroy {
multi = [
{
name: 'Germany',
series: [
{
name: '1990',
value: 31476,
},
{
name: '2000',
value: 36953,
},
{
name: '2010',
value: 40632,
},
],
},
{
name: 'USA',
series: [
{
name: '1990',
value: 37060,
},
{
name: '2000',
value: 45986,
},
{
name: '2010',
value: 49737,
},
],
},
{
name: 'France',
series: [
{
name: '1990',
value: 29476,
},
{
name: '2000',
value: 34774,
},
{
name: '2010',
value: 36240,
},
],
},
];
showLegend = true;
autoScale = true;
showXAxis = true;
showYAxis = true;
showXAxisLabel = true;
showYAxisLabel = true;
xAxisLabel = 'Country';
yAxisLabel = 'Population';
colorScheme: any;
themeSubscription: any;
constructor(private theme: NbThemeService) {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
this.colorScheme = {
domain: [colors.primaryLight, colors.infoLight, colors.successLight, colors.warningLight, colors.dangerLight],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,42 +0,0 @@
<div class="row">
<div class="col-lg-6">
<nb-card>
<nb-card-header>Pie</nb-card-header>
<nb-card-body>
<ngx-d3-pie></ngx-d3-pie>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Bar</nb-card-header>
<nb-card-body>
<ngx-d3-bar></ngx-d3-bar>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Line</nb-card-header>
<nb-card-body>
<ngx-d3-line></ngx-d3-line>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Advanced Pie</nb-card-header>
<nb-card-body>
<ngx-d3-advanced-pie></ngx-d3-advanced-pie>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Area Chart</nb-card-header>
<nb-card-body>
<ngx-d3-area-stack></ngx-d3-area-stack>
</nb-card-body>
</nb-card>
</div>
</div>

View File

@ -1,46 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
ngx-d3-bar,
ngx-d3-pie,
ngx-d3-advanced-pie,
ngx-d3-area-stack,
ngx-d3-line,
ngx-d3-polar {
display: block;
width: 100%;
height: nb-theme(card-height-medium);
::ng-deep {
.pie-label {
fill: nb-theme(text-basic-color);
}
text {
fill: nb-theme(text-hint-color);
}
.chart-legend {
.legend-labels {
background: nb-theme(background-basic-color-2);
}
.legend-label {
color: nb-theme(text-hint-color);
.active .legend-label-text {
color: nb-theme(text-basic-color);
}
}
}
.total-value,
.item-value,
.item-percent {
line-height: 1.25;
}
.legend-items {
overflow-y: hidden;
}
}
}
}

View File

@ -1,8 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-d3',
styleUrls: ['./d3.component.scss'],
templateUrl: './d3.component.html',
})
export class D3Component {}

View File

@ -1,140 +0,0 @@
import { AfterViewInit, Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-echarts-area-stack',
template: `
<div echarts [options]="options" class="echart"></div>
`,
})
export class EchartsAreaStackComponent implements AfterViewInit, OnDestroy {
options: any = {};
themeSubscription: any;
constructor(private theme: NbThemeService) {
}
ngAfterViewInit() {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const echarts: any = config.variables.echarts;
this.options = {
backgroundColor: echarts.bg,
color: [colors.warningLight, colors.infoLight, colors.dangerLight, colors.successLight, colors.primaryLight],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: echarts.tooltipBackgroundColor,
},
},
},
legend: {
data: ['Mail marketing', 'Affiliate advertising', 'Video ad', 'Direct interview', 'Search engine'],
textStyle: {
color: echarts.textColor,
},
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
axisTick: {
alignWithLabel: true,
},
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
yAxis: [
{
type: 'value',
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
splitLine: {
lineStyle: {
color: echarts.splitLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
series: [
{
name: 'Mail marketing',
type: 'line',
stack: 'Total amount',
areaStyle: { normal: { opacity: echarts.areaOpacity } },
data: [120, 132, 101, 134, 90, 230, 210],
},
{
name: 'Affiliate advertising',
type: 'line',
stack: 'Total amount',
areaStyle: { normal: { opacity: echarts.areaOpacity } },
data: [220, 182, 191, 234, 290, 330, 310],
},
{
name: 'Video ad',
type: 'line',
stack: 'Total amount',
areaStyle: { normal: { opacity: echarts.areaOpacity } },
data: [150, 232, 201, 154, 190, 330, 410],
},
{
name: 'Direct interview',
type: 'line',
stack: 'Total amount',
areaStyle: { normal: { opacity: echarts.areaOpacity } },
data: [320, 332, 301, 334, 390, 330, 320],
},
{
name: 'Search engine',
type: 'line',
stack: 'Total amount',
label: {
normal: {
show: true,
position: 'top',
textStyle: {
color: echarts.textColor,
},
},
},
areaStyle: { normal: { opacity: echarts.areaOpacity } },
data: [820, 932, 901, 934, 1290, 1330, 1320],
},
],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,103 +0,0 @@
import { AfterViewInit, Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-echarts-bar-animation',
template: `
<div echarts [options]="options" class="echart"></div>
`,
})
export class EchartsBarAnimationComponent implements AfterViewInit, OnDestroy {
options: any = {};
themeSubscription: any;
constructor(private theme: NbThemeService) {
}
ngAfterViewInit() {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const xAxisData = [];
const data1 = [];
const data2 = [];
const colors: any = config.variables;
const echarts: any = config.variables.echarts;
this.options = {
backgroundColor: echarts.bg,
color: [colors.primaryLight, colors.infoLight],
legend: {
data: ['bar', 'bar2'],
align: 'left',
textStyle: {
color: echarts.textColor,
},
},
xAxis: [
{
data: xAxisData,
silent: false,
axisTick: {
alignWithLabel: true,
},
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
yAxis: [
{
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
splitLine: {
lineStyle: {
color: echarts.splitLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
series: [
{
name: 'bar',
type: 'bar',
data: data1,
animationDelay: idx => idx * 10,
},
{
name: 'bar2',
type: 'bar',
data: data2,
animationDelay: idx => idx * 10 + 100,
},
],
animationEasing: 'elasticOut',
animationDelayUpdate: idx => idx * 5,
};
for (let i = 0; i < 100; i++) {
xAxisData.push('Category ' + i);
data1.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5);
data2.push((Math.cos(i / 5) * (i / 5 - 10) + i / 6) * 5);
}
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,92 +0,0 @@
import { AfterViewInit, Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-echarts-bar',
template: `
<div echarts [options]="options" class="echart"></div>
`,
})
export class EchartsBarComponent implements AfterViewInit, OnDestroy {
options: any = {};
themeSubscription: any;
constructor(private theme: NbThemeService) {
}
ngAfterViewInit() {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const echarts: any = config.variables.echarts;
this.options = {
backgroundColor: echarts.bg,
color: [colors.primaryLight],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisTick: {
alignWithLabel: true,
},
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
yAxis: [
{
type: 'value',
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
splitLine: {
lineStyle: {
color: echarts.splitLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
series: [
{
name: 'Score',
type: 'bar',
barWidth: '60%',
data: [10, 52, 200, 334, 390, 330, 220],
},
],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,106 +0,0 @@
import { AfterViewInit, Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-echarts-line',
template: `
<div echarts [options]="options" class="echart"></div>
`,
})
export class EchartsLineComponent implements AfterViewInit, OnDestroy {
options: any = {};
themeSubscription: any;
constructor(private theme: NbThemeService) {
}
ngAfterViewInit() {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const echarts: any = config.variables.echarts;
this.options = {
backgroundColor: echarts.bg,
color: [colors.danger, colors.primary, colors.info],
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c}',
},
legend: {
left: 'left',
data: ['Line 1', 'Line 2', 'Line 3'],
textStyle: {
color: echarts.textColor,
},
},
xAxis: [
{
type: 'category',
data: ['1', '2', '3', '4', '5', '6', '7', '8', '9'],
axisTick: {
alignWithLabel: true,
},
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
yAxis: [
{
type: 'log',
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
splitLine: {
lineStyle: {
color: echarts.splitLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
series: [
{
name: 'Line 1',
type: 'line',
data: [1, 3, 9, 27, 81, 247, 741, 2223, 6669],
},
{
name: 'Line 2',
type: 'line',
data: [1, 2, 4, 8, 16, 32, 64, 128, 256],
},
{
name: 'Line 3',
type: 'line',
data: [1 / 2, 1 / 4, 1 / 8, 1 / 16, 1 / 32, 1 / 64, 1 / 128, 1 / 256, 1 / 512],
},
],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,166 +0,0 @@
import { Component, AfterViewInit, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-echarts-multiple-xaxis',
template: `
<div echarts [options]="options" class="echart"></div>
`,
})
export class EchartsMultipleXaxisComponent implements AfterViewInit, OnDestroy {
options: any = {};
themeSubscription: any;
constructor(private theme: NbThemeService) {
}
ngAfterViewInit() {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const echarts: any = config.variables.echarts;
this.options = {
backgroundColor: echarts.bg,
color: [colors.success, colors.info],
tooltip: {
trigger: 'none',
axisPointer: {
type: 'cross',
},
},
legend: {
data: ['2015 Precipitation', '2016 Precipitation'],
textStyle: {
color: echarts.textColor,
},
},
grid: {
top: 70,
bottom: 50,
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true,
},
axisLine: {
onZero: false,
lineStyle: {
color: colors.info,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
axisPointer: {
label: {
formatter: params => {
return (
'Precipitation ' + params.value + (params.seriesData.length ? '' + params.seriesData[0].data : '')
);
},
},
},
data: [
'2016-1',
'2016-2',
'2016-3',
'2016-4',
'2016-5',
'2016-6',
'2016-7',
'2016-8',
'2016-9',
'2016-10',
'2016-11',
'2016-12',
],
},
{
type: 'category',
axisTick: {
alignWithLabel: true,
},
axisLine: {
onZero: false,
lineStyle: {
color: colors.success,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
axisPointer: {
label: {
formatter: params => {
return (
'Precipitation ' + params.value + (params.seriesData.length ? '' + params.seriesData[0].data : '')
);
},
},
},
data: [
'2015-1',
'2015-2',
'2015-3',
'2015-4',
'2015-5',
'2015-6',
'2015-7',
'2015-8',
'2015-9',
'2015-10',
'2015-11',
'2015-12',
],
},
],
yAxis: [
{
type: 'value',
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
splitLine: {
lineStyle: {
color: echarts.splitLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
series: [
{
name: '2015 Precipitation',
type: 'line',
xAxisIndex: 1,
smooth: true,
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
},
{
name: '2016 Precipitation',
type: 'line',
smooth: true,
data: [3.9, 5.9, 11.1, 18.7, 48.3, 69.2, 231.6, 46.6, 55.4, 18.4, 10.3, 0.7],
},
],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,81 +0,0 @@
import { AfterViewInit, Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-echarts-pie',
template: `
<div echarts [options]="options" class="echart"></div>
`,
})
export class EchartsPieComponent implements AfterViewInit, OnDestroy {
options: any = {};
themeSubscription: any;
constructor(private theme: NbThemeService) {
}
ngAfterViewInit() {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors = config.variables;
const echarts: any = config.variables.echarts;
this.options = {
backgroundColor: echarts.bg,
color: [colors.warningLight, colors.infoLight, colors.dangerLight, colors.successLight, colors.primaryLight],
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)',
},
legend: {
orient: 'vertical',
left: 'left',
data: ['USA', 'Germany', 'France', 'Canada', 'Russia'],
textStyle: {
color: echarts.textColor,
},
},
series: [
{
name: 'Countries',
type: 'pie',
radius: '80%',
center: ['50%', '50%'],
data: [
{ value: 335, name: 'Germany' },
{ value: 310, name: 'France' },
{ value: 234, name: 'Canada' },
{ value: 135, name: 'Russia' },
{ value: 1548, name: 'USA' },
],
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: echarts.itemHoverShadowColor,
},
},
label: {
normal: {
textStyle: {
color: echarts.textColor,
},
},
},
labelLine: {
normal: {
lineStyle: {
color: echarts.axisLineColor,
},
},
},
},
],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,76 +0,0 @@
import { AfterViewInit, Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-echarts-radar',
template: `
<div echarts [options]="options" class="echart"></div>
`,
})
export class EchartsRadarComponent implements AfterViewInit, OnDestroy {
options: any = {};
themeSubscription: any;
constructor(private theme: NbThemeService) {
}
ngAfterViewInit() {
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const echarts: any = config.variables.echarts;
this.options = {
backgroundColor: echarts.bg,
color: [colors.danger, colors.warning],
tooltip: {},
legend: {
data: ['Allocated Budget', 'Actual Spending'],
textStyle: {
color: echarts.textColor,
},
},
radar: {
name: {
textStyle: {
color: echarts.textColor,
},
},
indicator: [
{ name: 'Sales', max: 6500 },
{ name: 'Administration', max: 16000 },
{ name: 'Information Techology', max: 30000 },
{ name: 'Customer Support', max: 38000 },
{ name: 'Development', max: 52000 },
{ name: 'Marketing', max: 25000 },
],
splitArea: {
areaStyle: {
color: 'transparent',
},
},
},
series: [
{
name: 'Budget vs Spending',
type: 'radar',
data: [
{
value: [4300, 10000, 28000, 35000, 50000, 19000],
name: 'Allocated Budget',
},
{
value: [5000, 14000, 28000, 31000, 42000, 21000],
name: 'Actual Spending',
},
],
},
],
};
});
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,58 +0,0 @@
<div class="row">
<div class="col-lg-6">
<nb-card>
<nb-card-header>Pie</nb-card-header>
<nb-card-body>
<ngx-echarts-pie></ngx-echarts-pie>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Bar</nb-card-header>
<nb-card-body>
<ngx-echarts-bar></ngx-echarts-bar>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Line</nb-card-header>
<nb-card-body>
<ngx-echarts-line></ngx-echarts-line>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Multiple x-axis</nb-card-header>
<nb-card-body>
<ngx-echarts-multiple-xaxis></ngx-echarts-multiple-xaxis>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Area Stack</nb-card-header>
<nb-card-body>
<ngx-echarts-area-stack></ngx-echarts-area-stack>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Bar Animation</nb-card-header>
<nb-card-body>
<ngx-echarts-bar-animation></ngx-echarts-bar-animation>
</nb-card-body>
</nb-card>
</div>
<div class="col-lg-6">
<nb-card>
<nb-card-header>Radar</nb-card-header>
<nb-card-body>
<ngx-echarts-radar></ngx-echarts-radar>
</nb-card-body>
</nb-card>
</div>
</div>

View File

@ -1,20 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
ngx-echarts-pie,
ngx-echarts-bar,
ngx-echarts-line,
ngx-echarts-multiple-xaxis,
ngx-echarts-area-stack,
ngx-echarts-bar-animation,
ngx-echarts-radar {
display: block;
height: nb-theme(card-height-medium);
width: 100%;
}
::ng-deep .echart {
height: 100%;
width: 100%;
}
}

View File

@ -1,8 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-echarts',
styleUrls: ['./echarts.component.scss'],
templateUrl: './echarts.component.html',
})
export class EchartsComponent {}

View File

@ -1,23 +0,0 @@
<nb-card size="giant">
<nb-tabset fullWidth>
<nb-tab tabTitle="Contacts">
<nb-list>
<nb-list-item class="contact" *ngFor="let c of contacts">
<nb-user [picture]="c.user.picture" [name]="c.user.name" [title]="c.type" size="large"></nb-user>
<nb-icon icon="phone-outline" pack="eva"></nb-icon>
</nb-list-item>
</nb-list>
</nb-tab>
<nb-tab tabTitle="Recent">
<nb-list>
<nb-list-item class="contact" *ngFor="let c of recent">
<nb-user [picture]="c.user.picture" [name]="c.user.name" [title]="c.type" size="large"></nb-user>
<span class="caption">{{ c.time | date: 'shortTime' }}</span>
</nb-list-item>
</nb-list>
</nb-tab>
</nb-tabset>
</nb-card>

View File

@ -1,34 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
nb-card {
overflow: hidden;
}
nb-tabset {
display: flex;
flex-direction: column;
::ng-deep ul {
// make same size as card header
padding-bottom: 1px;
::ng-deep .tab-link {
padding: 1.25rem 2rem;
}
}
}
nb-tab {
padding: 0;
}
.contact {
display: flex;
align-items: center;
justify-content: space-between;
&:first-child {
border-top: none;
}
}
}

View File

@ -1,34 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { takeWhile } from 'rxjs/operators';
import { forkJoin } from 'rxjs';
import { Contacts, RecentUsers, UserData } from '../../../@core/data/users';
@Component({
selector: 'ngx-contacts',
styleUrls: ['./contacts.component.scss'],
templateUrl: './contacts.component.html',
})
export class ContactsComponent implements OnDestroy {
private alive = true;
contacts: any[];
recent: any[];
constructor(private userService: UserData) {
forkJoin(
this.userService.getContacts(),
this.userService.getRecentUsers(),
)
.pipe(takeWhile(() => this.alive))
.subscribe(([contacts, recent]: [Contacts[], RecentUsers[]]) => {
this.contacts = contacts;
this.recent = recent;
});
}
ngOnDestroy() {
this.alive = false;
}
}

View File

@ -1,42 +0,0 @@
<div class="row">
<div class="col-xxxl-3 col-md-6" *ngFor="let statusCard of statusCards">
<ngx-status-card [title]="statusCard.title" [type]="statusCard.type">
<i [ngClass]="statusCard.iconClass"></i>
</ngx-status-card>
</div>
</div>
<div class="row">
<div class="col-xxxl-3 col-xxl-4 col-lg-5 col-md-6">
<ngx-temperature></ngx-temperature>
</div>
<div class="col-xxxl-9 col-xxl-8 col-lg-7 col-md-6">
<ngx-electricity></ngx-electricity>
</div>
</div>
<div class="row">
<div class="col-xxxl-9 col-xl-12">
<ngx-rooms></ngx-rooms>
</div>
<div class="col-xxxl-3 col-xxl-4 col-lg-7 col-md-6">
<ngx-contacts></ngx-contacts>
</div>
<div class="col-xxxl-3 col-xxl-4 col-lg-5 col-md-6">
<ngx-solar [chartValue]="solarValue"></ngx-solar>
<ngx-kitten></ngx-kitten>
</div>
<div class="col-xxxl-3 col-xxl-4 col-md-5">
<ngx-traffic></ngx-traffic>
<ngx-weather></ngx-weather>
</div>
<div class="col-xxxl-6 col-xxl-12 col-md-7">
<ngx-security-cameras></ngx-security-cameras>
</div>
</div>

View File

@ -1,16 +0,0 @@
@import '../../@theme/styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
.solar-card nb-card-header {
border: none;
padding-bottom: 0;
}
@include media-breakpoint-down(sm) {
ngx-traffic {
display: none;
}
}
}

View File

@ -1,99 +0,0 @@
import {Component, OnDestroy} from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators' ;
import { SolarData } from '../../@core/data/solar';
interface CardSettings {
title: string;
iconClass: string;
type: string;
}
@Component({
selector: 'ngx-dashboard',
styleUrls: ['./dashboard.component.scss'],
templateUrl: './dashboard.component.html',
})
export class DashboardComponent implements OnDestroy {
private alive = true;
solarValue: number;
lightCard: CardSettings = {
title: 'Light',
iconClass: 'nb-lightbulb',
type: 'primary',
};
rollerShadesCard: CardSettings = {
title: 'Roller Shades',
iconClass: 'nb-roller-shades',
type: 'success',
};
wirelessAudioCard: CardSettings = {
title: 'Wireless Audio',
iconClass: 'nb-audio',
type: 'info',
};
coffeeMakerCard: CardSettings = {
title: 'Coffee Maker',
iconClass: 'nb-coffee-maker',
type: 'warning',
};
statusCards: string;
commonStatusCardsSet: CardSettings[] = [
this.lightCard,
this.rollerShadesCard,
this.wirelessAudioCard,
this.coffeeMakerCard,
];
statusCardsByThemes: {
default: CardSettings[];
cosmic: CardSettings[];
corporate: CardSettings[];
dark: CardSettings[];
} = {
default: this.commonStatusCardsSet,
cosmic: this.commonStatusCardsSet,
corporate: [
{
...this.lightCard,
type: 'warning',
},
{
...this.rollerShadesCard,
type: 'primary',
},
{
...this.wirelessAudioCard,
type: 'danger',
},
{
...this.coffeeMakerCard,
type: 'info',
},
],
dark: this.commonStatusCardsSet,
};
constructor(private themeService: NbThemeService,
private solarService: SolarData) {
this.themeService.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(theme => {
this.statusCards = this.statusCardsByThemes[theme.name];
});
this.solarService.getSolarData()
.pipe(takeWhile(() => this.alive))
.subscribe((data) => {
this.solarValue = data;
});
}
ngOnDestroy() {
this.alive = false;
}
}

View File

@ -1,69 +0,0 @@
import { NgModule } from '@angular/core';
import {
NbActionsModule,
NbButtonModule,
NbCardModule,
NbTabsetModule,
NbUserModule,
NbRadioModule,
NbSelectModule,
NbListModule,
NbIconModule,
} from '@nebular/theme';
import { NgxEchartsModule } from 'ngx-echarts';
import { ThemeModule } from '../../@theme/theme.module';
import { DashboardComponent } from './dashboard.component';
import { StatusCardComponent } from './status-card/status-card.component';
import { ContactsComponent } from './contacts/contacts.component';
import { RoomsComponent } from './rooms/rooms.component';
import { RoomSelectorComponent } from './rooms/room-selector/room-selector.component';
import { TemperatureComponent } from './temperature/temperature.component';
import { TemperatureDraggerComponent } from './temperature/temperature-dragger/temperature-dragger.component';
import { KittenComponent } from './kitten/kitten.component';
import { SecurityCamerasComponent } from './security-cameras/security-cameras.component';
import { ElectricityComponent } from './electricity/electricity.component';
import { ElectricityChartComponent } from './electricity/electricity-chart/electricity-chart.component';
import { WeatherComponent } from './weather/weather.component';
import { SolarComponent } from './solar/solar.component';
import { PlayerComponent } from './rooms/player/player.component';
import { TrafficComponent } from './traffic/traffic.component';
import { TrafficChartComponent } from './traffic/traffic-chart.component';
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
FormsModule,
ThemeModule,
NbCardModule,
NbUserModule,
NbButtonModule,
NbTabsetModule,
NbActionsModule,
NbRadioModule,
NbSelectModule,
NbListModule,
NbIconModule,
NbButtonModule,
NgxEchartsModule,
],
declarations: [
DashboardComponent,
StatusCardComponent,
TemperatureDraggerComponent,
ContactsComponent,
RoomSelectorComponent,
TemperatureComponent,
RoomsComponent,
KittenComponent,
SecurityCamerasComponent,
ElectricityComponent,
ElectricityChartComponent,
WeatherComponent,
PlayerComponent,
SolarComponent,
TrafficComponent,
TrafficChartComponent,
],
})
export class DashboardModule { }

View File

@ -1,14 +0,0 @@
@import '../../../../@theme/styles/themes';
@include nb-install-component() {
display: block;
flex: 1;
position: relative;
.echart {
position: absolute;
width: 100%;
height: 100%;
}
}

View File

@ -1,198 +0,0 @@
import { delay, takeWhile } from 'rxjs/operators';
import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { LayoutService } from '../../../../@core/utils';
import { ElectricityChart } from '../../../../@core/data/electricity';
@Component({
selector: 'ngx-electricity-chart',
styleUrls: ['./electricity-chart.component.scss'],
template: `
<div echarts
[options]="option"
[merge]="option"
class="echart"
(chartInit)="onChartInit($event)">
</div>
`,
})
export class ElectricityChartComponent implements AfterViewInit, OnDestroy {
private alive = true;
@Input() data: ElectricityChart[];
option: any;
echartsIntance: any;
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngAfterViewInit(): void {
this.theme.getJsTheme()
.pipe(
takeWhile(() => this.alive),
delay(1),
)
.subscribe(config => {
const eTheme: any = config.variables.electricity;
this.option = {
grid: {
left: 0,
top: 0,
right: 0,
bottom: 80,
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line',
lineStyle: {
color: eTheme.tooltipLineColor,
width: eTheme.tooltipLineWidth,
},
},
textStyle: {
color: eTheme.tooltipTextColor,
fontSize: 20,
fontWeight: eTheme.tooltipFontWeight,
},
position: 'top',
backgroundColor: eTheme.tooltipBg,
borderColor: eTheme.tooltipBorderColor,
borderWidth: 1,
formatter: '{c0} kWh',
extraCssText: eTheme.tooltipExtraCss,
},
xAxis: {
type: 'category',
boundaryGap: false,
offset: 25,
data: this.data.map(i => i.label),
axisTick: {
show: false,
},
axisLabel: {
color: eTheme.xAxisTextColor,
fontSize: 18,
},
axisLine: {
lineStyle: {
color: eTheme.axisLineColor,
width: '2',
},
},
},
yAxis: {
boundaryGap: [0, '5%'],
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: eTheme.yAxisSplitLine,
width: '1',
},
},
},
series: [
{
type: 'line',
smooth: true,
symbolSize: 20,
itemStyle: {
normal: {
opacity: 0,
},
emphasis: {
color: '#ffffff',
borderColor: eTheme.itemBorderColor,
borderWidth: 2,
opacity: 1,
},
},
lineStyle: {
normal: {
width: eTheme.lineWidth,
type: eTheme.lineStyle,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.lineGradFrom,
}, {
offset: 1,
color: eTheme.lineGradTo,
}]),
shadowColor: eTheme.lineShadow,
shadowBlur: 6,
shadowOffsetY: 12,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.areaGradFrom,
}, {
offset: 1,
color: eTheme.areaGradTo,
}]),
},
},
data: this.data.map(i => i.value),
},
{
type: 'line',
smooth: true,
symbol: 'none',
lineStyle: {
normal: {
width: eTheme.lineWidth,
type: eTheme.lineStyle,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: eTheme.lineGradFrom,
}, {
offset: 1,
color: eTheme.lineGradTo,
}]),
shadowColor: eTheme.shadowLineDarkBg,
shadowBlur: 14,
opacity: 1,
},
},
data: this.data.map(i => i.value),
},
],
};
});
}
onChartInit(echarts) {
this.echartsIntance = echarts;
}
resizeChart() {
if (this.echartsIntance) {
this.echartsIntance.resize();
}
}
ngOnDestroy() {
this.alive = false;
}
}

View File

@ -1,47 +0,0 @@
<nb-card class="cards-container">
<nb-card size="large" class="table-card">
<nb-card-header>
Electricity Consumption
</nb-card-header>
<nb-tabset fullWidth>
<nb-tab *ngFor="let year of listData" [tabTitle]="year.title" [active]="year.active">
<nb-list>
<nb-list-item *ngFor="let month of year.months">
<span class="month">{{ month.month }}</span>
<span>
<nb-icon
[class.down]="month.down"
[class.up]="!month.down"
[icon]="month.down ? 'arrow-down' : 'arrow-up'" pack="eva">
</nb-icon>
{{ month.delta }}
</span>
<span class="results">
{{ month.kWatts }} <span class="caption">kWh</span> / {{ month.cost }} <span class="caption">USD</span>
</span>
</nb-list-item>
</nb-list>
</nb-tab>
</nb-tabset>
</nb-card>
<nb-card size="large" class="chart-card">
<nb-card-header>
<span class="stats">
<span class="caption">Consumed</span>
<span>816 <span class="caption">kWh</span></span>
</span>
<span class="stats">
<span class="caption">Spent</span>
<span>291 <span class="caption">USD</span></span>
</span>
<nb-select [(selected)]="type" class="type-select">
<nb-option *ngFor="let t of types" [value]="t">{{ t }}</nb-option>
</nb-select>
</nb-card-header>
<ngx-electricity-chart [data]="chartData"></ngx-electricity-chart>
</nb-card>
</nb-card>

View File

@ -1,90 +0,0 @@
@import '../../../@theme/styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
.cards-container {
display: flex;
flex-direction: row;
overflow: hidden;
}
.table-card,
.chart-card {
box-shadow: none;
margin-bottom: 0;
border-width: 0;
}
.table-card {
flex: 0 0 auto;
}
.chart-card {
flex: 1 0 auto;
}
.chart-card nb-card-header {
display: flex;
align-items: center;
padding-top: nb-theme(card-header-with-select-padding-top);
padding-bottom: nb-theme(card-header-with-select-padding-bottom);
// prevents double border from chart yAxisSplitLine
margin-bottom: -1px;
}
.type-select {
margin-left: auto;
}
.stats {
margin-right: 1rem;
> .caption {
display: block;
}
}
nb-tabset {
display: flex;
flex-direction: column;
overflow: hidden;
}
nb-tab {
padding: 0;
}
nb-list-item {
display: flex;
align-items: baseline;
&:first-child {
border-top: none;
}
}
.month {
width: 2rem;
}
nb-icon.down {
color: nb-theme(color-danger-default);
}
nb-icon.up {
color: nb-theme(color-success-default);
}
.results {
margin-left: auto;
}
@include media-breakpoint-down(xl) {
.table-card {
display: none;
}
}
}

View File

@ -1,48 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { Electricity, ElectricityChart, ElectricityData } from '../../../@core/data/electricity';
import { takeWhile } from 'rxjs/operators';
import { forkJoin } from 'rxjs';
@Component({
selector: 'ngx-electricity',
styleUrls: ['./electricity.component.scss'],
templateUrl: './electricity.component.html',
})
export class ElectricityComponent implements OnDestroy {
private alive = true;
listData: Electricity[];
chartData: ElectricityChart[];
type = 'week';
types = ['week', 'month', 'year'];
currentTheme: string;
themeSubscription: any;
constructor(private electricityService: ElectricityData,
private themeService: NbThemeService) {
this.themeService.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(theme => {
this.currentTheme = theme.name;
});
forkJoin(
this.electricityService.getListData(),
this.electricityService.getChartData(),
)
.pipe(takeWhile(() => this.alive))
.subscribe(([listData, chartData]: [Electricity[], ElectricityChart[]] ) => {
this.listData = listData;
this.chartData = chartData;
});
}
ngOnDestroy() {
this.alive = false;
}
}

View File

@ -1,25 +0,0 @@
<nb-card size="medium">
<div class="picture" style.background-image="url('assets/images/kitten-{{currentTheme}}.png')"></div>
<div class="details">
<div class="h4">UI Kitten</div>
<div class="description">
UI Kitten is a framework that contains a set of commonly used UI components styled in a similar way. The most awesome thing: you can change themes on the fly by just passing a different set of variables. 100% native. Give our kitten a try!
</div>
</div>
<nb-card-footer>
<a href="https://akveo.github.io/react-native-ui-kitten?utm_campaign=ui_kitten%20-%20home%20-%20ngx_admin%20code%20embed&utm_source=ngx_admin&utm_medium=embedded&utm_content=iot_dashboard_kitten_card" target="_blank">
<nb-icon icon="globe" pack="eva"></nb-icon>
</a>
<a href="https://itunes.apple.com/us/app/kitten-tricks/id1246143230" target="_blank">
<i class="link-icon ion-social-apple"></i>
</a>
<a href="https://play.google.com/store/apps/details?id=com.akveo.kittenTricks" target="_blank">
<i class="link-icon ion-social-android"></i>
</a>
<a href="https://github.com/akveo/react-native-ui-kitten" target="_blank">
<nb-icon icon="github" pack="eva"></nb-icon>
</a>
</nb-card-footer>
</nb-card>

View File

@ -1,39 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
.picture {
background-position: center;
background-size: cover;
position: relative;
border-top-left-radius: nb-theme(card-border-radius);
border-top-right-radius: nb-theme(card-border-radius);
flex: 1;
}
.details {
padding: nb-theme(card-padding);
}
.description {
text-align: justify;
}
nb-card-footer {
display: flex;
justify-content: space-around;
align-items: center;
}
.link-icon {
font-size: 1.75rem;
}
nb-icon {
font-size: 1.55rem;
::ng-deep svg {
vertical-align: top;
}
}
}

View File

@ -1,23 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-kitten',
styleUrls: ['./kitten.component.scss'],
templateUrl: './kitten.component.html',
})
export class KittenComponent implements OnDestroy {
currentTheme: string;
themeSubscription: any;
constructor(private themeService: NbThemeService) {
this.themeSubscription = this.themeService.getJsTheme().subscribe(theme => {
this.currentTheme = theme.name;
});
}
ngOnDestroy() {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,59 +0,0 @@
<nb-card>
<nb-card-header class="header">My Playlist</nb-card-header>
<nb-card-body class="body">
<div class="track-info">
<div class="cover" style.background-image="url('{{track.cover}}')"></div>
<div class="details">
<h4 [class.subtitle]="collapsed">{{ track.name }}</h4>
<span>{{ track.artist }}</span>
</div>
</div>
<div class="progress-wrap">
<input dir="ltr" type="range" class="progress" [value]="getProgress()" min="0" max="100" step="0.01"
(input)="setProgress(duration.value)" #duration>
<div class="progress-foreground" [style.width.%]="getProgress()"></div>
</div>
<div class="timing">
<small class="current">{{ player.currentTime | timing }}</small>
<small class="remaining">- {{ player.duration - player.currentTime | timing }}</small>
</div>
<div class="controls">
<button class="control-button" nbButton ghost size="tiny" (click)="toggleShuffle()" [class.on]="shuffle">
<nb-icon icon="shuffle-2-outline" pack="eva"></nb-icon>
</button>
<button class="control-button" nbButton ghost size="medium" (click)="prev()">
<nb-icon class="skip" icon="skip-back-outline" pack="eva"></nb-icon>
</button>
<button class="control-button play-button" nbButton ghost size="medium" (click)="playPause()">
<nb-icon class="play" [icon]="player.paused ? 'play-circle-outline' : 'pause-circle-outline'" pack="eva">
</nb-icon>
</button>
<button class="control-button skip-forward-button" nbButton ghost size="medium" (click)="next()">
<nb-icon class="skip" icon="skip-forward-outline" pack="eva"></nb-icon>
</button>
<button class="control-button" nbButton ghost size="tiny" (click)="toggleLoop()" [class.on]="player.loop">
<nb-icon icon="repeat-outline" pack="eva"></nb-icon>
</button>
</div>
</nb-card-body>
<nb-card-footer class="footer">
<div class="volume">
<button nbButton ghost size="small" (click)="setVolume(0)">
<nb-icon class="volume-icon" icon="volume-down-outline" pack="eva"></nb-icon>
</button>
<div class="progress-wrap">
<input type="range" class="progress" [value]="getVolume()" max="100"
(input)="setVolume(volume.value)" #volume>
<div class="progress-foreground" [style.width.%]="getVolume()"></div>
</div>
<button nbButton ghost size="small" (click)="setVolume(100)">
<nb-icon class="volume-icon" icon="volume-up-outline" pack="eva"></nb-icon>
</button>
</div>
</nb-card-footer>
</nb-card>

View File

@ -1,283 +0,0 @@
@import '../../../../@theme/styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
height: 100%;
nb-card {
box-shadow: none;
border-width: 0;
margin: 0;
height: 100%;
}
.body {
display: flex;
flex-direction: column;
padding: 0;
}
.track-info {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
flex: 1;
padding: nb-theme(card-padding);
}
.cover {
border-radius: nb-theme(card-border-radius);
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 10rem;
height: 10rem;
}
.details {
text-align: center;
padding-top: 1.5rem;
span {
color: nb-theme(text-hint-color);
}
}
.progress-wrap {
position: relative;
height: 1rem;
}
.progress-foreground {
background-color: nb-theme(color-primary-default);
height: 2px;
position: absolute;
left: 0;
margin-top: calc(0.75rem - 1px);
width: 100px;
}
.progress {
appearance: none;
width: 100%;
background: transparent;
height: 1.5rem;
outline: none;
position: absolute;
@include install-thumb() {
width: 1rem;
height: 1rem;
border-radius: 50%;
background: nb-theme(color-primary-default);
cursor: pointer;
margin-top: calc(-0.5rem + 1px);
border: none;
}
@include install-track() {
width: 100%;
height: 2px;
cursor: pointer;
background: nb-theme(border-basic-color-3);
}
}
.timing {
padding-top: 0.5rem;
margin: 0 0.5rem;
display: flex;
justify-content: space-between;
color: nb-theme(text-hint-color);
.current {
@include nb-ltr(order, 0);
@include nb-rtl(order, 1);
}
.remaining {
@include nb-ltr(order, 1);
@include nb-rtl(order, 0);
}
}
.controls {
display: flex;
justify-content: space-between;
align-items: center;
@include nb-rtl(flex-direction, row-reverse);
padding: 1rem;
max-width: 400px;
width: 100%;
margin: 0 auto;
}
.control-button {
color: nb-theme(text-hint-color);
&.on {
color: nb-theme(color-primary-default);
}
nb-icon {
font-size: 1.5em;
}
}
.volume {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 auto;
position: relative;
max-width: 400px;
.progress-wrap {
height: 2.25rem;
margin: 0;
width: 80%;
.progress-foreground {
left: auto;
margin-top: calc(1rem + 1px);
z-index: 0;
max-width: 99.5%;
}
.progress {
height: 2.25rem;
overflow: visible;
@include install-thumb() {
width: 1.5rem;
height: 1.5rem;
background-color: nb-theme(background-basic-color-1);
box-shadow: 0 0.125rem 0.5rem 0 nb-theme(border-basic-color-3);
border: 1px solid nb-theme(border-basic-color-3);
margin-top: -0.75rem;
position: relative;
z-index: 10;
}
}
}
}
.volume-icon {
font-size: 1em;
color: nb-theme(text-hint-color);
}
&.collapsed {
$player-height: 4.5rem;
border: none;
height: $player-height;
.header {
display: none;
}
.body {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 0;
overflow: visible;
}
.footer {
display: none;
}
.track-info {
height: $player-height;
flex-direction: row;
padding: 0;
flex: none;
.cover {
height: $player-height;
width: $player-height;
flex: none;
}
.details {
margin-left: 0.875rem;
text-align: left;
padding: 0;
h4 {
margin-bottom: 0.125rem;
}
}
}
.progress-wrap {
width: calc(100% - 6rem);
align-self: flex-start;
position: absolute;
left: 0;
margin-top: calc(-0.75rem + 1px);
margin-left: calc(#{$player-height} + 0.75rem);
}
.timing {
display: none;
}
.controls {
padding: 0 1rem 0 0;
max-width: inherit;
width: inherit;
margin: 0;
button {
display: none;
}
.play-button,
.skip-forward-button {
display: block;
font-size: 1.3rem;
}
@include media-breakpoint-down(is) {
.play-button,
.skip-forward-button {
padding: 0.5rem;
}
}
@include media-breakpoint-down(xs) {
.skip-forward-button {
display: none;
}
}
}
.volume {
display: none;
}
.track-info .details {
@include media-breakpoint-down(is) {
span {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
@include media-breakpoint-between(lg, lg) {
.controls {
padding: 0.5rem;
}
.control-button.size-medium {
padding: nb-theme(button-ghost-small-padding);
}
}
}

View File

@ -1,100 +0,0 @@
import { Component, HostBinding, Input, OnDestroy } from '@angular/core';
import { PlayerService, Track } from '../../../../@core/utils/player.service';
@Component({
selector: 'ngx-player',
styleUrls: ['./player.component.scss'],
templateUrl: './player.component.html',
})
export class PlayerComponent implements OnDestroy {
@Input()
@HostBinding('class.collapsed')
collapsed: boolean;
track: Track;
player: HTMLAudioElement;
shuffle: boolean;
constructor(private playerService: PlayerService) {
this.track = this.playerService.random();
this.createPlayer();
}
ngOnDestroy() {
this.player.pause();
this.player.src = '';
this.player.load();
}
prev() {
if (!this.player.loop) {
if (this.shuffle) {
this.track = this.playerService.random();
} else {
this.track = this.playerService.prev();
}
}
this.reload();
}
next() {
if (!this.player.loop) {
if (this.shuffle) {
this.track = this.playerService.random();
} else {
this.track = this.playerService.next();
}
}
this.reload();
}
playPause() {
if (this.player.paused) {
this.player.play();
} else {
this.player.pause();
}
}
toggleShuffle() {
this.shuffle = !this.shuffle;
}
toggleLoop() {
this.player.loop = !this.player.loop;
}
setVolume(volume: number) {
this.player.volume = volume / 100;
}
getVolume(): number {
return this.player.volume * 100;
}
setProgress(duration: number) {
this.player.currentTime = this.player.duration * duration / 100;
}
getProgress(): number {
return this.player.currentTime / this.player.duration * 100 || 0;
}
private createPlayer() {
this.player = new Audio();
this.player.onended = () => this.next();
this.setTrack();
}
private reload() {
this.setTrack();
this.player.play();
}
private setTrack() {
this.player.src = this.track.url;
this.player.load();
}
}

View File

@ -1,90 +0,0 @@
<nb-card>
<nb-card-header>Room Management</nb-card-header>
<div class="room-selector">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
[attr.viewBox]="viewBox" preserveAspectRatio="xMidYMid">
<defs>
<filter id="f2" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur result="blurOut" in="StrokePaint" stdDeviation="3"/>
</filter>
<pattern id="New_Pattern_Swatch_1" data-name="New Pattern Swatch 1" width="60" height="60"
patternUnits="userSpaceOnUse" viewBox="0 0 60 60">
<line class="stroke-pattern" x1="-113.26" y1="123.26" x2="3.26" y2="6.74"/>
<line class="stroke-pattern" x1="-103.26" y1="133.26" x2="13.26" y2="16.74"/>
<line class="stroke-pattern" x1="-93.26" y1="143.26" x2="23.26" y2="26.74"/>
<line class="stroke-pattern" x1="-83.26" y1="153.26" x2="33.26" y2="36.74"/>
<line class="stroke-pattern" x1="-73.26" y1="163.26" x2="43.26" y2="46.74"/>
<line class="stroke-pattern" x1="-63.26" y1="173.26" x2="53.26" y2="56.74"/>
<line class="stroke-pattern" x1="-53.26" y1="123.26" x2="63.26" y2="6.74"/>
<line class="stroke-pattern" x1="-43.26" y1="133.26" x2="73.26" y2="16.74"/>
<line class="stroke-pattern" x1="-33.26" y1="143.26" x2="83.26" y2="26.74"/>
<line class="stroke-pattern" x1="-23.26" y1="153.26" x2="93.26" y2="36.74"/>
<line class="stroke-pattern" x1="-13.26" y1="163.26" x2="103.26" y2="46.74"/>
<line class="stroke-pattern" x1="-3.26" y1="173.26" x2="113.26" y2="56.74"/>
<line class="stroke-pattern" x1="6.74" y1="123.26" x2="123.26" y2="6.74"/>
<line class="stroke-pattern" x1="16.74" y1="133.26" x2="133.26" y2="16.74"/>
<line class="stroke-pattern" x1="26.74" y1="143.26" x2="143.26" y2="26.74"/>
<line class="stroke-pattern" x1="36.74" y1="153.26" x2="153.26" y2="36.74"/>
<line class="stroke-pattern" x1="46.74" y1="163.26" x2="163.26" y2="46.74"/>
<line class="stroke-pattern" x1="56.74" y1="173.26" x2="173.26" y2="56.74"/>
<line class="stroke-pattern" x1="-113.26" y1="63.26" x2="3.26" y2="-53.26"/>
<line class="stroke-pattern" x1="-103.26" y1="73.26" x2="13.26" y2="-43.26"/>
<line class="stroke-pattern" x1="-93.26" y1="83.26" x2="23.26" y2="-33.26"/>
<line class="stroke-pattern" x1="-83.26" y1="93.26" x2="33.26" y2="-23.26"/>
<line class="stroke-pattern" x1="-73.26" y1="103.26" x2="43.26" y2="-13.26"/>
<line class="stroke-pattern" x1="-63.26" y1="113.26" x2="53.26" y2="-3.26"/>
<line class="stroke-pattern" x1="-53.26" y1="63.26" x2="63.26" y2="-53.26"/>
<line class="stroke-pattern" x1="-43.26" y1="73.26" x2="73.26" y2="-43.26"/>
<line class="stroke-pattern" x1="-33.26" y1="83.26" x2="83.26" y2="-33.26"/>
<line class="stroke-pattern" x1="-23.26" y1="93.26" x2="93.26" y2="-23.26"/>
<line class="stroke-pattern" x1="-13.26" y1="103.26" x2="103.26" y2="-13.26"/>
<line class="stroke-pattern" x1="-3.26" y1="113.26" x2="113.26" y2="-3.26"/>
<line class="stroke-pattern" x1="6.74" y1="63.26" x2="123.26" y2="-53.26"/>
<line class="stroke-pattern" x1="16.74" y1="73.26" x2="133.26" y2="-43.26"/>
<line class="stroke-pattern" x1="26.74" y1="83.26" x2="143.26" y2="-33.26"/>
<line class="stroke-pattern" x1="36.74" y1="93.26" x2="153.26" y2="-23.26"/>
<line class="stroke-pattern" x1="46.74" y1="103.26" x2="163.26" y2="-13.26"/>
<line class="stroke-pattern" x1="56.74" y1="113.26" x2="173.26" y2="-3.26"/>
<line class="stroke-pattern" x1="-113.26" y1="3.26" x2="3.26" y2="-113.26"/>
<line class="stroke-pattern" x1="-103.26" y1="13.26" x2="13.26" y2="-103.26"/>
<line class="stroke-pattern" x1="-93.26" y1="23.26" x2="23.26" y2="-93.26"/>
<line class="stroke-pattern" x1="-83.26" y1="33.26" x2="33.26" y2="-83.26"/>
<line class="stroke-pattern" x1="-73.26" y1="43.26" x2="43.26" y2="-73.26"/>
<line class="stroke-pattern" x1="-63.26" y1="53.26" x2="53.26" y2="-63.26"/>
<line class="stroke-pattern" x1="-53.26" y1="3.26" x2="63.26" y2="-113.26"/>
<line class="stroke-pattern" x1="-43.26" y1="13.26" x2="73.26" y2="-103.26"/>
<line class="stroke-pattern" x1="-33.26" y1="23.26" x2="83.26" y2="-93.26"/>
<line class="stroke-pattern" x1="-23.26" y1="33.26" x2="93.26" y2="-83.26"/>
<line class="stroke-pattern" x1="-13.26" y1="43.26" x2="103.26" y2="-73.26"/>
<line class="stroke-pattern" x1="-3.26" y1="53.26" x2="113.26" y2="-63.26"/>
<line class="stroke-pattern" x1="6.74" y1="3.26" x2="123.26" y2="-113.26"/>
<line class="stroke-pattern" x1="16.74" y1="13.26" x2="133.26" y2="-103.26"/>
<line class="stroke-pattern" x1="26.74" y1="23.26" x2="143.26" y2="-93.26"/>
<line class="stroke-pattern" x1="36.74" y1="33.26" x2="153.26" y2="-83.26"/>
<line class="stroke-pattern" x1="46.74" y1="43.26" x2="163.26" y2="-73.26"/>
<line class="stroke-pattern" x1="56.74" y1="53.26" x2="173.26" y2="-63.26"/>
</pattern>
</defs>
<g>
<path class="room-border" [attr.d]="border.d" *ngFor="let border of roomSvg.borders" />
</g>
<g>
<path class="stroked-element"
[attr.fill]="getUrlPath('#New_Pattern_Swatch_1')"
[attr.d]="strokedArea.d" *ngFor="let strokedArea of roomSvg.stokedAreas"/>
</g>
<g [attr.id]="room.id" [class.selected-room]="selectedRoom == room.id" *ngFor="let room of sortedRooms">
<path class="room-bg" (click)="selectRoom(room.id)" [attr.d]="room.area.d" [style.filter]="isIE || isFirefox ? 'inherit': ''" />
<path class="room-border" [attr.d]="room.border.d" />
<path class="room-border room-border-glow" [attr.d]="room.border.d" [style.filter]="isIE || isFirefox ? 'inherit': ''" />
<text class="room-text" (click)="selectRoom(room.id)" text-anchor="middle"
[attr.x]="room.name.x" [attr.y]="room.name.y">{{room.name.text}}</text>
</g>
</svg>
</div>
</nb-card>

View File

@ -1,76 +0,0 @@
@import '../../../../@theme/styles/themes';
@include nb-install-component() {
nb-card {
background-color: transparent;
border-width: 0;
box-shadow: none;
margin: 0;
}
nb-card-header {
border-color: transparent;
}
svg {
width: 100%;
}
.stroke-pattern {
fill: none;
stroke: #bdc4cd;
stroke-miterlimit: 10;
opacity: 0.1;
stroke-width: 1px;
}
.stroked-element {
stroke-width: 4px;
stroke: #bdc4cd;
stroke-miterlimit: 10;
}
.room-border {
stroke-width: 4px;
stroke: #bdc4cd;
stroke-miterlimit: 10;
fill: none;
}
.room-bg {
fill: nb-theme(card-background-color);
stroke: transparent;
cursor: pointer;
stroke-width: 4px;
}
.room-bg-border-grad {
fill: none;
stroke: none;
stroke-width: 4px;
}
.room-text {
cursor: pointer;
user-select: none;
pointer-events: none;
fill: nb-theme(text-hint-color);
}
.selected-room {
z-index: 40;
.room-text {
fill: nb-theme(text-basic-color);
}
.room-border {
stroke: nb-theme(color-primary-default);
}
}
.header {
border-bottom: none;
padding-bottom: 0;
}
}

View File

@ -1,122 +0,0 @@
import { Component, EventEmitter, HostBinding, OnDestroy, OnInit, Output } from '@angular/core';
import { Location, LocationStrategy } from '@angular/common';
import { NbThemeService } from '@nebular/theme';
import { map, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
@Component({
selector: 'ngx-room-selector',
templateUrl: './room-selector.component.html',
styleUrls: ['./room-selector.component.scss'],
})
export class RoomSelectorComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
private hideGrid: boolean;
@Output() select: EventEmitter<number> = new EventEmitter();
selectedRoom = null;
sortedRooms = [];
viewBox = '-20 -20 618.88 407.99';
isIE = !!(navigator.userAgent.match(/Trident/)
|| navigator.userAgent.match(/MSIE/)
|| navigator.userAgent.match(/Edge/));
isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') >= 0;
roomSvg = {
borders: [{
d: 'M186.21,130.05H216.37V160H186.21Z',
}],
stokedAreas: [
{ d: 'M562.71,225V354h-290V319H418.37a6.09,6.09,0,0,0,6.09-6.09V225Z' },
{ d: 'M8.09,130V347.91A6.09,6.09,0,0,0,14.18,354h54V130Z' },
{ d: 'M216.37,49.82H358.8V92.5H216.37Z' },
],
rooms: [
{
id: '0',
name: { text: 'Kitchen', x: 142, y: 240.8 },
area: { d: 'M68.18,130V359.9A6.09,6.09,0,0,0,74.27,366h136a6.09,6.09,0,0,0,6.09-6.09V160H186.21V130Z' },
border: { d: 'M96,130H68.18V359.9A6.09,6.09,0,0,0,74.27,366h136a6.09,6.09,0,0,0,6.09-6.09V225 M152.71,' +
'130H186.21V160H218.5' },
},
{
id: '1',
name: { text: 'Bedroom', x: 109, y: 66 },
area: { d: 'M152.71,130h63.66V8.09A6.09,6.09,0,0,0,210.27,2H8.09A6.09,6.09,0,0,0,2,8.09V123.95A6.09,' +
'6.09,0,0,0,8.09,130H96Z' },
border: { d: 'M152.71,130h63.66V8.09A6.09,6.09,0,0,0,210.27,2H8.09A6.09,6.09,0,0,0,2,8.09V123.95A6.09' +
',6.09,0,0,0,8.09,130H96' },
},
{
id: '2',
name: { text: 'Living Room', x: 468, y: 134 },
area: { d: 'M358.8,160V49.82a6.09,6.09,0,0,1,6.09-6.09H570.78a6.09,6.09,0,0,1,6.09,6.09V218.9a6.09' +
',6.09,0,0,1-6.09,6.09h-212Z' },
border: { d: 'M358.8,160V49.82a6.09,6.09,0,0,1,6.09-6.09H570.78a6.09,6.09,0,0,1,6.09,6.09V218.9a6.09' +
',6.09,0,0,1-6.09,6.09h-212' },
},
{
id: '3',
name: { text: 'Hallway', x: 320, y: 273 },
area: { d: 'M216.37,354V92.5H358.8V225H424.39V319H272.71V354Z' },
border: { d: 'M216.37,225V356 M216.21,162V92.5H358.8V160 M358.8,225H424.39V312.91a6.09,' +
'6.09,0,0,1,-6.09,6.09H272.71V356' },
},
],
};
@HostBinding('style.background')
get background(): 'none' | null {
return this.hideGrid ? 'none' : null;
}
constructor(
private location: Location,
private locationStrategy: LocationStrategy,
private themeService: NbThemeService,
) {
this.selectRoom('2');
}
ngOnInit() {
this.hideGrid = this.themeService.currentTheme === 'corporate';
this.themeService.onThemeChange()
.pipe(
map(({ name }) => name === 'corporate'),
takeUntil(this.destroy$),
)
.subscribe((hideGrid: boolean) => this.hideGrid = hideGrid);
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
private sortRooms() {
this.sortedRooms = this.roomSvg.rooms.slice(0).sort((a, b) => {
if (a.id === this.selectedRoom) {
return 1;
}
if (b.id === this.selectedRoom) {
return -1;
}
return 0;
});
}
selectRoom(roomNumber) {
this.select.emit(roomNumber);
this.selectedRoom = roomNumber;
this.sortRooms();
}
getUrlPath(id: string) {
const baseHref = this.locationStrategy.getBaseHref().replace(/\/$/, '');
const path = this.location.path().replace(/\/$/, '');
return `url(${baseHref}${path}${id})`;
}
}

View File

@ -1,67 +0,0 @@
@import '../../../@theme/styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
ngx-room-selector {
width: 70%;
border-right: nb-theme(divider-width) nb-theme(divider-style) nb-theme(divider-color);
background: url('../../../../assets/images/square_pattern.svg') repeat;
background-size: 75px;
&.dark-background {
background-image: url('../../../../assets/images/square_pattern_cosmic.svg');
}
}
ngx-player {
width: 30%;
}
nb-card {
display: flex;
flex-direction: row;
}
ngx-room-selector {
display: flex;
flex-direction: column;
flex: 1;
::ng-deep .room-selector {
display: flex;
align-items: center;
justify-items: center;
flex: 1;
margin: 0 auto;
width: 90%;
max-width: 650px;
padding-bottom: 1rem;
}
}
@include media-breakpoint-down(md) {
&.expanded ngx-room-selector {
display: none;
}
ngx-room-selector, ngx-player {
width: 100%;
border: none;
}
nb-card {
flex-direction: column;
justify-content: space-between;
.collapse {
display: inline-block;
position: absolute;
top: 0.7rem;
left: 50%;
transform: translateX(-50%);
font-size: 2rem;
}
}
}
}

View File

@ -1,77 +0,0 @@
import { Component, HostBinding, OnDestroy } from '@angular/core';
import { NbThemeService, NbMediaBreakpoint, NbMediaBreakpointsService } from '@nebular/theme';
import { map } from 'rxjs/operators';
@Component({
selector: 'ngx-rooms',
styleUrls: ['./rooms.component.scss'],
template: `
<nb-card [size]="breakpoint.width >= breakpoints.sm ? 'giant' : ''">
<nb-icon icon="arrow-ios-downward" pack="eva"
(click)="collapse()"
class="collapse"
[hidden]="isCollapsed()">
</nb-icon>
<ngx-room-selector [class.dark-background]="isDarkTheme" (select)="select($event)"></ngx-room-selector>
<ngx-player [collapsed]="isCollapsed() && breakpoint.width <= breakpoints.md"></ngx-player>
</nb-card>
`,
})
export class RoomsComponent implements OnDestroy {
@HostBinding('class.expanded')
private expanded: boolean;
private selected: number;
isDarkTheme: boolean;
breakpoint: NbMediaBreakpoint;
breakpoints: any;
themeSubscription: any;
themeChangeSubscription: any;
constructor(private themeService: NbThemeService,
private breakpointService: NbMediaBreakpointsService) {
this.breakpoints = this.breakpointService.getBreakpointsMap();
this.themeSubscription = this.themeService.onMediaQueryChange()
.subscribe(([, newValue]) => {
this.breakpoint = newValue;
});
this.themeChangeSubscription = this.themeService.onThemeChange()
.pipe(map(({ name }) => name === 'cosmic' || name === 'dark'))
.subscribe((isDark: boolean) => this.isDarkTheme = isDark);
}
select(roomNumber) {
if (this.isSelected(roomNumber)) {
this.expand();
} else {
this.collapse();
}
this.selected = roomNumber;
}
expand() {
this.expanded = true;
}
collapse() {
this.expanded = false;
}
isCollapsed() {
return !this.expanded;
}
private isSelected(roomNumber): boolean {
return this.selected === roomNumber;
}
ngOnDestroy() {
this.themeSubscription.unsubscribe();
this.themeChangeSubscription.unsubscribe();
}
}

View File

@ -1,61 +0,0 @@
<nb-card size="giant">
<nb-card-header>
Security Cameras
<button class="single-view-button"
nbButton
size="small"
[appearance]="isSingleView ? 'filled' : 'outline'"
(click)="isSingleView = true">
<i class="nb-square"></i>
</button>
<button class="grid-view-button"
nbButton
size="small"
[appearance]="isSingleView ? 'outline' : 'filled'"
(click)="isSingleView = false">
<nb-icon icon="grid" pack="eva"></nb-icon>
</button>
</nb-card-header>
<div class="grid-container">
<div class="single-view" *ngIf="isSingleView">
<div class="camera" [style.background-image]="'url(' + selectedCamera.source + ')'">
<span class="camera-name">{{ selectedCamera.title }}</span>
</div>
</div>
<div class="grid-view" *ngIf="!isSingleView">
<div class="camera"
*ngFor="let camera of cameras"
[style.background-image]="'url(' + camera.source + ')'"
(click)="selectCamera(camera)">
<span class="camera-name">{{ camera.title }}</span>
</div>
</div>
</div>
<nb-card-footer>
<nb-actions [size]="actionSize" fullWidth>
<nb-action>
<nb-icon icon="pause-circle-outline" pack="eva"></nb-icon>
Pause
</nb-action>
<nb-action>
<nb-icon icon="list-outline" pack="eva"></nb-icon>
Logs
</nb-action>
<nb-action>
<nb-icon icon="search-outline" pack="eva"></nb-icon>
Search
</nb-action>
<nb-action>
<nb-icon icon="settings-2-outline" pack="eva"></nb-icon>
Setup
</nb-action>
</nb-actions>
</nb-card-footer>
</nb-card>

View File

@ -1,114 +0,0 @@
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@import '~bootstrap/scss/mixins/breakpoints';
@include nb-install-component() {
nb-card-header {
display: flex;
align-items: center;
padding-top: 0.625rem;
padding-bottom: 0.625rem;
}
.single-view-button {
.nb-square {
font-size: 1.25rem;
}
@include nb-ltr {
margin-left: auto;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
@include nb-rtl {
margin-right: auto;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
.grid-view-button {
::ng-deep svg {
vertical-align: top;
}
@include nb-ltr {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
@include nb-rtl {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
.grid-container {
height: 100%;
display: flex;
}
.single-view,
.grid-view {
flex: 1 0 100%;
}
.grid-view {
display: flex;
flex-wrap: wrap;
.camera {
flex: 1 0 50%;
}
}
.single-view .camera {
width: 100%;
height: 100%;
}
.camera {
background-position: center;
background-size: cover;
position: relative;
&::before {
background-color: rgba(255, 255, 255, 0.1);
content: '';
position: absolute;
width: 100%;
height: 100%;
opacity: 1;
}
&:hover::before {
opacity: 0;
}
}
.camera-name {
position: absolute;
bottom: 0;
width: 100%;
color: white;
background: nb-theme(overlay-backdrop-background-color);
padding: 0.5rem 1rem;
}
nb-action {
nb-icon {
@include nb-ltr(margin-right, 0.5rem);
@include nb-rtl(margin-left, 0.5rem);
}
::ng-deep svg {
vertical-align: top;
}
}
@include media-breakpoint-down(xl) {
nb-action {
padding: 0;
}
}
}

View File

@ -1,53 +0,0 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { map, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { NbComponentSize, NbMediaBreakpointsService, NbThemeService } from '@nebular/theme';
import { Camera, SecurityCamerasData } from '../../../@core/data/security-cameras';
@Component({
selector: 'ngx-security-cameras',
styleUrls: ['./security-cameras.component.scss'],
templateUrl: './security-cameras.component.html',
})
export class SecurityCamerasComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
cameras: Camera[];
selectedCamera: Camera;
isSingleView = false;
actionSize: NbComponentSize = 'medium';
constructor(
private themeService: NbThemeService,
private breakpointService: NbMediaBreakpointsService,
private securityCamerasService: SecurityCamerasData,
) {}
ngOnInit() {
this.securityCamerasService.getCamerasData()
.pipe(takeUntil(this.destroy$))
.subscribe((cameras: Camera[]) => {
this.cameras = cameras;
this.selectedCamera = this.cameras[0];
});
const breakpoints = this.breakpointService.getBreakpointsMap();
this.themeService.onMediaQueryChange()
.pipe(map(([, breakpoint]) => breakpoint.width))
.subscribe((width: number) => {
this.actionSize = width > breakpoints.md ? 'medium' : 'small';
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
selectCamera(camera: any) {
this.selectedCamera = camera;
this.isSingleView = true;
}
}

View File

@ -1,30 +0,0 @@
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@import '~bootstrap/scss/mixins/breakpoints';
@include nb-install-component() {
nb-card-body {
overflow: hidden;
}
.echart {
position: absolute;
left: 1em;
height: calc(100% - 2 * 1rem);
width: 40%;
}
.info {
margin-left: 45%;
padding-top: 1rem;
}
.value {
margin: 0;
}
.details {
color: nb-theme(text-hint-color);
}
}

View File

@ -1,186 +0,0 @@
import { delay } from 'rxjs/operators';
import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
declare const echarts: any;
@Component({
selector: 'ngx-solar',
styleUrls: ['./solar.component.scss'],
template: `
<nb-card size="tiny" class="solar-card">
<nb-card-header>Solar Energy Consumption</nb-card-header>
<nb-card-body>
<div echarts [options]="option" class="echart">
</div>
<div class="info">
<div class="h4 value">6.421 kWh</div>
<div class="details subtitle-2"><span>out of</span> 8.421 kWh</div>
</div>
</nb-card-body>
</nb-card>
`,
})
export class SolarComponent implements AfterViewInit, OnDestroy {
private value = 0;
@Input('chartValue')
set chartValue(value: number) {
this.value = value;
if (this.option.series) {
this.option.series[0].data[0].value = value;
this.option.series[0].data[1].value = 100 - value;
this.option.series[1].data[0].value = value;
}
}
option: any = {};
themeSubscription: any;
constructor(private theme: NbThemeService) {
}
ngAfterViewInit() {
this.themeSubscription = this.theme.getJsTheme().pipe(delay(1)).subscribe(config => {
const solarTheme: any = config.variables.solar;
this.option = Object.assign({}, {
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)',
},
series: [
{
name: ' ',
clockWise: true,
hoverAnimation: false,
type: 'pie',
center: ['45%', '50%'],
radius: solarTheme.radius,
data: [
{
value: this.value,
name: ' ',
label: {
normal: {
position: 'center',
formatter: '{d}%',
textStyle: {
fontSize: '22',
fontFamily: config.variables.fontSecondary,
fontWeight: '600',
color: config.variables.fgHeading,
},
},
},
tooltip: {
show: false,
},
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: solarTheme.gradientLeft,
},
{
offset: 1,
color: solarTheme.gradientRight,
},
]),
shadowColor: solarTheme.shadowColor,
shadowBlur: 0,
shadowOffsetX: 0,
shadowOffsetY: 3,
},
},
hoverAnimation: false,
},
{
value: 100 - this.value,
name: ' ',
tooltip: {
show: false,
},
label: {
normal: {
position: 'inner',
},
},
itemStyle: {
normal: {
color: solarTheme.secondSeriesFill,
},
},
},
],
},
{
name: ' ',
clockWise: true,
hoverAnimation: false,
type: 'pie',
center: ['45%', '50%'],
radius: solarTheme.radius,
data: [
{
value: this.value,
name: ' ',
label: {
normal: {
position: 'inner',
show: false,
},
},
tooltip: {
show: false,
},
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: solarTheme.gradientLeft,
},
{
offset: 1,
color: solarTheme.gradientRight,
},
]),
shadowColor: solarTheme.shadowColor,
shadowBlur: 7,
},
},
hoverAnimation: false,
},
{
value: 28,
name: ' ',
tooltip: {
show: false,
},
label: {
normal: {
position: 'inner',
},
},
itemStyle: {
normal: {
color: 'none',
},
},
},
],
},
],
});
});
}
ngOnDestroy() {
this.themeSubscription.unsubscribe();
}
}

View File

@ -1,79 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
nb-card {
flex-direction: row;
align-items: center;
height: 6rem;
overflow: visible;
.icon-container {
height: 100%;
padding: 0.625rem;
}
.icon {
display: flex;
align-items: center;
justify-content: center;
width: 5.75rem;
height: 4.75rem;
font-size: 3.75rem;
border-radius: nb-theme(card-border-radius);
transition: width 0.4s ease;
transform: translate3d(0, 0, 0);
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
color: nb-theme(text-control-color);
@each $status in nb-get-statuses() {
&.status-#{$status} {
$left-color: nb-theme(button-hero-#{$status}-left-background-color);
$right-color: nb-theme(button-hero-#{$status}-right-background-color);
background-image: linear-gradient(to right, $left-color, $right-color);
&:hover {
$left-hover-color: nb-theme(button-hero-#{$status}-hover-left-background-color);
$right-hover-color: nb-theme(button-hero-#{$status}-hover-right-background-color);
background-image: linear-gradient(to right, $left-hover-color, $right-hover-color);
}
}
}
}
&.off {
color: nb-theme(text-hint-color);
.status,
.title,
.icon {
color: nb-theme(text-hint-color);
}
@each $status in nb-get-statuses() {
.icon.status-#{$status} {
box-shadow: none;
background-image: linear-gradient(to right, transparent, transparent);
}
}
}
.details {
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
@include nb-ltr(padding, 0 0.5rem 0 0.75rem);
@include nb-rtl(padding, 0 0.75rem 0 0.5rem);
border-left: 1px solid transparent;
}
.title {
margin: 0;
}
.status {
text-transform: uppercase;
}
}
}

View File

@ -1,26 +0,0 @@
import { Component, Input } from '@angular/core';
@Component({
selector: 'ngx-status-card',
styleUrls: ['./status-card.component.scss'],
template: `
<nb-card (click)="on = !on" [ngClass]="{'off': !on}">
<div class="icon-container">
<div class="icon status-{{ type }}">
<ng-content></ng-content>
</div>
</div>
<div class="details">
<div class="title h5">{{ title }}</div>
<div class="status paragraph-2">{{ on ? 'ON' : 'OFF' }}</div>
</div>
</nb-card>
`,
})
export class StatusCardComponent {
@Input() title: string;
@Input() type: string;
@Input() on = true;
}

View File

@ -1,47 +0,0 @@
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsAQMAAABDsxw2AAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAACJJREFUaN7twTEBAAAAwiD7pzbFPmAAAAAAAAAAAAAAAGQOLbQAAU3zwM4AAAAASUVORK5CYII=">
<div class="svg-container">
<svg #svgRoot xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
[attr.viewBox]="styles.viewBox" preserveAspectRatio="xMinYMin meet" (mousedown)="mouseDown($event)">
<defs>
<filter [attr.id]="'blurFilter' + svgControlId" x="0" y="0" width="100%" height="100%">
<feGaussianBlur in="SourceGraphic" [attr.stdDeviation]="styles.blurRadius" />
<feComponentTransfer>
<feFuncA type="discrete" tableValues="1 1"/>
</feComponentTransfer>
</filter>
<clipPath [attr.id]="'sliderClip' + svgControlId">
<path [attr.d]="styles.clipPathStr" stroke="black"></path>
</clipPath>
</defs>
<g [attr.transform]="styles.arcTranslateStr">
<g class="toClip" [attr.clip-path]="getUrlPath('#sliderClip')">
<g class="toFilter" [attr.filter]="getUrlPath('#blurFilter')">
<path [attr.d]="arc.d" [attr.fill]="off ? styles.nonSelectedArc.color : arc.color" *ngFor="let arc of styles.gradArcs"></path>
</g>
<!-- ngFor is a quirk fix for webkit rendering issues -->
<path [attr.d]="styles.nonSelectedArc.d" [attr.fill]="styles.nonSelectedArc.color" *ngFor="let number of [0,1,2,3,4,5]"></path>
</g>
<circle [attr.cx]="styles.thumbPosition.x"
[attr.cy]="styles.thumbPosition.y"
[attr.r]="pinRadius"
[attr.stroke-width]="thumbBorder / scaleFactor"
[attr.fill]="off ? 'none' : thumbBg"
[attr.stroke]="off ? 'none' : thumbBorderColor">
</circle>
</g>
</svg>
</div>
<div class="temperature-bg">
<ng-content></ng-content>
</div>
<button nbButton appearance="ghost" class="power-bg" [class.on]="!off" (click)="switchPower()">
<nb-icon class="power-icon" icon="power-outline" pack="eva"></nb-icon>
</button>

View File

@ -1,63 +0,0 @@
@import '../../../../@theme/styles/themes';
@include nb-install-component() {
position: relative;
img {
width: 100%;
height: auto;
visibility: hidden;
}
.svg-container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.temperature-bg {
position: absolute;
width: 88%;
height: 88%;
top: 13%;
left: 6%;
border-radius: 50%;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: nb-theme(divider-width) nb-theme(divider-style) nb-theme(divider-color);
}
.power-bg {
position: absolute;
width: 5.25rem;
height: 5.25rem;
background-color: nb-theme(card-background-color);
border-radius: 50%;
bottom: 2%;
left: 50%;
transform: translate(-50%, 50%);
z-index: 2;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: nb-theme(divider-width) nb-theme(divider-style) nb-theme(divider-color);
&.on {
color: nb-theme(text-hint-color);
}
}
.power-icon {
font-size: 3rem;
}
}

View File

@ -1,380 +0,0 @@
import {
Component,
HostListener,
ViewChild,
ElementRef,
Input,
Output,
EventEmitter,
AfterViewInit,
OnChanges,
} from '@angular/core';
import { Location, LocationStrategy } from '@angular/common';
let uniqueId = 0;
const VIEW_BOX_SIZE = 300;
@Component({
selector: 'ngx-temperature-dragger',
templateUrl: './temperature-dragger.component.html',
styleUrls: ['./temperature-dragger.component.scss'],
})
export class TemperatureDraggerComponent implements AfterViewInit, OnChanges {
@ViewChild('svgRoot', { static: true }) svgRoot: ElementRef;
@Input() fillColors: string|string[];
@Input() disableArcColor;
@Input() bottomAngle = 90;
@Input() arcThickness = 18; // CSS pixels
@Input() thumbRadius = 16; // CSS pixels
@Input() thumbBorder = 3;
@Input() thumbBg;
@Input() thumbBorderColor;
@Input() maxLeap = 0.4;
value = 50;
@Output() valueChange = new EventEmitter<Number>();
@Input('value') set setValue(value) {
this.value = value;
}
@Input() min = 0; // min output value
@Input() max = 100; // max output value
@Input() step = 0.1;
@Output() power = new EventEmitter<boolean>();
@HostListener('window:mouseup', ['$event'])
onMouseUp(event) {
this.recalculateValue(event);
this.isMouseDown = false;
}
@HostListener('window:mousemove', ['$event'])
onMouseMove(event: MouseEvent) {
this.recalculateValue(event);
}
@HostListener('window:resize', ['$event'])
onResize(event) {
this.invalidate();
}
off = false;
oldValue: number;
svgControlId = uniqueId++;
scaleFactor = 1;
bottomAngleRad = 0;
radius = 100;
translateXValue = 0;
translateYValue = 0;
thickness = 6;
pinRadius = 10;
colors: any = [];
styles = {
viewBox: '0 0 300 300',
arcTranslateStr: 'translate(0, 0)',
clipPathStr: '',
gradArcs: [],
nonSelectedArc: {},
thumbPosition: { x: 0, y: 0 },
blurRadius: 15,
};
private isMouseDown = false;
private init = false;
constructor(
private location: Location,
private locationStrategy: LocationStrategy,
) {
this.oldValue = this.value;
}
ngAfterViewInit(): void {
// IE fix
setTimeout(() => {
this.invalidate();
this.init = true;
});
}
ngOnChanges(): void {
if (this.init) {
this.invalidate();
}
}
mouseDown(event) {
this.isMouseDown = true;
if (!this.off) {
this.recalculateValue(event, true);
}
}
switchPower() {
this.off = !this.off;
this.power.emit(!this.off);
if (this.off) {
this.oldValue = this.value;
this.value = this.min;
} else {
this.value = this.oldValue;
}
this.invalidatePinPosition();
}
getUrlPath(id: string) {
const baseHref = this.locationStrategy.getBaseHref().replace(/\/$/, '');
const path = this.location.path().replace(/\/$/, '');
return `url(${baseHref}${path}${id}${this.svgControlId})`;
}
private invalidate(): void {
this.bottomAngleRad = TemperatureDraggerComponent.toRad(this.bottomAngle);
this.calculateVars();
this.invalidateClipPathStr();
this.invalidatePinPosition();
// Chrome fix, temporary solution
// TODO: review set data to styles object
setTimeout(() => {
this.invalidateGradientArcs();
});
}
private calculateVars() {
this.bottomAngleRad = TemperatureDraggerComponent.toRad(this.bottomAngle);
this.colors = (typeof this.fillColors === 'string') ? [this.fillColors] : this.fillColors;
const halfAngle = this.bottomAngleRad / 2;
const svgBoundingRect = this.svgRoot.nativeElement.getBoundingClientRect();
const svgAreaFactor = svgBoundingRect.height && svgBoundingRect.width / svgBoundingRect.height || 1;
const svgHeight = VIEW_BOX_SIZE / svgAreaFactor;
const thumbMaxRadius = this.thumbRadius + this.thumbBorder;
const thumbMargin = 2 * thumbMaxRadius > this.arcThickness
? (thumbMaxRadius - this.arcThickness / 2) / this.scaleFactor
: 0;
this.scaleFactor = svgBoundingRect.width / VIEW_BOX_SIZE || 1;
this.styles.viewBox = `0 0 ${VIEW_BOX_SIZE} ${svgHeight}`;
const circleFactor = this.bottomAngleRad <= Math.PI
? ( 2 / (1 + Math.cos(halfAngle)) )
: ( 2 * Math.sin(halfAngle) / (1 + Math.cos(halfAngle)) );
if (circleFactor > svgAreaFactor) {
if (this.bottomAngleRad > Math.PI) {
this.radius = (VIEW_BOX_SIZE - 2 * thumbMargin) / (2 * Math.sin(halfAngle));
} else {
this.radius = VIEW_BOX_SIZE / 2 - thumbMargin;
}
} else {
this.radius = (svgHeight - 2 * thumbMargin) / (1 + Math.cos(halfAngle));
}
this.translateXValue = VIEW_BOX_SIZE / 2 - this.radius;
this.translateYValue = (svgHeight) / 2 - this.radius * (1 + Math.cos(halfAngle)) / 2;
this.styles.arcTranslateStr = `translate(${this.translateXValue}, ${this.translateYValue})`;
this.thickness = this.arcThickness / this.scaleFactor;
this.pinRadius = this.thumbRadius / this.scaleFactor;
}
private calculateClipPathSettings() {
const halfAngle = this.bottomAngleRad / 2;
const innerRadius = this.radius - this.thickness;
const xStartMultiplier = 1 - Math.sin(halfAngle);
const yMultiplier = 1 + Math.cos(halfAngle);
const xEndMultiplier = 1 + Math.sin(halfAngle);
return {
outer: {
start: {
x: xStartMultiplier * this.radius,
y: yMultiplier * this.radius,
},
end: {
x: xEndMultiplier * this.radius,
y: yMultiplier * this.radius,
},
radius: this.radius,
},
inner: {
start: {
x: xStartMultiplier * innerRadius + this.thickness,
y: yMultiplier * innerRadius + this.thickness,
},
end: {
x: xEndMultiplier * innerRadius + this.thickness,
y: yMultiplier * innerRadius + this.thickness,
},
radius: innerRadius,
},
thickness: this.thickness,
big: this.bottomAngleRad < Math.PI ? '1' : '0',
};
}
private invalidateClipPathStr() {
const s = this.calculateClipPathSettings();
let path = `M ${s.outer.start.x},${s.outer.start.y}`; // Start at startangle top
// Outer arc
// Draw an arc of radius 'radius'
// Arc details...
path += ` A ${s.outer.radius},${s.outer.radius}
0 ${s.big} 1
${s.outer.end.x},${s.outer.end.y}`; // Arc goes to top end angle coordinate
// Outer to inner connector
path += ` A ${s.thickness / 2},${s.thickness / 2}
0 1 1
${s.inner.end.x},${s.inner.end.y}`;
// Inner arc
path += ` A ${s.inner.radius},${s.inner.radius}
1 ${s.big} 0
${s.inner.start.x},${s.inner.start.y}`;
// Outer to inner connector
path += ` A ${s.thickness / 2},${s.thickness / 2}
0 1 1
${s.outer.start.x},${s.outer.start.y}`;
// Close path
path += ' Z';
this.styles.clipPathStr = path;
}
private calculateGradientConePaths(angleStep) {
const radius = this.radius;
function calcX(angle) {
return radius * (1 - 2 * Math.sin(angle));
}
function calcY(angle) {
return radius * (1 + 2 * Math.cos(angle));
}
const gradArray = [];
for (let i = 0, currentAngle = this.bottomAngleRad / 2; i < this.colors.length; i++, currentAngle += angleStep) {
gradArray.push({
start: { x: calcX(currentAngle), y: calcY(currentAngle) },
end: { x: calcX(currentAngle + angleStep), y: calcY(currentAngle + angleStep) },
big: Math.PI <= angleStep ? 1 : 0,
});
}
return gradArray;
}
private invalidateGradientArcs() {
const radius = this.radius;
function getArc(des) {
return `M ${radius},${radius}
L ${des.start.x},${des.start.y}
A ${2 * radius},${2 * radius}
0 ${des.big} 1
${des.end.x},${des.end.y}
Z`;
}
const angleStep = (2 * Math.PI - this.bottomAngleRad) / this.colors.length;
const s = this.calculateGradientConePaths(angleStep);
this.styles.gradArcs = [];
for (let i = 0; i < s.length; i++) {
const si = s[i];
const arcValue = getArc(si);
this.styles.gradArcs.push({
color: this.colors[i],
d: arcValue,
});
}
this.styles.blurRadius = 2 * radius * Math.sin(angleStep / 6);
}
private invalidateNonSelectedArc() {
const angle = this.bottomAngleRad / 2 + (1 - this.getValuePercentage()) * (2 * Math.PI - this.bottomAngleRad);
this.styles.nonSelectedArc = {
color: this.disableArcColor,
d: `M ${this.radius},${this.radius}
L ${this.radius},${3 * this.radius}
A ${2 * this.radius},${2 * this.radius}
1 ${angle > Math.PI ? '1' : '0'} 0
${this.radius + this.radius * 2 * Math.sin(angle)},${this.radius + this.radius * 2 * Math.cos(angle)}
Z`,
};
}
private invalidatePinPosition() {
const radiusOffset = this.thickness / 2;
const curveRadius = this.radius - radiusOffset;
const actualAngle = (2 * Math.PI - this.bottomAngleRad) * this.getValuePercentage() + this.bottomAngleRad / 2;
this.styles.thumbPosition = {
x: curveRadius * (1 - Math.sin(actualAngle)) + radiusOffset,
y: curveRadius * (1 + Math.cos(actualAngle)) + radiusOffset,
};
this.invalidateNonSelectedArc();
}
private recalculateValue(event, allowJumping = false) {
if (this.isMouseDown && !this.off) {
const rect = this.svgRoot.nativeElement.getBoundingClientRect();
const center = {
x: rect.left + VIEW_BOX_SIZE * this.scaleFactor / 2,
y: rect.top + (this.translateYValue + this.radius) * this.scaleFactor,
};
let actualAngle = Math.atan2(center.x - event.clientX, event.clientY - center.y);
if (actualAngle < 0) {
actualAngle = actualAngle + 2 * Math.PI;
}
const previousRelativeValue = this.getValuePercentage();
let relativeValue = 0;
if (actualAngle < this.bottomAngleRad / 2) {
relativeValue = 0;
} else if (actualAngle > 2 * Math.PI - this.bottomAngleRad / 2) {
relativeValue = 1;
} else {
relativeValue = (actualAngle - this.bottomAngleRad / 2) / (2 * Math.PI - this.bottomAngleRad);
}
const value = this.toValueNumber(relativeValue);
if (this.value !== value && (allowJumping || Math.abs(relativeValue - previousRelativeValue) < this.maxLeap)) {
this.value = value;
this.valueChange.emit(this.value);
this.invalidatePinPosition();
}
}
}
private getValuePercentage() {
return (this.value - this.min) / (this.max - this.min);
}
private toValueNumber(factor) {
return Math.round(factor * (this.max - this.min) / this.step) * this.step + this.min;
}
private static toRad(angle) {
return Math.PI * angle / 180;
}
}

View File

@ -1,69 +0,0 @@
<nb-card size="large">
<nb-tabset fullWidth>
<nb-tab tabTitle="Temperature">
<div class="slider-container">
<ngx-temperature-dragger [(value)]="temperature" (power)="temperatureOff = !$event"
[min]="temperatureData.min" [max]="temperatureData.max" [disableArcColor]="theme.arcEmpty"
[fillColors]="theme.arcFill" [thumbBg]="theme.thumbBg" [thumbBorderColor]="theme.thumbBorder">
<div class="slider-value-container" [ngClass]="{ 'off': temperatureOff }">
<div class="value temperature h1">
{{ temperatureOff ? '--' : (temperature | ngxRound) }}
</div>
<div class="desc">
Celsius
</div>
</div>
</ngx-temperature-dragger>
</div>
<nb-radio-group [(ngModel)]="temperatureMode" name="temperature-mode">
<nb-radio value="cool">
<i class="nb-snowy-circled"></i>
</nb-radio>
<nb-radio value="warm">
<i class="nb-sunny-circled"></i>
</nb-radio>
<nb-radio value="heat">
<i class="nb-flame-circled"></i>
</nb-radio>
<nb-radio value="fan">
<i class="nb-loop-circled"></i>
</nb-radio>
</nb-radio-group>
</nb-tab>
<nb-tab tabTitle="Humidity">
<div class="slider-container">
<ngx-temperature-dragger [(value)]="humidity" (power)="humidityOff = !$event"
[min]="humidityData.min" [max]="humidityData.max" [disableArcColor]="theme.arcEmpty"
[fillColors]="theme.arcFill" [thumbBg]="theme.thumbBg" [thumbBorderColor]="theme.thumbBorder">
<div class="slider-value-container" [ngClass]="{ 'off': humidityOff }">
<div class="value humidity h1">
{{ humidityOff ? '--' : (humidity | ngxRound) }}
</div>
</div>
</ngx-temperature-dragger>
</div>
<nb-radio-group [(ngModel)]="humidityMode" name="humidity-mode">
<nb-radio value="cool">
<i class="nb-snowy-circled"></i>
</nb-radio>
<nb-radio value="warm">
<i class="nb-sunny-circled"></i>
</nb-radio>
<nb-radio value="heat">
<i class="nb-flame-circled"></i>
</nb-radio>
<nb-radio value="fan">
<i class="nb-loop-circled"></i>
</nb-radio>
</nb-radio-group>
</nb-tab>
</nb-tabset>
</nb-card>

View File

@ -1,121 +0,0 @@
@import '../../../@theme/styles/themes';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
nb-tabset {
display: flex;
flex-direction: column;
height: 100%;
::ng-deep ul {
// make same size as card header
border-color: transparent;
padding-bottom: 1px;
.tab-link {
padding: 1.25rem 2rem;
}
}
}
nb-tab.content-active {
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
height: 100%;
}
.slider-container {
display: flex;
flex: 1;
-ms-flex: 1 1 auto;
justify-content: center;
align-items: center;
}
ngx-temperature-dragger {
margin-top: -1.5rem;
width: 100%;
max-width: 300px;
}
.slider-value-container {
display: flex;
flex-direction: column;
align-items: center;
.value {
position: relative;
margin: 0;
&.temperature::before {
position: absolute;
content: '°';
top: 0;
right: -0.85rem;
}
&.humidity::before {
position: absolute;
content: '%';
top: 3px;
right: -1.6rem;
font-size: 0.7em;
}
}
&.off {
.value {
color: nb-theme(text-hint-color);
letter-spacing: 0.25rem;
padding-left: 0.5rem;
&::before {
display: none;
}
}
.desc {
display: none;
}
}
}
nb-radio-group {
display: flex;
justify-content: space-between;
}
nb-radio {
flex: 0 0 auto;
width: calc(3.5rem + 2px);
height: calc(3.5rem + 2px);
::ng-deep {
.outer-circle,
.inner-circle {
display: none;
}
label {
padding: 0;
}
.text {
border: 1px solid transparent;
font-size: 2.5rem;
padding: 0.5rem;
margin: 0;
color: nb-theme(text-hint-color);
}
input:checked ~ .text {
border-color: nb-theme(color-primary-default);
border-radius: nb-theme(card-border-radius);
color: nb-theme(text-primary-color);
}
}
}
}

View File

@ -1,53 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { Temperature, TemperatureHumidityData } from '../../../@core/data/temperature-humidity';
import { takeWhile } from 'rxjs/operators';
import { forkJoin } from 'rxjs';
@Component({
selector: 'ngx-temperature',
styleUrls: ['./temperature.component.scss'],
templateUrl: './temperature.component.html',
})
export class TemperatureComponent implements OnDestroy {
private alive = true;
temperatureData: Temperature;
temperature: number;
temperatureOff = false;
temperatureMode = 'cool';
humidityData: Temperature;
humidity: number;
humidityOff = false;
humidityMode = 'heat';
theme: any;
themeSubscription: any;
constructor(private themeService: NbThemeService,
private temperatureHumidityService: TemperatureHumidityData) {
this.themeService.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(config => {
this.theme = config.variables.temperature;
});
forkJoin(
this.temperatureHumidityService.getTemperatureData(),
this.temperatureHumidityService.getHumidityData(),
)
.subscribe(([temperatureData, humidityData]: [Temperature, Temperature]) => {
this.temperatureData = temperatureData;
this.temperature = this.temperatureData.value;
this.humidityData = humidityData;
this.humidity = this.humidityData.value;
});
}
ngOnDestroy() {
this.alive = false;
}
}

View File

@ -1,174 +0,0 @@
import { delay, takeWhile } from 'rxjs/operators';
import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { LayoutService } from '../../../@core/utils';
@Component({
selector: 'ngx-traffic-chart',
template: `
<div echarts
[options]="option"
class="echart"
(chartInit)="onChartInit($event)">
</div>
`,
})
export class TrafficChartComponent implements AfterViewInit, OnDestroy {
private alive = true;
@Input() points: number[];
type = 'month';
types = ['week', 'month', 'year'];
option: any = {};
echartsIntance: any;
constructor(private theme: NbThemeService,
private layoutService: LayoutService) {
this.layoutService.onSafeChangeLayoutSize()
.pipe(
takeWhile(() => this.alive),
)
.subscribe(() => this.resizeChart());
}
ngAfterViewInit() {
this.theme.getJsTheme()
.pipe(
delay(1),
takeWhile(() => this.alive),
)
.subscribe(config => {
const trafficTheme: any = config.variables.traffic;
this.option = Object.assign({}, {
grid: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
xAxis: {
type: 'category',
boundaryGap: false,
data: this.points,
},
yAxis: {
boundaryGap: [0, '5%'],
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: true,
lineStyle: {
color: trafficTheme.yAxisSplitLine,
width: '1',
},
},
},
tooltip: {
axisPointer: {
type: 'shadow',
},
textStyle: {
color: trafficTheme.tooltipTextColor,
fontWeight: trafficTheme.tooltipFontWeight,
fontSize: 16,
},
position: 'top',
backgroundColor: trafficTheme.tooltipBg,
borderColor: trafficTheme.tooltipBorderColor,
borderWidth: 1,
formatter: '{c0} MB',
extraCssText: trafficTheme.tooltipExtraCss,
},
series: [
{
type: 'line',
symbol: 'circle',
symbolSize: 8,
sampling: 'average',
silent: true,
itemStyle: {
normal: {
color: trafficTheme.shadowLineDarkBg,
},
emphasis: {
color: 'rgba(0,0,0,0)',
borderColor: 'rgba(0,0,0,0)',
borderWidth: 0,
},
},
lineStyle: {
normal: {
width: 2,
color: trafficTheme.shadowLineDarkBg,
},
},
data: this.points.map(p => p - 15),
},
{
type: 'line',
symbol: 'circle',
symbolSize: 6,
sampling: 'average',
itemStyle: {
normal: {
color: trafficTheme.itemColor,
borderColor: trafficTheme.itemBorderColor,
borderWidth: 2,
},
emphasis: {
color: 'white',
borderColor: trafficTheme.itemEmphasisBorderColor,
borderWidth: 2,
},
},
lineStyle: {
normal: {
width: 2,
color: trafficTheme.lineBg,
shadowColor: trafficTheme.lineBg,
shadowBlur: trafficTheme.lineShadowBlur,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: trafficTheme.gradFrom,
}, {
offset: 1,
color: trafficTheme.gradTo,
}]),
opacity: 1,
},
},
data: this.points,
},
],
});
});
}
onChartInit(echarts) {
this.echartsIntance = echarts;
}
resizeChart() {
if (this.echartsIntance) {
this.echartsIntance.resize();
}
}
ngOnDestroy() {
this.alive = false;
}
}

View File

@ -1,35 +0,0 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
nb-card {
position: relative;
overflow: hidden;
}
nb-card-header {
display: flex;
align-items: center;
justify-content: space-between;
padding-top: nb-theme(card-header-with-select-padding-top);
padding-bottom: nb-theme(card-header-with-select-padding-bottom);
margin-bottom: -1px;
}
ngx-traffic-chart {
flex: 1;
}
::ng-deep {
.echart {
display: block;
height: 100%;
width: 100%;
}
canvas {
border-bottom-left-radius: nb-theme(card-border-radius);
border-bottom-right-radius: nb-theme(card-border-radius);
}
}
}

View File

@ -1,51 +0,0 @@
import { Component, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
import { TrafficChartData } from '../../../@core/data/traffic-chart';
@Component({
selector: 'ngx-traffic',
styleUrls: ['./traffic.component.scss'],
template: `
<nb-card size="tiny">
<nb-card-header>
<span>Traffic Consumption</span>
<nb-select [(selected)]="type">
<nb-option *ngFor="let t of types" [value]="t">{{ t }}</nb-option>
</nb-select>
</nb-card-header>
<ngx-traffic-chart [points]="trafficChartPoints"></ngx-traffic-chart>
</nb-card>
`,
})
export class TrafficComponent implements OnDestroy {
private alive = true;
trafficChartPoints: number[];
type = 'month';
types = ['week', 'month', 'year'];
currentTheme: string;
constructor(private themeService: NbThemeService,
private trafficChartService: TrafficChartData) {
this.themeService.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(theme => {
this.currentTheme = theme.name;
});
this.trafficChartService.getTrafficChartData()
.pipe(takeWhile(() => this.alive))
.subscribe((data) => {
this.trafficChartPoints = data;
});
}
ngOnDestroy() {
this.alive = false;
}
}

View File

@ -1,53 +0,0 @@
<nb-card size="medium">
<nb-card-body>
<span class="h3 location">New York</span>
<span class="date">Mon 29 May</span>
<div class="today">
<span class="today-temperature h1">20&deg;</span>
<nb-icon icon="sun-outline" pack="eva" class="today-icon"></nb-icon>
</div>
<div class="today-details">
<div class="parameter">
<span class="caption parameter-name">max</span>
<span class="parameter-value">23&deg;</span>
</div>
<div class="parameter">
<span class="caption parameter-name">min</span>
<span class="parameter-value">19&deg;</span>
</div>
<div class="parameter">
<span class="caption parameter-name">wind</span>
<span class="parameter-value">4 km/h</span>
</div>
<div class="parameter">
<span class="caption parameter-name">hum</span>
<span class="parameter-value">87%</span>
</div>
</div>
<div class="weekly-forecast">
<div class="day">
<span class="caption">Sun</span>
<i class="weather-icon ion-ios-cloudy-outline"></i>
<span class="temperature">17&deg;</span>
</div>
<div class="day">
<span class="caption">Mon</span>
<i class="weather-icon ion-ios-sunny-outline"></i>
<span class="temperature">19&deg;</span>
</div>
<div class="day">
<span class="caption">Tue</span>
<i class="weather-icon ion-ios-rainy-outline"></i>
<span class="temperature">22&deg;</span>
</div>
<div class="day">
<span class="caption">Wed</span>
<i class="weather-icon ion-ios-partlysunny-outline"></i>
<span class="temperature">21&deg;</span>
</div>
</div>
</nb-card-body>
</nb-card>

Some files were not shown because too many files have changed in this diff Show More