1/23/16

creating chart component - angular2

After creating my first component which displays current time, i want to try something little bit complicate.
This time lets create a component which displays chart:

For draw a chart i will use jquery flot library which is one of libraries/plugins which let you to create beautiful charts.
According to jquery flot docs - for draw a chart you need to pass html element(selector), data and options to plot plugin, like this:

$.plot( selector, dataset, options);


Component

As in previous case, lets create component

import {Component, ElementRef} from 'angular2/core';

@Component({
  selector: 'flot',
  template: `<div>loading</div>`

})

export class FlotCmp {
  private dataset;
  private options;
  private width = '100%';
  private height = 220;

  
  constructor(public el: ElementRef) {
        this.dataset = [{label: "line1",data:  [[1, 130], [2, 40], [3, 80], [4, 160], [5, 159], [6, 370], [7, 330], [8, 350], [9, 370], [10, 400], [11, 330], [12, 350]]}];
        this.options = {
            series: {
                lines: { show: true },
                points: {
                    radius: 3,
                    show: true
                }
            }
        };
        
        let plotArea = $(this.el.nativeElement).find('div');
        plotArea.css({
            width: this.width,
            height: this.height
        });
        $.plot( plotArea, this.dataset, this.options);

  }//end of constructor
}

Yes!!! Now the chart s created!!!
Note that for access the html element on which i want to apply the chart, i'v used ElementRef module

Passing properties

Our next goal is to make newly created component configurable - e.g. ability to pass dataset, options, width, height configuration properties through the attributes:
  
     <flot [options]="splineOptions" [dataset]="dataset" height="550px" width="100%"></flot>
 
"Piece of cake!" you may say, like in previous case use the "input" factory and you done:

import {Component, ElementRef, Input} from 'angular2/core';

@Component({
  selector: 'flot',
  template: `<div>loading</div>`

})
//this will cause error!!!
export class FlotCmp{

  private width = '100%';
  private height = 220;
  static chosenInitialized = false;
  
  @Input() private  options: any;
  @Input() private  dataset:any;
  @Input() private  width:string;
  @Input() private  height:string;
      
   
  constructor(public el: ElementRef) {
        plotArea.css({
            width: this.width, 
            height: this.height
        });
        $.plot( plotArea, this.dataset, this.options);        
  }
  ...  

Bad idea! No chart created anymore.
But why? Because the constructor runs before input setters passing their values. We must move plot initiating logic to some later phase. I find the solution here. This guy uses AfterViewInit factory:

import {Component, ElementRef, Input, AfterViewInit} from 'angular2/core';

@Component({
  selector: 'flot',
  template: `<div>loading</div>`

})

export class FlotCmp  implements AfterViewInit{

  private width = '100%';
  private height = 220;
  static chosenInitialized = false;
  
  @Input() private  options: any;
  @Input() private  dataset:any;
  @Input() private  width:string;
  @Input() private  height:string;
 
  constructor(public el: ElementRef) {}

  ngAfterViewInit() {
      if(!FlotCmp.chosenInitialized) {
        let plotArea = $(this.el.nativeElement).find('div').empty();
        plotArea.css({
            width: this.width, 
            height: this.height
        });
        $.plot( plotArea, this.dataset, this.options);    
        FlotCmp.chosenInitialized = true;
      }
  } 
} 


Now the chart initiating logic is in the ngAfterViewInit method which activates after properies already set.
Hope you have fun reading!
More posts about angular2 stuff (used for me as inspiration source)

No comments:

Post a Comment

Getting started with docker

It is very simple to get started usig docker. All you need to do-is download the docker desktop for your system Once you get docker syste...