xcharts_rails 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }());