function(metric, records) {
  var returnValue = {message: 'no stats available', name: metric.displayName};
  if (records && records.length > 0) {
    returnValue = _.chain(records).map(function(recordStr) {
      return JSON.parse(recordStr);
    }).groupBy(function(record) {
      return record.tags[metric.groupByTag];
    }).reduce(function(reduced, groupRecords, groupKey) {
      groupRecords = _.sortBy(groupRecords, 'ts');
      var processedData = _.reduce(groupRecords, function(memo, groupRecord) {
        var value = groupRecord.fields[metric.valueField];
        memo.current = value;
        memo.numberOfRecords++;
        memo.total += value;
        memo.max = Math.max(value, memo.max);
        memo.min = Math.min(value, memo.min);
        memo.from = Math.min(groupRecord.ts, memo.from);
        memo.end = Math.max(groupRecord.ts, memo.end);
        return memo;
      }, {max: 0, min: MAX_NUMBER, current: 0, numberOfRecords: 0, total: 0, from: MAX_NUMBER, end: 0});
      reduced[groupKey] = {
        current: metric.dataFormatter(processedData.current),
        max: metric.dataFormatter(processedData.max),
        min: metric.dataFormatter(processedData.min),
        average: metric.dataFormatter(processedData.total / processedData.numberOfRecords),
        numberOfRecords: processedData.numberOfRecords,
        from: new Date(processedData.from).toISOString(),
        end: new Date(processedData.end).toISOString()
      };
      return reduced;
    }, {}).value();
  }
  return returnValue;
}
function(metric, records) {
  var returnValue = {message: 'no stats available', name: metric.displayName};
  if (records && records.length > 0) {
    returnValue = _.chain(records).map(function(recordStr) {
      return JSON.parse(recordStr);
    }).groupBy(function(record) {
      return record.tags[metric.groupByTag];
    }).reduce(function(reduced, groupRecords, groupKey) {
      groupRecords = _.sortBy(groupRecords, 'ts');
      var processedData = _.reduce(groupRecords, function(memo, groupRecord) {
        var value = groupRecord.fields[metric.valueField];
        memo.current = value;
        memo.numberOfRecords++;
        memo.total += value;
        memo.max = Math.max(value, memo.max);
        memo.min = Math.min(value, memo.min);
        memo.from = Math.min(groupRecord.ts, memo.from);
        memo.end = Math.max(groupRecord.ts, memo.end);
        return memo;
      }, {max: 0, min: MAX_NUMBER, current: 0, numberOfRecords: 0, total: 0, from: MAX_NUMBER, end: 0});
      reduced[groupKey] = {
        current: metric.dataFormatter(processedData.current),
        max: metric.dataFormatter(processedData.max),
        min: metric.dataFormatter(processedData.min),
        average: metric.dataFormatter(processedData.total / processedData.numberOfRecords),
        numberOfRecords: processedData.numberOfRecords,
        from: new Date(processedData.from).toISOString(),
        end: new Date(processedData.end).toISOString()
      };
      return reduced;
    }, {}).value();
  }
  return returnValue;
}
function ( metric , records ) { var returnValue = { message : 'no stats available' , name : metric . displayName } ; if ( records && records . length > 0 ) { returnValue = _ . chain ( records ) . map ( function ( recordStr ) { return JSON . parse ( recordStr ) ; } ) . groupBy ( function ( record ) { return record . tags [ metric . groupByTag ] ; } ) . reduce ( function ( reduced , groupRecords , groupKey ) { groupRecords = _ . sortBy ( groupRecords , 'ts' ) ; var processedData = _ . reduce ( groupRecords , function ( memo , groupRecord ) { var value = groupRecord . fields [ metric . valueField ] ; memo . current = value ; memo . numberOfRecords ++ ; memo . total += value ; memo . max = Math . max ( value , memo . max ) ; memo . min = Math . min ( value , memo . min ) ; memo . from = Math . min ( groupRecord . ts , memo . from ) ; memo . end = Math . max ( groupRecord . ts , memo . end ) ; return memo ; } , { max : 0 , min : MAX_NUMBER , current : 0 , numberOfRecords : 0 , total : 0 , from : MAX_NUMBER , end : 0 } ) ; reduced [ groupKey ] = { current : metric . dataFormatter ( processedData . current ) , max : metric . dataFormatter ( processedData . max ) , min : metric . dataFormatter ( processedData . min ) , average : metric . dataFormatter ( processedData . total / processedData . numberOfRecords ) , numberOfRecords : processedData . numberOfRecords , from : new Date ( processedData . from ) . toISOString ( ) , end : new Date ( processedData . end ) . toISOString ( ) } ; return reduced ; } , { } ) . value ( ) ; } return returnValue ; }
Compute the max, min, current, average values from the records
@param {Object} metric some meta data about the metric
@param {Array} records
Compute the max min current average values from the records