在Angular 2中使用D3.js


78

我已经成功将Angular 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提供了即使不支持直接访问本机元素也可以安全使用的API。依赖于直接DOM访问,可以在应用程序和呈现层之间建立紧密的耦合,这将使得不可能将两者分开并将应用程序部署到Web Worker中。

现在出现了一个问题,如何将D3.js与Renderer API集成在一起?



我还尝试使D3与angular 2一起使用。在上面的示例中,我可以看到您在index.html中引用了d3-脚本,但是我看不到如何获得d3-变量。在app.js中?
user2915962

8
@ user2915962-npm install d3,确保运行后安装程序并由tsd创建d3.d.ts,然后import * as d3 from 'd3/d3';
drew moore

这里的评论之一中提到了一个视频:stackoverflow.com/q/34704148/2050479,这很有趣
Michael

1
@urosjarc-那是Angular 1,它执行这类事情的方式非常不同。
superluminary

Answers:


58

要使用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提供的功能轻松进行此操作,而无需依赖其他库。

使用纯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。


2
因此,以使用bootstrap的折叠插件为例,我是否正确地说这jQuery(this.el.nativeElement).collapse('show');是实例化插件的一种完全可以接受的方式?
garethdn '16

我猜想指令方法不适用于动态附加的h3吧?例如:plnkr.co/edit/U2lvYqtGvdf7kWoRg10N?p=preview
EKO

6

试试这个:

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

npm install @types/d3@3.5.36 --save 或更高版本(如果要d3 4+)

然后在你ts

import * as d3 from 'd3';

应该很好


使用最新的d3(v4)并基于angular 2快速入门示例,我还必须添加'd3':'npm:d3'到地图和 文件'd3': {main:'build/d3.js', defaultExtension:'js'}包中systemjs.config.js
Nikos Tsokos

嗨@Entrodus,您是否愿意根据快速入门给我确切的安装顺序?我尝试遵循此方法,包括您建议的系统mod,但我仍然受阻(也没有./build/d2.js,也没有./build文件夹)。
斯特凡·卢卡

@StéphanedeLuca:1.设置角度快速入门> 2.安装d3并为d3版本4.4.0键入内容> 3.在system.config.js中为d3添加了映射和包指令> 4.在使用以下组件的角度组件中添加d3的导入d3> 5.胜利。
Nikos Tsokos

4
npm install --save d3

在package.json中检查d3版本,并在node_modules中检查它。

然后,在component.ts中,将其导入如下

import * as d3 from 'd3';

3

我在使用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");
    };
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.