html5 boiler plate
[scannr.git] / js / flotr2 / flotr2.amd.js
blob:a/js/flotr2/flotr2.amd.js -> blob:b/js/flotr2/flotr2.amd.js
  (function (root, factory) {
  if (typeof define === 'function' && define.amd) {
  // AMD. Register as an anonymous module.
  define(['bean', 'underscore'], function (bean, _) {
  // Also create a global in case some scripts
  // that are loaded still are looking for
  // a global even when an AMD loader is in use.
  return (root.Flotr = factory(bean, _));
  });
  } else {
  // Browser globals
  root.Flotr = factory(root.bean, root._);
  }
  }(this, function (bean, _) {
   
  /**
  * Flotr2 (c) 2012 Carl Sutherland
  * MIT License
  * Special thanks to:
  * Flotr: http://code.google.com/p/flotr/ (fork)
  * Flot: https://github.com/flot/flot (original fork)
  */
  (function () {
   
  var
  global = this,
  previousFlotr = this.Flotr,
  Flotr;
   
  Flotr = {
  _: _,
  bean: bean,
  isIphone: /iphone/i.test(navigator.userAgent),
  isIE: (navigator.appVersion.indexOf("MSIE") != -1 ? parseFloat(navigator.appVersion.split("MSIE")[1]) : false),
   
  /**
  * An object of the registered graph types. Use Flotr.addType(type, object)
  * to add your own type.
  */
  graphTypes: {},
   
  /**
  * The list of the registered plugins
  */
  plugins: {},
   
  /**
  * Can be used to add your own chart type.
  * @param {String} name - Type of chart, like 'pies', 'bars' etc.
  * @param {String} graphType - The object containing the basic drawing functions (draw, etc)
  */
  addType: function(name, graphType){
  Flotr.graphTypes[name] = graphType;
  Flotr.defaultOptions[name] = graphType.options || {};
  Flotr.defaultOptions.defaultType = Flotr.defaultOptions.defaultType || name;
  },
   
  /**
  * Can be used to add a plugin
  * @param {String} name - The name of the plugin
  * @param {String} plugin - The object containing the plugin's data (callbacks, options, function1, function2, ...)
  */
  addPlugin: function(name, plugin){
  Flotr.plugins[name] = plugin;
  Flotr.defaultOptions[name] = plugin.options || {};
  },
   
  /**
  * Draws the graph. This function is here for backwards compatibility with Flotr version 0.1.0alpha.
  * You could also draw graphs by directly calling Flotr.Graph(element, data, options).
  * @param {Element} el - element to insert the graph into
  * @param {Object} data - an array or object of dataseries
  * @param {Object} options - an object containing options
  * @param {Class} _GraphKlass_ - (optional) Class to pass the arguments to, defaults to Flotr.Graph
  * @return {Object} returns a new graph object and of course draws the graph.
  */
  draw: function(el, data, options, GraphKlass){
  GraphKlass = GraphKlass || Flotr.Graph;
  return new GraphKlass(el, data, options);
  },
   
  /**
  * Recursively merges two objects.
  * @param {Object} src - source object (likely the object with the least properties)
  * @param {Object} dest - destination object (optional, object with the most properties)
  * @return {Object} recursively merged Object
  * @TODO See if we can't remove this.
  */
  merge: function(src, dest){
  var i, v, result = dest || {};
   
  for (i in src) {
  v = src[i];
  if (v && typeof(v) === 'object') {
  if (v.constructor === Array) {
  result[i] = this._.clone(v);
  } else if (v.constructor !== RegExp && !this._.isElement(v)) {
  result[i] = Flotr.merge(v, (dest ? dest[i] : undefined));
  } else {
  result[i] = v;
  }
  } else {
  result[i] = v;
  }
  }
   
  return result;
  },
   
  /**
  * Recursively clones an object.
  * @param {Object} object - The object to clone
  * @return {Object} the clone
  * @TODO See if we can't remove this.
  */
  clone: function(object){
  return Flotr.merge(object, {});
  },
   
  /**
  * Function calculates the ticksize and returns it.
  * @param {Integer} noTicks - number of ticks
  * @param {Integer} min - lower bound integer value for the current axis
  * @param {Integer} max - upper bound integer value for the current axis
  * @param {Integer} decimals - number of decimals for the ticks
  * @return {Integer} returns the ticksize in pixels
  */
  getTickSize: function(noTicks, min, max, decimals){
  var delta = (max - min) / noTicks,
  magn = Flotr.getMagnitude(delta),
  tickSize = 10,
  norm = delta / magn; // Norm is between 1.0 and 10.0.
   
  if(norm < 1.5) tickSize = 1;
  else if(norm < 2.25) tickSize = 2;
  else if(norm < 3) tickSize = ((decimals === 0) ? 2 : 2.5);
  else if(norm < 7.5) tickSize = 5;
   
  return tickSize * magn;
  },
   
  /**
  * Default tick formatter.
  * @param {String, Integer} val - tick value integer
  * @param {Object} axisOpts - the axis' options
  * @return {String} formatted tick string
  */
  defaultTickFormatter: function(val, axisOpts){
  return val+'';
  },
   
  /**
  * Formats the mouse tracker values.
  * @param {Object} obj - Track value Object {x:..,y:..}
  * @return {String} Formatted track string
  */
  defaultTrackFormatter: function(obj){
  return '('+obj.x+', '+obj.y+')';
  },
   
  /**
  * Utility function to convert file size values in bytes to kB, MB, ...
  * @param value {Number} - The value to convert
  * @param precision {Number} - The number of digits after the comma (default: 2)
  * @param base {Number} - The base (default: 1000)
  */
  engineeringNotation: function(value, precision, base){
  var sizes = ['Y','Z','E','P','T','G','M','k',''],
  fractionSizes = ['y','z','a','f','p','n','µ','m',''],
  total = sizes.length;
   
  base = base || 1000;
  precision = Math.pow(10, precision || 2);
   
  if (value === 0) return 0;
   
  if (value > 1) {
  while (total-- && (value >= base)) value /= base;
  }
  else {
  sizes = fractionSizes;
  total = sizes.length;
  while (total-- && (value < 1)) value *= base;
  }
   
  return (Math.round(value * precision) / precision) + sizes[total];
  },
   
  /**
  * Returns the magnitude of the input value.
  * @param {Integer, Float} x - integer or float value
  * @return {Integer, Float} returns the magnitude of the input value
  */
  getMagnitude: function(x){
  return Math.pow(10, Math.floor(Math.log(x) / Math.LN10));
  },
  toPixel: function(val){
  return Math.floor(val)+0.5;//((val-Math.round(val) < 0.4) ? (Math.floor(val)-0.5) : val);
  },
  toRad: function(angle){
  return -angle * (Math.PI/180);
  },
  floorInBase: function(n, base) {
  return base * Math.floor(n / base);
  },
  drawText: function(ctx, text, x, y, style) {
  if (!ctx.fillText) {
  ctx.drawText(text, x, y, style);
  return;
  }
   
  style = this._.extend({
  size: Flotr.defaultOptions.fontSize,
  color: '#000000',
  textAlign: 'left',
  textBaseline: 'bottom',
  weight: 1,
  angle: 0
  }, style);
   
  ctx.save();
  ctx.translate(x, y);
  ctx.rotate(style.angle);
  ctx.fillStyle = style.color;
  ctx.font = (style.weight > 1 ? "bold " : "") + (style.size*1.3) + "px sans-serif";
  ctx.textAlign = style.textAlign;
  ctx.textBaseline = style.textBaseline;
  ctx.fillText(text, 0, 0);
  ctx.restore();
  },
  getBestTextAlign: function(angle, style) {
  style = style || {textAlign: 'center', textBaseline: 'middle'};
  angle += Flotr.getTextAngleFromAlign(style);
   
  if (Math.abs(Math.cos(angle)) > 10e-3)
  style.textAlign = (Math.cos(angle) > 0 ? 'right' : 'left');
   
  if (Math.abs(Math.sin(angle)) > 10e-3)
  style.textBaseline = (Math.sin(angle) > 0 ? 'top' : 'bottom');
   
  return style;
  },
  alignTable: {
  'right middle' : 0,
  'right top' : Math.PI/4,
  'center top' : Math.PI/2,
  'left top' : 3*(Math.PI/4),
  'left middle' : Math.PI,
  'left bottom' : -3*(Math.PI/4),
  'center bottom': -Math.PI/2,
  'right bottom' : -Math.PI/4,
  'center middle': 0
  },
  getTextAngleFromAlign: function(style) {
  return Flotr.alignTable[style.textAlign+' '+style.textBaseline] || 0;
  },
  noConflict : function () {
  global.Flotr = previousFlotr;
  return this;
  }
  };
   
  global.Flotr = Flotr;
   
  })();
   
  /**
  * Flotr Defaults
  */
  Flotr.defaultOptions = {
  colors: ['#00A8F0', '#C0D800', '#CB4B4B', '#4DA74D', '#9440ED'], //=> The default colorscheme. When there are > 5 series, additional colors are generated.
  ieBackgroundColor: '#FFFFFF', // Background color for excanvas clipping
  title: null, // => The graph's title
  subtitle: null, // => The graph's subtitle
  shadowSize: 4, // => size of the 'fake' shadow
  defaultType: null, // => default series type
  HtmlText: true, // => wether to draw the text using HTML or on the canvas
  fontColor: '#545454', // => default font color
  fontSize: 7.5, // => canvas' text font size
  resolution: 1, // => resolution of the graph, to have printer-friendly graphs !
  parseFloat: true, // => whether to preprocess data for floats (ie. if input is string)
  preventDefault: true, // => preventDefault by default for mobile events. Turn off to enable scroll.
  xaxis: {
  ticks: null, // => format: either [1, 3] or [[1, 'a'], 3]
  minorTicks: null, // => format: either [1, 3] or [[1, 'a'], 3]
  showLabels: true, // => setting to true will show the axis ticks labels, hide otherwise
  showMinorLabels: false,// => true to show the axis minor ticks labels, false to hide
  labelsAngle: 0, // => labels' angle, in degrees
  title: null, // => axis title
  titleAngle: 0, // => axis title's angle, in degrees
  noTicks: 5, // => number of ticks for automagically generated ticks
  minorTickFreq: null, // => number of minor ticks between major ticks for autogenerated ticks
  tickFormatter: Flotr.defaultTickFormatter, // => fn: number, Object -> string
  tickDecimals: null, // => no. of decimals, null means auto
  min: null, // => min. value to show, null means set automatically
  max: null, // => max. value to show, null means set automatically
  autoscale: false, // => Turns autoscaling on with true
  autoscaleMargin: 0, // => margin in % to add if auto-setting min/max
  color: null, // => color of the ticks
  mode: 'normal', // => can be 'time' or 'normal'
  timeFormat: null,
  timeMode:'UTC', // => For UTC time ('local' for local time).
  timeUnit:'millisecond',// => Unit for time (millisecond, second, minute, hour, day, month, year)
  scaling: 'linear', // => Scaling, can be 'linear' or 'logarithmic'
  base: Math.E,
  titleAlign: 'center',
  margin: true // => Turn off margins with false
  },
  x2axis: {},
  yaxis: {
  ticks: null, // => format: either [1, 3] or [[1, 'a'], 3]
  minorTicks: null, // => format: either [1, 3] or [[1, 'a'], 3]
  showLabels: true, // => setting to true will show the axis ticks labels, hide otherwise
  showMinorLabels: false,// => true to show the axis minor ticks labels, false to hide
  labelsAngle: 0, // => labels' angle, in degrees
  title: null, // => axis title
  titleAngle: 90, // => axis title's angle, in degrees
  noTicks: 5, // => number of ticks for automagically generated ticks
  minorTickFreq: null, // => number of minor ticks between major ticks for autogenerated ticks
  tickFormatter: Flotr.defaultTickFormatter, // => fn: number, Object -> string
  tickDecimals: null, // => no. of decimals, null means auto
  min: null, // => min. value to show, null means set automatically
  max: null, // => max. value to show, null means set automatically
  autoscale: false, // => Turns autoscaling on with true
  autoscaleMargin: 0, // => margin in % to add if auto-setting min/max
  color: null, // => The color of the ticks
  scaling: 'linear', // => Scaling, can be 'linear' or 'logarithmic'
  base: Math.E,
  titleAlign: 'center',
  margin: true // => Turn off margins with false
  },
  y2axis: {
  titleAngle: 270
  },
  grid: {
  color: '#545454', // => primary color used for outline and labels
  backgroundColor: null, // => null for transparent, else color
  backgroundImage: null, // => background image. String or object with src, left and top
  watermarkAlpha: 0.4, // =>
  tickColor: '#DDDDDD', // => color used for the ticks
  labelMargin: 3, // => margin in pixels
  verticalLines: true, // => whether to show gridlines in vertical direction
  minorVerticalLines: null, // => whether to show gridlines for minor ticks in vertical dir.
  horizontalLines: true, // => whether to show gridlines in horizontal direction
  minorHorizontalLines: null, // => whether to show gridlines for minor ticks in horizontal dir.
  outlineWidth: 1, // => width of the grid outline/border in pixels
  outline : 'nsew', // => walls of the outline to display
  circular: false // => if set to true, the grid will be circular, must be used when radars are drawn
  },
  mouse: {
  track: false, // => true to track the mouse, no tracking otherwise
  trackAll: false,
  position: 'se', // => position of the value box (default south-east)
  relative: false, // => next to the mouse cursor
  trackFormatter: Flotr.defaultTrackFormatter, // => formats the values in the value box
  margin: 5, // => margin in pixels of the valuebox
  lineColor: '#FF3F19', // => line color of points that are drawn when mouse comes near a value of a series
  trackDecimals: 1, // => decimals for the track values
  sensibility: 2, // => the lower this number, the more precise you have to aim to show a value
  trackY: true, // => whether or not to track the mouse in the y axis
  radius: 3, // => radius of the track point
  fillCo