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 +7 -0
- data/README.md +10 -0
- data/lib/xcharts_rails/version.rb +1 -1
- data/vendor/assets/javascripts/xcharts.js +1155 -2
- data/vendor/assets/stylesheets/xcharts.css +283 -1
- data/xcharts_rails.gemspec +2 -2
- metadata +10 -12
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,5 +1,1158 @@
|
|
1
1
|
/*!
|
2
|
-
xCharts v0.
|
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:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};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:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};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
|
+
}());
|