Вход Регистрация
Файл: src/public/plugins/metrics-graphics/common/x_axis.js
Строк: 598
<?php
function x_rug (args) {
  
'use strict';
  
args.rug_buffer_size = args.chart_type === 'point'
    
? args.buffer / 2
    
: args.buffer;
  var 
rug = mg_make_rug(args, 'mg-x-rug');
  
rug.attr('x1', args.scalefns.xf)
    .
attr('x2', args.scalefns.xf)
    .
attr('y1', args.height - args.bottom - args.rug_buffer_size)
    .
attr('y2', args.height - args.bottom);
  
mg_add_color_accessor_to_rug(rug, args, 'mg-x-rug-mono');
}

MG.x_rug = x_rug;

function 
mg_add_processed_object (args) {
  if (!
args.processed) {
    
args.processed = {};
  }
}

// function mg_define_x_scale (args) {
//   console.log('THIS IS OBSOLETE NOW')
//   mg_add_scale_function(args, 'xf', 'X', args.x_accessor);
//   mg_find_min_max_x(args);

//   var time_scale = (args.utc_time)
//     ? d3.time.scale.utc()
//     : d3.time.scale();

//   args.scales.X = (args.time_series)
//     ? time_scale
//     : (args.x_scale_type === 'log')
//         ? d3.scale.log()
//         : d3.scale.linear();

//   args.scales.X
//     .domain([args.processed.min_x, args.processed.max_x])
//     .range([mg_get_plot_left(args), mg_get_plot_right(args) - args.additional_buffer]);

//   args.scales.X.clamp(args.x_scale_type === 'log');
// }

function x_axis (args) {
  
'use strict';

  var 
svg = mg_get_svg_child_of(args.target);
  
mg_add_processed_object(args);
  
//mg_define_x_scale(args);
  
mg_select_xax_format(args);
  if (
args.chart_type === 'point') {
    
//mg_point_add_color_scale(args);
    //mg_point_add_size_scale(args);
  
}
  
mg_selectAll_and_remove(svg, '.mg-x-axis');

  if (!
args.x_axis) { return this; }
  var 
g = mg_add_g(svg, 'mg-x-axis');


  
mg_add_x_ticks(g, args);
  
mg_add_x_tick_labels(g, args);
  if (
args.x_label) { mg_add_x_label(g, args); }
  if (
args.x_rug) { x_rug(args); }

  return 
this;
}

MG.x_axis = x_axis;

function 
x_axis_categorical (args) {
  var 
svg = mg_get_svg_child_of(args.target);
  var 
additional_buffer = 0;
  if (
args.chart_type === 'bar') { additional_buffer = args.buffer + 5; }

  
mg_add_categorical_scale(args, 'X', args.categorical_variables.reverse(), args.left, mg_get_plot_right(args) - additional_buffer);
  
mg_add_scale_function(args, 'xf', 'X', 'value')//args.x_accessor);
  
mg_selectAll_and_remove(svg, '.mg-x-axis');

  var 
g = mg_add_g(svg, 'mg-x-axis');

  if (!
args.x_axis) { return this; }

  
mg_add_x_axis_categorical_labels(g, args, additional_buffer);
  return 
this;
}

function 
mg_add_x_axis_categorical_labels (g, args, additional_buffer) {
  var 
labels = g.selectAll('text').data(args.categorical_variables).enter().append('svg:text');
  
labels.attr('x', function (d) {
    return 
args.scales.X(d) + args.scales.X.rangeBand() / 2
    
+ (args.buffer) * args.bar_outer_padding_percentage + (additional_buffer / 2);
  })
    .
attr('y', mg_get_plot_bottom(args))
    .
attr('dy', '.35em')
    .
attr('text-anchor', 'middle')
    .
text(String);

  if (
args.truncate_x_labels) {
    
labels.each(function (d, idx) {
      var 
elem = this,
        
width = args.scales.X.rangeBand();
      
truncate_text(elem, d, width);
    });
  }
  
mg_rotate_labels(labels, args.rotate_x_labels);
}

MG.x_axis_categorical = x_axis_categorical;

function 
mg_point_add_color_scale (args) {
  var 
color_domain, color_range;

  if (
args.color_accessor !== null) {
    
color_domain = mg_get_color_domain(args);
    
color_range = mg_get_color_range(args);

    if (
args.color_type === 'number') {
      
args.scales.color = d3.scale.linear()
        .
domain(color_domain)
        .
range(color_range)
        .
clamp(true);
    } else {
      
args.scales.color = args.color_range !== null
        
? d3.scale.ordinal().range(color_range)
        : (
color_domain.length > 10
          
? d3.scale.category20() : d3.scale.category10());

      
args.scales.color.domain(color_domain);
    }
    
mg_add_scale_function(args, 'color', 'color', args.color_accessor);
  }
}

function 
mg_get_color_domain (args) {
  var 
color_domain;
  if (
args.color_domain === null) {
    if (
args.color_type === 'number') {
      
color_domain = d3.extent(args.data[0],function(d){return d[args.color_accessor];});
    }
    else if (
args.color_type === 'category') {
      
color_domain = d3.set(args.data[0]
        .
map(function (d) { return d[args.color_accessor]; }))
        .
values();

      
color_domain.sort();
    }
  } else {
    
color_domain = args.color_domain;
  }
  return 
color_domain;
}

function 
mg_get_color_range (args) {
  var 
color_range;
  if (
args.color_range === null) {
    if (
args.color_type === 'number') {
      
color_range = ['blue', 'red'];
    } else {
      
color_range = null;
    }
  } else {
    
color_range = args.color_range;
  }
  return 
color_range;
}

function 
mg_point_add_size_scale (args) {
  var 
min_size, max_size, size_domain, size_range;
  if (
args.size_accessor !== null) {
    
size_domain = mg_get_size_domain(args);
    
size_range = mg_get_size_range(args);

    
args.scales.size = d3.scale.linear()
      .
domain(size_domain)
      .
range(size_range)
      .
clamp(true);

    
mg_add_scale_function(args, 'size', 'size', args.size_accessor);
  }
}

function 
mg_get_size_domain (args) {
  return 
args.size_domain === null ?
    
d3.extent(args.data[0], function(d) { return d[args.size_accessor]; }) :
    
args.size_domain;
}

function 
mg_get_size_range (args) {
  var 
size_range;
  if (
args.size_range === null) {
    
size_range = [1, 5]; // args.size_domain;
  
} else {
    
size_range = args.size_range;
  }
  return 
size_range;
}

function 
mg_add_x_label (g, args) {
  
g.append('text')
    .
attr('class', 'label')
    .
attr('x', function () {
      return 
mg_get_plot_left(args) + (mg_get_plot_right(args) - mg_get_plot_left(args)) / 2;
    })
    .
attr('dx', args.x_label_nudge_x != null ? args.x_label_nudge_x : 0)
    .
attr('y', function(){
      var 
xAxisTextElement = d3.select(args.target)
        .
select('.mg-x-axis text').node().getBoundingClientRect();
      return 
mg_get_bottom(args) + args.xax_tick_length *(7/3) + xAxisTextElement.height * 0.8  + 10;
    })
    .
attr('dy', '.5em')
    .
attr('text-anchor', 'middle')
    .
text(function (d) {
      return 
args.x_label;
    });
}

function 
mg_default_bar_xax_format (args) {
  return function (
f) {
    if (
f < 1.0) {
      
// don't scale tiny values
      
return args.xax_units + d3.round(f, args.decimals);
    } else {
      var 
pf = d3.formatPrefix(f);
      return 
args.xax_units + pf.scale(f) + pf.symbol;
    }
  };
}

function 
mg_get_time_frame (diff) {
  
// diff should be (max_x - min_x) / 1000, in other words, the difference in seconds.
  
var time_frame;
  if (
mg_milisec_diff(diff)) {
    
time_frame = 'millis';
  } else if ( 
mg_sec_diff(diff)) {
    
time_frame = 'seconds';
  } else if (
mg_day_diff(diff)) {
    
time_frame = 'less-than-a-day';
  } else if (
mg_four_days(diff)) {
    
time_frame = 'four-days';
  } else if (
mg_many_days(diff)) { /// a handful of months?
    
time_frame = 'many-days';
  } else if (
mg_many_months(diff)) {
    
time_frame = 'many-months';
  } else if (
mg_years(diff)) {
    
time_frame = 'years';
  }else {
    
time_frame = 'default';
  }
  return 
time_frame;
}

function 
mg_milisec_diff       (diff) { return diff < 10; }
function 
mg_sec_diff           (diff) { return diff < 60; }
function 
mg_day_diff           (diff) { return diff / (60 * 60) <= 24; }
function 
mg_four_days          (diff) { return diff / (60 * 60) <= 24 * 4; }
function 
mg_many_days          (diff) { return diff / (60 * 60 * 24) <= 93; }
function 
mg_many_months        (diff) { return diff / (60 * 60 * 24) < 365 * 2; }
function 
mg_years              (diff) { return diff / (60 * 60 * 24) >= 365 * 2; }

function 
mg_get_time_format (utc, diff) {
  var 
main_time_format;
         if ( 
mg_milisec_diff(diff) ) {
    
main_time_format = MG.time_format(utc, '%M:%S.%L');
  } else if ( 
mg_sec_diff(diff) ) {
    
main_time_format = MG.time_format(utc, '%M:%S');

  } else if ( 
mg_day_diff(diff) ) {
    
main_time_format = MG.time_format(utc, '%H:%M');

  } else if ( 
mg_four_days(diff) ) {
    
main_time_format = MG.time_format(utc, '%H:%M');

  } else if ( 
mg_many_days(diff) ) {
    
main_time_format = MG.time_format(utc, '%b %d');

  } else if ( 
mg_many_months(diff) ) {
    
main_time_format = MG.time_format(utc, '%b');
  } else {
    
main_time_format = MG.time_format(utc, '%Y');

  }
  return 
main_time_format;
}

function 
mg_process_time_format (args) {
  var 
diff;
  var 
main_time_format;
  var 
time_frame;

  if (
args.time_series) {
    
diff = (args.processed.max_x - args.processed.min_x) / 1000;
    
time_frame = mg_get_time_frame(diff);
    
main_time_format = mg_get_time_format(args.utc_time, diff);
  }

  
args.processed.main_x_time_format = main_time_format;
  
args.processed.x_time_frame = time_frame;
}

function 
mg_default_xax_format (args) {
  if (
args.xax_format) {
    return 
args.xax_format;
  }
  var 
data = args.processed.original_data || args.data;
  var 
test_point = mg_flatten_array(data)[0][args.processed.original_x_accessor || args.x_accessor];
  return function (
d) {
    
mg_process_time_format(args);
    var 
pf = d3.formatPrefix(d);
    if (
test_point instanceof Date) {
      return 
args.processed.main_x_time_format(new Date(d));
    } else if (
typeof test_point === 'number') {
      if (
d < 1.0) {
        
// don't scale tiny values
        
return args.xax_units + d3.round(d, args.decimals);
      } else {
        
pf = d3.formatPrefix(d);
        return 
args.xax_units + pf.scale(d) + pf.symbol;
      }
    } else {
      return 
d;
    }
  };
}

function 
mg_add_x_ticks (g, args) {
  
mg_process_scale_ticks(args, 'x');
  
mg_add_x_axis_rim(args, g);
  
mg_add_x_axis_tick_lines(args, g);
}

function 
mg_add_x_axis_rim (args, g) {
  var 
tick_length = args.processed.x_ticks.length;
  var 
last_i = args.scales.X.ticks(args.xax_count).length - 1;

  if (!
args.x_extended_ticks) {
    
g.append('line')
      .
attr('x1', function () {
        if (
args.xax_count === 0) {
          return 
mg_get_plot_left(args);
        } else if (
args.axes_not_compact && args.chart_type !== 'bar') {
          return 
args.left;
        } else {
          return (
args.scales.X(args.scales.X.ticks(args.xax_count)[0])).toFixed(2);
        }
      })
      .
attr('x2', function () {
        if (
args.xax_count === 0 || (args.axes_not_compact && args.chart_type !== 'bar')) {
          return 
mg_get_plot_right(args);
        } else {
          return 
args.scales.X(args.scales.X.ticks(args.xax_count)[last_i]).toFixed(2);
        }
      })
      .
attr('y1', args.height - args.bottom)
      .
attr('y2', args.height - args.bottom);
  }
}

function 
mg_add_x_axis_tick_lines (args, g) {
  
g.selectAll('.mg-xax-ticks')
    .
data(args.processed.x_ticks).enter()
    .
append('line')
    .
attr('x1', function (d) { return args.scales.X(d).toFixed(2); })
    .
attr('x2', function (d) { return args.scales.X(d).toFixed(2); })
    .
attr('y1', args.height - args.bottom)
    .
attr('y2', function () {
      return (
args.x_extended_ticks)
        ? 
args.top
        
: args.height - args.bottom + args.xax_tick_length;
    })
    .
attr('class', function () {
      if (
args.x_extended_ticks) {
        return 
'mg-extended-x-ticks';
      }
    })
    .
classed('mg-xax-ticks', true);
}

function 
mg_add_x_tick_labels (g, args) {
  
mg_add_primary_x_axis_label(args, g);
  
mg_add_secondary_x_axis_label(args, g);

}

function 
mg_add_primary_x_axis_label (args, g) {
  var 
labels = g.selectAll('.mg-xax-labels')
    .
data(args.processed.x_ticks).enter()
    .
append('text')
    .
attr('x', function (d) { return args.scales.X(d).toFixed(2); })
    .
attr('y', (args.height - args.bottom + args.xax_tick_length * 7 / 3).toFixed(2))
    .
attr('dy', '.50em')
    .
attr('text-anchor', 'middle');

  if (
args.time_series && args.european_clock) {
    
labels.append('tspan').classed('mg-european-hours', true).text(function (_d, i) {
      var 
d = new Date(_d);
      if (
i === 0) return d3.time.format('%H')(d);
      else return 
'';
    });
    
labels.append('tspan').classed('mg-european-minutes-seconds', true).text(function (_d, i) {
      var 
d = new Date(_d);
      return 
':' + args.processed.xax_format(d);
    });
  } else {
    
labels.text(function (d) {
      return 
args.xax_units + args.processed.xax_format(d);
    });
  }
  
// CHECK TO SEE IF OVERLAP for labels. If so,
  // remove half of them. This is a dirty hack.
  // We will need to figure out a more principled way of doing this.
  
if (mg_elements_are_overlapping(labels)) {
    
labels.filter(function(d,i) {
      return (
i+1) % 2 === 0;
    }).
remove();

    var 
svg = mg_get_svg_child_of(args.target);
    
svg.selectAll('.mg-xax-ticks').filter(function(d,i){ return (i+1) % 2 === 0; })
      .
remove();
  }
}

function 
mg_add_secondary_x_axis_label (args, g) {
  if (
args.time_series && (args.show_years || args.show_secondary_x_label)) {
    var 
tf = mg_get_yformat_and_secondary_time_function(args);
    
mg_add_secondary_x_axis_elements(args, g, tf.timeframe, tf.yformat, tf.secondary);
  }
}

function 
mg_get_yformat_and_secondary_time_function (args) {
  var 
tf = {};
  
tf.timeframe = args.processed.x_time_frame;
  switch (
tf.timeframe) {
    case 
'millis':
    case 
'seconds':
      
tf.secondary = d3.time.days;
      if (
args.european_clock) tf.yformat = MG.time_format(args.utc_time, '%b %d');
      else 
tf.yformat = MG.time_format(args.utc_time, '%I %p');
      break;
    case 
'less-than-a-day':
      
tf.secondary = d3.time.days;
      
tf.yformat = MG.time_format(args.utc_time, '%b %d');
      break;
    case 
'four-days':
      
tf.secondary = d3.time.days;
      
tf.yformat = MG.time_format(args.utc_time, '%b %d');
      break;
    case 
'many-days':
      
tf.secondary = d3.time.years;
      
tf.yformat = MG.time_format(args.utc_time, '%Y');
      break;
    case 
'many-months':
      
tf.secondary = d3.time.years;
      
tf.yformat = MG.time_format(args.utc_time, '%Y');
      break;
    default:
      
tf.secondary = d3.time.years;
      
tf.yformat = MG.time_format(args.utc_time, '%Y');
  }
  return 
tf;
}

function 
mg_add_secondary_x_axis_elements (args, g, time_frame, yformat, secondary_function) {
  var 
years = secondary_function(args.processed.min_x, args.processed.max_x);
  if (
years.length === 0) {
    var 
first_tick = args.scales.X.ticks(args.xax_count)[0];
    
years = [first_tick];
  }

  var 
yg = mg_add_g(g, 'mg-year-marker');
  if (
time_frame === 'default' && args.show_year_markers) {
    
mg_add_year_marker_line(args, yg, years, yformat);
  }
  if (
time_frame != 'years') mg_add_year_marker_text(args, yg, years, yformat);
}

function 
mg_add_year_marker_line (args, g, years, yformat) {
  
g.selectAll('.mg-year-marker')
    .
data(years).enter()
    .
append('line')
    .
attr('x1', function (d) { return args.scales.X(d).toFixed(2); })
    .
attr('x2', function (d) { return args.scales.X(d).toFixed(2); })
    .
attr('y1', mg_get_top(args))
    .
attr('y2', mg_get_bottom(args));
}

function 
mg_add_year_marker_text (args, g, years, yformat) {
  
g.selectAll('.mg-year-marker')
    .
data(years).enter()
    .
append('text')
    .
attr('x', function (d, i) {
      return 
args.scales.X(d).toFixed(2);
    })
    .
attr('y', function () {
      var 
xAxisTextElement = d3.select(args.target)
        .
select('.mg-x-axis text').node().getBoundingClientRect();
      return (
mg_get_bottom(args) + args.xax_tick_length * 7 / 3) + (xAxisTextElement.height * 0.8);
    })
    .
attr('dy', '.50em')
    .
attr('text-anchor', 'middle')
    .
text(function (d) {
      return 
yformat(new Date(d));
    });
}

function 
mg_min_max_x_for_nonbars (mx, args, data) {
  var 
extent_x = d3.extent(data, function (d) { return d[args.x_accessor]; });
  
mx.min = extent_x[0];
  
mx.max = extent_x[1];
}

function 
mg_min_max_x_for_bars (mx, args, data) {
  
mx.min = d3.min(data, function (d) {
    var 
trio = [
      
d[args.x_accessor],
      (
d[args.baseline_accessor]) ? d[args.baseline_accessor] : 0,
      (
d[args.predictor_accessor]) ? d[args.predictor_accessor] : 0
    
];
    return 
Math.min.apply(null, trio);
  });

  if (
mx.min > 0) mx.min = 0;

  
mx.max = d3.max(data, function (d) {
    var 
trio = [
      
d[args.x_accessor],
      (
d[args.baseline_accessor]) ? d[args.baseline_accessor] : 0,
      (
d[args.predictor_accessor]) ? d[args.predictor_accessor] : 0
    
];
    return 
Math.max.apply(null, trio);
  });
  return 
mx;
}

function 
mg_min_max_x_for_dates (mx) {
  var 
yesterday = MG.clone(mx.min).setDate(mx.min.getDate() - 1);
  var 
tomorrow = MG.clone(mx.min).setDate(mx.min.getDate() + 1);
  
mx.min = yesterday;
  
mx.max = tomorrow;
}

function 
mg_min_max_x_for_numbers (mx) {
  
// this seems silly. I envision a problem with something this simplistic.
  
mx.min = mx.min - 1;
  
mx.max = mx.max + 1;
}

function 
mg_min_max_x_for_strings (mx) {
  
// ok. Not sure who wrote this, but this seems also pretty silly. We
  // should not be allowing strings here to be coerced into numbers. Veto.
  
mx.min = Number(mx.min) - 1;
  
mx.max = Number(mx.max) + 1;
}

function 
mg_force_xax_count_to_be_two (args) {
  
args.xax_count = 2;
}

function 
mg_sort_through_data_type_and_set_x_min_max_accordingly (mx, args, data) {
  if (
args.chart_type === 'line' || args.chart_type === 'point' || args.chart_type === 'histogram') {
    
mg_min_max_x_for_nonbars(mx, args, data);

  } else if (
args.chart_type === 'bar') {
    
mg_min_max_x_for_bars(mx, args, data);
  }
  
// if data set is of length 1, expand the range so that we can build the x-axis
  
if (mx.min === mx.max && !(args.min_x && args.max_x)) {
    if (
mx.min instanceof Date) {
      
mg_min_max_x_for_dates(mx);
    } else if (
typeof min_x === 'number') {
      
mg_min_max_x_for_numbers(mx);
    } else if (
typeof min_x === 'string') {
      
mg_min_max_x_for_strings(mx);
    }
    
// force xax_count to be 2
    
mg_force_xax_count_to_be_two(args);
  }
}

function 
mg_find_min_max_x_from_data (args) {
  var 
all_data = mg_flatten_array(args.data);

  if (
args.x_scale_type === 'log') {
    
all_data = all_data.filter(function (d) {
      return 
d[args.x_accessor] > 0;
    });
  }

  var 
mx = {};
  
mg_sort_through_data_type_and_set_x_min_max_accordingly(mx, args, all_data);

  
mx.min = args.min_x || mx.min;
  
mx.max = args.max_x || mx.max;

  
args.x_axis_negative = false;
  
args.processed.min_x = mx.min;
  
args.processed.max_x = mx.max;
}

function 
mg_find_min_max_x (args) {
  
mg_find_min_max_x_from_data(args);
  
mg_select_xax_format(args);
  
MG.call_hook('x_axis.process_min_max', args, args.processed.min_x, args.processed.max_x);
  if (!
args.time_series) {
    if (
args.processed.min_x < 0) {
      
args.processed.min_x = args.processed.min_x - (args.processed.max_x * (args.inflator - 1));
      
args.x_axis_negative = true;
    }
  }

  if (
args.chart_type === 'bar') {
    
args.additional_buffer = args.buffer * 5;
  } else {
    
args.additional_buffer = 0;
  }
}

function 
mg_select_xax_format (args) {
  var 
c = args.chart_type;

  if (!
args.processed.xax_format) {
    if (
args.xax_format) {
      
args.processed.xax_format = args.xax_format;
    } else {
      if (
c === 'line' || c === 'point' || c === 'histogram') {
        
args.processed.xax_format = mg_default_xax_format(args);
      } else if (
c === 'bar') {
        
args.processed.xax_format = mg_default_bar_xax_format(args);
      }
    }
  }
}
?>
Онлайн: 2
Реклама