2017-04-04 183 views
3

我現在開始與Angular2一起工作,並對框架ng2-charts有疑問。Angular2使用標籤更新ng2圖表

這裏是我的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()); 
    } 

} 

隨着碼上面,這是我的有,沒有任何顏色的圖表:enter image description here

實際上,當我深入瞭解我的代碼時,HTML組件在開始時接受了變量並更新它們。因此,當標籤爲空時,即使我添加了一些標籤,它們也會被添加爲未定義的標籤。所以我有一個正確的值的圖表,但沒有正確的標籤。一切標記爲未定義。

如果我在一開始啓動的標籤,我會用正確的價值觀

良好的彩色圖表所以我的問題是:

如何加載數據,然後渲染HTML零件 ?

無論如何渲染沒有數據的chart.js組件並用正確的標籤和數據更新它?

任何幫助是必要的,謝謝。

回答

11

在標準chart.js中,您可以使用.update()原型方法在修改其數據(包括標籤)後重新呈現圖表。

但是,看來ng2-charts沒有提供觸發更新的機制(根據this github issue)。我對Angular2並不是很有經驗,但也許這對你有用?該方法取自zbagley在17天前發佈的github問題中發佈的評論(不幸的是,我找不到一種方法來生成引用此特定評論的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> 
+0

我從Web服務將數據作爲圖表數據源同樣的問題。 –

+0

非常感謝,對我來說工作得很好。我剛看到答案:)。我用了一個ngIf來測試是否有數據,它的工作 – ben

+0

感謝我的工作.. –

1

我可以得到值時,我打印到控制檯,但不顯示在圖表上。

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

有沒有更新圖表的方法。從Web服務收到數據之前,似乎圖表已加載。

isDataAvailable2 = true 

但是圖表從不加載。

0

首先你要確保標籤的順序匹配data_set的順序,因此basicly你有這兩個變量:

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> 

多數民衆贊成,你應該嘗試這種方式,它應該工作

1

我通過更新config屬性中的標籤更新了圖表標籤。

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>