how to Create AngularJS charts with dynamic data
Asked Answered
A

2

6

Hi im trying having a webpage that displays the sentiments of tweets of politicians. I am trying to create a chart for the sentiment statistics. I am using Zingchart and i am able to create for static data but i am not able to create for dynamic data.

This is the code that i used to insert static data with array chartdata.

   <div class="row">
    <div class="col-sm-12">
      <div ng-init="chartdata = [[1167],[456],[990]]">
        <zingchart id="chart-1" zc-values="chartdata" zc-json="myJson" 
         zc-width="100%" zc-height="568px"></zingchart>
      </div>
    </div>
  </div>

static pie chart

It works fine like this but i want to use data from my angularjs instead of the static values. For example: Im trying to do something like this but it does not work

  <div class="row">
      <div class="col-sm-12">
        <div ng-init="chartdata =[[{{politicianData.stats.total_positive}}],[{{politicianData.stats.total_negative}}],[{{politicianData.stats.total_neutral}}]]">
          <zingchart id="chart-1" zc-values="chartdata" zc-json="myJson" zc-width="100%" zc-height="568px"></zingchart>
        </div>
      </div>
    </div>

How to get the data from the promise array data from the angular controller?

this is my politician-controller:

    angular.module('myapp')
    .controller('PoliticianController', function($scope, PoliticianData, Politician, searchService, utilService) {
var politicianData = new Politician(PoliticianData);

        politicianData.$promise.then(function (result) {

            $scope.politicianData = result;
  });
$scope.myJson = {
                            globals: {
                            shadow: false,
                            fontFamily: "Verdana",
                            fontWeight: "100"
                                        },
                                        type: "pie",
                                        backgroundColor: "#fff",

                                        legend: {
                                            layout: "x5",
                                            position: "50%",
                                            borderColor: "transparent",
                                            marker: {
                                                borderRadius: 10,
                                                borderColor: "transparent"
                                            }
                                        },
                                        tooltip: {
                                            text: "%v requests"
                                        },
                                        plot: {
                                            refAngle: "-90",
                                            borderWidth: "0px",
                                            valueBox: {
                                                placement: "in",
                                                text: "%npv %",
                                                fontSize: "15px",
                                                textAlpha: 1,
                                            }
                                        },
                                        series: [{
                                            text: "Positive",
                                            backgroundColor: "#FA6E6E",
                                        }, {
                                            text: "Negative",
                                            backgroundColor: "#D2D6DE"
                                        }, {
                                            text: "Neutral",
                                            backgroundColor: "#28C2D1"
                                        }]
                                    };

    });

And this is the politician.html page

<span>{{politician.first_name}} {{politician.last_name}}</span>
                    </td>
                    <td>{{politicianData.stats.total}}</td>
                    <td>{{politicianData.stats.twitter.total}}</td>
                    <td>{{politicianData.stats.rss.total}}</td>
                   <td>{{politicianData.stats.total_negative}}</td>
                   <td>{{politicianData.stats.total_positive}}</td>
                   <td>{{politicianData.stats.total_neutral}}</td>

PoliticianData.stats.total_positive displays the count correctly and i want to use the same data as input values to my chart. How do I do that?

Apophthegm answered 26/7, 2016 at 11:57 Comment(0)
Y
3
  • Create a service with factory
  • Call that service for data
  • Use only zingchart directive
  • When scope data changed, chart will be open.

Example:

var myModule = angular.module('myModule', []);

myModule.controller('myController', function($scope, chartService) {
  $scope.chartdata = chartService.getDataWithService();
});

myModule.factory('chartService', function($http) {
  return {
    getDataWithService: function() {
      var url = "yourServiceURL";
      return $http.get(url);
    },
    getData: function() {
      return {
        type: 'line',
        series: [{
          values: [54, 23, 34, 23, 43]
        }, {
          values: [10, 15, 16, 20, 40]
        }]
      };
    }
  };
});

html:

 <zingchart id="chart-1" zc-values="chartdata" zc-json="myJson" zc-width="100%" zc-height="568px"></zingchart>
Yestreen answered 26/7, 2016 at 12:19 Comment(1)
Hello thanks for reply...but i already have my data from open database. see the edit above..maybe it will help you understand my question better.Apophthegm
V
7

Full disclosure, I'm a member of the ZingChart team.

This exact functionality you are looking for is data binding. We have documentation on our angularjs-charts page for data binding elements to the chart.

In your case there are a few steps need to achieve what you want. My first suggestion would be to take unnecessary controller logic out of your view in the ng-init and keep it inside the directive. Just a suggestion, not necessary. For the sake of this answer my format will keep most everything inside the controller.

HTML:

<body ng-app="myApp">
  <div ng-controller="MainController">
    <div zingchart id="chart-1" zc-json="myJson" zc-width="100%" zc-height="568px" zc-values="aValues"></div>
  </div>
</body>

App Logic:

var app = angular.module('myApp',['zingchart-angularjs']);

app.controller('MainController', function($scope, $timeout) {

// mimick your promise
(function(){
  $scope.data = {};
  $scope.data.valuesOne = [1,2,3,4,5];
  $scope.data.valuesTwo = [1,2,3,4,5];
  $scope.aValues = [$scope.data.valuesOne,$scope.data.valuesTwo];
})();

$scope.myJson = {
  type : "bar",
  title:{
    backgroundColor : "transparent",
    fontColor :"black",
    text : "Hello world"
  },
  backgroundColor : "white",
  series : [
    {
      backgroundColor : '#00baf2'
    },
    {
      backgroundColor : '#4caf4f'
    }
  ]
};

 // automatically wraps code in $apply
 $timeout(function(){

   // wont reflect changes in aValues because its an object
   $scope.data.valuesOne = [5]; 

   // must force the reflection of the changes
   $scope.aValues = [$scope.data.valuesOne, $scope.data.valuesTwo];

   // will reflect changes with one line, not the above two lines
   //$scope.aValues[0] = [5];

 },1500);

});

You can see that I have set a $timeout to reflect graph changes after a 1.5 seconds. This $timeout is to mimic some sort of object change from a DB update. There are two ways to update the values but to see why we must first learn more about the ZingChart Angular directive.

You must use zc-values in HTML and not just zc-json because the code has a deep equality watch on zc-values by using $watchCollection().

"The $watchCollection() function is a sort-of mid-ground between the two $watch() configurations above. It's more in-depth than the vanilla $watch() function; but, it's not nearly as expensive as the deep-equality $watch() function. Like the $watch() function, the $watchCollection() works by comparing physical object references; however, unlike the $watch() function, the $watchCollection() goes one-level deep and performs an additional, shallow reference check of the top level items in the collection." -referenced here.

Thats why it'll only work in my example when I change references in the aValues array.

You can see that inside the $timeout there are two ways to update the values of the chart. Because you have an array of arrays making changes to the inner arrays wont be reflected because they are deep object properties. You can see updating a single array must be force assigned back into the parent to reflect the change. A change on the parent directly will update the reference and will reflect changes in one line.

Codepen demo here.

More Angular/ZingChart Links

  1. Angular Page
  2. ZingChart Codepen
Vanhoose answered 26/7, 2016 at 18:20 Comment(4)
I came across this link, and currently i'm working on the same kind of requirement. Please check the example codepen.io/anon/pen/BWGEYG. I want to show first stacked bar with data $scope.data.valuesOne = [10,20,30,40,5] and second stacked bar should represent the data $scope.data.valuesTwo = [12,12,30,10,5]. I went through many links to find the solution but i think its not that straight forward..Please advice.Broad
Unfortunately the way you see the input is how we approach our stacked bars. It is pretty straight forward. The first series (data.valuesOne) is the first row in the stack. The second series (data.valuesTwo) is the second row in each stack. You just need to convert your data to that format.Vanhoose
If you have further questions, please open up a new question. $scope.data.valuesOne = [10,12]; $scope.data.valuesTwo = [20,12]; $scope.data.valuesThree = [30, 30]; $scope.data.valuesFour = [40, 10]; $scope.data.valuesFive = [5, 5] $scope.aValues = [$scope.data.valuesOne,$scope.data.valuesTwo,$scope.data.valuesThree,$scope.data.valuesFour,$scope.data.valuesFive];Vanhoose
@Vanhoose can we use zingchart for a graph that changes at like every 1 second? how?Chace
Y
3
  • Create a service with factory
  • Call that service for data
  • Use only zingchart directive
  • When scope data changed, chart will be open.

Example:

var myModule = angular.module('myModule', []);

myModule.controller('myController', function($scope, chartService) {
  $scope.chartdata = chartService.getDataWithService();
});

myModule.factory('chartService', function($http) {
  return {
    getDataWithService: function() {
      var url = "yourServiceURL";
      return $http.get(url);
    },
    getData: function() {
      return {
        type: 'line',
        series: [{
          values: [54, 23, 34, 23, 43]
        }, {
          values: [10, 15, 16, 20, 40]
        }]
      };
    }
  };
});

html:

 <zingchart id="chart-1" zc-values="chartdata" zc-json="myJson" zc-width="100%" zc-height="568px"></zingchart>
Yestreen answered 26/7, 2016 at 12:19 Comment(1)
Hello thanks for reply...but i already have my data from open database. see the edit above..maybe it will help you understand my question better.Apophthegm

© 2022 - 2024 — McMap. All rights reserved.