5

I'm trying out Kendo charts with angular, and I have problem displaying data, here is my code:

HTML:

<div  kendo-chart="rchart" data-k-options="chartOptions" data-role="chart" class="k-chart" style="position: relative;"></div>

Javascript:

resultService.getResult().then(function (resultResponse) {
         $scope.data = resultResponse.data;
         $scope.oldReps = _.pluck($scope.data.TreningScores.Item1, 'Item2');
         $scope.newReps = _.pluck($scope.data.TreningScores.Item2, 'Item2');
         $scope.categories = _.pluck($scope.data.TreningScores.Item1, 'Item1');
     });


$scope.chartOptions = {

         legend: {
             position: "bottom"
         },
         seriesDefaults: {
             type: "column"
         },
         series: [{
             name: "Total Visits",
             data: $scope.oldReps
         }, {
             name: "Unique visitors",
             data: $scope.newReps
         }],
         valueAxis: {
             line: {
                 visible: false
             }
         },

         tooltip: {
             visible: true,
             format: "{0}"
         }
     };

The problem is chart isn't updated after data is fetched from server, I've tried refreshing chart like this (but with no luck):

$scope.chart = {        
        refreshChart : function() {
            $scope.rchart.refresh();
        },
    };

And calling this method in:

resultService.getResult().then(function (resultResponse) {});

And I've also tried to define $scope.chartOptions inside same function, but nothing. Is there any way to fix this ?

George Brighton
  • 5,131
  • 9
  • 27
  • 36
hyperN
  • 2,674
  • 9
  • 54
  • 92
  • 1
    @george-brighton I'm a bit late to the party on this reply, but check out my simplified solution and example: http://stackoverflow.com/a/39739389/1467810 – TaeKwonJoe Sep 28 '16 at 07:14

3 Answers3

11

It's not well documented, but to get a UI control with remote data-binding to update after data has been returned from a server requires both watching the collection for updates from the Angular side and rebinding the data object to its respective UI control from the Kendo side.

In your controller, watch for changes to your data objects using $watchCollection, and update the objects/properties which are bound to those collections:

// API call
$http.get('...').success(function(data){
   $scope.data = data;
});

// KendoUI config object
$scope.chart = {
    dataSource: {
        data: $scope.data
    }
};

// Watch for changes to $scope.data
$scope.$watchCollection('data', function(newData) {

    // Update data bindings with changes
    $scope.chart.dataSource.data = newData;
});

In your view, define the object your UI control should be bound to when changes are made via the k-rebind Angular-Kendo directive:

<div kendo-chart k-options="chart" k-rebind="chart"></div>

Here is an example of a chart bound to remote data:

http://codepen.io/micjamking/pen/4980a5e22cbd4de01264fadae5f25f06

micjamking
  • 2,183
  • 1
  • 21
  • 24
  • wow! that k-rebind was really helpful thanks!, where can I find more information about it? – Sebastian Perez May 19 '14 at 20:20
  • 1
    By the kendo teams own admission, `k-rebind` is missing from the documentation. I had to dig through the Angular-Kendo Github repo's closed issues to find it: https://github.com/kendo-labs/angular-kendo/issues/33#issuecomment-20264067. Glad this helped someone else. – micjamking May 20 '14 at 03:16
  • Finally i found answer for this problem. Thanks! – the_bluescreen Apr 20 '15 at 22:59
  • @micjamking the example of the Kendo Chart is not working anymore. Can you update it? thank you. – Shaohao Jul 30 '15 at 17:44
  • @ShaohaoLin Spotify changed their api endpoint, should be updated now: http://codepen.io/micjamking/pen/4980a5e22cbd4de01264fadae5f25f06 – micjamking Jul 30 '15 at 21:16
  • @micjamking still not working. The link that you commented has the same end point as the one your post on the answer session. – Shaohao Jul 31 '15 at 12:58
  • @shaohaolin the endpoint didn't change and should be the same, I only updated the code in the link. I'm sorry it's not working for you, the chart is displaying and working properly from my end after updating yesterday. Have you tried the solution yet in your actual use-case? – micjamking Jul 31 '15 at 16:54
  • @micjamking improperly assigning dataSource.data instead of using the dataSource.data() method is what required $watchCollection. – TaeKwonJoe Sep 28 '16 at 07:22
1

The use of $watchCollection to track and assign the dataSource.data in the accepted answer and others is a needlessly convoluted approach.

Here's a straightforward implementation:

view:

<div kendo-chart k-theme='metro' k-options="chart" k-rebind="chart"></div>

controller:

$scope.chart = {
  dataSource: new kendo.data.DataSource({
    data: [{ title: "Loading", value: 100, color: '#EFEFEF' }]
  }),
  series: [{ field: 'value', categoryField: 'title', padding: 0, holeSize: 25 }],
  seriesDefaults: { type: 'donut', startAngle: 90 }
};

Using the dataSource.data() method instead of assigning dataSource.data as an array is the key here:

payrollService.load(userId).then(function (result) {
  $scope.chart.dataSource.data(result.items); //where result.items is an array like so:
  //[
  //  { title: "Net Pay", value: 60, color: '#6BAE4B' },
  //  { title: "Taxes", value: 15, color: '#ED6347' },
  //  { title: "Deductions", value: 25, color: '#8161C2' }
  //]
});

Codepen Demo: http://codepen.io/TaeKwonJoe/pen/WGOpEv

TaeKwonJoe
  • 1,077
  • 11
  • 24
0

I think your problem is that $scope.chartOptions is set before the data of the resultService is retrieved. Angular is returning an empty array in this case and filling in the data later. But $scope.chartOptions not not updated with new data.

You could try with

$scope.$watchCollection('oldReps', function(newData, oldData) {
  $scope.chartOptions.series[0].data = newData;
});
$scope.$watchCollection('newReps', function(newData, oldData) {
  $scope.chartOptions.series[1].data = newData;
});

So chartOptions are updated if oldReps or newReps have changed.

I had a similiar problem and $watchCollection saved my day (Caching data and updating another object for an chart does not work)

Community
  • 1
  • 1
KEB
  • 13
  • 3