web-dev-qa-db-ja.com

動的に更新されたng2チャート

ng2-chartsからchartを動的に更新することは可能ですか? angular2-highchartsのような他のライブラリがあることは知っていますが、ng2-chartsを使用して処理したいと思います。主な質問は、ボタンをクリックした後、どうすればchartを再描画できますか?ウィンドウのサイズを変更するとデータが更新されるので、手動で行うには任意のオプションが必要です。

https://plnkr.co/edit/fXQTIjONhzeMDYmAWTe1?p=preview

5
ulou

私はそれを理解します、多分それは最良の既存のオプションではありませんが、それは機能します。既存のchartを更新することはできませんが、既存のchartを使用して新しいポイントを作成し、新しいポイントを追加することはできます。チャートのアニメーションをオフにすることで、より良い効果を得ることができます。

問題を解決した関数:

updateChart(){
   let _dataSets:Array<any> = new Array(this.datasets.length);
   for (let i = 0; i < this.datasets.length; i++) {
      _dataSets[i] = {data: new Array(this.datasets[i].data.length), label: this.datasets[i].label};
      for (let j = 0; j < this.datasets[i].data.length; j++) {
        _dataSets[i].data[j] = this.datasets[i].data[j];
      }
   }
   this.datasets = _dataSets;
}

ライブデモ: https://plnkr.co/edit/fXQTIjONhzeMDYmAWTe1?p=preview

@ UPDATE:@ Raydelto Hernandezが以下のコメントで述べているように、より良い解決策は次のとおりです。

updateChart(){
    this.datasets = this.dataset.slice()
}
6
ulou

良い方法は、APIを使用してグラフを再描画するために、グラフ自体を把握することです。

export class MyClass {
 @ViewChild( BaseChartDirective ) chart: BaseChartDirective;

  private updateChart(){
   this.chart.ngOnChanges({});
  }

}

最近、ng2-chartsを使用する必要があり、この解決策が見つかるまで、データの更新で非常に大きな問題が発生していました。

<div class="chart">
        <canvas baseChart [datasets]="datasets_lines" [labels]="labels_line" [colors]="chartColors" [options]="options" [chartType]="lineChartType">
        </canvas>
</div>

そしてここに私が私のコンポーネントに持っているもの:

import { Component, OnInit, Pipe, ViewChild, ElementRef } from '@angular/core';
import { BaseChartDirective } from 'ng2-charts/ng2-charts';

@Component({
    moduleId: module.id,
    selector: 'product-detail',
    templateUrl: 'product-detail.component.html'
})

export class ProductDetailComponent {
    @ViewChild(BaseChartDirective) chart: BaseChartDirective;

    private datasets_lines: { label: string, backgroundColor: string, borderColor: string, data: Array<any> }[] = [
        {
            label: "Quantities",
            data: Array<any>()
        }
    ];

    private labels_line = Array<any>();

    private options = {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero: true
                }
            }]
        }
    };


    constructor() { }
    ngOnInit() {

        this.getStats();

    }
    getStats() {

        this.labels_line = this.getDates();

        this._statsService.getStatistics(this.startDate, this.endDate, 'comparaison')
            .subscribe(
            res => {
                console.log('getStats success');
                this.stats = res;

                this.datasets_lines = [];

                let arr: any[];
                arr = [];
                for (let stat of this.stats) {
                    arr.Push(stat.quantity);
                }

                this.datasets_lines.Push({
                    label: 'title',
                    data: arr
                });

                this.refresh_chart();

            },
            err => {
                console.log("getStats failed from component");
            },
            () => {
                console.log('getStats finished');
            });
    }

    refresh_chart() {
        setTimeout(() => {
            console.log(this.datasets_lines_copy);
            console.log(this.datasets_lines);
            if (this.chart && this.chart.chart && this.chart.chart.config) {
                this.chart.chart.config.data.labels = this.labels_line;
                this.chart.chart.config.data.datasets = this.datasets_lines;
                this.chart.chart.update();
            }
        });
    }

    getDates() {
        let dateArray: string[] = [];
        let currentDate: Date = new Date();
        currentDate.setTime(this.startDate.getTime());
        let pushed: string;
        for (let i = 1; i < this.daysNum; i++) {
            pushed = currentDate == null ? '' : this._datePipe.transform(currentDate, 'dd/MM/yyyy');
            dateArray.Push(pushed);
            currentDate.setTime(currentDate.getTime() + 24 * 60 * 60 * 1000);
        }
        return dateArray;
    }    
}

これが正しい方法だと確信しています。

**これは私にとってはうまくいきました-円グラフで:*

Component.html:

 <canvas baseChart [colors]="chartColors" [data]="pieChartData" [labels]="pieChartLabels" [chartType]="pieChartType"></canvas>

Component.ts:

ヘッダーセクション:

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { Chart } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts/ng2-charts';

エクスポートクラスの宣言セクション:

@ViewChild(BaseChartDirective) chart: BaseChartDirective;
// for custom colors
public chartColors: Array<any> = [{
backgroundColor: ['rgb(87, 111, 158)', 'yellow', 'pink', 'rgb(102, 151, 185)'],
borderColor: ['white', 'white', 'white', 'white']
}];

円グラフデータを更新するブロックの後(サービス/ソケットまたはその他の手段を使用):

this.chart.chart.update();
3
Abhijeet

ng2-chartsから任意のチャートを動的に更新することが可能です。例: http://plnkr.co/edit/m3fBiHpKuDgYG6GVdJQD?p=preview

そのAngular更新チャート、変数、または参照を変更する必要があります。配列要素の値を変更するだけでは、変数と参照は変更されません。 Githubも参照

1
Sfairet

しばらく検索してこの記事を見つけました。次に、この記事に記載されているすべての解決策を試しましたが、どれも正しく機能していませんでした。最後に、動的コンポーネントを使用して解決しました。

親コンポーネントに動的に追加されるコンポーネントに動的データを提供しました。私は プロセス全体 について書いたので、あなたは挑戦を経験しません。

0
Samiullah Khan