I am trying to integrate d3 and angular2 alpha.37 (started from here ). The problem I'm currently facing is that the created DOM elements do not get the attributes used in encapsulation with emulated style, so I cannot style them without setting the encapsulation of the view for the None (or Native, element, but I rather would rather emulate).
I managed to programmatically extract the required attribute from the element inside the component [1], and then add it to the generated elements [2], which works, but this is clearly incredibly hacky:
import {Component, View, Attribute, ElementRef, LifecycleEvent} from 'angular2/angular2'; import d3 from 'd3'; @Component({ selector: 'bar-graph', properties: [ 'data' ] }) @View({ template: '<div class="chart"></div>', styles: [`.chart { background: #eee; padding: 3px; } div.bar { width: 0; transition: all 1s ease-out; -moz-transition: all 1s ease-out; -webkit-transition: all 1s ease-out; } div.bar { font: 10px sans-serif; background-color: steelblue; text-align: right; padding: 3px; margin: 5px; color: white; box-shadow: 2px 2px 2px #666; }`] }) export class BarGraph implements LifecycleEvent.OnChanges { data: Array<number>; divs: any; constructor(elementRef: ElementRef, @Attribute('width') width: string, @Attribute('height') height: string) { var el:any = elementRef.nativeElement; var graph:any = d3.select(el); this.hostAttr = graph[0][0].children[0].attributes[1].name; //hack here [1] this.divs = graph. select('div.chart'). style({ 'width': width + 'px', 'height': height + 'px', }). selectAll('div.bar'); } render(newValue) { if (!newValue) return; this.divs.data(newValue) .enter().append('div') .classed('bar', true) .attr(this.hostAttr, true) //add the attribute here [2] .style('width', d => d + '%') .text(d => d + '%'); } onChanges() { this.render(this.data); } }
Is there a recommended way to deal with such things (or should I stop redoing the DOM outside of Angular2)?
Richl source share