Ng2-Chart - 将 JSON 数据分配给数据集

Ng2-Chart - Assign JSON Data To DataSet

我有以下 JSON 数据,这些是最近几天的出勤详情:

[
    {
        "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
    }
]

我正在使用模板进行测试,这是 link,它使用 ng2-chart:

Purple Angular

GitHub Link: GitHub Link

我尝试将这些 JSON 数据分配到数据集中并尝试使用模板中的 ng2-chart:

我的计划是在图表中将最近 4/6 天的出勤数据(JSON 数据)显示为水平线和垂直线的日期,它将具有 teacher/student 特定日期的总出勤率。我已经分析了图表并尝试了如下操作:

//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)); 
} 

在模板中,数据源如下:

<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"];

问题是当我在前端渲染图表时,它只显示一个条形,在它下面,所有日期都逐行对齐,尽管它应该水平并排创建日期。

有什么方法可以使它工作或需要任何特定的东西?

工作样本Stackblitz

概念

  1. type (Student/Teacher) 对 lastFour 数据进行分组。
  2. groupedByTypeResult 中删除密钥(第 1 步)以附加到 chartDatavisitSaleChartData
  3. 格式化日期 DatePipevisitSaleChartLabels 的不同日期(删除重复项)。

解决方案

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)
    );
  }
}

Sample Solution on StackBlitz

Output