From 2ffc328822a4e5f2331fc818caff66a85088609b Mon Sep 17 00:00:00 2001 From: FaizanMohammed326 Date: Wed, 13 Sep 2023 13:08:19 +0530 Subject: [PATCH] added trendline chart to telemetry --- .../telemetry/config/telemetry_config.ts | 103 ++++++- ...try-active-users-big-number.component.html | 1 + ...try-active-users-big-number.component.scss | 0 ...-active-users-big-number.component.spec.ts | 23 ++ ...metry-active-users-big-number.component.ts | 158 ++++++++++ ...etry-active-users-trendline.component.html | 1 + ...etry-active-users-trendline.component.scss | 0 ...y-active-users-trendline.component.spec.ts | 23 ++ ...emetry-active-users-trendline.component.ts | 283 ++++++++++++++++++ .../telemetry-tab.component.html | 19 +- .../telemetry-tab/telemetry-tab.component.ts | 242 ++++++++------- src/app/views/telemetry/telemetry.module.ts | 6 +- 12 files changed, 730 insertions(+), 129 deletions(-) create mode 100644 src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.html create mode 100644 src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.scss create mode 100644 src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.spec.ts create mode 100644 src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.ts create mode 100644 src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.html create mode 100644 src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.scss create mode 100644 src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.spec.ts create mode 100644 src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.ts diff --git a/src/app/views/telemetry/config/telemetry_config.ts b/src/app/views/telemetry/config/telemetry_config.ts index 41396f34..d610e397 100644 --- a/src/app/views/telemetry/config/telemetry_config.ts +++ b/src/app/views/telemetry/config/telemetry_config.ts @@ -17,8 +17,8 @@ export const config = { "hierarchyLevel": "0", "actions": { "queries": { - "bigNumber1": "select count(userid) as daily_user_count from datasets.telemetry_usercount_daily_users where date = current_date", - "bigNumber2": "select count(userid) as weekly_user_count from datasets.telemetry_usercount_daily_users where date between current_date - interval '7 days' and current_date " + "bigNumber1": "select count(distinct userid) as daily_user_count from datasets.telemetry_usercount_daily_users where date = current_date", + "bigNumber2": "select count(distinct userid) as weekly_user_count from datasets.telemetry_usercount_daily_users where date between current_date - interval '7 days' and current_date " }, "level": "state" } @@ -30,8 +30,8 @@ export const config = { "hierarchyLevel": "1", "actions": { "queries": { - "bigNumber1": "select count(userid) as daily_user_count from datasets.telemetry_usercount_daily_users where date = current_date", - "bigNumber2": "select count(userid) as weekly_user_count from datasets.telemetry_usercount_daily_users where date between current_date - interval '7 days' and current_date " + "bigNumber1": "select count(distinct userid) as daily_user_count from datasets.telemetry_usercount_daily_users where date = current_date", + "bigNumber2": "select count(distinct userid) as weekly_user_count from datasets.telemetry_usercount_daily_users where date between current_date - interval '7 days' and current_date " }, "level": "district" } @@ -54,7 +54,7 @@ export const config = { "hierarchyLevel": "0", "actions": { "queries": { - "barChart": "select count(userid) as user_count, browsername from datasets.telemetry_browserscount_zgr6vhegehrjbhb__cx0s where date between startDate and endDate group by browsername", + "barChart": "select count(distinct userid) as user_count, browsername from datasets.telemetry_browserscount_zgr6vhegehrjbhb__cx0s where date between startDate and endDate group by browsername", }, "level": "district" } @@ -64,7 +64,7 @@ export const config = { "hierarchyLevel": "1", "actions": { "queries": { - "barChart": "select count(userid) as user_count, browsername from datasets.telemetry_browserscount_zgr6vhegehrjbhb__cx0s where date between startDate and endDate group by browsername", + "barChart": "select count(distinct userid) as user_count, browsername from datasets.telemetry_browserscount_zgr6vhegehrjbhb__cx0s where date between startDate and endDate group by browsername", }, "level": "district" } @@ -95,7 +95,7 @@ export const config = { "hierarchyLevel": "0", "actions": { "queries": { - "barChart": "select count(userid) as user_count, devicename from datasets.telemetry_devicescount_ynndeshvzvtuxwh6dzyw where date between startDate and endDate group by devicename", + "barChart": "select count(distinct userid) as user_count, devicename from datasets.telemetry_devicescount_ynndeshvzvtuxwh6dzyw where date between startDate and endDate group by devicename", }, "level": "district" } @@ -105,7 +105,7 @@ export const config = { "hierarchyLevel": "1", "actions": { "queries": { - "barChart": "select count(userid) as user_count, devicename from datasets.telemetry_devicescount_ynndeshvzvtuxwh6dzyw where date between startDate and endDate group by devicename", + "barChart": "select count(distinct userid) as user_count, devicename from datasets.telemetry_devicescount_ynndeshvzvtuxwh6dzyw where date between startDate and endDate group by devicename", }, "level": "district" } @@ -195,5 +195,90 @@ export const config = { } } }, - + active_users_trendline: { + "label": "Telemetry", + "defaultLevel": "state", + "filters": [ + { + "name": "National", + "hierarchyLevel": "0", + "timeSeriesQueries": { + "table": "select count(distinct userid) as user_count, date from datasets.telemetry_usercount_daily_users where date between startDate and endDate group by date order by date" + }, + "actions": { + "queries": { + "table": "select count(distinct userid) as user_count, date from datasets.telemetry_usercount_daily_users where date between startDate and endDate group by date order by date" + }, + "level": "school" + } + }, + { + "name": "State", + "hierarchyLevel": "1", + "timeSeriesQueries": { + "table": "select count(distinct userid) as user_count, date from datasets.telemetry_usercount_daily_users where date between startDate and endDate group by date order by date" + }, + "actions": { + "queries": { + "table": "select count(distinct userid) as user_count, date from datasets.telemetry_usercount_daily_users where date between startDate and endDate group by date order by date" + }, + "level": "school" + } + } + ], + "options": { + "table": { + "columns": [ + { + name: "date", + property: "date", + class: "text-center" + }, + { + name: "avarage", + property: "user_count", + class: "text-center", + } + ], + } + } + }, + active_users_bignumber: { + "label": "Average Teachers Present", + "filters": [ + { + "name": "National", + "hierarchyLevel": "0", + "timeSeriesQueries": { + "bigNumber": "select count(distinct userid) as user_count from datasets.telemetry_usercount_daily_users where date between startDate and endDate", + }, + "actions": { + "queries": { + "bigNumber": "select count(distinct userid) as user_count from datasets.telemetry_usercount_daily_users where date between startDate and endDate", + }, + "level": "state" + } + }, + { + "name": "State", + "hierarchyLevel": "1", + "timeSeriesQueries": { + "bigNumber": "select count(distinct userid) as user_count from datasets.telemetry_usercount_daily_users where date between startDate and endDate", + }, + "actions": { + "queries": { + "bigNumber": "select count(distinct userid) as user_count from datasets.telemetry_usercount_daily_users where date between startDate and endDate", + }, + "level": "district" + } + } + ], + "options": { + "bigNumber": { + "title": "Total Active Users", + "valueSuffix": '', + "property": 'user_count' + } + } + }, } \ No newline at end of file diff --git a/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.html b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.html new file mode 100644 index 00000000..48734b65 --- /dev/null +++ b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.scss b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.spec.ts b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.spec.ts new file mode 100644 index 00000000..eb86beef --- /dev/null +++ b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TelemetryActiveUsersBigNumberComponent } from './telemetry-active-users-big-number.component'; + +describe('TelemetryActiveUsersBigNumberComponent', () => { + let component: TelemetryActiveUsersBigNumberComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ TelemetryActiveUsersBigNumberComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TelemetryActiveUsersBigNumberComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.ts b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.ts new file mode 100644 index 00000000..3cbcf868 --- /dev/null +++ b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component.ts @@ -0,0 +1,158 @@ +import { Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { CommonService } from 'src/app/core/services/common/common.service'; +import { RbacService } from 'src/app/core/services/rbac-service.service'; +import { WrapperService } from 'src/app/core/services/wrapper.service'; +import { buildQuery, parseRbacFilter, parseTimeSeriesQuery } from 'src/app/utilities/QueryBuilder'; +import { config } from '../../../../config/telemetry_config'; +import { DataService } from 'src/app/core/services/data.service'; + +@Component({ + selector: 'app-telemetry-active-users-big-number', + templateUrl: './telemetry-active-users-big-number.component.html', + styleUrls: ['./telemetry-active-users-big-number.component.scss'] +}) +export class TelemetryActiveUsersBigNumberComponent implements OnInit, OnDestroy { + + reportName: string = 'active_users_bignumber'; + filters: any = []; + levels: any; + tableReportData: any; + bigNumberReportData: any = { + reportName: "Total Active Users" + }; + currentReportName: string = "Telemetry"; + minDate: any; + maxDate: any; + compareDateRange: any = 30; + filterIndex: any; + rbacDetails: any; + title = 'Total Active Users'; + @Input() startDate: any; + @Input() endDate: any; + drillDownSubscription: any; + drillDownLevel: any; + + + constructor(private readonly _commonService: CommonService, + private _dataService: DataService, + private _rbacService: RbacService, + ) { + + } + ngOnInit(): void { + this.drillDownSubscription = this._rbacService.getRbacDetails().subscribe((rbacDetails: any) => { + this.rbacDetails = rbacDetails; + }) + // this.getReportData(); + } + + getReportData(values): void { + console.log(values) + let { filterValues, timeSeriesValues } = values ?? {}; + + this.startDate = timeSeriesValues?.startDate; + this.endDate = timeSeriesValues?.endDate; + let reportConfig = config + let { timeSeriesQueries, queries, levels, label, defaultLevel, filters, options } = reportConfig[this.reportName]; + let onLoadQuery; + if (this.rbacDetails?.role !== undefined && this.rbacDetails?.role !== null) { + filters.every((filter: any) => { + if (Number(this.rbacDetails?.role) === Number(filter.hierarchyLevel)) { + timeSeriesQueries = { ...filter?.timeSeriesQueries } + Object.keys(timeSeriesQueries).forEach((key) => { + timeSeriesQueries[key] = this.parseRbacFilter(timeSeriesQueries[key]) + }); + return false + } + return true + }) + } + + Object.keys(timeSeriesQueries).forEach(async (key: any) => { + if (key.toLowerCase().includes('comparison')) { + let endDate = new Date(); + let days = endDate.getDate() - this.compareDateRange; + let startDate = new Date(); + startDate.setDate(days) + onLoadQuery = parseTimeSeriesQuery(timeSeriesQueries[key], startDate.toISOString().split('T')[0], endDate.toISOString().split('T')[0]) + } + else if (this.startDate !== undefined && this.endDate !== undefined && Object.keys(timeSeriesQueries).length > 0) { + onLoadQuery = parseTimeSeriesQuery(timeSeriesQueries[key], this.startDate, this.endDate) + } + else { + onLoadQuery = queries[key] + } + let query = buildQuery(onLoadQuery, defaultLevel, this.levels, this.filters, this.startDate, this.endDate, key, this.compareDateRange); + + // if (query && key === 'bigNumber') { + // this.getBigNumberReportData(query, options, 'averagePercentage'); + // } + if (query && key === 'bigNumber') { + this.bigNumberReportData = await this._dataService.getBigNumberReportData(query, options, 'averagePercentage', this.bigNumberReportData); + } + }) + } + + parseRbacFilter(query: string) { + let newQuery = query; + + let startIndex = newQuery?.indexOf('{'); + let endIndex = newQuery?.indexOf('}'); + + while (startIndex > -1 && endIndex > -1) { + if (newQuery && startIndex > -1) { + let propertyName = newQuery.substring(startIndex + 1, endIndex); + let re = new RegExp(`{${propertyName}}`, "g"); + + Object.keys(this.rbacDetails).forEach((key: any) => { + if (propertyName === key + '_id') { + newQuery = newQuery.replace(re, '\'' + this.rbacDetails[key] + '\''); + } + }); + } + startIndex = newQuery?.indexOf('{'); + endIndex = newQuery?.indexOf('}'); + } + return newQuery + } + + // async getBigNumberReportData(query: string, options: any, indicator: string): Promise { + // let { bigNumber } = options ?? {}; + // let { valueSuffix, property } = bigNumber ?? {}; + + // if (indicator === 'averagePercentage') { + // this.bigNumberReportData = { + // ...this.bigNumberReportData, + // valueSuffix: valueSuffix, + + // } + // await this._commonService.getReportDataNew(query).subscribe((res: any) => { + + // if (res) { + // let rows = res; + // this.bigNumberReportData = { + // ...this.bigNumberReportData, + // averagePercentage: rows[0]?.[property] + // } + // } + // }) + // } + // else if (indicator === 'differencePercentage') { + // await this._commonService.getReportDataNew(query).subscribe((res: any) => { + // if (res) { + // let rows = res; + // this.bigNumberReportData = { + // ...this.bigNumberReportData, + // differencePercentage: rows[0]?.[property] + // } + // } + // }) + // } + + // } + + ngOnDestroy(): void { + this.drillDownSubscription.unsubscribe() + } + +} diff --git a/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.html b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.html new file mode 100644 index 00000000..bf3d4b72 --- /dev/null +++ b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.scss b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.spec.ts b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.spec.ts new file mode 100644 index 00000000..a6111675 --- /dev/null +++ b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TelemetryActiveUsersTrendlineComponent } from './telemetry-active-users-trendline.component'; + +describe('TelemetryActiveUsersTrendlineComponent', () => { + let component: TelemetryActiveUsersTrendlineComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ TelemetryActiveUsersTrendlineComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TelemetryActiveUsersTrendlineComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.ts b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.ts new file mode 100644 index 00000000..075ef796 --- /dev/null +++ b/src/app/views/telemetry/pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component.ts @@ -0,0 +1,283 @@ +import Chart from 'chart.js'; +import { ChartDataSets, ChartOptions, ChartType, PluginServiceRegistrationOptions, TimeScale } from 'chart.js'; +import { AfterViewInit, Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { CommonService } from 'src/app/core/services/common/common.service'; +import { RbacService } from 'src/app/core/services/rbac-service.service'; +import { WrapperService } from 'src/app/core/services/wrapper.service'; +import { buildQuery, parseRbacFilter, parseTimeSeriesQuery } from 'src/app/utilities/QueryBuilder'; +import { config } from 'src/app/views/telemetry/config/telemetry_config'; +import _ from "lodash"; + +interface TrendlineChartDataSets extends ChartDataSets { + trendlineLinear?: PluginServiceRegistrationOptions; +} +var chart; + +@Component({ + selector: 'app-telemetry-active-users-trendline', + templateUrl: './telemetry-active-users-trendline.component.html', + styleUrls: ['./telemetry-active-users-trendline.component.scss'] +}) +export class TelemetryActiveUsersTrendlineComponent implements OnInit, OnDestroy { + reportName: string = 'active_users_trendline'; + filters: any = []; + levels: any; + tableReportData: any; + minDate: any; + maxDate: any; + compareDateRange: any = 30; + filterIndex: any; + rbacDetails: any; + title: any = "Daily Active Users" + drillDownSubscription: any; + + + @Output() exportDates = new EventEmitter(); + @Input() startDate: any; + @Input() endDate: any; + @Input() chartConfig: any = {}; + constructor(private readonly _commonService: CommonService, + private readonly _wrapperService: WrapperService, private _rbacService: RbacService) { + this._rbacService.getRbacDetails().subscribe((rbacDetails: any) => { + this.rbacDetails = rbacDetails; + }) + } + + ngOnInit() { + // this.generateChart(); + } + + getReportData(values): void { + let { filterValues, timeSeriesValues } = values ?? {}; + + this.startDate = timeSeriesValues?.startDate; + this.endDate = timeSeriesValues?.endDate; + let reportConfig = config + + let { timeSeriesQueries, queries, levels, label, defaultLevel, filters, options } = reportConfig[this.reportName]; + let onLoadQuery; + if (this.rbacDetails?.role !== undefined && this.rbacDetails?.role !== null) { + filters.every((filter: any) => { + if (Number(this.rbacDetails?.role) === Number(filter.hierarchyLevel)) { + queries = { ...filter?.actions?.queries } + timeSeriesQueries = { ...filter?.timeSeriesQueries } + Object.keys(queries).forEach((key) => { + queries[key] = this.parseRbacFilter(queries[key]) + timeSeriesQueries[key] = this.parseRbacFilter(timeSeriesQueries[key]) + }); + return false + } + return true + }) + } + + Object.keys(queries).forEach((key: any) => { + if (key.toLowerCase().includes('comparison')) { + let endDate = new Date(); + let days = endDate.getDate() - this.compareDateRange; + let startDate = new Date(); + startDate.setDate(days) + onLoadQuery = parseTimeSeriesQuery(queries[key], startDate.toISOString().split('T')[0], endDate.toISOString().split('T')[0]) + } + else if (this.startDate !== undefined && this.endDate !== undefined && Object.keys(timeSeriesQueries).length > 0) { + onLoadQuery = parseTimeSeriesQuery(timeSeriesQueries[key], this.startDate, this.endDate) + } + else { + onLoadQuery = queries[key] + } + let query = buildQuery(onLoadQuery, defaultLevel, this.levels, this.filters, this.startDate, this.endDate, key, this.compareDateRange); + + if (query && key === 'table') { + this.getTableReportData(query, options); + } + }) + } + + parseRbacFilter(query: string) { + let newQuery = query; + let startIndex = newQuery?.indexOf('{'); + let endIndex = newQuery?.indexOf('}'); + + if (newQuery && startIndex > -1) { + let propertyName = query.substring(startIndex + 1, endIndex); + let re = new RegExp(`{${propertyName}}`, "g"); + Object.keys(this.rbacDetails).forEach((key: any) => { + if (propertyName === key + '_id') { + newQuery = newQuery.replace(re, '\'' + this.rbacDetails[key] + '\''); + } + }); + } + return newQuery + } + + getTableReportData(query, options): void { + this._commonService.getReportDataNew(query).subscribe((res: any) => { + let rows = res; + let { table: { columns } } = options; + this.tableReportData = { + data: rows.map(row => { + if (this.minDate !== undefined && this.maxDate !== undefined) { + if (row['min_date'] < this.minDate) { + this.minDate = row['min_date'] + } + if (row['max_date'] > this.maxDate) { + this.maxDate = row['max_date'] + } + } + else { + this.minDate = row['min_date'] + this.maxDate = row['max_date'] + } + columns.forEach((col: any) => { + if (row[col.property]) { + row = { + ...row, + [col.property]: { value: row[col.property] } + } + } + }); + return row + }), + columns: columns.filter(col => { + if (rows[0] && col.property in rows[0]) { + return col; + } + }) + } + if (this.tableReportData?.data?.length > 0) { + let reportsData = { + reportData: this.tableReportData.data, + reportType: "table", + reportName: this.title, + }; + this.generateChart(this.tableReportData); + } + else { + let data = null; + this.generateChart(data) + } + }); + } + + updateChart(reportData) { + + var dates = reportData?.data?.map(data => { + const dateValue = new Date(data.date.value); + return dateValue.toLocaleDateString(); + }); + const values = reportData?.data?.map(data => data.user_count.value); + + chart.data.labels = dates; + chart.data.datasets = [ + { + data: [...values, 0, 100], + label: '% Teacher Present', + borderColor: 'green', + fill: true, + lineTension: 0, + }, + ] + chart.update() + + } + + + generateChart(reportData) { + if (chart) { + chart.destroy(); + chart = null; + } + // const dates = reportData?.data?.map(data => moment(data.perc_teachers.value).format('YYYY-MM-DD')); + var dates = reportData?.data?.map(data => { + const dateValue = new Date(data.date.value); + return dateValue.toLocaleDateString(); + }); + const values = reportData?.data?.map(data => data.user_count.value); + const ctx = document.getElementById('trendlineChart') as HTMLCanvasElement; + let defaultOptions = { + type: 'line', + + data: { + labels: dates, + datasets: [ + { + data: [...values], + label: 'Active Users', + borderColor: 'green', + fill: true, + lineTension: 0, + + // backgroundColor: 'rgba(0,255,0,0.3)', + }, + ] + }, + options: { + responsive: true, + title: { + display: true, + text: "Daily Active Users", + fontStyle: "normal", + fontColor: "#333" + }, + hover: { mode: null }, + zoom: { + // Boolean to enable zooming + enabled: false, + // Zooming directions. Remove the appropriate direction to disable + // Eg. 'y' would only allow zooming in the y direction + // mode: 'x', + }, + tooltips: { + callbacks: { + label: function (context) { + const value = context.value + // return `Date: ${date}/n% Teacher Present: ${value}%`; + return 'User Count: ' + value + } + } + }, + scales: { + yAxes: [{ + ticks: { + beginAtZero: true, + callback: (value) => { + if (Number(value) % 1 === 0) { + return value; + } + } + } + }], + x: { + type: 'time', + time: { + unit: 'day' + }, + grid: { + display: false + } as TimeScale + }, + y: { + + suggestedMin: Math.min(...values), + suggestedMax: Math.max(...values), + grid: { + display: false + } + } + } as ChartOptions['scales'], + }, + }; + defaultOptions = _.merge(defaultOptions, this.chartConfig); + + chart = new Chart(ctx, defaultOptions); + } + + ngOnDestroy(): void { + if (chart) { + chart.destroy(); + chart = null; + } + this.drillDownSubscription.unsubscribe() + } +} + diff --git a/src/app/views/telemetry/pages/telemetry-tab/telemetry-tab.component.html b/src/app/views/telemetry/pages/telemetry-tab/telemetry-tab.component.html index 61f367fc..f669e553 100644 --- a/src/app/views/telemetry/pages/telemetry-tab/telemetry-tab.component.html +++ b/src/app/views/telemetry/pages/telemetry-tab/telemetry-tab.component.html @@ -29,7 +29,7 @@ -->
-
+
-
+ + +
+ +
+
-
-
-
diff --git a/src/app/views/telemetry/pages/telemetry-tab/telemetry-tab.component.ts b/src/app/views/telemetry/pages/telemetry-tab/telemetry-tab.component.ts index 14a1cbf3..00c42509 100644 --- a/src/app/views/telemetry/pages/telemetry-tab/telemetry-tab.component.ts +++ b/src/app/views/telemetry/pages/telemetry-tab/telemetry-tab.component.ts @@ -9,123 +9,139 @@ import { DeviceTypeWiseBarChartComponent } from './reports/device-type-wise-bar- import { PopularLandingPagesBarChartComponent } from './reports/popular-landing-pages-bar-chart/popular-landing-pages-bar-chart.component'; import { TimeSpentPerPageBarChartComponent } from './reports/time-spent-per-page-bar-chart/time-spent-per-page-bar-chart.component'; import moment from 'moment'; +import { TelemetryActiveUsersTrendlineComponent } from './reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component'; +import { TelemetryActiveUsersBigNumberComponent } from './reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component'; @Component({ - selector: 'app-telemetry-tab', - templateUrl: './telemetry-tab.component.html', - styleUrls: ['./telemetry-tab.component.scss'] + selector: 'app-telemetry-tab', + templateUrl: './telemetry-tab.component.html', + styleUrls: ['./telemetry-tab.component.scss'] }) export class TelemetryTabComponent implements OnInit { - bigNumberReports: any = {}; - minYear: any; - maxYear: any; - minMonth: any; - maxMonth: any; - academicYear: any = []; - months: any = []; - filters: any; - reportsToBeShown: any = []; - rbacDetails: any; - reportsData: any = []; - startDate: any; - endDate: any; - defaultSelectedDays: any = 7; - hasTimeSeriesFilters: boolean = true; - hasCommonFilters: boolean = false; - tabLabel: any = "telemetry"; - NVSK: boolean = true; - matLabel = 'Telemtery'; - - @ViewChild('telemetryBigNumber') telemetryBigNumber: TelemetryBigNumberComponent; - @ViewChild('browserTypeWiseBarChartComponent') browserTypeWiseBarChartComponent: BrowserTypeWiseBarChartComponent; - @ViewChild('deviceTypeWiseBarChartComponent') deviceTypeWiseBarChartComponent: DeviceTypeWiseBarChartComponent; - @ViewChild('popularLandingPagesBarChartComponent') popularLandingPagesBarChartComponent: PopularLandingPagesBarChartComponent; - @ViewChild('timeSpentPerPageBarChartComponent') timeSpentPerPageBarChartComponent: TimeSpentPerPageBarChartComponent; - - @Input() bigNumberMetrics: any = []; - - constructor(private _wrapperService: WrapperService, private _rbacService: RbacService) { - this._rbacService.getRbacDetails().subscribe((rbacDetails: any) => { - this.rbacDetails = rbacDetails; - }) - if(environment.config === 'VSK') { - this.NVSK = false - } - } - - async ngOnInit(): Promise { - // this.renderReports(); - } - - async ngAfterViewInit(): Promise { - if (this.hasCommonFilters) { - this.filters = await this._wrapperService.constructCommonFilters(config.filters, this.tabLabel); - this.telemetryBigNumber?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); - this.browserTypeWiseBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); - this.deviceTypeWiseBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); - this.popularLandingPagesBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); - this.timeSpentPerPageBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); - - } - - if (this.startDate != undefined && this.endDate != undefined && this.hasTimeSeriesFilters) { - // let endDate = new Date(); - // let days = endDate.getDate() - this.defaultSelectedDays; - // let startDate = new Date(); - // startDate.setDate(days); - let startDate = moment(this.startDate).format('YYYY-MM-DD'); - let endDate = moment(this.endDate).format('YYYY-MM-DD'); - this.browserTypeWiseBarChartComponent?.getReportData({ timeSeriesValues: { startDate: startDate, endDate: endDate } }); - this.deviceTypeWiseBarChartComponent?.getReportData({ timeSeriesValues: { startDate: startDate, endDate: endDate } }); - this.popularLandingPagesBarChartComponent?.getReportData({ timeSeriesValues: { startDate:startDate, endDate:endDate } }); - this.timeSpentPerPageBarChartComponent?.getReportData({ timeSeriesValues: { startDate: startDate, endDate: endDate } }); - } - } - - checkReport(key: string, reportType: string): Boolean { - let reportConfig = config; - let flag = false; - reportConfig[key]?.filters?.forEach((filter: any) => { - if (Number(filter.hierarchyLevel) === Number(this.rbacDetails?.role) && Object.keys(filter?.actions?.queries).includes(reportType)) { - flag = true - } - }) - return flag - } - - csvDownload(csvData: any) { - if (csvData) { - this.reportsData.push(csvData) - } - } - - filtersUpdated(filters: any) { - this.reportsData = []; - this.telemetryBigNumber?.getReportData({ filterValues: filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); - this.browserTypeWiseBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); - this.deviceTypeWiseBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); - this.popularLandingPagesBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); - this.timeSpentPerPageBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); - - } - - timeSeriesUpdated(event: any): void { - this.startDate = moment(event.startDate).format('YYYY-MM-DD'); - this.endDate = moment(event.endDate).format('YYYY-MM-DD'); - if (event?.startDate !== null && event?.endDate !== null) { - console.log(event); - this.reportsData = []; - // this.telemetryBigNumber?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); - this.browserTypeWiseBarChartComponent?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); - this.deviceTypeWiseBarChartComponent?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); - this.popularLandingPagesBarChartComponent?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); - this.timeSpentPerPageBarChartComponent?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); - } - } - - importBigNumberMetrics(bigNumberMetric: any) { - this.bigNumberMetrics[bigNumberMetric.ind] = bigNumberMetric.data - } + bigNumberReports: any = {}; + minYear: any; + maxYear: any; + minMonth: any; + maxMonth: any; + academicYear: any = []; + months: any = []; + filters: any; + reportsToBeShown: any = []; + rbacDetails: any; + reportsData: any = []; + startDate: any; + endDate: any; + defaultSelectedDays: any = 7; + hasTimeSeriesFilters: boolean = true; + hasCommonFilters: boolean = false; + tabLabel: any = "telemetry"; + NVSK: boolean = true; + matLabel = 'Telemtery'; + trendLineConfig = { + options: { + tooltips: { displayColors: false }, + legend: { display: false } + } + }; + + @ViewChild('telemetryBigNumber') telemetryBigNumber: TelemetryBigNumberComponent; + @ViewChild('browserTypeWiseBarChartComponent') browserTypeWiseBarChartComponent: BrowserTypeWiseBarChartComponent; + @ViewChild('deviceTypeWiseBarChartComponent') deviceTypeWiseBarChartComponent: DeviceTypeWiseBarChartComponent; + @ViewChild('popularLandingPagesBarChartComponent') popularLandingPagesBarChartComponent: PopularLandingPagesBarChartComponent; + @ViewChild('timeSpentPerPageBarChartComponent') timeSpentPerPageBarChartComponent: TimeSpentPerPageBarChartComponent; + @ViewChild('activeUsersTrendline') activeUsersTrendline: TelemetryActiveUsersTrendlineComponent; + @ViewChild('activeUsersBignumber') activeUsersBignumber: TelemetryActiveUsersBigNumberComponent; + + @Input() bigNumberMetrics: any = []; + + constructor(private _wrapperService: WrapperService, private _rbacService: RbacService) { + this._rbacService.getRbacDetails().subscribe((rbacDetails: any) => { + this.rbacDetails = rbacDetails; + }) + if (environment.config === 'VSK') { + this.NVSK = false + } + } + + async ngOnInit(): Promise { + // this.renderReports(); + } + + async ngAfterViewInit(): Promise { + if (this.hasCommonFilters) { + this.filters = await this._wrapperService.constructCommonFilters(config.filters, this.tabLabel); + this.telemetryBigNumber?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.browserTypeWiseBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.deviceTypeWiseBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.popularLandingPagesBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.timeSpentPerPageBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.activeUsersTrendline?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.activeUsersBignumber?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + } + + if (this.startDate != undefined && this.endDate != undefined && this.hasTimeSeriesFilters) { + // let endDate = new Date(); + // let days = endDate.getDate() - this.defaultSelectedDays; + // let startDate = new Date(); + // startDate.setDate(days); + let startDate = moment(this.startDate).format('YYYY-MM-DD'); + let endDate = moment(this.endDate).format('YYYY-MM-DD'); + this.browserTypeWiseBarChartComponent?.getReportData({ timeSeriesValues: { startDate: startDate, endDate: endDate } }); + this.deviceTypeWiseBarChartComponent?.getReportData({ timeSeriesValues: { startDate: startDate, endDate: endDate } }); + this.popularLandingPagesBarChartComponent?.getReportData({ timeSeriesValues: { startDate: startDate, endDate: endDate } }); + this.timeSpentPerPageBarChartComponent?.getReportData({ timeSeriesValues: { startDate: startDate, endDate: endDate } }); + this.activeUsersTrendline?.getReportData({ timeSeriesValues: { startDate: startDate, endDate: endDate } }); + this.activeUsersBignumber?.getReportData({ timeSeriesValues: { startDate: startDate, endDate: endDate } }); + } + } + + checkReport(key: string, reportType: string): Boolean { + let reportConfig = config; + let flag = false; + reportConfig[key]?.filters?.forEach((filter: any) => { + if (Number(filter.hierarchyLevel) === Number(this.rbacDetails?.role) && Object.keys(filter?.actions?.queries).includes(reportType)) { + flag = true + } + }) + return flag + } + + csvDownload(csvData: any) { + if (csvData) { + this.reportsData.push(csvData) + } + } + + filtersUpdated(filters: any) { + this.reportsData = []; + this.telemetryBigNumber?.getReportData({ filterValues: filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.browserTypeWiseBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.deviceTypeWiseBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.popularLandingPagesBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.timeSpentPerPageBarChartComponent?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.activeUsersTrendline?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + this.activeUsersBignumber?.getReportData({ filterValues: this.filters.map((filter) => { return { ...filter, columnName: filter.valueProp, filterType: filter.id } }) }); + } + + timeSeriesUpdated(event: any): void { + this.startDate = moment(event.startDate).format('YYYY-MM-DD'); + this.endDate = moment(event.endDate).format('YYYY-MM-DD'); + if (event?.startDate !== null && event?.endDate !== null) { + console.log(event); + this.reportsData = []; + // this.telemetryBigNumber?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); + this.browserTypeWiseBarChartComponent?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); + this.deviceTypeWiseBarChartComponent?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); + this.popularLandingPagesBarChartComponent?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); + this.timeSpentPerPageBarChartComponent?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); + this.activeUsersTrendline?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); + this.activeUsersBignumber?.getReportData({ timeSeriesValues: { startDate: this.startDate, endDate: this.endDate } }); + } + } + + importBigNumberMetrics(bigNumberMetric: any) { + this.bigNumberMetrics[bigNumberMetric.ind] = bigNumberMetric.data + } } diff --git a/src/app/views/telemetry/telemetry.module.ts b/src/app/views/telemetry/telemetry.module.ts index 8d9b1228..c86f98f7 100644 --- a/src/app/views/telemetry/telemetry.module.ts +++ b/src/app/views/telemetry/telemetry.module.ts @@ -11,6 +11,8 @@ import { BrowserTypeWiseBarChartComponent } from './pages/telemetry-tab/reports/ import { DeviceTypeWiseBarChartComponent } from './pages/telemetry-tab/reports/device-type-wise-bar-chart/device-type-wise-bar-chart.component'; import { PopularLandingPagesBarChartComponent } from './pages/telemetry-tab/reports/popular-landing-pages-bar-chart/popular-landing-pages-bar-chart.component'; import { TimeSpentPerPageBarChartComponent } from './pages/telemetry-tab/reports/time-spent-per-page-bar-chart/time-spent-per-page-bar-chart.component'; +import { TelemetryActiveUsersTrendlineComponent } from './pages/telemetry-tab/reports/telemetry-active-users-trendline/telemetry-active-users-trendline.component'; +import { TelemetryActiveUsersBigNumberComponent } from './pages/telemetry-tab/reports/telemetry-active-users-big-number/telemetry-active-users-big-number.component'; @NgModule({ declarations: [ @@ -20,7 +22,9 @@ import { TimeSpentPerPageBarChartComponent } from './pages/telemetry-tab/reports BrowserTypeWiseBarChartComponent, DeviceTypeWiseBarChartComponent, PopularLandingPagesBarChartComponent, - TimeSpentPerPageBarChartComponent + TimeSpentPerPageBarChartComponent, + TelemetryActiveUsersTrendlineComponent, + TelemetryActiveUsersBigNumberComponent ], imports: [ DashletModule.forRoot({