Primeng: Charts do not update

Created on 6 Jul 2016  路  13Comments  路  Source: primefaces/primeng

I'm trying to update a chart, but not working just changing the values, and calling the function update fails since I don't know wha'ts the Chart.js instance:

//Template
<ul class="dropdown-menu" role="menu" aria-labelledby="simple-btn-keyboard-nav">
                                <li *ngFor="let item of volumeSalesFilter" role="menuitem"><a class="dropdown-item" (click)="volumesSalesFilterClicked(item, chartVolumeSales)">{{item.label}}</a></li>
                            </ul>
<p-chart type="line" height="50" [data]="volumeSalesData"  [options]="volumeSalesOptions" #chartVolumeSales></p-chart>

//Component
volumesSalesFilterClicked(item: SelectItem, chart:any) {
        this.volumeSalesData.labels = this.filterLabels[item.value];
        this.volumeSalesData.datasets[0].data = this.lineChartLabels;
        chart.reset();
        console.log(this.volumeSalesData.labels);
        console.log(this.volumeSalesData.datasets[0].data);
        this.volumeSalesFilterSelected = item.label;
    }
defect

Most helpful comment

Similar issue: (EDIT: [email protected])

Calling chart.refresh() from a separate, "manual" button function updates the chart immediately for me.

But calling it after changing the value of datasets[0].data within a .subscribe() block doesn't. Triggering the function with the .subscribe() block twice does update the chart the second time, though.

Am I missing an initialization step somewhere?

export class GraphTest implements OnInit {
    @ViewChild("chart") chart: UIChart
    graphData: any;

    constructor(dataservice: DataService) {}

    ngOnInit (): void {
        this.graphData = {
            labels: ['a', 'b', 'c', 'd', 'e'],
            datasets: [{label: 'Label', data: [1, 2, 3, 4, 5]}]
        };
    }

    // This updates the chart immediately on button press
    update (chart: UIChart): void {
        this.graphData.datasets[0].data = [6, 7, 8, 9, 10];
        chart.refresh();
    }

    // I have to press this button twice for the chart to update
    getRemote (datsetId: number, chart: UIChart): void {
        // HTTP request to get data from remote server
        this.dataservice.getData(datasetId)
            .subscribe(res => {
                this.graphData.datasets[0].data = res.data;
                chart.refresh();
             });
    }
}
<p-chart #chart type="line" [data]="graphData"></p-chart>
<button pButton type="button" label="Update" (click)="update(chart)"></button>
<button pButton type="button" label="Get Remote" (click)="getRemote(17, chart)"></button>

All 13 comments

@MarcelCremer ?

+1 I really need this to be fixed.

EDIT: I've looked into the code and tried to find the issue.. seems like the iterable differ (angular2) doesn't detect the changes. It returns 0 everytime and that's why the "if" to reinit the chart doesn't get executed.

EDIT2: The problem I got is that when I change the datasets[x].data, it does not get detected by the changes-variable in chart.ts. When I set changes to "this.differs.diff(this.data.datasets[0].data)", it works just fine.
So changes on "this.datasets" do not get detected by the iterablediffer.
I then tried setting a variable to the current state of the datatable ( var current= this.data.datasets[0]), used shift() on "this.data.dataset" and then used push(current) to make it get detected.
That doesn't work either.
I'm actually not sure anymore if this really is a PrimeNG-bug or some issue of Angular2. However, I'm not using the latest version of Angular2, so I don't know if this has been fixed already (or if it is an angular-bug anyways).

I even tried setting a "updated" timestamp to my dataset and changed it everytime I changed the "data.dataset[0].data", but that does not get detected either. Seems like IterableDiffers have Issues with detecting changes on array properties.

Changes DO get detected if you JUST push(xxx) into this.data.datasets. Creating a new dataset does make it get detected by the differ. BUT: Using a shift straight afterwards makes the differ NOT detecting it anymore. Seems like if the array.length before and after using methods on the array has the same value, changes do NOT get detected.

However, I might have made mistakes, since I'm not an experienced programmer in any way. (started ~2month ago)

Any comment on this would be awesome!

I haven't looked at it as deep as you have... Great job, maybe the developers can find out the solution easier...

Has anyone tried this with the latest Versions of Angular2? Does change detection work the way described in the previous posts?

@cagataycivici
Really happy to see this going into RC5. Thank you!
It would be great if it also detected changes in the options, not just the dataset.
My old solution (prior to using primeng) was just to call chart.update()

@albertosramires Yesterday I wanted to write that it indeed does work, but today it just stopped. I didn't actually change anything. I uninstalled/reinstalled primeng and tried it with [email protected] as well, but it seems to be defect again. I don't know what happened.

EDIT: Alrighty, I didn't notice, that there is RC6 & 7, those came quick. Well, in RC.5 it did work, yesterday I updated my packages. I'll try Rc5 again.

EDIT 2: RC5 does work for me.

@cagataycivici Looks like the ngDoCheck function was deleted in rc6/7. Not sure if that was intended.

@albertosramires I perform .pop() and .slice() on my datasets.data, not the datasets array itself. I am sorry, I missread you there. You are right, pushing a completely new dataset into the datasets arrays doesnt work for me as well.
Have you tried other methods like pop, slice, shift?

@albertosramires That doesn't work for me. My charts are within different childcomponents, while my data gets updated in their parent. But it seems as if using the @ViewChild doesn't work here, it returns undefined.

Sorry, if I do any stupid msitakes, I am very unexperienced.

I did, but I can't get it to work. But thanks for your help!

Similar issue: (EDIT: [email protected])

Calling chart.refresh() from a separate, "manual" button function updates the chart immediately for me.

But calling it after changing the value of datasets[0].data within a .subscribe() block doesn't. Triggering the function with the .subscribe() block twice does update the chart the second time, though.

Am I missing an initialization step somewhere?

export class GraphTest implements OnInit {
    @ViewChild("chart") chart: UIChart
    graphData: any;

    constructor(dataservice: DataService) {}

    ngOnInit (): void {
        this.graphData = {
            labels: ['a', 'b', 'c', 'd', 'e'],
            datasets: [{label: 'Label', data: [1, 2, 3, 4, 5]}]
        };
    }

    // This updates the chart immediately on button press
    update (chart: UIChart): void {
        this.graphData.datasets[0].data = [6, 7, 8, 9, 10];
        chart.refresh();
    }

    // I have to press this button twice for the chart to update
    getRemote (datsetId: number, chart: UIChart): void {
        // HTTP request to get data from remote server
        this.dataservice.getData(datasetId)
            .subscribe(res => {
                this.graphData.datasets[0].data = res.data;
                chart.refresh();
             });
    }
}
<p-chart #chart type="line" [data]="graphData"></p-chart>
<button pButton type="button" label="Update" (click)="update(chart)"></button>
<button pButton type="button" label="Get Remote" (click)="getRemote(17, chart)"></button>

@albertosramires Every second (4th, 6th etc).

@albertosramires That did it. Even just a delay of 50ms made the difference. Thanks.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

just-paja picture just-paja  路  3Comments

jisqaqov picture jisqaqov  路  3Comments

Helayxa picture Helayxa  路  3Comments

cyberrranger picture cyberrranger  路  3Comments

KannanMuruganmony picture KannanMuruganmony  路  3Comments