0

I want to implement a Chart of a Sharepoint tracker list. I decided to use angular-chart.js, to use this code I also needed Charter.js. So I downloaded both and decided to make a try as one of the examples in their page.
They have a bar chart with a code like this:

<script>
angular.module("app", ["chart.js"]).controller("BarCtrl", function ($scope) 
{
  $scope.labels = ['2006', '2007', '2008', '2009', '2010', '2011', '2012'];
  $scope.series = ['Series A', 'Series B'];

  $scope.data = [
    [65, 59, 80, 81, 56, 55, 40],
    [28, 48, 40, 19, 86, 27, 90]
  ];
});
</script>
<canvas id="bar" class="chart chart-bar"
  chart-data="data" chart-labels="labels"> chart-series="series"
</canvas>

So I decided to make a similar code and I customize it a little, my Sharepoint list have these columns: Title, Number Actions, Section.

<!DOCTYPE html>
<html>
<head>
    <script src="jquery-2.1.4.min.js"></script>
    <script src="angular.js"></script>
    <script src="Chart.js"></script>
    <script src="angular-chart.min.js"></script>
    <script>
        var myApp = angular.module("myApp", ["chart.js"]);

        myApp.controller("myController", function($scope, $http) {
            //Here's the code to call the Sharepoint List
            $http({
                method:'GET',
                url:_spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('My Tracker')/items?$select=*,LinkTitle",
                headers: { "Accept": "application/json; odata=verbose" }
            }).success(function(data, status, headers, config) {
                $scope.dataResults = data.d.results;
            }).error(function(data, status, headers, config) {
                alert("Error! The Tracker Chart can't be loaded.");
            });

            //These are the chart settings
            $scope.labels = dataResults.LinkTitle
            $scope.series = [
                'Number Actions',
                'Section'
            ];
            $scope.data = [
                dataResults.Number_x0020_Actions,
                dataResults.Section
            ];
        });
    </script>
</head>
<body>
    <div ng-app="myApp" ng-controller="myController">
        <canvas id="bar" class="chart chart-bar"
                chart-data="data"
                chart-labels="labels"
                chart-series="series">
        </canvas>
    </div>
</body>
</html>

Obviously this is not working, because I don't know what I'm doing. But I would like to know how can I link the chart with my sharepoint list, because in every site I visit when people ask how to make a chart with angularJS they write the data already in the code, but I need to read that data directly from the list.

Please help c:

EDIT:
This is my final code, I hope it can help somebody:

<!DOCTYPE html>
<html>
<head>
    <script src="jquery-2.1.4.min.js"></script>
    <script src="angular.js"></script>
    <script src="Chart.js"></script>
    <script src="angular-chart.min.js"></script>
    <script>
        var myApp = angular.module("myApp", ["chart.js"]).controller("myController", function($scope, $http) {
            $http({
                method:'GET',
                url:_spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('My Tracker')/items?$select=*,LinkTitle",
                headers: { "Accept": "application/json; odata=verbose" }
            }).success(function(data, status, headers, config) {
                $scope.dataResults = data.d.results;

                var dataR = $scope.dataResults, arrayLabels = [], arrayNumberActions = [], arraySections = [];
                for(var i = 0 ; i< dataR.length; i++){
                    var currentItem = dataR[i];
                    arrayLabels .push(currentItem.LinkTitle);
                    arrayNumberActions.push(currentItem.Number_x0020_Actions);
                    arraySections.push(currentItem.Section);
                }

                $scope.labels = arrayLabels;
                $scope.series = ['Number Actions', 'Section'];
                $scope.data = [
                            arrayNumberActions,
                            arraySections
                        ];
            }).error(function(data, status, headers, config) {
                alert("Error! The Tracker Chart can't be loaded.");
            });
        });
    </script>
</head>
<body>
    <div ng-app="myApp" ng-controller="myController">
        <canvas id="bar" class="chart chart-bar"
                chart-data="data" chart-labels="labels" chart-series="series">
        </canvas>
    </div>
</body>
</html>
0

dataResults is an array of Object. For example consider your list having 2 columns - Number_x0020_Actions and Section and 3 items in it. the result returned by %http will be like this:

[{
    "Title" : "Title One",
    "Number_x0020_Actions" : 10,
    "Section" : 10
},{
    "Title" : "Title Two",
    "Number_x0020_Actions" : 10,
    "Section" : 20
},{
    "Title" : "Title Three",
    "Number_x0020_Actions" : 10,
    "Section" : 30
}]

So, if you pass the array to chart like this - "dataResults.Number_x0020_Actions", it is going to throw an error because dataResults is an array.

You need to build your array to pass to chart data from the data returned by http. To do so you can either loop through all items and create an array or use "lodash.js" script.

1. Looping through items

    var arrayLabels = [], arrayNumberActions = [], arraySections = [];
    for(var i = 0 ; i< dataResults.length; i++){
        var currentItem = dataResults[i];
        arrayLabels .push(currentItem.Title);
        arrayNumberActions.push(currentItem.Number_x0020_Actions);
        arraySections.push(currentItem.Section);
    }

    //Now your Chart labels & data becomes like this:
    $scope.labels = arrayLabels; //this should be ["Title One","Title Two","Title Three"]
    $scope.data = [
                arrayNumberActions, //this should be [10,10,10]
                arraySections //this should be [10,20,30]
            ];

2. Using Lodash

add this script to your html

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

This library has numerous functions to parse objects & arrays.

Like in the loop above we have to create 3 arrays and then get data out of the result returned by http call.

var arrayLabels = [], arrayNumberActions = [], arraySections = [];
arrayLabels = _.map(dataResults, 'Title'); //this should be ["Title One","Title Two","Title Three"]
arrayNumberActions = _.map(dataResults, 'Number_x0020_Actions'); //this should be [10,10,10]
arraySections = _.map(dataResults, 'Section'); //this should be [10,20,30]
//Now your Chart labels & data becomes like this:
    $scope.labels = arrayLabels;
    $scope.data = [
            arrayNumberActions,
            arraySections
        ];
  • don't know why, but everytime I try to use your code it's telling me that "dataResults is not defined", but I thought "$scope.dataResults" is defining it ..I tried this code inside and outside the Success handler and always gives me the same error. – Soul Eeater Nov 12 '18 at 17:15
  • Try it only inside the sucess handler. And replace dataResults (everywhere in my code) with $scope.dataResults (this is the variable you have used) – harshal gite Nov 12 '18 at 17:18
  • Thanks dude, that really worked! actually now was giving me an error like "length is not a function", so I added "var dataR = $scope.dataResults". The code works pretty well, thank you. – Soul Eeater Nov 12 '18 at 20:53
0

dataresults is an array of objects. The properties you've tried to access on that - LinkTitle, Number Actions, and Section - are going to be undefined because they're not part of dataresults. They're part of the individual items that make up dataresults. So to populate the chart data you'll need to create three new arrays, loop through the items in dataresults and store off those properties in your new arrays, then bind the chart to those arrays.

But more than that you have a more fundamental problem, or rather, opportunity. I'm going to go out on a limb and guess that you don't know how to debug JavaScript in the browser. If my assumption is correct, then learning how to do this is going to change your life.

A Google search on "how to debug JavaScript in Chrome" yields lots of useful resources. Here's one. If videos aren't your bag there are lots of articles and books where you can learn this.

Lastly, you definitely want to use Chrome for most of your debugging as the other browsers, especially IE, have god-awful debugging experiences and Chrome's is pretty good.

Good luck!

EDIT Just noticed, you have some async stuff going on as well that is all broken. All the stuff you have setting up the chart needs to go into the success handler on your http call. Yet another thing that's not so easy to see just looking at the code, but very obvious inside the debugger.

  • I see... as I say, I had no idea what I was doing, I have used AngularJS only for tables but never for charts. I gonna give an eye on this.. – Soul Eeater Nov 12 '18 at 3:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.