ng2-charts : Error during evaluation of "mousemove"
<p>I'm trying to display the <code>ng2-charts</code> example code for the line-chart <a href="http://valor-software.com/ng2-charts/" rel="nofollow">here</a>.</p>

<p>The line-graph displays correctly. But, when I'm  hovering the graph, I've got an <code>Error during evaluation of "mousemove"</code>.</p>

<p>I have installed <code>ng2-charts</code> via npm and <code>Chart.js</code> via bower, as proposed in <a href="https://github.com/valor-software/ng2-charts#quick-start" rel="nofollow">this</a> quickstart.</p>

<p>This is the SystemJS config I am using:</p>

<pre><code>    System.config({
        map: {
            "ng2-charts": "node_modules/ng2-charts"
        },
        packages: {
            transpiler: 'typescript',
            typescriptOptions: { emitDecoratorMetadata: true },
            app: { format: 'register', defaultExtension: 'js' },
            "ng2-charts": { defaultExtension: 'js' }
        }
    });

    System.import('./app/boot')
        .then(null, console.error.bind(console));
</code></pre>

<p>Concerning the way to import <code>ng2-charts</code>, I have made some tests, and there are some results I can't explain:</p>

<p><strong>1/ Without any <code>&lt;script&gt;</code>:</strong></p>

<pre><code>ReferenceError: Chart is not defined
</code></pre>

<p>Isn't Bower supposed to deal with all the UI dependencies for me? On top of that, the graph doesn't display, but when I hover the zone where it should appear, I've got an <code>Error during evaluation of "mousemove"</code>.</p>

<p><strong>2/ With <code>&lt;script src="app/bower_components/Chart.js/Chart.js"&gt;&lt;/script&gt;</code>:</strong></p>

<p>I don't have any error in the console, but not any graph is displaying, neither does the weird behaviour of the "ghost line-graph not hoverable".</p>

<p><strong>3/ With a CDN:</strong></p>

<p>If the 1.0.2 version, <code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"&gt;&lt;/script&gt;</code>, same behaviour as in <strong>2/</strong>.</p>

<p>If the 0.2.0 version, <code>&lt;script src="http://cdnjs.cloudflare.com/ajax/libs/Chart.js/0.2.0/Chart.js"&gt;&lt;/script&gt;</code>, the line-graph finally displays, but I still have an <code>Error during evaluation of "mousemove"</code>. </p>

<p>Here are few details of the <code>Error during evaluation of "mousemove"</code>:</p>

<pre><code>Uncaught EXCEPTION: Error during evaluation of "mousemove"
ORIGINAL EXCEPTION: TypeError: Cannot read property 'call' of undefined
ORIGINAL STACKTRACE:
TypeError: Cannot read property 'call' of undefined
    at BaseChart.hover (http://localhost:3000/node_modules/ng2-charts/components/charts/charts.js:199:47)
    at AbstractChangeDetector.ChangeDetector_BaseChart_0.handleEventInternal (viewFactory_BaseChart:36:24)
    at AbstractChangeDetector.handleEvent (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:8075:25)
    at AppView.triggerEventHandlers (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:10856:34)
    at eval (viewFactory_BaseChart:84:108)
    at http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:14003:34
    at http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:13356:18
    at Zone.run (http://localhost:3000/node_modules/angular2/bundles/angular2-polyfills.js:1243:24)
    at Zone.run (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:13558:32)
    at NgZone.run (http://localhost:3000/node_modules/angular2/bundles/angular2.dev.js:13520:34)
</code></pre>

<p>When digging into the <code>hover</code> method of <code>charts.ts</code> from my <code>node_modules</code>, I find this:</p>

<pre><code>public hover(evt) {
    console.log(evt); // I added this line
    let atEvent = this.chart.getPointsAtEvent || this.chart.getBarsAtEvent || this.chart.getSegmentsAtEvent;
    console.log(atEvent); // I added this line
    let activePoints = atEvent.call(this.chart, evt);
    if (activePoints.length &gt; 0) {
      let activeLabel = activePoints[0].label;
      let activePoint = activePoints[0].value;
      this.chartHover.emit({activePoints: activePoints, activePoint: activePoint, activeLabel: activeLabel});
    } else {
      console.log('not point');
    }
  }
</code></pre>

<p>According to the logs I added, it seems that <code>atEvent</code> is effectively <code>null</code>, as said in the details of the error.</p>

<p>I hope I have given you enough information to help me.</p>

<p>Thank you in advance!</p>

<p><strong>EDIT:</strong></p>

<p>Here is the whole <code>charts.ts</code> file:</p>

<pre><code>import {
  Component, View,
  Directive, AfterViewChecked, OnDestroy, OnInit,
  EventEmitter, ElementRef, Input
} from 'angular2/core';
import {CORE_DIRECTIVES, FORM_DIRECTIVES, NgClass} from 'angular2/common';

declare var Chart:any;

@Component({
  selector: 'chart, canvas[chart]',
  template: `&lt;canvas&gt;&lt;/canvas&gt;`,
  directives: [CORE_DIRECTIVES, NgClass]
})
export class Charts {
  constructor(element:ElementRef) {
  }

}

@Component({
  selector: 'base-chart',
  properties: [
    'data',
    'labels',
    'series',
    'colours',
    'chartType',
    'legend',
    'options'
  ],
  inputs: ['chartClick', 'chartHover'],
  template: `
  &lt;canvas style="width: 100%; height: 100%;" (click)="click($event)" (mousemove)="hover($event)"&gt;&lt;/canvas&gt;
  `,
  directives: [CORE_DIRECTIVES, FORM_DIRECTIVES, NgClass]
})
export class BaseChart implements OnInit, OnDestroy {
  private ctx:any;
  private cvs:any;
  private parent:any;
  private chart:any;
  private _data:Array&lt;any&gt; = [];
  private labels:Array&lt;any&gt; = [];
  private options:any = {responsive: true};
  private _chartType:string;
  private series:Array&lt;any&gt; = [];
  private colours:Array&lt;any&gt; = [];
  private legend:boolean;
  private legendTemplate:any;
  private initFlag:boolean = false;
  private chartClick:EventEmitter&lt;any&gt; = new EventEmitter();
  private chartHover:EventEmitter&lt;any&gt; = new EventEmitter();
  private defaultsColours:Array&lt;any&gt; = [
    {
      fillColor: 'rgba(151,187,205,0.2)',
      strokeColor: 'rgba(151,187,205,1)',
      pointColor: 'rgba(151,187,205,1)',
      pointStrokeColor: '#fff',
      pointHighlightFill: '#fff',
      pointHighlightStroke: 'rgba(151,187,205,0.8)',
      color: 'rgba(151,187,205,1)',
      highlight: 'rgba(151,187,205,0.8)'
    }, {
      fillColor: 'rgba(220,220,220,0.2)',
      strokeColor: 'rgba(220,220,220,1)',
      pointColor: 'rgba(220,220,220,1)',
      pointStrokeColor: '#fff',
      pointHighlightFill: '#fff',
      pointHighlightStroke: 'rgba(220,220,220,0.8)',
      color: 'rgba(220,220,220,1)',
      highlight: 'rgba(220,220,220,0.8)'
    }, {
      fillColor: 'rgba(247,70,74,0.2)',
      strokeColor: 'rgba(247,70,74,1)',
      pointColor: 'rgba(247,70,74,1)',
      pointStrokeColor: '#fff',
      pointHighlightFill: '#fff',
      pointHighlightStroke: 'rgba(247,70,74,0.8)',
      color: 'rgba(247,70,74,1)',
      highlight: 'rgba(247,70,74,0.8)'
    }, {
      fillColor: 'rgba(70,191,189,0.2)',
      strokeColor: 'rgba(70,191,189,1)',
      pointColor: 'rgba(70,191,189,1)',
      pointStrokeColor: '#fff',
      pointHighlightFill: '#fff',
      pointHighlightStroke: 'rgba(70,191,189,0.8)',
      color: 'rgba(70,191,189,1)',
      highlight: 'rgba(70,191,189,0.8)'
    }, {
      fillColor: 'rgba(253,180,92,0.2)',
      strokeColor: 'rgba(253,180,92,1)',
      pointColor: 'rgba(253,180,92,1)',
      pointStrokeColor: '#fff',
      pointHighlightFill: '#fff',
      pointHighlightStroke: 'rgba(253,180,92,0.8)',
      color: 'rgba(253,180,92,1)',
      highlight: 'rgba(253,180,92,0.8)'
    }, {
      fillColor: 'rgba(148,159,177,0.2)',
      strokeColor: 'rgba(148,159,177,1)',
      pointColor: 'rgba(148,159,177,1)',
      pointStrokeColor: '#fff',
      pointHighlightFill: '#fff',
      pointHighlightStroke: 'rgba(148,159,177,0.8)',
      color: 'rgba(148,159,177,1)',
      highlight: 'rgba(148,159,177,0.8)'
    }, {
      fillColor: 'rgba(77,83,96,0.2)',
      strokeColor: 'rgba(77,83,96,1)',
      pointColor: 'rgba(77,83,96,1)',
      pointStrokeColor: '#fff',
      pointHighlightFill: '#fff',
      pointHighlightStroke: 'rgba(77,83,96,0.8)',
      color: 'rgba(77,83,96,1)',
      highlight: 'rgba(77,83,96,0.8)'
    }];


  constructor(private element:ElementRef) {
  }

  ngOnInit() {
    this.ctx = this.element.nativeElement.children[0].getContext('2d');
    this.cvs = this.element.nativeElement.children[0];
    this.parent = this.element.nativeElement;
    this.refresh();
    this.initFlag = true;
  }

  ngOnDestroy() {
    if (this.chart) {
      this.chart.destroy();
      this.chart = null;
    }
    if (this.legendTemplate) {
      this.legendTemplate.destroy();
      this.legendTemplate = null;
    }
  }

  private get data() {
    return this._data;
  }

  private set data(value) {
    this._data = value;
    if (this.initFlag &amp;&amp; this._data &amp;&amp; this._data.length &gt; 0) {
      this.refresh();
    }
  }

  private get chartType() {
    return this._chartType;
  }

  private set chartType(value) {
    this._chartType = value;
    if (this.initFlag &amp;&amp; this._chartType &amp;&amp; this._chartType.length &gt; 0) {
      this.refresh();
    }
  }

  setLegend() {
    let list = this.parent.getElementsByTagName('ul');
    if (list.length) {
      list[0].remove();
      this.parent.insertAdjacentHTML('beforeend', this.chart.generateLegend());
    } else {
      this.parent.insertAdjacentHTML('beforeend', this.chart.generateLegend());
    }
  }

  getColour(colour:Array&lt;number&gt;):any {
    return {
      fillColor: this.rgba(colour, 0.2),
      strokeColor: this.rgba(colour, 1),
      pointColor: this.rgba(colour, 1),
      pointStrokeColor: '#fff',
      pointHighlightFill: '#fff',
      pointHighlightStroke: this.rgba(colour, 0.8),
      color: this.rgba(colour, 1),
      highlight: this.rgba(colour, 0.8)
    };
  }

  getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

  rgba(colour, alpha) {
    return 'rgba(' + colour.concat(alpha).join(',') + ')';
  }

  public click(evt) {
    let atEvent = this.chart.getPointsAtEvent || this.chart.getBarsAtEvent || this.chart.getSegmentsAtEvent;
    let activePoints = atEvent.call(this.chart, evt);
    if (activePoints.length &gt; 0) {
      let activeLabel = activePoints[0].label;
      this.chartClick.emit({activePoints: activePoints, activeLabel: activeLabel});
    } else {
      console.log('not point');
    }
  }

  public hover(evt) {
    console.log(evt);
    let atEvent = this.chart.getPointsAtEvent || this.chart.getBarsAtEvent || this.chart.getSegmentsAtEvent;
    console.log(atEvent);
    let activePoints = atEvent.call(this.chart, evt);
    if (activePoints.length &gt; 0) {
      let activeLabel = activePoints[0].label;
      let activePoint = activePoints[0].value;
      this.chartHover.emit({activePoints: activePoints, activePoint: activePoint, activeLabel: activeLabel});
    } else {
      console.log('not point');
    }
  }

  getChartBuilder(ctx:any, data:Array&lt;any&gt;, options:any) {
    return new Chart(ctx)[this.chartType](data, options);
  }

  getDataObject(label:string, value:any):any {
    if (this.chartType === 'Line'
      || this.chartType === 'Bar'
      || this.chartType === 'Radar') {
      return {
        label: label,
        data: value
      };
    }

    if (this.chartType === 'Pie'
      || this.chartType === 'Doughnut'
      || this.chartType === 'PolarArea') {
      return {
        label: label,
        value: value
      };
    }

    return null;
  }

  getChartData(labels:any, dataObject:any) {
    if (this.chartType === 'Line'
      || this.chartType === 'Bar'
      || this.chartType === 'Radar') {
      return {
        labels: labels,
        datasets: dataObject
      };
    }
    if (this.chartType === 'Pie'
      || this.chartType === 'Doughnut'
      || this.chartType === 'PolarArea') {
      return dataObject;
    }

  }

  private refresh() {

    this.ngOnDestroy();
    let dataset:Array&lt;any&gt; = [];

    for (let i = 0; i &lt; this.data.length; i++) {

      let colourDesc:Array&lt;number&gt; = [this.getRandomInt(0, 255), this.getRandomInt(0, 255), this.getRandomInt(0, 255)];
      let colour = i &lt; this.colours.length ? this.colours[i] : this.defaultsColours[i] || this.getColour(colourDesc);


      let data:any = (&lt;any&gt;Object).assign(colour,
        this.getDataObject(this.series[i] || this.labels[i], this.data[i]));

      dataset.push(data);

    }
    let data:any = this.getChartData(this.labels, dataset);

    this.chart = this.getChartBuilder(this.ctx, data, this.options);

    if (this.legend) {
      this.setLegend();
    }
  }
}


export const CHART_DIRECTIVES:Array&lt;any&gt; = [Charts, BaseChart];
</code></pre>

<p><strong>EDIT (29/02/16):</strong></p>

<p>I've tried to use PrimeNG instead of ng2-chart: <a href="http://www.primefaces.org/primeng/#/linechart" rel="nofollow">http://www.primefaces.org/primeng/#/linechart</a>. What I can't explain to myself, is that I've got more or less the same kind of behaviour: the chart is displaying fine, but if I click on it, I've got</p>

<p><code>Uncaught EXCEPTION: Error during evaluation of "click"
ORIGINAL EXCEPTION: TypeError: this.chart.getPointsAtEvent is not a function
</code></p>

<p>Again, when I'm looking at the code from PrimeNg (in <code>node_modules/primeng/components/chart/linechart/linechart.js</code>), there is <code>var activePoints = this.chart.getPointsAtEvent(event);</code> and <code>getPointsAtEvent(event)</code> seems to be defined nowhere...</p>

<p>Am I missing something somewhere? I really don't know how to explain all of this.</p>

<p>Any help would be really appreciated! :)</p>