2015-10-28 35 views
72

tôi đã tích hợp thành công kiễu góc 2 (Alpha 44) với D3.js:Sử dụng D3.js với góc 2

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

Tất cả mọi thứ đang làm việc tốt. Nhưng tài liệu Angular 2 cho ElementRef nêu rõ:

Sử dụng API này làm phương sách cuối cùng khi truy cập trực tiếp vào DOM là cần thiết. Sử dụng templating và dữ liệu ràng buộc được cung cấp bởi Angular thay thế. Ngoài ra, bạn hãy xem {@link Renderer} cung cấp API có thể được sử dụng một cách an toàn ngay cả khi truy cập trực tiếp vào các yếu tố gốc không được hỗ trợ. Dựa vào truy cập DOM trực tiếp tạo ra sự ghép nối chặt chẽ giữa ứng dụng của bạn và các lớp dựng hình mà sẽ làm cho nó không thể tách rời hai ứng dụng và triển khai ứng dụng của bạn thành một nhân viên web.

Bây giờ câu hỏi đặt ra cách tích hợp D3.js với API của trình kết xuất?

+0

Đây có phải là trong bất kỳ sự giúp đỡ? http://www.ng-newsletter.com/posts/d3-on-angular.html – urosjarc

+0

Tôi cũng đang cố gắng để D3 làm việc với góc cạnh 2. Trong ví dụ trên, tôi có thể thấy rằng bạn tham khảo tập lệnh d3 trong bạn index.html, nhưng tôi không thể thấy cách bạn nắm giữ biến d3 trong app.js? – user2915962

+7

@ user2915962 - npm install d3, đảm bảo chạy postinstall và d3.d.ts được tạo bởi tsd, sau đó 'import * as d3 từ 'd3/d3';' – drewmoore

Trả lời

53

Để sử dụng Trình kết xuất đồ họa, bạn cần phần tử HTML thô (aka nativeElement). Vì vậy, về cơ bản bạn phải sử dụng bất cứ thư viện nào của bạn, lấy nguyên tố thô và chuyển nó tới Renderer.

Ví dụ

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

Cảnh báo về ElementRef là về việc sử dụng nó trực tiếp. Điều đó có nghĩa rằng đây không được khuyến khích

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

Nhưng điều này là tốt

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

Đối với thể hiện mục đích bạn có thể sử dụng nó như tốt với jQuery

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

Khuyến cáo của tôi mặc dù là để dính vào sử dụng những gì angular2 cung cấp cho bạn để làm điều này một cách dễ dàng mà không phụ thuộc vào một thư viện khác.

Với angular2 tinh khiết bạn có hai cách dễ dàng

  • Sử dụng chỉ thị
// 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 {} 
  • Sử dụng ViewChild với các biến địa phương
@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'); 
    } 
} 

Đây là plnkr với tất cả các trường hợp tôi đã đề cập trong câu trả lời này. Yêu cầu của bạn có thể khác nhau, tất nhiên, nhưng cố gắng sử dụng angular2 bất cứ khi nào bạn có thể.

+2

Vì vậy, ví dụ về việc sử dụng bootstrap's sụp đổ plugin, tôi có quyền nói rằng 'jQuery (this.el.nativeElement) .collapse ('show');' sẽ là một cách hoàn toàn chấp nhận được instantiating các plugin? – garethdn

+0

Tôi đoán cách tiếp cận chỉ thị sẽ không hoạt động đối với các h3 được gắn động vào đúng không? Ví dụ: http://plnkr.co/edit/U2lvYqtGvdf7kWoRg10N?p=preview – echonax

2

Tôi gặp sự cố khi sử dụng ElementRef, tôi không chắc liệu API đó có thay đổi hay không. Vì vậy, tôi đã kết thúc bằng cách sử dụng ViewContainRef để lấy 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"); 
    }; 
} 
5

Hãy thử điều này:

npm install [email protected] --saveđể thiết lập các phiên bản bạn cần

npm install @types/[email protected] --save hoặc phiên bản cao hơn nếu bạn muốn d3 4+

và sau đó trong ts của bạn làm

import * as d3 from 'd3';

nên chỉ làm việc tốt

+0

bằng cách sử dụng d3 mới nhất (v4) và dựa trên ví dụ nhanh hơn về góc 2, tôi cũng phải thêm '' d3 ':' npm: d3'' vào bản đồ và ''d3': {main: 'build/d3.js', defaultExtension: 'js'}' vào các gói trong tệp 'systemjs.config.js'. – Entrodus

+0

Xin chào @Entrodus, bạn có phiền khi đưa cho tôi chuỗi cài đặt chính xác, dựa trên Quickstart không? Tôi đã cố gắng làm theo điều này, bao gồm mod của hệ thống mà bạn đã đề xuất, nhưng tôi vẫn bị kẹt (không có ./build/d2.js, không có thư mục /build nào). –

+0

@ StéphanedeLuca: 1.Thiết lập quickstart góc> 2.install d3 và typings cho d3 version 4.4.0> 3.added map and packages chỉ thị cho d3 trong system.config.js> 4.add import của d3 trong thành phần góc mà sử dụng d3> 5.Victory. – Entrodus

2
npm install --save d3 

phiên bản kiểm tra d3 trong package.json và kiểm tra xem nó trong node_modules quá.

sau đó, trong component.ts, nhập nó như sau

import * as d3 from 'd3'; 
+0

Điều này cũng làm việc trong Angular 4? – fangio