Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time-series support in attendance #201

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div>
<h6 class="font-medium xs:text-xs sm:text-sm md:text-md lg:text-lg xl:text-xl bg-white text-center">{{title}}</h6>
<div #container [ngStyle]="{ height: height }"></div>
</div>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';

import {TimeSeriesComponent} from './time-series.component';

describe('BarChartComponent', () => {
let component: TimeSeriesComponent;
let fixture: ComponentFixture<TimeSeriesComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [TimeSeriesComponent]
})
.compileComponents();

fixture = TestBed.createComponent(TimeSeriesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
130 changes: 130 additions & 0 deletions src/app/shared/components/charts/time-series/time-series.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import {Component, HostListener, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';
import * as Highcharts from "highcharts/highstock";
import * as HighchartsMore from "highcharts/highcharts-more";

const HighchartsMore2: any = HighchartsMore;
HighchartsMore2(Highcharts);

@Component({
selector: 'app-time-series-chart',
templateUrl: './time-series.component.html',
styleUrls: ['./time-series.component.scss']
})
export class TimeSeriesComponent implements OnInit, OnChanges {
chart!: Highcharts.Chart;
@Input() height: number | string = 'auto';
@Input() title!: string;
@Input() options: Highcharts.Options | undefined;
@Input() marginTop: any = 90;

@ViewChild('container') container: any;

@HostListener('window:resize', ['$event'])
onResize(event: any) {

const elFontSize = window.getComputedStyle(document.documentElement).getPropertyValue('font-size');

const localFontSize = localStorage.getItem('fontSize');
const currentFontSize = localFontSize ? localFontSize : elFontSize;
this.chart.update(
{
xAxis: {
labels: {
step: 1,
style: {
fontSize: currentFontSize
}
}
},
yAxis: {
labels: {
style: {
fontSize: currentFontSize
}
}
},
tooltip: {
style: {
fontSize: currentFontSize
}
},
legend: {
itemStyle: {
fontSize: currentFontSize
}
},
plotOptions: {
series: {
dataLabels: {
style: {
fontSize: currentFontSize
}
}
}
},
}
)
}

constructor() {
}

ngOnInit(): void {
}

ngOnChanges(changes: SimpleChanges): void {
if (this.options !== undefined) {
setTimeout(() => {
this.createMultiBarChart(this.options);
}, 100);
}
}

createMultiBarChart(options: Highcharts.Options | undefined): void {
let defaultOptions: Highcharts.Options = {
chart: {
// zoomType: 'x'
},
title: {
text: '',
align: 'left'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: ''
}
},
legend: {
enabled: false
},
plotOptions: {
area: {
fillColor: {
linearGradient: {
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops: []
},
marker: {
radius: 2
},
lineWidth: 1,
states: {
hover: {
lineWidth: 1
}
},
threshold: null
}
}
};
this.chart = Highcharts.chart(this.container.nativeElement, Highcharts.merge(defaultOptions, options), function (this: any) {
});
}
}
4 changes: 3 additions & 1 deletion src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { BreadcrumbComponentComponent } from './components/breadcrumb-component/
import { SbBarChartComponent } from './components/charts/sb-bar-chart/sb-bar-chart.component';
import { DashletModule, DataService } from '@project-sunbird/sb-dashlet-v14';
import { MaterialHeatChartDrilldownTableComponent } from './components/tables/material-heat-chart-drilldown-table/material-heat-chart-drilldown-table.component';
import {TimeSeriesComponent} from "./components/charts/time-series/time-series.component";

const IMPORTS: any[] = [
ReactiveFormsModule,
Expand Down Expand Up @@ -104,7 +105,8 @@ const DECLARATIONS = [
PopupOptionsComponent,
BreadcrumbComponentComponent,
SbBarChartComponent,
MaterialHeatChartDrilldownTableComponent
MaterialHeatChartDrilldownTableComponent,
TimeSeriesComponent
];

@NgModule({
Expand Down
153 changes: 146 additions & 7 deletions src/app/views/teacher-attendance/config/teacher_attendance_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ export const config = {
}],
extraInfo: {
hierarchyLevel: 1,
linkedReports: ["tas_average_attendance_barchart", "tas_average_attendance_bignumber"]
linkedReports: ["tas_average_attendance_barchart", "tas_average_attendance_bignumber", "tas_attendance_time_series"]
},
allowedLevels: [1]
}
Expand All @@ -644,7 +644,7 @@ export const config = {
}],
extraInfo: {
hierarchyLevel: 2,
linkedReports: ["tas_average_attendance_barchart", "tas_average_attendance_bignumber"]
linkedReports: ["tas_average_attendance_barchart", "tas_average_attendance_bignumber", "tas_attendance_time_series"]
},
allowedLevels: [1]
}
Expand All @@ -662,7 +662,7 @@ export const config = {
}],
extraInfo: {
hierarchyLevel: 3,
linkedReports: ["tas_average_attendance_barchart", "tas_average_attendance_bignumber"]
linkedReports: ["tas_average_attendance_barchart", "tas_average_attendance_bignumber", "tas_attendance_time_series"]
},
allowedLevels: [1]
}
Expand All @@ -680,10 +680,10 @@ export const config = {
}],
extraInfo: {
hierarchyLevel: 4,
linkedReports: ["tas_average_attendance_barchart", "tas_average_attendance_bignumber"]
linkedReports: ["tas_average_attendance_barchart", "tas_average_attendance_bignumber", "tas_attendance_time_series"]
},
allowedLevels: [1]

}
},
{
Expand Down Expand Up @@ -1057,9 +1057,148 @@ export const config = {
"level": "school"
}
},

],
"options": {
"options": {
"barChart": {
"metricLabelProp": "% Teacher Present",
"metricValueProp": "stt_avg",
"yAxis": {
"title": "Attendance %"
},
"xAxis": {
"title": " ",
"label": "level",
"value": "level",

},
"tooltipMetrics": [
{
"valuePrefix": "District Id: ",
"value": "district_id",
"valueSuffix": ""
},
{
"valuePrefix": "District Name: ",
"value": "district_name",
"valueSuffix": ""
},
{
"valuePrefix": "Block Id: ",
"value": "block_id",
"valueSuffix": ""
},
{
"valuePrefix": "Block Name: ",
"value": "block_name",
"valueSuffix": ""
},
{
"valuePrefix": "Cluster Id: ",
"value": "cluster_id",
"valueSuffix": ""
},
{
"valuePrefix": "Cluster Name: ",
"value": "cluster_name",
"valueSuffix": ""
},
{
"valuePrefix": "School Id: ",
"value": "school_id",
"valueSuffix": ""
},
{
"valuePrefix": "School Name: ",
"value": "school_name",
"valueSuffix": ""
},
{
"valuePrefix": "Total Number of Schools: ",
"value": "total_schools",
"valueSuffix": ""
},
{
"valuePrefix": "Total Number of Teachers: ",
"value": "total_teachers",
"valueSuffix": ""
},
{
"valuePrefix": "Average percentage of attendance: ",
"value": "stt_avg",
"valueSuffix": "%"
},
]
}
}
},

tas_attendance_time_series:{
"defaultLevel": "state",
"filters": [
{
"name": "State",
"labelProp": "state_name",
"valueProp": "state_id",
"hierarchyLevel": "1",
"timeSeriesQueries": {
"timeSeries": "select district_name as level, district_name, a.district_id,total_teachers, ceil(round(CAST(COALESCE(avg(a.teachers_present/NULLIF(a.total_teachers, 0))*100) as numeric),2)) as stt_avg from( select present_table.district_id,present_table.date as att_date,present_table.sum as teachers_present ,total_teachers.sum as total_teachers from datasets.sch_att_teachers_marked_present_daily_district as present_table join datasets.sch_att_total_teachers_daily_district as total_teachers on present_table.date = total_teachers.date and present_table.district_id = total_teachers.district_id) as a join dimensions.district as district_wise_table on district_wise_table.district_id = a.district_id where a.att_date between '01-01-2021' and '05-05-2023' group by a.district_id, district_name,a.total_teachers ,a.district_id order by stt_avg asc",
},
"actions": {
"queries": {
"timeSeries":"SELECT subject,round(cast(AVG(obtained_marks/total_marks)*100 as numeric),2) AS average FROM( SELECT obtained_marks.sum AS obtained_marks, total_marks.sum AS total_marks, obtained_marks.grade_id, obtained_marks.academicyear_id, obtained_marks.subject_id, obtained_marks.exam_id, subject.subject FROM datasets.assessment_obtainedmarks_bWBOdTt2fndsW2k7dSkK AS obtained_marks INNER JOIN datasets.assessment_totalmarks_eTt2dmFxQlM6YwIfCgk5 AS total_marks ON total_marks.school_id = obtained_marks.school_id INNER JOIN dimensions.subject AS subject ON subject.subject_id = obtained_marks.subject_id INNER JOIN dimensions.exam as exam on exam.exam_id=obtained_marks.exam_id INNER JOIN dimensions.grade AS grade ON grade.grade_id = obtained_marks.grade_id) AS student_assessment GROUP BY subject;"
},
"level": "district"
}
},
{
"name": "District",
"labelProp": "district_name",
"valueProp": "district_id",
"hierarchyLevel": "2",
"timeSeriesQueries": {
"timeSeries": "select block_name as level, block_name, a.block_id, sum(a.total_teachers) as total_teachers, ceil(round(CAST(COALESCE(avg(a.teachers_present/NULLIF(a.total_teachers, 0))*100) as numeric),2)) as stt_avg from (select present_table.block_id,present_table.date as att_date,present_table.sum as teachers_present,total_teachers.sum as total_teachers from datasets.sch_att_teachers_marked_present_daily_block as present_table join datasets.sch_att_total_teachers_daily_block as total_teachers on present_table.date = total_teachers.date and present_table.block_id = total_teachers.block_id) as a join dimensions.block as block_wise_table on block_wise_table.block_id = a.block_id where district_id = {district_id} and a.att_date between startDate and endDate group by a.block_id, block_name order by stt_avg asc",
},
"actions": {
"queries": {
"timeSeries":"SELECT subject,round(cast(AVG(obtained_marks/total_marks)*100 as numeric),2) AS average FROM( SELECT obtained_marks.sum AS obtained_marks, total_marks.sum AS total_marks, obtained_marks.subject_id, obtained_marks.grade_id, obtained_marks.exam_id, obtained_marks.academicyear_id, subject.subject, district.district_id FROM datasets.assessment_obtainedmarks_bWBOdTt2fndsW2k7dSkK AS obtained_marks INNER JOIN datasets.assessment_totalmarks_eTt2dmFxQlM6YwIfCgk5 AS total_marks ON total_marks.school_id = obtained_marks.school_id INNER JOIN dimensions.subject AS subject ON subject.subject_id = obtained_marks.subject_id INNER JOIN dimensions.school AS school ON school.school_id = obtained_marks.school_id INNER JOIN dimensions.exam as exam on exam.exam_id=obtained_marks.exam_id INNER JOIN dimensions.grade AS grade ON grade.grade_id = obtained_marks.grade_id INNER JOIN dimensions.district AS district ON district.district_id = school.district_id) AS student_assessment WHERE district_id = {district_id} GROUP BY subject;",
},
"level": "block"
}
},
{
"name": "Block",
"labelProp": "block_name",
"valueProp": "block_id",
"hierarchyLevel": "3",
"timeSeriesQueries": {
"timeSeries": "select cluster_name as level, cluster_name, a.cluster_id, sum(a.total_teachers) as total_teachers, ceil(round(CAST(COALESCE(avg(a.teachers_present/NULLIF(a.total_teachers, 0))*100) as numeric),2)) as stt_avg from (select present_table.cluster_id,present_table.date as att_date,present_table.sum as teachers_present,total_teachers.sum as total_teachers from datasets.sch_att_teachers_marked_present_daily_cluster as present_table join datasets.sch_att_total_teachers_daily_cluster as total_teachers on present_table.date = total_teachers.date and present_table.cluster_id = total_teachers.cluster_id) as a join dimensions.cluster as cluster_wise_table on cluster_wise_table.cluster_id = a.cluster_id where block_id = {block_id} and a.att_date between startDate and endDate group by a.cluster_id, cluster_name order by stt_avg asc",
},
"actions": {
"queries": {
"timeSeries":"SELECT subject,round(cast(AVG(obtained_marks/total_marks)*100 as numeric),2) AS average FROM( SELECT obtained_marks.sum AS obtained_marks, total_marks.sum AS total_marks, obtained_marks.subject_id, obtained_marks.grade_id, obtained_marks.exam_id, obtained_marks.academicyear_id, subject.subject, block.block_id FROM datasets.assessment_obtainedmarks_bWBOdTt2fndsW2k7dSkK AS obtained_marks INNER JOIN datasets.assessment_totalmarks_eTt2dmFxQlM6YwIfCgk5 AS total_marks ON total_marks.school_id = obtained_marks.school_id INNER JOIN dimensions.subject AS subject ON subject.subject_id = obtained_marks.subject_id INNER JOIN dimensions.school AS school ON school.school_id = obtained_marks.school_id INNER JOIN dimensions.exam as exam on exam.exam_id=obtained_marks.exam_id INNER JOIN dimensions.grade AS grade ON grade.grade_id = obtained_marks.grade_id INNER JOIN dimensions.block AS block ON block.block_id = school.block_id) AS student_assessment WHERE block_id = {block_id} GROUP BY subject;"
},
"level": "cluster"
}
},
{
"name": "Cluster",
"labelProp": "cluster_name",
"valueProp": "cluster_id",
"hierarchyLevel": "4",
"timeSeriesQueries": {
"timeSeries": "select school_name as level, school_name, a.school_id, sum(a.total_teachers) as total_teachers, ceil(round(CAST(COALESCE(avg(a.teachers_present/NULLIF(a.total_teachers, 0))*100) as numeric),2)) as stt_avg from (select present_table.school_id,present_table.date as att_date,present_table.sum as teachers_present,total_teachers.sum as total_teachers from datasets.sch_att_teachers_marked_present_daily_school as present_table join datasets.sch_att_total_teachers_daily_school as total_teachers on present_table.date = total_teachers.date and present_table.school_id = total_teachers.school_id) as a join dimensions.school as school_wise_table on school_wise_table.school_id = a.school_id where cluster_id = {cluster_id} and a.att_date between startDate and endDate group by a.school_id, school_name order by stt_avg asc",
},
"actions": {
"queries": {
"timeSeries":"SELECT subject,round(cast(AVG(obtained_marks/total_marks)*100 as numeric),2) AS average FROM( SELECT obtained_marks.sum AS obtained_marks, total_marks.sum AS total_marks, obtained_marks.subject_id, obtained_marks.grade_id, obtained_marks.exam_id, obtained_marks.academicyear_id, subject.subject, cluster.cluster_id FROM datasets.assessment_obtainedmarks_bWBOdTt2fndsW2k7dSkK AS obtained_marks INNER JOIN datasets.assessment_totalmarks_eTt2dmFxQlM6YwIfCgk5 AS total_marks ON total_marks.school_id = obtained_marks.school_id INNER JOIN dimensions.subject AS subject ON subject.subject_id = obtained_marks.subject_id INNER JOIN dimensions.school AS school ON school.school_id = obtained_marks.school_id INNER JOIN dimensions.exam as exam on exam.exam_id=obtained_marks.exam_id INNER JOIN dimensions.grade AS grade ON grade.grade_id = obtained_marks.grade_id INNER JOIN dimensions.cluster AS cluster ON cluster.cluster_id = school.cluster_id) AS student_assessment WHERE cluster_id = {cluster_id} GROUP BY subject;"
},
"level": "school"
}
},

],
"options": {
"barChart": {
"metricLabelProp": "% Teacher Present",
"metricValueProp": "stt_avg",
Expand Down
Loading