@@ -0,0 +1,30 @@
|
||||
<mat-card class="card">
|
||||
|
||||
<mat-card-header class="header">
|
||||
<h3 fxFlex="100%">
|
||||
<fa-icon icon="donate"></fa-icon>
|
||||
Amount Collected
|
||||
<div>
|
||||
<mat-form-field id="office" fxFlex="94%">
|
||||
<mat-label>Office</mat-label>
|
||||
<mat-select [formControl]="officeId">
|
||||
<mat-option *ngFor="let office of officeData" [value]="office.id">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</h3>
|
||||
</mat-card-header>
|
||||
|
||||
<mat-card-content>
|
||||
<!-- Structural directives like *ngIf break the canvas -->
|
||||
<div [ngStyle]="{'display': (hideOutput) ? 'none' : 'block'}">
|
||||
<canvas id="collection-pie" width="800" height="600"></canvas>
|
||||
</div>
|
||||
<div *ngIf="showFallback" class="fallback" fxLayoutAlign="center center">
|
||||
<p>No Data</p>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
||||
</mat-card>
|
||||
@@ -0,0 +1,12 @@
|
||||
.card {
|
||||
width: 27.5rem;
|
||||
padding: 0;
|
||||
.header {
|
||||
#office{
|
||||
margin-bottom: -1.20em;
|
||||
}
|
||||
}
|
||||
.fallback {
|
||||
height: 20rem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AmountCollectedPieComponent } from './amount-collected-pie.component';
|
||||
|
||||
describe('AmountCollectedPieComponent', () => {
|
||||
let component: AmountCollectedPieComponent;
|
||||
let fixture: ComponentFixture<AmountCollectedPieComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AmountCollectedPieComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AmountCollectedPieComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,104 @@
|
||||
/** Angular Imports */
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
/** Custom Services */
|
||||
import { HomeService } from '../../home.service';
|
||||
|
||||
/** Charting Imports */
|
||||
import Chart from 'chart.js';
|
||||
|
||||
/**
|
||||
* Amount Collected Pie Chart Component
|
||||
*/
|
||||
@Component({
|
||||
selector: 'mifosx-amount-collected-pie',
|
||||
templateUrl: './amount-collected-pie.component.html',
|
||||
styleUrls: ['./amount-collected-pie.component.scss']
|
||||
})
|
||||
export class AmountCollectedPieComponent implements OnInit {
|
||||
|
||||
/** Static Form control for office Id */
|
||||
officeId = new FormControl();
|
||||
/** Office Data */
|
||||
officeData: any;
|
||||
/** Chart.js chart */
|
||||
chart: any;
|
||||
/** Substitute for resolver */
|
||||
hideOutput = true;
|
||||
/** Shows fallback element */
|
||||
showFallback = false;
|
||||
|
||||
/**
|
||||
* Fetches offices data from `resolve`.
|
||||
* @param {HomeService} homeService Home Service.
|
||||
* @param {ActivatedRoute} route Activated Route.
|
||||
*/
|
||||
constructor(private homeService: HomeService,
|
||||
private route: ActivatedRoute) {
|
||||
this.route.data.subscribe( (data: { offices: any }) => {
|
||||
this.officeData = data.offices;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pie chart
|
||||
* Initialize with office Id 1 for better UX.
|
||||
*/
|
||||
ngOnInit() {
|
||||
this.getChartData();
|
||||
this.officeId.patchValue(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribes to value changes of office Id fetches chart data accordingly.
|
||||
*/
|
||||
getChartData() {
|
||||
this.officeId.valueChanges.subscribe((value: number) => {
|
||||
this.homeService.getCollectedAmount(value).subscribe((response: any) => {
|
||||
const data = Object.entries(response[0]).map(entry => entry[1]);
|
||||
if (!(data[0] === 0 && data[1] === 0)) {
|
||||
this.setChart(data);
|
||||
this.hideOutput = false;
|
||||
this.showFallback = false;
|
||||
} else {
|
||||
this.showFallback = true;
|
||||
this.hideOutput = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Chart.js pie chart
|
||||
* Refer: https://www.chartjs.org/docs/latest/charts/doughnut.html for configuration details.
|
||||
* @param {any} data Chart Data.
|
||||
*/
|
||||
setChart(data: any) {
|
||||
if (!this.chart) {
|
||||
this.chart = new Chart('collection-pie', {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: ['Pending', 'Collected'],
|
||||
datasets: [{
|
||||
backgroundColor: ['red', 'green'],
|
||||
data: data
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
layout: {
|
||||
padding: {
|
||||
top: 10,
|
||||
bottom: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.chart.data.datasets[0].data = data;
|
||||
this.chart.update();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user