Reputation: 59
I have a list of data in a json file. I want display all the months but I want the year that matches to just show as one big year. I posted this question in a different name, as no one saw it. Look at the image: The image shows the same data but it's been split into year and month. Rather than it repeating the word 2017 over and over again, I want it just say 2017 in the middle of the pink block. Problem is it needs to correspond with the data as the data changes all the time, where it says 2017 could easily change to 2018 so it needs to say the correct year that the data specifies it is.
JSON:
[
{
"month": "2017-03-01",
"modelVolume" [{
"id": 1,
"model": P213
}]
}
{
"month": "2017-03-01",
"modelVolume" [{
"id": 1,
"model": P213
}]
}
{
"month": "2017-03-01",
"modelVolume" [{
"id": 1,
"model": P213
}]
}
{
"month": "2017-03-01",
"modelVolume" [{
"id": 1,
"model": P213
}]
}
{
"month": "2017-03-01",
"modelVolume" [{
"id": 1,
"model": P213
}]
}
{
"month": "2017-03-01",
"modelVolume" [{
"id": 1,
"model": P213
}]
}
{
"month": "2017-03-01",
"modelVolume" [{
"id": 1,
"model": P213
}]
}
{
"month": "2017-03-01",
"modelVolume" [{
"id": 1,
"model": P213
}]
}
{
"month": "2017-03-01",
"modelVolume" [{
"id": 1,
"model": P213
}]
}]
I'm only using the "month" data for this problem.
HTML: Year:
<div class="row justify-content-md-center">
<div class="col-md-auto">
<table id="year">
<tr>
<th class="y17" class="y18" *ngFor="let value of groupVolumes(groupKeys()[0])" [ngClass]="getYear(value.month)">{{ value.month | date: "yyyy" | uppercase }}</th>
</tr>
</table>
</div>
</div>
Month:
<div class="row justify-content-md-center">
<div class="col-md-auto" class="scroll">
<table id ="t2">
<tr>
<th class="line">Line 1</th>
<th class="y18" *ngFor="let value of groupVolumes(groupKeys()[0])" [ngClass]="getYear(value.month)">{{ value.month | date: "MMM" | uppercase }}</th>
</tr>
Upvotes: 0
Views: 57
Reputation: 4247
Here's a simple prototype that answers your needs:
For simplicity, I stored the content of the JSON file in a field variable called data
.
From what I understood, the content of this file will change dynamically, so you'll need to declare the field data
as an Input of this component and implement the abstract method ngOnChanges
which will call processData
each time the input data
changes.
Here's the code:
import {Component} from '@angular/core';
@Component({
selector: 'app-root',
template: `
<table id="year">
<tr>
<th *ngFor="let year of availableYears" [attr.colspan]="displayedData[year].length">
{{ year }}
</th>
</tr>
<tr>
<ng-container *ngFor="let year of availableYears">
<td *ngFor="let data of displayedData[year]">
{{ data.month | date: "MMM" | uppercase }}
</td>
</ng-container>
</tr>
</table>`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
// raw data
public data = [
{
month: '2017-02-01',
modelVolume: [{
id: 1,
model: 'P213'
}]
},
{
month: '2017-07-01',
modelVolume: [{
id: 1,
model: 'P213'
}]
},
{
month: '2017-11-01',
modelVolume: [{
id: 1,
model: 'P213'
}]
},
{
month: '2016-09-01',
modelVolume: [{
id: 1,
model: 'P213'
}]
},
{
month: '2016-10-01',
modelVolume: [{
id: 1,
model: 'P213'
}]
},
{
month: '2017-03-01',
modelVolume: [{
id: 1,
model: 'P213'
}]
},
{
month: '2018-08-01',
modelVolume: [{
id: 1,
model: 'P213'
}]
},
{
month: '2018-05-01',
modelVolume: [{
id: 1,
model: 'P213'
}]
},
{
month: '2015-04-01',
modelVolume: [{
id: 1,
model: 'P213'
}]
}];
// displayedData is the object that will be used in the template to map the data of each year
public displayedData = {};
// availableYears will contain the range of years of data
public availableYears = [];
constructor() {
this.processData();
}
private processData() {
this.data.forEach((item: any) => {
const itemYear = new Date(item.month).getFullYear();
if (!this.displayedData[itemYear]) {
// add the year when it's still not inside availableYears
this.availableYears.push(itemYear);
// store the first item corresponding to that year in an array
this.displayedData[itemYear] = [item];
} else {
// if the year already exists in the object we simply append the item to the array
this.displayedData[itemYear].push(item);
}
});
// optional sort to display years in order
this.availableYears.sort();
}
}
Upvotes: 1