1

Problem: How to get PrimeNg Charts to refresh asynchronously?

Scenario: I have a dropdown that I want to refresh the chart based on a user selection.

I thought I knew the answer to this question after gaining an understanding of Angular change detection and how I would need to reassign an object for it to see the data had been changed (as opposed to updating the data within the object in place), but after reading about many other charts and even trying them, I learned that the problem was a bit more difficult than I initially thought.

When I read about ng2-charts, which builds directives off of charts.js as well, they use solutions that were a bit cloogy to get around this problem in Angular. Here is an excerpt from their example code:

/**
* (My guess), for Angular to recognize the change in the dataset
* it has to change the dataset variable directly,
* so one way around it, is to clone the data, change it and then
* assign it;
**/

http://valor-software.com/ng2-charts/

Even though they stringify and reparse the data to make a clone copy and reassign the data and it seemed to work for them, I tried this approach with PrimeNg with no success.

In other examples, they do a .slice() on the chart data, or access the CHART_DIRECTIVES directly and .update() the chart. They also wait to draw the chart until the data is loaded in asynchronously, which only loads the first time and wouldn't solve my desired behavior. Why should I practice Test Driven Development and how should I start?

I know my data is there behind the scenes, I just need to know how to refresh the chart (i.e. come up with a way for Angular to properly recognize I have changed the data).

Community
  • 1
  • 1
MapLion
  • 1,041
  • 1
  • 12
  • 38
  • 1
    From the docs; https://www.primefaces.org/primeng/#/chart In order to chart to redraw itself, a new data object needs to be created. Changing the array contents without creating a new array instance does not trigger change detection. – Cagatay Civici Mar 31 '17 at 15:12
  • Hi Cagatay Civici, thanks for the response. I answered my own question below; this was really put here to help others (extracting forum conversation out). As explained, creating a new array was not functioning as desired. I could set the data in the constructor, but I could not change the data once the chart loaded (e.g. populate this.changeData and then set this.data = this.changeData and get it to redraw). It is possible (and maybe likely) I was doing something wrong, but the resolution below provided me with what I wanted, which was a way to refresh the chart on the fly. Thx DarthMaul. – MapLion Mar 31 '17 at 20:16

1 Answers1

1

I wanted a "real" solution, so I went to the source. I was informed that after 4.0.0-rc.1 that the behavior of the charts was changed. I installed 4.0.0-rc.1 and followed the following example and got it to work as intended.

   changeData() {
            this.changedData = {
                labels: ['X','Y','Z'],
                datasets: [
                    {
                        data: [200, 200, 50],
                        backgroundColor: [
                            "#50f442",
                            "#f441c4",
                            "#4195f4"
                        ],
                        hoverBackgroundColor: [
                            "#50f442",
                            "#f441c4",
                            "#4195f4"
                        ]
                     }]
            }
            this.data = Object.assign({}, this.changedData);

}

https://github.com/primefaces/primeng/issues/2235

MapLion
  • 1,041
  • 1
  • 12
  • 38