pyk 0.2.1 → 0.2.2

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Njk2OTBkYTkzMjA3MTUwYmQ4NjUwYjE1OTU2YmY2Y2UyNjkxMTU5NA==
4
+ MDM1ODViMDUyODQ2MzQ1N2I3NTEwNGViYWRmNzE4ZGYxMjAwNTA2Ng==
5
5
  data.tar.gz: !binary |-
6
- ZDA5ZGYxODIzYjhiNGEwZjQ2ZjhlYjY5NTcyZmY2ZjA5MDVhZjhkOQ==
6
+ MjFlYzM2NDUzYWNkZDk3ZmExOTA2NDgyZjE5Yzc3ZDk3MDI3Y2UwZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MzgxODZjZWU5YTk3ZjRlNzQxZjM2OGQxNzc3ZGViYjEzN2QyNzQ3YmZhOWM3
10
- ZDY2NWQ5ZTU2NTAwNDljYTJlOWRjOTdmMGRmNjg3MWRjYWQ2ZThmZmMwZTA5
11
- MTFlMWZkZjRlYzUzMGY5OGVlZDVlM2E1NzQ5YTFjMmEzNGU4NDk=
9
+ Y2YzYWViYTcxZjJjMDZkMDg3NGE2NDNlYzdjYzJlMTM0YzQ2YzZlZjdhYTEx
10
+ NmJhYWZkMjQ5ZjMyZWNlMWNkNGZmNGU3MTA4OWJkNDc0N2VmYzE4ZDNmNWM1
11
+ ZmNlZjg4MjU3NWZmM2Q4ZjEyZTlmZDU2NTkxMTI4MTI5M2JhOTg=
12
12
  data.tar.gz: !binary |-
13
- NDBlYzg0MmY5YzA2ZjczYzNlNzUxYTBkNTVlY2EzM2RhMDBjN2U4YTFhZmQw
14
- ZWUzZGQwZGQ3ZmE4NDM0NzlhYzcyMDY0YzllMTk2MWQ5MDhjZGEwNmY1OWY1
15
- ZmFlZGYzZmI4NzJhNTc2ZDNjNTRiMzhkZmM0ZjUzYjVhZTNjOGE=
13
+ YmZlZTBkMmQ2OWQ3ZDVmODAwNTUyNmE4NWM4OWY5ZjhmM2M3OTliNjM1Zjc5
14
+ N2ViYmIzYmI3ZjU5NDNhYzAxZDFlYjI3NzA1M2Y2OTAyN2VjZTBjMTQ3Nzgy
15
+ OWI2MDcwZWM4YWY3ZWQyMzFkOTcyN2ZiZDAzNmQ4NDBlOTNiNjk=
@@ -0,0 +1 @@
1
+ !function(r){function n(r){return r}function t(r,n){for(var t=0,e=n.length,u=Array(e);e>t;++t)u[t]=r[n[t]];return u}function e(r){function n(n,t,e,u){for(;u>e;){var f=e+u>>>1;r(n[f])<t?e=f+1:u=f}return e}function t(n,t,e,u){for(;u>e;){var f=e+u>>>1;t<r(n[f])?u=f:e=f+1}return e}return t.right=t,t.left=n,t}function u(r){function n(r,n,t){for(var u=t-n,f=(u>>>1)+1;--f>0;)e(r,f,u,n);return r}function t(r,n,t){for(var u,f=t-n;--f>0;)u=r[n],r[n]=r[n+f],r[n+f]=u,e(r,1,f,n);return r}function e(n,t,e,u){for(var f,o=n[--u+t],i=r(o);(f=t<<1)<=e&&(e>f&&r(n[u+f])>r(n[u+f+1])&&f++,!(i<=r(n[u+f])));)n[u+t]=n[u+f],t=f;n[u+t]=o}return n.sort=t,n}function f(r){function n(n,e,u,f){var o,i,a,c,l=Array(f=Math.min(u-e,f));for(i=0;f>i;++i)l[i]=n[e++];if(t(l,0,f),u>e){o=r(l[0]);do(a=r(c=n[e])>o)&&(l[0]=c,o=r(t(l,0,f)[0]));while(++e<u)}return l}var t=u(r);return n}function o(r){function n(n,t,e){for(var u=t+1;e>u;++u){for(var f=u,o=n[u],i=r(o);f>t&&r(n[f-1])>i;--f)n[f]=n[f-1];n[f]=o}return n}return n}function i(r){function n(r,n,u){return(U>u-n?e:t)(r,n,u)}function t(t,e,u){var f,o=0|(u-e)/6,i=e+o,a=u-1-o,c=e+u-1>>1,l=c-o,v=c+o,s=t[i],h=r(s),p=t[l],d=r(p),g=t[c],y=r(g),m=t[v],b=r(m),x=t[a],A=r(x);h>d&&(f=s,s=p,p=f,f=h,h=d,d=f),b>A&&(f=m,m=x,x=f,f=b,b=A,A=f),h>y&&(f=s,s=g,g=f,f=h,h=y,y=f),d>y&&(f=p,p=g,g=f,f=d,d=y,y=f),h>b&&(f=s,s=m,m=f,f=h,h=b,b=f),y>b&&(f=g,g=m,m=f,f=y,y=b,b=f),d>A&&(f=p,p=x,x=f,f=d,d=A,A=f),d>y&&(f=p,p=g,g=f,f=d,d=y,y=f),b>A&&(f=m,m=x,x=f,f=b,b=A,A=f);var k=p,O=d,E=m,w=b;t[i]=s,t[l]=t[e],t[c]=g,t[v]=t[u-1],t[a]=x;var M=e+1,U=u-2,z=w>=O&&O>=w;if(z)for(var N=M;U>=N;++N){var C=t[N],S=r(C);if(O>S)N!==M&&(t[N]=t[M],t[M]=C),++M;else if(S>O)for(;;){var q=r(t[U]);{if(!(q>O)){if(O>q){t[N]=t[M],t[M++]=t[U],t[U--]=C;break}t[N]=t[U],t[U--]=C;break}U--}}}else for(var N=M;U>=N;N++){var C=t[N],S=r(C);if(O>S)N!==M&&(t[N]=t[M],t[M]=C),++M;else if(S>w)for(;;){var q=r(t[U]);{if(!(q>w)){O>q?(t[N]=t[M],t[M++]=t[U],t[U--]=C):(t[N]=t[U],t[U--]=C);break}if(U--,N>U)break}}}if(t[e]=t[M-1],t[M-1]=k,t[u-1]=t[U+1],t[U+1]=E,n(t,e,M-1),n(t,U+2,u),z)return t;if(i>M&&U>a){for(var F,q;(F=r(t[M]))<=O&&F>=O;)++M;for(;(q=r(t[U]))<=w&&q>=w;)--U;for(var N=M;U>=N;N++){var C=t[N],S=r(C);if(O>=S&&S>=O)N!==M&&(t[N]=t[M],t[M]=C),M++;else if(w>=S&&S>=w)for(;;){var q=r(t[U]);{if(!(w>=q&&q>=w)){O>q?(t[N]=t[M],t[M++]=t[U],t[U--]=C):(t[N]=t[U],t[U--]=C);break}if(U--,N>U)break}}}}return n(t,M,U+1)}var e=o(r);return n}function a(r){return Array(r)}function c(r,n){return function(t){var e=t.length;return[r.left(t,n,0,e),r.right(t,n,0,e)]}}function l(r,n){var t=n[0],e=n[1];return function(n){var u=n.length;return[r.left(n,t,0,u),r.left(n,e,0,u)]}}function v(r){return[0,r.length]}function s(){return null}function h(){return 0}function p(r){return r+1}function d(r){return r-1}function g(r){return function(n,t){return n+ +r(t)}}function y(r){return function(n,t){return n-r(t)}}function m(){function r(r){var n=w,t=r.length;return t&&(E=E.concat(r),N=S(N,w+=t),F.forEach(function(e){e(r,n,t)})),O}function e(){for(var r=b(w,w),n=[],t=0,e=0;w>t;++t)N[t]?r[t]=e++:n.push(t);C.forEach(function(r){r(0,[],n)}),R.forEach(function(n){n(r)});for(var u,t=0,e=0;w>t;++t)(u=N[t])&&(t!==e&&(N[e]=u,E[e]=E[t]),++e);for(E.length=e;w>e;)N[--w]=0}function o(r){function e(n,e,u){T=n.map(r),V=$(x(u),0,u),T=t(T,V);var f,o=_(T),i=o[0],a=o[1];if(W)for(f=0;u>f;++f)W(T[f],f)||(N[V[f]+e]|=Y);else{for(f=0;i>f;++f)N[V[f]+e]|=Y;for(f=a;u>f;++f)N[V[f]+e]|=Y}if(!e)return P=T,Q=V,tn=i,en=a,void 0;var c=P,l=Q,v=0,s=0;for(P=Array(w),Q=b(w,w),f=0;e>v&&u>s;++f)c[v]<T[s]?(P[f]=c[v],Q[f]=l[v++]):(P[f]=T[s],Q[f]=V[s++]+e);for(;e>v;++v,++f)P[f]=c[v],Q[f]=l[v];for(;u>s;++s,++f)P[f]=T[s],Q[f]=V[s]+e;o=_(P),tn=o[0],en=o[1]}function o(r,n,t){rn.forEach(function(r){r(T,V,n,t)}),T=V=null}function a(r){for(var n,t=0,e=0;w>t;++t)N[n=Q[t]]&&(t!==e&&(P[e]=P[t]),Q[e]=r[n],++e);for(P.length=e;w>e;)Q[e++]=0;var u=_(P);tn=u[0],en=u[1]}function m(r){var n=r[0],t=r[1];if(W)return W=null,G(function(r,e){return e>=n&&t>e}),tn=n,en=t,X;var e,u,f,o=[],i=[];if(tn>n)for(e=n,u=Math.min(tn,t);u>e;++e)N[f=Q[e]]^=Y,o.push(f);else if(n>tn)for(e=tn,u=Math.min(n,en);u>e;++e)N[f=Q[e]]^=Y,i.push(f);if(t>en)for(e=Math.max(n,en),u=t;u>e;++e)N[f=Q[e]]^=Y,o.push(f);else if(en>t)for(e=Math.max(tn,t),u=en;u>e;++e)N[f=Q[e]]^=Y,i.push(f);return tn=n,en=t,C.forEach(function(r){r(Y,o,i)}),X}function O(r){return null==r?B():Array.isArray(r)?j(r):"function"==typeof r?D(r):z(r)}function z(r){return m((_=c(k,r))(P))}function j(r){return m((_=l(k,r))(P))}function B(){return m((_=v)(P))}function D(r){return _=v,G(W=r),tn=0,en=w,X}function G(r){var n,t,e,u=[],f=[];for(n=0;w>n;++n)!(N[t=Q[n]]&Y)^(e=r(P[n],n))&&(e?(N[t]&=Z,u.push(t)):(N[t]|=Y,f.push(t)));C.forEach(function(r){r(Y,u,f)})}function H(r){for(var n,t=[],e=en;--e>=tn&&r>0;)N[n=Q[e]]||(t.push(E[n]),--r);return t}function I(r){for(var n,t=[],e=tn;en>e&&r>0;)N[n=Q[e]]||(t.push(E[n]),--r),e++;return t}function J(r){function t(n,t,e,u){function f(){++T===L&&(m=q(m,K<<=1),B=q(B,K),L=A(K))}var l,v,h,p,d,g,y=j,m=b(T,L),x=H,k=J,O=T,M=0,U=0;for(X&&(x=k=s),j=Array(T),T=0,B=O>1?S(B,w):b(w,L),O&&(h=(v=y[0]).key);u>U&&!((p=r(n[U]))>=p);)++U;for(;u>U;){for(v&&p>=h?(d=v,g=h,m[M]=T,(v=y[++M])&&(h=v.key)):(d={key:p,value:k()},g=p),j[T]=d;!(p>g||(B[l=t[U]+e]=T,N[l]&Z||(d.value=x(d.value,E[l])),++U>=u));)p=r(n[U]);f()}for(;O>M;)j[m[M]=T]=y[M++],f();if(T>M)for(M=0;e>M;++M)B[M]=m[B[M]];l=C.indexOf(V),T>1?(V=o,W=a):(1===T?(V=i,W=c):(V=s,W=s),B=null),C[l]=V}function e(){if(T>1){for(var r=T,n=j,t=b(r,r),e=0,u=0;w>e;++e)N[e]&&(t[B[u]=B[e]]=1,++u);for(j=[],T=0,e=0;r>e;++e)t[e]&&(t[e]=T++,j.push(n[e]));if(T>1)for(var e=0;u>e;++e)B[e]=t[B[e]];else B=null;C[C.indexOf(V)]=T>1?(W=a,V=o):1===T?(W=c,V=i):W=V=s}else if(1===T){for(var e=0;w>e;++e)if(N[e])return;j=[],T=0,C[C.indexOf(V)]=V=W=s}}function o(r,n,t){if(r!==Y&&!X){var e,u,f,o;for(e=0,f=n.length;f>e;++e)N[u=n[e]]&Z||(o=j[B[u]],o.value=H(o.value,E[u]));for(e=0,f=t.length;f>e;++e)(N[u=t[e]]&Z)===r&&(o=j[B[u]],o.value=I(o.value,E[u]))}}function i(r,n,t){if(r!==Y&&!X){var e,u,f,o=j[0];for(e=0,f=n.length;f>e;++e)N[u=n[e]]&Z||(o.value=H(o.value,E[u]));for(e=0,f=t.length;f>e;++e)(N[u=t[e]]&Z)===r&&(o.value=I(o.value,E[u]))}}function a(){var r,n;for(r=0;T>r;++r)j[r].value=J();for(r=0;w>r;++r)N[r]&Z||(n=j[B[r]],n.value=H(n.value,E[r]))}function c(){var r,n=j[0];for(n.value=J(),r=0;w>r;++r)N[r]&Z||(n.value=H(n.value,E[r]))}function l(){return X&&(W(),X=!1),j}function v(r){var n=D(l(),0,j.length,r);return G.sort(n,0,n.length)}function m(r,n,t){return H=r,I=n,J=t,X=!0,F}function x(){return m(p,d,h)}function k(r){return m(g(r),y(r),h)}function O(r){function n(n){return r(n.value)}return D=f(n),G=u(n),F}function M(){return O(n)}function U(){return T}function z(){var r=C.indexOf(V);return r>=0&&C.splice(r,1),r=rn.indexOf(t),r>=0&&rn.splice(r,1),r=R.indexOf(e),r>=0&&R.splice(r,1),F}var F={top:v,all:l,reduce:m,reduceCount:x,reduceSum:k,order:O,orderNatural:M,size:U,dispose:z,remove:z};nn.push(F);var j,B,D,G,H,I,J,K=8,L=A(K),T=0,V=s,W=s,X=!0;return arguments.length<1&&(r=n),C.push(V),rn.push(t),R.push(e),t(P,Q,0,w),x().orderNatural()}function K(){var r=J(s),n=r.all;return delete r.all,delete r.top,delete r.order,delete r.orderNatural,delete r.size,r.value=function(){return n()[0].value},r}function L(){nn.forEach(function(r){r.dispose()});var r=F.indexOf(e);for(r>=0&&F.splice(r,1),r=F.indexOf(o),r>=0&&F.splice(r,1),r=R.indexOf(a),r>=0&&R.splice(r,1),r=0;w>r;++r)N[r]&=Z;return M&=Z,X}var P,Q,T,V,W,X={filter:O,filterExact:z,filterRange:j,filterFunction:D,filterAll:B,top:H,bottom:I,group:J,groupAll:K,dispose:L,remove:L},Y=~M&-~M,Z=~Y,$=i(function(r){return T[r]}),_=v,rn=[],nn=[],tn=0,en=0;return F.unshift(e),F.push(o),R.push(a),M|=Y,(U>=32?!Y:M&(1<<U)-1)&&(N=q(N,U<<=1)),e(E,0,w),o(E,0,w),X}function a(){function r(r,n){var t;if(!m)for(t=n;w>t;++t)N[t]||(a=c(a,E[t]))}function n(r,n,t){var e,u,f;if(!m){for(e=0,f=n.length;f>e;++e)N[u=n[e]]||(a=c(a,E[u]));for(e=0,f=t.length;f>e;++e)N[u=t[e]]===r&&(a=l(a,E[u]))}}function t(){var r;for(a=v(),r=0;w>r;++r)N[r]||(a=c(a,E[r]))}function e(r,n,t){return c=r,l=n,v=t,m=!0,s}function u(){return e(p,d,h)}function f(r){return e(g(r),y(r),h)}function o(){return m&&(t(),m=!1),a}function i(){var t=C.indexOf(n);return t>=0&&C.splice(t),t=F.indexOf(r),t>=0&&F.splice(t),s}var a,c,l,v,s={reduce:e,reduceCount:u,reduceSum:f,value:o,dispose:i,remove:i},m=!0;return C.push(n),F.push(r),r(E,0,w),u()}function m(){return w}var O={add:r,remove:e,dimension:o,groupAll:a,size:m},E=[],w=0,M=0,U=8,N=z(0),C=[],F=[],R=[];return arguments.length?r(arguments[0]):O}function b(r,n){return(257>n?z:65537>n?N:C)(r)}function x(r){for(var n=b(r,r),t=-1;++t<r;)n[t]=t;return n}function A(r){return 8===r?256:16===r?65536:4294967296}m.version="1.3.5",m.permute=t;var k=m.bisect=e(n);k.by=e;var O=m.heap=u(n);O.by=u;var E=m.heapselect=f(n);E.by=f;var w=m.insertionsort=o(n);w.by=o;var M=m.quicksort=i(n);M.by=i;var U=32,z=a,N=a,C=a,S=n,q=n;"undefined"!=typeof Uint8Array&&(z=function(r){return new Uint8Array(r)},N=function(r){return new Uint16Array(r)},C=function(r){return new Uint32Array(r)},S=function(r,n){if(r.length>=n)return r;var t=new r.constructor(n);return t.set(r),t},q=function(r,n){var t;switch(n){case 16:t=N(r.length);break;case 32:t=C(r.length);break;default:throw Error("invalid array width!")}return t.set(r),t}),r.crossfilter=m}(this);
@@ -0,0 +1,4078 @@
1
+ /*!
2
+ * dc 1.6.0-dev
3
+ * http://nickqizhu.github.io/dc.js/
4
+ * Copyright 2012 Nick Zhu and other contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+
20
+ dc = (function(){
21
+ 'use strict';
22
+
23
+ var dc = {
24
+ version: "1.6.0-dev",
25
+ constants: {
26
+ CHART_CLASS: "dc-chart",
27
+ DEBUG_GROUP_CLASS: "debug",
28
+ STACK_CLASS: "stack",
29
+ DESELECTED_CLASS: "deselected",
30
+ SELECTED_CLASS: "selected",
31
+ NODE_INDEX_NAME: "__index__",
32
+ GROUP_INDEX_NAME: "__group_index__",
33
+ DEFAULT_CHART_GROUP: "__default_chart_group__",
34
+ EVENT_DELAY: 40,
35
+ NEGLIGIBLE_NUMBER: 1e-10
36
+ },
37
+ _renderlet: null
38
+ };
39
+
40
+ dc.chartRegistry = function() {
41
+ // chartGroup:string => charts:array
42
+ var _chartMap = {};
43
+
44
+ function initializeChartGroup(group) {
45
+ if (!group)
46
+ group = dc.constants.DEFAULT_CHART_GROUP;
47
+
48
+ if (!_chartMap[group])
49
+ _chartMap[group] = [];
50
+
51
+ return group;
52
+ }
53
+
54
+ return {
55
+ has: function(chart) {
56
+ for (var e in _chartMap) {
57
+ if (_chartMap[e].indexOf(chart) >= 0)
58
+ return true;
59
+ }
60
+ return false;
61
+ },
62
+
63
+ register: function(chart, group) {
64
+ group = initializeChartGroup(group);
65
+ _chartMap[group].push(chart);
66
+ },
67
+
68
+ clear: function() {
69
+ _chartMap = {};
70
+ },
71
+
72
+ list: function(group) {
73
+ group = initializeChartGroup(group);
74
+ return _chartMap[group];
75
+ }
76
+ };
77
+ }();
78
+
79
+ dc.registerChart = function(chart, group) {
80
+ dc.chartRegistry.register(chart, group);
81
+ };
82
+
83
+ dc.hasChart = function(chart) {
84
+ return dc.chartRegistry.has(chart);
85
+ };
86
+
87
+ dc.deregisterAllCharts = function() {
88
+ dc.chartRegistry.clear();
89
+ };
90
+
91
+ dc.filterAll = function(group) {
92
+ var charts = dc.chartRegistry.list(group);
93
+ for (var i = 0; i < charts.length; ++i) {
94
+ charts[i].filterAll();
95
+ }
96
+ };
97
+
98
+ dc.renderAll = function(group) {
99
+ var charts = dc.chartRegistry.list(group);
100
+ for (var i = 0; i < charts.length; ++i) {
101
+ charts[i].render();
102
+ }
103
+
104
+ if(dc._renderlet !== null)
105
+ dc._renderlet(group);
106
+ };
107
+
108
+ dc.redrawAll = function(group) {
109
+ var charts = dc.chartRegistry.list(group);
110
+ for (var i = 0; i < charts.length; ++i) {
111
+ charts[i].redraw();
112
+ }
113
+
114
+ if(dc._renderlet !== null)
115
+ dc._renderlet(group);
116
+ };
117
+
118
+ dc.transition = function(selections, duration, callback) {
119
+ if (duration <= 0 || duration === undefined)
120
+ return selections;
121
+
122
+ var s = selections
123
+ .transition()
124
+ .duration(duration);
125
+
126
+ if (callback instanceof Function) {
127
+ callback(s);
128
+ }
129
+
130
+ return s;
131
+ };
132
+
133
+ dc.units = {};
134
+ dc.units.integers = function(s, e) {
135
+ return Math.abs(e - s);
136
+ };
137
+
138
+ dc.units.ordinal = function(s, e, domain){
139
+ return domain;
140
+ };
141
+ dc.units.fp = {};
142
+ dc.units.fp.precision = function(precision){
143
+ var _f = function(s, e){return Math.ceil(Math.abs((e-s)/_f.resolution));};
144
+ _f.resolution = precision;
145
+ return _f;
146
+ };
147
+
148
+ dc.round = {};
149
+ dc.round.floor = function(n) {
150
+ return Math.floor(n);
151
+ };
152
+ dc.round.ceil = function(n) {
153
+ return Math.ceil(n);
154
+ };
155
+ dc.round.round = function(n) {
156
+ return Math.round(n);
157
+ };
158
+
159
+ dc.override = function(obj, functionName, newFunction) {
160
+ var existingFunction = obj[functionName];
161
+ obj["_" + functionName] = existingFunction;
162
+ obj[functionName] = newFunction;
163
+ };
164
+
165
+ dc.renderlet = function(_){
166
+ if(!arguments.length) return dc._renderlet;
167
+ dc._renderlet = _;
168
+ return dc;
169
+ };
170
+
171
+ dc.instanceOfChart = function (o) {
172
+ return o instanceof Object && o.__dc_flag__;
173
+ };
174
+
175
+ dc.errors = {};
176
+
177
+ dc.errors.Exception = function(msg) {
178
+ var _msg = msg !== undefined ? msg : "Unexpected internal error";
179
+
180
+ this.message = _msg;
181
+
182
+ this.toString = function(){
183
+ return _msg;
184
+ };
185
+ };
186
+
187
+ dc.errors.InvalidStateException = function() {
188
+ dc.errors.Exception.apply(this, arguments);
189
+ };
190
+
191
+ dc.dateFormat = d3.time.format("%m/%d/%Y");
192
+
193
+ dc.printers = {};
194
+
195
+ dc.printers.filters = function (filters) {
196
+ var s = "";
197
+
198
+ for (var i = 0; i < filters.length; ++i) {
199
+ if (i > 0) s += ", ";
200
+ s += dc.printers.filter(filters[i]);
201
+ }
202
+
203
+ return s;
204
+ };
205
+
206
+ dc.printers.filter = function (filter) {
207
+ var s = "";
208
+
209
+ if (filter) {
210
+ if (filter instanceof Array) {
211
+ if (filter.length >= 2)
212
+ s = "[" + dc.utils.printSingleValue(filter[0]) + " -> " + dc.utils.printSingleValue(filter[1]) + "]";
213
+ else if (filter.length >= 1)
214
+ s = dc.utils.printSingleValue(filter[0]);
215
+ } else {
216
+ s = dc.utils.printSingleValue(filter);
217
+ }
218
+ }
219
+
220
+ return s;
221
+ };
222
+
223
+ dc.utils = {};
224
+
225
+ dc.utils.printSingleValue = function (filter) {
226
+ var s = "" + filter;
227
+
228
+ if (filter instanceof Date)
229
+ s = dc.dateFormat(filter);
230
+ else if (typeof(filter) == "string")
231
+ s = filter;
232
+ else if (dc.utils.isFloat(filter))
233
+ s = dc.utils.printSingleValue.fformat(filter);
234
+ else if (dc.utils.isInteger(filter))
235
+ s = Math.round(filter);
236
+
237
+ return s;
238
+ };
239
+ dc.utils.printSingleValue.fformat = d3.format(".2f");
240
+
241
+ dc.utils.add = function (l, r) {
242
+ if (typeof r === "string")
243
+ r = r.replace("%", "");
244
+
245
+ if (l instanceof Date) {
246
+ if (typeof r === "string") r = +r;
247
+ var d = new Date();
248
+ d.setTime(l.getTime());
249
+ d.setDate(l.getDate() + r);
250
+ return d;
251
+ } else if (typeof r === "string") {
252
+ var percentage = (+r / 100);
253
+ return l > 0 ? l * (1 + percentage) : l * (1 - percentage);
254
+ } else {
255
+ return l + r;
256
+ }
257
+ };
258
+
259
+ dc.utils.subtract = function (l, r) {
260
+ if (typeof r === "string")
261
+ r = r.replace("%", "");
262
+
263
+ if (l instanceof Date) {
264
+ if (typeof r === "string") r = +r;
265
+ var d = new Date();
266
+ d.setTime(l.getTime());
267
+ d.setDate(l.getDate() - r);
268
+ return d;
269
+ } else if (typeof r === "string") {
270
+ var percentage = (+r / 100);
271
+ return l < 0 ? l * (1 + percentage) : l * (1 - percentage);
272
+ } else {
273
+ return l - r;
274
+ }
275
+ };
276
+
277
+ dc.utils.GroupStack = function () {
278
+ var _dataLayers = [[ ]];
279
+ var _groups = [];
280
+ var _defaultAccessor;
281
+
282
+ function initializeDataLayer(i) {
283
+ if (!_dataLayers[i])
284
+ _dataLayers[i] = [];
285
+ }
286
+
287
+ this.setDataPoint = function (layerIndex, pointIndex, data) {
288
+ initializeDataLayer(layerIndex);
289
+ _dataLayers[layerIndex][pointIndex] = data;
290
+ };
291
+
292
+ this.getDataPoint = function (x, y) {
293
+ initializeDataLayer(x);
294
+ var dataPoint = _dataLayers[x][y];
295
+ if (dataPoint === undefined)
296
+ dataPoint = 0;
297
+ return dataPoint;
298
+ };
299
+
300
+ this.addGroup = function (group, accessor) {
301
+ if (!accessor)
302
+ accessor = _defaultAccessor;
303
+ _groups.push([group, accessor]);
304
+ return _groups.length - 1;
305
+ };
306
+
307
+ this.getGroupByIndex = function (index) {
308
+ return _groups[index][0];
309
+ };
310
+
311
+ this.getAccessorByIndex = function (index) {
312
+ return _groups[index][1];
313
+ };
314
+
315
+ this.size = function () {
316
+ return _groups.length;
317
+ };
318
+
319
+ this.clear = function () {
320
+ _dataLayers = [];
321
+ _groups = [];
322
+ };
323
+
324
+ this.setDefaultAccessor = function (retriever) {
325
+ _defaultAccessor = retriever;
326
+ };
327
+
328
+ this.getDataLayers = function () {
329
+ return _dataLayers;
330
+ };
331
+
332
+ this.toLayers = function () {
333
+ var layers = [];
334
+
335
+ for (var i = 0; i < _dataLayers.length; ++i) {
336
+ var layer = {index: i, points: []};
337
+ var dataPoints = _dataLayers[i];
338
+
339
+ for (var j = 0; j < dataPoints.length; ++j)
340
+ layer.points.push(dataPoints[j]);
341
+
342
+ layers.push(layer);
343
+ }
344
+
345
+ return layers;
346
+ };
347
+ };
348
+
349
+ dc.utils.isNumber = function(n) {
350
+ return n===+n;
351
+ };
352
+
353
+ dc.utils.isFloat = function (n) {
354
+ return n===+n && n!==(n|0);
355
+ };
356
+
357
+ dc.utils.isInteger = function (n) {
358
+ return n===+n && n===(n|0);
359
+ };
360
+
361
+ dc.utils.isNegligible = function (max) {
362
+ return max === undefined || (max < dc.constants.NEGLIGIBLE_NUMBER && max > -dc.constants.NEGLIGIBLE_NUMBER);
363
+ };
364
+
365
+ dc.utils.groupMax = function (group, accessor) {
366
+ var max = d3.max(group.all(), function (e) {
367
+ return accessor(e);
368
+ });
369
+ if (dc.utils.isNegligible(max)) max = 0;
370
+ return max;
371
+ };
372
+
373
+ dc.utils.groupMin = function (group, accessor) {
374
+ var min = d3.min(group.all(), function (e) {
375
+ return accessor(e);
376
+ });
377
+ if (dc.utils.isNegligible(min)) min = 0;
378
+ return min;
379
+ };
380
+
381
+ dc.utils.nameToId = function (name) {
382
+ return name.toLowerCase().replace(/[\s]/g, "_").replace(/[\.']/g, "");
383
+ };
384
+
385
+ dc.utils.appendOrSelect = function (parent, name) {
386
+ var element = parent.select(name);
387
+ if (element.empty()) element = parent.append(name);
388
+ return element;
389
+ };
390
+
391
+ dc.utils.createLegendable = function (chart, group, index, accessor) {
392
+ var legendable = {name: chart.getGroupName(group, accessor), data: group};
393
+ if (typeof chart.colors === 'function') legendable.color = chart.colors()(index);
394
+ return legendable;
395
+ };
396
+
397
+ dc.utils.safeNumber = function(n){return dc.utils.isNumber(+n)?+n:0;};
398
+
399
+ dc.events = {
400
+ current: null
401
+ };
402
+
403
+ dc.events.trigger = function(closure, delay) {
404
+ if (!delay){
405
+ closure();
406
+ return;
407
+ }
408
+
409
+ dc.events.current = closure;
410
+
411
+ setTimeout(function() {
412
+ if (closure == dc.events.current)
413
+ closure();
414
+ }, delay);
415
+ };
416
+
417
+ dc.cumulative = {};
418
+
419
+ dc.cumulative.Base = function() {
420
+ this._keyIndex = [];
421
+ this._map = {};
422
+
423
+ this.sanitizeKey = function(key) {
424
+ key = key + "";
425
+ return key;
426
+ };
427
+
428
+ this.clear = function() {
429
+ this._keyIndex = [];
430
+ this._map = {};
431
+ };
432
+
433
+ this.size = function() {
434
+ return this._keyIndex.length;
435
+ };
436
+
437
+ this.getValueByKey = function(key) {
438
+ key = this.sanitizeKey(key);
439
+ var value = this._map[key];
440
+ return value;
441
+ };
442
+
443
+ this.setValueByKey = function(key, value) {
444
+ key = this.sanitizeKey(key);
445
+ return this._map[key] = value;
446
+ };
447
+
448
+ this.indexOfKey = function(key) {
449
+ key = this.sanitizeKey(key);
450
+ return this._keyIndex.indexOf(key);
451
+ };
452
+
453
+ this.addToIndex = function(key) {
454
+ key = this.sanitizeKey(key);
455
+ this._keyIndex.push(key);
456
+ };
457
+
458
+ this.getKeyByIndex = function(index) {
459
+ return this._keyIndex[index];
460
+ };
461
+ };
462
+
463
+ dc.cumulative.Sum = function() {
464
+ dc.cumulative.Base.apply(this, arguments);
465
+
466
+ this.add = function(key, value) {
467
+ if (!value)
468
+ value = 0;
469
+
470
+ if (this.getValueByKey(key) === undefined) {
471
+ this.addToIndex(key);
472
+ this.setValueByKey(key, value);
473
+ } else {
474
+ this.setValueByKey(key, this.getValueByKey(key) + value);
475
+ }
476
+ };
477
+
478
+ this.minus = function(key, value) {
479
+ this.setValueByKey(key, this.getValueByKey(key) - value);
480
+ };
481
+
482
+ this.cumulativeSum = function(key) {
483
+ var keyIndex = this.indexOfKey(key);
484
+ if (keyIndex < 0) return 0;
485
+ var cumulativeValue = 0;
486
+ for (var i = 0; i <= keyIndex; ++i) {
487
+ var k = this.getKeyByIndex(i);
488
+ cumulativeValue += this.getValueByKey(k);
489
+ }
490
+ return cumulativeValue;
491
+ };
492
+ };
493
+ dc.cumulative.Sum.prototype = new dc.cumulative.Base();
494
+
495
+ dc.cumulative.CountUnique = function() {
496
+ dc.cumulative.Base.apply(this, arguments);
497
+
498
+ function hashSize(hash) {
499
+ var size = 0, key;
500
+ for (key in hash) {
501
+ if (hash.hasOwnProperty(key)) size++;
502
+ }
503
+ return size;
504
+ }
505
+
506
+ this.add = function(key, e) {
507
+ if (this.getValueByKey(key) === undefined) {
508
+ this.setValueByKey(key, {});
509
+ this.addToIndex(key);
510
+ }
511
+
512
+ if (e !== undefined) {
513
+ if (this.getValueByKey(key)[e] === undefined)
514
+ this.getValueByKey(key)[e] = 0;
515
+
516
+ this.getValueByKey(key)[e] += 1;
517
+ }
518
+ };
519
+
520
+ this.minus = function(key, e) {
521
+ this.getValueByKey(key)[e] -= 1;
522
+ if (this.getValueByKey(key)[e] <= 0)
523
+ delete this.getValueByKey(key)[e];
524
+ };
525
+
526
+ this.count = function(key) {
527
+ return hashSize(this.getValueByKey(key));
528
+ };
529
+
530
+ this.cumulativeCount = function(key) {
531
+ var keyIndex = this.indexOfKey(key);
532
+ if (keyIndex < 0) return 0;
533
+ var cumulativeCount = 0;
534
+ for (var i = 0; i <= keyIndex; ++i) {
535
+ var k = this.getKeyByIndex(i);
536
+ cumulativeCount += this.count(k);
537
+ }
538
+ return cumulativeCount;
539
+ };
540
+ };
541
+ dc.cumulative.CountUnique.prototype = new dc.cumulative.Base();
542
+
543
+ dc.baseChart = function (_chart) {
544
+ _chart.__dc_flag__ = true;
545
+
546
+ var _dimension;
547
+ var _group;
548
+
549
+ var _anchor;
550
+ var _root;
551
+ var _svg;
552
+
553
+ var _width = 200, _height = 200;
554
+
555
+ var _keyAccessor = function (d) {
556
+ return d.key;
557
+ };
558
+ var _valueAccessor = function (d) {
559
+ return d.value;
560
+ };
561
+ var _ordering = function (p) {
562
+ return p.key;
563
+ };
564
+
565
+ var _label = function (d) {
566
+ return d.key;
567
+ };
568
+ var _renderLabel = false;
569
+
570
+ var _title = function (d) {
571
+ return d.key + ": " + d.value;
572
+ };
573
+ var _renderTitle = false;
574
+
575
+ var _transitionDuration = 750;
576
+
577
+ var _filterPrinter = dc.printers.filters;
578
+
579
+ var _renderlets = [];
580
+
581
+ var _chartGroup = dc.constants.DEFAULT_CHART_GROUP;
582
+
583
+ var NULL_LISTENER = function (chart) {
584
+ };
585
+ var _listeners = {
586
+ preRender: NULL_LISTENER,
587
+ postRender: NULL_LISTENER,
588
+ preRedraw: NULL_LISTENER,
589
+ postRedraw: NULL_LISTENER,
590
+ filtered: NULL_LISTENER,
591
+ zoomed: NULL_LISTENER
592
+ };
593
+ var _legend;
594
+
595
+ var _filters = [];
596
+ var _filterHandler = function (dimension, filters) {
597
+ dimension.filter(null);
598
+
599
+ if (filters.length === 0)
600
+ dimension.filter(null);
601
+ else if (filters.length === 1)
602
+ dimension.filter(filters[0]);
603
+ else
604
+ dimension.filterFunction(function (d) {
605
+ return filters.indexOf(d) >= 0;
606
+ });
607
+
608
+ return filters;
609
+ };
610
+
611
+ _chart.width = function (w) {
612
+ if (!arguments.length) return _width;
613
+ _width = w;
614
+ return _chart;
615
+ };
616
+
617
+ _chart.height = function (h) {
618
+ if (!arguments.length) return _height;
619
+ _height = h;
620
+ return _chart;
621
+ };
622
+
623
+ _chart.dimension = function (d) {
624
+ if (!arguments.length) return _dimension;
625
+ _dimension = d;
626
+ _chart.expireCache();
627
+ return _chart;
628
+ };
629
+
630
+ _chart.group = function (g, name) {
631
+ if (!arguments.length) return _group;
632
+ _group = g;
633
+ _chart.expireCache();
634
+ if (typeof name === 'string') _chart.setGroupName(_group, name);
635
+ return _chart;
636
+ };
637
+
638
+ _chart.setGroupName = function (g, name, accessor) {
639
+ if (!g.__names__) g.__names__ = {};
640
+ g.__names__[groupNameKey(accessor)] = name;
641
+ };
642
+
643
+ function groupNameKey(accessor) {
644
+ var defaultKey = "default";
645
+ return accessor ? (accessor == _chart.valueAccessor() ? defaultKey : accessor) : defaultKey;
646
+ }
647
+
648
+ _chart.getGroupName = function (g, accessor) {
649
+ if (!g.__names__) g.__names__ = {};
650
+ return g.__names__[groupNameKey(accessor)];
651
+ };
652
+
653
+ _chart.ordering = function(o) {
654
+ if (!arguments.length) return _ordering;
655
+ _ordering = o;
656
+ _chart.expireCache();
657
+ return _chart;
658
+ };
659
+
660
+ _chart.computeOrderedGroups = function(arr) {
661
+ var data = arr ? arr : _chart.group().all().slice(0); // clone
662
+ if(data.length < 2)
663
+ return data;
664
+ var sort = crossfilter.quicksort.by(_chart.ordering());
665
+ return sort(data,0,data.length);
666
+ };
667
+
668
+ _chart.filterAll = function () {
669
+ return _chart.filter(null);
670
+ };
671
+
672
+ _chart.dataSet = function () {
673
+ return _dimension !== undefined && _group !== undefined;
674
+ };
675
+
676
+ _chart.select = function (s) {
677
+ return _root.select(s);
678
+ };
679
+
680
+ _chart.selectAll = function (s) {
681
+ return _root ? _root.selectAll(s) : null;
682
+ };
683
+
684
+ _chart.anchor = function (a, chartGroup) {
685
+ if (!arguments.length) return _anchor;
686
+ if (dc.instanceOfChart(a)) {
687
+ _anchor = a.anchor();
688
+ _root = a.root();
689
+ } else {
690
+ _anchor = a;
691
+ _root = d3.select(_anchor);
692
+ _root.classed(dc.constants.CHART_CLASS, true);
693
+ dc.registerChart(_chart, chartGroup);
694
+ }
695
+ _chartGroup = chartGroup;
696
+ return _chart;
697
+ };
698
+
699
+ _chart.anchorName = function () {
700
+ var a = _chart.anchor();
701
+ if (a && a.id) return a.id;
702
+ if (a) return a.replace('#','');
703
+ return '';
704
+ };
705
+
706
+ _chart.root = function (r) {
707
+ if (!arguments.length) return _root;
708
+ _root = r;
709
+ return _chart;
710
+ };
711
+
712
+ _chart.svg = function (_) {
713
+ if (!arguments.length) return _svg;
714
+ _svg = _;
715
+ return _chart;
716
+ };
717
+
718
+ _chart.resetSvg = function () {
719
+ _chart.select("svg").remove();
720
+ return _chart.generateSvg();
721
+ };
722
+
723
+ _chart.generateSvg = function () {
724
+ _svg = _chart.root().append("svg")
725
+ .attr("width", _chart.width())
726
+ .attr("height", _chart.height());
727
+ return _svg;
728
+ };
729
+
730
+ _chart.filterPrinter = function (_) {
731
+ if (!arguments.length) return _filterPrinter;
732
+ _filterPrinter = _;
733
+ return _chart;
734
+ };
735
+
736
+ _chart.turnOnControls = function () {
737
+ if (_root) {
738
+ _chart.selectAll(".reset").style("display", null);
739
+ _chart.selectAll(".filter").text(_filterPrinter(_chart.filters())).style("display", null);
740
+ }
741
+ return _chart;
742
+ };
743
+
744
+ _chart.turnOffControls = function () {
745
+ if (_root) {
746
+ _chart.selectAll(".reset").style("display", "none");
747
+ _chart.selectAll(".filter").style("display", "none").text(_chart.filter());
748
+ }
749
+ return _chart;
750
+ };
751
+
752
+ _chart.transitionDuration = function (d) {
753
+ if (!arguments.length) return _transitionDuration;
754
+ _transitionDuration = d;
755
+ return _chart;
756
+ };
757
+
758
+ _chart.render = function () {
759
+ _listeners.preRender(_chart);
760
+
761
+ if (_dimension === undefined)
762
+ throw new dc.errors.InvalidStateException("Mandatory attribute chart.dimension is missing on chart[#"
763
+ + _chart.anchorName() + "]");
764
+
765
+ if (_group === undefined)
766
+ throw new dc.errors.InvalidStateException("Mandatory attribute chart.group is missing on chart[#"
767
+ + _chart.anchorName() + "]");
768
+
769
+ var result = _chart.doRender();
770
+
771
+ if (_legend) _legend.render();
772
+
773
+ _chart.activateRenderlets("postRender");
774
+
775
+ return result;
776
+ };
777
+
778
+ _chart.activateRenderlets = function (event) {
779
+ if (_chart.transitionDuration() > 0 && _svg) {
780
+ _svg.transition().duration(_chart.transitionDuration())
781
+ .each("end", function () {
782
+ runAllRenderlets();
783
+ if (event) _listeners[event](_chart);
784
+ });
785
+ } else {
786
+ runAllRenderlets();
787
+ if (event) _listeners[event](_chart);
788
+ }
789
+ };
790
+
791
+ _chart.redraw = function () {
792
+ _listeners.preRedraw(_chart);
793
+
794
+ var result = _chart.doRedraw();
795
+
796
+ _chart.activateRenderlets("postRedraw");
797
+
798
+ return result;
799
+ };
800
+
801
+ _chart.invokeFilteredListener = function (f) {
802
+ if (f !== undefined) _listeners.filtered(_chart, f);
803
+ };
804
+
805
+ _chart.invokeZoomedListener = function () {
806
+ _listeners.zoomed(_chart);
807
+ };
808
+
809
+ _chart.hasFilter = function (filter) {
810
+ if (!arguments.length) return _filters.length > 0;
811
+ return _filters.indexOf(filter) >= 0;
812
+ };
813
+
814
+ function removeFilter(_) {
815
+ _filters.splice(_filters.indexOf(_), 1);
816
+ applyFilters();
817
+ _chart.invokeFilteredListener(_);
818
+ }
819
+
820
+ function addFilter(_) {
821
+ _filters.push(_);
822
+ applyFilters();
823
+ _chart.invokeFilteredListener(_);
824
+ }
825
+
826
+ function resetFilters() {
827
+ _filters = [];
828
+ applyFilters();
829
+ _chart.invokeFilteredListener(null);
830
+ }
831
+
832
+ function applyFilters() {
833
+ if (_chart.dataSet() && _chart.dimension().filter !== undefined) {
834
+ var fs = _filterHandler(_chart.dimension(), _filters);
835
+ _filters = fs ? fs : _filters;
836
+ }
837
+ }
838
+
839
+ _chart.filter = function (_) {
840
+ if (!arguments.length) return _filters.length > 0 ? _filters[0] : null;
841
+
842
+ if (_ === null) {
843
+ resetFilters();
844
+ } else {
845
+ if (_chart.hasFilter(_))
846
+ removeFilter(_);
847
+ else
848
+ addFilter(_);
849
+ }
850
+
851
+ if (_root !== null && _chart.hasFilter()) {
852
+ _chart.turnOnControls();
853
+ } else {
854
+ _chart.turnOffControls();
855
+ }
856
+
857
+ return _chart;
858
+ };
859
+
860
+ _chart.filters = function () {
861
+ return _filters;
862
+ };
863
+
864
+ _chart.highlightSelected = function (e) {
865
+ d3.select(e).classed(dc.constants.SELECTED_CLASS, true);
866
+ d3.select(e).classed(dc.constants.DESELECTED_CLASS, false);
867
+ };
868
+
869
+ _chart.fadeDeselected = function (e) {
870
+ d3.select(e).classed(dc.constants.SELECTED_CLASS, false);
871
+ d3.select(e).classed(dc.constants.DESELECTED_CLASS, true);
872
+ };
873
+
874
+ _chart.resetHighlight = function (e) {
875
+ d3.select(e).classed(dc.constants.SELECTED_CLASS, false);
876
+ d3.select(e).classed(dc.constants.DESELECTED_CLASS, false);
877
+ };
878
+
879
+ _chart.onClick = function (d) {
880
+ var filter = _chart.keyAccessor()(d);
881
+ dc.events.trigger(function () {
882
+ _chart.filter(filter);
883
+ dc.redrawAll(_chart.chartGroup());
884
+ });
885
+ };
886
+
887
+ _chart.filterHandler = function (_) {
888
+ if (!arguments.length) return _filterHandler;
889
+ _filterHandler = _;
890
+ return _chart;
891
+ };
892
+
893
+ // abstract function stub
894
+ _chart.doRender = function () {
895
+ // do nothing in base, should be overridden by sub-function
896
+ return _chart;
897
+ };
898
+
899
+ _chart.doRedraw = function () {
900
+ // do nothing in base, should be overridden by sub-function
901
+ return _chart;
902
+ };
903
+
904
+ _chart.legendables = function () {
905
+ // do nothing in base, should be overridden by sub-function
906
+ return [];
907
+ };
908
+
909
+ _chart.legendHighlight = function (d) {
910
+ // do nothing in base, should be overridden by sub-function
911
+ };
912
+
913
+ _chart.legendReset = function (d) {
914
+ // do nothing in base, should be overridden by sub-function
915
+ };
916
+
917
+ _chart.keyAccessor = function (_) {
918
+ if (!arguments.length) return _keyAccessor;
919
+ _keyAccessor = _;
920
+ return _chart;
921
+ };
922
+
923
+ _chart.valueAccessor = function (_) {
924
+ if (!arguments.length) return _valueAccessor;
925
+ _valueAccessor = _;
926
+ return _chart;
927
+ };
928
+
929
+ _chart.label = function (_) {
930
+ if (!arguments.length) return _label;
931
+ _label = _;
932
+ _renderLabel = true;
933
+ return _chart;
934
+ };
935
+
936
+ _chart.renderLabel = function (_) {
937
+ if (!arguments.length) return _renderLabel;
938
+ _renderLabel = _;
939
+ return _chart;
940
+ };
941
+
942
+ _chart.title = function (_) {
943
+ if (!arguments.length) return _title;
944
+ _title = _;
945
+ _renderTitle = true;
946
+ return _chart;
947
+ };
948
+
949
+ _chart.renderTitle = function (_) {
950
+ if (!arguments.length) return _renderTitle;
951
+ _renderTitle = _;
952
+ return _chart;
953
+ };
954
+
955
+ _chart.renderlet = function (_) {
956
+ _renderlets.push(_);
957
+ return _chart;
958
+ };
959
+
960
+ function runAllRenderlets() {
961
+ for (var i = 0; i < _renderlets.length; ++i) {
962
+ _renderlets[i](_chart);
963
+ }
964
+ }
965
+
966
+ _chart.chartGroup = function (_) {
967
+ if (!arguments.length) return _chartGroup;
968
+ _chartGroup = _;
969
+ return _chart;
970
+ };
971
+
972
+ _chart.on = function (event, listener) {
973
+ _listeners[event] = listener;
974
+ return _chart;
975
+ };
976
+
977
+ _chart.expireCache = function () {
978
+ // do nothing in base, should be overridden by sub-function
979
+ return _chart;
980
+ };
981
+
982
+ _chart.legend = function (l) {
983
+ if (!arguments.length) return _legend;
984
+ _legend = l;
985
+ _legend.parent(_chart);
986
+ return _chart;
987
+ };
988
+
989
+ return _chart;
990
+ };
991
+
992
+ dc.marginable = function (_chart) {
993
+ var _margin = {top: 10, right: 50, bottom: 30, left: 30};
994
+
995
+ _chart.margins = function (m) {
996
+ if (!arguments.length) return _margin;
997
+ _margin = m;
998
+ return _chart;
999
+ };
1000
+
1001
+ _chart.effectiveWidth = function () {
1002
+ return _chart.width() - _chart.margins().left - _chart.margins().right;
1003
+ };
1004
+
1005
+ _chart.effectiveHeight = function () {
1006
+ return _chart.height() - _chart.margins().top - _chart.margins().bottom;
1007
+ };
1008
+
1009
+ return _chart;
1010
+ };
1011
+
1012
+ dc.coordinateGridChart = function (_chart) {
1013
+ var GRID_LINE_CLASS = "grid-line";
1014
+ var HORIZONTAL_CLASS = "horizontal";
1015
+ var VERTICAL_CLASS = "vertical";
1016
+ var Y_AXIS_LABEL_CLASS = 'y-axis-label';
1017
+ var X_AXIS_LABEL_CLASS = 'x-axis-label';
1018
+ var DEFAULT_AXIS_LABLEL_PADDING = 12;
1019
+
1020
+ _chart = dc.colorChart(dc.marginable(dc.baseChart(_chart)));
1021
+
1022
+ _chart.colors(d3.scale.category10());
1023
+
1024
+ var _parent;
1025
+ var _g;
1026
+ var _chartBodyG;
1027
+
1028
+ var _x;
1029
+ var _xOriginalDomain;
1030
+ var _xAxis = d3.svg.axis();
1031
+ var _xUnits = dc.units.integers;
1032
+ var _xAxisPadding = 0;
1033
+ var _xElasticity = false;
1034
+ var _xAxisLabel;
1035
+ var _xAxisLabelPadding = 0;
1036
+
1037
+ var _y;
1038
+ var _yAxis = d3.svg.axis();
1039
+ var _yAxisPadding = 0;
1040
+ var _yElasticity = false;
1041
+ var _yAxisLabel;
1042
+ var _yAxisLabelPadding = 0;
1043
+
1044
+ var _brush = d3.svg.brush();
1045
+ var _brushOn = true;
1046
+ var _round;
1047
+
1048
+ var _renderHorizontalGridLine = false;
1049
+ var _renderVerticalGridLine = false;
1050
+
1051
+ var _refocused = false;
1052
+ var _unitCount;
1053
+
1054
+ var _zoomScale = [-10, 100]; // -10 to allow zoom out of the original domain
1055
+ var _zoomOutRestrict = false; // restrict zoomOut to the original domain?
1056
+
1057
+ var _rangeChart;
1058
+ var _focusChart;
1059
+
1060
+ var _mouseZoomable = false;
1061
+ var _clipPadding = 0;
1062
+
1063
+ _chart.title(function (d) {
1064
+ return d.data.key + ": " + d.data.value;
1065
+ });
1066
+
1067
+ _chart.rescale = function () {
1068
+ _unitCount = undefined;
1069
+ _chart.xUnitCount();
1070
+ };
1071
+
1072
+ _chart.rangeChart = function (_) {
1073
+ if (!arguments.length) return _rangeChart;
1074
+ _rangeChart = _;
1075
+ _rangeChart.focusChart(_chart);
1076
+ return _chart;
1077
+ };
1078
+
1079
+ _chart.zoomScale = function (_) {
1080
+ if (!arguments.length) return _zoomScale;
1081
+ _zoomScale = _;
1082
+ return _chart;
1083
+ };
1084
+
1085
+ _chart.zoomOutRestrict = function (_) {
1086
+ if (!arguments.length) return _zoomOutRestrict;
1087
+ _zoomOutRestrict = _;
1088
+ return _chart;
1089
+ };
1090
+
1091
+ _chart.generateG = function (parent) {
1092
+ if (parent === undefined)
1093
+ _parent = _chart.svg();
1094
+ else
1095
+ _parent = parent;
1096
+
1097
+ _g = _parent.append("g");
1098
+
1099
+ _chartBodyG = _g.append("g").attr("class", "chart-body")
1100
+ .attr("transform", "translate(" + _chart.margins().left + ", " + _chart.margins().top + ")")
1101
+ .attr("clip-path", "url(#" + getClipPathId() + ")");
1102
+
1103
+ return _g;
1104
+ };
1105
+
1106
+ _chart.g = function (_) {
1107
+ if (!arguments.length) return _g;
1108
+ _g = _;
1109
+ return _chart;
1110
+ };
1111
+
1112
+ _chart.mouseZoomable = function (z) {
1113
+ if (!arguments.length) return _mouseZoomable;
1114
+ _mouseZoomable = z;
1115
+ return _chart;
1116
+ };
1117
+
1118
+ _chart.chartBodyG = function (_) {
1119
+ if (!arguments.length) return _chartBodyG;
1120
+ _chartBodyG = _;
1121
+ return _chart;
1122
+ };
1123
+
1124
+ _chart.x = function (_) {
1125
+ if (!arguments.length) return _x;
1126
+ _x = _;
1127
+ _xOriginalDomain = _x.domain();
1128
+ return _chart;
1129
+ };
1130
+
1131
+ _chart.xOriginalDomain = function () {
1132
+ return _xOriginalDomain;
1133
+ };
1134
+
1135
+ _chart.xUnits = function (_) {
1136
+ if (!arguments.length) return _xUnits;
1137
+ _xUnits = _;
1138
+ return _chart;
1139
+ };
1140
+
1141
+ _chart.xAxis = function (_) {
1142
+ if (!arguments.length) return _xAxis;
1143
+ _xAxis = _;
1144
+ return _chart;
1145
+ };
1146
+
1147
+ _chart.elasticX = function (_) {
1148
+ if (!arguments.length) return _xElasticity;
1149
+ _xElasticity = _;
1150
+ return _chart;
1151
+ };
1152
+
1153
+ _chart.xAxisPadding = function (_) {
1154
+ if (!arguments.length) return _xAxisPadding;
1155
+ _xAxisPadding = _;
1156
+ return _chart;
1157
+ };
1158
+
1159
+ _chart.xUnitCount = function () {
1160
+ if (_unitCount === undefined) {
1161
+ var units = _chart.xUnits()(_chart.x().domain()[0], _chart.x().domain()[1], _chart.x().domain());
1162
+
1163
+ if (units instanceof Array)
1164
+ _unitCount = units.length;
1165
+ else
1166
+ _unitCount = units;
1167
+ }
1168
+
1169
+ return _unitCount;
1170
+ };
1171
+
1172
+ _chart.isOrdinal = function () {
1173
+ return _chart.xUnits() === dc.units.ordinal;
1174
+ };
1175
+
1176
+ _chart.prepareOrdinalXAxis = function (count) {
1177
+ if (!count)
1178
+ count = _chart.xUnitCount();
1179
+ var range = [];
1180
+ var increment = _chart.xAxisLength() / (count + 1);
1181
+ var currentPosition = increment/2;
1182
+ for (var i = 0; i < count; i++) {
1183
+ range[i] = currentPosition;
1184
+ currentPosition += increment;
1185
+ }
1186
+ _x.range(range);
1187
+ };
1188
+
1189
+ function prepareXAxis(g) {
1190
+ if (_chart.elasticX() && !_chart.isOrdinal()) {
1191
+ _x.domain([_chart.xAxisMin(), _chart.xAxisMax()]);
1192
+ }
1193
+ else if (_chart.isOrdinal() && _x.domain().length===0) {
1194
+ _x.domain(_chart.computeOrderedGroups().map(function(kv) { return kv.key; }));
1195
+ }
1196
+
1197
+ if (_chart.isOrdinal()) {
1198
+ _chart.prepareOrdinalXAxis();
1199
+ } else {
1200
+ _x.range([0, _chart.xAxisLength()]);
1201
+ }
1202
+
1203
+ _xAxis = _xAxis.scale(_chart.x()).orient("bottom");
1204
+
1205
+ renderVerticalGridLines(g);
1206
+ }
1207
+
1208
+ _chart.renderXAxis = function (g) {
1209
+ var axisXG = g.selectAll("g.x");
1210
+
1211
+ if (axisXG.empty())
1212
+ axisXG = g.append("g")
1213
+ .attr("class", "axis x")
1214
+ .attr("transform", "translate(" + _chart.margins().left + "," + _chart.xAxisY() + ")");
1215
+
1216
+ var axisXLab = g.selectAll("text."+X_AXIS_LABEL_CLASS);
1217
+ if (axisXLab.empty() && _chart.xAxisLabel())
1218
+ axisXLab = g.append('text')
1219
+ .attr("transform", "translate(" + _chart.xAxisLength() / 2 + "," + (_chart.height() - _xAxisLabelPadding) + ")")
1220
+ .attr('class', X_AXIS_LABEL_CLASS)
1221
+ .attr('text-anchor', 'middle')
1222
+ .text(_chart.xAxisLabel());
1223
+ if (_chart.xAxisLabel() && axisXLab.text() != _chart.xAxisLabel())
1224
+ axisYLab.text(_chart.xAxisLabel());
1225
+
1226
+ dc.transition(axisXG, _chart.transitionDuration())
1227
+ .call(_xAxis);
1228
+ };
1229
+
1230
+ function renderVerticalGridLines(g) {
1231
+ var gridLineG = g.selectAll("g." + VERTICAL_CLASS);
1232
+
1233
+ if (_renderVerticalGridLine) {
1234
+ if (gridLineG.empty())
1235
+ gridLineG = g.insert("g", ":first-child")
1236
+ .attr("class", GRID_LINE_CLASS + " " + VERTICAL_CLASS)
1237
+ .attr("transform", "translate(" + _chart.yAxisX() + "," + _chart.margins().top + ")");
1238
+
1239
+ var ticks = _xAxis.tickValues() ? _xAxis.tickValues() : _x.ticks(_xAxis.ticks()[0]);
1240
+
1241
+ var lines = gridLineG.selectAll("line")
1242
+ .data(ticks);
1243
+
1244
+ // enter
1245
+ var linesGEnter = lines.enter()
1246
+ .append("line")
1247
+ .attr("x1", function (d) {
1248
+ return _x(d);
1249
+ })
1250
+ .attr("y1", _chart.xAxisY() - _chart.margins().top)
1251
+ .attr("x2", function (d) {
1252
+ return _x(d);
1253
+ })
1254
+ .attr("y2", 0)
1255
+ .attr("opacity", 0);
1256
+ dc.transition(linesGEnter, _chart.transitionDuration())
1257
+ .attr("opacity", 1);
1258
+
1259
+ // update
1260
+ dc.transition(lines, _chart.transitionDuration())
1261
+ .attr("x1", function (d) {
1262
+ return _x(d);
1263
+ })
1264
+ .attr("y1", _chart.xAxisY() - _chart.margins().top)
1265
+ .attr("x2", function (d) {
1266
+ return _x(d);
1267
+ })
1268
+ .attr("y2", 0);
1269
+
1270
+ // exit
1271
+ lines.exit().remove();
1272
+ }
1273
+ else {
1274
+ gridLineG.selectAll("line").remove();
1275
+ }
1276
+ }
1277
+
1278
+ _chart.xAxisY = function () {
1279
+ return (_chart.height() - _chart.margins().bottom);
1280
+ };
1281
+
1282
+ _chart.xAxisLength = function () {
1283
+ return _chart.effectiveWidth();
1284
+ };
1285
+
1286
+ _chart.xAxisLabel = function (_,pad) {
1287
+ if (!arguments.length) return _xAxisLabel;
1288
+ _xAxisLabel = _;
1289
+ _chart.margins().bottom -= _xAxisLabelPadding;
1290
+ _xAxisLabelPadding = (pad===undefined) ? DEFAULT_AXIS_LABLEL_PADDING : pad;
1291
+ _chart.margins().bottom += _xAxisLabelPadding;
1292
+ return _chart;
1293
+ };
1294
+
1295
+ function prepareYAxis(g) {
1296
+ if (_y === undefined || _chart.elasticY()) {
1297
+ _y = d3.scale.linear();
1298
+ _y.domain([_chart.yAxisMin(), _chart.yAxisMax()]).rangeRound([_chart.yAxisHeight(), 0]);
1299
+ }
1300
+
1301
+ _y.range([_chart.yAxisHeight(), 0]);
1302
+ _yAxis = _yAxis.scale(_y).orient("left");
1303
+
1304
+ renderHorizontalGridLines(g);
1305
+ }
1306
+
1307
+ _chart.renderYAxis = function (g) {
1308
+ var axisYG = g.selectAll("g.y");
1309
+ if (axisYG.empty())
1310
+ axisYG = g.append("g")
1311
+ .attr("class", "axis y")
1312
+ .attr("transform", "translate(" + _chart.yAxisX() + "," + _chart.margins().top + ")");
1313
+
1314
+ var axisYLab = g.selectAll("text."+Y_AXIS_LABEL_CLASS);
1315
+ if (axisYLab.empty() && _chart.yAxisLabel())
1316
+ axisYLab = g.append('text')
1317
+ .attr("transform", "translate(" + _yAxisLabelPadding + "," + _chart.yAxisHeight()/2 + "),rotate(-90)")
1318
+ .attr('class', Y_AXIS_LABEL_CLASS)
1319
+ .attr('text-anchor', 'middle')
1320
+ .text(_chart.yAxisLabel());
1321
+ if (_chart.yAxisLabel() && axisYLab.text() != _chart.yAxisLabel())
1322
+ axisYLab.text(_chart.yAxisLabel());
1323
+
1324
+ dc.transition(axisYG, _chart.transitionDuration())
1325
+ .call(_yAxis);
1326
+ };
1327
+
1328
+
1329
+ function renderHorizontalGridLines(g) {
1330
+ var gridLineG = g.selectAll("g." + HORIZONTAL_CLASS);
1331
+
1332
+ if (_renderHorizontalGridLine) {
1333
+ var ticks = _yAxis.tickValues() ? _yAxis.tickValues() : _y.ticks(_yAxis.ticks()[0]);
1334
+
1335
+ if (gridLineG.empty())
1336
+ gridLineG = g.insert("g", ":first-child")
1337
+ .attr("class", GRID_LINE_CLASS + " " + HORIZONTAL_CLASS)
1338
+ .attr("transform", "translate(" + _chart.yAxisX() + "," + _chart.margins().top + ")");
1339
+
1340
+ var lines = gridLineG.selectAll("line")
1341
+ .data(ticks);
1342
+
1343
+ // enter
1344
+ var linesGEnter = lines.enter()
1345
+ .append("line")
1346
+ .attr("x1", 1)
1347
+ .attr("y1", function (d) {
1348
+ return _y(d);
1349
+ })
1350
+ .attr("x2", _chart.xAxisLength())
1351
+ .attr("y2", function (d) {
1352
+ return _y(d);
1353
+ })
1354
+ .attr("opacity", 0);
1355
+ dc.transition(linesGEnter, _chart.transitionDuration())
1356
+ .attr("opacity", 1);
1357
+
1358
+ // update
1359
+ dc.transition(lines, _chart.transitionDuration())
1360
+ .attr("x1", 1)
1361
+ .attr("y1", function (d) {
1362
+ return _y(d);
1363
+ })
1364
+ .attr("x2", _chart.xAxisLength())
1365
+ .attr("y2", function (d) {
1366
+ return _y(d);
1367
+ });
1368
+
1369
+ // exit
1370
+ lines.exit().remove();
1371
+ }
1372
+ else {
1373
+ gridLineG.selectAll("line").remove();
1374
+ }
1375
+ }
1376
+
1377
+ _chart.yAxisX = function () {
1378
+ return _chart.margins().left;
1379
+ };
1380
+
1381
+ _chart.yAxisLabel = function (_,pad) {
1382
+ if (!arguments.length) return _yAxisLabel;
1383
+ _yAxisLabel = _;
1384
+ _chart.margins().left -= _yAxisLabelPadding;
1385
+ _yAxisLabelPadding = (pad===undefined) ? DEFAULT_AXIS_LABLEL_PADDING : pad;
1386
+ _chart.margins().left += _yAxisLabelPadding;
1387
+ return _chart;
1388
+ };
1389
+
1390
+ _chart.y = function (_) {
1391
+ if (!arguments.length) return _y;
1392
+ _y = _;
1393
+ return _chart;
1394
+ };
1395
+
1396
+ _chart.yAxis = function (y) {
1397
+ if (!arguments.length) return _yAxis;
1398
+ _yAxis = y;
1399
+ return _chart;
1400
+ };
1401
+
1402
+ _chart.elasticY = function (_) {
1403
+ if (!arguments.length) return _yElasticity;
1404
+ _yElasticity = _;
1405
+ return _chart;
1406
+ };
1407
+
1408
+ _chart.renderHorizontalGridLines = function (_) {
1409
+ if (!arguments.length) return _renderHorizontalGridLine;
1410
+ _renderHorizontalGridLine = _;
1411
+ return _chart;
1412
+ };
1413
+
1414
+ _chart.renderVerticalGridLines = function (_) {
1415
+ if (!arguments.length) return _renderVerticalGridLine;
1416
+ _renderVerticalGridLine = _;
1417
+ return _chart;
1418
+ };
1419
+
1420
+ _chart.xAxisMin = function () {
1421
+ var min = d3.min(_chart.group().all(), function (e) {
1422
+ return _chart.keyAccessor()(e);
1423
+ });
1424
+ return dc.utils.subtract(min, _xAxisPadding);
1425
+ };
1426
+
1427
+ _chart.xAxisMax = function () {
1428
+ var max = d3.max(_chart.group().all(), function (e) {
1429
+ return _chart.keyAccessor()(e);
1430
+ });
1431
+ return dc.utils.add(max, _xAxisPadding);
1432
+ };
1433
+
1434
+ _chart.yAxisMin = function () {
1435
+ var min = d3.min(_chart.group().all(), function (e) {
1436
+ return _chart.valueAccessor()(e);
1437
+ });
1438
+ min = dc.utils.subtract(min, _yAxisPadding);
1439
+ return min;
1440
+ };
1441
+
1442
+ _chart.yAxisMax = function () {
1443
+ var max = d3.max(_chart.group().all(), function (e) {
1444
+ return _chart.valueAccessor()(e);
1445
+ });
1446
+ max = dc.utils.add(max, _yAxisPadding);
1447
+ return max;
1448
+ };
1449
+
1450
+ _chart.yAxisPadding = function (_) {
1451
+ if (!arguments.length) return _yAxisPadding;
1452
+ _yAxisPadding = _;
1453
+ return _chart;
1454
+ };
1455
+
1456
+ _chart.yAxisHeight = function () {
1457
+ return _chart.effectiveHeight();
1458
+ };
1459
+
1460
+ _chart.round = function (_) {
1461
+ if (!arguments.length) return _round;
1462
+ _round = _;
1463
+ return _chart;
1464
+ };
1465
+
1466
+ dc.override(_chart, "filter", function (_) {
1467
+ if (!arguments.length) return _chart._filter();
1468
+
1469
+ _chart._filter(_);
1470
+
1471
+ if (_) {
1472
+ _chart.brush().extent(_);
1473
+ } else {
1474
+ _chart.brush().clear();
1475
+ }
1476
+
1477
+ return _chart;
1478
+ });
1479
+
1480
+ _chart.brush = function (_) {
1481
+ if (!arguments.length) return _brush;
1482
+ _brush = _;
1483
+ return _chart;
1484
+ };
1485
+
1486
+ function brushHeight() {
1487
+ return _chart.xAxisY() - _chart.margins().top;
1488
+ }
1489
+
1490
+ _chart.renderBrush = function (g) {
1491
+ if (_chart.isOrdinal())
1492
+ _brushOn = false;
1493
+
1494
+ if (_brushOn) {
1495
+ _brush.on("brushstart", brushStart)
1496
+ .on("brush", brushing)
1497
+ .on("brushend", brushEnd);
1498
+
1499
+ var gBrush = g.append("g")
1500
+ .attr("class", "brush")
1501
+ .attr("transform", "translate(" + _chart.margins().left + "," + _chart.margins().top + ")")
1502
+ .call(_brush.x(_chart.x()));
1503
+ gBrush.selectAll("rect").attr("height", brushHeight());
1504
+ gBrush.selectAll(".resize").append("path").attr("d", _chart.resizeHandlePath);
1505
+
1506
+ if (_chart.hasFilter()) {
1507
+ _chart.redrawBrush(g);
1508
+ }
1509
+ }
1510
+ };
1511
+
1512
+ function brushStart(p) {
1513
+ }
1514
+
1515
+ _chart.extendBrush = function () {
1516
+ var extent = _brush.extent();
1517
+ if (_chart.round()) {
1518
+ extent[0] = extent.map(_chart.round())[0];
1519
+ extent[1] = extent.map(_chart.round())[1];
1520
+
1521
+ _g.select(".brush")
1522
+ .call(_brush.extent(extent));
1523
+ }
1524
+ return extent;
1525
+ };
1526
+
1527
+ _chart.brushIsEmpty = function (extent) {
1528
+ return _brush.empty() || !extent || extent[1] <= extent[0];
1529
+ };
1530
+
1531
+ function brushing(p) {
1532
+ var extent = _chart.extendBrush();
1533
+
1534
+ _chart.redrawBrush(_g);
1535
+
1536
+ if (_chart.brushIsEmpty(extent)) {
1537
+ dc.events.trigger(function () {
1538
+ _chart.filter(null);
1539
+ dc.redrawAll(_chart.chartGroup());
1540
+ });
1541
+ } else {
1542
+ dc.events.trigger(function () {
1543
+ _chart.filter(null);
1544
+ _chart.filter([extent[0], extent[1]]);
1545
+ dc.redrawAll(_chart.chartGroup());
1546
+ }, dc.constants.EVENT_DELAY);
1547
+ }
1548
+ }
1549
+
1550
+ function brushEnd(p) {
1551
+ }
1552
+
1553
+ _chart.redrawBrush = function (g) {
1554
+ if (_brushOn) {
1555
+ if (_chart.filter() && _chart.brush().empty())
1556
+ _chart.brush().extent(_chart.filter());
1557
+
1558
+ var gBrush = g.select("g.brush");
1559
+ gBrush.call(_chart.brush().x(_chart.x()));
1560
+ gBrush.selectAll("rect").attr("height", brushHeight());
1561
+ }
1562
+
1563
+ _chart.fadeDeselectedArea();
1564
+ };
1565
+
1566
+ _chart.fadeDeselectedArea = function () {
1567
+ // do nothing, sub-chart should override this function
1568
+ };
1569
+
1570
+ // borrowed from Crossfilter example
1571
+ _chart.resizeHandlePath = function (d) {
1572
+ var e = +(d == "e"), x = e ? 1 : -1, y = brushHeight() / 3;
1573
+ return "M" + (0.5 * x) + "," + y
1574
+ + "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6)
1575
+ + "V" + (2 * y - 6)
1576
+ + "A6,6 0 0 " + e + " " + (0.5 * x) + "," + (2 * y)
1577
+ + "Z"
1578
+ + "M" + (2.5 * x) + "," + (y + 8)
1579
+ + "V" + (2 * y - 8)
1580
+ + "M" + (4.5 * x) + "," + (y + 8)
1581
+ + "V" + (2 * y - 8);
1582
+ };
1583
+
1584
+ function getClipPathId() {
1585
+ return _chart.anchorName() + "-clip";
1586
+ }
1587
+
1588
+ _chart.clipPadding = function (p) {
1589
+ if (!arguments.length) return _clipPadding;
1590
+ _clipPadding = p;
1591
+ return _chart;
1592
+ };
1593
+
1594
+ function generateClipPath() {
1595
+ var defs = dc.utils.appendOrSelect(_parent, "defs");
1596
+
1597
+ var chartBodyClip = dc.utils.appendOrSelect(defs, "clipPath").attr("id", getClipPathId());
1598
+
1599
+ var padding = _clipPadding * 2;
1600
+
1601
+ dc.utils.appendOrSelect(chartBodyClip, "rect")
1602
+ .attr("width", _chart.xAxisLength() + padding)
1603
+ .attr("height", _chart.yAxisHeight() + padding);
1604
+ }
1605
+
1606
+ _chart.doRender = function () {
1607
+ if (_x === undefined)
1608
+ throw new dc.errors.InvalidStateException("Mandatory attribute chart.x is missing on chart[#"
1609
+ + _chart.anchorName() + "]");
1610
+
1611
+ _chart.resetSvg();
1612
+
1613
+ if (_chart.dataSet()) {
1614
+ _chart.generateG();
1615
+
1616
+ generateClipPath();
1617
+ prepareXAxis(_chart.g());
1618
+ prepareYAxis(_chart.g());
1619
+
1620
+ _chart.plotData();
1621
+
1622
+ _chart.renderXAxis(_chart.g());
1623
+ _chart.renderYAxis(_chart.g());
1624
+
1625
+ _chart.renderBrush(_chart.g());
1626
+
1627
+ enableMouseZoom();
1628
+ }
1629
+
1630
+ return _chart;
1631
+ };
1632
+
1633
+ function enableMouseZoom() {
1634
+ if (_mouseZoomable) {
1635
+ _chart.root().call(d3.behavior.zoom()
1636
+ .x(_chart.x())
1637
+ .scaleExtent(_zoomScale)
1638
+ .on("zoom", function () {
1639
+ _chart.focus(_chart.x().domain());
1640
+ _chart.invokeZoomedListener();
1641
+ updateRangeSelChart();
1642
+ }));
1643
+ }
1644
+ }
1645
+
1646
+ function updateRangeSelChart() {
1647
+ if (_rangeChart) {
1648
+ var refDom = _chart.x().domain();
1649
+ if (_zoomOutRestrict) {
1650
+ var origDom = _rangeChart.xOriginalDomain();
1651
+ var newDom = [
1652
+ refDom[0] < origDom[0] ? refDom[0] : origDom[0],
1653
+ refDom[1] > origDom[1] ? refDom[1] : origDom[1]];
1654
+ _rangeChart.focus(newDom);
1655
+ } else {
1656
+ _rangeChart.focus(refDom);
1657
+ }
1658
+ _rangeChart.filter(null);
1659
+ _rangeChart.filter(refDom);
1660
+
1661
+ dc.events.trigger(function () {
1662
+ dc.redrawAll(_chart.chartGroup());
1663
+ });
1664
+ }
1665
+ }
1666
+
1667
+ _chart.doRedraw = function () {
1668
+ prepareXAxis(_chart.g());
1669
+ prepareYAxis(_chart.g());
1670
+
1671
+ _chart.plotData();
1672
+
1673
+ if (_chart.elasticY())
1674
+ _chart.renderYAxis(_chart.g());
1675
+
1676
+ if (_chart.elasticX() || _refocused)
1677
+ _chart.renderXAxis(_chart.g());
1678
+
1679
+ _chart.redrawBrush(_chart.g());
1680
+
1681
+ return _chart;
1682
+ };
1683
+
1684
+ _chart.subRender = function () {
1685
+ if (_chart.dataSet()) {
1686
+ _chart.plotData();
1687
+ }
1688
+
1689
+ return _chart;
1690
+ };
1691
+
1692
+ _chart.brushOn = function (_) {
1693
+ if (!arguments.length) return _brushOn;
1694
+ _brushOn = _;
1695
+ return _chart;
1696
+ };
1697
+
1698
+ _chart.getDataWithinXDomain = function (group) {
1699
+ var data = [];
1700
+
1701
+ if (_chart.isOrdinal()) {
1702
+ data = group.all();
1703
+ } else {
1704
+ group.all().forEach(function (d) {
1705
+ var key = _chart.keyAccessor()(d);
1706
+ if (key >= _chart.x().domain()[0] && key <= _chart.x().domain()[1])
1707
+ data.push(d);
1708
+ });
1709
+ }
1710
+
1711
+ return data;
1712
+ };
1713
+
1714
+ function hasRangeSelected(range) {
1715
+ return range instanceof Array && range.length > 1;
1716
+ }
1717
+
1718
+ _chart.focus = function (range) {
1719
+ _refocused = true;
1720
+
1721
+ if (hasRangeSelected(range)) {
1722
+ _chart.x().domain(range);
1723
+ } else {
1724
+ _chart.x().domain(_chart.xOriginalDomain());
1725
+ }
1726
+
1727
+ _chart.rescale();
1728
+
1729
+ _chart.redraw();
1730
+
1731
+ if (!hasRangeSelected(range))
1732
+ _refocused = false;
1733
+ };
1734
+
1735
+ _chart.refocused = function () {
1736
+ return _refocused;
1737
+ };
1738
+
1739
+ _chart.focusChart = function (c) {
1740
+ if (!arguments.length) return _focusChart;
1741
+ _focusChart = c;
1742
+ _chart.on("filtered", function (chart) {
1743
+ dc.events.trigger(function () {
1744
+ _focusChart.focus(chart.filter());
1745
+ _focusChart.filter(chart.filter());
1746
+ dc.redrawAll(chart.chartGroup());
1747
+ });
1748
+ });
1749
+ return _chart;
1750
+ };
1751
+
1752
+ return _chart;
1753
+ };
1754
+
1755
+ dc.colorChart = function(_chart) {
1756
+ var _colors = d3.scale.category20c();
1757
+
1758
+ var _colorDomain = [0, _colors.range().length];
1759
+
1760
+ var _colorCalculator = function(value) {
1761
+ var minValue = _colorDomain[0];
1762
+ var maxValue = _colorDomain[1];
1763
+
1764
+ if (isNaN(value)) value = 0;
1765
+ if(maxValue === null) return _colors(value);
1766
+
1767
+ var colorsLength = _chart.colors().range().length;
1768
+ var denominator = (maxValue - minValue) / colorsLength;
1769
+ var colorValue = Math.abs(Math.min(colorsLength - 1, Math.round((value - minValue) / denominator)));
1770
+ return _chart.colors()(colorValue);
1771
+ };
1772
+
1773
+ var _colorAccessor = function(d, i){return i;};
1774
+
1775
+ _chart.colors = function(_) {
1776
+ if (!arguments.length) return _colors;
1777
+
1778
+ if (_ instanceof Array) {
1779
+ _colors = d3.scale.ordinal().range(_);
1780
+ var domain = [];
1781
+ for(var i = 0; i < _.length; ++i){
1782
+ domain.push(i);
1783
+ }
1784
+ _colors.domain(domain);
1785
+ } else {
1786
+ _colors = _;
1787
+ }
1788
+
1789
+ _colorDomain = [0, _colors.range().length];
1790
+
1791
+ return _chart;
1792
+ };
1793
+
1794
+ _chart.colorCalculator = function(_){
1795
+ if(!arguments.length) return _colorCalculator;
1796
+ _colorCalculator = _;
1797
+ return _chart;
1798
+ };
1799
+
1800
+ _chart.getColor = function(d, i){
1801
+ return _colorCalculator(_colorAccessor(d, i));
1802
+ };
1803
+
1804
+ _chart.colorAccessor = function(_){
1805
+ if(!arguments.length) return _colorAccessor;
1806
+ _colorAccessor = _;
1807
+ return _chart;
1808
+ };
1809
+
1810
+ _chart.colorDomain = function(_){
1811
+ if(!arguments.length) return _colorDomain;
1812
+ _colorDomain = _;
1813
+ return _chart;
1814
+ };
1815
+
1816
+ return _chart;
1817
+ };
1818
+
1819
+ dc.stackableChart = function (_chart) {
1820
+ var _groupStack = new dc.utils.GroupStack();
1821
+ var _stackLayout = d3.layout.stack()
1822
+ .offset("zero")
1823
+ .order("default")
1824
+ .values(function (d) {
1825
+ return d.points;
1826
+ });
1827
+ var _allGroups;
1828
+ var _allValueAccessors;
1829
+ var _allKeyAccessors;
1830
+ var _stackLayers;
1831
+
1832
+ _chart.stack = function (group, p2, retriever) {
1833
+ if(!arguments.length)
1834
+ _groupStack.clear();
1835
+
1836
+ if (typeof p2 === 'string')
1837
+ _chart.setGroupName(group, p2, retriever);
1838
+ else if (typeof p2 === 'function')
1839
+ retriever = p2;
1840
+
1841
+ _groupStack.setDefaultAccessor(_chart.valueAccessor());
1842
+ _groupStack.addGroup(group, retriever);
1843
+
1844
+ _chart.expireCache();
1845
+
1846
+ return _chart;
1847
+ };
1848
+
1849
+ _chart.expireCache = function () {
1850
+ _allGroups = null;
1851
+ _allValueAccessors = null;
1852
+ _allKeyAccessors = null;
1853
+ _stackLayers = null;
1854
+ return _chart;
1855
+ };
1856
+
1857
+ _chart.allGroups = function () {
1858
+ if (_allGroups === null) {
1859
+ _allGroups = [];
1860
+
1861
+ _allGroups.push(_chart.group());
1862
+
1863
+ for (var i = 0; i < _groupStack.size(); ++i)
1864
+ _allGroups.push(_groupStack.getGroupByIndex(i));
1865
+ }
1866
+
1867
+ return _allGroups;
1868
+ };
1869
+
1870
+ _chart.allValueAccessors = function () {
1871
+ if (_allValueAccessors === null) {
1872
+ _allValueAccessors = [];
1873
+
1874
+ _allValueAccessors.push(_chart.valueAccessor());
1875
+
1876
+ for (var i = 0; i < _groupStack.size(); ++i)
1877
+ _allValueAccessors.push(_groupStack.getAccessorByIndex(i));
1878
+ }
1879
+
1880
+ return _allValueAccessors;
1881
+ };
1882
+
1883
+ _chart.getValueAccessorByIndex = function (groupIndex) {
1884
+ return _chart.allValueAccessors()[groupIndex];
1885
+ };
1886
+
1887
+ _chart.yAxisMin = function () {
1888
+ var min, all = flattenStack();
1889
+
1890
+ min = d3.min(all, function (p) {
1891
+ return (p.y + p.y0 < p.y0) ? (p.y + p.y0) : p.y0;
1892
+ });
1893
+
1894
+ min = dc.utils.subtract(min, _chart.yAxisPadding());
1895
+
1896
+ return min;
1897
+ };
1898
+
1899
+ _chart.yAxisMax = function () {
1900
+ var max, all = flattenStack();
1901
+
1902
+ max = d3.max(all, function (p) {
1903
+ return p.y + p.y0;
1904
+ });
1905
+
1906
+ max = dc.utils.add(max, _chart.yAxisPadding());
1907
+
1908
+ return max;
1909
+ };
1910
+
1911
+ function flattenStack() {
1912
+ var all = [];
1913
+
1914
+ if (_chart.x()) {
1915
+ var xDomain = _chart.x().domain();
1916
+
1917
+ _chart.stackLayers().forEach(function (e) {
1918
+ e.points.forEach(function (p) {
1919
+ if (p.x >= xDomain[0] && p.x <= xDomain[xDomain.length-1])
1920
+ all.push(p);
1921
+ });
1922
+ });
1923
+ } else {
1924
+ _chart.stackLayers().forEach(function (e) {
1925
+ all = all.concat(e.points);
1926
+ });
1927
+ }
1928
+
1929
+ return all;
1930
+ }
1931
+
1932
+ _chart.allKeyAccessors = function () {
1933
+ if (_allKeyAccessors === null) {
1934
+ _allKeyAccessors = [];
1935
+
1936
+ _allKeyAccessors.push(_chart.keyAccessor());
1937
+
1938
+ for (var i = 0; i < _groupStack.size(); ++i)
1939
+ _allKeyAccessors.push(_chart.keyAccessor());
1940
+ }
1941
+
1942
+ return _allKeyAccessors;
1943
+ };
1944
+
1945
+ _chart.getKeyAccessorByIndex = function (groupIndex) {
1946
+ return _chart.allKeyAccessors()[groupIndex];
1947
+ };
1948
+
1949
+ _chart.xAxisMin = function () {
1950
+ var min = null;
1951
+ var allGroups = _chart.allGroups();
1952
+
1953
+ for (var groupIndex = 0; groupIndex < allGroups.length; ++groupIndex) {
1954
+ var group = allGroups[groupIndex];
1955
+ var m = dc.utils.groupMin(group, _chart.getKeyAccessorByIndex(groupIndex));
1956
+ if (min === null || min > m) min = m;
1957
+ }
1958
+
1959
+ return dc.utils.subtract(min, _chart.xAxisPadding());
1960
+ };
1961
+
1962
+ _chart.xAxisMax = function () {
1963
+ var max = null;
1964
+ var allGroups = _chart.allGroups();
1965
+
1966
+ for (var groupIndex = 0; groupIndex < allGroups.length; ++groupIndex) {
1967
+ var group = allGroups[groupIndex];
1968
+ var m = dc.utils.groupMax(group, _chart.getKeyAccessorByIndex(groupIndex));
1969
+ if (max === null || max < m) max = m;
1970
+ }
1971
+
1972
+ return dc.utils.add(max, _chart.xAxisPadding());
1973
+ };
1974
+
1975
+ function getKeyFromData(groupIndex, d) {
1976
+ return _chart.getKeyAccessorByIndex(groupIndex)(d);
1977
+ }
1978
+
1979
+ function getValueFromData(groupIndex, d) {
1980
+ return _chart.getValueAccessorByIndex(groupIndex)(d);
1981
+ }
1982
+
1983
+ function calculateDataPointMatrix(data, groupIndex) {
1984
+ for (var dataIndex = 0; dataIndex < data.length; ++dataIndex) {
1985
+ var d = data[dataIndex];
1986
+ var key = getKeyFromData(groupIndex, d);
1987
+ var value = getValueFromData(groupIndex, d);
1988
+
1989
+ _groupStack.setDataPoint(groupIndex, dataIndex, {data: d, x: key, y: value});
1990
+ }
1991
+ }
1992
+
1993
+ _chart.calculateDataPointMatrixForAll = function () {
1994
+ var groups = _chart.allGroups();
1995
+ for (var groupIndex = 0; groupIndex < groups.length; ++groupIndex) {
1996
+ var group = groups[groupIndex];
1997
+ var data = group.all();
1998
+
1999
+ calculateDataPointMatrix(data, groupIndex);
2000
+ }
2001
+ };
2002
+
2003
+ _chart.getChartStack = function () {
2004
+ return _groupStack;
2005
+ };
2006
+
2007
+ dc.override(_chart, "valueAccessor", function (_) {
2008
+ if (!arguments.length) return _chart._valueAccessor();
2009
+ _chart.expireCache();
2010
+ return _chart._valueAccessor(_);
2011
+ });
2012
+
2013
+ dc.override(_chart, "keyAccessor", function (_) {
2014
+ if (!arguments.length) return _chart._keyAccessor();
2015
+ _chart.expireCache();
2016
+ return _chart._keyAccessor(_);
2017
+ });
2018
+
2019
+ _chart.stackLayout = function (stack) {
2020
+ if (!arguments.length) return _stackLayout;
2021
+ _stackLayout = stack;
2022
+ return _chart;
2023
+ };
2024
+
2025
+ _chart.stackLayers = function (_) {
2026
+ if (!arguments.length) {
2027
+ if (_stackLayers === null) {
2028
+ _chart.calculateDataPointMatrixForAll();
2029
+ _stackLayers = _chart.stackLayout()(_groupStack.toLayers());
2030
+ }
2031
+ return _stackLayers;
2032
+ } else {
2033
+ _stackLayers = _;
2034
+ }
2035
+ };
2036
+
2037
+ _chart.legendables = function () {
2038
+ var items = [];
2039
+ _allGroups.forEach(function (g, i) {
2040
+ items.push(dc.utils.createLegendable(_chart, g, i, _chart.getValueAccessorByIndex(i)));
2041
+ });
2042
+ return items;
2043
+ };
2044
+
2045
+ return _chart;
2046
+ };
2047
+
2048
+ dc.abstractBubbleChart = function (_chart) {
2049
+ var _maxBubbleRelativeSize = 0.3;
2050
+ var _minRadiusWithLabel = 10;
2051
+
2052
+ _chart.BUBBLE_NODE_CLASS = "node";
2053
+ _chart.BUBBLE_CLASS = "bubble";
2054
+ _chart.MIN_RADIUS = 10;
2055
+
2056
+ _chart = dc.colorChart(_chart);
2057
+
2058
+ _chart.renderLabel(true);
2059
+ _chart.renderTitle(false);
2060
+
2061
+ var _r = d3.scale.linear().domain([0, 100]);
2062
+
2063
+ var _rValueAccessor = function (d) {
2064
+ return d.r;
2065
+ };
2066
+
2067
+ _chart.r = function (_) {
2068
+ if (!arguments.length) return _r;
2069
+ _r = _;
2070
+ return _chart;
2071
+ };
2072
+
2073
+ _chart.radiusValueAccessor = function (_) {
2074
+ if (!arguments.length) return _rValueAccessor;
2075
+ _rValueAccessor = _;
2076
+ return _chart;
2077
+ };
2078
+
2079
+ _chart.rMin = function () {
2080
+ var min = d3.min(_chart.group().all(), function (e) {
2081
+ return _chart.radiusValueAccessor()(e);
2082
+ });
2083
+ return min;
2084
+ };
2085
+
2086
+ _chart.rMax = function () {
2087
+ var max = d3.max(_chart.group().all(), function (e) {
2088
+ return _chart.radiusValueAccessor()(e);
2089
+ });
2090
+ return max;
2091
+ };
2092
+
2093
+ _chart.bubbleR = function (d) {
2094
+ var value = _chart.radiusValueAccessor()(d);
2095
+ var r = _chart.r()(value);
2096
+ if (isNaN(r) || value <= 0)
2097
+ r = 0;
2098
+ return r;
2099
+ };
2100
+
2101
+ var labelFunction = function (d) {
2102
+ return _chart.label()(d);
2103
+ };
2104
+
2105
+ var labelOpacity = function (d) {
2106
+ return (_chart.bubbleR(d) > _minRadiusWithLabel) ? 1 : 0;
2107
+ };
2108
+
2109
+ _chart.doRenderLabel = function (bubbleGEnter) {
2110
+ if (_chart.renderLabel()) {
2111
+ var label = bubbleGEnter.select("text");
2112
+
2113
+ if (label.empty()) {
2114
+ label = bubbleGEnter.append("text")
2115
+ .attr("text-anchor", "middle")
2116
+ .attr("dy", ".3em")
2117
+ .on("click", _chart.onClick);
2118
+ }
2119
+
2120
+ label
2121
+ .attr("opacity", 0)
2122
+ .text(labelFunction);
2123
+ dc.transition(label, _chart.transitionDuration())
2124
+ .attr("opacity", labelOpacity);
2125
+ }
2126
+ };
2127
+
2128
+ _chart.doUpdateLabels = function (bubbleGEnter) {
2129
+ if (_chart.renderLabel()) {
2130
+ var labels = bubbleGEnter.selectAll("text")
2131
+ .text(labelFunction);
2132
+ dc.transition(labels, _chart.transitionDuration())
2133
+ .attr("opacity", labelOpacity);
2134
+ }
2135
+ };
2136
+
2137
+ var titleFunction = function (d) {
2138
+ return _chart.title()(d);
2139
+ };
2140
+
2141
+ _chart.doRenderTitles = function (g) {
2142
+ if (_chart.renderTitle()) {
2143
+ var title = g.select("title");
2144
+
2145
+ if (title.empty())
2146
+ g.append("title").text(titleFunction);
2147
+ }
2148
+ };
2149
+
2150
+ _chart.doUpdateTitles = function (g) {
2151
+ if (_chart.renderTitle()) {
2152
+ g.selectAll("title").text(titleFunction);
2153
+ }
2154
+ };
2155
+
2156
+ _chart.minRadiusWithLabel = function (_) {
2157
+ if (!arguments.length) return _minRadiusWithLabel;
2158
+ _minRadiusWithLabel = _;
2159
+ return _chart;
2160
+ };
2161
+
2162
+ _chart.maxBubbleRelativeSize = function (_) {
2163
+ if (!arguments.length) return _maxBubbleRelativeSize;
2164
+ _maxBubbleRelativeSize = _;
2165
+ return _chart;
2166
+ };
2167
+
2168
+ _chart.initBubbleColor = function (d, i) {
2169
+ this[dc.constants.NODE_INDEX_NAME] = i;
2170
+ return _chart.getColor(d, i);
2171
+ };
2172
+
2173
+ _chart.updateBubbleColor = function (d, i) {
2174
+ // a work around to get correct node index since
2175
+ return _chart.getColor(d, this[dc.constants.NODE_INDEX_NAME]);
2176
+ };
2177
+
2178
+ _chart.fadeDeselectedArea = function () {
2179
+ if (_chart.hasFilter()) {
2180
+ _chart.selectAll("g." + _chart.BUBBLE_NODE_CLASS).each(function (d) {
2181
+ if (_chart.isSelectedNode(d)) {
2182
+ _chart.highlightSelected(this);
2183
+ } else {
2184
+ _chart.fadeDeselected(this);
2185
+ }
2186
+ });
2187
+ } else {
2188
+ _chart.selectAll("g." + _chart.BUBBLE_NODE_CLASS).each(function (d) {
2189
+ _chart.resetHighlight(this);
2190
+ });
2191
+ }
2192
+ };
2193
+
2194
+ _chart.isSelectedNode = function (d) {
2195
+ return _chart.hasFilter(d.key);
2196
+ };
2197
+
2198
+ _chart.onClick = function (d) {
2199
+ var filter = d.key;
2200
+ dc.events.trigger(function () {
2201
+ _chart.filter(filter);
2202
+ dc.redrawAll(_chart.chartGroup());
2203
+ });
2204
+ };
2205
+
2206
+ return _chart;
2207
+ };
2208
+
2209
+ dc.pieChart = function (parent, chartGroup) {
2210
+ var DEFAULT_MIN_ANGLE_FOR_LABEL = 0.5;
2211
+
2212
+ var _sliceCssClass = "pie-slice";
2213
+
2214
+ var _radius,
2215
+ _innerRadius = 0;
2216
+
2217
+ var _g;
2218
+
2219
+ var _minAngleForLabel = DEFAULT_MIN_ANGLE_FOR_LABEL;
2220
+
2221
+ var _chart = dc.colorChart(dc.baseChart({}));
2222
+
2223
+ var _slicesCap = Infinity;
2224
+ var _othersLabel = "Others";
2225
+ var _othersGrouper = function (topRows) {
2226
+ var topRowsSum = d3.sum(topRows, _chart.valueAccessor()),
2227
+ allRows = _chart.group().all(),
2228
+ allRowsSum = d3.sum(allRows, _chart.valueAccessor()),
2229
+ topKeys = topRows.map(_chart.keyAccessor()),
2230
+ allKeys = allRows.map(_chart.keyAccessor()),
2231
+ topSet = d3.set(topKeys),
2232
+ others = allKeys.filter(function(d){return !topSet.has(d);});
2233
+ topRows.push({"others": others,"key": _othersLabel, "value": allRowsSum - topRowsSum });
2234
+ };
2235
+
2236
+ function assemblePieData() {
2237
+ if (_slicesCap == Infinity) {
2238
+ return _chart.computeOrderedGroups();
2239
+ } else {
2240
+ var topRows = _chart.group().top(_slicesCap); // ordered by value
2241
+ topRows = _chart.computeOrderedGroups(topRows); // re-order by key
2242
+ _othersGrouper(topRows);
2243
+ return topRows;
2244
+ }
2245
+ }
2246
+
2247
+ _chart.label(function (d) {
2248
+ return _chart.keyAccessor()(d.data);
2249
+ });
2250
+
2251
+ _chart.renderLabel(true);
2252
+
2253
+ _chart.title(function (d) {
2254
+ return _chart.keyAccessor()(d.data) + ": " + _chart.valueAccessor()(d.data);
2255
+ });
2256
+
2257
+ _chart.transitionDuration(350);
2258
+
2259
+ _chart.doRender = function () {
2260
+ _chart.resetSvg();
2261
+
2262
+ _g = _chart.svg()
2263
+ .append("g")
2264
+ .attr("transform", "translate(" + _chart.cx() + "," + _chart.cy() + ")");
2265
+
2266
+ drawChart();
2267
+
2268
+ return _chart;
2269
+ };
2270
+
2271
+ function drawChart() {
2272
+ if (_chart.dataSet()) {
2273
+ var pie = calculateDataPie();
2274
+
2275
+ // set radius on basis of chart dimension if missing
2276
+ _radius = _radius ? _radius : d3.min([_chart.width(), _chart.height()]) /2;
2277
+
2278
+ var arc = _chart.buildArcs();
2279
+
2280
+ var pieData = pie(assemblePieData());
2281
+
2282
+ if (_g) {
2283
+ var slices = _g.selectAll("g." + _sliceCssClass)
2284
+ .data(pieData);
2285
+
2286
+ createElements(slices, arc, pieData);
2287
+
2288
+ updateElements(pieData, arc);
2289
+
2290
+ removeElements(slices);
2291
+
2292
+ highlightFilter();
2293
+ }
2294
+ }
2295
+ }
2296
+
2297
+ function createElements(slices, arc, pieData) {
2298
+ var slicesEnter = createSliceNodes(slices);
2299
+
2300
+ createSlicePath(slicesEnter, arc);
2301
+
2302
+ createTitles(slicesEnter);
2303
+
2304
+ createLabels(pieData, arc);
2305
+ }
2306
+
2307
+ function createSliceNodes(slices) {
2308
+ var slicesEnter = slices
2309
+ .enter()
2310
+ .append("g")
2311
+ .attr("class", function (d, i) {
2312
+ return _sliceCssClass + " _" + i;
2313
+ });
2314
+ return slicesEnter;
2315
+ }
2316
+
2317
+ function createSlicePath(slicesEnter, arc) {
2318
+ var slicePath = slicesEnter.append("path")
2319
+ .attr("fill", function (d, i) {
2320
+ return _chart.getColor(d, i);
2321
+ })
2322
+ .on("click", onClick)
2323
+ .attr("d", function (d, i) {
2324
+ return safeArc(d, i, arc);
2325
+ });
2326
+ slicePath.transition()
2327
+ .duration(_chart.transitionDuration())
2328
+ .attrTween("d", tweenPie);
2329
+ }
2330
+
2331
+ function createTitles(slicesEnter) {
2332
+ if (_chart.renderTitle()) {
2333
+ slicesEnter.append("title").text(function (d) {
2334
+ return _chart.title()(d);
2335
+ });
2336
+ }
2337
+ }
2338
+
2339
+ function createLabels(pieData, arc) {
2340
+ if (_chart.renderLabel()) {
2341
+ var labels = _g.selectAll("text." + _sliceCssClass)
2342
+ .data(pieData);
2343
+
2344
+ labels.exit().remove();
2345
+
2346
+ var labelsEnter = labels
2347
+ .enter()
2348
+ .append("text")
2349
+ .attr("class", function (d, i) {
2350
+ return _sliceCssClass + " _" + i;
2351
+ })
2352
+ .on("click", onClick);
2353
+ dc.transition(labelsEnter, _chart.transitionDuration())
2354
+ .attr("transform", function (d) {
2355
+ d.innerRadius = _chart.innerRadius();
2356
+ d.outerRadius = _radius;
2357
+ var centroid = arc.centroid(d);
2358
+ if (isNaN(centroid[0]) || isNaN(centroid[1])) {
2359
+ return "translate(0,0)";
2360
+ } else {
2361
+ return "translate(" + centroid + ")";
2362
+ }
2363
+ })
2364
+ .attr("text-anchor", "middle")
2365
+ .text(function (d) {
2366
+ var data = d.data;
2367
+ if (sliceHasNoData(data) || sliceTooSmall(d))
2368
+ return "";
2369
+ return _chart.label()(d);
2370
+ });
2371
+ }
2372
+ }
2373
+
2374
+ function updateElements(pieData, arc) {
2375
+ updateSlicePaths(pieData, arc);
2376
+ updateLabels(pieData, arc);
2377
+ updateTitles(pieData);
2378
+ }
2379
+
2380
+ function updateSlicePaths(pieData, arc) {
2381
+ var slicePaths = _g.selectAll("g." + _sliceCssClass)
2382
+ .data(pieData)
2383
+ .select("path")
2384
+ .attr("d", function (d, i) {
2385
+ return safeArc(d, i, arc);
2386
+ });
2387
+ dc.transition(slicePaths, _chart.transitionDuration(),
2388
+ function (s) {
2389
+ s.attrTween("d", tweenPie);
2390
+ }).attr("fill", function (d, i) {
2391
+ return _chart.getColor(d, i);
2392
+ });
2393
+ }
2394
+
2395
+ function updateLabels(pieData, arc) {
2396
+ if (_chart.renderLabel()) {
2397
+ var labels = _g.selectAll("text." + _sliceCssClass)
2398
+ .data(pieData);
2399
+ dc.transition(labels, _chart.transitionDuration())
2400
+ .attr("transform", function (d) {
2401
+ d.innerRadius = _chart.innerRadius();
2402
+ d.outerRadius = _radius;
2403
+ var centroid = arc.centroid(d);
2404
+ if (isNaN(centroid[0]) || isNaN(centroid[1])) {
2405
+ return "translate(0,0)";
2406
+ } else {
2407
+ return "translate(" + centroid + ")";
2408
+ }
2409
+ })
2410
+ .attr("text-anchor", "middle")
2411
+ .text(function (d) {
2412
+ var data = d.data;
2413
+ if (sliceHasNoData(data) || sliceTooSmall(d))
2414
+ return "";
2415
+ return _chart.label()(d);
2416
+ });
2417
+ }
2418
+ }
2419
+
2420
+ function updateTitles(pieData) {
2421
+ if (_chart.renderTitle()) {
2422
+ _g.selectAll("g." + _sliceCssClass)
2423
+ .data(pieData)
2424
+ .select("title")
2425
+ .text(function (d) {
2426
+ return _chart.title()(d);
2427
+ });
2428
+ }
2429
+ }
2430
+
2431
+ function removeElements(slices) {
2432
+ slices.exit().remove();
2433
+ }
2434
+
2435
+ function highlightFilter() {
2436
+ if (_chart.hasFilter()) {
2437
+ _chart.selectAll("g." + _sliceCssClass).each(function (d) {
2438
+ if (_chart.isSelectedSlice(d)) {
2439
+ _chart.highlightSelected(this);
2440
+ } else {
2441
+ _chart.fadeDeselected(this);
2442
+ }
2443
+ });
2444
+ } else {
2445
+ _chart.selectAll("g." + _sliceCssClass).each(function (d) {
2446
+ _chart.resetHighlight(this);
2447
+ });
2448
+ }
2449
+ }
2450
+
2451
+ _chart.innerRadius = function (r) {
2452
+ if (!arguments.length) return _innerRadius;
2453
+ _innerRadius = r;
2454
+ return _chart;
2455
+ };
2456
+
2457
+ _chart.radius = function (r) {
2458
+ if (!arguments.length) return _radius;
2459
+ _radius = r;
2460
+ return _chart;
2461
+ };
2462
+
2463
+ _chart.cx = function () {
2464
+ return _chart.width() / 2;
2465
+ };
2466
+
2467
+ _chart.cy = function () {
2468
+ return _chart.height() / 2;
2469
+ };
2470
+
2471
+ _chart.buildArcs = function () {
2472
+ return d3.svg.arc().outerRadius(_radius).innerRadius(_innerRadius);
2473
+ };
2474
+
2475
+ _chart.isSelectedSlice = function (d) {
2476
+ return _chart.hasFilter(_chart.keyAccessor()(d.data));
2477
+ };
2478
+
2479
+ _chart.doRedraw = function () {
2480
+ drawChart();
2481
+ return _chart;
2482
+ };
2483
+
2484
+ _chart.minAngleForLabel = function (_) {
2485
+ if (!arguments.length) return _minAngleForLabel;
2486
+ _minAngleForLabel = _;
2487
+ return _chart;
2488
+ };
2489
+
2490
+ _chart.slicesCap = function (_) {
2491
+ if (!arguments.length) return _slicesCap;
2492
+ _slicesCap = _;
2493
+ return _chart;
2494
+ };
2495
+
2496
+ _chart.othersLabel = function (_) {
2497
+ if (!arguments.length) return _othersLabel;
2498
+ _othersLabel = _;
2499
+ return _chart;
2500
+ };
2501
+
2502
+ _chart.othersGrouper = function (_) {
2503
+ if (!arguments.length) return _othersGrouper;
2504
+ _othersGrouper = _;
2505
+ return _chart;
2506
+ };
2507
+
2508
+ function calculateDataPie() {
2509
+ return d3.layout.pie().sort(null).value(function (d) {
2510
+ return _chart.valueAccessor()(d);
2511
+ });
2512
+ }
2513
+
2514
+ function sliceTooSmall(d) {
2515
+ var angle = (d.endAngle - d.startAngle);
2516
+ return isNaN(angle) || angle < _minAngleForLabel;
2517
+ }
2518
+
2519
+ function sliceHasNoData(data) {
2520
+ return _chart.valueAccessor()(data) === 0;
2521
+ }
2522
+
2523
+ function tweenPie(b) {
2524
+ b.innerRadius = _chart.innerRadius();
2525
+ var current = this._current;
2526
+ if (isOffCanvas(current))
2527
+ current = {startAngle: 0, endAngle: 0};
2528
+ var i = d3.interpolate(current, b);
2529
+ this._current = i(0);
2530
+ return function (t) {
2531
+ return safeArc(i(t), 0, _chart.buildArcs());
2532
+ };
2533
+ }
2534
+
2535
+ function isOffCanvas(current) {
2536
+ return !current || isNaN(current.startAngle) || isNaN(current.endAngle);
2537
+ }
2538
+
2539
+ function onClick(d) {
2540
+ if (d.data.others)
2541
+ d.data.others.forEach(function(f) {
2542
+ _chart.filter(f);
2543
+ });
2544
+ _chart.onClick(d.data);
2545
+ }
2546
+
2547
+ function safeArc(d, i, arc) {
2548
+ var path = arc(d, i);
2549
+ if (path.indexOf("NaN") >= 0)
2550
+ path = "M0,0";
2551
+ return path;
2552
+ }
2553
+
2554
+ return _chart.anchor(parent, chartGroup);
2555
+ };
2556
+
2557
+ dc.barChart = function (parent, chartGroup) {
2558
+ var MIN_BAR_WIDTH = 1;
2559
+ var DEFAULT_GAP_BETWEEN_BARS = 2;
2560
+
2561
+ var _chart = dc.stackableChart(dc.coordinateGridChart({}));
2562
+
2563
+ var _gap = DEFAULT_GAP_BETWEEN_BARS;
2564
+ var _centerBar = false;
2565
+
2566
+ var _numberOfBars;
2567
+ var _barWidth;
2568
+
2569
+ dc.override(_chart, 'rescale', function () {
2570
+ _chart._rescale();
2571
+ _numberOfBars = undefined;
2572
+ _barWidth = undefined;
2573
+ getNumberOfBars();
2574
+ });
2575
+
2576
+ _chart.plotData = function () {
2577
+ var layers = _chart.chartBodyG().selectAll("g.stack")
2578
+ .data(_chart.stackLayers());
2579
+
2580
+ calculateBarWidth();
2581
+
2582
+ layers
2583
+ .enter()
2584
+ .append("g")
2585
+ .attr("class", function (d, i) {
2586
+ return "stack " + "_" + i;
2587
+ });
2588
+
2589
+ layers.each(function (d, i) {
2590
+ var layer = d3.select(this);
2591
+
2592
+ renderBars(layer, d, i);
2593
+ });
2594
+
2595
+ _chart.stackLayers(null);
2596
+ };
2597
+
2598
+ function barHeight(d) {
2599
+ return dc.utils.safeNumber(Math.abs(_chart.y()(d.y + d.y0) - _chart.y()(d.y0)));
2600
+ }
2601
+
2602
+ function renderBars(layer, d, i) {
2603
+ var bars = layer.selectAll("rect.bar")
2604
+ .data(d.points);
2605
+
2606
+ bars.enter()
2607
+ .append("rect")
2608
+ .attr("class", "bar")
2609
+ .attr("fill", function (d) {
2610
+ return _chart.colors()(i);
2611
+ })
2612
+ .append("title").text(_chart.title());
2613
+
2614
+ if (_chart.isOrdinal())
2615
+ bars.on("click", onClick);
2616
+
2617
+ dc.transition(bars, _chart.transitionDuration())
2618
+ .attr("x", function (d) {
2619
+ var x = _chart.x()(d.x);
2620
+ if (_centerBar || _chart.isOrdinal()) x -= _barWidth / 2;
2621
+ return dc.utils.safeNumber(x);
2622
+ })
2623
+ .attr("y", function (d) {
2624
+ var y = _chart.y()(d.y + d.y0);
2625
+
2626
+ if (d.y < 0)
2627
+ y -= barHeight(d);
2628
+
2629
+ return dc.utils.safeNumber(y);
2630
+ })
2631
+ .attr("width", _barWidth)
2632
+ .attr("height", function (d) {
2633
+ return barHeight(d);
2634
+ })
2635
+ .select("title").text(_chart.title());
2636
+
2637
+ dc.transition(bars.exit(), _chart.transitionDuration())
2638
+ .attr("height", 0)
2639
+ .remove();
2640
+ }
2641
+
2642
+ function calculateBarWidth() {
2643
+ if (_barWidth === undefined) {
2644
+ var numberOfBars = _chart.isOrdinal() ? getNumberOfBars() + 1 : getNumberOfBars();
2645
+
2646
+ var w = Math.floor((_chart.xAxisLength() - (numberOfBars - 1) * _gap) / numberOfBars);
2647
+
2648
+ if (w == Infinity || isNaN(w) || w < MIN_BAR_WIDTH)
2649
+ w = MIN_BAR_WIDTH;
2650
+
2651
+ _barWidth = w;
2652
+ }
2653
+ }
2654
+
2655
+ function getNumberOfBars() {
2656
+ if (_numberOfBars === undefined) {
2657
+ _numberOfBars = _chart.xUnitCount();
2658
+ }
2659
+
2660
+ return _numberOfBars;
2661
+ }
2662
+
2663
+ _chart.fadeDeselectedArea = function () {
2664
+ var bars = _chart.chartBodyG().selectAll("rect.bar");
2665
+ var extent = _chart.brush().extent();
2666
+
2667
+ if (_chart.isOrdinal()) {
2668
+ if (_chart.hasFilter()) {
2669
+ bars.classed(dc.constants.SELECTED_CLASS, function (d) {
2670
+ return _chart.hasFilter(_chart.keyAccessor()(d.data));
2671
+ });
2672
+ bars.classed(dc.constants.DESELECTED_CLASS, function (d) {
2673
+ return !_chart.hasFilter(_chart.keyAccessor()(d.data));
2674
+ });
2675
+ } else {
2676
+ bars.classed(dc.constants.SELECTED_CLASS, false);
2677
+ bars.classed(dc.constants.DESELECTED_CLASS, false);
2678
+ }
2679
+ } else {
2680
+ if (!_chart.brushIsEmpty(extent)) {
2681
+ var start = extent[0];
2682
+ var end = extent[1];
2683
+
2684
+ bars.classed(dc.constants.DESELECTED_CLASS, function (d) {
2685
+ var xValue = _chart.keyAccessor()(d.data);
2686
+ return xValue < start || xValue >= end;
2687
+ });
2688
+ } else {
2689
+ bars.classed(dc.constants.DESELECTED_CLASS, false);
2690
+ }
2691
+ }
2692
+ };
2693
+
2694
+ _chart.centerBar = function (_) {
2695
+ if (!arguments.length) return _centerBar;
2696
+ _centerBar = _;
2697
+ return _chart;
2698
+ };
2699
+
2700
+ function onClick(d) {
2701
+ _chart.onClick(d.data);
2702
+ }
2703
+
2704
+ _chart.gap = function (_) {
2705
+ if (!arguments.length) return _gap;
2706
+ _gap = _;
2707
+ return _chart;
2708
+ };
2709
+
2710
+ _chart.extendBrush = function () {
2711
+ var extent = _chart.brush().extent();
2712
+ if (_chart.round() && !_centerBar) {
2713
+ extent[0] = extent.map(_chart.round())[0];
2714
+ extent[1] = extent.map(_chart.round())[1];
2715
+
2716
+ _chart.chartBodyG().select(".brush")
2717
+ .call(_chart.brush().extent(extent));
2718
+ }
2719
+ return extent;
2720
+ };
2721
+
2722
+ _chart.legendHighlight = function (d) {
2723
+ _chart.select('.chart-body').selectAll('rect.bar').filter(function () {
2724
+ return d3.select(this).attr('fill') == d.color;
2725
+ }).classed('highlight', true);
2726
+ _chart.select('.chart-body').selectAll('rect.bar').filter(function () {
2727
+ return d3.select(this).attr('fill') != d.color;
2728
+ }).classed('fadeout', true);
2729
+ };
2730
+
2731
+ _chart.legendReset = function (d) {
2732
+ _chart.selectAll('.chart-body').selectAll('rect.bar').filter(function () {
2733
+ return d3.select(this).attr('fill') == d.color;
2734
+ }).classed('highlight', false);
2735
+ _chart.selectAll('.chart-body').selectAll('rect.bar').filter(function () {
2736
+ return d3.select(this).attr('fill') != d.color;
2737
+ }).classed('fadeout', false);
2738
+ };
2739
+
2740
+ return _chart.anchor(parent, chartGroup);
2741
+ };
2742
+
2743
+ dc.lineChart = function (parent, chartGroup) {
2744
+ var DEFAULT_DOT_RADIUS = 5;
2745
+ var TOOLTIP_G_CLASS = "dc-tooltip";
2746
+ var DOT_CIRCLE_CLASS = "dot";
2747
+ var Y_AXIS_REF_LINE_CLASS = "yRef";
2748
+ var X_AXIS_REF_LINE_CLASS = "xRef";
2749
+
2750
+ var _chart = dc.stackableChart(dc.coordinateGridChart({}));
2751
+ var _renderArea = false;
2752
+ var _dotRadius = DEFAULT_DOT_RADIUS;
2753
+ var _interpolate = 'linear';
2754
+ var _tension = 0.7;
2755
+
2756
+ _chart.transitionDuration(500);
2757
+
2758
+ _chart.plotData = function () {
2759
+ var layers = _chart.chartBodyG().selectAll("g.stack")
2760
+ .data(_chart.stackLayers());
2761
+
2762
+ var layersEnter = layers
2763
+ .enter()
2764
+ .append("g")
2765
+ .attr("class", function (d, i) {
2766
+ return "stack " + "_" + i;
2767
+ });
2768
+
2769
+ drawLine(layersEnter, layers);
2770
+
2771
+ drawArea(layersEnter, layers);
2772
+
2773
+ drawDots(layers);
2774
+
2775
+ _chart.stackLayers(null);
2776
+ };
2777
+
2778
+ _chart.interpolate = function(_){
2779
+ if (!arguments.length) return _interpolate;
2780
+ _interpolate = _;
2781
+ return _chart;
2782
+ };
2783
+
2784
+ _chart.tension = function(_){
2785
+ if (!arguments.length) return _tension;
2786
+ _tension = _;
2787
+ return _chart;
2788
+ };
2789
+
2790
+ _chart.renderArea = function (_) {
2791
+ if (!arguments.length) return _renderArea;
2792
+ _renderArea = _;
2793
+ return _chart;
2794
+ };
2795
+
2796
+ function drawLine(layersEnter, layers) {
2797
+ var line = d3.svg.line()
2798
+ .x(function (d) {
2799
+ return _chart.x()(d.x);
2800
+ })
2801
+ .y(function (d) {
2802
+ return _chart.y()(d.y + d.y0);
2803
+ })
2804
+ .interpolate(_interpolate)
2805
+ .tension(_tension);
2806
+
2807
+ layersEnter.append("path")
2808
+ .attr("class", "line")
2809
+ .attr("stroke", function (d, i) {
2810
+ return _chart.colors()(i);
2811
+ })
2812
+ .attr("fill", function (d, i) {
2813
+ return _chart.colors()(i);
2814
+ });
2815
+
2816
+ dc.transition(layers.select("path.line"), _chart.transitionDuration())
2817
+ .attr("d", function (d) {
2818
+ return safeD(line(d.points));
2819
+ });
2820
+ }
2821
+
2822
+ function drawArea(layersEnter, layers) {
2823
+ if (_renderArea) {
2824
+ var area = d3.svg.area()
2825
+ .x(function (d) {
2826
+ return _chart.x()(d.x);
2827
+ })
2828
+ .y(function (d) {
2829
+ return _chart.y()(d.y + d.y0);
2830
+ })
2831
+ .y0(function (d) {
2832
+ return _chart.y()(d.y0);
2833
+ })
2834
+ .interpolate(_interpolate)
2835
+ .tension(_tension);
2836
+
2837
+ layersEnter.append("path")
2838
+ .attr("class", "area")
2839
+ .attr("fill", function (d, i) {
2840
+ return _chart.colors()(i);
2841
+ })
2842
+ .attr("d", function (d) {
2843
+ return safeD(area(d.points));
2844
+ });
2845
+
2846
+ dc.transition(layers.select("path.area"), _chart.transitionDuration())
2847
+ .attr("d", function (d) {
2848
+ return safeD(area(d.points));
2849
+ });
2850
+ }
2851
+ }
2852
+
2853
+ function safeD(d){
2854
+ return (!d || d.indexOf("NaN") >= 0) ? "M0,0" : d;
2855
+ }
2856
+
2857
+ function drawDots(layersEnter) {
2858
+ if (!_chart.brushOn()) {
2859
+ layersEnter.each(function (d, i) {
2860
+ var layer = d3.select(this);
2861
+
2862
+ var g = layer.select("g." + TOOLTIP_G_CLASS);
2863
+ if (g.empty()) g = layer.append("g").attr("class", TOOLTIP_G_CLASS);
2864
+
2865
+ createRefLines(g);
2866
+
2867
+ var dots = g.selectAll("circle." + DOT_CIRCLE_CLASS)
2868
+ .data(g.datum().points);
2869
+
2870
+ dots.enter()
2871
+ .append("circle")
2872
+ .attr("class", DOT_CIRCLE_CLASS)
2873
+ .attr("r", _dotRadius)
2874
+ .attr("fill", function (d) {
2875
+ return _chart.colors()(i);
2876
+ })
2877
+ .style("fill-opacity", 1e-6)
2878
+ .style("stroke-opacity", 1e-6)
2879
+ .on("mousemove", function (d) {
2880
+ var dot = d3.select(this);
2881
+ showDot(dot);
2882
+ showRefLines(dot, g);
2883
+ })
2884
+ .on("mouseout", function (d) {
2885
+ var dot = d3.select(this);
2886
+ hideDot(dot);
2887
+ hideRefLines(g);
2888
+ })
2889
+ .append("title").text(_chart.title());
2890
+
2891
+ dots.attr("cx", function (d) {
2892
+ return dc.utils.safeNumber(_chart.x()(d.x));
2893
+ })
2894
+ .attr("cy", function (d) {
2895
+ return dc.utils.safeNumber(_chart.y()(d.y + d.y0));
2896
+ })
2897
+ .select("title").text(_chart.title());
2898
+
2899
+ dots.exit().remove();
2900
+ });
2901
+ }
2902
+ }
2903
+
2904
+ function createRefLines(g) {
2905
+ var yRefLine = g.select("path." + Y_AXIS_REF_LINE_CLASS).empty() ? g.append("path").attr("class", Y_AXIS_REF_LINE_CLASS) : g.select("path." + Y_AXIS_REF_LINE_CLASS);
2906
+ yRefLine.style("display", "none").attr("stroke-dasharray", "5,5");
2907
+
2908
+ var xRefLine = g.select("path." + X_AXIS_REF_LINE_CLASS).empty() ? g.append("path").attr("class", X_AXIS_REF_LINE_CLASS) : g.select("path." + X_AXIS_REF_LINE_CLASS);
2909
+ xRefLine.style("display", "none").attr("stroke-dasharray", "5,5");
2910
+ }
2911
+
2912
+ function showDot(dot) {
2913
+ dot.style("fill-opacity", 0.8);
2914
+ dot.style("stroke-opacity", 0.8);
2915
+ return dot;
2916
+ }
2917
+
2918
+ function showRefLines(dot, g) {
2919
+ var x = dot.attr("cx");
2920
+ var y = dot.attr("cy");
2921
+ g.select("path." + Y_AXIS_REF_LINE_CLASS).style("display", "").attr("d", "M0 " + y + "L" + (x) + " " + (y));
2922
+ g.select("path." + X_AXIS_REF_LINE_CLASS).style("display", "").attr("d", "M" + x + " " + _chart.yAxisHeight() + "L" + x + " " + y);
2923
+ }
2924
+
2925
+ function hideDot(dot) {
2926
+ dot.style("fill-opacity", 1e-6).style("stroke-opacity", 1e-6);
2927
+ }
2928
+
2929
+ function hideRefLines(g) {
2930
+ g.select("path." + Y_AXIS_REF_LINE_CLASS).style("display", "none");
2931
+ g.select("path." + X_AXIS_REF_LINE_CLASS).style("display", "none");
2932
+ }
2933
+
2934
+ _chart.dotRadius = function (_) {
2935
+ if (!arguments.length) return _dotRadius;
2936
+ _dotRadius = _;
2937
+ return _chart;
2938
+ };
2939
+
2940
+ _chart.legendHighlight = function (d) {
2941
+ _chart.selectAll('.chart-body').selectAll('path').filter(function () {
2942
+ return d3.select(this).attr('fill') == d.color;
2943
+ }).classed('highlight', true);
2944
+ _chart.selectAll('.chart-body').selectAll('path').filter(function () {
2945
+ return d3.select(this).attr('fill') != d.color;
2946
+ }).classed('fadeout', true);
2947
+ };
2948
+
2949
+ _chart.legendReset = function (d) {
2950
+ _chart.selectAll('.chart-body').selectAll('path').filter(function () {
2951
+ return d3.select(this).attr('fill') == d.color;
2952
+ }).classed('highlight', false);
2953
+ _chart.selectAll('.chart-body').selectAll('path').filter(function () {
2954
+ return d3.select(this).attr('fill') != d.color;
2955
+ }).classed('fadeout', false);
2956
+ };
2957
+
2958
+ return _chart.anchor(parent, chartGroup);
2959
+ };
2960
+
2961
+ dc.dataCount = function(parent, chartGroup) {
2962
+ var _formatNumber = d3.format(",d");
2963
+ var _chart = dc.baseChart({});
2964
+
2965
+ _chart.doRender = function() {
2966
+ _chart.selectAll(".total-count").text(_formatNumber(_chart.dimension().size()));
2967
+ _chart.selectAll(".filter-count").text(_formatNumber(_chart.group().value()));
2968
+
2969
+ return _chart;
2970
+ };
2971
+
2972
+ _chart.doRedraw = function(){
2973
+ return _chart.doRender();
2974
+ };
2975
+
2976
+ return _chart.anchor(parent, chartGroup);
2977
+ };
2978
+
2979
+ dc.dataTable = function(parent, chartGroup) {
2980
+ var LABEL_CSS_CLASS = "dc-table-label";
2981
+ var ROW_CSS_CLASS = "dc-table-row";
2982
+ var COLUMN_CSS_CLASS = "dc-table-column";
2983
+ var GROUP_CSS_CLASS = "dc-table-group";
2984
+
2985
+ var _chart = dc.baseChart({});
2986
+
2987
+ var _size = 25;
2988
+ var _columns = [];
2989
+ var _sortBy = function(d) {
2990
+ return d;
2991
+ };
2992
+ var _order = d3.ascending;
2993
+ var _sort;
2994
+
2995
+ _chart.doRender = function() {
2996
+ _chart.selectAll("tbody").remove();
2997
+
2998
+ renderRows(renderGroups());
2999
+
3000
+ return _chart;
3001
+ };
3002
+
3003
+ function renderGroups() {
3004
+ var groups = _chart.root().selectAll("tbody")
3005
+ .data(nestEntries(), function(d) {
3006
+ return _chart.keyAccessor()(d);
3007
+ });
3008
+
3009
+ var rowGroup = groups
3010
+ .enter()
3011
+ .append("tbody");
3012
+
3013
+ rowGroup
3014
+ .append("tr")
3015
+ .attr("class", GROUP_CSS_CLASS)
3016
+ .append("td")
3017
+ .attr("class", LABEL_CSS_CLASS)
3018
+ .attr("colspan", _columns.length)
3019
+ .html(function(d) {
3020
+ return _chart.keyAccessor()(d);
3021
+ });
3022
+
3023
+ groups.exit().remove();
3024
+
3025
+ return rowGroup;
3026
+ }
3027
+
3028
+ function nestEntries() {
3029
+ if (!_sort)
3030
+ _sort = crossfilter.quicksort.by(_sortBy);
3031
+
3032
+ var entries = _chart.dimension().top(_size);
3033
+
3034
+ return d3.nest()
3035
+ .key(_chart.group())
3036
+ .sortKeys(_order)
3037
+ .sortValues(_order)
3038
+ .entries(_sort(entries, 0, entries.length));
3039
+ }
3040
+
3041
+ function renderRows(groups) {
3042
+ var rows = groups.order()
3043
+ .selectAll("tr." + ROW_CSS_CLASS)
3044
+ .data(function(d) {
3045
+ return d.values;
3046
+ });
3047
+
3048
+ var rowEnter = rows.enter()
3049
+ .append("tr")
3050
+ .attr("class", ROW_CSS_CLASS);
3051
+
3052
+ for (var i = 0; i < _columns.length; ++i) {
3053
+ var f = _columns[i];
3054
+ rowEnter.append("td")
3055
+ .attr("class", COLUMN_CSS_CLASS + " _" + i)
3056
+ .html(function(d) {
3057
+ return f(d);
3058
+ });
3059
+ }
3060
+
3061
+ rows.exit().remove();
3062
+
3063
+ return rows;
3064
+ }
3065
+
3066
+ _chart.doRedraw = function() {
3067
+ return _chart.doRender();
3068
+ };
3069
+
3070
+ _chart.size = function(s) {
3071
+ if (!arguments.length) return _size;
3072
+ _size = s;
3073
+ return _chart;
3074
+ };
3075
+
3076
+ _chart.columns = function(_) {
3077
+ if (!arguments.length) return _columns;
3078
+ _columns = _;
3079
+ return _chart;
3080
+ };
3081
+
3082
+ _chart.sortBy = function(_) {
3083
+ if (!arguments.length) return _sortBy;
3084
+ _sortBy = _;
3085
+ return _chart;
3086
+ };
3087
+
3088
+ _chart.order = function(_) {
3089
+ if (!arguments.length) return _order;
3090
+ _order = _;
3091
+ return _chart;
3092
+ };
3093
+
3094
+ return _chart.anchor(parent, chartGroup);
3095
+ };
3096
+
3097
+ dc.bubbleChart = function(parent, chartGroup) {
3098
+ var _chart = dc.abstractBubbleChart(dc.coordinateGridChart({}));
3099
+
3100
+ var _elasticRadius = false;
3101
+
3102
+ _chart.transitionDuration(750);
3103
+
3104
+ var bubbleLocator = function(d) {
3105
+ return "translate(" + (bubbleX(d)) + "," + (bubbleY(d)) + ")";
3106
+ };
3107
+
3108
+ _chart.elasticRadius = function(_) {
3109
+ if (!arguments.length) return _elasticRadius;
3110
+ _elasticRadius = _;
3111
+ return _chart;
3112
+ };
3113
+
3114
+ _chart.plotData = function() {
3115
+ if (_elasticRadius)
3116
+ _chart.r().domain([_chart.rMin(), _chart.rMax()]);
3117
+
3118
+ _chart.r().range([_chart.MIN_RADIUS, _chart.xAxisLength() * _chart.maxBubbleRelativeSize()]);
3119
+
3120
+ var bubbleG = _chart.chartBodyG().selectAll("g." + _chart.BUBBLE_NODE_CLASS)
3121
+ .data(_chart.group().all());
3122
+
3123
+ renderNodes(bubbleG);
3124
+
3125
+ updateNodes(bubbleG);
3126
+
3127
+ removeNodes(bubbleG);
3128
+
3129
+ _chart.fadeDeselectedArea();
3130
+ };
3131
+
3132
+ function renderNodes(bubbleG) {
3133
+ var bubbleGEnter = bubbleG.enter().append("g");
3134
+
3135
+ bubbleGEnter
3136
+ .attr("class", _chart.BUBBLE_NODE_CLASS)
3137
+ .attr("transform", bubbleLocator)
3138
+ .append("circle").attr("class", function(d, i) {
3139
+ return _chart.BUBBLE_CLASS + " _" + i;
3140
+ })
3141
+ .on("click", _chart.onClick)
3142
+ .attr("fill", _chart.initBubbleColor)
3143
+ .attr("r", 0);
3144
+ dc.transition(bubbleG, _chart.transitionDuration())
3145
+ .attr("r", function(d) {
3146
+ return _chart.bubbleR(d);
3147
+ })
3148
+ .attr("opacity", function(d) {
3149
+ return (_chart.bubbleR(d) > 0) ? 1 : 0;
3150
+ });
3151
+
3152
+ _chart.doRenderLabel(bubbleGEnter);
3153
+
3154
+ _chart.doRenderTitles(bubbleGEnter);
3155
+ }
3156
+
3157
+ function updateNodes(bubbleG) {
3158
+ dc.transition(bubbleG, _chart.transitionDuration())
3159
+ .attr("transform", bubbleLocator)
3160
+ .selectAll("circle." + _chart.BUBBLE_CLASS)
3161
+ .attr("fill", _chart.updateBubbleColor)
3162
+ .attr("r", function(d) {
3163
+ return _chart.bubbleR(d);
3164
+ })
3165
+ .attr("opacity", function(d) {
3166
+ return (_chart.bubbleR(d) > 0) ? 1 : 0;
3167
+ });
3168
+
3169
+ _chart.doUpdateLabels(bubbleG);
3170
+ _chart.doUpdateTitles(bubbleG);
3171
+ }
3172
+
3173
+ function removeNodes(bubbleG) {
3174
+ bubbleG.exit().remove();
3175
+ }
3176
+
3177
+ function bubbleX(d) {
3178
+ var x = _chart.x()(_chart.keyAccessor()(d));
3179
+ if (isNaN(x))
3180
+ x = 0;
3181
+ return x;
3182
+ }
3183
+
3184
+ function bubbleY(d) {
3185
+ var y = _chart.y()(_chart.valueAccessor()(d));
3186
+ if (isNaN(y))
3187
+ y = 0;
3188
+ return y;
3189
+ }
3190
+
3191
+ _chart.renderBrush = function(g) {
3192
+ // override default x axis brush from parent chart
3193
+ };
3194
+
3195
+ _chart.redrawBrush = function(g) {
3196
+ // override default x axis brush from parent chart
3197
+ _chart.fadeDeselectedArea();
3198
+ };
3199
+
3200
+ return _chart.anchor(parent, chartGroup);
3201
+ };
3202
+
3203
+ dc.compositeChart = function (parent, chartGroup) {
3204
+ var SUB_CHART_CLASS = "sub";
3205
+
3206
+ var _chart = dc.coordinateGridChart({});
3207
+ var _children = [];
3208
+
3209
+ _chart.transitionDuration(500);
3210
+
3211
+ dc.override(_chart, "generateG", function () {
3212
+ var g = this._generateG();
3213
+
3214
+ for (var i = 0; i < _children.length; ++i) {
3215
+ var child = _children[i];
3216
+
3217
+ generateChildG(child, i);
3218
+
3219
+ if (child.dimension() === undefined) child.dimension(_chart.dimension());
3220
+ if (child.group() === undefined) child.group(_chart.group());
3221
+ child.chartGroup(_chart.chartGroup());
3222
+ child.svg(_chart.svg());
3223
+ child.xUnits(_chart.xUnits());
3224
+ child.transitionDuration(_chart.transitionDuration());
3225
+ child.brushOn(_chart.brushOn());
3226
+ }
3227
+
3228
+ return g;
3229
+ });
3230
+
3231
+ function generateChildG(child, i) {
3232
+ child.generateG(_chart.g());
3233
+ child.g().attr("class", SUB_CHART_CLASS + " _" + i);
3234
+ }
3235
+
3236
+ _chart.plotData = function () {
3237
+ for (var i = 0; i < _children.length; ++i) {
3238
+ var child = _children[i];
3239
+
3240
+ if (child.g() === undefined) {
3241
+ generateChildG(child, i);
3242
+ }
3243
+
3244
+ child.x(_chart.x());
3245
+ child.y(_chart.y());
3246
+ child.xAxis(_chart.xAxis());
3247
+ child.yAxis(_chart.yAxis());
3248
+
3249
+ child.plotData();
3250
+
3251
+ child.activateRenderlets();
3252
+ }
3253
+ };
3254
+
3255
+ _chart.fadeDeselectedArea = function () {
3256
+ for (var i = 0; i < _children.length; ++i) {
3257
+ var child = _children[i];
3258
+ child.brush(_chart.brush());
3259
+ child.fadeDeselectedArea();
3260
+ }
3261
+ };
3262
+
3263
+ _chart.compose = function (charts) {
3264
+ _children = charts;
3265
+ for (var i = 0; i < _children.length; ++i) {
3266
+ var child = _children[i];
3267
+ child.height(_chart.height());
3268
+ child.width(_chart.width());
3269
+ child.margins(_chart.margins());
3270
+ }
3271
+ return _chart;
3272
+ };
3273
+
3274
+ _chart.children = function () {
3275
+ return _children;
3276
+ };
3277
+
3278
+ function getAllYAxisMinFromChildCharts() {
3279
+ var allMins = [];
3280
+ for (var i = 0; i < _children.length; ++i) {
3281
+ allMins.push(_children[i].yAxisMin());
3282
+ }
3283
+ return allMins;
3284
+ }
3285
+
3286
+ _chart.yAxisMin = function () {
3287
+ return d3.min(getAllYAxisMinFromChildCharts());
3288
+ };
3289
+
3290
+ function getAllYAxisMaxFromChildCharts() {
3291
+ var allMaxes = [];
3292
+ for (var i = 0; i < _children.length; ++i) {
3293
+ allMaxes.push(_children[i].yAxisMax());
3294
+ }
3295
+ return allMaxes;
3296
+ }
3297
+
3298
+ _chart.yAxisMax = function () {
3299
+ return dc.utils.add(d3.max(getAllYAxisMaxFromChildCharts()), _chart.yAxisPadding());
3300
+ };
3301
+
3302
+ function getAllXAxisMinFromChildCharts() {
3303
+ var allMins = [];
3304
+ for (var i = 0; i < _children.length; ++i) {
3305
+ allMins.push(_children[i].xAxisMin());
3306
+ }
3307
+ return allMins;
3308
+ }
3309
+
3310
+ _chart.xAxisMin = function () {
3311
+ return dc.utils.subtract(d3.min(getAllXAxisMinFromChildCharts()), _chart.xAxisPadding());
3312
+ };
3313
+
3314
+ function getAllXAxisMaxFromChildCharts() {
3315
+ var allMaxes = [];
3316
+ for (var i = 0; i < _children.length; ++i) {
3317
+ allMaxes.push(_children[i].xAxisMax());
3318
+ }
3319
+ return allMaxes;
3320
+ }
3321
+
3322
+ _chart.xAxisMax = function () {
3323
+ return dc.utils.add(d3.max(getAllXAxisMaxFromChildCharts()), _chart.xAxisPadding());
3324
+ };
3325
+
3326
+ _chart.legendables = function () {
3327
+ var items = [];
3328
+
3329
+ for (var j = 0; j < _children.length; ++j) {
3330
+ var childChart = _children[j];
3331
+ childChart.allGroups().forEach(function (g, i) {
3332
+ items.push(dc.utils.createLegendable(childChart, g, i, childChart.getValueAccessorByIndex(i)));
3333
+ });
3334
+ }
3335
+
3336
+ return items;
3337
+ };
3338
+
3339
+ _chart.legendHighlight = function (d) {
3340
+ for (var j = 0; j < _children.length; ++j) {
3341
+ var child = _children[j];
3342
+ child.legendHighlight(d);
3343
+ }
3344
+ };
3345
+
3346
+ _chart.legendReset = function (d) {
3347
+ for (var j = 0; j < _children.length; ++j) {
3348
+ var child = _children[j];
3349
+ child.legendReset(d);
3350
+ }
3351
+ };
3352
+
3353
+ return _chart.anchor(parent, chartGroup);
3354
+ };
3355
+
3356
+ dc.geoChoroplethChart = function (parent, chartGroup) {
3357
+ var _chart = dc.colorChart(dc.baseChart({}));
3358
+
3359
+ _chart.colorAccessor(function (d, i) {
3360
+ return d;
3361
+ });
3362
+
3363
+ var _geoPath = d3.geo.path();
3364
+ var _projectionFlag;
3365
+
3366
+ var _geoJsons = [];
3367
+
3368
+ _chart.doRender = function () {
3369
+ _chart.resetSvg();
3370
+ for (var layerIndex = 0; layerIndex < _geoJsons.length; ++layerIndex) {
3371
+ var states = _chart.svg().append("g")
3372
+ .attr("class", "layer" + layerIndex);
3373
+
3374
+ var regionG = states.selectAll("g." + geoJson(layerIndex).name)
3375
+ .data(geoJson(layerIndex).data)
3376
+ .enter()
3377
+ .append("g")
3378
+ .attr("class", geoJson(layerIndex).name);
3379
+
3380
+ regionG
3381
+ .append("path")
3382
+ .attr("fill", "white")
3383
+ .attr("d", _geoPath);
3384
+
3385
+ regionG.append("title");
3386
+
3387
+ plotData(layerIndex);
3388
+ }
3389
+ _projectionFlag = false;
3390
+ };
3391
+
3392
+ function plotData(layerIndex) {
3393
+ var maxValue = dc.utils.groupMax(_chart.group(), _chart.valueAccessor());
3394
+ var data = generateLayeredData();
3395
+
3396
+ if (isDataLayer(layerIndex)) {
3397
+ var regionG = renderRegionG(layerIndex);
3398
+
3399
+ renderPaths(regionG, layerIndex, data, maxValue);
3400
+
3401
+ renderTitle(regionG, layerIndex, data);
3402
+ }
3403
+ }
3404
+
3405
+ function generateLayeredData() {
3406
+ var data = {};
3407
+ var groupAll = _chart.group().all();
3408
+ for (var i = 0; i < groupAll.length; ++i) {
3409
+ data[_chart.keyAccessor()(groupAll[i])] = _chart.valueAccessor()(groupAll[i]);
3410
+ }
3411
+ return data;
3412
+ }
3413
+
3414
+ function isDataLayer(layerIndex) {
3415
+ return geoJson(layerIndex).keyAccessor;
3416
+ }
3417
+
3418
+ function renderRegionG(layerIndex) {
3419
+ var regionG = _chart.svg()
3420
+ .selectAll(layerSelector(layerIndex))
3421
+ .classed("selected", function (d) {
3422
+ return isSelected(layerIndex, d);
3423
+ })
3424
+ .classed("deselected", function (d) {
3425
+ return isDeselected(layerIndex, d);
3426
+ })
3427
+ .attr("class", function (d) {
3428
+ var layerNameClass = geoJson(layerIndex).name;
3429
+ var regionClass = dc.utils.nameToId(geoJson(layerIndex).keyAccessor(d));
3430
+ var baseClasses = layerNameClass + " " + regionClass;
3431
+ if (isSelected(layerIndex, d)) baseClasses += " selected";
3432
+ if (isDeselected(layerIndex, d)) baseClasses += " deselected";
3433
+ return baseClasses;
3434
+ });
3435
+ return regionG;
3436
+ }
3437
+
3438
+ function layerSelector(layerIndex) {
3439
+ return "g.layer" + layerIndex + " g." + geoJson(layerIndex).name;
3440
+ }
3441
+
3442
+ function isSelected(layerIndex, d) {
3443
+ return _chart.hasFilter() && _chart.hasFilter(getKey(layerIndex, d));
3444
+ }
3445
+
3446
+ function isDeselected(layerIndex, d) {
3447
+ return _chart.hasFilter() && !_chart.hasFilter(getKey(layerIndex, d));
3448
+ }
3449
+
3450
+ function getKey(layerIndex, d) {
3451
+ return geoJson(layerIndex).keyAccessor(d);
3452
+ }
3453
+
3454
+ function geoJson(index) {
3455
+ return _geoJsons[index];
3456
+ }
3457
+
3458
+ function renderPaths(regionG, layerIndex, data) {
3459
+ var paths = regionG
3460
+ .select("path")
3461
+ .attr("fill", function (d) {
3462
+ var currentFill = d3.select(this).attr("fill");
3463
+ if (currentFill)
3464
+ return currentFill;
3465
+ return "none";
3466
+ })
3467
+ .on("click", function (d) {
3468
+ return _chart.onClick(d, layerIndex);
3469
+ });
3470
+
3471
+ dc.transition(paths, _chart.transitionDuration()).attr("fill", function (d, i) {
3472
+ return _chart.getColor(data[geoJson(layerIndex).keyAccessor(d)], i);
3473
+ });
3474
+ }
3475
+
3476
+ _chart.onClick = function (d, layerIndex) {
3477
+ var selectedRegion = geoJson(layerIndex).keyAccessor(d);
3478
+ dc.events.trigger(function () {
3479
+ _chart.filter(selectedRegion);
3480
+ dc.redrawAll(_chart.chartGroup());
3481
+ });
3482
+ };
3483
+
3484
+ function renderTitle(regionG, layerIndex, data) {
3485
+ if (_chart.renderTitle()) {
3486
+ regionG.selectAll("title").text(function (d) {
3487
+ var key = getKey(layerIndex, d);
3488
+ var value = data[key];
3489
+ return _chart.title()({key: key, value: value});
3490
+ });
3491
+ }
3492
+ }
3493
+
3494
+ _chart.doRedraw = function () {
3495
+ for (var layerIndex = 0; layerIndex < _geoJsons.length; ++layerIndex) {
3496
+ plotData(layerIndex);
3497
+ if(_projectionFlag) {
3498
+ _chart.svg().selectAll("g." + geoJson(layerIndex).name + " path").attr("d", _geoPath);
3499
+ }
3500
+ }
3501
+ _projectionFlag = false;
3502
+ };
3503
+
3504
+ _chart.overlayGeoJson = function (json, name, keyAccessor) {
3505
+ for (var i = 0; i < _geoJsons.length; ++i) {
3506
+ if (_geoJsons[i].name == name) {
3507
+ _geoJsons[i].data = json;
3508
+ _geoJsons[i].keyAccessor = keyAccessor;
3509
+ return _chart;
3510
+ }
3511
+ }
3512
+ _geoJsons.push({name: name, data: json, keyAccessor: keyAccessor});
3513
+ return _chart;
3514
+ };
3515
+
3516
+ _chart.projection = function (projection) {
3517
+ _geoPath.projection(projection);
3518
+ _projectionFlag = true;
3519
+ return _chart;
3520
+ };
3521
+
3522
+ _chart.geoJsons = function () {
3523
+ return _geoJsons;
3524
+ };
3525
+
3526
+ _chart.removeGeoJson = function (name) {
3527
+ var geoJsons = [];
3528
+
3529
+ for (var i = 0; i < _geoJsons.length; ++i) {
3530
+ var layer = _geoJsons[i];
3531
+ if (layer.name != name) {
3532
+ geoJsons.push(layer);
3533
+ }
3534
+ }
3535
+
3536
+ _geoJsons = geoJsons;
3537
+
3538
+ return _chart;
3539
+ };
3540
+
3541
+ return _chart.anchor(parent, chartGroup);
3542
+ };
3543
+
3544
+ dc.bubbleOverlay = function(root, chartGroup) {
3545
+ var BUBBLE_OVERLAY_CLASS = "bubble-overlay";
3546
+ var BUBBLE_NODE_CLASS = "node";
3547
+ var BUBBLE_CLASS = "bubble";
3548
+
3549
+ var _chart = dc.abstractBubbleChart(dc.baseChart({}));
3550
+ var _g;
3551
+ var _points = [];
3552
+
3553
+ _chart.transitionDuration(750);
3554
+
3555
+ _chart.radiusValueAccessor(function(d) {
3556
+ return d.value;
3557
+ });
3558
+
3559
+ _chart.point = function(name, x, y) {
3560
+ _points.push({name: name, x: x, y: y});
3561
+ return _chart;
3562
+ };
3563
+
3564
+ _chart.doRender = function() {
3565
+ _g = initOverlayG();
3566
+
3567
+ _chart.r().range([_chart.MIN_RADIUS, _chart.width() * _chart.maxBubbleRelativeSize()]);
3568
+
3569
+ initializeBubbles();
3570
+
3571
+ _chart.fadeDeselectedArea();
3572
+
3573
+ return _chart;
3574
+ };
3575
+
3576
+ function initOverlayG() {
3577
+ _g = _chart.select("g." + BUBBLE_OVERLAY_CLASS);
3578
+ if (_g.empty())
3579
+ _g = _chart.svg().append("g").attr("class", BUBBLE_OVERLAY_CLASS);
3580
+ return _g;
3581
+ }
3582
+
3583
+ function initializeBubbles() {
3584
+ var data = mapData();
3585
+
3586
+ _points.forEach(function(point) {
3587
+ var nodeG = getNodeG(point, data);
3588
+
3589
+ var circle = nodeG.select("circle." + BUBBLE_CLASS);
3590
+
3591
+ if (circle.empty())
3592
+ circle = nodeG.append("circle")
3593
+ .attr("class", BUBBLE_CLASS)
3594
+ .attr("r", 0)
3595
+ .attr("fill", _chart.initBubbleColor)
3596
+ .on("click", _chart.onClick);
3597
+
3598
+ dc.transition(circle, _chart.transitionDuration())
3599
+ .attr("r", function(d) {
3600
+ return _chart.bubbleR(d);
3601
+ });
3602
+
3603
+ _chart.doRenderLabel(nodeG);
3604
+
3605
+ _chart.doRenderTitles(nodeG);
3606
+ });
3607
+ }
3608
+
3609
+ function mapData() {
3610
+ var data = {};
3611
+ _chart.group().all().forEach(function(datum) {
3612
+ data[_chart.keyAccessor()(datum)] = datum;
3613
+ });
3614
+ return data;
3615
+ }
3616
+
3617
+ function getNodeG(point, data) {
3618
+ var bubbleNodeClass = BUBBLE_NODE_CLASS + " " + dc.utils.nameToId(point.name);
3619
+
3620
+ var nodeG = _g.select("g." + dc.utils.nameToId(point.name));
3621
+
3622
+ if (nodeG.empty()) {
3623
+ nodeG = _g.append("g")
3624
+ .attr("class", bubbleNodeClass)
3625
+ .attr("transform", "translate(" + point.x + "," + point.y + ")");
3626
+ }
3627
+
3628
+ nodeG.datum(data[point.name]);
3629
+
3630
+ return nodeG;
3631
+ }
3632
+
3633
+ _chart.doRedraw = function() {
3634
+ updateBubbles();
3635
+
3636
+ _chart.fadeDeselectedArea();
3637
+
3638
+ return _chart;
3639
+ };
3640
+
3641
+ function updateBubbles() {
3642
+ var data = mapData();
3643
+
3644
+ _points.forEach(function(point) {
3645
+ var nodeG = getNodeG(point, data);
3646
+
3647
+ var circle = nodeG.select("circle." + BUBBLE_CLASS);
3648
+
3649
+ dc.transition(circle, _chart.transitionDuration())
3650
+ .attr("r", function(d) {
3651
+ return _chart.bubbleR(d);
3652
+ })
3653
+ .attr("fill", _chart.updateBubbleColor);
3654
+
3655
+ _chart.doUpdateLabels(nodeG);
3656
+
3657
+ _chart.doUpdateTitles(nodeG);
3658
+ });
3659
+ }
3660
+
3661
+ _chart.debug = function(flag) {
3662
+ if(flag){
3663
+ var debugG = _chart.select("g." + dc.constants.DEBUG_GROUP_CLASS);
3664
+
3665
+ if(debugG.empty())
3666
+ debugG = _chart.svg()
3667
+ .append("g")
3668
+ .attr("class", dc.constants.DEBUG_GROUP_CLASS);
3669
+
3670
+ var debugText = debugG.append("text")
3671
+ .attr("x", 10)
3672
+ .attr("y", 20);
3673
+
3674
+ debugG
3675
+ .append("rect")
3676
+ .attr("width", _chart.width())
3677
+ .attr("height", _chart.height())
3678
+ .on("mousemove", function() {
3679
+ var position = d3.mouse(debugG.node());
3680
+ var msg = position[0] + ", " + position[1];
3681
+ debugText.text(msg);
3682
+ });
3683
+ }else{
3684
+ _chart.selectAll(".debug").remove();
3685
+ }
3686
+
3687
+ return _chart;
3688
+ };
3689
+
3690
+ _chart.anchor(root, chartGroup);
3691
+
3692
+ return _chart;
3693
+ };
3694
+
3695
+ dc.rowChart = function (parent, chartGroup) {
3696
+
3697
+ var _g;
3698
+
3699
+ var _labelOffsetX = 10;
3700
+
3701
+ var _labelOffsetY = 15;
3702
+
3703
+ var _gap = 5;
3704
+
3705
+ var _rowCssClass = "row";
3706
+
3707
+ var _chart = dc.marginable(dc.colorChart(dc.baseChart({})));
3708
+
3709
+ var _x;
3710
+
3711
+ var _elasticX;
3712
+
3713
+ var _xAxis = d3.svg.axis().orient("bottom");
3714
+
3715
+ function calculateAxisScale() {
3716
+ if (!_x || _elasticX) {
3717
+ var extent = d3.extent(_chart.group().all(), _chart.valueAccessor());
3718
+ if (extent[0] > 0) extent[0] = 0;
3719
+ _x = d3.scale.linear().domain(extent)
3720
+ .range([0, _chart.effectiveWidth()]);
3721
+
3722
+ _xAxis.scale(_x);
3723
+ }
3724
+ }
3725
+
3726
+ function drawAxis() {
3727
+ var axisG = _g.select("g.axis");
3728
+
3729
+ calculateAxisScale();
3730
+
3731
+ if (axisG.empty())
3732
+ axisG = _g.append("g").attr("class", "axis")
3733
+ .attr("transform", "translate(0, " + _chart.effectiveHeight() + ")");
3734
+
3735
+ dc.transition(axisG, _chart.transitionDuration())
3736
+ .call(_xAxis);
3737
+ }
3738
+
3739
+ _chart.doRender = function () {
3740
+ _chart.resetSvg();
3741
+
3742
+ _g = _chart.svg()
3743
+ .append("g")
3744
+ .attr("transform", "translate(" + _chart.margins().left + "," + _chart.margins().top + ")");
3745
+
3746
+ drawAxis();
3747
+ drawGridLines();
3748
+ drawChart();
3749
+
3750
+ return _chart;
3751
+ };
3752
+
3753
+ _chart.title(function (d) {
3754
+ return _chart.keyAccessor()(d) + ": " + _chart.valueAccessor()(d);
3755
+ });
3756
+
3757
+ _chart.label(function (d) {
3758
+ return _chart.keyAccessor()(d);
3759
+ });
3760
+
3761
+ _chart.x = function(x){
3762
+ if(!arguments.length) return _x;
3763
+ _x = x;
3764
+ return _chart;
3765
+ };
3766
+
3767
+ function drawGridLines() {
3768
+ _g.selectAll("g.tick")
3769
+ .select("line.grid-line")
3770
+ .remove();
3771
+
3772
+ _g.selectAll("g.tick")
3773
+ .append("line")
3774
+ .attr("class", "grid-line")
3775
+ .attr("x1", 0)
3776
+ .attr("y1", 0)
3777
+ .attr("x2", 0)
3778
+ .attr("y2", function (d) {
3779
+ return -_chart.effectiveHeight();
3780
+ });
3781
+ }
3782
+
3783
+ function drawChart() {
3784
+ drawAxis();
3785
+ drawGridLines();
3786
+
3787
+ var rows = _g.selectAll("g." + _rowCssClass)
3788
+ .data(_chart.group().all());
3789
+
3790
+ createElements(rows);
3791
+ removeElements(rows);
3792
+ updateElements(rows);
3793
+ }
3794
+
3795
+ function createElements(rows) {
3796
+ var rowEnter = rows.enter()
3797
+ .append("g")
3798
+ .attr("class", function (d, i) {
3799
+ return _rowCssClass + " _" + i;
3800
+ });
3801
+
3802
+ rowEnter.append("rect").attr("width", 0);
3803
+
3804
+ createLabels(rowEnter);
3805
+ updateLabels(rows);
3806
+ }
3807
+
3808
+ function removeElements(rows) {
3809
+ rows.exit().remove();
3810
+ }
3811
+
3812
+ function updateElements(rows) {
3813
+ var height = rowHeight();
3814
+
3815
+ var rect = rows.attr("transform",function (d, i) {
3816
+ return "translate(0," + ((i + 1) * _gap + i * height) + ")";
3817
+ }).select("rect")
3818
+ .attr("height", height)
3819
+ .attr("fill", _chart.getColor)
3820
+ .on("click", onClick)
3821
+ .classed("deselected", function (d) {
3822
+ return (_chart.hasFilter()) ? !_chart.isSelectedRow(d) : false;
3823
+ })
3824
+ .classed("selected", function (d) {
3825
+ return (_chart.hasFilter()) ? _chart.isSelectedRow(d) : false;
3826
+ });
3827
+
3828
+ dc.transition(rect, _chart.transitionDuration())
3829
+ .attr("width", function (d) {
3830
+ return Math.abs(_x(0) - _x(_chart.valueAccessor()(d)));
3831
+ })
3832
+ .attr("transform", translateX);
3833
+
3834
+ createTitles(rows);
3835
+ updateLabels(rows);
3836
+ }
3837
+
3838
+ function createTitles(rows) {
3839
+ if (_chart.renderTitle()) {
3840
+ rows.selectAll("title").remove();
3841
+ rows.append("title").text(function (d) {
3842
+ return _chart.title()(d);
3843
+ });
3844
+ }
3845
+ }
3846
+
3847
+ function createLabels(rowEnter) {
3848
+ if (_chart.renderLabel()) {
3849
+ rowEnter.append("text")
3850
+ .on("click", onClick);
3851
+ }
3852
+ }
3853
+
3854
+ function updateLabels(rows) {
3855
+ if (_chart.renderLabel()) {
3856
+ var lab = rows.select("text")
3857
+ .attr("x", _labelOffsetX)
3858
+ .attr("y", _labelOffsetY)
3859
+ .attr("class", function (d, i) {
3860
+ return _rowCssClass + " _" + i;
3861
+ })
3862
+ .text(function (d) {
3863
+ return _chart.label()(d);
3864
+ });
3865
+ dc.transition(lab, _chart.transitionDuration())
3866
+ .attr("transform", translateX);
3867
+ }
3868
+ }
3869
+
3870
+ function numberOfRows() {
3871
+ return _chart.group().all().length;
3872
+ }
3873
+
3874
+ function rowHeight() {
3875
+ var n = numberOfRows();
3876
+ return (_chart.effectiveHeight() - (n + 1) * _gap) / n;
3877
+ }
3878
+
3879
+ function onClick(d) {
3880
+ _chart.onClick(d);
3881
+ }
3882
+
3883
+ function translateX(d) {
3884
+ var x = _x(_chart.valueAccessor()(d)),
3885
+ x0 = _x(0),
3886
+ s = x > x0 ? x0 : x;
3887
+ return "translate("+s+",0)";
3888
+ }
3889
+
3890
+ _chart.doRedraw = function () {
3891
+ drawChart();
3892
+ return _chart;
3893
+ };
3894
+
3895
+ _chart.xAxis = function () {
3896
+ return _xAxis;
3897
+ };
3898
+
3899
+ _chart.gap = function (g) {
3900
+ if (!arguments.length) return _gap;
3901
+ _gap = g;
3902
+ return _chart;
3903
+ };
3904
+
3905
+ _chart.elasticX = function (_) {
3906
+ if (!arguments.length) return _elasticX;
3907
+ _elasticX = _;
3908
+ return _chart;
3909
+ };
3910
+
3911
+ _chart.labelOffsetX = function (o) {
3912
+ if (!arguments.length) return _labelOffsetX;
3913
+ _labelOffsetX = o;
3914
+ return _chart;
3915
+ };
3916
+
3917
+ _chart.labelOffsetY = function (o) {
3918
+ if (!arguments.length) return _labelOffsetY;
3919
+ _labelOffsetY = o;
3920
+ return _chart;
3921
+ };
3922
+
3923
+ _chart.isSelectedRow = function (d) {
3924
+ return _chart.hasFilter(_chart.keyAccessor()(d));
3925
+ };
3926
+
3927
+ return _chart.anchor(parent, chartGroup);
3928
+ };
3929
+
3930
+ dc.legend = function () {
3931
+ var LABEL_GAP = 2;
3932
+
3933
+ var _legend = {},
3934
+ _parent,
3935
+ _x = 0,
3936
+ _y = 0,
3937
+ _itemHeight = 12,
3938
+ _gap = 5;
3939
+
3940
+ var _g;
3941
+
3942
+ _legend.parent = function (p) {
3943
+ if (!arguments.length) return _parent;
3944
+ _parent = p;
3945
+ return _legend;
3946
+ };
3947
+
3948
+ _legend.render = function () {
3949
+ _g = _parent.svg().append("g")
3950
+ .attr("class", "dc-legend")
3951
+ .attr("transform", "translate(" + _x + "," + _y + ")");
3952
+
3953
+ var itemEnter = _g.selectAll('g.dc-legend-item')
3954
+ .data(_parent.legendables())
3955
+ .enter()
3956
+ .append("g")
3957
+ .attr("class", "dc-legend-item")
3958
+ .attr("transform", function (d, i) {
3959
+ return "translate(0," + i * legendItemHeight() + ")";
3960
+ })
3961
+ .on("mouseover", function(d){
3962
+ _parent.legendHighlight(d);
3963
+ })
3964
+ .on("mouseout", function (d) {
3965
+ _parent.legendReset(d);
3966
+ });
3967
+
3968
+ itemEnter
3969
+ .append("rect")
3970
+ .attr("width", _itemHeight)
3971
+ .attr("height", _itemHeight)
3972
+ .attr("fill", function(d){return d.color;});
3973
+
3974
+ itemEnter.append("text")
3975
+ .text(function(d){return d.name;})
3976
+ .attr("x", _itemHeight + LABEL_GAP)
3977
+ .attr("y", function(){return _itemHeight / 2 + (this.clientHeight?this.clientHeight:13) / 2 - 2;});
3978
+ };
3979
+
3980
+ function legendItemHeight() {
3981
+ return _gap + _itemHeight;
3982
+ }
3983
+
3984
+ _legend.x = function (x) {
3985
+ if (!arguments.length) return _x;
3986
+ _x = x;
3987
+ return _legend;
3988
+ };
3989
+
3990
+ _legend.y = function (y) {
3991
+ if (!arguments.length) return _y;
3992
+ _y = y;
3993
+ return _legend;
3994
+ };
3995
+
3996
+ _legend.gap = function (gap) {
3997
+ if (!arguments.length) return _gap;
3998
+ _gap = gap;
3999
+ return _legend;
4000
+ };
4001
+
4002
+ _legend.itemHeight = function (h) {
4003
+ if (!arguments.length) return _itemHeight;
4004
+ _itemHeight = h;
4005
+ return _legend;
4006
+ };
4007
+
4008
+ return _legend;
4009
+ };
4010
+
4011
+ dc.scatterPlot = function (parent, chartGroup) {
4012
+ var _chart = dc.coordinateGridChart({});
4013
+
4014
+ _chart.plotData = function(){
4015
+ _chart.chartBodyG().selectAll("path.dc-symbol")
4016
+ .data(_chart.group().all())
4017
+ .enter()
4018
+ .append("path")
4019
+ .attr("class", "dc-symbol")
4020
+ .attr("transform", function(d){
4021
+ return "translate("+_chart.x()(_chart.keyAccessor()(d))+","+_chart.y()(_chart.valueAccessor()(d))+")";
4022
+ })
4023
+ .attr("d", d3.svg.symbol());
4024
+ };
4025
+
4026
+ return _chart.anchor(parent, chartGroup);
4027
+ };
4028
+
4029
+ dc.numberDisplay = function (parent, chartGroup) {
4030
+ var SPAN_CLASS = 'number-display';
4031
+ var _formatNumber = d3.format(".2s");
4032
+ var _chart = dc.baseChart({});
4033
+
4034
+ _chart.dimension({}); // dummy dimension to remove warnings
4035
+
4036
+ _chart.value = function () {
4037
+ var valObj = _chart.group().all && _chart.group().all()[0] || _chart.group().value();
4038
+ return _chart.valueAccessor()(valObj);
4039
+ };
4040
+
4041
+ _chart.doRender = function () {
4042
+ var newValue = _chart.value(),
4043
+ span = _chart.selectAll("."+SPAN_CLASS);
4044
+
4045
+ if(span.empty())
4046
+ span = span.data([0])
4047
+ .enter()
4048
+ .append("span")
4049
+ .attr("class", SPAN_CLASS);
4050
+
4051
+ span.transition()
4052
+ .duration(250)
4053
+ .ease('quad-out-in')
4054
+ .tween("text", function () {
4055
+ var interp = d3.interpolateNumber(this.lastValue || 0, newValue);
4056
+ this.lastValue = newValue;
4057
+ return function (t) {
4058
+ this.textContent = _chart.formatNumber()(interp(t));
4059
+ };
4060
+ });
4061
+
4062
+ return _chart;
4063
+ };
4064
+
4065
+ _chart.doRedraw = function(){
4066
+ return _chart.doRender();
4067
+ };
4068
+
4069
+ _chart.formatNumber = function (_) {
4070
+ if (!arguments.length) return _formatNumber;
4071
+ _formatNumber = _;
4072
+ return _chart;
4073
+ };
4074
+
4075
+ return _chart.anchor(parent, chartGroup);
4076
+ };
4077
+
4078
+ return dc;})();