BUG: Setting Function to generate bar colors causes chart to reload on hover?

Bug – When I set the colours of a bar chart to equal a function e.g. [colors]="getColors()" (this is using the ng2-charts directive). Where:

  getColors() {
    var red = 'rgba(255, 99, 132, 0.2)';
    var green = 'rgba(45, 227, 81, 0.2)';
    return [{
      backgroundColor: this.barChartData[0].data.map(d => d < this.target ? red : green)
    }];
  }

Then I get a weird refresh whenever I hover over the charts. See below:

Issue Gif

Expected Behavior

A tooltip should appear, the graph shouldn’t reload as shown in the screen shot.

Current Behavior

See above

Possible Solution

Not sure I’m affraid.

Steps to Reproduce (for bugs)

  1. See here – doesn’t work, I believe for the same issue.

Context

Environment

  • Chart.js version: 2.3.0
  • Browser name and version: Chrome 53.0.2785.143 m

Author: Fantashit

1 thought on “BUG: Setting Function to generate bar colors causes chart to reload on hover?

  1. @georgeedwards: when stepping in the calling code, the result of getColors() is checked for changes (I don’t know Angular, so not sure why there is this change detection), but that could be the issue. Maybe the template is infinitely created and destroyed because Angular would consider that the result of getColors() is always different. The browser loading state would simply be the consequence of the Chart.js internal iframe which is continuously re-created.

    Returning a constant object (e.g. 42) doesn’t cause the infinite loop. Different array instances can’t be compared based on their content (i.e. [42] != [42]), same for objects ({foo: 42} != {foo: 42}). In your case, you return a new array of objects, so it’s even more true.

    It works if the result is cached (returning always the same array instance):

      private colors: any;
      getColors() {
        if (!this.colors) {
          this.colors = [{
            backgroundColor: this.datasets[0].data.map(d => d < 10 ? 'red' : 'green')
          }];
        }
    
        return this.colors;
      }

    However if your data change, colors will not be updated, so maybe getColors() should not be a member of AppComponent? Or simply a pre-computed property (e.g. colors), refreshed when datasets changes. Also note that getColors() is called at every animation frame, going through Angular seems a perf killer. But then I guess that’s out of the scope of Chart.js 🙂

Comments are closed.