xcharts_rails 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b8b48200f0b727fc441e6ddaa366f97fec520eec
4
+ data.tar.gz: b6e2b553b7c19dc5dbf832b2eb0f741fb14935fb
5
+ SHA512:
6
+ metadata.gz: 23a8950428065bac7f2fac9b43cf5afa2c2aa7335648ed2d2a6e6c7674a93263a09f9829c40c652fc3320e2d8b9eed5436c18d5a6db51165e42c8028cc9b8e22
7
+ data.tar.gz: da015280561f49268e90801f7dbae23e489ec452d14ccf9b86f21681be93010d2ca2da3ef98084d1a74369ddbc461cfdffc904ca496c1a26d2866919d471f133
data/README.md CHANGED
@@ -4,6 +4,11 @@ A gem to include Xcharts into Rails 3.1+ Assets Pipeline
4
4
 
5
5
  ## Installation
6
6
 
7
+ this library requires D3, i didn't want to include it on this gem since
8
+ it may have be installed before, i recommend using the
9
+ [d3_rails](https://github.com/logical42/d3_rails) gem, install it and
10
+ then install this one
11
+
7
12
  Add this line to your application's Gemfile:
8
13
 
9
14
  gem 'xcharts_rails'
@@ -18,6 +23,11 @@ After that execute:
18
23
 
19
24
  This should add `xcharts` to `application.js` and `application.css`
20
25
 
26
+ your `application.js` should look like this to `xcharts` to work
27
+
28
+ //= require d3.v3
29
+ //= require xcharts
30
+
21
31
  ## Contributing
22
32
 
23
33
  1. Fork it
@@ -1,3 +1,3 @@
1
1
  module XchartsRails
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -1,5 +1,1158 @@
1
1
  /*!
2
- xCharts v0.1.3 Copyright (c) 2012, tenXer, Inc. All Rights Reserved.
2
+ xCharts v0.3.0 Copyright (c) 2012, tenXer, Inc. All Rights Reserved.
3
3
  @license MIT license. http://github.com/tenXer/xcharts for details
4
4
  */
5
- (function(){var xChart,_vis={},_scales={},_visutils={};(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,v=e.reduce,h=e.reduceRight,g=e.filter,d=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new w(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VERSION="1.4.3";var A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(r,n,u,i)}),e)};var O="Reduce of empty array with no initial value";w.reduce=w.foldl=w.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduce===v)return e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},w.reduceRight=w.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduceRight===h)return e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},w.find=w.detect=function(n,t,r){var e;return E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},w.filter=w.select=function(n,t,r){var e=[];return null==n?e:g&&n.filter===g?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=function(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:d&&n.every===d?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};w.contains=w.include=function(n,t){return null==n?!1:y&&n.indexOf===y?-1!=n.indexOf(t):E(n,function(n){return n===t})},w.invoke=function(n,t){var r=o.call(arguments,2);return w.map(n,function(n){return(w.isFunction(t)?t:n[t]).apply(n,r)})},w.pluck=function(n,t){return w.map(n,function(n){return n[t]})},w.where=function(n,t){return w.isEmpty(t)?[]:w.filter(n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},w.max=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w.min=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var F=function(n){return w.isFunction(n)?n:function(t){return t[n]}};w.sortBy=function(n,t,r){var e=F(t);return w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||void 0===r)return 1;if(e>r||void 0===e)return-1}return n.index<t.index?-1:1}),"value")};var k=function(n,t,r,e){var u={},i=F(t||w.identity);return A(n,function(t,a){var o=i.call(r,t,a,n);e(u,o,t)}),u};w.groupBy=function(n,t,r){return k(n,t,r,function(n,t,r){(w.has(n,t)?n[t]:n[t]=[]).push(r)})},w.countBy=function(n,t,r){return k(n,t,r,function(n,t){w.has(n,t)||(n[t]=0),n[t]++})},w.sortedIndex=function(n,t,r,e){r=null==r?w.identity:F(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return i},w.toArray=function(n){return n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values(n):[]},w.size=function(n){return null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail=w.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},w.compact=function(n){return w.filter(n,w.identity)};var R=function(n,t,r){return A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flatten=function(n,t){return R(n,t,[])},w.without=function(n){return w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.isFunction(t)&&(e=r,r=t,t=!1);var u=r?w.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.push(n[e]))}),i},w.union=function(){return w.uniq(c.apply(e,arguments))},w.intersection=function(n){var t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return w.every(t,function(t){return w.indexOf(t,n)>=0})})},w.difference=function(n){var t=c.apply(e,o.call(arguments,1));return w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[e]=w.pluck(n,""+e);return r},w.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},w.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},w.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return i};var I=function(){};w.bind=function(n,t){var r,e;if(n.bind===j&&j)return j.apply(n,o.call(arguments,1));if(!w.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));I.prototype=n.prototype;var u=new I;I.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},w.bindAll=function(n){var t=o.call(arguments,1);return 0==t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var e=t.apply(this,arguments);return w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},w.defer=function(n){return w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return function(){var c=new Date,l=t-(c-a);return r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return function(){var i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return t},w.values=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return t},w.functions=w.methods=function(n){var t=[];for(var r in n)w.isFunction(n[r])&&t.push(r);return t.sort()},w.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},w.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},w.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObject(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==t+"";case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=S(n[a],t[a],r,e)););}else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&S(n[s],t[s],r,e))))break;if(o){for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return r.pop(),e.pop(),o};w.isEqual=function(n,t){return S(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w.isString(n))return 0===n.length;for(var t in n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!==n.nodeType)},w.isArray=x||function(n){return"[object Array]"==l.call(n)},w.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){w["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n||!w.has(n,"callee"))}),w.isFunction=function(n){return"function"==typeof n},w.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},w.isNull=function(n){return null===n},w.isUndefined=function(n){return void 0===n},w.has=function(n,t){return f.call(n,t)},w.noConflict=function(){return n._=t,this},w.identity=function(n){return n},w.times=function(n,t,r){for(var e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return e},w.random=function(n,t){return null==t&&(t=n,n=0),n+(0|Math.random()*(t-n+1))};var T={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};T.unescape=w.invert(T.escape);var M={escape:RegExp("["+w.keys(T.escape).join("")+"]","g"),unescape:RegExp("("+w.keys(T.unescape).join("|")+")","g")};w.each(["escape","unescape"],function(n){w[n]=function(t){return null==t?"":(""+t).replace(M[n],function(t){return T[n][t]})}}),w.result=function(n,t){if(null==n)return null;var r=n[t];return w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function(t){var r=w[t]=n[t];w.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(w,n))}})};var N=0;w.uniqueId=function(n){var t=""+ ++N;return n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,r){r=w.defaults({},r,w.templateSettings);var e=RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,a,o){return i+=n.slice(u,o).replace(D,function(n){return"\\"+B[n]}),r&&(i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(i+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),a&&(i+="';\n"+a+"\n__p+='"),u=o+t.length,t}),i+="';\n",r.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var a=Function(r.variable||"obj","_",i)}catch(o){throw o.source=i,o}if(t)return a(t,w);var c=function(n){return a.call(this,n,w)};return c.source="function("+(r.variable||"obj")+"){\n"+i+"}",c},w.chain=function(n){return w(n).chain()};var z=function(n){return this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];w.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];w.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);function getInsertionPoint(zIndex){return _.chain(_.range(zIndex,10)).reverse().map(function(z){return'g[data-index="'+z+'"]'}).value().join(", ")}function colorClass(el,i){var c=el.getAttribute("class");return(c!==null?c.replace(/color\d+/g,""):"")+" color"+i}_visutils={getInsertionPoint:getInsertionPoint,colorClass:colorClass};var local=this,defaultSpacing=.25;function _getDomain(data,axis){return _.chain(data).pluck("data").flatten().pluck(axis).uniq().filter(function(d){return d!==undefined&&d!==null}).value().sort(d3.ascending)}function ordinal(data,axis,bounds,spacing){spacing=spacing||defaultSpacing;var domain=_getDomain(data,axis);return d3.scale.ordinal().domain(domain).rangeRoundBands(bounds,spacing)}function linear(extents,bounds,axis){return d3.scale.linear().domain(extents).nice().rangeRound(bounds)}function exponential(extents,bounds,axis){return d3.scale.pow().exponent(.65).domain(extents).nice().rangeRound(bounds)}function time(extents,bounds){return d3.time.scale().domain(_.map(extents,function(d){return new Date(d)})).range(bounds)}function _extendDomain(domain,axis){var min=domain[0],max=domain[1],diff,e;if(min===max){e=Math.max(Math.round(min/10),4);min-=e;max+=e}diff=max-min;min=min?min-diff/10:min;min=domain[0]>0?Math.max(min,0):min;max=max?max+diff/10:max;max=domain[1]<0?Math.min(max,0):max;return[min,max]}function _getExtents(options,data,xType,yType){var extents,nData=_.chain(data).pluck("data").flatten().value();extents={x:d3.extent(nData,function(d){return d.x}),y:d3.extent(nData,function(d){return d.y})};_.each([xType,yType],function(type,i){var axis=i?"y":"x",extended;extents[axis]=d3.extent(nData,function(d){return d[axis]});if(type==="ordinal"){return}_.each([axis+"Min",axis+"Max"],function(minMax,i){if(type!=="time"){extended=_extendDomain(extents[axis])}extents[axis][i]=options.hasOwnProperty(minMax)&&options[minMax]!==null?options[minMax]:type!=="time"?extended[i]:extents[axis][i]})});return extents}function xy(self,data,xType,yType){var o=self._options,extents=_getExtents(o,data,xType,yType),scales={},horiz=[o.axisPaddingLeft,self._width],vert=[self._height,o.axisPaddingTop],xScale,yScale;_.each([xType,yType],function(type,i){var axis=i===0?"x":"y",bounds=i===0?horiz:vert;switch(type){case"ordinal":scales[axis]=ordinal(data,axis,bounds);break;case"linear":scales[axis]=linear(extents[axis],bounds,axis);break;case"exponential":scales[axis]=exponential(extents[axis],bounds,axis);break;case"time":scales[axis]=time(extents[axis],bounds);break}});return scales}var _scales={ordinal:ordinal,linear:linear,exponential:exponential,time:time,xy:xy};(function(){var zIndex=2,selector="g.bar",insertBefore=_visutils.getInsertionPoint(zIndex);function postUpdateScale(self,scaleData,mainData,compData){self.xScale2=d3.scale.ordinal().domain(d3.range(0,mainData.length)).rangeRoundBands([0,self.xScale.rangeBand()],.08)}function enter(self,storage,className,data,callbacks){var barGroups,bars,yZero=self.yZero;barGroups=self._g.selectAll(selector+className).data(data,function(d){return d.className});barGroups.enter().insert("g",insertBefore).attr("data-index",zIndex).style("opacity",0).attr("class",function(d,i){var cl=_.uniq((className+d.className).split(".")).join(" ");return cl+" bar "+_visutils.colorClass(this,i)}).attr("transform",function(d,i){return"translate("+self.xScale2(i)+",0)"});bars=barGroups.selectAll("rect").data(function(d){return d.data},function(d){return d.x});bars.enter().append("rect").attr("width",0).attr("rx",3).attr("ry",3).attr("x",function(d){return self.xScale(d.x)+self.xScale2.rangeBand()/2}).attr("height",function(d){return Math.abs(yZero-self.yScale(d.y))}).attr("y",function(d){return d.y<0?yZero:self.yScale(d.y)}).on("mouseover",callbacks.mouseover).on("mouseout",callbacks.mouseout).on("click",callbacks.click);storage.barGroups=barGroups;storage.bars=bars}function update(self,storage,timing){var yZero=self.yZero;storage.barGroups.attr("class",function(d,i){return _visutils.colorClass(this,i)}).transition().duration(timing).style("opacity",1).attr("transform",function(d,i){return"translate("+self.xScale2(i)+",0)"});storage.bars.transition().duration(timing).attr("width",self.xScale2.rangeBand()).attr("x",function(d){return self.xScale(d.x)}).attr("height",function(d){return Math.abs(yZero-self.yScale(d.y))}).attr("y",function(d){return d.y<0?yZero:self.yScale(d.y)})}function exit(self,storage,timing){storage.bars.exit().transition().duration(timing).attr("width",0).remove();storage.barGroups.exit().transition().duration(timing).style("opacity",0).remove()}function destroy(self,storage,timing){var band=self.xScale2?self.xScale2.rangeBand()/2:0;delete self.xScale2;storage.bars.transition().duration(timing).attr("width",0).attr("x",function(d){return self.xScale(d.x)+band})}_vis.bar={postUpdateScale:postUpdateScale,enter:enter,update:update,exit:exit,destroy:destroy}})();(function(){var zIndex=3,selector="g.line",insertBefore=_visutils.getInsertionPoint(zIndex);function enter(self,storage,className,data,callbacks){var inter=self._options.interpolation,x=function(d,i){if(!self.xScale2&&!self.xScale.rangeBand){return self.xScale(d.x)}return self.xScale(d.x)+self.xScale.rangeBand()/2},y=function(d){return self.yScale(d.y)},line=d3.svg.line().x(x).interpolate(inter),area=d3.svg.area().x(x).y1(self.yZero).interpolate(inter),container,fills,paths;function datum(d){return[d.data]}container=self._g.selectAll(selector+className).data(data,function(d){return d.className});container.enter().insert("g",insertBefore).attr("data-index",zIndex).attr("class",function(d,i){var cl=_.uniq((className+d.className).split(".")).join(" ");return cl+" line "+_visutils.colorClass(this,i)});fills=container.selectAll("path.fill").data(datum);fills.enter().append("path").attr("class","fill").style("opacity",0).attr("d",area.y0(y));paths=container.selectAll("path.line").data(datum);paths.enter().append("path").attr("class","line").style("opacity",0).attr("d",line.y(y));storage.lineContainers=container;storage.lineFills=fills;storage.linePaths=paths;storage.lineX=x;storage.lineY=y;storage.lineA=area;storage.line=line}function update(self,storage,timing){storage.lineContainers.attr("class",function(d,i){return _visutils.colorClass(this,i)});storage.lineFills.transition().duration(timing).style("opacity",1).attr("d",storage.lineA.y0(storage.lineY));storage.linePaths.transition().duration(timing).style("opacity",1).attr("d",storage.line.y(storage.lineY))}function exit(self,storage){storage.linePaths.exit().style("opacity",0).remove();storage.lineFills.exit().style("opacity",0).remove();storage.lineContainers.exit().remove()}function destroy(self,storage,timing){storage.linePaths.transition().duration(timing).style("opacity",0);storage.lineFills.transition().duration(timing).style("opacity",0)}_vis.line={enter:enter,update:update,exit:exit,destroy:destroy}})();(function(){var line=_vis.line;function enter(self,storage,className,data,callbacks){var circles;line.enter(self,storage,className,data,callbacks);circles=storage.lineContainers.selectAll("circle").data(function(d){return d.data},function(d){return d.x});circles.enter().append("circle").style("opacity",0).attr("cx",storage.lineX).attr("cy",storage.lineY).attr("r",5).on("mouseover",callbacks.mouseover).on("mouseout",callbacks.mouseout).on("click",callbacks.click);storage.lineCircles=circles}function update(self,storage,timing){line.update.apply(null,_.toArray(arguments));storage.lineCircles.transition().duration(timing).style("opacity",1).attr("cx",storage.lineX).attr("cy",storage.lineY)}function exit(self,storage){storage.lineCircles.exit().remove();line.exit.apply(null,_.toArray(arguments))}function destroy(self,storage,timing){line.destroy.apply(null,_.toArray(arguments));if(!storage.lineCircles){return}storage.lineCircles.transition().duration(timing).style("opacity",0)}_vis["line-dotted"]={enter:enter,update:update,exit:exit,destroy:destroy}})();(function(){var line=_vis["line-dotted"];function enter(self,storage,className,data,callbacks){line.enter(self,storage,className,data,callbacks)}function _accumulate_data(data){function reduce(memo,num){return memo+num.y}var nData=_.map(data,function(set){var i=set.data.length,d=_.clone(set.data);set=_.clone(set);while(i){i-=1;d[i]=_.clone(set.data[i]);d[i].y0=set.data[i].y;d[i].y=_.reduce(_.first(set.data,i),reduce,set.data[i].y)}return _.extend(set,{data:d})});return nData}function _resetData(self){if(!self.hasOwnProperty("cumulativeOMainData")){return}self._mainData=self.cumulativeOMainData;delete self.cumulativeOMainData;self._compData=self.cumulativeOCompData;delete self.cumulativeOCompData}function preUpdateScale(self,data){_resetData(self);self.cumulativeOMainData=self._mainData;self._mainData=_accumulate_data(self._mainData);self.cumulativeOCompData=self._compData;self._compData=_accumulate_data(self._compData)}function destroy(self,storage,timing){_resetData(self);line.destroy.apply(null,_.toArray(arguments))}_vis.cumulative={preUpdateScale:preUpdateScale,enter:enter,update:line.update,exit:line.exit,destroy:destroy}})();var emptyData=[[]],defaults={mouseover:function(data,i){},mouseout:function(data,i){},click:function(data,i){},axisPaddingTop:0,axisPaddingRight:0,axisPaddingBottom:5,axisPaddingLeft:20,paddingTop:0,paddingRight:0,paddingBottom:20,paddingLeft:60,tickHintX:10,tickFormatX:function(x){return x},tickHintY:10,tickFormatY:function(y){return y},xMin:null,xMax:null,yMin:null,yMax:null,dataFormatX:function(x){return x},dataFormatY:function(y){return y},unsupported:function(selector){d3.select(selector).text("SVG is not supported on your browser")},empty:function(self,selector,d){},notempty:function(self,selector){},timing:750,interpolation:"monotone"};function svgEnabled(){var d=document;return!!d.createElementNS&&!!d.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect}function xChart(type,data,selector,options){var self=this,resizeLock;self._options=options=_.defaults(options||{},defaults);if(svgEnabled()===false){return options.unsupported(selector)}self._selector=selector;self._container=d3.select(selector);self._drawSvg();data=_.clone(data);if(type&&!data.type){data.type=type}self.setData(data);d3.select(window).on("resize.for."+selector,function(){if(resizeLock){clearTimeout(resizeLock)}resizeLock=setTimeout(function(){resizeLock=null;self._resize()},500)})}xChart.setVis=function(type,vis){if(_vis.hasOwnProperty(type)){throw'Cannot override vis type "'+type+'".'}_vis[type]=vis};xChart.getVis=function(type){if(!_vis.hasOwnProperty(type)){throw'Vis type "'+type+'" does not exist.'}return _.clone(_vis[type])};xChart.visutils=_visutils;xChart.scales=_scales;_.defaults(xChart.prototype,{setType:function(type,skipDraw){var self=this;if(self._type&&type===self._type){return}if(!_vis.hasOwnProperty(type)){throw'Vis type "'+type+'" is not defined.'}if(self._type){self._destroy(self._vis,self._mainStorage)}self._type=type;self._vis=_vis[type];if(!skipDraw){self._draw()}},setData:function(data){var self=this,o=self._options,nData=_.clone(data);if(!data.hasOwnProperty("main")){throw'No "main" key found in given chart data.'}switch(data.type){case"bar":data.xScale="ordinal";break;case undefined:data.type=self._type;break}o.xMin=data.xMin||o.xMin;o.xMax=data.xMax||o.xMax;o.yMin=data.yMin||o.yMin;o.yMax=data.yMax||o.yMax;if(self._vis){self._destroy(self._vis,self._mainStorage)}self.setType(data.type,true);function _mapData(set){var d=_.map(_.clone(set.data),function(p){var np=_.clone(p);if(p.hasOwnProperty("x")){np.x=o.dataFormatX(p.x)}if(p.hasOwnProperty("y")){np.y=o.dataFormatY(p.y)}return np}).sort(function(a,b){if(!a.x&&!b.x){return 0}return a.x<b.x?-1:1});return _.extend(_.clone(set),{data:d})}nData.main=_.map(nData.main,_mapData);self._mainData=nData.main;self._xScaleType=nData.xScale;self._yScaleType=nData.yScale;if(nData.hasOwnProperty("comp")){nData.comp=_.map(nData.comp,_mapData);self._compData=nData.comp}else{self._compData=[]}self._draw()},setScale:function(axis,type){var self=this;switch(axis){case"x":self._xScaleType=type;break;case"y":self._yScaleType=type;break;default:throw'Cannot change scale of unknown axis "'+axis+'".'}self._draw()},_drawSvg:function(){var self=this,c=self._container,options=self._options,width=parseInt(c.style("width").replace("px",""),10),height=parseInt(c.style("height").replace("px",""),10),svg,g,gScale;svg=c.selectAll("svg").data(emptyData);svg.enter().append("svg").attr("height",height).attr("width",width).attr("class","xchart");svg.transition().attr("width",width).attr("height",height);g=svg.selectAll("g").data(emptyData);g.enter().append("g").attr("transform","translate("+options.paddingLeft+","+options.paddingTop+")");gScale=g.selectAll("g.scale").data(emptyData);gScale.enter().append("g").attr("class","scale");self._svg=svg;self._g=g;self._gScale=gScale;self._height=height-options.paddingTop-options.paddingBottom-options.axisPaddingTop-options.axisPaddingBottom;self._width=width-options.paddingLeft-options.paddingRight-options.axisPaddingLeft-options.axisPaddingRight},_resize:function(event){var self=this;self._drawSvg();self._draw()},_drawAxes:function(){if(this._noData){return}var self=this,o=self._options,t=self._gScale.transition().duration(o.timing),xTicks=o.tickHintX,yTicks=o.tickHintY,bottom=self._height+o.axisPaddingTop+o.axisPaddingBottom,zeroLine=d3.svg.line().x(function(d){return d}),zLine,zLinePath,xAxis,xRules,yAxis,yRules,labels;xRules=d3.svg.axis().scale(self.xScale).ticks(xTicks).tickSize(-self._height).tickFormat(o.tickFormatX).orient("bottom");xAxis=self._gScale.selectAll("g.axisX").data(emptyData);xAxis.enter().append("g").attr("class","axis axisX").attr("transform","translate(0,"+bottom+")");xAxis.call(xRules);labels=self._gScale.selectAll(".axisX g")[0];if(labels.length>self._width/80){labels.sort(function(a,b){var r=/translate\(([^,)]+)/;a=a.getAttribute("transform").match(r);b=b.getAttribute("transform").match(r);return parseFloat(a[1],10)-parseFloat(b[1],10)});d3.selectAll(labels).filter(function(d,i){return i%(Math.ceil(labels.length/xTicks)+1)}).remove()}yRules=d3.svg.axis().scale(self.yScale).ticks(yTicks).tickSize(-self._width-o.axisPaddingRight-o.axisPaddingLeft).tickFormat(o.tickFormatY).orient("left");yAxis=self._gScale.selectAll("g.axisY").data(emptyData);yAxis.enter().append("g").attr("class","axis axisY").attr("transform","translate(0,0)");t.selectAll("g.axisY").call(yRules);zLine=self._gScale.selectAll("g.axisZero").data([[]]);zLine.enter().append("g").attr("class","axisZero");zLinePath=zLine.selectAll("line").data([[]]);zLinePath.enter().append("line").attr("x1",0).attr("x2",self._width+o.axisPaddingLeft+o.axisPaddingRight).attr("y1",self.yZero).attr("y2",self.yZero);zLinePath.transition().duration(o.timing).attr("y1",self.yZero).attr("y2",self.yZero)},_updateScale:function(){var self=this,_unionData=function(){return _.union(self._mainData,self._compData)},scaleData=_unionData(),vis=self._vis,scale,min;delete self.xScale;delete self.yScale;delete self.yZero;if(vis.hasOwnProperty("preUpdateScale")){vis.preUpdateScale(self,scaleData,self._mainData,self._compData)}scaleData=_unionData();scale=_scales.xy(self,scaleData,self._xScaleType,self._yScaleType);self.xScale=scale.x;self.yScale=scale.y;min=self.yScale.domain()[0];self.yZero=min>0?self.yScale(min):self.yScale(0);if(vis.hasOwnProperty("postUpdateScale")){vis.postUpdateScale(self,scaleData,self._mainData,self._compData)}},_enter:function(vis,storage,data,className){var self=this,callbacks={click:self._options.click,mouseover:self._options.mouseover,mouseout:self._options.mouseout};self._checkVisMethod(vis,"enter");vis.enter(self,storage,className,data,callbacks)},_update:function(vis,storage){var self=this;self._checkVisMethod(vis,"update");vis.update(self,storage,self._options.timing)},_exit:function(vis,storage){var self=this;self._checkVisMethod(vis,"exit");vis.exit(self,storage,self._options.timing)},_destroy:function(vis,storage){var self=this;self._checkVisMethod(vis,"destroy");try{vis.destroy(self,storage,self._options.timing)}catch(e){}},_mainStorage:{},_compStorage:{},_draw:function(){var self=this,o=self._options,comp,compKeys;self._noData=_.flatten(_.pluck(self._mainData,"data").concat(_.pluck(self._compData,"data"))).length===0;self._updateScale();self._drawAxes();self._enter(self._vis,self._mainStorage,self._mainData,".main");self._exit(self._vis,self._mainStorage);self._update(self._vis,self._mainStorage);comp=_.chain(self._compData).groupBy(function(d){return d.type});compKeys=comp.keys();_.each(self._compStorage,function(d,key){if(-1===compKeys.indexOf(key).value()){var vis=_vis[key];self._enter(vis,d,[],".comp."+key.replace(/\W+/g,""));self._exit(vis,d)}});comp.each(function(d,key){var vis=_vis[key],storage;if(!self._compStorage.hasOwnProperty(key)){self._compStorage[key]={}}storage=self._compStorage[key];self._enter(vis,storage,d,".comp."+key.replace(/\W+/g,""));self._exit(vis,storage);self._update(vis,storage)});if(self._noData){o.empty(self,self._selector,self._mainData)}else{o.notempty(self,self._selector)}},_checkVisMethod:function(vis,method){var self=this;if(!vis[method]){throw'Required method "'+method+'" not found on vis type "'+self._type+'".'}}});if(typeof define==="function"&&define.amd&&typeof define.amd==="object"){define(function(){return xChart});return}window.xChart=xChart})();
5
+
6
+ (function () {
7
+
8
+ var xChart,
9
+ _vis = {},
10
+ _scales = {},
11
+ _visutils = {};
12
+ (function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,v=e.reduce,h=e.reduceRight,g=e.filter,d=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new w(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VERSION="1.4.3";var A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(r,n,u,i)}),e)};var O="Reduce of empty array with no initial value";w.reduce=w.foldl=w.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduce===v)return e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},w.reduceRight=w.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduceRight===h)return e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},w.find=w.detect=function(n,t,r){var e;return E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},w.filter=w.select=function(n,t,r){var e=[];return null==n?e:g&&n.filter===g?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=function(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:d&&n.every===d?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};w.contains=w.include=function(n,t){return null==n?!1:y&&n.indexOf===y?-1!=n.indexOf(t):E(n,function(n){return n===t})},w.invoke=function(n,t){var r=o.call(arguments,2);return w.map(n,function(n){return(w.isFunction(t)?t:n[t]).apply(n,r)})},w.pluck=function(n,t){return w.map(n,function(n){return n[t]})},w.where=function(n,t){return w.isEmpty(t)?[]:w.filter(n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},w.max=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w.min=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var F=function(n){return w.isFunction(n)?n:function(t){return t[n]}};w.sortBy=function(n,t,r){var e=F(t);return w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||void 0===r)return 1;if(e>r||void 0===e)return-1}return n.index<t.index?-1:1}),"value")};var k=function(n,t,r,e){var u={},i=F(t||w.identity);return A(n,function(t,a){var o=i.call(r,t,a,n);e(u,o,t)}),u};w.groupBy=function(n,t,r){return k(n,t,r,function(n,t,r){(w.has(n,t)?n[t]:n[t]=[]).push(r)})},w.countBy=function(n,t,r){return k(n,t,r,function(n,t){w.has(n,t)||(n[t]=0),n[t]++})},w.sortedIndex=function(n,t,r,e){r=null==r?w.identity:F(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return i},w.toArray=function(n){return n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values(n):[]},w.size=function(n){return null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail=w.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},w.compact=function(n){return w.filter(n,w.identity)};var R=function(n,t,r){return A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flatten=function(n,t){return R(n,t,[])},w.without=function(n){return w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.isFunction(t)&&(e=r,r=t,t=!1);var u=r?w.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.push(n[e]))}),i},w.union=function(){return w.uniq(c.apply(e,arguments))},w.intersection=function(n){var t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return w.every(t,function(t){return w.indexOf(t,n)>=0})})},w.difference=function(n){var t=c.apply(e,o.call(arguments,1));return w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[e]=w.pluck(n,""+e);return r},w.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},w.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},w.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return i};var I=function(){};w.bind=function(n,t){var r,e;if(n.bind===j&&j)return j.apply(n,o.call(arguments,1));if(!w.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));I.prototype=n.prototype;var u=new I;I.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},w.bindAll=function(n){var t=o.call(arguments,1);return 0==t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var e=t.apply(this,arguments);return w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},w.defer=function(n){return w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return function(){var c=new Date,l=t-(c-a);return r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return function(){var i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return t},w.values=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return t},w.functions=w.methods=function(n){var t=[];for(var r in n)w.isFunction(n[r])&&t.push(r);return t.sort()},w.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},w.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},w.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObject(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==t+"";case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=S(n[a],t[a],r,e)););}else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&S(n[s],t[s],r,e))))break;if(o){for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return r.pop(),e.pop(),o};w.isEqual=function(n,t){return S(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w.isString(n))return 0===n.length;for(var t in n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!==n.nodeType)},w.isArray=x||function(n){return"[object Array]"==l.call(n)},w.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){w["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n||!w.has(n,"callee"))}),w.isFunction=function(n){return"function"==typeof n},w.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},w.isNull=function(n){return null===n},w.isUndefined=function(n){return void 0===n},w.has=function(n,t){return f.call(n,t)},w.noConflict=function(){return n._=t,this},w.identity=function(n){return n},w.times=function(n,t,r){for(var e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return e},w.random=function(n,t){return null==t&&(t=n,n=0),n+(0|Math.random()*(t-n+1))};var T={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};T.unescape=w.invert(T.escape);var M={escape:RegExp("["+w.keys(T.escape).join("")+"]","g"),unescape:RegExp("("+w.keys(T.unescape).join("|")+")","g")};w.each(["escape","unescape"],function(n){w[n]=function(t){return null==t?"":(""+t).replace(M[n],function(t){return T[n][t]})}}),w.result=function(n,t){if(null==n)return null;var r=n[t];return w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function(t){var r=w[t]=n[t];w.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(w,n))}})};var N=0;w.uniqueId=function(n){var t=""+ ++N;return n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,r){r=w.defaults({},r,w.templateSettings);var e=RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,a,o){return i+=n.slice(u,o).replace(D,function(n){return"\\"+B[n]}),r&&(i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(i+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),a&&(i+="';\n"+a+"\n__p+='"),u=o+t.length,t}),i+="';\n",r.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var a=Function(r.variable||"obj","_",i)}catch(o){throw o.source=i,o}if(t)return a(t,w);var c=function(n){return a.call(this,n,w)};return c.source="function("+(r.variable||"obj")+"){\n"+i+"}",c},w.chain=function(n){return w(n).chain()};var z=function(n){return this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];w.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];w.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);function getInsertionPoint(zIndex) {
13
+ return _.chain(_.range(zIndex, 10)).reverse().map(function (z) {
14
+ return 'g[data-index="' + z + '"]';
15
+ }).value().join(', ');
16
+ }
17
+
18
+ function colorClass(el, i) {
19
+ var c = el.getAttribute('class');
20
+ return ((c !== null) ? c.replace(/color\d+/g, '') : '') + ' color' + i;
21
+ }
22
+
23
+ _visutils = {
24
+ getInsertionPoint: getInsertionPoint,
25
+ colorClass: colorClass
26
+ };
27
+ var local = this,
28
+ defaultSpacing = 0.25;
29
+
30
+ function _getDomain(data, axis) {
31
+ return _.chain(data)
32
+ .pluck('data')
33
+ .flatten()
34
+ .pluck(axis)
35
+ .uniq()
36
+ .filter(function (d) {
37
+ return d !== undefined && d !== null;
38
+ })
39
+ .value()
40
+ .sort(d3.ascending);
41
+ }
42
+
43
+ _scales.ordinal = function (data, axis, bounds, extents) {
44
+ var domain = _getDomain(data, axis);
45
+ return d3.scale.ordinal()
46
+ .domain(domain)
47
+ .rangeRoundBands(bounds, defaultSpacing);
48
+ };
49
+
50
+ _scales.linear = function (data, axis, bounds, extents) {
51
+ return d3.scale.linear()
52
+ .domain(extents)
53
+ .nice()
54
+ .rangeRound(bounds);
55
+ };
56
+
57
+ _scales.exponential = function (data, axis, bounds, extents) {
58
+ return d3.scale.pow()
59
+ .exponent(0.65)
60
+ .domain(extents)
61
+ .nice()
62
+ .rangeRound(bounds);
63
+ };
64
+
65
+ _scales.time = function (data, axis, bounds, extents) {
66
+ return d3.time.scale()
67
+ .domain(_.map(extents, function (d) { return new Date(d); }))
68
+ .range(bounds);
69
+ };
70
+
71
+ function _extendDomain(domain, axis) {
72
+ var min = domain[0],
73
+ max = domain[1],
74
+ diff,
75
+ e;
76
+
77
+ if (min === max) {
78
+ e = Math.max(Math.round(min / 10), 4);
79
+ min -= e;
80
+ max += e;
81
+ }
82
+
83
+ diff = max - min;
84
+ min = (min) ? min - (diff / 10) : min;
85
+ min = (domain[0] > 0) ? Math.max(min, 0) : min;
86
+ max = (max) ? max + (diff / 10) : max;
87
+ max = (domain[1] < 0) ? Math.min(max, 0) : max;
88
+
89
+ return [min, max];
90
+ }
91
+
92
+ function _getExtents(options, data, xType, yType) {
93
+ var extents,
94
+ nData = _.chain(data)
95
+ .pluck('data')
96
+ .flatten()
97
+ .value();
98
+
99
+ extents = {
100
+ x: d3.extent(nData, function (d) { return d.x; }),
101
+ y: d3.extent(nData, function (d) { return d.y; })
102
+ };
103
+
104
+ _.each([xType, yType], function (type, i) {
105
+ var axis = (i) ? 'y' : 'x',
106
+ extended;
107
+ extents[axis] = d3.extent(nData, function (d) { return d[axis]; });
108
+ if (type === 'ordinal') {
109
+ return;
110
+ }
111
+
112
+ _.each([axis + 'Min', axis + 'Max'], function (minMax, i) {
113
+ if (type !== 'time') {
114
+ extended = _extendDomain(extents[axis]);
115
+ }
116
+
117
+ if (options.hasOwnProperty(minMax) && options[minMax] !== null) {
118
+ extents[axis][i] = options[minMax];
119
+ } else if (type !== 'time') {
120
+ extents[axis][i] = extended[i];
121
+ }
122
+ });
123
+ });
124
+
125
+ return extents;
126
+ }
127
+
128
+ _scales.xy = function (self, data, xType, yType) {
129
+ var o = self._options,
130
+ extents = _getExtents(o, data, xType, yType),
131
+ scales = {},
132
+ horiz = [o.axisPaddingLeft, self._width],
133
+ vert = [self._height, o.axisPaddingTop],
134
+ xScale,
135
+ yScale;
136
+
137
+ _.each([xType, yType], function (type, i) {
138
+ var axis = (i === 0) ? 'x' : 'y',
139
+ bounds = (i === 0) ? horiz : vert,
140
+ fn = xChart.getScale(type);
141
+ scales[axis] = fn(data, axis, bounds, extents[axis]);
142
+ });
143
+
144
+ return scales;
145
+ };
146
+ (function () {
147
+ var zIndex = 2,
148
+ selector = 'g.bar',
149
+ insertBefore = _visutils.getInsertionPoint(zIndex);
150
+
151
+ function postUpdateScale(self, scaleData, mainData, compData) {
152
+ self.xScale2 = d3.scale.ordinal()
153
+ .domain(d3.range(0, mainData.length))
154
+ .rangeRoundBands([0, self.xScale.rangeBand()], 0.08);
155
+ }
156
+
157
+ function enter(self, storage, className, data, callbacks) {
158
+ var barGroups, bars,
159
+ yZero = self.yZero;
160
+
161
+ barGroups = self._g.selectAll(selector + className)
162
+ .data(data, function (d) {
163
+ return d.className;
164
+ });
165
+
166
+ barGroups.enter().insert('g', insertBefore)
167
+ .attr('data-index', zIndex)
168
+ .style('opacity', 0)
169
+ .attr('class', function (d, i) {
170
+ var cl = _.uniq((className + d.className).split('.')).join(' ');
171
+ return cl + ' bar ' + _visutils.colorClass(this, i);
172
+ })
173
+ .attr('transform', function (d, i) {
174
+ return 'translate(' + self.xScale2(i) + ',0)';
175
+ });
176
+
177
+ bars = barGroups.selectAll('rect')
178
+ .data(function (d) {
179
+ return d.data;
180
+ }, function (d) {
181
+ return d.x;
182
+ });
183
+
184
+ bars.enter().append('rect')
185
+ .attr('width', 0)
186
+ .attr('rx', 3)
187
+ .attr('ry', 3)
188
+ .attr('x', function (d) {
189
+ return self.xScale(d.x) + (self.xScale2.rangeBand() / 2);
190
+ })
191
+ .attr('height', function (d) {
192
+ return Math.abs(yZero - self.yScale(d.y));
193
+ })
194
+ .attr('y', function (d) {
195
+ return (d.y < 0) ? yZero : self.yScale(d.y);
196
+ })
197
+ .on('mouseover', callbacks.mouseover)
198
+ .on('mouseout', callbacks.mouseout)
199
+ .on('click', callbacks.click);
200
+
201
+ storage.barGroups = barGroups;
202
+ storage.bars = bars;
203
+ }
204
+
205
+ function update(self, storage, timing) {
206
+ var yZero = self.yZero;
207
+
208
+ storage.barGroups
209
+ .attr('class', function (d, i) {
210
+ return _visutils.colorClass(this, i);
211
+ })
212
+ .transition().duration(timing)
213
+ .style('opacity', 1)
214
+ .attr('transform', function (d, i) {
215
+ return 'translate(' + self.xScale2(i) + ',0)';
216
+ });
217
+
218
+ storage.bars.transition().duration(timing)
219
+ .attr('width', self.xScale2.rangeBand())
220
+ .attr('x', function (d) {
221
+ return self.xScale(d.x);
222
+ })
223
+ .attr('height', function (d) {
224
+ return Math.abs(yZero - self.yScale(d.y));
225
+ })
226
+ .attr('y', function (d) {
227
+ return (d.y < 0) ? yZero : self.yScale(d.y);
228
+ });
229
+ }
230
+
231
+ function exit(self, storage, timing) {
232
+ storage.bars.exit()
233
+ .transition().duration(timing)
234
+ .attr('width', 0)
235
+ .remove();
236
+ storage.barGroups.exit()
237
+ .transition().duration(timing)
238
+ .style('opacity', 0)
239
+ .remove();
240
+ }
241
+
242
+ function destroy(self, storage, timing) {
243
+ var band = (self.xScale2) ? self.xScale2.rangeBand() / 2 : 0;
244
+ delete self.xScale2;
245
+ storage.bars
246
+ .transition().duration(timing)
247
+ .attr('width', 0)
248
+ .attr('x', function (d) {
249
+ return self.xScale(d.x) + band;
250
+ });
251
+ }
252
+
253
+ _vis.bar = {
254
+ postUpdateScale: postUpdateScale,
255
+ enter: enter,
256
+ update: update,
257
+ exit: exit,
258
+ destroy: destroy
259
+ };
260
+ }());
261
+ (function () {
262
+
263
+ var zIndex = 3,
264
+ selector = 'g.line',
265
+ insertBefore = _visutils.getInsertionPoint(zIndex);
266
+
267
+ function enter(self, storage, className, data, callbacks) {
268
+ var inter = self._options.interpolation,
269
+ x = function (d, i) {
270
+ if (!self.xScale2 && !self.xScale.rangeBand) {
271
+ return self.xScale(d.x);
272
+ }
273
+ return self.xScale(d.x) + (self.xScale.rangeBand() / 2);
274
+ },
275
+ y = function (d) { return self.yScale(d.y); },
276
+ line = d3.svg.line()
277
+ .x(x)
278
+ .interpolate(inter),
279
+ area = d3.svg.area()
280
+ .x(x)
281
+ .y1(self.yZero)
282
+ .interpolate(inter),
283
+ container,
284
+ fills,
285
+ paths;
286
+
287
+ function datum(d) {
288
+ return [d.data];
289
+ }
290
+
291
+ container = self._g.selectAll(selector + className)
292
+ .data(data, function (d) {
293
+ return d.className;
294
+ });
295
+
296
+ container.enter().insert('g', insertBefore)
297
+ .attr('data-index', zIndex)
298
+ .attr('class', function (d, i) {
299
+ var cl = _.uniq((className + d.className).split('.')).join(' ');
300
+ return cl + ' line ' + _visutils.colorClass(this, i);
301
+ });
302
+
303
+ fills = container.selectAll('path.fill')
304
+ .data(datum);
305
+
306
+ fills.enter().append('path')
307
+ .attr('class', 'fill')
308
+ .style('opacity', 0)
309
+ .attr('d', area.y0(y));
310
+
311
+ paths = container.selectAll('path.line')
312
+ .data(datum);
313
+
314
+ paths.enter().append('path')
315
+ .attr('class', 'line')
316
+ .style('opacity', 0)
317
+ .attr('d', line.y(y));
318
+
319
+ storage.lineContainers = container;
320
+ storage.lineFills = fills;
321
+ storage.linePaths = paths;
322
+ storage.lineX = x;
323
+ storage.lineY = y;
324
+ storage.lineA = area;
325
+ storage.line = line;
326
+ }
327
+
328
+ function update(self, storage, timing) {
329
+ storage.lineContainers
330
+ .attr('class', function (d, i) {
331
+ return _visutils.colorClass(this, i);
332
+ });
333
+
334
+ storage.lineFills.transition().duration(timing)
335
+ .style('opacity', 1)
336
+ .attr('d', storage.lineA.y0(storage.lineY));
337
+
338
+ storage.linePaths.transition().duration(timing)
339
+ .style('opacity', 1)
340
+ .attr('d', storage.line.y(storage.lineY));
341
+ }
342
+
343
+ function exit(self, storage) {
344
+ storage.linePaths.exit()
345
+ .style('opacity', 0)
346
+ .remove();
347
+ storage.lineFills.exit()
348
+ .style('opacity', 0)
349
+ .remove();
350
+
351
+ storage.lineContainers.exit()
352
+ .remove();
353
+ }
354
+
355
+ function destroy(self, storage, timing) {
356
+ storage.linePaths.transition().duration(timing)
357
+ .style('opacity', 0);
358
+ storage.lineFills.transition().duration(timing)
359
+ .style('opacity', 0);
360
+ }
361
+
362
+ _vis.line = {
363
+ enter: enter,
364
+ update: update,
365
+ exit: exit,
366
+ destroy: destroy
367
+ };
368
+ }());
369
+ (function () {
370
+ var line = _vis.line;
371
+
372
+ function enter(self, storage, className, data, callbacks) {
373
+ var circles;
374
+
375
+ line.enter(self, storage, className, data, callbacks);
376
+
377
+ circles = storage.lineContainers.selectAll('circle')
378
+ .data(function (d) {
379
+ return d.data;
380
+ }, function (d) {
381
+ return d.x;
382
+ });
383
+
384
+ circles.enter().append('circle')
385
+ .style('opacity', 0)
386
+ .attr('cx', storage.lineX)
387
+ .attr('cy', storage.lineY)
388
+ .attr('r', 5)
389
+ .on('mouseover', callbacks.mouseover)
390
+ .on('mouseout', callbacks.mouseout)
391
+ .on('click', callbacks.click);
392
+
393
+ storage.lineCircles = circles;
394
+ }
395
+
396
+ function update(self, storage, timing) {
397
+ line.update.apply(null, _.toArray(arguments));
398
+
399
+ storage.lineCircles.transition().duration(timing)
400
+ .style('opacity', 1)
401
+ .attr('cx', storage.lineX)
402
+ .attr('cy', storage.lineY);
403
+ }
404
+
405
+ function exit(self, storage) {
406
+ storage.lineCircles.exit()
407
+ .remove();
408
+ line.exit.apply(null, _.toArray(arguments));
409
+ }
410
+
411
+ function destroy(self, storage, timing) {
412
+ line.destroy.apply(null, _.toArray(arguments));
413
+ if (!storage.lineCircles) {
414
+ return;
415
+ }
416
+ storage.lineCircles.transition().duration(timing)
417
+ .style('opacity', 0);
418
+ }
419
+
420
+ _vis['line-dotted'] = {
421
+ enter: enter,
422
+ update: update,
423
+ exit: exit,
424
+ destroy: destroy
425
+ };
426
+ }());
427
+ (function () {
428
+ var line = _vis['line-dotted'];
429
+
430
+ function enter(self, storage, className, data, callbacks) {
431
+ line.enter(self, storage, className, data, callbacks);
432
+ }
433
+
434
+ function _accumulate_data(data) {
435
+ function reduce(memo, num) {
436
+ return memo + num.y;
437
+ }
438
+
439
+ var nData = _.map(data, function (set) {
440
+ var i = set.data.length,
441
+ d = _.clone(set.data);
442
+ set = _.clone(set);
443
+ while (i) {
444
+ i -= 1;
445
+ // Need to clone here, otherwise we are actually setting the same
446
+ // data onto the original data set.
447
+ d[i] = _.clone(set.data[i]);
448
+ d[i].y0 = set.data[i].y;
449
+ d[i].y = _.reduce(_.first(set.data, i), reduce, set.data[i].y);
450
+ }
451
+ return _.extend(set, { data: d });
452
+ });
453
+
454
+ return nData;
455
+ }
456
+
457
+ function _resetData(self) {
458
+ if (!self.hasOwnProperty('cumulativeOMainData')) {
459
+ return;
460
+ }
461
+ self._mainData = self.cumulativeOMainData;
462
+ delete self.cumulativeOMainData;
463
+ self._compData = self.cumulativeOCompData;
464
+ delete self.cumulativeOCompData;
465
+ }
466
+
467
+ function preUpdateScale(self, data) {
468
+ _resetData(self);
469
+ self.cumulativeOMainData = self._mainData;
470
+ self._mainData = _accumulate_data(self._mainData);
471
+ self.cumulativeOCompData = self._compData;
472
+ self._compData = _accumulate_data(self._compData);
473
+ }
474
+
475
+ function destroy(self, storage, timing) {
476
+ _resetData(self);
477
+ line.destroy.apply(null, _.toArray(arguments));
478
+ }
479
+
480
+ _vis.cumulative = {
481
+ preUpdateScale: preUpdateScale,
482
+ enter: enter,
483
+ update: line.update,
484
+ exit: line.exit,
485
+ destroy: destroy
486
+ };
487
+ }());
488
+ var emptyData = [[]],
489
+ defaults = {
490
+ // User interaction callbacks
491
+ mouseover: function (data, i) {},
492
+ mouseout: function (data, i) {},
493
+ click: function (data, i) {},
494
+
495
+ // Padding between the axes and the contents of the chart
496
+ axisPaddingTop: 0,
497
+ axisPaddingRight: 0,
498
+ axisPaddingBottom: 5,
499
+ axisPaddingLeft: 20,
500
+
501
+ // Padding around the edge of the chart (space for axis labels, etc)
502
+ paddingTop: 0,
503
+ paddingRight: 0,
504
+ paddingBottom: 20,
505
+ paddingLeft: 60,
506
+
507
+ // Axis tick formatting
508
+ tickHintX: 10,
509
+ tickFormatX: function (x) { return x; },
510
+ tickHintY: 10,
511
+ tickFormatY: function (y) { return y; },
512
+
513
+ // Min/Max Axis Values
514
+ xMin: null,
515
+ xMax: null,
516
+ yMin: null,
517
+ yMax: null,
518
+
519
+ // Pre-format input data
520
+ dataFormatX: function (x) { return x; },
521
+ dataFormatY: function (y) { return y; },
522
+
523
+ unsupported: function (selector) {
524
+ d3.select(selector).text('SVG is not supported on your browser');
525
+ },
526
+
527
+ // Callback functions if no data
528
+ empty: function (self, selector, d) {},
529
+ notempty: function (self, selector) {},
530
+
531
+ timing: 750,
532
+
533
+ // Line interpolation
534
+ interpolation: 'monotone',
535
+
536
+ // Data sorting
537
+ sortX: function (a, b) {
538
+ return (!a.x && !b.x) ? 0 : (a.x < b.x) ? -1 : 1;
539
+ }
540
+ };
541
+
542
+ // What/how should the warning/error be presented?
543
+ function svgEnabled() {
544
+ var d = document;
545
+ return (!!d.createElementNS &&
546
+ !!d.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect);
547
+ }
548
+
549
+ /**
550
+ * Creates a new chart
551
+ *
552
+ * @param string type The drawing type for the main data
553
+ * @param array data Data to render in the chart
554
+ * @param string selector CSS Selector for the parent element for the chart
555
+ * @param object options Optional. See `defaults` for options
556
+ *
557
+ * Examples:
558
+ * var data = {
559
+ * "main": [
560
+ * {
561
+ * "data": [
562
+ * {
563
+ * "x": "2012-08-09T07:00:00.522Z",
564
+ * "y": 68
565
+ * },
566
+ * {
567
+ * "x": "2012-08-10T07:00:00.522Z",
568
+ * "y": 295
569
+ * },
570
+ * {
571
+ * "x": "2012-08-11T07:00:00.522Z",
572
+ * "y": 339
573
+ * },
574
+ * ],
575
+ * "className": ".foo"
576
+ * }
577
+ * ],
578
+ * "xScale": "ordinal",
579
+ * "yScale": "linear",
580
+ * "comp": [
581
+ * {
582
+ * "data": [
583
+ * {
584
+ * "x": "2012-08-09T07:00:00.522Z",
585
+ * "y": 288
586
+ * },
587
+ * {
588
+ * "x": "2012-08-10T07:00:00.522Z",
589
+ * "y": 407
590
+ * },
591
+ * {
592
+ * "x": "2012-08-11T07:00:00.522Z",
593
+ * "y": 459
594
+ * }
595
+ * ],
596
+ * "className": ".comp.comp_foo",
597
+ * "type": "line-arrowed"
598
+ * }
599
+ * ]
600
+ * },
601
+ * myChart = new Chart('bar', data, '#chart');
602
+ *
603
+ */
604
+ function xChart(type, data, selector, options) {
605
+ var self = this,
606
+ resizeLock;
607
+
608
+ self._options = options = _.defaults(options || {}, defaults);
609
+
610
+ if (svgEnabled() === false) {
611
+ return options.unsupported(selector);
612
+ }
613
+
614
+ self._selector = selector;
615
+ self._container = d3.select(selector);
616
+ self._drawSvg();
617
+ self._mainStorage = {};
618
+ self._compStorage = {};
619
+
620
+ data = _.clone(data);
621
+ if (type && !data.type) {
622
+ data.type = type;
623
+ }
624
+
625
+ self.setData(data);
626
+
627
+ d3.select(window).on('resize.for.' + selector, function () {
628
+ if (resizeLock) {
629
+ clearTimeout(resizeLock);
630
+ }
631
+ resizeLock = setTimeout(function () {
632
+ resizeLock = null;
633
+ self._resize();
634
+ }, 500);
635
+ });
636
+ }
637
+
638
+ /**
639
+ * Add a visualization type
640
+ *
641
+ * @param string type Unique key/name used with setType
642
+ * @param object vis object map of vis methods
643
+ */
644
+ xChart.setVis = function (type, vis) {
645
+ if (_vis.hasOwnProperty(type)) {
646
+ throw 'Cannot override vis type "' + type + '".';
647
+ }
648
+ _vis[type] = vis;
649
+ };
650
+
651
+ /**
652
+ * Get a clone of a visualization
653
+ * Useful for extending vis functionality
654
+ *
655
+ * @param string type Unique key/name of the vis
656
+ */
657
+ xChart.getVis = function (type) {
658
+ if (!_vis.hasOwnProperty(type)) {
659
+ throw 'Vis type "' + type + '" does not exist.';
660
+ }
661
+
662
+ return _.clone(_vis[type]);
663
+ };
664
+
665
+ xChart.setScale = function (name, fn) {
666
+ if (_scales.hasOwnProperty(name)) {
667
+ throw 'Scale type "' + name + '" already exists.';
668
+ }
669
+
670
+ _scales[name] = fn;
671
+ };
672
+
673
+ xChart.getScale = function (name) {
674
+ if (!_scales.hasOwnProperty(name)) {
675
+ throw 'Scale type "' + name + '" does not exist.';
676
+ }
677
+ return _scales[name];
678
+ };
679
+
680
+ xChart.visutils = _visutils;
681
+
682
+ _.defaults(xChart.prototype, {
683
+ /**
684
+ * Set or change the drawing type for the main data.
685
+ *
686
+ * @param string type Must be an available drawing type
687
+ *
688
+ */
689
+ setType: function (type, skipDraw) {
690
+ var self = this;
691
+
692
+ if (self._type && type === self._type) {
693
+ return;
694
+ }
695
+
696
+ if (!_vis.hasOwnProperty(type)) {
697
+ throw 'Vis type "' + type + '" is not defined.';
698
+ }
699
+
700
+ if (self._type) {
701
+ self._destroy(self._vis, self._mainStorage);
702
+ }
703
+
704
+ self._type = type;
705
+ self._vis = _vis[type];
706
+ if (!skipDraw) {
707
+ self._draw();
708
+ }
709
+ },
710
+
711
+ /**
712
+ * Set and update the data for the chart. Optionally skip drawing.
713
+ *
714
+ * @param object data New data. See new xChart example for format
715
+ *
716
+ */
717
+ setData: function (data) {
718
+ var self = this,
719
+ o = self._options,
720
+ nData = _.clone(data);
721
+
722
+ if (!data.hasOwnProperty('main')) {
723
+ throw 'No "main" key found in given chart data.';
724
+ }
725
+
726
+ switch (data.type) {
727
+ case 'bar':
728
+ // force the xScale to be ordinal
729
+ data.xScale = 'ordinal';
730
+ break;
731
+ case undefined:
732
+ data.type = self._type;
733
+ break;
734
+ }
735
+
736
+ o.xMin = (isNaN(parseInt(data.xMin, 10))) ? o.xMin : data.xMin;
737
+ o.xMax = (isNaN(parseInt(data.xMax, 10))) ? o.xMax : data.xMax;
738
+ o.yMin = (isNaN(parseInt(data.yMin, 10))) ? o.yMin : data.yMin;
739
+ o.yMax = (isNaN(parseInt(data.yMax, 10))) ? o.yMax : data.yMax;
740
+
741
+ if (self._vis) {
742
+ self._destroy(self._vis, self._mainStorage);
743
+ }
744
+
745
+ self.setType(data.type, true);
746
+
747
+ function _mapData(set) {
748
+ var d = _.map(_.clone(set.data), function (p) {
749
+ var np = _.clone(p);
750
+ if (p.hasOwnProperty('x')) {
751
+ np.x = o.dataFormatX(p.x);
752
+ }
753
+ if (p.hasOwnProperty('y')) {
754
+ np.y = o.dataFormatY(p.y);
755
+ }
756
+ return np;
757
+ }).sort(o.sortX);
758
+ return _.extend(_.clone(set), { data: d });
759
+ }
760
+
761
+ nData.main = _.map(nData.main, _mapData);
762
+ self._mainData = nData.main;
763
+ self._xScaleType = nData.xScale;
764
+ self._yScaleType = nData.yScale;
765
+
766
+ if (nData.hasOwnProperty('comp')) {
767
+ nData.comp = _.map(nData.comp, _mapData);
768
+ self._compData = nData.comp;
769
+ } else {
770
+ self._compData = [];
771
+ }
772
+
773
+ self._draw();
774
+ },
775
+
776
+ /**
777
+ * Change the scale of an axis
778
+ *
779
+ * @param string axis Name of an axis. One of 'x' or 'y'
780
+ * @param string type Name of the scale type
781
+ *
782
+ */
783
+ setScale: function (axis, type) {
784
+ var self = this;
785
+
786
+ switch (axis) {
787
+ case 'x':
788
+ self._xScaleType = type;
789
+ break;
790
+ case 'y':
791
+ self._yScaleType = type;
792
+ break;
793
+ default:
794
+ throw 'Cannot change scale of unknown axis "' + axis + '".';
795
+ }
796
+
797
+ self._draw();
798
+ },
799
+
800
+ /**
801
+ * Create the SVG element and g container. Resize if necessary.
802
+ */
803
+ _drawSvg: function () {
804
+ var self = this,
805
+ c = self._container,
806
+ options = self._options,
807
+ width = parseInt(c.style('width').replace('px', ''), 10),
808
+ height = parseInt(c.style('height').replace('px', ''), 10),
809
+ svg,
810
+ g,
811
+ gScale;
812
+
813
+ svg = c.selectAll('svg')
814
+ .data(emptyData);
815
+
816
+ svg.enter().append('svg')
817
+ // Inherit the height and width from the parent element
818
+ .attr('height', height)
819
+ .attr('width', width)
820
+ .attr('class', 'xchart');
821
+
822
+ svg.transition()
823
+ .attr('width', width)
824
+ .attr('height', height);
825
+
826
+ g = svg.selectAll('g')
827
+ .data(emptyData);
828
+
829
+ g.enter().append('g')
830
+ .attr(
831
+ 'transform',
832
+ 'translate(' + options.paddingLeft + ',' + options.paddingTop + ')'
833
+ );
834
+
835
+ gScale = g.selectAll('g.scale')
836
+ .data(emptyData);
837
+
838
+ gScale.enter().append('g')
839
+ .attr('class', 'scale');
840
+
841
+ self._svg = svg;
842
+ self._g = g;
843
+ self._gScale = gScale;
844
+
845
+ self._height = height - options.paddingTop - options.paddingBottom -
846
+ options.axisPaddingTop - options.axisPaddingBottom;
847
+ self._width = width - options.paddingLeft - options.paddingRight -
848
+ options.axisPaddingLeft - options.axisPaddingRight;
849
+ },
850
+
851
+ /**
852
+ * Resize the visualization
853
+ */
854
+ _resize: function (event) {
855
+ var self = this;
856
+
857
+ self._drawSvg();
858
+ self._draw();
859
+ },
860
+
861
+ /**
862
+ * Draw the x and y axes
863
+ */
864
+ _drawAxes: function () {
865
+ if (this._noData) {
866
+ return;
867
+ }
868
+ var self = this,
869
+ o = self._options,
870
+ t = self._gScale.transition().duration(o.timing),
871
+ xTicks = o.tickHintX,
872
+ yTicks = o.tickHintY,
873
+ bottom = self._height + o.axisPaddingTop + o.axisPaddingBottom,
874
+ zeroLine = d3.svg.line().x(function (d) { return d; }),
875
+ zLine,
876
+ zLinePath,
877
+ xAxis,
878
+ xRules,
879
+ yAxis,
880
+ yRules,
881
+ labels;
882
+
883
+ xRules = d3.svg.axis()
884
+ .scale(self.xScale)
885
+ .ticks(xTicks)
886
+ .tickSize(-self._height)
887
+ .tickFormat(o.tickFormatX)
888
+ .orient('bottom');
889
+
890
+ xAxis = self._gScale.selectAll('g.axisX')
891
+ .data(emptyData);
892
+
893
+ xAxis.enter().append('g')
894
+ .attr('class', 'axis axisX')
895
+ .attr('transform', 'translate(0,' + bottom + ')');
896
+
897
+ xAxis.call(xRules);
898
+
899
+ labels = self._gScale.selectAll('.axisX g')[0];
900
+ if (labels.length > (self._width / 80)) {
901
+ labels.sort(function (a, b) {
902
+ var r = /translate\(([^,)]+)/;
903
+ a = a.getAttribute('transform').match(r);
904
+ b = b.getAttribute('transform').match(r);
905
+ return parseFloat(a[1], 10) - parseFloat(b[1], 10);
906
+ });
907
+
908
+ d3.selectAll(labels)
909
+ .filter(function (d, i) {
910
+ return i % (Math.ceil(labels.length / xTicks) + 1);
911
+ })
912
+ .remove();
913
+ }
914
+
915
+ yRules = d3.svg.axis()
916
+ .scale(self.yScale)
917
+ .ticks(yTicks)
918
+ .tickSize(-self._width - o.axisPaddingRight - o.axisPaddingLeft)
919
+ .tickFormat(o.tickFormatY)
920
+ .orient('left');
921
+
922
+ yAxis = self._gScale.selectAll('g.axisY')
923
+ .data(emptyData);
924
+
925
+ yAxis.enter().append('g')
926
+ .attr('class', 'axis axisY')
927
+ .attr('transform', 'translate(0,0)');
928
+
929
+ t.selectAll('g.axisY')
930
+ .call(yRules);
931
+
932
+ // zero line
933
+ zLine = self._gScale.selectAll('g.axisZero')
934
+ .data([[]]);
935
+
936
+ zLine.enter().append('g')
937
+ .attr('class', 'axisZero');
938
+
939
+ zLinePath = zLine.selectAll('line')
940
+ .data([[]]);
941
+
942
+ zLinePath.enter().append('line')
943
+ .attr('x1', 0)
944
+ .attr('x2', self._width + o.axisPaddingLeft + o.axisPaddingRight)
945
+ .attr('y1', self.yZero)
946
+ .attr('y2', self.yZero);
947
+
948
+ zLinePath.transition().duration(o.timing)
949
+ .attr('y1', self.yZero)
950
+ .attr('y2', self.yZero);
951
+ },
952
+
953
+ /**
954
+ * Update the x and y scales (used when drawing)
955
+ *
956
+ * Optional methods in drawing types:
957
+ * preUpdateScale
958
+ * postUpdateScale
959
+ *
960
+ * Example implementation in vis type:
961
+ *
962
+ * function postUpdateScale(self, scaleData, mainData, compData) {
963
+ * self.xScale2 = d3.scale.ordinal()
964
+ * .domain(d3.range(0, mainData.length))
965
+ * .rangeRoundBands([0, self.xScale.rangeBand()], 0.08);
966
+ * }
967
+ *
968
+ */
969
+ _updateScale: function () {
970
+ var self = this,
971
+ _unionData = function () {
972
+ return _.union(self._mainData, self._compData);
973
+ },
974
+ scaleData = _unionData(),
975
+ vis = self._vis,
976
+ scale,
977
+ min;
978
+
979
+ delete self.xScale;
980
+ delete self.yScale;
981
+ delete self.yZero;
982
+
983
+ if (vis.hasOwnProperty('preUpdateScale')) {
984
+ vis.preUpdateScale(self, scaleData, self._mainData, self._compData);
985
+ }
986
+
987
+ // Just in case preUpdateScale modified
988
+ scaleData = _unionData();
989
+ scale = _scales.xy(self, scaleData, self._xScaleType, self._yScaleType);
990
+
991
+ self.xScale = scale.x;
992
+ self.yScale = scale.y;
993
+
994
+ min = self.yScale.domain()[0];
995
+ self.yZero = (min > 0) ? self.yScale(min) : self.yScale(0);
996
+
997
+ if (vis.hasOwnProperty('postUpdateScale')) {
998
+ vis.postUpdateScale(self, scaleData, self._mainData, self._compData);
999
+ }
1000
+ },
1001
+
1002
+ /**
1003
+ * Create (Enter) the elements for the vis
1004
+ *
1005
+ * Required method
1006
+ *
1007
+ * Example implementation in vis type:
1008
+ *
1009
+ * function enter(self, data, callbacks) {
1010
+ * var foo = self._g.selectAll('g.foobar')
1011
+ * .data(data);
1012
+ * foo.enter().append('g')
1013
+ * .attr('class', 'foobar');
1014
+ * self.foo = foo;
1015
+ * }
1016
+ */
1017
+ _enter: function (vis, storage, data, className) {
1018
+ var self = this,
1019
+ callbacks = {
1020
+ click: self._options.click,
1021
+ mouseover: self._options.mouseover,
1022
+ mouseout: self._options.mouseout
1023
+ };
1024
+ self._checkVisMethod(vis, 'enter');
1025
+ vis.enter(self, storage, className, data, callbacks);
1026
+ },
1027
+
1028
+ /**
1029
+ * Update the elements opened by the select method
1030
+ *
1031
+ * Required method
1032
+ *
1033
+ * Example implementation in vis type:
1034
+ *
1035
+ * function update(self, timing) {
1036
+ * self.bars.transition().duration(timing)
1037
+ * .attr('width', self.xScale2.rangeBand())
1038
+ * .attr('height', function (d) {
1039
+ * return self.yScale(d.y);
1040
+ * });
1041
+ * }
1042
+ */
1043
+ _update: function (vis, storage) {
1044
+ var self = this;
1045
+ self._checkVisMethod(vis, 'update');
1046
+ vis.update(self, storage, self._options.timing);
1047
+ },
1048
+
1049
+ /**
1050
+ * Remove or transition out the elements that no longer have data
1051
+ *
1052
+ * Required method
1053
+ *
1054
+ * Example implementation in vis type:
1055
+ *
1056
+ * function exit(self) {
1057
+ * self.bars.exit().remove();
1058
+ * }
1059
+ */
1060
+ _exit: function (vis, storage) {
1061
+ var self = this;
1062
+ self._checkVisMethod(vis, 'exit');
1063
+ vis.exit(self, storage, self._options.timing);
1064
+ },
1065
+
1066
+ /**
1067
+ * Destroy the current vis type (transition to new type)
1068
+ *
1069
+ * Required method
1070
+ *
1071
+ * Example implementation in vis type:
1072
+ *
1073
+ * function destroy(self, timing) {
1074
+ * self.bars.transition().duration(timing)
1075
+ * attr('height', 0);
1076
+ * delete self.bars;
1077
+ * }
1078
+ */
1079
+ _destroy: function (vis, storage) {
1080
+ var self = this;
1081
+ self._checkVisMethod(vis, 'destroy');
1082
+ try {
1083
+ vis.destroy(self, storage, self._options.timing);
1084
+ } catch (e) {}
1085
+ },
1086
+
1087
+ /**
1088
+ * Draw the visualization
1089
+ */
1090
+ _draw: function () {
1091
+ var self = this,
1092
+ o = self._options,
1093
+ comp,
1094
+ compKeys;
1095
+
1096
+ self._noData = _.flatten(_.pluck(self._mainData, 'data')
1097
+ .concat(_.pluck(self._compData, 'data'))).length === 0;
1098
+
1099
+ self._updateScale();
1100
+ self._drawAxes();
1101
+
1102
+ self._enter(self._vis, self._mainStorage, self._mainData, '.main');
1103
+ self._exit(self._vis, self._mainStorage);
1104
+ self._update(self._vis, self._mainStorage);
1105
+
1106
+ comp = _.chain(self._compData).groupBy(function (d) {
1107
+ return d.type;
1108
+ });
1109
+ compKeys = comp.keys();
1110
+
1111
+ // Find old comp vis items and remove any that no longer exist
1112
+ _.each(self._compStorage, function (d, key) {
1113
+ if (-1 === compKeys.indexOf(key).value()) {
1114
+ var vis = _vis[key];
1115
+ self._enter(vis, d, [], '.comp.' + key.replace(/\W+/g, ''));
1116
+ self._exit(vis, d);
1117
+ }
1118
+ });
1119
+
1120
+ comp.each(function (d, key) {
1121
+ var vis = _vis[key], storage;
1122
+ if (!self._compStorage.hasOwnProperty(key)) {
1123
+ self._compStorage[key] = {};
1124
+ }
1125
+ storage = self._compStorage[key];
1126
+ self._enter(vis, storage, d, '.comp.' + key.replace(/\W+/g, ''));
1127
+ self._exit(vis, storage);
1128
+ self._update(vis, storage);
1129
+ });
1130
+
1131
+ if (self._noData) {
1132
+ o.empty(self, self._selector, self._mainData);
1133
+ } else {
1134
+ o.notempty(self, self._selector);
1135
+ }
1136
+ },
1137
+
1138
+ /**
1139
+ * Ensure drawing method exists
1140
+ */
1141
+ _checkVisMethod: function (vis, method) {
1142
+ var self = this;
1143
+ if (!vis[method]) {
1144
+ throw 'Required method "' + method + '" not found on vis type "' +
1145
+ self._type + '".';
1146
+ }
1147
+ }
1148
+ });
1149
+ if (typeof define === 'function' && define.amd && typeof define.amd === 'object') {
1150
+ define(function () {
1151
+ return xChart;
1152
+ });
1153
+ return;
1154
+ }
1155
+
1156
+ window.xChart = xChart;
1157
+
1158
+ }());