import _ from 'lodash';
import Highcharts from 'highcharts';

function getTopGroups(data, n) {
  return _
    .chain(data)
    .sortBy([function(x) {
      if (x.counts.length) {
        return x.counts[x.counts.length - 1].totalPatients;
      } else {
        return 0;
      }
    }, 'group.name'])
    .take(n)
    .map('group.id')
    .value();
}

function patientsByGroupDateGraph(adapter) {
  return {
    scope: {
      groupType: '@',
      type: '@',
      top: '@'
    },
    template: '<div loading="loading" class="graph"></div>',
    link: function(scope, element) {
      scope.loading = true;

      var params = {groupType: scope.groupType};

      var title = scope.type === 'new' ? 'New Patients' : 'Total Patients';
      var key = scope.type === 'new' ? 'newPatients' : 'totalPatients';

      adapter.get('/stats/patients-by-group-date', params).then(function(response) {
        scope.loading = false;

        var options = {
          chart: {
            renderTo: element.get(0),
            type: 'spline',
            zoomType: 'x',
            height: 600
          },
          title: {
            text: title
          },
          xAxis: {
            type: 'datetime'
          },
          yAxis: {
            title: {
              text: 'Patients'
            },
            min: 0
          },
          series: [],
          plotOptions: {
            spline: {
              marker: {
                enabled: false
              }
            }
          }
        };

        var n = parseInt(scope.top);
        var isVisible;

        if (n) {
          var topGroups = getTopGroups(response.data, n);

          isVisible = function(group) {
            return _.includes(topGroups, group.id);
          };
        } else {
          isVisible = function() {
            return true;
          };
        }

        var data = _.sortBy(response.data, 'group.name');

        _.forEach(data, function(group) {
          var series = {
            name: group.group.name,
            data: [],
            visible: isVisible(group.group)
          };

          options.series.push(series);

          _.forEach(group.counts, function(count) {
            series.data.push([Date.parse(count.date), count[key]]);
          });
        });

        new Highcharts.Chart(options);
      });
    }
  };
}

patientsByGroupDateGraph.$inject = ['adapter'];

export default patientsByGroupDateGraph;

@@ -55,16 +55,67 @@
 arts';%0A%0A
+/** Get the top n groups by number of patients. */%0A
 function
@@ -172,20 +172,21 @@
 a)%0A    .
-s
 or
-t
+der
 By(%5Bfunc
@@ -345,16 +345,33 @@
 p.name'%5D
+, %5B'desc', 'asc'%5D
 )%0A    .t

Fix sort order