tomwanzek / d3-ng2-service

A D3 service for use with Angular.
MIT License
205 stars 42 forks source link

Appending a g element to SVGSVGElement returns BaseType instead of SVGGElement #71

Closed denisemauldin closed 7 years ago

denisemauldin commented 7 years ago

Using D3Service from d3-ng2-service, I am doing the following:

export class TimelineComponent implements OnDestroy, OnInit {
    private d3: D3;
    private htmlElement: HTMLElement; // HTML <timeline> element
    private d3ParentElement: Selection<HTMLElement, any, null, undefined>; 
    private d3Svg: Selection<SVGSVGElement, any, null, undefined>;  // d3.select('svg')
    private d3G: Selection<SVGGElement, any, null, undefined>;  // d3.select('g') child of svg
    private margin: {top: number, right: number, bottom: number, left: number};   
    private width: number;       // Component width
    private height: number;      // Component height
    private colorScale: ScaleOrdinal<number, string>;

    constructor(private element: ElementRef, d3Service: D3Service) {
        this.d3 = d3Service.getD3();
        this.htmlElement = element.nativeElement;
    }

    ngOnInit() {
        this.d3ParentElement = this.d3.select(this.htmlElement);
        this.d3Svg = this.d3ParentElement.select<SVGSVGElement>('svg');
        this.setup();
        this.buildContainer();
    }

    private setup() {
        this.margin = { top: 10, right: 10, bottom: 10, left: 10 };
        this.width = this.htmlElement.firstElementChild.clientWidth - this.margin.left - this.margin.right;
        this.height = this.width * 0.5 - this.margin.top - this.margin.bottom;
    }

    buildContainer() {
      this.d3Svg = this.d3Svg
        .attr('width', this.width + this.margin.left + this.margin.right)
        .attr('height', this.height + this.margin.top + this.margin.bottom);
      this.d3G = this.d3Svg
        .append('g')
        .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')')
        .attr('class', 'container');
     }
}

This throws a TypeScript error:

error TS2322: Type 'Selection<BaseType, any, null, undefined>' is not 
assignable to type 'Selection<SVGGElement, any, null, undefined>'.
 Type 'BaseType' is not assignable to type 'SVGGElement'.
Type 'Element' is not assignable to type 'SVGGElement'.
  Property 'farthestViewportElement' is missing in type 'Element'.

Is this an error in the D3Service Types or am I selecting/appending incorrectly?

tomwanzek commented 7 years ago

This should be a very quick fix in your assignment/append. The append signature is parameterized with a generic for the type of element being appended (child element type). See the JSDoc comments here.

So all you need to do is use append<SVGGElement>('g') and it will work :smile:

denisemauldin commented 7 years ago

Thanks! :)