0

Im using Chartjs to draw charts in my ionic app. Everything works fine excepts the it renders the last in loop. Lets say there's there objects [0,1,2], it renders only 2, well using ng-repeat, it repeat 3 times since theres 3 objects in the array. ill attach my view and consoles log.

Console:

There are 3 pie objects, it only renders the last in loop

App view:

As you can see theres are the same charts

script:

for(i in blogs.data) {
   if(blogs.data[i].post_type_id == 3) {

        var chartdraw = JSON.parse(blogs.data[i].chart.data);

        if(blogs.data[i].chart.chart_type_id == 1){
            $scope.pieData = chartdraw;
            $log.info('pieData:',$scope.pieData);
        }
        else if(blogs.data[i].chart.chart_type_id == 2){
            $scope.barData = chartdraw;
            $log.info('barData:',$scope.barData);
        }
        else if(blogs.data[i].chart.chart_type_id == 3){
            $scope.lineData = chartdraw;
            $log.info('lineData:',$scope.lineData);
        }
        else if(blogs.data[i].chart.chart_type_id == 4){
            $scope.numberData = chartdraw;
            $log.info('numberData:',$scope.numberData);
        }

   }
}

view:

      <div class="card image" ng-if="blog.post_type_id == 3" >
         <a href="#/app/home/{{blog.id}}">
          <div class="thumb">
            <div>
              <canvas piechart options="chartOptions" data="pieData" width="150" height="150" ng-if="blog.chart.chart_type_id == 1">
              </canvas>
              <canvas barchart options="chartOptions" data="barData" width="150" height="150" ng-if="blog.chart.chart_type_id == 2">
              </canvas>
              <canvas linechart options="chartOptions" data="lineData" width="150" height="150" ng-if="blog.chart.chart_type_id == 3">
              </canvas>
              <div ng-if="blog.chart.chart_type_id == 4">
                <p ng-bind-html="numberData.details[0].value"></p>
                <p ng-bind-html="numberData.details[0].label"></p>
              </div>
            </div>
            <div class="text-center cat-icon">
              <span class="icon-wrapper">
                <i class="icon ion-stats-bars" style="position:relative;"></i>
              </span>
            </div>
          </div>

          <h4 class="title">{{blog.title}}</h4>
          <p class="details"><i class="icon ion-calendar"></i> {{blog.created_at}}</p>
         </a>
      </div> 

1 Answer 1

1

What's happening is this - charts from each of your blog posts (all of the ones in the picture happen to be pie) are bound to one of 3 objects depending on the chart type (for the picture, its $scope.pieData for all the charts)

The rest is a result of how angular works - it doesn't matter what the value of $scope.pieData was - when you update $scope.pieData, angular updates all references to $scope.pieData (and consequently the charts get updated as well).

In your case, you keep updating it in the loop and so at the end of the loop $scope.pieData is whatever was in the last post, consequently all your charts have that data. You need to have one scope variable for each chart

Here is a code pen illustrating what is happening in your case - http://codepen.io/anon/pen/doOqjN (I just removed chartjs to make it clearer) - notice that all the values are 3000.

And here is the codepen with the fix - http://codepen.io/anon/pen/MwbqBM. Notice that the values are now all different. The only lines I changed are

<div ng-if="blog.chart.chart_type_id == 1">{{blog.chart.data}}</div>
<div ng-if="blog.chart.chart_type_id == 2">{{blog.chart.data}}</div>
<div ng-if="blog.chart.chart_type_id == 3">{{blog.chart.data}}</div>

And you actually don't need the entirety of your script block!

You could probably optimize a bit more and I didn't actually do anything about numberData.details because I wasn't sure what it was supposed to be for.

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

2 Comments

Thanks man for the concept and codepen. I need to actually get the index for each objects from the api hence the loop. i would be undefined if i take it out of the loop. the api structure is like this, Objects [0,1,2,3,4,5,6,7] -> there are 4 types of posts, so i have to sort first using post.id.post_type_id , then if the post is for charts, I have to sort it again as there are 4 different types of charts , post.id.post_type_id.chart.chart_type_id . My script is just not working or it is badly structured.
Can't quite visualize it, but you might want to set up a parallel structure in the scope (i.e. one scope object for each chart's data).

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.