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에서 제공하는 템플릿 및 데이터 바인딩을 사용하십시오. 또는 네이티브 요소에 대한 직접 액세스가 지원되지 않는 경우에도 안전하게 사용할 수있는 API를 제공하는 {@link Renderer}를 살펴보세요. 직접 DOM 액세스에 의존하면 애플리케이션과 렌더링 레이어간에 긴밀한 결합이 생성되어 두 레이어를 분리하고 애플리케이션을 웹 작업자에 배포하는 것이 불가능합니다.

이제 D3.js를 Renderer API와 통합하는 방법에 대한 질문이 생깁니다.



또한 D3가 angular 2와 함께 작동하도록하려고합니다. 위의 예에서 index.html에서 d3 스크립트를 참조하는 것을 볼 수 있지만 d3 변수를 얻는 방법을 볼 수 없습니다. app.js에서?
user2915962

8
@ user2915962-npm install d3, postinstall 실행 및 d3.d.ts가 tsd에 의해 생성되었는지 확인한 다음import * as d3 from 'd3/d3';
drew moore

여기 댓글 중 하나에 언급 된 비디오가 있습니다. stackoverflow.com/q/34704148/2050479 꽤 흥미로운
Michael

1
@urosjarc-Angular 1은 이러한 종류의 작업을 수행하는 매우 다른 방법을 가지고 있습니다.
superluminary

답변:


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가 제공하는 것을 사용하여 다른 라이브러리에 의존하지 않고 쉽게 수행하는 것입니다.

순수한 각도 2를 사용하면 두 가지 쉬운 방법이 있습니다.

  • 지시문 사용
// 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');
    }
}

이 답변에서 언급 한 모든 사례 가 담긴 plnkr 이 있습니다. 물론 요구 사항은 다를 수 있지만 가능할 때마다 angular2를 사용하십시오.


2
그렇다면 부트 스트랩의 축소 플러그인을 사용하는 예에서 jQuery(this.el.nativeElement).collapse('show');이것이 플러그인을 인스턴스화하는 완벽하게 허용되는 방법 이라고 말하는 것이 맞 습니까?
garethdn

지시어 접근 방식이 동적으로 추가 된 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, 빠른 시작을 기반으로 정확한 설치 순서를 알려주시겠습니까? 나는 당신이 제안한 시스템의 모드를 포함하여 이것을 따르려고 노력했지만 여전히 멈춰 있습니다 (./build/d2.js, ./build 폴더도 없음).
Stéphane de Luca

@ StéphanedeLuca : 1. angular 빠른 시작 설정> 2. d3 버전 4.4.0에 대한 d3 설치 및 입력> 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가 변경되었는지 확실하지 않습니다. 그래서 NativeElement를 얻기 위해 ViewContainRef를 사용했습니다.

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");
    };
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.