Programing

Angular 2와 함께 D3.js 사용

crosscheck 2020. 10. 20. 07:19
반응형

Angular 2와 함께 D3.js 사용


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와 통합하는 방법에 대한 질문이 생깁니다.


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가 제공하는 것을 사용하는 것입니다.

pure 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');
    }
}

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


이 시도:

npm install d3@3.5.36 --save 필요한 버전을 설정하려면

npm install @types/d3@3.5.36 --save 또는 d3 4+를 원한다면 더 높은 버전

그리고 당신의 ts

import * as d3 from 'd3';

Should work just fine


I was having trouble using ElementRef, I'm not sure if that API has changed. So I ended up using ViewContainRef to get the 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 --save d3

check d3 version in package.json and check it in node_modules too.

then, in the component.ts, import it as below

import * as d3 from 'd3';

참고URL : https://stackoverflow.com/questions/33385500/using-d3-js-with-angular-2

반응형