From be9e305cafc2c95b1cdec01efa3316cb5c990697 Mon Sep 17 00:00:00 2001 From: FaizanMohammed326 Date: Tue, 3 Jan 2023 12:40:33 +0530 Subject: [PATCH 1/3] angular component additions in ui poc --- apis/core-apis/package.json | 4 +- apis/wrapper-api/index.js | 4 +- .../dashboard/package.json | 4 +- .../big-number/big-number.component.html | 25 ++++++++ .../big-number/big-number.component.scss | 57 +++++++++++++++++++ .../big-number/big-number.component.spec.ts | 23 ++++++++ .../big-number/big-number.component.ts | 44 ++++++++++++++ .../filter-panel/filter-panel.component.ts | 23 ++++---- .../time-series-filter-panel.component.scss | 0 ...time-series-filter-panel.component.spec.ts | 23 ++++++++ .../time-series-filter-panel.component.ts | 24 ++++++++ .../table-heat-map.directive.ts | 4 +- .../dashboard/src/app/shared/shared.module.ts | 12 +++- 13 files changed, 227 insertions(+), 20 deletions(-) create mode 100644 reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.html create mode 100644 reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.scss create mode 100644 reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.spec.ts create mode 100644 reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.ts create mode 100644 reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.scss create mode 100644 reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.spec.ts create mode 100644 reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.ts diff --git a/apis/core-apis/package.json b/apis/core-apis/package.json index 95a4f9b7..de4a71fa 100644 --- a/apis/core-apis/package.json +++ b/apis/core-apis/package.json @@ -10,9 +10,9 @@ "author": "", "license": "ISC", "dependencies": { + "2fa-util": "^1.1.1", "@azure/storage-blob": "^12.12.0", "@types/speakeasy": "^2.0.7", - "2fa-util": "^1.1.1", "aws-sdk": "^2.633.0", "axios": "^0.19.2", "azure-storage": "^2.10.5", @@ -21,7 +21,7 @@ "cors": "^2.8.5", "csvtojson": "^2.0.10", "dotenv": "^8.2.0", - "express": "^4.17.1", + "express": "^4.18.2", "group-array": "^1.0.0", "json2csv": "^5.0.6", "jsonexport": "^3.0.1", diff --git a/apis/wrapper-api/index.js b/apis/wrapper-api/index.js index 7d8596ae..1977d1d7 100644 --- a/apis/wrapper-api/index.js +++ b/apis/wrapper-api/index.js @@ -10,8 +10,8 @@ app.use(cors()); const client = new Client({ user: "postgres", // Replace with your PostgreSQL username host: "localhost", // Replace with the hostname of your PostgreSQL server - database: "POC", // Replace with the name of your database - password: "Root@123", // Replace with your password + database: "cqube", // Replace with the name of your database + password: "postgres", // Replace with your password port: 5432, // Replace with the port of your PostgreSQL server (usually 5432) }); diff --git a/reference-visualization-app/dashboard/package.json b/reference-visualization-app/dashboard/package.json index 80f98795..44c4af3b 100644 --- a/reference-visualization-app/dashboard/package.json +++ b/reference-visualization-app/dashboard/package.json @@ -18,7 +18,7 @@ "@angular/compiler": "^14.0.0", "@angular/core": "^14.0.0", "@angular/forms": "^14.0.0", - "@angular/material": "^14.0.4", + "@angular/material": "^14.2.7", "@angular/platform-browser": "^14.0.0", "@angular/platform-browser-dynamic": "^14.0.0", "@angular/router": "^14.0.0", @@ -32,6 +32,7 @@ "@ngx-translate/http-loader": "^7.0.0", "@project-sunbird/sb-dashlet-v14": "^1.0.6", "@project-sunbird/sb-themes": "^0.0.78", + "angular-material-datepicker": "^1.0.2", "apexcharts": "^3.35.5", "bootstrap": "^4.3.1", "chart.js": "^2.9.4", @@ -51,6 +52,7 @@ "ng-apexcharts": "^1.7.1", "ng-circle-progress": "^1.6.0", "ngx-bootstrap": "^9.0.0", + "ngx-daterangepicker-material": "^6.0.4", "ngx-spinner": "^14.0.0", "rxjs": "~7.5.0", "tslib": "^2.3.0", diff --git a/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.html b/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.html new file mode 100644 index 00000000..1dd39c20 --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.html @@ -0,0 +1,25 @@ +
+
+ {{bigNumberReportData?.reportName}} +
+
+

{{averagePercentage + this.valueSuffix}}

+
+
+
+

{{differenceInPercentage + this.valueSuffix}}

+
+
+
+ +
+
+ +
+
+ +
+
+
+ +
\ No newline at end of file diff --git a/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.scss b/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.scss new file mode 100644 index 00000000..bcdf9e4f --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.scss @@ -0,0 +1,57 @@ +.fa-arrow-down{ + color: rgb(246, 49, 49); +} + +.fa-arrow-up{ + color: rgb(53, 185, 53); +} + +.fa-minus{ + color: black; +} + +.report-wrapper{ + border-radius: 14px; + width: 100px; + padding: 5px; + margin-bottom: 20px; + width: auto; + background-color: white; + display: flex; + flex-direction: column; +} + +.average-wrapper{ + // margin: 30px; + margin-right: auto; + margin-left: auto; + display: flex; + padding: 5px; + align-items: center; + justify-content: center; +} + +.difference-wrapper{ + padding: 5px; + justify-content: end; + display: flex; + flex-direction: row; +} + +.difference-percentage{ + margin-right: 3px; + font-size: medium; + font-weight: bolder; + color: #4c30f5; +} + +.average-percentage{ + font-size: 40px; + font-weight: bolder; + color: #4c30f5; +} + +.report-name{ + font-size: medium; + color: #4c30f5; +} diff --git a/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.spec.ts b/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.spec.ts new file mode 100644 index 00000000..344fc916 --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BigNumberComponent } from './big-number.component'; + +describe('BigNumberComponent', () => { + let component: BigNumberComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ BigNumberComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(BigNumberComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.ts b/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.ts new file mode 100644 index 00000000..0e9863b0 --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.ts @@ -0,0 +1,44 @@ +import { Component, Input, OnChanges, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-big-number', + templateUrl: './big-number.component.html', + styleUrls: ['./big-number.component.scss'] +}) +export class BigNumberComponent implements OnInit, OnChanges { + + @Input() bigNumberReportData: any; + averagePercentage: any; + differenceInPercentage: any; + differenceIndicator: boolean = undefined; + valueSuffix: any; + constructor() { } + + ngOnInit(): void { + + } + + ngOnChanges(): void { + this.updateValues(); + } + + updateValues(): void { + this.averagePercentage = this.bigNumberReportData?.averagePercentage; + this.valueSuffix = this.bigNumberReportData.valueSuffix ? this.bigNumberReportData.valueSuffix : ''; + if(this.bigNumberReportData && this.bigNumberReportData.differencePercentage && this.bigNumberReportData.averagePercentage) { + this.differenceInPercentage = (this.bigNumberReportData.averagePercentage - this.bigNumberReportData.differencePercentage).toFixed(2); + console.log(this.differenceInPercentage) + } + if(this.differenceInPercentage > 0){ + this.differenceIndicator = true; + } + else if(this.differenceInPercentage < 0) { + this.differenceIndicator = false; + this.differenceInPercentage = Math.abs(this.differenceInPercentage) + } + else { + this.differenceIndicator = undefined; + } + } + +} diff --git a/reference-visualization-app/dashboard/src/app/shared/components/filter-panel/filter-panel.component.ts b/reference-visualization-app/dashboard/src/app/shared/components/filter-panel/filter-panel.component.ts index e4d52df5..f9c749e5 100644 --- a/reference-visualization-app/dashboard/src/app/shared/components/filter-panel/filter-panel.component.ts +++ b/reference-visualization-app/dashboard/src/app/shared/components/filter-panel/filter-panel.component.ts @@ -9,7 +9,7 @@ export class FilterPanelComponent implements OnInit, OnChanges { @Input() filters: any = []; @Input() colSize: any = "md:col-span-3 xs:col-span-12 xmd:col-span-4 4k:col-span-2"; - @Input() resetOthers = true; + @Input() resetOthers = false; @Output() filtersUpdated = new EventEmitter(); @@ -22,16 +22,17 @@ export class FilterPanelComponent implements OnInit, OnChanges { } onSelectOption(event: any, ind: number): void { - // if (this.resetOthers) { - // this.filters = this.filters.map((filter: any, filterInd: number) => { - // if (filterInd > ind) { - // filter.options = []; - // filter.value = null; - // } - - // return filter; - // }); - // } + if (this.resetOthers) { + this.filters = this.filters.filter((filter: any, filterInd: number) => { + if (filterInd > ind) { + // filter.options = []; + // filter.value = null; + return false; + } + + return true; + }); + } this.filtersUpdated.emit(this.filters); } diff --git a/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.scss b/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.spec.ts b/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.spec.ts new file mode 100644 index 00000000..3aa2cee3 --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TimeSeriesFilterPanelComponent } from './time-series-filter-panel.component'; + +describe('TimeSeriesFilterPanelComponent', () => { + let component: TimeSeriesFilterPanelComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ TimeSeriesFilterPanelComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TimeSeriesFilterPanelComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.ts b/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.ts new file mode 100644 index 00000000..4a8a48bd --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.ts @@ -0,0 +1,24 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; + +@Component({ + selector: 'app-time-series-filter-panel', + templateUrl: './time-series-filter-panel.component.html', + styleUrls: ['./time-series-filter-panel.component.scss'] +}) +export class TimeSeriesFilterPanelComponent implements OnInit { + + @Output() timeSeriesUpdated = new EventEmitter(); + @Input() minDate: any; + @Input() maxDate: any; + + constructor() { } + + selected: any; + + ngOnInit(): void { + } + + changeDate(event: any) { + this.timeSeriesUpdated.emit(this.selected) + } +} diff --git a/reference-visualization-app/dashboard/src/app/shared/directives/table-heat-map/table-heat-map.directive.ts b/reference-visualization-app/dashboard/src/app/shared/directives/table-heat-map/table-heat-map.directive.ts index 072b320d..30311eab 100644 --- a/reference-visualization-app/dashboard/src/app/shared/directives/table-heat-map/table-heat-map.directive.ts +++ b/reference-visualization-app/dashboard/src/app/shared/directives/table-heat-map/table-heat-map.directive.ts @@ -108,12 +108,12 @@ export class TableHeatMapDirective implements AfterViewInit { } private getColor(id: string, value: string | number) { - const color = this.config[id].color; + const color = this.config[id] ? this.config[id].color : '#fff'; let [r, g, b, a] = parseToRgba(Array.isArray(color) ? color[color.length - 1] : color); if (!isNaN(Number(value))) { value = Number(value); - let color = this.config[id].color; + let color = this.config[id] ? this.config[id].color : '#fff'; let textColor = null; let bgColor = null; if (color != null) { diff --git a/reference-visualization-app/dashboard/src/app/shared/shared.module.ts b/reference-visualization-app/dashboard/src/app/shared/shared.module.ts index 5eca52df..b0bc1058 100644 --- a/reference-visualization-app/dashboard/src/app/shared/shared.module.ts +++ b/reference-visualization-app/dashboard/src/app/shared/shared.module.ts @@ -39,6 +39,10 @@ import { NgApexchartsModule } from "ng-apexcharts"; import { ManagementSelectorComponent } from './components/core-components/management-selector/management-selector.component'; import { DownloadButtonComponent } from './components/buttons/download-button/download-button.component'; +import { TimeSeriesFilterPanelComponent } from './components/time-series-filter-panel/time-series-filter-panel.component'; +import { NgxDaterangepickerMd } from 'ngx-daterangepicker-material'; +import { BigNumberComponent } from './components/big-number/big-number.component'; +import { StudentAttendanceMapComponent } from './components/student-attendance-map/student-attendance-map.component'; const IMPORTS: any[] = [ MatTableModule, @@ -53,7 +57,8 @@ const IMPORTS: any[] = [ TooltipModule.forRoot(), NgCircleProgressModule.forRoot(), NgApexchartsModule, - TooltipModule.forRoot() + TooltipModule.forRoot(), + NgxDaterangepickerMd.forRoot() ]; const DECLARATIONS = [ @@ -81,12 +86,15 @@ const DECLARATIONS = [ BubblesComponent, ProgressCircleComponent, ManagementSelectorComponent, - DownloadButtonComponent + DownloadButtonComponent, + TimeSeriesFilterPanelComponent, + BigNumberComponent ]; @NgModule({ declarations: [ DECLARATIONS, + StudentAttendanceMapComponent, ], imports: [ CommonModule, From f2a8068ef63c6decbf842015ac67cf8faf6367a7 Mon Sep 17 00:00:00 2001 From: FaizanMohammed326 Date: Tue, 3 Jan 2023 12:56:18 +0530 Subject: [PATCH 2/3] UI POC changes for student attendance complaince --- .../src/app/core/services/wrapper.service.ts | 2 +- .../big-number/big-number.component.scss | 11 +- .../time-series-filter-panel.component.html | 2 + .../src/app/utilities/QueryBuilder.ts | 74 ++++-- .../attendance/config/attendance_config.ts | 200 +++++++++++++++ .../student-attendance-new.component.html | 13 +- .../student-attendance-new.component.ts | 241 +++++++++++------- 7 files changed, 427 insertions(+), 116 deletions(-) create mode 100644 reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.html create mode 100644 reference-visualization-app/dashboard/src/app/views/attendance/config/attendance_config.ts diff --git a/reference-visualization-app/dashboard/src/app/core/services/wrapper.service.ts b/reference-visualization-app/dashboard/src/app/core/services/wrapper.service.ts index ceb65863..25be9692 100644 --- a/reference-visualization-app/dashboard/src/app/core/services/wrapper.service.ts +++ b/reference-visualization-app/dashboard/src/app/core/services/wrapper.service.ts @@ -82,7 +82,7 @@ export class WrapperService { let parentFilter = filters.find(filter => filter.valueProp === propertyName); if (parentFilter && parentFilter.value) { let re = new RegExp(`{${propertyName}}`); - query = query.replace(re, parentFilter.value); + query = query.replace(re, '\'' + parentFilter.value + '\''); } else { query = null; break; diff --git a/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.scss b/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.scss index bcdf9e4f..a91e30ea 100644 --- a/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.scss +++ b/reference-visualization-app/dashboard/src/app/shared/components/big-number/big-number.component.scss @@ -16,7 +16,7 @@ padding: 5px; margin-bottom: 20px; width: auto; - background-color: white; + background-color: #4c30f5; display: flex; flex-direction: column; } @@ -25,6 +25,8 @@ // margin: 30px; margin-right: auto; margin-left: auto; + margin-top: 10px; + margin-bottom: 10px; display: flex; padding: 5px; align-items: center; @@ -42,16 +44,17 @@ margin-right: 3px; font-size: medium; font-weight: bolder; - color: #4c30f5; + color: white; } .average-percentage{ font-size: 40px; font-weight: bolder; - color: #4c30f5; + color: white; } .report-name{ + margin: 5px 0px; font-size: medium; - color: #4c30f5; + color: white; } diff --git a/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.html b/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.html new file mode 100644 index 00000000..1271c77e --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/shared/components/time-series-filter-panel/time-series-filter-panel.component.html @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/reference-visualization-app/dashboard/src/app/utilities/QueryBuilder.ts b/reference-visualization-app/dashboard/src/app/utilities/QueryBuilder.ts index 0e463a7c..932481d2 100644 --- a/reference-visualization-app/dashboard/src/app/utilities/QueryBuilder.ts +++ b/reference-visualization-app/dashboard/src/app/utilities/QueryBuilder.ts @@ -1,5 +1,7 @@ -export const buildQuery = (query: string, levels: any, filters: any = []) => { - let level = "district"; + + +export const buildQuery = (query: string, levels: any, filters: any = [], startDate: any, endDate: any, compareDateRange: any, key: any) => { + let level = "state"; let newQuery = ""; if (filters && filters.length > 0) { @@ -10,19 +12,19 @@ export const buildQuery = (query: string, levels: any, filters: any = []) => { return filter.value }); - newQuery = getCubeNameFromSelFilter(filters); + newQuery = getCubeNameFromSelFilter(filters, startDate, endDate, compareDateRange, key); } return newQuery !== "" ? newQuery : query; } -const getCubeNameFromSelFilter = (filters) => { +const getCubeNameFromSelFilter = (filters, startDate, endDate, compareDateRange, key) => { let newQuery = ""; if (filters.length > 0) { filters.forEach(({ actions: { level, query } }, index) => { if (level && level !== '') { - newQuery = parseQuery(filters, index); + newQuery = parseQuery(filters, index, startDate, endDate, compareDateRange, key); } }); } @@ -30,27 +32,59 @@ const getCubeNameFromSelFilter = (filters) => { return newQuery; } -function parseQuery(filters, index): string { +function parseQuery(filters, index, startDate, endDate, compareDateRange, key): string { const filter = filters[index]; - let { query } = filter.actions; + let query; + if (key.toLowerCase().includes('comparison')) { + let endDate = new Date(); + let days = endDate.getDate() - compareDateRange; + let startDate = new Date(); + startDate.setDate(days) + console.log(startDate.toISOString().split('T')[0], ' - ', endDate.toISOString().split('T')[0]) + query = parseTimeSeriesQuery(filter?.timeSeriesQueries[key], startDate.toISOString().split('T')[0], endDate.toISOString().split('T')[0]) + console.log(query) + } + else if (startDate !== undefined && endDate !== undefined && Object.keys(filter?.timeSeriesQueries).length > 0) { + query = parseTimeSeriesQuery(filter?.timeSeriesQueries[key], startDate, endDate) + } + else { + let { queries } = filter.actions; + query = queries[key] + } let startIndex = query.indexOf('{'); let endIndex = query.indexOf('}'); - + if (query && startIndex > -1) { - while (startIndex > -1) { - let propertyName = query.substring(startIndex + 1, endIndex); - if (filter.value) { - let re = new RegExp(`{${propertyName}}`, "g"); - query = query.replace(re, filter.value); - } else { - query = null; - break; - } + while (startIndex > -1) { + let propertyName = query.substring(startIndex + 1, endIndex); + if (filter.value) { + let re = new RegExp(`{${propertyName}}`, "g"); + query = query.replace(re, '\'' + filter.value + '\''); + } else { + query = null; + break; + } - startIndex = query.indexOf('{'); - endIndex = query.indexOf('}'); - } + startIndex = query.indexOf('{'); + endIndex = query.indexOf('}'); + } } return query; } + +export function parseTimeSeriesQuery(query, startDate, endDate): string { + let startIndex = query.indexOf('{'); + if (query && startIndex > -1) { + if (startDate && endDate) { + let minDateRE = new RegExp(`{startDate}`, "g"); + let maxDateRE = new RegExp(`{endDate}`, "g"); + query = query.replace(minDateRE, '\'' + startDate + '\''); + query = query.replace(maxDateRE, '\'' + endDate + '\''); + } + else { + query = null; + } + } + return query; +} diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/config/attendance_config.ts b/reference-visualization-app/dashboard/src/app/views/attendance/config/attendance_config.ts new file mode 100644 index 00000000..d2379741 --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/views/attendance/config/attendance_config.ts @@ -0,0 +1,200 @@ +export const config = { + student_attendance_complaince: { + "queries": { + "table": "select min(date) as min_date, max(date) as max_date, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_state as t1 left join ingestion.student_attendance as t2 on t1.state_id = t2.state_id group by t1.state_id, state_name", + "bigNumber": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_state", + "bigNumberComparison": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_state where date between {startDate} and {endDate}" + }, + "timeSeriesQueries": { + "table": "select state_name, avg(percentage) as percentage from ingestion.student_attendance_by_state as t1 left join ingestion.student_attendance as t2 on t1.state_id = t2.state_id where date between {startDate} and {endDate} group by t1.state_id, state_name", + "bigNumber": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_state where date between {startDate} and {endDate}", + "bigNumberComparison": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_state where date between {startDate} and {endDate}" + }, + "filters": [ + { + "name": "State", + "labelProp": "state_name", + "valueProp": "state_id", + "query": "select t1.state_id, state_name from ingestion.student_attendance_by_state as t1 left join ingestion.student_attendance as t2 on t1.state_id = t2.state_id group by t1.state_id,state_name", + "timeSeriesQueries": { + "table": "select district_name, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_district as t1 left join ingestion.student_attendance as t2 on t1.district_id = t2.district_id where (date between {startDate} and {endDate}) and state_id={state_id} group by t1.district_id,district_name, state_name", + "bigNumber": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_state where state_id = {state_id} and date between {startDate} and {endDate}", + "bigNumberComparison": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_state where state_id = {state_id} and date between {startDate} and {endDate}" + }, + "actions": { + "queries": { + "table": "select min(date) as min_date, max(date) as max_date, district_name, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_district as t1 left join ingestion.student_attendance as t2 on t1.district_id = t2.district_id where state_id={state_id} group by t1.district_id,district_name, state_name", + "bigNumber": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_state where state_id = {state_id}", + "bigNumberComparison": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_state where state_id = {state_id} and date between {startDate} and {endDate}" + }, + "level": "district" + } + }, + { + "name": "District", + "labelProp": "district_name", + "valueProp": "district_id", + "timeSeriesQueries": { + "table": "select block_name, district_name, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_block as t1 left join ingestion.student_attendance as t2 on t1.block_id = t2.block_id where (date between {startDate} and {endDate}) and district_id={district_id} group by t1.block_id,block_name,district_name, state_name", + "bigNumber": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_district where district_id = {district_id} and date between {startDate} and {endDate}", + "bigNumberComparison": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_district where district_id = {district_id} and date between {startDate} and {endDate}" + }, + "query": "select t1.district_id, district_name from ingestion.student_attendance_by_district as t1 left join ingestion.student_attendance as t2 on t1.district_id = t2.district_id where state_id={state_id} group by t1.district_id,district_name", + "actions": { + "queries": { + "table": "select min(date) as min_date, max(date) as max_date, block_name, district_name, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_block as t1 left join ingestion.student_attendance as t2 on t1.block_id = t2.block_id where district_id={district_id} group by t1.block_id,block_name,district_name, state_name", + "bigNumber": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_district where district_id = {district_id}", + "bigNumberComparison": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_district where district_id = {district_id} and date between {startDate} and {endDate}" + }, + "level": "block" + } + }, + { + "name": "Block", + "labelProp": "block_name", + "valueProp": "block_id", + "timeSeriesQueries": { + "table": "select cluster_name, block_name, district_name, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_cluster as t1 left join ingestion.student_attendance as t2 on t1.cluster_id = t2.cluster_id where (date between {startDate} and {endDate}) and block_id={block_id} group by t1.cluster_id,cluster_name,block_name,district_name, state_name", + "bigNumber": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_block where block_id = {block_id} and date between {startDate} and {endDate}", + "bigNumberComparison": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_block where block_id = {block_id} and date between {startDate} and {endDate}" + }, + "query": "select t1.block_id, block_name from ingestion.student_attendance_by_block as t1 left join ingestion.student_attendance as t2 on t1.block_id = t2.block_id where district_id={district_id} group by t1.block_id,block_name", + "actions": { + "queries": { + "table": "select min(date) as min_date, max(date) as max_date, cluster_name, block_name, district_name, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_cluster as t1 left join ingestion.student_attendance as t2 on t1.cluster_id = t2.cluster_id where block_id={block_id} group by t1.cluster_id,cluster_name,block_name,district_name, state_name", + "bigNumber": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_block where block_id = {block_id}", + "bigNumberComparison": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_block where block_id = {block_id} and date between {startDate} and {endDate}" + }, + "level": "cluster" + } + }, + { + "name": "Cluster", + "labelProp": "cluster_name", + "valueProp": "cluster_id", + "timeSeriesQueries": { + "table": "select school_name, cluster_name, block_name, district_name, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_school as t1 left join ingestion.student_attendance as t2 on t1.school_id = t2.school_id where (date between {startDate} and {endDate}) and cluster_id={cluster_id} group by t1.school_id,school_name,cluster_name,block_name,district_name, state_name", + "bigNumber": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_cluster where cluster_id = {cluster_id} and date between {startDate} and {endDate}", + "bigNumberComparison": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_cluster where cluster_id = {cluster_id} and date between {startDate} and {endDate}", + }, + "query": "select t1.cluster_id, cluster_name from ingestion.student_attendance_by_cluster as t1 left join ingestion.student_attendance as t2 on t1.cluster_id = t2.cluster_id where block_id={block_id} group by t1.cluster_id,cluster_name", + "actions": { + "queries": { + "table": "select min(date) as min_date, max(date) as max_date, school_name, cluster_name, block_name, district_name, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_school as t1 left join ingestion.student_attendance as t2 on t1.school_id = t2.school_id where cluster_id={cluster_id} group by t1.school_id,school_name,cluster_name,block_name,district_name, state_name", + "bigNumber": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_cluster where cluster_id = {cluster_id}", + "bigNumberComparison": "select round(avg((sum/count)* 100.00),2) as percentage from ingestion.student_attendance_marked_above_50_percent_by_cluster where cluster_id = {cluster_id} and date between {startDate} and {endDate}", + }, + "level": "school" + } + }, + { + "name": "School", + "labelProp": "school_name", + "valueProp": "school_id", + "timeSeriesQueries": { + "table": "select grade, school_name, cluster_name, block_name, district_name, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_class as t1 left join ingestion.student_attendance as t2 on t1.school_id = t2.school_id where (date between {startDate} and {endDate}) and t1.school_id={school_id} group by grade,school_name,cluster_name,block_name,district_name, state_name", + }, + "query": "select t1.school_id, school_name from ingestion.student_attendance_by_school as t1 left join ingestion.student_attendance as t2 on t1.school_id = t2.school_id where cluster_id={cluster_id} group by t1.school_id,school_name", + "actions": { + "queries": { + "table": "select min(date) as min_date, max(date) as max_date, grade, school_name, cluster_name, block_name, district_name, state_name, avg(percentage) as percentage from ingestion.student_attendance_by_class as t1 left join ingestion.student_attendance as t2 on t1.school_id = t2.school_id where t1.school_id={school_id} group by grade,school_name,cluster_name,block_name,district_name, state_name" + }, + "level": "grade" + } + } + ], + "levels": [ + { + "name": "Blocks", + "value": "block", + "query": "Select * from table_name" + }, + { + "name": "Clusters", + "value": "cluster", + "query": "Select * from table_name" + } + ], + "options": { + "chart": { + "type": "table", + "title": "Student Attendance" + }, + "table": { + "columns": [ + { + name: "State", + property: "state_name", + sticky: true, + class: "text-center" + }, + { + name: "District", + property: "district_name", + sticky: true, + class: "text-center" + }, + { + name: "Block", + property: "block_name", + sticky: true, + class: "text-center" + }, + { + name: "Cluster", + property: "cluster_name", + sticky: true, + class: "text-center" + }, + { + name: "School", + property: "school_name", + sticky: true, + class: "text-center" + }, + { + name: "Grade", + property: "grade", + sticky: true, + class: "text-center" + }, + { + name: "Student Attendance Complaince", + property: "percentage", + sticky: true, + class: "text-center", + isHeatMapRequired: true, + color: '#002966', + } + ], + "sortByProperty": "location", + "sortDirection": "asc" + }, + "bigNumber": { + "valueSuffix": '%' + }, + "tooltip": "District ID: {district_id}\nDistrict Name: {district_name}\nAttendance: {attendancec}", + } + }, + student_attendance_map: { + "query": "select * from ingestion.student_attendance_by_district", + "filters": [], + "levels": [], + "options": { + "chart": { + "type": "map", + "title": "Student Attendance" + }, + "map": { + "indicator": "attendance", + "indicatorType": "percent", + "legend": { + "title": "Student Attendance" + }, + "latitude": "latitude", + "longitude": "longitude" + }, + "tooltip": "District ID: {district_code}\nDistrict Name: {district_name}\nAttendance: {attendance}" + } + } +} \ No newline at end of file diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.html b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.html index c415db43..f303e5eb 100644 --- a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.html +++ b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.html @@ -5,15 +5,22 @@ -->
- + +
- +
+
+ +
-
+ +
+
+ +
+
+ +
+
+ + + + + \ No newline at end of file diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-bar/student-attendance-bar.component.scss b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-bar/student-attendance-bar.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-bar/student-attendance-bar.component.spec.ts b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-bar/student-attendance-bar.component.spec.ts new file mode 100644 index 00000000..096094cc --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-bar/student-attendance-bar.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StudentAttendanceBarComponent } from './student-attendance-bar.component'; + +describe('StudentAttendanceBarComponent', () => { + let component: StudentAttendanceBarComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ StudentAttendanceBarComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(StudentAttendanceBarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-bar/student-attendance-bar.component.ts b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-bar/student-attendance-bar.component.ts new file mode 100644 index 00000000..a6126a64 --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-bar/student-attendance-bar.component.ts @@ -0,0 +1,140 @@ +import { Component, OnInit } from '@angular/core'; +import { Axis } from 'highcharts'; +import { getBarDatasetConfig, getChartJSConfig } from 'src/app/core/config/ChartjsConfig'; +import { CommonService } from 'src/app/core/services/common/common.service'; +import { WrapperService } from 'src/app/core/services/wrapper.service'; +import { formatNumberForReport } from 'src/app/utilities/NumberFomatter'; +import { buildQuery, parseTimeSeriesQuery } from 'src/app/utilities/QueryBuilder'; +import { environment } from 'src/environments/environment'; +import { config } from '../../config/attendance_config'; + +@Component({ + selector: 'app-student-attendance-bar', + templateUrl: './student-attendance-bar.component.html', + styleUrls: ['./student-attendance-bar.component.scss'] +}) +export class StudentAttendanceBarComponent implements OnInit { + + title: any; + chartHeight: any; + marginTop: any; + config; + data; + fileName: string = "Student_Attendance_Bar"; + reportName: string = 'student_attendance_bar'; + filters: any = []; + levels: any; + tableReportData: any; + startDate: any; + endDate: any; + minDate: any; + maxDate: any; + level = environment.config === 'national' ? 'state' : 'district'; + filterIndex: any; + + constructor(private readonly _commonService: CommonService, private readonly _wrapperService: WrapperService) { } + + ngOnInit(): void { + this.getReportData(); + } + + async getReportData(): Promise { + let reportConfig = config + + let { timeSeriesQueries, queries, levels, defaultLevel, filters, options } = reportConfig[this.reportName]; + let onLoadQuery; + + this._wrapperService.constructFilters(this.filters, filters); + + Object.keys(queries).forEach((key: any) => { + 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); + + if (query && key === 'barChart') { + this.getBarChartReportData(query, options); + } + + + }) + } + + getBarChartReportData(query, options): void { + this._commonService.getReportDataNew(query).subscribe((res: any) => { + let { rows } = res; + let { barChart: { yAxis, xAxis } } = options; + rows.forEach(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'] + } + }); + this.tableReportData = { + values: rows + } + this.config = getChartJSConfig({ + labelExpr: yAxis.value, + datasets: getBarDatasetConfig(xAxis?.metrics?.map((metric: any) => { + return { + dataExpr: metric.value, label: metric.label + } + })), + options: { + height: (rows.length * 15 + 150).toString(), + tooltips: { + callbacks: { + label: (tooltipItem, data) => { + let multistringText = []; + if (tooltipItem.datasetIndex === 0) { + xAxis.metrics.forEach((metric: any) => { + multistringText.push(`${metric.label}: ${formatNumberForReport(rows[tooltipItem.index][metric.value])}`); + }); + } + + return multistringText; + } + } + }, + scales: { + yAxes: [{ + scaleLabel: { + display: true, + labelString: yAxis.title + } + }], + xAxes: [{ + scaleLabel: { + display: true, + labelString: xAxis.title + } + }] + } + } + }); + }); + } + + filtersUpdated(filters: any): void { + this.filters = filters; + this.getReportData(); + } + + timeSeriesUpdated(event: any): void { + this.startDate = event?.startDate?.toDate().toISOString().split('T')[0] + this.endDate = event?.endDate?.toDate().toISOString().split('T')[0] + this.getReportData(); + } + +} diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.html b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.html new file mode 100644 index 00000000..2eadce9b --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.html @@ -0,0 +1,21 @@ +
+
+
+
+ + +
+
+ +
+
+ +
+
+
+
+ +
+
+
+
diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.scss b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.spec.ts b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.spec.ts new file mode 100644 index 00000000..e8cbb761 --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StudentAttendanceMapComponent } from './student-attendance-map.component'; + +describe('StudentAttendanceMapComponent', () => { + let component: StudentAttendanceMapComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ StudentAttendanceMapComponent ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(StudentAttendanceMapComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.ts b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.ts new file mode 100644 index 00000000..7c70c32a --- /dev/null +++ b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-map/student-attendance-map.component.ts @@ -0,0 +1,195 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonService } from 'src/app/core/services/common/common.service'; +import { WrapperService } from 'src/app/core/services/wrapper.service'; +import { buildQuery, parseTimeSeriesQuery } from 'src/app/utilities/QueryBuilder'; +import { environment } from 'src/environments/environment'; +import { config } from '../../config/attendance_config'; + +@Component({ + selector: 'app-student-attendance-map', + templateUrl: './student-attendance-map.component.html', + styleUrls: ['./student-attendance-map.component.scss'] +}) +export class StudentAttendanceMapComponent implements OnInit { + + reportName: string = 'student_attendance_map'; + filters: any = []; + metricFilter: any = {}; + levels: any; + reportData: any; + startDate: any; + endDate: any; + minDate: any; + maxDate: any; + level = environment.config === 'national' ? 'state' : 'district'; + currentHierarchyLevel: any = this.level === 'state' ? 1 : 2; + + constructor(private readonly _commonService: CommonService, private readonly _wrapperService: WrapperService) { } + + ngOnInit(): void { + this.getReportData(); + } + + async getReportData(): Promise { + let reportConfig = config + + let { timeSeriesQueries, queries, levels, filters, options, defaultLevel } = reportConfig[this.reportName]; + if (this.levels === undefined && levels?.length > 0) { + levels[0].selected = true; + this.levels = levels; + this.updateLevels(true); + } + let onLoadQuery; + + this.filters = await this._wrapperService.constructFilters(this.filters, filters); + + Object.keys(queries).forEach((key: any) => { + 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); + + if (key === 'map') { + this.getMapReportData(query, options); + } + }) + } + + getMapReportData(query: any, options: any): void { + this._commonService.getReportDataNew(query).subscribe((res: any) => { + let { rows } = res; + let { map: { indicator, indicatorType, legend, metrics, metricFilterNeeded, tooltipMetrics } } = options ?? {}; + let selectedMetric = { + name: undefined, + value: undefined + } + if (metricFilterNeeded && metrics && Object.keys(this.metricFilter).length === 0) { + this.metricFilter = { + name: "Metrics to be shown", + options: metrics, + value: null + }; + + + } + + if (this.metricFilter.value !== null) { + let results = metrics.filter((metric: any) => { + return this.metricFilter.value == metric.value + }) + selectedMetric = results.length > 0 ? results[0] : selectedMetric + } + + if (metrics && indicator && Object.keys(this.metricFilter).length > 0 && this.metricFilter.value === null) { + let results = metrics.filter((metric: any) => { + return indicator == metric.value + }) + selectedMetric = results.length > 0 ? results[0] : selectedMetric + this.metricFilter.value = indicator; + } + + this.reportData = { + 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'] + } + row = { + ...row, + Latitude: row['latitude'], + Longitude: row['longitude'], + indicator: Number(row[selectedMetric.value]), + tooltip: this._wrapperService.constructTooltip(tooltipMetrics, row, selectedMetric.value) + }; + + return row; + }), + options: { + reportIndicatorType: indicatorType, + legend, + selectedMetric: selectedMetric.name + } + } + }); + } + + async filtersUpdated(filters: any): Promise { + await new Promise(r => setTimeout(r, 100)); + this.filters = filters + setTimeout(() => { + let tempLevel = this.level === 'state' ? 1 : 2; + this.filters.forEach((filter: any) => { + tempLevel = filter.hierarchyLevel > tempLevel ? filter.hierarchyLevel : tempLevel; + }) + this.currentHierarchyLevel = tempLevel; + this.updateLevels(false); + }, 100); + this.getReportData(); + } + + onSelectMetricFilter(metricFilter: any): void { + this.metricFilter = metricFilter + this.getReportData(); + } + + onSelectLevel(levels: any): void { + this.levels = levels.items; + this.getReportData(); + } + + timeSeriesUpdated(event: any): void { + this.startDate = event?.startDate?.toDate().toISOString().split('T')[0] + this.endDate = event?.endDate?.toDate().toISOString().split('T')[0] + this.getReportData(); + } + + updateLevels(init: boolean): void { + let flag = 1; + this.levels = this.levels.map((level: any) => { + if (level.hierarchyLevel >= this.currentHierarchyLevel) { + level.hidden = false; + if (flag) { + level.selected = true; + flag = 0; + } + else { + level.selected = false; + } + } + else { + level.selected = false; + level.hidden = true; + } + return level; + }); + if (!init) this.getReportData(); + } + + + async drillDownFilterUpdate(value: any) { + for (let i = 0; i < Object.keys(value).length; i++) { + let id = Object.keys(value)[i] + await new Promise(r => setTimeout(r, 500)); + let filters = [...this.filters]; + filters.map(async (filter: any) => { + if (filter.valueProp === id) { + filter.value = value[id] + } + return filter + }); + this.filtersUpdated(filters) + } + } + +} diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.html b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.html index f303e5eb..8a2aff86 100644 --- a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.html +++ b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.html @@ -12,7 +12,7 @@ -
+
diff --git a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.ts b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.ts index 88e895ce..74379274 100644 --- a/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.ts +++ b/reference-visualization-app/dashboard/src/app/views/attendance/pages/student-attendance-new/student-attendance-new.component.ts @@ -42,7 +42,7 @@ export class StudentAttendanceNewComponent implements OnInit { async getReportData(): Promise { let reportConfig = config - let { timeSeriesQueries, queries, levels, filters, options } = reportConfig[this.reportName]; + let { timeSeriesQueries, queries, levels, defaultLevel, filters, options } = reportConfig[this.reportName]; let onLoadQuery; this._wrapperService.constructFilters(this.filters, filters); @@ -53,7 +53,6 @@ export class StudentAttendanceNewComponent implements OnInit { let days = endDate.getDate() - this.compareDateRange; let startDate = new Date(); startDate.setDate(days) - console.log(startDate.toISOString().split('T')[0], ' - ', endDate.toISOString().split('T')[0]) 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) { @@ -62,15 +61,15 @@ export class StudentAttendanceNewComponent implements OnInit { else { onLoadQuery = queries[key] } - let query = buildQuery(onLoadQuery, this.levels, this.filters, this.startDate, this.endDate, this.compareDateRange, key); + let query = buildQuery(onLoadQuery, defaultLevel, this.levels, this.filters, this.startDate, this.endDate, key, this.compareDateRange); - if (key === 'table') { + if (query && key === 'table') { this.getTableReportData(query, options); } - else if (key === 'bigNumber') { + else if (query && key === 'bigNumber') { this.getBigNumberReportData(query, options, 'averagePercentage'); } - else if (key === 'bigNumberComparison') { + else if (query && key === 'bigNumberComparison') { this.getBigNumberReportData(query, options, 'differencePercentage') } @@ -97,25 +96,7 @@ export class StudentAttendanceNewComponent implements OnInit { getTableReportData(query, options): void { this._commonService.getReportDataNew(query).subscribe((res: any) => { let { rows } = res; - // let { map: { indicator, indicatorType, legend, latitude, longitude }, tooltip } = options; - let { table: { columns }, tooltip } = options; - // this.reportData = { - // data: rows.map(row => { - // row = { - // ...row, - // Latitude: row[latitude], - // Longitude: row[longitude], - // indicator: row[indicator], - // tooltip: this._wrapperService.formatToolTip(tooltip, row) - // }; - - // return row; - // }), - // options: { - // reportIndicatorType: indicatorType, - // legend - // } - // } + let { table: { columns }} = options; this.tableReportData = { data: rows.map(row => { if (this.minDate !== undefined && this.maxDate !== undefined) { @@ -177,7 +158,6 @@ export class StudentAttendanceNewComponent implements OnInit { } // this.bigNumberReport.emit(this.bigNumberReportData) } - console.log(this.bigNumberReportData) }) } // console.log(rows)