使用带有角度2的 D3.js

我已经成功地将角度2(Alpha 44)与 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);

一切正常,但 ElementRef 的 Angular 2文档说明如下:

当需要直接访问 DOM 时,使用此 API 作为最后的手段。改用 Angular 提供的模板和数据绑定。或者,您可以查看{@link Renderer } ,它提供了即使不支持直接访问本机元素也可以安全使用的 API。依赖于直接的 DOM 访问在应用程序和呈现层之间创建了紧密的耦合,这将使得不可能将两者分离并将应用程序部署到 Web worker 中。

现在的问题是如何集成 D3.js 和渲染器 API?

47456 次浏览

要使用 Renderer,您需要原始的 HTML 元素(也就是 nativeElement)。所以基本上你必须使用你的库,获取原始元素并传递给 Renderer。

比如说

// 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');

关于 ElementRef 的警告是关于直接使用它。这意味着不鼓励这样做

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

不过这样也行

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

为了显示目的,您也可以将它与 jQuery 一起使用

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

不过,我的建议是坚持使用 angular2提供的方法来轻松完成这项工作,而无需依赖其他库。

有了纯角度,你有两种简单的方法

  • 使用指令
// 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 {}
  • 对局部变量使用 ViewChild
@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');
}
}

这是我在这个答案中提到的所有案例的 普林克。当然,您的要求可能不同,但是尽可能使用 angular2。

我在使用 ElementRef 时遇到了麻烦,我不确定那个 API 是否改变了。因此,我最终使用 ViewContainRef 来获取 nativeElement。

import {Component, ViewContainerRef, OnInit} from '@angular/core';
declare var d3:any;
@Component({
selector: 'line-chart',
directives: [],
template: `<div class="sh-chart">chart</div>`
})
export class LineChart implements OnInit{
elem ;
constructor(private viewContainerRef:ViewContainerRef) {}
ngOnInit(){
this.elem = this.viewContainerRef.element.nativeElement;


d3.select(this.elem).select("div").style("background-color", "yellow");
};
}

试试这个:

npm install d3@3.5.36 --save 设置您需要的版本

npm install @types/d3@3.5.36 --save 或更高的版本,如果你想 d34 +

然后在你的 ts

import * as d3 from 'd3';

应该没问题

npm install --save d3

在 package.json 中检查 d3版本,并在 node _ module 中检查它。

然后,在 Component. ts 中导入它,如下所示

import * as d3 from 'd3';