2

I'm trying to create a pie chart on an element using the directive in Angular 5. I created a directive like:

@Directive({
  selector: '[pieChart]'
})
export class PieChartDirective implements AfterViewInit {

  @Input() pieChart: any;
  @Input() pieChartElementId: string;
  @Input() pieChartData: any;

  constructor(elem: ElementRef, renderer: Renderer2) {}

  ngAfterViewInit() {
    this.generatePieChart(this.pieChartElementId);
  }

  generatePieChart(elemId) {
    var values = [1, 2, 3];

    $('#' + elemId).sparkline(values, {
      type: "pie",

      tooltipFormat: '{{offset:offset}} ({{percent.1}}%)',
      tooltipValueLookups: {
        'offset': {
          0: 'First',
          1: 'Second',
          2: 'Third'
        }
      },
    });
  }
}

In the template I'm calling directive like:

<div class="pieChartDiv" [attr.id]="'classroom.field1' + '_'+ i" [pieChart]="'classroom.field1' + '_'+ i" [pieChartElementId]="'classroom.field1' + '_'+ i"></div>

I'm creating id dynamically and want to draw the pie chart on each id. But unfortunately, I'm not getting the length of element in directive when using console.log($("#"+this.pieChartElementId).length) in the directive file. Due to that charts are not working because they are not getting the element. Could anyone please tell me why this happening. Thanks in advance.

1
  • 1
    Instead of doing $('#' + elemId) try $(this.elem.nativeElement). For this to work you will also have to add an access modifier to the elem parameter for your constructor to automatically make it a property of your class e.g. constructor(private elem:ElementRef, renderer:Renderer2) {}. Commented Jul 19, 2019 at 12:48

1 Answer 1

2

You should not use JQuery #() selector with Angular: as you can see, even after view init your pieChartElementId element might not be rendered yet.

Instead you should use elementRef or @ViewChild:

  • If pieChartElementId is the element on which pieChart directive is applied, you should use:

    elementRef.nativeElement

  • If you want to select another element, it's a little more complexe. You have to use @ViewChild to get the element:

    @ViewChild('pieChartElement') pieChartElement;

    then pass it to the directive input:

    <div pieChart [externalElement]="pieChartElement"> Element with directive </div> <p #pieChartElement> External element </p>

See this working example

Sign up to request clarification or add additional context in comments.

1 Comment

great explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.