Machinarius
Machinarius

Reputation: 3731

Why would a ChartJS chart end up with width 0 and height 0?

I have the following angularJS directive

app.directive('answersPlot', function() {
  return {
    scope: {
      chartData: "=chartData",
      chartType: "=chartType"
    },
    template: '<canvas width="100px" height="100px" style="width:100px; !important height:100px; !important"></canvas>',
    link: function(scope, element, attrs) {
      var canvas = element[0].childNodes[0];
      var context = canvas.getContext('2d');
      var chart = new Chart(context);

      if (scope.chartType == 0) {
        chart.Bar(scope.chartData, {});
      } else {
        chart.Pie(scope.chartData, {});
      }
    }
  }
});

I am instantiating it inside an ng-repeat DOM block like this

<div ng-repeat="question in talk.questions track by $index">
  <answers-plot chart-data="question.chartData" chart-type="question.chartType"></answers-plot>
</div>

Yet when i inspect the DOM i find this

<answers-plot chart-data="question.chartData" 
chart-type="question.chartType" 
class="ng-isolate-scope">
  <canvas width="0" height="0" style="width: 0px; height: 0px;"></canvas>
</answers-plot>

With no errors logged into the console. chartData has this format: "{"labels":["A","C","D","B"],"datasets":[{"data":[0,2,0,1]}]}".

Manually changing the width/height values (in CSS and as attributes) only yields a bigger blank canvas.

I have tried two angularjs chartjs libraries that experience this same issue, resorted to writing my own directive to verify the data was actually getting to the chartjs library. Still no nuts. What am i doing wrong?

Upvotes: 2

Views: 2495

Answers (3)

iam91
iam91

Reputation: 71

I encountered the same problem the other day.
And I found that:

The parent of <canvas> is <answers-plot>, and the <answers-plot> 's width and height are 0. It seems that Chartjs resizes its chart according to the size of the parent element of <canvas> which causes the width and height of the canvas to be 0.

I used a <div> to wrap the <canvas> in my directive's template and gave a non-zero size to the <div>
or
set the responsive (in Chartjs's options) to false, and the problem is solved.

Upvotes: 7

user888734
user888734

Reputation: 3897

I found similar behaviour with Aurelia (rather than Angular) - it didn't like rending the chart inside an element with a custom name, in your case "answers-plot". With Aurelia, I can just add "containerless" to my custom element and it works. I'm not sure with Angular directives - maybe replace:true, or transclude:true in the directive options?

Upvotes: 1

Thomas
Thomas

Reputation: 181950

The width and height attributes of the <canvas> element are unitless, so use:

template: '<canvas width="100" height="100" style="width:100px; !important height:100px; !important"></canvas>'

Upvotes: 0

Related Questions