It seems fine whenever I dump the chart to the main app.component.html, but as soon as I use it in a child component and have the app routed to it, the chart doesn't show up. In the inspector window, it shows the element as having 0 height and 0 width. Does anyone have a solution to this?
Here is my code for my app.component.ts:
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {HomeComponent} from './home.component';
import {ProfileComponent} from './profile.component';
import {HoursComponent} from './hours.component';
import {SettingsComponent} from './settings.component';
import {TaskComponent} from './task.component';
import {ChartDirective} from './chart.directive';
@Component({
selector: 'track-me',
templateUrl: 'app/app.component.html',
directives: [ROUTER_DIRECTIVES,ChartDirective]
})
@RouteConfig([
{ path: '/', component: HomeComponent, name: 'Home' },
{ path: '/home', component: HomeComponent, name: 'Home' },
{ path: '/profile', component: ProfileComponent, name: 'Profile' },
{ path: '/hours', component: HoursComponent, name: 'Hours' },
{ path: '/settings', component: SettingsComponent, name: 'Settings' },
{ path: '/task', component: TaskComponent, name: 'Task' },
])
export class AppComponent { }
Here is my code for my app.component.html:
<ul class="nav navmenu-nav">
<li><a [routerLink]="['/Home']">Home</a></li>
<li><a [routerLink]="['/Profile']">Profile</a></li>
<li><a [routerLink]="['/Hours']">Set Hours</a></li>
<li><a [routerLink]="['/Settings']">Settings</a></li>
<li><a [routerLink]="['/Task']">Completed Task</a></li>
</ul>
<router-outlet></router-outlet>
<canvas id="myChart" chart height="250" width="350"></canvas>
The canvas element on the html page will show fine. However, once I put it inside of my home.component, it wont show.
Here's my home.component.ts:
import {Component} from 'angular2/core';
import {ChartDirective} from './chart.directive';
import {TopicsComponent} from './topics.component';
@Component({
selector: 'home',
templateUrl: 'app/home.component.html',
directives: [TopicsComponent, ChartDirective]
})
export class HomeComponent { }
Here's my home.component.html:
<div class="container details-container">
<topics></topics>
</div>
<div class="graph-container">
<div class="row no-pad" style="position: relative;">
<div style="margin-left:14px; z-index: 100; height: 250px;">
<canvas id="myChart" chart height="250" width="350"></canvas>
</div>
<div class="vaxis-bar"></div>
</div><!--/row-->
<div class="row">
<div class="col-sm-12 text-center bottom-row">
HOURS(9)
</div>
</div>
</div>
Finally, here's my chart.directive.ts:
/// <reference path="../node_modules/chart.js/chart.d.ts" />
import {Directive, ElementRef, Renderer, Input} from 'angular2/core';
@Directive({
selector: '[chart]'
})
export class ChartDirective {
constructor(el: ElementRef, renderer: Renderer) {
//el.nativeElement.style.backgroundColor = 'yellow';
var data = {
labels: ["", "", "", "", "", "", "", "", ""],
datasets: [
{
label: "Track Me",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(13,220,138,1)",
pointColor: "rgba(13,220,138,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [1, 3, 13, 7, 0, 5, 9, 2, 5]
}
]
};
var opts = {
pointDot: false, scaleFontColor: "#50728d", scaleShowLabels: true, responsive: false, scaleLineColor: "rgba(255,255,255,.3)"
};
var ctx: any = el.nativeElement.getContext("2d");
var lineChart = new Chart(ctx);
////var lineChartOptions = areaChartOptions;
////lineChartOptions.datasetFill = false;
lineChart.Line(data,opts);
}
}
Ok, so here's how I solved the issue I was having. I created a new canvas component with just the canvas element and imported my chart directive to the new component. After that, I used the DynamicComponentLoader class to dynamically load my component whenever I create an instance of my home component.
New home.component.ts:
import {Component, DynamicComponentLoader, Injector} from 'angular2/core';
import {TopicsComponent} from './topics.component';
import {CanvasComponent} from './canvas.component';
@Component({
selector: 'home',
templateUrl: 'app/home.component.html',
directives: [TopicsComponent, CanvasComponent]
})
export class HomeComponent {
constructor(dcl: DynamicComponentLoader, injector: Injector) {
dcl.loadAsRoot(CanvasComponent, '#chartInsert', injector);
}
}
New home.component.html
<div class="container details-container">
<topics></topics>
</div>
<div class="graph-container">
<div class="row no-pad" style="position: relative;">
<div style="margin-left:14px; z-index: 100; height: 250px;" id="chartInsert">
</div>
<div class="vaxis-bar"></div>
</div><!--/row-->
<div class="row">
<div class="col-sm-12 text-center bottom-row">
HOURS(9)
</div>
</div>
</div>
New canvas.component.ts
import {Component} from 'angular2/core';
import {ChartDirective} from './chart.directive';
@Component({
selector: 'canvas-component',
template: '<canvas id="myChart" chart height="250" width="350"></canvas>',
directives: [ChartDirective]
})
export class CanvasComponent { }
I hope this can help someone out.
There was a breaking change in Angular 2.0.0-beta.3 regarding ElementRef https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta3-2016-02-03. Instead of using ElementRef inside the constructor you should look at ngOnInit as a LifeCycle hook https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With