feat(dashboard): add new E-commerce dashboard (#1754)

This commit is contained in:
ESadouski 2018-08-08 16:45:31 +03:00 committed by Dmitry Nehaychik
parent 3482404b88
commit 56e4709a55
106 changed files with 6333 additions and 19 deletions

View file

@ -6,6 +6,15 @@ import { ElectricityService } from './electricity.service';
import { StateService } from './state.service';
import { SmartTableService } from './smart-table.service';
import { PlayerService } from './player.service';
import { UserActivityService } from './user-activity.service';
import { OrdersChartService } from './orders-chart.service';
import { ProfitChartService } from './profit-chart.service';
import { TrafficListService } from './traffic-list.service';
import { PeriodsService } from './periods.service';
import { EarningService } from './earning.service';
import { OrdersProfitChartService } from './orders-profit-chart.service';
import { TrafficBarService } from './traffic-bar.service';
import { ProfitBarAnimationChartService } from './profit-bar-animation-chart.service';
const SERVICES = [
UserService,
@ -13,6 +22,15 @@ const SERVICES = [
StateService,
SmartTableService,
PlayerService,
UserActivityService,
OrdersChartService,
ProfitChartService,
TrafficListService,
PeriodsService,
EarningService,
OrdersProfitChartService,
TrafficBarService,
ProfitBarAnimationChartService,
];
@NgModule({

View file

@ -0,0 +1,116 @@
import { Injectable } from '@angular/core';
import { of as observableOf, Observable } from 'rxjs';
export class LiveUpdateChart {
liveChart: { value: [string, number] }[];
delta: {
up: boolean;
value: number;
};
dailyIncome: number;
}
export class PieChart {
value: number;
name: string;
}
@Injectable()
export class EarningService {
private currentDate: Date = new Date();
private currentValue = Math.random() * 1000;
private ONE_DAY = 24 * 3600 * 1000;
private pieChartData = [
{
value: 50,
name: 'Bitcoin',
},
{
value: 25,
name: 'Tether',
},
{
value: 25,
name: 'Ethereum',
},
];
private liveUpdateChartData = {
bitcoin: {
liveChart: [],
delta: {
up: true,
value: 4,
},
dailyIncome: 45895,
},
tether: {
liveChart: [],
delta: {
up: false,
value: 9,
},
dailyIncome: 5862,
},
ethereum: {
liveChart: [],
delta: {
up: false,
value: 21,
},
dailyIncome: 584,
},
};
getDefaultLiveChartData(elementsNumber: number) {
this.currentDate = new Date();
this.currentValue = Math.random() * 1000;
return Array.from(Array(elementsNumber))
.map(item => this.generateRandomLiveChartData());
}
generateRandomLiveChartData() {
this.currentDate = new Date(+this.currentDate + this.ONE_DAY);
this.currentValue = this.currentValue + Math.random() * 20 - 11;
if (this.currentValue < 0) {
this.currentValue = Math.random() * 100;
}
return {
value: [
[
this.currentDate.getFullYear(),
this.currentDate.getMonth(),
this.currentDate.getDate(),
].join('/'),
Math.round(this.currentValue),
],
};
}
generateRandomEarningData(currency) {
const data = this.liveUpdateChartData[currency.toLowerCase()];
const newValue = this.generateRandomLiveChartData();
data.liveChart.shift();
data.liveChart.push(newValue);
return observableOf(data.liveChart);
}
getEarningLiveUpdateCardData(currency: string) {
const data = this.liveUpdateChartData[currency.toLowerCase()];
data.liveChart = this.getDefaultLiveChartData(150);
return observableOf(data);
}
getEarningPieChartData(): Observable<PieChart[]> {
return observableOf(this.pieChartData);
}
}

View file

@ -0,0 +1,158 @@
import { Injectable } from '@angular/core';
import { PeriodsService } from './periods.service';
export class OrdersChart {
chartLabel: string[];
linesData: number[][];
}
@Injectable()
export class OrdersChartService {
private year = [
'2012',
'2013',
'2014',
'2015',
'2016',
'2017',
'2018',
];
private data = { };
constructor(private period: PeriodsService) {
this.data = {
week: this.getDataForWeekPeriod(),
month: this.getDataForMonthPeriod(),
year: this.getDataForYearPeriod(),
};
}
private getDataForWeekPeriod(): OrdersChart {
return {
chartLabel: this.getDataLabels(42, this.period.getWeeks()),
linesData: [
[
184, 267, 326, 366, 389, 399,
392, 371, 340, 304, 265, 227,
191, 158, 130, 108, 95, 91, 97,
109, 125, 144, 166, 189, 212,
236, 259, 280, 300, 316, 329,
338, 342, 339, 329, 312, 288,
258, 221, 178, 128, 71,
],
[
158, 178, 193, 205, 212, 213,
204, 190, 180, 173, 168, 164,
162, 160, 159, 158, 159, 166,
179, 195, 215, 236, 257, 276,
292, 301, 304, 303, 300, 293,
284, 273, 262, 251, 241, 234,
232, 232, 232, 232, 232, 232,
],
[
58, 137, 202, 251, 288, 312,
323, 324, 311, 288, 257, 222,
187, 154, 124, 100, 81, 68, 61,
58, 61, 69, 80, 96, 115, 137,
161, 186, 210, 233, 254, 271,
284, 293, 297, 297, 297, 297,
297, 297, 297, 297, 297,
],
],
};
}
private getDataForMonthPeriod(): OrdersChart {
return {
chartLabel: this.getDataLabels(47, this.period.getMonths()),
linesData: [
[
5, 63, 113, 156, 194, 225,
250, 270, 283, 289, 290,
286, 277, 264, 244, 220,
194, 171, 157, 151, 150,
152, 155, 160, 166, 170,
167, 153, 135, 115, 97,
82, 71, 64, 63, 62, 61,
62, 65, 73, 84, 102,
127, 159, 203, 259, 333,
],
[
6, 83, 148, 200, 240,
265, 273, 259, 211,
122, 55, 30, 28, 36,
50, 68, 88, 109, 129,
146, 158, 163, 165,
173, 187, 208, 236,
271, 310, 346, 375,
393, 400, 398, 387,
368, 341, 309, 275,
243, 220, 206, 202,
207, 222, 247, 286, 348,
],
[
398, 348, 315, 292, 274,
261, 251, 243, 237, 231,
222, 209, 192, 172, 152,
132, 116, 102, 90, 80, 71,
64, 58, 53, 49, 48, 54, 66,
84, 104, 125, 142, 156, 166,
172, 174, 172, 167, 159, 149,
136, 121, 105, 86, 67, 45, 22,
],
],
};
}
private getDataForYearPeriod(): OrdersChart {
return {
chartLabel: this.getDataLabels(42, this.year),
linesData: [
[
190, 269, 327, 366, 389, 398,
396, 387, 375, 359, 343, 327,
312, 298, 286, 276, 270, 268,
265, 258, 247, 234, 220, 204,
188, 172, 157, 142, 128, 116,
106, 99, 95, 94, 92, 89, 84,
77, 69, 60, 49, 36, 22,
],
[
265, 307, 337, 359, 375, 386,
393, 397, 399, 397, 390, 379,
365, 347, 326, 305, 282, 261,
241, 223, 208, 197, 190, 187,
185, 181, 172, 160, 145, 126,
105, 82, 60, 40, 26, 19, 22,
43, 82, 141, 220, 321,
],
[
9, 165, 236, 258, 244, 206,
186, 189, 209, 239, 273, 307,
339, 365, 385, 396, 398, 385,
351, 300, 255, 221, 197, 181,
170, 164, 162, 161, 159, 154,
146, 135, 122, 108, 96, 87,
83, 82, 82, 82, 82, 82, 82,
],
],
};
}
getDataLabels(nPoints: number, labelsArray: string[]): string[] {
const labelsArrayLength = labelsArray.length;
const step = Math.round(nPoints / labelsArrayLength);
return Array.from(Array(nPoints)).map((item, index) => {
const dataIndex = Math.round(index / step);
return index % step === 0 ? labelsArray[dataIndex] : '';
});
}
getOrdersChartData(period: string): OrdersChart {
return this.data[period];
}
}

View file

@ -0,0 +1,48 @@
import { of as observableOf, Observable } from 'rxjs';
import { Injectable } from '@angular/core';
import { OrdersChart, OrdersChartService } from './orders-chart.service';
import { ProfitChart, ProfitChartService } from './profit-chart.service';
export class OrderProfitChartSummary {
title: string;
value: number;
}
@Injectable()
export class OrdersProfitChartService {
private summary = [
{
title: 'Marketplace',
value: 3654,
},
{
title: 'Last Month',
value: 946,
},
{
title: 'Last Week',
value: 654,
},
{
title: 'Today',
value: 230,
},
];
constructor(private ordersChartService: OrdersChartService,
private profitChartService: ProfitChartService) {
}
getOrderProfitChartSummary(): Observable<OrderProfitChartSummary[]> {
return observableOf(this.summary);
}
getOrdersChartData(period: string): Observable<OrdersChart> {
return observableOf(this.ordersChartService.getOrdersChartData(period));
}
getProfitChartData(period: string): Observable<ProfitChart> {
return observableOf(this.profitChartService.getProfitChartData(period));
}
}

View file

@ -0,0 +1,33 @@
import { Injectable } from '@angular/core';
@Injectable()
export class PeriodsService {
getYears() {
return [
'2010', '2011', '2012',
'2013', '2014', '2015',
'2016', '2017', '2018',
];
}
getMonths() {
return [
'Jan', 'Feb', 'Mar',
'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec',
];
}
getWeeks() {
return [
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun',
];
}
}

View file

@ -0,0 +1,41 @@
import { Injectable } from '@angular/core';
import { of as observableOf, Observable } from 'rxjs';
@Injectable()
export class ProfitBarAnimationChartService {
private data: any;
constructor() {
this.data = {
firstLine: this.getDataForFirstLine(),
secondLine: this.getDataForSecondLine(),
};
}
getDataForFirstLine(): number[] {
return this.createEmptyArray(100)
.map((_, index) => {
const oneFifth = index / 5;
return (Math.sin(oneFifth) * (oneFifth - 10) + index / 6) * 5;
});
}
getDataForSecondLine(): number[] {
return this.createEmptyArray(100)
.map((_, index) => {
const oneFifth = index / 5;
return (Math.cos(oneFifth) * (oneFifth - 10) + index / 6) * 5;
});
}
createEmptyArray(nPoints: number) {
return Array.from(Array(nPoints));
}
getChartData(): Observable<{ firstLine: number[]; secondLine: number[] }> {
return observableOf(this.data);
}
}

View file

@ -0,0 +1,80 @@
import { Injectable } from '@angular/core';
import { PeriodsService } from './periods.service';
export class ProfitChart {
chartLabel: string[];
data: number[][];
}
@Injectable()
export class ProfitChartService {
private year = [
'2012',
'2013',
'2014',
'2015',
'2016',
'2017',
'2018',
];
private data = { };
constructor(private period: PeriodsService) {
this.data = {
week: this.getDataForWeekPeriod(),
month: this.getDataForMonthPeriod(),
year: this.getDataForYearPeriod(),
};
}
private getDataForWeekPeriod(): ProfitChart {
const nPoint = this.period.getWeeks().length;
return {
chartLabel: this.period.getWeeks(),
data: [
this.getRandomData(nPoint),
this.getRandomData(nPoint),
this.getRandomData(nPoint),
],
};
}
private getDataForMonthPeriod(): ProfitChart {
const nPoint = this.period.getMonths().length;
return {
chartLabel: this.period.getMonths(),
data: [
this.getRandomData(nPoint),
this.getRandomData(nPoint),
this.getRandomData(nPoint),
],
};
}
private getDataForYearPeriod(): ProfitChart {
const nPoint = this.year.length;
return {
chartLabel: this.year,
data: [
this.getRandomData(nPoint),
this.getRandomData(nPoint),
this.getRandomData(nPoint),
],
};
}
private getRandomData(nPoints: number): number[] {
return Array.from(Array(nPoints)).map(() => {
return Math.round(Math.random() * 500);
});
}
getProfitChartData(period: string): ProfitChart {
return this.data[period];
}
}

View file

@ -0,0 +1,51 @@
import { Injectable } from '@angular/core';
import { of as observableOf, Observable } from 'rxjs';
import { PeriodsService } from './periods.service';
export class TrafficBar {
data: number[];
labels: string[];
formatter: string;
}
@Injectable()
export class TrafficBarService {
private data = { };
constructor(private period: PeriodsService) {
this.data = {
week: this.getDataForWeekPeriod(),
month: this.getDataForMonthPeriod(),
year: this.getDataForYearPeriod(),
};
}
getDataForWeekPeriod(): TrafficBar {
return {
data: [10, 15, 19, 7, 20, 13, 15],
labels: this.period.getWeeks(),
formatter: '{c0} MB',
};
}
getDataForMonthPeriod(): TrafficBar {
return {
data: [0.5, 0.3, 0.8, 0.2, 0.3, 0.7, 0.8, 1, 0.7, 0.8, 0.6, 0.7],
labels: this.period.getMonths(),
formatter: '{c0} GB',
};
}
getDataForYearPeriod(): TrafficBar {
return {
data: [10, 15, 19, 7, 20, 13, 15, 19, 11],
labels: this.period.getYears(),
formatter: '{c0} GB',
};
}
getTrafficBarData(period: string): Observable<TrafficBar> {
return observableOf(this.data[period]);
}
}

View file

@ -0,0 +1,100 @@
import { Injectable } from '@angular/core';
import { of as observableOf, Observable } from 'rxjs';
import { PeriodsService } from './periods.service';
export class TrafficList {
date: string;
value: number;
delta: {
up: boolean;
value: number;
};
comparison: {
prevDate: string;
prevValue: number;
nextDate: string;
nextValue: number;
};
}
@Injectable()
export class TrafficListService {
private getRandom = (roundTo: number) => Math.round(Math.random() * roundTo);
private data = {};
constructor(private period: PeriodsService) {
this.data = {
week: this.getDataWeek(),
month: this.getDataMonth(),
year: this.getDataYear(),
};
}
private getDataWeek(): TrafficList[] {
const getFirstDateInPeriod = () => {
const weeks = this.period.getWeeks();
return weeks[weeks.length - 1];
};
return this.reduceData(this.period.getWeeks(), getFirstDateInPeriod);
}
private getDataMonth(): TrafficList[] {
const getFirstDateInPeriod = () => {
const months = this.period.getMonths();
const date = new Date();
const prevYear = date.getFullYear() - 1;
return `${months[months.length - 1]}, ${prevYear}`;
};
return this.reduceData(this.period.getMonths(), getFirstDateInPeriod);
}
private getDataYear(): TrafficList[] {
const getFirstDateInPeriod = () => {
const years = this.period.getYears();
return `${parseInt(years[0], 10) - 1}`;
};
return this.reduceData(this.period.getYears(), getFirstDateInPeriod);
}
private reduceData(timePeriods: string[], getFirstDateInPeriod: () => string): TrafficList[] {
return timePeriods.reduce((result, timePeriod, index) => {
const hasResult = result[index - 1];
const prevDate = hasResult ?
result[index - 1].comparison.nextDate :
getFirstDateInPeriod();
const prevValue = hasResult ?
result[index - 1].comparison.nextValue :
this.getRandom(100);
const nextValue = this.getRandom(100);
const deltaValue = prevValue - nextValue;
const item = {
date: timePeriod,
value: this.getRandom(1000),
delta: {
up: deltaValue <= 0,
value: Math.abs(deltaValue),
},
comparison: {
prevDate,
prevValue,
nextDate: timePeriod,
nextValue,
},
};
return [...result, item];
}, []);
}
getTrafficListData(period: string): Observable<TrafficList> {
return observableOf(this.data[period]);
}
}

View file

@ -0,0 +1,67 @@
import { Injectable } from '@angular/core';
import { of as observableOf, Observable } from 'rxjs';
import { PeriodsService } from './periods.service';
export class UserActive {
date: string;
pagesVisitCount: number;
deltaUp: boolean;
newVisits: number;
}
@Injectable()
export class UserActivityService {
private getRandom = (roundTo: number) => Math.round(Math.random() * roundTo);
data = {};
constructor(private periods: PeriodsService) {
this.data = {
week: this.getDataWeek(),
month: this.getDataMonth(),
year: this.getDataYear(),
};
}
private getDataWeek(): UserActive[] {
return this.periods.getWeeks().map((week) => {
return {
date: week,
pagesVisitCount: this.getRandom(1000),
deltaUp: this.getRandom(1) % 2 === 0,
newVisits: this.getRandom(100),
};
});
}
private getDataMonth(): UserActive[] {
const date = new Date();
const days = date.getDate();
const month = this.periods.getMonths()[date.getMonth()];
return Array.from(Array(days)).map((_, index) => {
return {
date: `${index + 1} ${month}`,
pagesVisitCount: this.getRandom(1000),
deltaUp: this.getRandom(1) % 2 === 0,
newVisits: this.getRandom(100),
};
});
}
private getDataYear(): UserActive[] {
return this.periods.getYears().map((year) => {
return {
date: year,
pagesVisitCount: this.getRandom(1000),
deltaUp: this.getRandom(1) % 2 === 0,
newVisits: this.getRandom(100),
};
});
}
getUserActivityData(period: string): Observable<UserActive[]> {
return observableOf(this.data[period]);
}
}