I have the below JSON data and these are attendance details for the few last days:
[
{
"date": "2021-09-07T00:00:00",
"type": "Teacher",
"total": 744
},
{
"date": "2021-09-07T00:00:00",
"type": "Student",
"total": 4769
},
{
"date": "2021-09-08T00:00:00",
"type": "Teacher",
"total": 740
},
{
"date": "2021-09-08T00:00:00",
"type": "Student",
"total": 4743
},
{
"date": "2021-09-09T00:00:00",
"type": "Teacher",
"total": 736
},
{
"date": "2021-09-09T00:00:00",
"type": "Student",
"total": 4714
},
{
"date": "2021-09-10T00:00:00",
"type": "Teacher",
"total": 52
},
{
"date": "2021-09-10T00:00:00",
"type": "Student",
"total": 47
},
{
"date": "2021-09-11T00:00:00",
"type": "Teacher",
"total": 648
},
{
"date": "2021-09-11T00:00:00",
"type": "Student",
"total": 4341
}
]
I am using a template for test purposes and this is the link for it, it uses ng2-chart:
GitHub Link: GitHub Link
I tried to assign those JSON data into a dataset and tried to use the ng2-chart from the template:
My plan is to show the last 4/6 days' attendance data (JSON data) in the chart as dates in the horizontal line and in the vertical line, it'll have the teacher/student total attendance for specific dates. I analyzed the chart already and tried something as follows:
//Get Last Four Days Data
LoadLastFour() {
debugger;
this.dataservice.GetLastFour().subscribe(result => {
this.lastFour = JSON.parse(result);
this.visitSaleChartData = [{
label: this.lastFour.map((m: any) => m.type),
data: this.lastFour.map((m: any) => m.total),
borderWidth: 1,
fill: false,
}];
this.visitSaleChartLabels = [this.lastFour.map((m: any) => m.date)]
console.log(this.lastFour);
}, error => console.error(error));
}
In the template, it has data source as follows:
<canvas baseChart #visitSaleChart
[chartType]="'bar'" *ngIf="visitSaleChartData"
[datasets]="visitSaleChartData" [labels]="visitSaleChartLabels"
[options]="visitSaleChartOptions" [colors]="visitSaleChartColors"></canvas>
visitSaleChartData = [{
label: 'CHN',
data: [20, 40, 15, 35, 25, 50, 30, 20],
borderWidth: 1,
fill: false,
},
{
label: 'USA',
data: [40, 30, 20, 10, 50, 15, 35, 40],
borderWidth: 1,
fill: false,
},
{
label: 'UK',
data: [70, 10, 30, 40, 25, 50, 15, 30],
borderWidth: 1,
fill: false,
}];
visitSaleChartLabels = ["2013", "2014", "2014", "2015", "2016", "2017"];
The issue is when I render the chart in the front-end, it shows only a bar and under it, all the dates are aligned row by row though it should create the dates horizontally side by side.
Any way that I can make it work or require anything specific?
Working Sample: Stackblitz
lastFour
data by type
(Student/Teacher).groupedByTypeResult
(Step 1) to append to chartData
and for visitSaleChartData
.DatePipe
and Distinct date (remove duplicates) for visitSaleChartLabels
.app.component.html
<div style="display: block;">
<canvas baseChart #visitSaleChart
[chartType]="'bar'"
*ngIf="visitSaleChartData"
[datasets]="visitSaleChartData"
[labels]="visitSaleChartLabels"
[options]="visitSaleChartOptions"
[colors]="visitSaleChartColors"
></canvas>
</div>
export class AppComponent {
lastFour: any[] = [];
visitSaleChartData: ChartDataSets[] = [];
visitSaleChartLabels = [];
visitSaleChartOptions = {};
visitSaleChartColors = [];
constructor(private dataservice: DataService, private datePipe: DatePipe) {}
ngOnInit() {
this.LoadLastFour();
}
LoadLastFour() {
this.dataservice.GetLastFour().subscribe(
result => {
this.lastFour = result;
// Group Last Four by Type
let groupedByTypeResult: any[] = this.lastFour.reduce(function(
obj: any,
item: any
) {
let type = item.type;
obj[type] = obj[type] || { label: item.type, data: [] };
obj[type].data.push(item.total);
return obj;
},
{});
// Remove key to append to chartData
let chartData = [];
for (let type in groupedByTypeResult) {
chartData.push({
label: groupedByTypeResult[type].label,
data: groupedByTypeResult[type].data,
borderWidth: 1,
fill: false
});
}
this.visitSaleChartData = chartData;
// Distinct date for chartLabel
this.visitSaleChartLabels = [
...new Map(
this.lastFour.map(item => [
item.date,
this.datePipe.transform(item.date, 'yyyy-MM-dd')
])
).values()
];
},
error => console.error(error)
);
}
}
Output