Graph.prototype.rebucket = function()

in kitsune/sumo/static/sumo/js/rickshaw_utils.js [96:212]


  Graph.prototype.rebucket = function () {
    var buckets, bucketed, i, d, axisGroup, axis, series, name, date, chopLimit, now;
    buckets = {};
    bucketed = [];

    // Bucket data
    if (this.data.bucketSize) {
      for (i = 0; i < this.data.datums.length; i += 1) {
        // make a copy.
        d = $.extend({}, this.data.datums[i]);
        date = new Date(d.date * 1000);

        // NB: These are resilient to borders in months and years because
        // JS's Date has the neat property that
        //   new Date(2013, 4, -1) === new Date(2013, 3, 29)
        //   new Date(2013, 0, -60) === new Date(2012, 10, 1)
        // This might be the only nice thing about JS's Date.
        switch (this.data.bucketSize) {
          case 'day':
          // Get midnight of today (ie, the boundary between today and yesterday)
            d.date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
            break;
          case 'week':
          // Get the most recent Sunday.
            d.date = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());
            break;
          case 'month':
          // Get the first of this month.
            d.date = new Date(date.getFullYear(), date.getMonth(), 1);
            break;
          default:
            throw 'Unknown bucket size ' + this.data.bucketSize;
        }
        d.date = d.date / 1000;

        if (buckets[d.date] === undefined) {
          buckets[d.date] = [d];
        } else {
          buckets[d.date].push(d);
        }
      }

      bucketed = $.map(buckets, function (dList) {
        var out, key;
        out = $.extend({}, dList[0]);

        for (key in out) {
          if (out.hasOwnProperty(key) && key !== 'date') {
            for (i = 1; i < dList.length; i += 1) {
              out[key] += dList[i][key];
            }
          }
        }

        return out;
      });

    } else {
      bucketed = this.data.datums.slice();
    }

    /* Data points that are too near the present represent a UX problem.
     * The data in them is not representative of a full time period, so
     * they appear to be downward trending. `chopLimit` represents the
     * boundary of what is considered to be "too new".  Bug #876912. */
    now = new Date();
    if (this.data.bucketSize === 'week') {
      // Get most recent Sunday.
      chopLimit = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getDay());
    } else if (this.data.bucketSize === 'month') {
      // Get the first of the current month.
      chopLimit = new Date(now.getFullYear(), now.getMonth(), 1);
    } else {
      // Get midnight of today (ie, the boundary between today and yesterday)
      chopLimit = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    }
    bucketed = _filter(bucketed, function (datum) {
      return datum.date < chopLimit / 1000;
    });

    this.data.series = this.makeSeries(bucketed, this.data.seriesSpec);

    // Scale data based on axis groups
    this.axisGroups = {};
    for (i = 0; i < this.data.series.length; i += 1) {
      series = this.data.series[i];
      name = series.axisGroup;
      if (this.axisGroups[name] === undefined) {
        this.axisGroups[name] = {
          max: -Infinity
        };
      }

      // Only adjust the axis max if the series is enabled.
      if (!series.disabled) {
        this.axisGroups[name].max = Math.max(this.axisGroups[name].max, series.max);
      }
    }

    function mapHandler(point) {
      return {
        x: point.x,
        y: point.y / axisGroup.max
      };
    }

    for (i = 0; i < this.data.series.length; i += 1) {
      series = this.data.series[i];
      axisGroup = this.axisGroups[series.axisGroup];
      series.data = _map(series.data, mapHandler);
      series.scale = axisGroup.max;
      axis = this.d3.axises[series.axisGroup];
      if (axis) {
        axis.setScale(axisGroup.max);
      }
    }
  };