I am trying to get the combo d3, nvd3 and ng2-nvd3 to work on a Angular 2 project with angular-cli 1.0.0-beta.15.
I have installed the packages with the corresponding @types via npm, package.json looks like this (irrelevant packages omitted):
"dependencies": {
"d3": "3.5.16",
"ng2-nvd3": "1.1.3",
"nvd3": "1.8.4",
},
"devDependencies": {
"@types/d3": "0.0.33",
"@types/nvd3": "1.8.32",
"angular-cli": "1.0.0-beta.15",
}
I included the d3.js and nv.d3.js as well as nv.d3.css in the angular-cli.json (packages are bundled correctly):
"styles": [
"../../../node_modules/nvd3/build/nv.d3.css",
"styles.scss"
],
"scripts": [
"../../../node_modules/d3/d3.js",
"../../../node_modules/nvd3/build/nv.d3.js"
],
I created a common module for importing ng2-nvd3 (I verified the code is bundled as well):
import { NgModule } from "@angular/core";
import { nvD3 } from "ng2-nvd3";
@NgModule({
declarations: [nvD3],
exports: [nvD3]
})
export class MyCommonModule {
}
Then, I imported the common module into the app module that expects to use it (in the ActivityChartComponent):
@NgModule({
imports: [PaginationModule, CommonModule, FormsModule, routing, MyCommonModule],
declarations: [ActivityChartComponent],
exports: [PlatformComponent]
})
export class PlatformModule {
}
and here is the ActivityChartComponent template (the component code itself just calculates the data, it is irrelevant here):
<h5 class="card-title">{{title}}</h5>
<span *ngIf="description" class="chart-info">{{description}}</span>
<nvd3 [options]="chart" [data]="data"></nvd3>
I am getting an exception ( I masked the URLs in the stack trace with '...' to protect private data):
TypeError: groups.watchTransition is not a function
at SVGGElement.<anonymous> (http://localhost:8000/.../nv.d3.js:12243:20)
at http://localhost:8000/.../main.bundle.js:50272:16
at d3_selection_each (http://localhost:8000/.../main.bundle.js:50278:30)
at Array.d3_selectionPrototype.each (http://localhost:8000/.../main.bundle.js:50271:12)
at Array.chart (http://localhost:8000/.../nv.d3.js:11919:19)
at Array.d3_selectionPrototype.call (http://localhost:8000/.../main.bundle.js:50285:14)
at SVGGElement.<anonymous> (http://localhost:8000/.../nv.d3.js:6540:25)
at http://localhost:8000/.../main.bundle.js:50272:16
at d3_selection_each (http://localhost:8000/.../main.bundle.js:50278:30)
at Array.d3_selectionPrototype.each (http://localhost:8000/.../main.bundle.js:50271:12)
To be able to debug this - I removed the d3 and nvd3 references from angular-cli.json and I imported them directly into the index.html instead.
Looking at the d3 code, I couldn't find any reference to watchTransition, however nvd3 adds the implementation on d3.selection.prototype.
snippet from nv.d3.js:
d3.selection.prototype.watchTransition = function(renderWatch){
var args = [this].concat([].slice.call(arguments, 1));
return renderWatch.transition.apply(renderWatch, args);
};
When debugging, I see the prototype does not have the watchTransition reference...
Any ideas, leads or information would be greatly appreciated.
OK, managed to solve this.
The problem was, that when the
d3andnvd3were bundled viaangular-cli.jsonthey were bundled into thescripts.bundleand the application code inmain.bundleand that apparently caused them to have different scopes.I imported them in the common module instead of in the angular-cli config and that made everything be bundled in
main.bundle.So, common module now looks like this: