【问题标题】:Angular2 Update ng2-charts with labelsAngular2 用标签更新 ng2-charts
【发布时间】:2017-07-25 15:22:42
【问题描述】:

这些天我开始使用 Angular2,并且对框架 ng2-charts 有疑问。

这是我的 component.ts 代码:

import { Component } from '@angular/core';
import { ChartsModule } from 'ng2-charts';
import { PredictionService } from './prediction.service'

@Component({
  selector: 'prediction-result-chart',
  templateUrl: './predictionResultChart.component.html'
})

export class PredictionResultChartComponent{

  public pieChartLabels:string[] = [];
  public pieChartData:number[] = [];
  public pieChartType:string = 'pie';
  public JSONobject = {}

  constructor(private predictionService: PredictionService){
    this.getPredictions();
  }

  public getPredictions() {
    this.predictionService.getPredictions('hello').do(result => this.populateChart(result)).subscribe();
  }

  public populateChart(obj): void{
    let labels:string[] = [];
    let data:number[] = [];
    for (var i = 0; i < obj.predictions.length; i++)
    {
      labels.push(String(obj.predictions[i].class));
      data.push(obj.predictions[i].percentage);
    };
    this.pieChartData = data;
    this.pieChartLabels = labels;
  }

  public chartClicked(e:any):void {}
  public chartHovered(e:any):void {}

}

component.html 代码:

<div style="display: block">
  <canvas baseChart
      [data]="pieChartData"
      [labels]="pieChartLabels"
      [chartType]="pieChartType"
      (chartHover)="chartHovered($event)"
      (chartClick)="chartClicked($event)"></canvas>
</div>

服务代码:

import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';

import { Observable }     from 'rxjs/Observable';
import 'rxjs/add/operator/map';


@Injectable()
export class PredictionService {

  private baseUrl: string = 'http://localhost:8080/predict/';
  constructor(private http : Http){
  }

  getPredictions(text :string) {
    return this.http.get(this.baseUrl + text).map(res => res.json());
  }

}

使用上面的代码,这是我所拥有的,没有任何颜色的图表:

事实上,当我深入研究我的代码时,HTML 组件在开始时获取变量并随后更新它们。所以当标签为空时,即使我添加了一些标签,它们也会被添加为未定义的。所以我有一个带有正确值但没有正确标签的图表。一切都标记为未定义。

如果我在开始时启动标签,我将有一个具有正确值的良好彩色图表

所以我的问题是:

如何加载数据,然后渲染 HTML 组件?

有没有办法在没有数据的情况下渲染 chart.js 组件并用正确的标签和数据更新它?

需要任何帮助,谢谢。

【问题讨论】:

    标签: javascript angular charts chart.js ng2-charts


    【解决方案1】:

    在标准chart.js 中,您可以在修改图表数据(包括标签)后使用.update() 原型方法重新渲染图表。

    但是,ng2-charts 似乎没有提供触发更新的机制(根据this github issue)。我在 Angular2 方面的经验并不丰富,但也许这对你有用?该方法取自 zbagley 在 17 天前发布的 github issue 中的评论(不幸的是,我找不到生成引用此特定评论的 url 的方法)。

    方法是在数据可用之前基本上不渲染图表。以下是对 component.ts 代码的更改。

    import { Component } from '@angular/core';
    import { ChartsModule } from 'ng2-charts';
    import { PredictionService } from './prediction.service'
    
    @Component({
      selector: 'prediction-result-chart',
      templateUrl: './predictionResultChart.component.html'
    })
    
    export class PredictionResultChartComponent {    
      public pieChartLabels:string[] = [];
      public pieChartData:number[] = [];
      public pieChartType:string = 'pie';
      public JSONobject = {};
      public isDataAvailable:boolean = false;
    
      constructor(private predictionService: PredictionService){
        this.getPredictions();
      }
    
      public getPredictions() {
        this.predictionService.getPredictions('hello').do(result => this.populateChart(result)).subscribe();
      }
    
      public populateChart(obj): void {        
        let labels:string[] = [];
        let data:number[] = [];
        for (var i = 0; i < obj.predictions.length; i++)
        {
          labels.push(String(obj.predictions[i].class));
          data.push(obj.predictions[i].percentage);
        };
        this.pieChartData = data;
        this.pieChartLabels = labels;
        this.isDataAvailable = true;
      }
    
      public chartClicked(e:any):void {}
      public chartHovered(e:any):void {}    
    }
    

    然后您将在 component.html 代码中使用ngIf

    <div style="display: block" *ngIf="isDataAvailable">
      <canvas baseChart
          [data]="pieChartData"
          [labels]="pieChartLabels"
          [chartType]="pieChartType"
          (chartHover)="chartHovered($event)"
          (chartClick)="chartClicked($event)"></canvas>
    </div>
    

    【讨论】:

    • 我从 Web 服务传递数据作为图表的数据源时遇到了同样的问题。
    • 非常感谢,这对我来说很好用。我刚看到答案:)。我使用 ngIf 来测试是否有数据并且它有效
    • 当我们尝试更新图表时旧标签和值数组看起来像 旧数据 label = ['html', "css", "javascript"];数据 = [10,20,30]; 新数据 label = ['html', "css", "javascript", "json", "image"];数据 = [10,20,30, 40,50];图表标签和颜色未正确呈现。更新图表时添加新字段时会发生这种情况。如何解决这个问题?
    • 如何在图表列内添加标签或静态文本
    【解决方案2】:

    当我打印到控制台但未显示在图表上时,我可以获得值。

    this.pieChartLabels :: ['PayDirect agent deposit','GtCollections agent deposit','Quickteller agent deposit']
    this.pieChartData :: [1990,1202,2476]
    

    有没有办法更新图表。似乎图表是在从 Web 服务接收数据之前加载的。

    isDataAvailable2 = true
    

    但图表从未加载。

    【讨论】:

      【解决方案3】:

      我通过更新配置属性中的标签来更新图表标签。

      import { Component } from '@angular/core';
      import { ChartsModule } from 'ng2-charts';
      import { PredictionService } from './prediction.service'
      import { BaseChartDirective } from 'ng2-charts'; // ----- added
      
      @Component({
        selector: 'prediction-result-chart',
        templateUrl: './predictionResultChart.component.html'
      })
      
      export class PredictionResultChartComponent {    
        public pieChartLabels:string[] = [];
        public pieChartData:number[] = [];
        public pieChartType:string = 'pie';
        public JSONobject = {};
        public isDataAvailable:boolean = false;
      
        @ViewChild('mainChart') mainChart: BaseChartDirective; // ----- added
      
        constructor(private predictionService: PredictionService){
          this.getPredictions();
        }
      
        public getPredictions() {
          this.predictionService.getPredictions('hello').do(result => 
          this.populateChart(result)).subscribe();
        }
      
        public populateChart(obj): void {        
          let labels:string[] = [];
          let data:number[] = [];
          for (var i = 0; i < obj.predictions.length; i++)
          {
            labels.push(String(obj.predictions[i].class));
            data.push(obj.predictions[i].percentage);
          };
          this.pieChartData = data;
          this.mainChart.chart.config.data.labels = labels; // ---- updated
          this.isDataAvailable = true;
        }
      
        public chartClicked(e:any):void {}
        public chartHovered(e:any):void {}    
      }
      

      在 HTML 中添加 #{chartName} 以访问它

      <div style="display: block" *ngIf="isDataAvailable">
        <canvas #mainChart="base-chart" baseChart
            [data]="pieChartData"
            [labels]="pieChartLabels"
            [chartType]="pieChartType"
            (chartHover)="chartHovered($event)"
            (chartClick)="chartClicked($event)"></canvas>
      </div>
      

      【讨论】:

        【解决方案4】:

        首先你要确保标签的顺序与数据集的顺序相匹配,所以基本上你有这两个变量:

        private datasets_pie = [
            {
                label: "Commissions",
                data: Array<any>(),
                backgroundColor: Array<any>()
            }
        ];
        private labels_pie = Array<any>();
        

        其次,我对颜色有同样的问题,所以我不得不手动插入颜色,这里是一个例子:

        private chartColors: any[] = [{ backgroundColor: ["#FFA1B5", "#7B68EE", "#87CEFA", "#B22222", "#FFE29A", "#D2B48C", "#90EE90", "#FF69B4", "#EE82EE", "#6A5ACD", "#b8436d", "#9ACD32", "#00d9f9", "#800080", "#FF6347", "#DDA0DD", "#a4c73c", "#a4add3", "#008000", "#DAA520", "#00BFFF", "#2F4F4F", "#FF8C00", "#A9A9A9", "#FFB6C1", "#00FFFF", "#6495ED", "#7FFFD4", "#F0F8FF", "#7FFF00", "#008B8B", "#9932CC", "#E9967A", "#8FBC8F", "#483D8B", "#D3D3D3", "#ADD8E6"] }];
        

        最后在正确创建这些对象之后,你必须调用这个函数:

        setTimeout(() => {
                    if (this.chart && this.chart.chart && this.chart.chart.config) {
                        this.chart.chart.config.data.labels = this.labels_pie;
                        this.chart.chart.config.data.datasets = this.datasets_pie;
                        this.chart.chart.config.data.colors = this.chartColors;
                        this.chart.chart.update();
                    }
                    this.sommeStat = this.getSomme();
                });
        

        所以我认为这可能有效:

            import { Component, ViewChild, ElementRef } from '@angular/core';
            import { ChartsModule } from 'ng2-charts';
            import { PredictionService } from './prediction.service';
            import { BaseChartDirective } from 'ng2-charts/ng2-charts';
        
            @Component({
              selector: 'prediction-result-chart',
              templateUrl: './predictionResultChart.component.html'
            })
        
            export class PredictionResultChartComponent{
                @ViewChild(BaseChartDirective) chart: BaseChartDirective;
        
              public pieChartType: string = 'doughnut';
                //public lineChartType: string = 'line';
        
                private datasets_pie = [
                    {
                        label: "Commissions",
                        data: Array<any>(),
                        backgroundColor: Array<any>()
                    }
                ];
                private labels_pie = Array<any>();
        
                //private datasets_line : LineData[] = [];
                // private datasets_line : { label : string, data : Array<any>}[] ;
                // private labels_line = Array<any>();
        
                private chartColors: any[] = [{ backgroundColor: ["#FFA1B5", "#7B68EE", "#87CEFA", "#B22222", "#FFE29A", "#D2B48C", "#90EE90", "#FF69B4", "#EE82EE", "#6A5ACD", "#b8436d", "#9ACD32", "#00d9f9", "#800080", "#FF6347", "#DDA0DD", "#a4c73c", "#a4add3", "#008000", "#DAA520", "#00BFFF", "#2F4F4F", "#FF8C00", "#A9A9A9", "#FFB6C1", "#00FFFF", "#6495ED", "#7FFFD4", "#F0F8FF", "#7FFF00", "#008B8B", "#9932CC", "#E9967A", "#8FBC8F", "#483D8B", "#D3D3D3", "#ADD8E6"] }];
        
                private options = {
                    scales: {
                        yAxes: [{
                            ticks: {
                                beginAtZero: true
                            }
                        }]
                    }
                };
              public JSONobject = {}
        
              constructor(private predictionService: PredictionService){
                this.getPredictions();
              }
        
              public getPredictions() {
                this.predictionService.getPredictions('hello').do(result => this.populateChart(result)).subscribe();
              }
        
              public populateChart(obj): void{
        
                this.labels_pie = [];
                this.datasets_pie[0]['data'] = [];
                for (var i = 0; i < obj.predictions.length; i++)
                {
                  labels.push(String(obj.predictions[i].class));
                  this.datasets_pie[0]['data'].push(obj.predictions[i].percentage);
                };
        let arrColors: any[];
                arrColors = arrColorsCopy.splice(0, this.products.length);
                this.datasets_pie[0]['backgroundColor'] = arrColors;
        
                setTimeout(() => {
                        if (this.chart && this.chart.chart && this.chart.chart.config) {
                            this.chart.chart.config.data.labels = this.labels_pie;
                            this.chart.chart.config.data.datasets = this.datasets_pie;
                            this.chart.chart.config.data.colors = this.chartColors;
                            this.chart.chart.update();
                        }
                    });
              }
        
              public chartClicked(e:any):void {}
              public chartHovered(e:any):void {}
        
            }
        

        对于 html,它应该是这样的:

        <div class="col-md-8">
                        <div class="chart">
                            <canvas baseChart [datasets]="datasets_pie" [labels]="labels_pie" [chartType]="pieChartType" [colors]="chartColors"> </canvas>
                        </div>
                    </div>
        

        就是这样,你应该试试这个方法,它应该可以工作

        【讨论】:

          猜你喜欢
          • 2017-05-22
          • 2017-09-03
          • 2016-12-28
          • 2017-12-05
          • 1970-01-01
          • 2020-09-08
          • 1970-01-01
          • 2017-07-20
          • 1970-01-01
          相关资源
          最近更新 更多