1

I am working on using flotcharts to chart some points on a dashboard and am having some trouble with it.

First, the dashboard is angular, so I have setup a directive to initialize flot and it seems to be working. The chart loads and graphs the first set of data available to it. The issue arises when I try to update the data used to generate the graph.

When I do this, the data updates, but only displays the first 3 points, it does not display the full dataset in the result - only the first 3 charted values. The JSON result set retrieved can vary in length (the data returned is based on date values set elsewhere and requested by the updateStats function). What I need it to do, so dynamically chart all the data that is there not just the first few rows in the dataset.

Im not sure why it is doing it and have given up on banging my head on the desk :D. Any help with this would be GREATLY appreciated.

Here is my code (please disregard the console.logs etc - I have been trying to debug this in a variety of ways):

The Directive

.directive('flotChart', function () {
return {
  restrict: 'AE',
  scope: {
    data: '=flotData',
    options: '=flotOptions',
    plothover: '&plotHover',
    plotclick: '&plotClick'
  },
  link: function (scope, element, attr) {
    var plot = $.plot($(element), scope.data, scope.options);

    $(element).bind('plothover', function (event, position, item) {
      scope.plothover( {
        event: event,
        position: position, 
        item: item
      });
    });

    $(element).bind('plotclick', function (event, position, item) {
      scope.plotclick( {
        event: event,
        position: position, 
        item: item
      });
    });

    scope.$watch('data', function (newVal, oldVal) {
      console.log("DATA WATCH");
      plot.setData(newVal);
      plot.draw();
    });

    scope.$watch('options', function (newVal, oldVal) {
      plot = $.plot($(element), scope.data, newVal);
    }, true);
  }
}

})

The Controller

.controller('DashboardController', ['$scope','$http', function ($scope,$http) {

//removed a section of code not pertinent to this conversation

    $scope.plotStatsData = [{data:[[1,500],[2,250],[3,150]], label:'TEST'}];

$scope.init = function() {
   $scope.updateStats(); 
}

    $scope.updateStats = function() {
    $http.post("/admin/dashboard/loaddata",{start_date: $scope.drp_start, end_date: $scope.drp_end}).success(function(response){
        $scope.totals = response.summary;
        //console.log(response.dataset);
        $scope.plotPoints(response.dataset);
    });
};

$scope.plotPoints = function(data) {
    var layer1 = {data:[],label:'Users'};

    var count = 1;

    if (confirm("Clear it?"))
    $scope.plotStatsData = [];

    for (var i=1; i < data.length; i++)
        layer1.data.push([i,parseInt(data[i-1].users)]);

    console.log(layer1);

    $scope.plotStatsData.push(layer1);

}

$scope.plotStatsOptions =  {
    series: {
        lines: {
            show: true,
            lineWidth: 1.5,
            fill: 0.1
        },
        points: {
            show: true
        },
        shadowSize: 0
    },
    grid: {
        labelMargin: 10,
        hoverable: true,
        clickable: true,
        borderWidth: 0
    },
    tooltip: true,
    tooltipOpts: {
      defaultTheme: false,
      content: "View Count: %y"
    },
    colors: ["#b3bcc7"],
    xaxis: {
        tickColor: 'transparent',

        tickDecimals: 0,
        autoscaleMargin: 0,
        font: {
            color: 'rgba(0,0,0,0.4)',
            size: 11
        }
    },
    yaxis: {
        ticks: 4,
        tickDecimals: 0,
        tickColor: "rgba(0,0,0,0.04)",
        font: {
            color: 'rgba(0,0,0,0.4)',
            size: 11
        },
        tickFormatter: function (val, axis) {
            if (val>999) {return (val/1000) + "K";} else {return val;}
        }
    },
    legend : {
        labelBoxBorderColor: 'transparent'
    }
};





}])

The HTML

<div flot-chart style="width: 100%; height:250px" 
                                    data-flot-data="plotStatsData"
                                    data-flot-options="plotStatsOptions"
                                ></div>
1
  • Can you build a fiddle which reproduces the problem? Commented May 24, 2015 at 16:44

2 Answers 2

1

Your initial data has only three data points:

$scope.plotStatsData = [{data:[[1,500],[2,250],[3,150]], label:'TEST'}]; 

Then you update the data, but only do a redraw with the existing grid / axes.
Insert a call to setupGrid() and it should work:

scope.$watch('data', function (newVal, oldVal) {
    console.log("DATA WATCH");
    plot.setData(newVal);
    plot.setupGrid();
    plot.draw();
});
Sign up to request clarification or add additional context in comments.

2 Comments

That doesnt seem to work. ` plot.setData(newVal); plot.setGrid(); plot.draw();`. Still the same result.
Strange, this should do the same as drawing a complete new chart like in your answer.
0

I found the solution. To make it reload properly, instead of calling setData, and draw functions. I simply replaced that with the following:

In the directive change:

plot.setData(newVal);
plot.draw();

to

plot = $.plot($(element), newVal, scope.options);

This seems to effectively force the flot chart to reload and properly render the data set. :D

Comments

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.