Brian Brian - 1 month ago 20
TypeScript Question

Is there any benefit installing d3.js via npm for Anglar 2 TypeScript project?

I have an Angular 2 project (it's the Quick Start project for simplicity), and I'm importing d3.js version 4. There is no TypeScript definitions with d3, as it's javascript only.

In the index.html I add the lib:

<script src="https://d3js.org/d3.v4.min.js"></script>


In the typescript app.component.ts, I reference the d3.select().... and it works fine - draws a circle:

d3.select("body").append("svg").attr("width", 50).attr("height", 50).append("circle").attr("cx", 25).attr("cy", 25).attr("r", 25).style("fill", "purple");


Visual Studio Code does not recognise d3 so I install the typings from DefinitelyTyped - the IDE then recognises d3, and I get code completion etc:

typings install dt~d3 --save --global


Now, I tried a second project, but went the
npm
route,
npm install --save d3
and I can reference the d3.js via the node_modules in index.html using

<script src="node_modules/d3/build/d3.min.js"></script>


But, I do not see why I would use npm in this instance? I'm not using import statements for d3 in the component.ts files, and it works ok anyway. Maybe I'm missing something here?

Answer

As of now you have fundamentally the following two import-based options to utilize D3 version 4 (Always conditional on using TypeScript 2):

Option 1 (Use of Standard D3 bundle)

  • npm install --save d3 (The normal approach to installing the Standard D3 v4 Bundle)
  • npm install --save-dev @types/d3 (Installs the definitions for the Standard D3 v4 Bundle) You should use --save, if you are building a library to be used by other Angular 2 applications, so that the library consumer can develop with typing support)
  • No you can use import * as d3 from 'd3', e.g. in the module which creates a singleton D3 service to be injected into components on an as needed basis.

Option 2 (Use only what you need)

  • npm install --save d3-selection d3-transition d3-shape d3-scale Install only the modules you need for your project
  • npm install --save-dev @types/d3-selection @types/d3-transition @types/d3-shape @types/d3-scale (Install the matching definitions. Again, use --save instead of --save-dev depending on your use case.)
  • For convenience, you can now bundle these modules in a barrel module d3-bundle.ts

e.g.

// d3-bundle.ts    
export * from 'd3-selection';
export * from 'd3-transition';
export * from 'd3-shape';
export * from 'd3-scale';
  • Import from the bundle (using the appropriate relative path) to create a singleton D3 service i.e. import * as d3 from './d3-bundle'

The approach under Option 2 is essentially what d3-ng2-service does. It can also give you an idea on how to build your own D3 Service, if the published one is not right for. You can always suggest improvements to it, of course.

I will say that, using the import-based options with angular-cli has become a lost easier since it changed to Webpack 2 for module-loading/bundling.