7
votes

I've been trying to get D3 up and running with my Angular2 app.
However there seems to be currently an issue with the new D3v4 and the available typings file, i.e. trying to use new methods such as scaleLinear() instead of the no longer available scale.linear() will result in an error
Property 'scaleLinear' does not exist on type 'typeof d3'.
 

Since tomwanzek seems to be already on the issue and trying to create the new definitions over at https://github.com/tomwanzek/d3-v4-definitelytyped I was wondering if there is a way to manually include the already available typings files in my angular2 project?

4
I haven't found a way at the moment, so I've just defined the d3v4 object with type Any and gone on my merry way. Will bring the types on-board when they are finished. But if there is a way, I'd like to know as well.Ethan Jewett
How exactly did you do this? I currently have import * as D3 from 'd3'; but import * as D3:any from 'd3'; doesn't work...TommyF
I load d3 into the page in its own script element, then grab it in my controller using an extended angular.IWindowService that just adds a d3: any property.Ethan Jewett
if you're using TS 2.0, npm install @types/d3v4drew moore

4 Answers

7
votes

In reference to Arlo's answer, let me expand with a brief history and a current answer. I created the repo https://github.com/tomwanzek/d3-v4-definitelytyped to develop new D3 version 4 TypeScript definitions, when D3 v4 was not yet final and TypeScript 2 was just on the horizon. The latter was a major factor, because it changed the way definitions are written and can be acquired, i.e. @types.

With a few noted nods to the collaborators listed on the repo, we finalized the definitions and migrated them to DefinitelyTyped. They are now actively maintained in the types-2.0 branch of DefinitelyTyped. That is the branch that is published to npm @types.

Some of confusion you might have seen, had to do with the fact that the individual D3 v4 module definitions, e.g. d3-selection, had been available through npm install --save @types/d3-selection for quite some time. However, until yesterday the definition acquired by npm install --save @types/d3 still pulled down the old D3 v3.5.x definition.

As of now, the D3 v4 Standard bundle definitions are available from npm install --save @types/d3 (The legacy version definitions for D3 v3.5 can still be pulled from @types by acquiring a 3.5 version if need be)

As for using the definitions with imports:

  • Do not install and use the d3 Standard Bundle from ('d3' and '@types/d3', respectively) while at the same time installing D3 modules already contained in it separately, e.g. 'd3-hierarchy' and '@types/d3-hierarchy'.

As for Angular 2, yes, the d3-ng2-service or something similar is one way to go. I'm sure there can be improvements to it, it was started for rapid prototyping in conjunction with angular-cli.

2
votes

I don't know about drewmoore's suggestion of @types/d3v4, but @types/d3-MODULE works, though this requires Typescript 2.0 as mentioned.

Install the @types package for each d3 module you use, for example axis would be:

npm install --save-dev @types/d3-axis

I think these come from: https://github.com/tomwanzek/d3-v4-definitelytyped Check the status/availability of each D3 module: Issue 56

Apparently, npm @types will replace typings and tsd in the future: The Future of Declaration Files

2
votes

I'm not sure about drewmoore's suggestiong either. It didn't seem to work for me.

I've got two suggestions for continuing.

Best Answer

The first is an addendum to Arlo's answer. When I originally wrote this comment, I couldn't get Arlo's answer to work. Now I have understood why. I was trying to use the d3-hierarchy package. So installing:

npm install d3 --save
npm install @types/d3 --save-dev
npm install @types/d3-hierarchy --save-dev

And then using the modules this way:

import * as d3 from "d3";

d3.hierarchy(blah);

And then it would complain that it didn't know about the d3.hierarchy member. Now I understand that I must use that object (I don't know why it didn't register before). So, updated:

import * as d3 from "d3";
import * as d3Hierarchy from "d3-hierarchy";

d3Hierarchy.hierarchy(blah);

Original Answer

What seems to be the only answer I've found so far is using the d3-ng2-service module located at the link. It's not a great switch, but it does allow you to use d3v4 in your angular 2 project.

An excerpt from the readme can be found below of how to use it in an angular 2 component:

import { Component, OnInit, ElementRef } from '@angular/core';
import { D3Service, D3, Selection } from 'd3-ng2-service'; // <-- import the D3 Service, the type alias for the d3 variable and the Selection interface

@Component({
  selector: 'app-test-d3',
  templateUrl: 'test-d3.component.html',
  styleUrls: ['test-d33.component.css']
})
export class TestD3Component implements OnInit {

  private d3: D3; // <-- Define the private member which will hold the d3 reference
  private parentNativeElement: any;

  constructor(element: ElementRef, d3Service: D3Service) { // <-- pass the D3 Service into the constructor
    this.d3 = d3Service.getD3(); // <-- obtain the d3 object from the D3 Service
    this.parentNativeElement = element.nativeElement;
  }

  ngOnInit() {
    let d3 = this.d3; // <-- for convenience use a block scope variable
    let d3ParentElement: Selection<any, any, any, any>; // <-- Use the Selection interface (very basic here for illustration only)

// ...

    if (this.parentNativeElement !== null) {

      d3ParentElement = d3.select(this.parentNativeElement); // <-- use the D3 select method 

      // Do more D3 things 

    }
  }

}
2
votes

builds on answer from AMB0027

import * as d3 from "d3";
import * as d3Hierarchy from "d3-hierarchy";

d3Hierarchy.hierarchy(blah);

A workaround for cleaner code

create a d3-bundle.ts file in your project with;

export * from "d3-selection"
export * from "d3-heirachy"

in the ts using d3 - you can now do;

import * as d3 from "./d3-bundle"

d3.hierarchy(blah)

To specifically avoid the "scaleLinear" error

npm install @types/d3-axis

and add

export * from "d3-axis"

to your d3-bundle.ts

Note there are issues related to this on TypeScript https://github.com/Microsoft/TypeScript/issues/9681