Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using D3.js with Angular 2

Tags:

angular

d3.js

I have successfully integrated Angular 2 (Alpha 44) with D3.js:

<html> <head> <title>Angular 2 QuickStart</title> <script src="../node_modules/systemjs/dist/system.src.js"></script> <script src="../node_modules/angular2/bundles/angular2.dev.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script> <script>   System.config({packages: {'app': {defaultExtension: 'js'}}});   System.import('app/app'); </script> </head> <body> <my-app>Loading...</my-app> </body> </html> 

app.js:

/// <reference path="./../../typings/tsd.d.ts" />  import {Component, bootstrap, ElementRef} from 'angular2/angular2';  @Component({   selector: 'my-app',   template: '<h1>D3.js Integrated if background is yellow</h1>',   providers: [ElementRef] }) class AppComponent {    elementRef: ElementRef;    constructor(elementRef: ElementRef) {    this.elementRef = elementRef;   }  afterViewInit(){     console.log("afterViewInit() called");     d3.select(this.elementRef.nativeElement).select("h1").style("background-color", "yellow");   } } bootstrap(AppComponent); 

Everything is working fine. But Angular 2 documentation for ElementRef states the following:

Use this API as the last resort when direct access to DOM is needed. Use templating and data-binding provided by Angular instead. Alternatively you take a look at {@link Renderer} which provides API that can safely be used even when direct access to native elements is not supported. Relying on direct DOM access creates tight coupling between your application and rendering layers which will make it impossible to separate the two and deploy your application into a web worker.

Now the question arises how to integrate D3.js with the Renderer API's?

like image 737
Zia Khan Avatar asked Oct 28 '15 07:10

Zia Khan


People also ask

Can D3 be used with angular?

D3 natively supports JSON data, so it makes it really easy to integrate with your Angular application. First, you'll need a JSON API endpoint or file.

Do people still use D3 JS?

The JavaScript ecosystem has completely changed during this time, in terms of libraries, best practices and even language features. Nevertheless, D3 is still here. And it's more popular than ever.

Does D3 support TypeScript?

The d3 code is packaged into the web app under web app root in the d3 directory. The TypeScript source is being written in the source tree, outside of the WebContent folder, being compiled into the WebContent hierarchy. The TypeScript source is configured via tsconfig.

What is better than D3 JS?

three. js, Plotly. js, Highcharts, Python, and Tableau are the most popular alternatives and competitors to D3. js.


2 Answers

To use Renderer, you need the raw HTML element (aka nativeElement). So basically you have to use whatever your library is, get the raw element and pass it to Renderer.

For example

// h3[0][0] contains the raw element var h3 = d3.select(this.el.nativeElement).select('h3'); this.renderer.setElementStyle(h3[0][0], 'background-color', 'blue'); 

The warning about ElementRef is about using it directly. That means that this is discouraged

elementRef.nativeElement.style.backgroundColor = 'blue'; 

But this is fine

renderer.setElementStyle(elementRef.nativeElement, 'background-color', 'blue'); 

For showing purposes you can use it as well with jQuery

// h2[0] contains the raw element var h2 = jQuery(this.el.nativeElement).find('h2'); this.renderer.setElementStyle(h2[0], 'background-color', 'blue'); 

My recommendation though is to stick to use what angular2 provides you to do this easily without depending on another libraries.

With pure angular2 you have two easy ways

  • Using directives
// This directive would style all the H3 elements inside MyComp @Directive({     selector : 'h3',     host : {         '[style.background-color]' : "'blue'"     } }) class H3 {}  @Component({     selector : 'my-comp',     template : '<h3>some text</h3>',     directives : [H3] }) class MyComp {} 
  • Using ViewChild with local variables
@Component({     selector : 'my-comp',     template : '<h3 #myH3>some text</h3>', }) class MyComp {     @ViewChild('myH3') myH3;     ngAfterViewInit() {         this.renderer.setElementStyle(this.myH3.nativeElement, 'background-color', 'blue');     } } 

Here's a plnkr with all the cases I mentioned in this answer. Your requirements may differ, of course, but try to use angular2 whenever you can.

like image 113
Eric Martinez Avatar answered Sep 17 '22 19:09

Eric Martinez


Try this:

npm install [email protected] --save to set the version you need

npm install @types/[email protected] --save or a higher version if you want d3 4+

and then in your ts do

import * as d3 from 'd3';

Should work just fine

like image 38
Pian0_M4n Avatar answered Sep 17 '22 19:09

Pian0_M4n