首页 > 解决方案 > 将json数据分配给Ng2图表中的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
    }
]

我正在使用模板进行测试,这是它的链接,它使用 ng2 图表:

紫角

GitHub 链接GitHub 链接

我尝试将这些jSon数据分配到数据集中,并尝试使用模板中的 ng2 图表:

图表

我的计划是jSon在图表中将最近 4/6 天的出勤数据(数据)显示为水平线和垂直线上的日期,它将显示特定日期的教师/学生总出勤率。我已经分析了图表并尝试了以下方法:

//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

标签: angulartypescriptangular8ng2-charts

解决方案


概念

  1. 按(学生/教师)分组lastFour数据。type
  2. groupedByTypeResult(步骤 1)中删除键以附加到chartData和 for visitSaleChartData
  3. DatePipe使用和 Distinct date(删除重复项)格式化日期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)
    );
  }
}

StackBlitz 上的示例解决方案

输出

在此处输入图像描述


推荐阅读