diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 26434bf..456f43f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -86,6 +86,8 @@ import {ServerPlayerViewer} from "./pages/servers-page/server-player-viewer"; import {MatTabsModule} from "@angular/material/tabs"; import {MatRadioModule} from "@angular/material/radio"; import {UsertimeGraphComponent} from "./pages/internal-components/usertime.graph.component"; +import {VipGraphComponents} from "./pages/internal-components/vip.graph.components"; +import {ConnectionsGraphComponent} from "./pages/internal-components/connections.graph.component"; registerLocaleData(localeRu, "ru") @@ -139,7 +141,9 @@ registerLocaleData(localeRu, "ru") FilesUploader, ServerPlayerViewer, //graph - UsertimeGraphComponent + UsertimeGraphComponent, + VipGraphComponents, + ConnectionsGraphComponent ], imports: [ BrowserModule, diff --git a/src/app/entities/VipGiveMethod.ts b/src/app/entities/VipGiveMethod.ts new file mode 100644 index 0000000..0184ca1 --- /dev/null +++ b/src/app/entities/VipGiveMethod.ts @@ -0,0 +1,10 @@ +export const VipGiveMethod = [ + "Бесплатно", + "Steam", + "Qiwi", + "Админ", + "Убрана", + "Итого",//?????? + "Donation Alerts", + "Промокод" +]; diff --git a/src/app/pages/internal-components/abstract.perperiod.graph.component.ts b/src/app/pages/internal-components/abstract.perperiod.graph.component.ts new file mode 100644 index 0000000..2ebc523 --- /dev/null +++ b/src/app/pages/internal-components/abstract.perperiod.graph.component.ts @@ -0,0 +1,203 @@ +import {Component, OnInit} from "@angular/core"; +import {Chart} from "chart.js/auto"; +import {PerPeriodStatistic} from "../../services/graph.service"; +import {ServerService} from "../../services/server.service"; +import {SearchFilter} from "../../entities/search/SearchFilter"; +import {BaseUtils} from "../../utils/BaseUtils"; + +@Component({ + selector: 'app-abstract-per-period-graph', + template: '' +}) +export abstract class AbstractPerperiodGraphComponent implements OnInit { + protected constructor(protected serverService: ServerService) {} + ngOnInit(): void { + const fill = (res:any) => { + const keys = res.data ? Object.keys(res.data) : []; + for (const key of keys) { + // @ts-ignore + this.serverList.push({name: res.data[key].name, server_id: key}); + } + } + + this.serverService.getServers().subscribe( + (res) => { + fill(res); + } + ) + } + settingsOfChart: { + chart: Chart|null + period: 'day' | 'month' | 'year', + loading: boolean + } = { + chart: null, + period: "day", + loading: false + }; + + serverList: {name: string, server_id: string }[] = []; + + public getServerName(server_id: string|null) { + try { + // @ts-ignore + return this.serverList.filter(s => s.server_id == server_id).pop().name; + } catch (e) { + return "Неизвестно"; + } + } + + public getSearchFilter(steam64:string|null): SearchFilter { + const filter: SearchFilter = new SearchFilter(); + if (steam64) + filter.addAccountToSearch(steam64); + let endDate = new Date(); + endDate.setUTCHours(23, 59, 59); + filter.addEndTimeToSearch(endDate.getTime()); + switch (this.settingsOfChart.period) { + case "day": { + endDate.setDate(endDate.getDate() - 30); + break; + } + case "month": { + endDate.setDate(endDate.getDate() - 365); + break; + } + case "year": { + endDate.setDate(endDate.getDate() - (365*10)); + break; + } + } + filter.addBeginTimeToSearch(endDate); + return filter; + } + + public updateGraph(objs: PerPeriodStatistic[], + canvasName: string, + tooltopFooter:any = null, + text = "", + timeDelimiter:number = -1) { + let chartConfig = {type: 'bar', data: {}, options: { + plugins: { + title: { + display: true, + text: text + }, + tooltip:{ + callbacks: { + footer: tooltopFooter + } + } + }, + responsive: true, + scales: { + x: { + stacked: true, + }, + y: { + stacked: true + } + } + } + }; + let chartData: {labels: string[], datasets: any[]} = { + labels: [],//даты + datasets: [] + /** + * { + * label: 'Dataset 1', + * data: Utils.numbers(NUMBER_CFG), + * backgroundColor: Utils.CHART_COLORS.red, + * }, + */ + }; + let valueOnServer: {[srv_name: string]: number[]} = {} + let srvList: string[] = []; + + let maxValue = 0; + ////// + objs.forEach((obj) => {if (obj.value > maxValue) maxValue = obj.value}) + + console.log(timeDelimiter) + if (timeDelimiter != -1) { + if (maxValue >= 60) { + timeDelimiter = 60; + chartConfig.options.plugins.title.text = "Наиграно минут по серверам"; + } //po minutam + if (maxValue >= 60 * 60) { + timeDelimiter = 60 * 60; + chartConfig.options.plugins.title.text = "Наиграно часов по серверам"; + } //po chasam + if (maxValue >= 60 * 60 * 24) { + timeDelimiter = 60 * 60 * 24; + chartConfig.options.plugins.title.text = "Наиграно дней по серверам"; + }//po dnyam + + const tooltipFooterInternal = (items:any) => { //todo remove + return "Наиграно: " + BaseUtils.formatSeconds(items.pop().parsed.y * timeDelimiter); + }; + chartConfig.options.plugins.tooltip.callbacks.footer = tooltipFooterInternal; + } + console.log(timeDelimiter) + + const groupByDate = objs.reduce((acc: {[date: string]: PerPeriodStatistic[]}, obj) => { + const key = obj.date; + if (!acc[key]) acc[key] = []; + acc[key].push(obj) + return acc; + }, {}); + chartData.labels = Object.keys(groupByDate); + //console.log(groupByDate); + + chartData.labels.forEach( + (date) => { + groupByDate[date].forEach((stat) => { + if (srvList.indexOf(stat.srv_id) == -1) + srvList.push(stat.srv_id) + }) + } + ); + //console.log(srvList) + srvList.forEach((srv) => { + valueOnServer[srv] = []; + }); + chartData.labels.forEach( + (date) => { + let filled: string[] = []; + groupByDate[date].forEach( + (obj) => { + if (timeDelimiter == -1) { + valueOnServer[obj.srv_id].push(obj.value); + } else { + valueOnServer[obj.srv_id].push(obj.value / timeDelimiter); + } + filled.push(obj.srv_id); + } + ) + srvList.forEach( + (srv) => { + if (filled.indexOf(srv) == -1) { + valueOnServer[srv].push(0); + } + } + ) + }, + ) + //console.log(valueOnServer) + Object.keys(valueOnServer).forEach( + (key) => { + chartData.datasets.push( + {label: this.getServerName(key) + " ("+key+")", data: valueOnServer[key]} + ) + } + ) + /// + chartConfig.data = chartData; + + if (this.settingsOfChart.chart) + this.settingsOfChart.chart.destroy(); + // @ts-ignore + this.settingsOfChart.chart = new Chart(canvasName, chartConfig); + this.settingsOfChart.loading = false; + } +} diff --git a/src/app/pages/internal-components/connections.graph.component.ts b/src/app/pages/internal-components/connections.graph.component.ts new file mode 100644 index 0000000..03b5cc4 --- /dev/null +++ b/src/app/pages/internal-components/connections.graph.component.ts @@ -0,0 +1,66 @@ +import {Component, Input} from "@angular/core"; +import {AbstractPerperiodGraphComponent} from "./abstract.perperiod.graph.component"; +import {ServerService} from "../../services/server.service"; +import {GraphService} from "../../services/graph.service"; +import {MatSnackBar} from "@angular/material/snack-bar"; +import {BaseUtils} from "../../utils/BaseUtils"; + +@Component({ + selector: "app-connections-graph", + template: ` +
+ + За месяц + За год + За 10 лет + +
+
+ {{ settingsOfChart.chart }} +
` +}) +export class ConnectionsGraphComponent extends AbstractPerperiodGraphComponent { + + @Input("steam64") + steam64: string|null = null; + + tooltipFooter = (items:any) => { + return `Подключений: ${items.pop().parsed.y}` + }; + + constructor(protected override serverService: ServerService, + private graphService: GraphService, + private snack: MatSnackBar) { + super(serverService); + } + + connectionsTabChanged(event: any, tabIndex: number) { + if (event.index == tabIndex) { + this.updateConnectionsGraph(); + } + } + + updateConnectionsGraph() { + if (this.steam64 || true) { + if (this.settingsOfChart.loading) return; + this.settingsOfChart.loading = true; + this.graphService.getConnectionsOnPeriod(this.getSearchFilter(this.steam64)).subscribe( + (objs) => { + this.updateGraph(objs, "connectionsCanvasChart", + this.tooltipFooter, + "Количество уникальных игроков по серверам (уникальность, первый заход на любой из серверов, сыграл более 5 минут,Ï последующие не учитываются)", + -1); + }, (err) => { + this.settingsOfChart.loading = false; + this.snack.open("Ошибка загрузка графика"); + } + ); + } else { + this.snack.open("Нельзя загрузить график т.к нельзя определить индификатор профиля"); + } + } +} diff --git a/src/app/pages/internal-components/usertime.graph.component.ts b/src/app/pages/internal-components/usertime.graph.component.ts index b3929e1..1d91119 100644 --- a/src/app/pages/internal-components/usertime.graph.component.ts +++ b/src/app/pages/internal-components/usertime.graph.component.ts @@ -1,10 +1,9 @@ -import {AfterViewInit, Component, Input, OnInit} from "@angular/core"; -import {SearchFilter} from "../../entities/search/SearchFilter"; -import {GraphService, PerPeriodStatistic} from "../../services/graph.service"; -import {Chart} from "chart.js/auto"; +import {Component, Input} from "@angular/core"; +import {GraphService} from "../../services/graph.service"; import {MatSnackBar} from "@angular/material/snack-bar"; import {ServerService} from "../../services/server.service"; import {BaseUtils} from "../../utils/BaseUtils"; +import {AbstractPerperiodGraphComponent} from "./abstract.perperiod.graph.component"; @Component({ selector: "app-usertime-graph", @@ -12,8 +11,8 @@ import {BaseUtils} from "../../utils/BaseUtils";
За месяц За год @@ -21,203 +20,45 @@ import {BaseUtils} from "../../utils/BaseUtils";
- {{ usertimeChart.chart }} + {{ settingsOfChart.chart }}
` }) -export class UsertimeGraphComponent implements OnInit { - - usertimeChart: { - chart: Chart|null - period: 'day' | 'month' | 'year', - loading: boolean - } = { - chart: null, - period: "day", - loading: false - }; +export class UsertimeGraphComponent extends AbstractPerperiodGraphComponent { @Input("steam64") steam64: string|null = null; - serverList: {name: string, server_id: string }[] = []; timeDelimiter: number = 1; - tooltipFooter = (items:any) => { + tooltipFooter = (items:any) => { //todo remove return "Наиграно: " + BaseUtils.formatSeconds(items.pop().parsed.y * this.timeDelimiter); }; - constructor(protected serverService: ServerService, + constructor(protected override serverService: ServerService, private graphService: GraphService, private snack: MatSnackBar) { + super(serverService); } - ngOnInit(): void { - const fill = (res:any) => { - const keys = res.data ? Object.keys(res.data) : []; - for (const key of keys) { - // @ts-ignore - this.serverList.push({name: res.data[key].name, server_id: key}); - } - } - - this.serverService.getServers().subscribe( - (res) => { - fill(res); - } - ) - } - - getServerName(server_id: string|null) { - try { - // @ts-ignore - return this.serverList.filter(s => s.server_id == server_id).pop().name; - } catch (e) { - return "Неизвестно"; - } - } - - usertimeTabChanged(event: any) { - if (event.index == 1) { + usertimeTabChanged(event: any, tabIndex: number) { + if (event.index == tabIndex) { this.updateUsertimeGraph() } } updateUsertimeGraph() { if (this.steam64 || true) { - if (this.usertimeChart.loading) return; - this.usertimeChart.loading = true; - - const filter: SearchFilter = new SearchFilter(); - if (this.steam64) - filter.addAccountToSearch(this.steam64); - let endDate = new Date(); - endDate.setUTCHours(23, 59, 59); - filter.addEndTimeToSearch(endDate.getTime()); - switch (this.usertimeChart.period) { - case "day": { - endDate.setDate(endDate.getDate() - 30); - break; - } - case "month": { - endDate.setDate(endDate.getDate() - 365); - break; - } - case "year": { - endDate.setDate(endDate.getDate() - (365*10)); - break; - } - } - filter.addBeginTimeToSearch(endDate); - let chartConfig = {type: 'bar', data: {}, options: { - plugins: { - title: { - display: true, - text: "Наиграно секунд по серверам" - }, - tooltip:{ - callbacks: { - footer: this.tooltipFooter - } - } - }, - responsive: true, - scales: { - x: { - stacked: true, - }, - y: { - stacked: true - } - } - } - }; - let chartData: {labels: string[], datasets: any[]} = { - labels: [],//даты - datasets: [] - /** - * { - * label: 'Dataset 1', - * data: Utils.numbers(NUMBER_CFG), - * backgroundColor: Utils.CHART_COLORS.red, - * }, - */ - }; - let valueOnServer: {[srv_name: string]: number[]} = {} - let srvList: string[] = []; - - let maxValue = 0; - - this.graphService.getUsertimeOnPeriod(filter).subscribe( + if (this.settingsOfChart.loading) return; + this.settingsOfChart.loading = true; + this.graphService.getUsertimeOnPeriod(this.getSearchFilter(this.steam64)).subscribe( (objs) => { - objs.forEach((obj) => {if (obj.value > maxValue) maxValue = obj.value}) - if (maxValue >= 60) { - this.timeDelimiter = 60; - chartConfig.options.plugins.title.text = "Наиграно минут по серверам"; - } //po minutam - if (maxValue >= 60 * 60) { - this.timeDelimiter = 60 * 60; - chartConfig.options.plugins.title.text = "Наиграно часов по серверам"; - } //po chasam - if (maxValue >= 60 * 60 * 24) { - this.timeDelimiter = 60 * 60 * 24; - chartConfig.options.plugins.title.text = "Наиграно дней по серверам"; - }//po dnyam - - const groupByDate = objs.reduce((acc: {[date: string]: PerPeriodStatistic[]}, obj) => { - const key = obj.date; - if (!acc[key]) acc[key] = []; - acc[key].push(obj) - return acc; - }, {}); - chartData.labels = Object.keys(groupByDate); - //console.log(groupByDate); - - chartData.labels.forEach( - (date) => { - groupByDate[date].forEach((stat) => { - if (srvList.indexOf(stat.srv_id) == -1) - srvList.push(stat.srv_id) - }) - } - ); - //console.log(srvList) - srvList.forEach((srv) => { - valueOnServer[srv] = []; - }); - chartData.labels.forEach( - (date) => { - let filled: string[] = []; - groupByDate[date].forEach( - (obj) => { - valueOnServer[obj.srv_id].push(obj.value / this.timeDelimiter) - filled.push(obj.srv_id); - } - ) - srvList.forEach( - (srv) => { - if (filled.indexOf(srv) == -1) { - valueOnServer[srv].push(0); - } - } - ) - }, - ) - //console.log(valueOnServer) - Object.keys(valueOnServer).forEach( - (key) => { - chartData.datasets.push( - {label: this.getServerName(key) + " ("+key+")", data: valueOnServer[key]} - ) - } - ) - /// - chartConfig.data = chartData; - - if (this.usertimeChart.chart) - this.usertimeChart.chart.destroy(); - // @ts-ignore - this.usertimeChart.chart = new Chart('usertimeChart', chartConfig); - this.usertimeChart.loading = false; - }, (err) => {this.usertimeChart.loading = false; this.snack.open("Ошибка загрузка графика")} + this.updateGraph(objs, "usertimeCanvasChart", + this.tooltipFooter, + "Наиграно секунд по серверам", + this.timeDelimiter); + }, (err) => { + this.settingsOfChart.loading = false; + this.snack.open("Ошибка загрузка графика"); + } ); } else { this.snack.open("Нельзя загрузить график т.к нельзя определить индификатор профиля"); diff --git a/src/app/pages/internal-components/vip.graph.components.ts b/src/app/pages/internal-components/vip.graph.components.ts new file mode 100644 index 0000000..bb40bb0 --- /dev/null +++ b/src/app/pages/internal-components/vip.graph.components.ts @@ -0,0 +1,210 @@ +import {Component, Input, OnInit} from "@angular/core"; +import {Chart} from "chart.js/auto"; +import {SearchFilter} from "../../entities/search/SearchFilter"; +import {GraphService, PerPeriodStatistic, VipPerPeriodStatistic} from "../../services/graph.service"; +import {MatSnackBar} from "@angular/material/snack-bar"; +import {VipGiveMethod} from "../../entities/VipGiveMethod"; +import {BaseUtils} from "../../utils/BaseUtils"; + +@Component({ + selector: 'app-vip-graph', + template: ` +
+ + За месяц + За год + За 10 лет + + Не учитывать нестандартное время +
+
+ +
+ ` +}) +export class VipGraphComponents implements OnInit { + chartConfig: { + chart: Chart|null, + period: 'day' | 'month' | 'year', + loading: boolean + } = { + chart: null, + period: 'day', + loading: false + } + + @Input("steam64") + steam64: string|null = null; + objs: VipPerPeriodStatistic[] = []; + + removeNotStandartValue: boolean = true; + standartPeriods: number[] = [86400, 86400*7, 86400*30, 86400*31]; + + constructor(private graphService: GraphService, + private snack: MatSnackBar) { + } + + ngOnInit(): void { + //nothing here + } + + tabChangedTrigger(event: any, tabIndex: number) { + if (event.index == tabIndex) { + this.updateGraph() + } + } + + updateGraph() { + if (this.chartConfig.loading) return; + this.chartConfig.loading = true; + + const filter: SearchFilter = new SearchFilter(); + if (this.steam64) + filter.addAccountToSearch(this.steam64) + + let endDate = new Date(); + endDate.setUTCHours(23, 59, 59); + filter.addEndTimeToSearch(endDate.getTime()); + switch (this.chartConfig.period) { + case "day": { + endDate.setDate(endDate.getDate() - 30); + break; + } + case "month": { + endDate.setDate(endDate.getDate() - 365); + break; + } + case "year": { + endDate.setDate(endDate.getDate() - (365*10)); + break; + } + } + filter.addBeginTimeToSearch(endDate); + + this.graphService.getGivedVipOnPeriod(filter).subscribe( + (objs) => { + this.objs = objs; + this.processGraph(); + this.chartConfig.loading = false; + }, (err) => {this.chartConfig.loading = false; this.snack.open("Ошибка загрузка графика")} + ) + } + + /** + * Обертка над рендер графом чтобы брать данные которые есть в переменоой обж + */ + processGraph() { + this.renderGraph(this.objs); + } + + private renderGraph(objs: VipPerPeriodStatistic[]): void { + let chartConfig = { + type: 'bar', data: {}, options: { + plugins: { + title: { + display: false, + text: "ggggg" + } + }, + responsive: true, + interaction: { + intersect: false + }, + scales: { + x: { + stacked: true, + }, + y: { + stacked: true, + } + } + } + } + + let chartData: {labels: string[], datasets: any[]} = { + labels: [], + datasets: [] + } + + if (this.removeNotStandartValue) { + objs = objs.filter(value => this.standartPeriods.indexOf(value.amount) != -1) + } + + const groupByDate = objs.reduce((acc: {[date: string]: VipPerPeriodStatistic[]}, obj) => { + const key = obj.date; + if (!acc[key]) acc[key] = []; + acc[key].push(obj) + return acc; + }, {}); + + let existsAmount: number[] = []; + let existsGiveMethod: number[] = [] + objs.forEach((obj) => { + if (existsAmount.indexOf(obj.amount) == -1) { + existsAmount.push(obj.amount); + } + if (existsGiveMethod.indexOf(obj.givemethod) == -1) { + existsGiveMethod.push(obj.givemethod); + } + }) + + let datasets:{[str: string]: number[]} = {}; + existsAmount.forEach((ea) => { + existsGiveMethod.forEach((egm) => { + datasets[`${ea}-${egm}`] = []; + }) + }) + + chartData.labels = Object.keys(groupByDate); + //stack это количетсво выданного времени + chartData.labels.forEach( + (date) => { + let foundAmountsAndGiveMethods: string[] = []; + groupByDate[date].forEach((data) => { + const key = `${data.amount}-${data.givemethod}`; + datasets[key].push(data.value); + foundAmountsAndGiveMethods.push(key); + }); + Object.keys(datasets).forEach(//заполняем 0 пропуски + (key) => { + if (foundAmountsAndGiveMethods.indexOf(key) == -1) { + datasets[key].push(0) + } + } + ) + }); + + const humanGiveMethod = (num: any) => { + try { + return VipGiveMethod[Number.parseInt(num)]; + } catch (e) { + return "Неизвестно" + } + } + + chartData.datasets = Object.keys(datasets) + .map((key) => { + const stack = key.split("-")[0];//amount + const label = key.split("-")[1];//givemethod + return { + label: humanGiveMethod(label) + " на " + BaseUtils.formatSeconds(Number.parseInt(stack)), + data: datasets[key], + stack: stack, + skipNull: true, + } + }) + + chartConfig.data = chartData; + //console.log(chartData); + + if (this.chartConfig.chart) + this.chartConfig.chart.destroy(); + + // @ts-ignore + this.chartConfig.chart = new Chart('vipChart', chartConfig); + } +} diff --git a/src/app/pages/main-page/main-page.component.html b/src/app/pages/main-page/main-page.component.html index 602a81f..1da59ff 100644 --- a/src/app/pages/main-page/main-page.component.html +++ b/src/app/pages/main-page/main-page.component.html @@ -76,4 +76,11 @@ - + + diff --git a/src/app/pages/main-page/main-page.component.ts b/src/app/pages/main-page/main-page.component.ts index c29820e..06c5e4d 100644 --- a/src/app/pages/main-page/main-page.component.ts +++ b/src/app/pages/main-page/main-page.component.ts @@ -85,4 +85,8 @@ export class MainPageComponent implements OnInit { () => this.loading = false ) } + + getYear():number { + return new Date().getFullYear(); + } } diff --git a/src/app/pages/profile-page/profile-page.component.html b/src/app/pages/profile-page/profile-page.component.html index 55be0a2..0319ce4 100644 --- a/src/app/pages/profile-page/profile-page.component.html +++ b/src/app/pages/profile-page/profile-page.component.html @@ -109,12 +109,12 @@ Наиграно времени - + -

{{gametime.key}} - {{gametime.value | ValueServerMapDate:false}} секунд

+

{{gametime.key}} - {{gametime.value | ValueServerMapDate:false}}

@@ -139,8 +139,15 @@ История получения VIP - - + + + + + + + + + diff --git a/src/app/pages/profile-page/profile-page.component.scss b/src/app/pages/profile-page/profile-page.component.scss index 0271c8e..6f73c3d 100644 --- a/src/app/pages/profile-page/profile-page.component.scss +++ b/src/app/pages/profile-page/profile-page.component.scss @@ -1,3 +1,7 @@ p { margin: 0 0; } + +::ng-deep .mat-tab-body-content { + overflow: unset !important; +} diff --git a/src/app/pages/profile-page/profile-page.component.ts b/src/app/pages/profile-page/profile-page.component.ts index 8421ba3..fe844a7 100644 --- a/src/app/pages/profile-page/profile-page.component.ts +++ b/src/app/pages/profile-page/profile-page.component.ts @@ -12,6 +12,7 @@ import {GraphService, PerPeriodStatistic} from "../../services/graph.service"; import {SearchFilter} from "../../entities/search/SearchFilter"; import _default from "chart.js/dist/plugins/plugin.legend"; import labels = _default.defaults.labels; +import {BaseUtils} from "../../utils/BaseUtils"; @Component({ selector: 'app-profile-page', @@ -116,7 +117,7 @@ export class ValueServerMapDatePipe implements PipeTransform { transform(value: {[name: string]: number}, createDate: boolean = true, delimiter: string = " - "): any { const keys = Object.keys(value); - return `${this.mapCleaner(keys[0])}${delimiter}${createDate?(new Date(value[keys[0]]*1000)).toLocaleString():value[keys[0]]}`; + return `${this.mapCleaner(keys[0])}${delimiter}${createDate?(new Date(value[keys[0]]*1000)).toLocaleString():BaseUtils.formatSeconds(value[keys[0]])}`; } } diff --git a/src/app/pages/servers-page/servers-page.component.html b/src/app/pages/servers-page/servers-page.component.html index 066b50a..dfd42fa 100644 --- a/src/app/pages/servers-page/servers-page.component.html +++ b/src/app/pages/servers-page/servers-page.component.html @@ -162,7 +162,11 @@ - + + + + +
diff --git a/src/app/pages/servers-page/servers-page.component.ts b/src/app/pages/servers-page/servers-page.component.ts index b78bb65..eefcbe0 100644 --- a/src/app/pages/servers-page/servers-page.component.ts +++ b/src/app/pages/servers-page/servers-page.component.ts @@ -14,6 +14,7 @@ import {Period} from "../statistic-page/statistic-page.component"; import {GraphService} from "../../services/graph.service"; import {ServerService} from "../../services/server.service"; import {UsertimeGraphComponent} from "../internal-components/usertime.graph.component"; +import {ConnectionsGraphComponent} from "../internal-components/connections.graph.component"; @Component({ selector: 'app-servers-page', @@ -36,6 +37,9 @@ export class ServersPageComponent implements OnInit { @ViewChild("usertimeGraphComponent") usertimeGraphComponent!: UsertimeGraphComponent; + @ViewChild("connectionsGraphComponent") + connectionsGraphComponent!: ConnectionsGraphComponent; + periods:Period[] = [ {name: 'По дням', value: 'days'}, {name: 'По минутам', value: 'minutes'} @@ -170,6 +174,10 @@ export class ServersPageComponent implements OnInit { this.usertimeGraphComponent.updateUsertimeGraph(); break; } + case 3: { + this.connectionsGraphComponent.updateConnectionsGraph(); + break; + } default: { break; } diff --git a/src/app/pages/statistic-page/statistic-page.component.html b/src/app/pages/statistic-page/statistic-page.component.html index 7c175a1..ebf125f 100644 --- a/src/app/pages/statistic-page/statistic-page.component.html +++ b/src/app/pages/statistic-page/statistic-page.component.html @@ -1,24 +1,27 @@

Уникальные игроки

-

За "уникальность" берется игрок который зашел за данный период первый раз и поиграл более 5 минут

-
- - {{uniq.day}} - игроков за день - - - {{uniq.month}} - игроков за месяц - - - {{uniq.year}} - игроков за год - - - {{uniq.total}} - игроков за всё время - +

Подробная статистика находиться на странице серверов в закладке "Количество подключений"

+

Мы патриоты, но уважаем и другие народы, смотрите сколько их понабежало к нам с начала года, но не все выдержали РУССКОЙ БАЗЫ в течении 5 минут. Ну или кто-то умеет пользоваться сервисами обходов блокировок

diff --git a/src/app/pages/vip-page/vip-page.component.html b/src/app/pages/vip-page/vip-page.component.html index f20af6b..0e136e1 100644 --- a/src/app/pages/vip-page/vip-page.component.html +++ b/src/app/pages/vip-page/vip-page.component.html @@ -64,10 +64,14 @@
-

Последние выданые випки

-
- -
+ + + + + + + +
diff --git a/src/app/pages/vip-page/vip-page.component.scss b/src/app/pages/vip-page/vip-page.component.scss index e69de29..05571b3 100644 --- a/src/app/pages/vip-page/vip-page.component.scss +++ b/src/app/pages/vip-page/vip-page.component.scss @@ -0,0 +1,3 @@ +::ng-deep .mat-tab-body-content { + overflow: unset !important; +} diff --git a/src/app/pages/vip-page/vip-page.component.ts b/src/app/pages/vip-page/vip-page.component.ts index 2a6cf56..c81a8f1 100644 --- a/src/app/pages/vip-page/vip-page.component.ts +++ b/src/app/pages/vip-page/vip-page.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import {Component, OnInit, ViewChild} from '@angular/core'; import {VipService} from "../../services/vip.service"; import {VipBuy} from "../../entities/VipBuy"; import {MatDialog, MatDialogConfig, MatDialogRef} from "@angular/material/dialog"; @@ -6,6 +6,7 @@ import {VipBuyDialog} from "./VipBuyDialog"; import {VipFreeDialog} from "./VipFreeDialog"; import {VipPromocodeDialog} from "./VipPromocodeDialog"; import {AuthService} from "../../services/auth.service"; +import {VipGraphComponents} from "../internal-components/vip.graph.components"; @Component({ selector: 'app-vip-page', @@ -35,6 +36,9 @@ export class VipPageComponent implements OnInit { {name: 'Здоровье', about: 'Постоянно убивают? Так увеличь себе здоровье через !sethealth 99999 или через пункт в меню'}, ]; + @ViewChild("vipGraphComponent") + vipGraphComponent!:VipGraphComponents + constructor(private vipService: VipService, private dialog: MatDialog, public authService: AuthService) { } @@ -62,4 +66,18 @@ export class VipPageComponent implements OnInit { return null; } + onTabChanged(event:any) { + switch (event.index) { + case 0: { + break; + } + case 1: { + this.vipGraphComponent.updateGraph(); + break; + } + default: { + break; + } + } + } } diff --git a/src/app/services/graph.service.ts b/src/app/services/graph.service.ts index b2683d7..ca3af8e 100644 --- a/src/app/services/graph.service.ts +++ b/src/app/services/graph.service.ts @@ -11,6 +11,11 @@ export interface PerPeriodStatistic { date: string; } +export interface VipPerPeriodStatistic extends PerPeriodStatistic { + givemethod: number; + amount: number; +} + @Injectable({ providedIn: 'root' }) @@ -30,4 +35,14 @@ export class GraphService { // @ts-ignore return this.http.post(`api/profile/usertime/graph`, filter); } + + public getConnectionsOnPeriod(filter: SearchFilter): Observable { + // @ts-ignore + return this.http.post(`api/profile/usertime/connections/graph`, filter); + } + + public getGivedVipOnPeriod(filter: SearchFilter): Observable { + // @ts-ignore + return this.http.post(`api/web/vip/graph`, filter); + } } diff --git a/src/app/utils/BaseUtils.ts b/src/app/utils/BaseUtils.ts index f89ee1e..151756a 100644 --- a/src/app/utils/BaseUtils.ts +++ b/src/app/utils/BaseUtils.ts @@ -45,6 +45,9 @@ export class BaseUtils { } } - return `${days} ${dayWord} ${timePart}`.split(".")[0]; + if (timePart == '00:00:00') + return `${days} ${dayWord}`; + else + return `${days} ${dayWord} ${timePart}`.split(".")[0]; } }