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 errorProperty '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?
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:
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.
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
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
}
}
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With