Вход Регистрация
Файл: src/public/plugins/metrics-graphics/misc/process.js
Строк: 339
<?php
function mg_process_scale_ticks (argsaxis) {
  var 
accessor;
  var 
scale_ticks;
  var 
max;

  if (
axis === 'x') {
    
accessor args.x_accessor;
    
scale_ticks args.scales.X.ticks(args.xax_count);
    
max args.processed.max_x;
  } else if (
axis === 'y') {
    
accessor args.y_accessor;
    
scale_ticks args.scales.Y.ticks(args.yax_count)
    
max args.processed.max_y;
  }

  function 
log10 (val) {
    if (
val === 1000) {
      return 
3;
    }
    if (
val === 1000000) {
      return 
7;
    }
    return 
Math.log(val) / Math.LN10;
  }

  if ((
axis === 'x' && args.x_scale_type === 'log')
    || (
axis === 'y' && args.y_scale_type === 'log')
  ) {
    
// get out only whole logs
    
scale_ticks scale_ticks.filter(function (d) {
      return 
Math.abs(log10(d)) % 1e-6 || Math.abs(log10(d)) % 1e-6;
    });
  }

  
// filter out fraction ticks if our data is ints and if xmax > number of generated ticks
  
var number_of_ticks scale_ticks.length;

  
// is our data object all ints?
  
var data_is_int true;
  
args.data.forEach(function (di) {
    
d.forEach(function (di) {
      if (
d[accessor] % !== 0) {
        
data_is_int false;
        return 
false;
      }
    });
  });

  if (
data_is_int && number_of_ticks max && args.format === 'count') {
    
// remove non-integer ticks
    
scale_ticks scale_ticks.filter(function (d) {
      return 
=== 0;
    });
  }

  if (
axis === 'x') {
    
args.processed.x_ticks scale_ticks;
  } else if(
axis === 'y') {
    
args.processed.y_ticks scale_ticks;
  }
}

function 
raw_data_transformation (args) {
  
'use strict';

  
// dupe our data so we can modify it without adverse effect
  
args.data MG.clone(args.data);

  
// we need to account for a few data format cases:
  // #0 {bar1:___, bar2:___}                                    // single object (for, say, bar charts)
  // #1 [{key:__, value:__}, ...]                               // unnested obj-arrays
  // #2 [[{key:__, value:__}, ...], [{key:__, value:__}, ...]]  // nested obj-arrays
  // #3 [[4323, 2343],..]                                       // unnested 2d array
  // #4 [[[4323, 2343],..] , [[4323, 2343],..]]                 // nested 2d array
  
args.single_object    false// for bar charts.
  
args.array_of_objects false;
  
args.array_of_arrays false;
  
args.nested_array_of_arrays false;
  
args.nested_array_of_objects false;

  
// is the data object a nested array?

  
if (is_array_of_arrays(args.data)) {
    
args.nested_array_of_objects args.data.map(function(d) {
      return 
is_array_of_objects_or_empty(d);
    });                               
// Case #2
    
args.nested_array_of_arrays args.data.map(function(d) {
      return 
is_array_of_arrays(d);
    });                               
// Case #4
  
} else {
    
args.array_of_objects is_array_of_objects(args.data);     // Case #1
    
args.array_of_arrays is_array_of_arrays(args.data);     // Case #3
  
}

  if (
args.chart_type === 'line') {
    if (
args.array_of_objects || args.array_of_arrays) {
      
args.data = [args.data];
    }
  } else {
    if (!(
args.data[0] instanceof Array)) {
      
args.data = [args.data];
    }
  }
  
// if the y_accessor is an array, break it up and store the result in args.data
  
mg_process_multiple_x_accessors(args);
  
mg_process_multiple_y_accessors(args);

  
// if user supplies keyword in args.color, change to arg.colors.
  // this is so that the API remains fairly sensible and legible.
  
if (args.color !== undefined) {
    
args.colors args.color;
  }

  
// if user has supplied args.colors, and that value is a string, turn it into an array.
  
if (args.colors !== null && typeof args.colors === 'string') {
    
args.colors = [args.colors];
  }

  
// sort x-axis data
  
if (args.chart_type === 'line' && args.x_sort === true) {
    for (var 
0args.data.lengthi++) {
      
args.data[i].sort(function(ab) {
        return 
a[args.x_accessor] - b[args.x_accessor];
      });
    }
  }

  return 
this;
}

function 
mg_process_multiple_accessors(argswhich_accessor) {
  
// turns an array of accessors into ...
  
if (args[which_accessor] instanceof Array) {
      
args.data args.data.map(function(_d) {
        return 
args[which_accessor].map(function(ya) {
          return 
_d.map(function(di) {
            
di MG.clone(di);

            if (
di[ya] === undefined) {
              return 
undefined;
            }

            
di['multiline_' which_accessor] = di[ya];
            return 
di;
          }).
filter(function(di) {
            return 
di !== undefined;
          });
        });
      })[
0];
      
args[which_accessor] = 'multiline_' which_accessor;
    }
}

function 
mg_process_multiple_x_accessors(args) { mg_process_multiple_accessors(args'x_accessor'); }
function 
mg_process_multiple_y_accessors(args) { mg_process_multiple_accessors(args'y_accessor'); }

MG.raw_data_transformation raw_data_transformation;

function 
process_line(args) {
  
'use strict';

  var 
time_frame;

  
// do we have a time-series?
  
var is_time_series d3.sum(args.data.map(function(series) {
    return 
series.length && series[0][args.x_accessor] instanceof Date;
  })) > 
0;

  
// force linear interpolation when missing_is_hidden is enabled
  
if (args.missing_is_hidden) {
    
args.interpolate 'linear';
  }

  
// are we replacing missing y values with zeros?
  
if ((args.missing_is_zero || args.missing_is_hidden)
      && 
args.chart_type === 'line'
      
&& is_time_series
    
) {
    for (var 
0args.data.lengthi++) {
      
// we need to have a dataset of length > 2, so if it's less than that, skip
      
if (args.data[i].length <= 1) {
        continue;
      }

      var 
first args.data[i][0];
      var 
last args.data[i][args.data[i].length-1];

      
// initialize our new array for storing the processed data
      
var processed_data = [];

      
// we'll be starting from the day after our first date
      
var start_date MG.clone(first[args.x_accessor]).setDate(first[args.x_accessor].getDate() + 1);

      
// if we've set a max_x, add data points up to there
      
var from = (args.min_x) ? args.min_x start_date;
      var 
upto = (args.max_x) ? args.max_x last[args.x_accessor];

      
time_frame mg_get_time_frame((upto-from)/1000);

      if (
time_frame == 'default' && args.missing_is_hidden_accessor === null) {
        for (var 
= new Date(from); <= uptod.setDate(d.getDate() + 1)) {
          var 
= {};
          
d.setHours(0000);

          
// add the first date item, we'll be starting from the day after our first date
          
if (Date.parse(d) === Date.parse(new Date(start_date))) {
            
processed_data.push(MG.clone(args.data[i][0]));
          }

          
// check to see if we already have this date in our data object
          
var existing_o null;
          
args.data[i].forEach(function(vali) {
            if (
Date.parse(val[args.x_accessor]) === Date.parse(new Date(d))) {
              
existing_o val;

              return 
false;
            }
          });

          
// if we don't have this date in our data object, add it and set it to zero
          
if (!existing_o) {
            
o[args.x_accessor] = new Date(d);
            
o[args.y_accessor] = 0;
            
o['_missing'] = true//we want to distinguish between zero-value and missing observations
            
processed_data.push(o);
          }

          
// if the data point has, say, a 'missing' attribute set or if its
          // y-value is null identify it internally as missing
          
else if (existing_o[args.missing_is_hidden_accessor]
              || 
existing_o[args.y_accessor] === null
            
) {
            
existing_o['_missing'] = true;
            
processed_data.push(existing_o);
          }

          
//otherwise, use the existing object for that date
          
else {
            
processed_data.push(existing_o);
          }
        }
      } else {
        for (var 
0args.data[i].length+= 1) {
          var 
obj MG.clone(args.data[i][j]);
          
obj['_missing'] = args.data[i][j][args.missing_is_hidden_accessor];
          
processed_data.push(obj);
        }
      }

      
// update our date object
      
args.data[i] = processed_data;
    }
  }

  return 
this;
}

MG.process_line process_line;

function 
process_histogram(args) {
  
'use strict';

  
// if args.binned == false, then we need to bin the data appropriately.
  // if args.binned == true, then we need to make sure to compute the relevant computed data.
  // the outcome of either of these should be something in args.computed_data.
  // the histogram plotting function will be looking there for the data to plot.

  // we need to compute an array of objects.
  // each object has an x, y, and dx.

  // histogram data is always single dimension
  
var our_data args.data[0];

  var 
extracted_data;
  if (
args.binned === false) {
    
// use d3's built-in layout.histogram functionality to compute what you need.

    
if (typeof(our_data[0]) === 'object') {
      
// we are dealing with an array of objects. Extract the data value of interest.
      
extracted_data our_data
        
.map(function(d) {
          return 
d[args.x_accessor];
        });
    } else if (
typeof(our_data[0]) === 'number') {
      
// we are dealing with a simple array of numbers. No extraction needed.
      
extracted_data our_data;
    } else {
      
console.log('TypeError: expected an array of numbers, found ' typeof(our_data[0]));
      return;
    }

    var 
hist d3.layout.histogram();
    if (
args.bins) {
      
hist hist.bins(args.bins);
    }

    
args.processed_data hist(extracted_data)
      .
map(function(d) {
        
// extract only the data we need per data point.
        
return {'x'd.x'y'd.y'dx'd.dx};
      });
  } else {
    
// here, we just need to reconstruct the array of objects
    // take the x accessor and y accessor.
    // pull the data as x and y. y is count.

    
args.processed_data our_data.map(function(d) {
      return {
'x'd[args.x_accessor], 'y'd[args.y_accessor]};
    });

    var 
this_pt;
    var 
next_pt;

    
// we still need to compute the dx component for each data point
    
for (var i=0args.processed_data.lengthi++) {
      
this_pt args.processed_data[i];
      if (
=== args.processed_data.length 1) {
        
this_pt.dx args.processed_data[i-1].dx;
      } else {
        
next_pt args.processed_data[i+1];
        
this_pt.dx next_pt.this_pt.x;
      }
    }
  }

  
// capture the original data and accessors before replacing args.data
  
if (!args.processed) {
    
args.processed = {};
  }
  
args.processed.original_data args.data;
  
args.processed.original_x_accessor args.x_accessor;
  
args.processed.original_y_accessor args.y_accessor;

  
args.data = [args.processed_data];
  
args.x_accessor args.processed_x_accessor;
  
args.y_accessor args.processed_y_accessor;

  return 
this;
}

MG.process_histogram process_histogram;

// for use with bar charts, etc.
function process_categorical_variables(args) {
  
'use strict';

  var 
extracted_dataprocessed_data={}, pd=[];
  
//var our_data = args.data[0];
  
var label_accessor args.bar_orientation === 'vertical' args.x_accessor args.y_accessor;
  var 
data_accessor =  args.bar_orientation === 'vertical' args.y_accessor args.x_accessor;

  if (
args.binned === false) {
    
args.categorical_variables = [];
    if (
typeof(our_data[0]) === 'object') {
      
// we are dealing with an array of objects, extract the data value of interest
      
extracted_data our_data
        
.map(function(d) {
          return 
d[label_accessor];
        });
    } else {
      
extracted_data our_data;
    }

    var 
this_dp;

    for (var 
0extracted_data.lengthi++) {
      
this_dp=extracted_data[i];
      if (
args.categorical_variables.indexOf(this_dp) === -1args.categorical_variables.push(this_dp);
      if (!
processed_data.hasOwnProperty(this_dp)) processed_data[this_dp] = 0;

      
processed_data[this_dp] += 1;
    }

    
processed_data Object.keys(processed_data).map(function(d) {
      var 
obj = {};
      
obj[data_accessor] = processed_data[d];
      
obj[label_accessor] = d;
      return 
obj;
    });
  } else {

    
processed_data args.data[0];
    
args.categorical_variables d3.set(processed_data.map(function(d) {
      return 
d[label_accessor];
    })).
values();

    
args.categorical_variables.reverse();
  }

  
args.data = [processed_data];
  return 
this;
}

MG.process_categorical_variables process_categorical_variables;

function 
process_point(args) {
  
'use strict';

  var 
data args.data[0];
  var 
data.map(function(d) { return d[args.x_accessor]; });
  var 
data.map(function(d) { return d[args.y_accessor]; });

  if (
args.least_squares) {
    
args.ls_line least_squares(x,y);
  }

  return 
this;
}

MG.process_point process_point;
?>
Онлайн: 2
Реклама