refactor(iot): electricity consumption

This commit is contained in:
Sergey Andrievskiy 2019-06-18 13:02:12 +03:00
parent d57a52ac43
commit 5943cfc7ac
3 changed files with 85 additions and 331 deletions

View file

@ -6,6 +6,9 @@ import {
NbTabsetModule,
NbUserModule,
NbRadioModule,
NbSelectModule,
NbListModule,
NbIconModule,
} from '@nebular/theme';
import { NgxEchartsModule } from 'ngx-echarts';
@ -39,6 +42,9 @@ import { FormsModule } from '@angular/forms';
NbTabsetModule,
NbActionsModule,
NbRadioModule,
NbSelectModule,
NbListModule,
NbIconModule,
NgxEchartsModule,
],
declarations: [

View file

@ -1,57 +1,47 @@
<nb-card size="large">
<div class="consumption-table">
<div class="table-header">
<div>Electricity</div>
<div class="subtitle">Consumption</div>
</div>
<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">
<div class="stats-month" *ngFor="let month of year.months">
<div>
<nb-list>
<nb-list-item *ngFor="let month of year.months">
<span class="month">{{ month.month }}</span>
<span class="delta" [ngClass]="{ 'down': month.down }">{{ month.delta }}</span>
</div>
<div class="results">
<b>{{ month.kWatts }}</b> kWh / <b>{{ month.cost }}</b> USD
</div>
</div>
<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>
</div>
</nb-card>
<div class="chart-container">
<div class="chart-header">
<div class="header-stats">
<div class="stats-block">
<div class="subtitle">Consumed</div>
<div>
<span class="value">816</span>
<span class="unit">kWh</span>
</div>
</div>
<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>
<div class="stats-block currency">
<div class="subtitle">Spent</div>
<div>
<span class="value">291</span>
<span class="unit">USD</span>
</div>
</div>
</div>
<nb-select [(selected)]="type" class="type-select">
<nb-option *ngFor="let t of types" [value]="t">{{ t }}</nb-option>
</nb-select>
</nb-card-header>
<div class="dropdown"
[ngClass]="{ 'ghost-dropdown': currentTheme === 'corporate' }"
ngbDropdown>
<button type="button" ngbDropdownToggle class="btn"
[ngClass]="{ 'btn-outline-success': currentTheme == 'default', 'btn-primary': currentTheme != 'default'}">
{{ type }}
</button>
<ul class="dropdown-menu" ngbDropdownMenu>
<li class="dropdown-item" *ngFor="let t of types" (click)="type = t">{{ t }}</li>
</ul>
</div>
</div>
<ngx-electricity-chart [data]="chartData"></ngx-electricity-chart>
</div>
</nb-card>
</nb-card>

View file

@ -1,328 +1,86 @@
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/components/card/card.component.theme';
@import '~@nebular/theme/styles/global/typography/typography';
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
//@import '~@nebular/bootstrap/styles/hero-buttons';
@include nb-install-component() {
nb-card {
.cards-container {
display: flex;
flex-direction: row;
}
nb-card-body {
overflow: hidden;
}
.consumption-table {
display: flex;
flex-direction: column;
width: 20rem;
height: 100%;
z-index: 2;
box-shadow: nb-theme(card-shadow);
@include nb-for-theme(corporate) {
border-right: 1px solid nb-theme(card-border-color);
}
.table-card,
.chart-card {
box-shadow: none;
margin-bottom: 0;
}
.table-header {
@include nb-card-header();
font-size: 1.25rem;
.subtitle {
color: nb-theme(color-fg);
font-family: nb-theme(font-main);
font-size: 1rem;
font-weight: nb-theme(font-weight-light);
}
.table-card {
flex: 0 0 auto;
}
nb-tabset ::ng-deep {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
ul {
align-items: center;
padding: 1rem;
}
ul li a {
font-weight: nb-theme(font-weight-bolder);
padding: 0.75rem 1rem;
}
ul li.active {
position: relative;
background-color: nb-theme(layout-bg);
border-radius: nb-theme(radius) nb-theme(radius) 0 0;
&::before {
position: absolute;
content: '';
width: 100%;
height: 5px;
border-radius: 2.5px;
bottom: 0;
left: 0;
background: nb-theme(color-success);
}
a {
font-size: 1.5rem;
}
a::before {
display: none;
}
}
nb-tab {
flex: 1;
overflow-y: auto;
}
.chart-card {
flex: 1 0 auto;
}
.stats-month {
.chart-card nb-card-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: nb-theme(padding);
color: nb-theme(color-fg);
position: relative;
padding-top: 0.45rem;
padding-bottom: 0.45rem;
border-bottom-color: transparent;
}
&:not(:first-child) {
border-top: 1px solid nb-theme(separator);
.type-select {
margin-left: auto;
}
@include nb-for-theme(corporate) {
border-top-color: nb-theme(tabs-separator);
}
}
.stats {
margin-right: 1rem;
&:hover {
background-color: nb-theme(layout-bg);
&::before {
position: absolute;
content: '';
height: 100%;
width: 6px;
left: 0;
top: 0;
background-color: nb-theme(color-success);
border-radius: nb-theme(radius);
}
}
.month {
display: inline-block;
width: 2.75rem;
font-family: nb-theme(font-secondary);
font-size: 1.25rem;
font-weight: nb-theme(font-weight-bolder);
color: nb-theme(color-fg-heading);
}
.delta {
position: relative;
display: inline-block;
padding-left: 1rem;
font-size: 0.75rem;
//color: text-danger();
&::before {
position: absolute;
content: '';
bottom: 3px;
left: 2px;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
//border-bottom: 8px solid text-danger();
}
&.down {
//color: text-success();
&::before {
top: 3px;
//border-top: 8px solid text-success();
border-bottom: none;
}
}
}
.results {
font-size: 0.875rem;
font-weight: nb-theme(font-weight-light);
b {
font-family: nb-theme(font-secondary);
font-size: 1rem;
font-weight: nb-theme(font-weight-bolder);
color: nb-theme(color-fg-heading);
}
> .caption {
display: block;
}
}
.chart-container {
flex: 1;
height: 100%;
background-image: nb-theme(radial-gradient);
display: flex;
flex-direction: column;
nb-tabset {
overflow: hidden;
}
.chart-header {
nb-tab {
height: 29.5rem;
overflow-y: auto;
}
nb-tab {
padding: 0;
}
nb-list-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1rem 1.75rem 1rem 1rem;
align-items: baseline;
}
.header-stats {
display: flex;
align-items: center;
.month {
width: 2rem;
}
.stats-block {
display: flex;
flex-direction: column;
align-items: normal;
color: nb-theme(color-fg);
padding: 0 1.5rem;
border-right: 1px solid nb-theme(separator);
.subtitle {
font-size: 1rem;
font-weight: nb-theme(font-weight-light);
}
.value {
font-family: nb-theme(font-secondary);
font-size: 1.5rem;
font-weight: nb-theme(font-weight-bold);
color: nb-theme(color-fg-heading);
}
.unit {
font-family: nb-theme(font-secondary);
font-size: 1.25rem;
font-weight: nb-theme(font-weight-light);
}
nb-icon.down {
color: nb-theme(color-danger-default);
}
.dropdown {
min-width: 130px;
nb-icon.up {
color: nb-theme(color-success-default);
}
@include nb-for-theme(cosmic) {
nb-tabset ::ng-deep ul li.active {
background-color: nb-theme(color-primary);
border-radius: nb-theme(radius);
&::before {
display: none;
}
}
.stats-block .value {
font-weight: nb-theme(font-weight-bolder);
}
.stats-month {
&:hover {
&::before {
$color-top: nb-theme(btn-success-bg);
//$color-bottom: btn-hero-success-left-color();
//background-image: linear-gradient(to top, $color-top, $color-bottom);
//box-shadow: 0 0 16px -2px btn-hero-success-middle-color();
}
}
}
.results {
margin-left: auto;
}
@include nb-for-theme(corporate) {
nb-tabset ::ng-deep ul li.active {
&::before {
display: none;
}
}
.stats-block {
border-right: none;
}
.stats-month {
&:hover {
&::before {
background-color: nb-theme(color-primary);
}
}
.delta {
&.down {
//color: text-primary();
&::before {
//border-top: 8px solid text-primary();
}
}
}
}
}
@include media-breakpoint-down(xxl) {
.stats-block {
border: none;
padding: 0 1rem;
}
}
@include media-breakpoint-between(md, xl) {
.consumption-table {
@include media-breakpoint-down(xl) {
.table-card {
display: none;
}
}
@include media-breakpoint-down(md) {
.chart-header {
padding: 1rem;
}
.dropdown {
min-width: 100px;
button {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
}
}
@include media-breakpoint-down(sm) {
.consumption-table {
display: none;
}
}
@include media-breakpoint-down(xs) {
.stats-block {
padding: 0;
&:first-child {
padding: 0 0.5rem;
}
.subtitle {
font-size: 1rem;
}
.value {
font-size: 1.5rem;
}
.unit {
display: none;
}
}
}
}