(function() {
  'use strict';

  var app = angular.module('bydimension-service', [
    'lodash'
  ]);

  /**
   * A proxy service to the ByDimension API.
   */
  app.factory('byDimensionProxy', ['_', '$http', function(_, $http) {

    this.data = [];

    this.config = {
      primary_dimension: 'service',
      secondary_dimension: 'host',
      use_logarithmic_planet_size: true,
      percentiles: [50, 90, 99, 99.5]
    };

    this.timerange = {
      from: "now-1d",
      to: "now"
    };

    this.metrics = [
      "volume",
      "rt_max",
      "rt_avg",
      "rt_percentiles",
      "secondary_count",
      "errors_rate"
    ];

    var service = this;

    this.load = function() {
      var request = {
        timerange: service.timerange,
        metrics: service.metrics,
        config: service.config
      };

      return $http.post('/api/bydimension', request)
        .success(function(data) {
          service.data = data.primary;
          service.afterLoad(service.data);
        })
        .error(function(data, status, headers, config) {
          console.log("Error: ", status);
        });
    };

    // process data after it's loaded
    this.afterLoad = function(data) {
      _.each(data, function(d) {
        // make sure we have a values array
        if (_.isUndefined(d.values)) {
          d.values = [];
        }
      });

      service.compute_relative_sizes(data,
        service.config.use_logarithmic_planet_size);
    };

    // compute the size of the relative planets
    this.compute_relative_sizes = function(data, useLogarithmicPlanetSize) {
      if (_.isEmpty(data)) {
        return;
      }

      var max_size = _.max(data, function(d) { return d.metrics.volume; })
        .metrics.volume;

      _.each(data, function(d) {
        if (useLogarithmicPlanetSize) {
          // logarithmic scale
          d.size_rel = Math.log(d.metrics.volume) / Math.log(max_size);
        } else {
          d.size_rel = d.metrics.volume / max_size;
        }
      });
    };


    return {
      load: function() {
        return service.load();
      },
      get: function(sort_key) {
        switch (sort_key) {
          case 'errors':
            return service.data.sort(function(a, b) {
              if (Math.abs(a.metrics.errors_rate - b.metrics.errors_rate) < 1e-6) {
                return b.metrics.volume - a.metrics.volume;
              }
              return b.metrics.errors_rate - a.metrics.errors_rate;
            });
          case 'volume':
            return _.sortBy(service.data, function(d) { return -d.metrics.volume; });
          case 'alpha':
            return _.sortBy(service.data, 'name');
          default:
            return service.data;
        }
      },
      recomputePlanetSizes: function(useLogScale) {
        service.compute_relative_sizes(service.data, useLogScale);
      }
    };
  }]);
})();

@@ -414,16 +414,44 @@
 9, 99.5%5D
+,%0A      histogram_points: 50
 %0A    %7D;%0A
@@ -492,17 +492,17 @@
 : %22now-1
-d
+h
 %22,%0A     
@@ -662,24 +662,73 @@
 te%22%0A    %5D;%0A%0A
+    this.hist_metrics = %5B%0A      %22volume%22%0A    %5D;%0A%0A
     var serv
@@ -863,16 +863,65 @@
 etrics,%0A
+        histogram_metrics: service.hist_metrics,%0A
         
@@ -1376,40 +1376,35 @@
  // 
-make sure we have a va
+values come from the vo
 lu
+m
 e
-s array
 %0A   
@@ -1420,65 +1420,290 @@
 _.is
-Undefined(d.values)) %7B%0A          d.values = %5B%5D;%0A        %7D
+Object(d.hist_metrics) && _.isArray(d.hist_metrics.volume)) %7B%0A          d.values = d.hist_metrics.volume;%0A        %7D else %7B%0A          d.values = %5B%5D;%0A        %7D%0A%0A        // parse timestamps%0A        _.each(d.values, function(v) %7B%0A          v.ts = new Date(Date.parse(v.ts));%0A        %7D);
 %0A   

use the volume histogram metric for the graph