@@ -64,10 +64,17 @@ dc.override = function(obj, functionName, newFunction) {
64
64
var existingFunction = obj [ functionName ] ;
65
65
newFunction . _ = existingFunction ;
66
66
obj [ functionName ] = function ( ) {
67
- return newFunction ( existingFunction ) ;
67
+ var expression = "newFunction(" ;
68
+
69
+ for ( var i = 0 ; i < arguments . length ; ++ i )
70
+ expression += "argument[" + i + "]," ;
71
+
72
+ expression += "existingFunction);"
73
+
74
+ return eval ( expression ) ;
68
75
} ;
69
76
}
70
- dc . dateFormat = d3 . time . format ( "%m/%d/%Y" ) ;
77
+ dc . dateFormat = d3 . time . format ( "%m/%d/%Y" ) ;
71
78
72
79
dc . printers = { } ;
73
80
@@ -93,19 +100,73 @@ function printSingleValue(filter) {
93
100
94
101
if ( filter instanceof Date )
95
102
s = dc . dateFormat ( filter ) ;
96
- else if ( typeof ( filter ) == "string" )
103
+ else if ( typeof ( filter ) == "string" )
97
104
s = filter ;
98
- else if ( typeof ( filter ) == "number" )
105
+ else if ( typeof ( filter ) == "number" )
99
106
s = Math . round ( filter ) ;
100
107
101
108
return s ;
102
109
}
103
110
104
- dc . constants = function ( ) { } ;
111
+ dc . constants = function ( ) {
112
+ } ;
105
113
dc . constants . STACK_CLASS = "stack" ;
106
114
dc . constants . DESELECTED_CLASS = "deselected" ;
107
115
dc . constants . SELECTED_CLASS = "selected" ;
108
116
dc . constants . GROUP_INDEX_NAME = "__group_index__" ;
117
+
118
+ dc . utils = { } ;
119
+ dc . utils . GroupStack = function ( ) {
120
+ var _dataPointMatrix = [ ] ;
121
+ var _groups = [ ] ;
122
+ var _defaultRetriever ;
123
+
124
+ function initializeDataPointRow ( x ) {
125
+ if ( ! _dataPointMatrix [ x ] )
126
+ _dataPointMatrix [ x ] = [ ] ;
127
+ }
128
+
129
+ this . setDataPoint = function ( x , y , data ) {
130
+ initializeDataPointRow ( x ) ;
131
+ _dataPointMatrix [ x ] [ y ] = data ;
132
+ } ;
133
+
134
+ this . getDataPoint = function ( x , y ) {
135
+ initializeDataPointRow ( x ) ;
136
+ var dataPoint = _dataPointMatrix [ x ] [ y ] ;
137
+ if ( dataPoint == undefined )
138
+ dataPoint = 0 ;
139
+ return dataPoint ;
140
+ } ;
141
+
142
+ this . addGroup = function ( group , retriever ) {
143
+ if ( ! retriever )
144
+ retriever = _defaultRetriever ;
145
+ _groups . push ( [ group , retriever ] ) ;
146
+ return _groups . length - 1 ;
147
+ } ;
148
+
149
+ this . getGroupByIndex = function ( index ) {
150
+ return _groups [ index ] [ 0 ] ;
151
+ } ;
152
+
153
+ this . getRetrieverByIndex = function ( index ) {
154
+ return _groups [ index ] [ 1 ] ;
155
+ } ;
156
+
157
+ this . size = function ( ) {
158
+ return _groups . length ;
159
+ } ;
160
+
161
+ this . clear = function ( ) {
162
+ _dataPointMatrix = [ ] ;
163
+ _groups = [ ] ;
164
+ } ;
165
+
166
+ this . setDefaultRetriever = function ( retriever ) {
167
+ _defaultRetriever = retriever ;
168
+ } ;
169
+ } ;
109
170
dc . baseChart = function ( _chart ) {
110
171
var _dimension ;
111
172
var _group ;
@@ -629,12 +690,11 @@ dc.stackableChart = function(_chart) {
629
690
var MIN_DATA_POINT_HEIGHT = 0 ;
630
691
var DATA_POINT_PADDING_BOTTOM = 1 ;
631
692
632
- var _stack = [ ] ;
633
- var _dataPointMatrix = [ ] ;
693
+ var _groupStack = new dc . utils . GroupStack ( ) ;
634
694
635
- _chart . stack = function ( _ ) {
636
- if ( ! arguments . length ) return _stack ;
637
- _stack = _ ;
695
+ _chart . stack = function ( group , retriever ) {
696
+ _groupStack . setDefaultRetriever ( _chart . valueRetriever ( ) ) ;
697
+ _groupStack . addGroup ( group , retriever ) ;
638
698
return _chart ;
639
699
} ;
640
700
@@ -643,20 +703,35 @@ dc.stackableChart = function(_chart) {
643
703
644
704
allGroups . push ( _chart . group ( ) ) ;
645
705
646
- for ( var i = 0 ; i < _chart . stack ( ) . length ; ++ i )
647
- allGroups . push ( _chart . stack ( ) [ i ] ) ;
706
+ for ( var i = 0 ; i < _groupStack . size ( ) ; ++ i )
707
+ allGroups . push ( _groupStack . getGroupByIndex ( i ) ) ;
648
708
649
709
return allGroups ;
650
710
} ;
651
711
712
+ _chart . allValueRetrievers = function ( ) {
713
+ var allRetrievers = [ ] ;
714
+
715
+ allRetrievers . push ( _chart . valueRetriever ( ) ) ;
716
+
717
+ for ( var i = 0 ; i < _groupStack . size ( ) ; ++ i )
718
+ allRetrievers . push ( _groupStack . getRetrieverByIndex ( i ) ) ;
719
+
720
+ return allRetrievers ;
721
+ } ;
722
+
723
+ _chart . getValueRetrieverByIndex = function ( groupIndex ) {
724
+ return _chart . allValueRetrievers ( ) [ groupIndex ] ;
725
+ } ;
726
+
652
727
_chart . yAxisMin = function ( ) {
653
728
var min = 0 ;
654
729
var allGroups = _chart . allGroups ( ) ;
655
730
656
- for ( var i = 0 ; i < allGroups . length ; ++ i ) {
657
- var group = allGroups [ i ] ;
731
+ for ( var groupIndex = 0 ; groupIndex < allGroups . length ; ++ groupIndex ) {
732
+ var group = allGroups [ groupIndex ] ;
658
733
var m = d3 . min ( group . all ( ) , function ( e ) {
659
- return _chart . valueRetriever ( ) ( e ) ;
734
+ return _chart . getValueRetrieverByIndex ( groupIndex ) ( e ) ;
660
735
} ) ;
661
736
if ( m < min ) min = m ;
662
737
}
@@ -668,10 +743,10 @@ dc.stackableChart = function(_chart) {
668
743
var max = 0 ;
669
744
var allGroups = _chart . allGroups ( ) ;
670
745
671
- for ( var i = 0 ; i < allGroups . length ; ++ i ) {
672
- var group = allGroups [ i ] ;
746
+ for ( var groupIndex = 0 ; groupIndex < allGroups . length ; ++ groupIndex ) {
747
+ var group = allGroups [ groupIndex ] ;
673
748
max += d3 . max ( group . all ( ) , function ( e ) {
674
- return _chart . valueRetriever ( ) ( e ) ;
749
+ return _chart . getValueRetrieverByIndex ( groupIndex ) ( e ) ;
675
750
} ) ;
676
751
}
677
752
@@ -682,8 +757,8 @@ dc.stackableChart = function(_chart) {
682
757
return _chart . margins ( ) . top + _chart . yAxisHeight ( ) - DATA_POINT_PADDING_BOTTOM ;
683
758
} ;
684
759
685
- _chart . dataPointHeight = function ( d ) {
686
- var h = ( _chart . yAxisHeight ( ) - _chart . y ( ) ( _chart . valueRetriever ( ) ( d ) ) - DATA_POINT_PADDING_BOTTOM ) ;
760
+ _chart . dataPointHeight = function ( d , groupIndex ) {
761
+ var h = ( _chart . yAxisHeight ( ) - _chart . y ( ) ( _chart . getValueRetrieverByIndex ( groupIndex ) ( d ) ) - DATA_POINT_PADDING_BOTTOM ) ;
687
762
if ( isNaN ( h ) || h < MIN_DATA_POINT_HEIGHT )
688
763
h = MIN_DATA_POINT_HEIGHT ;
689
764
return h ;
@@ -692,25 +767,23 @@ dc.stackableChart = function(_chart) {
692
767
_chart . calculateDataPointMatrix = function ( groups ) {
693
768
for ( var groupIndex = 0 ; groupIndex < groups . length ; ++ groupIndex ) {
694
769
var data = groups [ groupIndex ] . all ( ) ;
695
- _dataPointMatrix [ groupIndex ] = [ ] ;
696
770
for ( var dataIndex = 0 ; dataIndex < data . length ; ++ dataIndex ) {
697
771
var d = data [ dataIndex ] ;
698
772
if ( groupIndex == 0 )
699
- _dataPointMatrix [ groupIndex ] [ dataIndex ] = _chart . dataPointBaseline ( ) - _chart . dataPointHeight ( d ) ;
773
+ _groupStack . setDataPoint ( groupIndex , dataIndex , _chart . dataPointBaseline ( ) - _chart . dataPointHeight ( d , groupIndex ) ) ;
700
774
else
701
- _dataPointMatrix [ groupIndex ] [ dataIndex ] = _dataPointMatrix [ groupIndex - 1 ] [ dataIndex ] - _chart . dataPointHeight ( d ) ;
775
+ _groupStack . setDataPoint ( groupIndex , dataIndex , _groupStack . getDataPoint ( groupIndex - 1 , dataIndex ) - _chart . dataPointHeight ( d , groupIndex ) )
702
776
}
703
777
}
704
778
} ;
705
779
706
- _chart . dataPointMatrix = function ( _ ) {
707
- if ( ! arguments . length ) return _dataPointMatrix ;
708
- _dataPointMatrix = _ ;
709
- return _chart ;
780
+ _chart . getChartStack = function ( ) {
781
+ return _groupStack ;
710
782
} ;
711
783
712
784
return _chart ;
713
- } ; dc . pieChart = function ( _parent ) {
785
+ } ;
786
+ dc . pieChart = function ( _parent ) {
714
787
var _sliceCssClass = "pie-slice" ;
715
788
716
789
var _radius = 0 , _innerRadius = 0 ;
@@ -951,14 +1024,19 @@ dc.barChart = function(_parent) {
951
1024
. attr ( "y" , function ( data , dataIndex ) {
952
1025
return barY ( this , data , dataIndex ) ;
953
1026
} )
954
- . attr ( "height" , _chart . dataPointHeight ) ;
1027
+ . attr ( "height" , function ( data ) {
1028
+ return _chart . dataPointHeight ( data , getGroupIndexFromBar ( this ) ) ;
1029
+ } ) ;
955
1030
956
1031
// update
957
1032
dc . transition ( bars , _chart . transitionDuration ( ) )
958
1033
. attr ( "y" , function ( data , dataIndex ) {
1034
+
959
1035
return barY ( this , data , dataIndex ) ;
960
1036
} )
961
- . attr ( "height" , _chart . dataPointHeight ) ;
1037
+ . attr ( "height" , function ( data ) {
1038
+ return _chart . dataPointHeight ( data , getGroupIndexFromBar ( this ) ) ;
1039
+ } ) ;
962
1040
963
1041
// delete
964
1042
dc . transition ( bars . exit ( ) , _chart . transitionDuration ( ) )
@@ -974,16 +1052,23 @@ dc.barChart = function(_parent) {
974
1052
return w ;
975
1053
}
976
1054
977
- function barX ( bar , data , groupIndex , dataIndex ) {
978
- // cache group index in each individual bar to avoid timing issue introduced by transition
1055
+ function setGroupIndexToBar ( bar , groupIndex ) {
979
1056
bar [ dc . constants . GROUP_INDEX_NAME ] = groupIndex ;
1057
+ }
1058
+
1059
+ function barX ( bar , data , groupIndex , dataIndex ) {
1060
+ setGroupIndexToBar ( bar , groupIndex ) ;
980
1061
return _chart . x ( ) ( _chart . keyRetriever ( ) ( data ) ) + _chart . margins ( ) . left ;
981
1062
}
982
1063
983
- function barY ( bar , data , dataIndex ) {
984
- // cached group index can then be safely retrieved from bar wo/ worrying about transition
1064
+ function getGroupIndexFromBar ( bar ) {
985
1065
var groupIndex = bar [ dc . constants . GROUP_INDEX_NAME ] ;
986
- return _chart . dataPointMatrix ( ) [ groupIndex ] [ dataIndex ] ;
1066
+ return groupIndex ;
1067
+ }
1068
+
1069
+ function barY ( bar , data , dataIndex ) {
1070
+ var groupIndex = getGroupIndexFromBar ( bar ) ;
1071
+ return _chart . getChartStack ( ) . getDataPoint ( groupIndex , dataIndex ) ;
987
1072
}
988
1073
989
1074
_chart . fadeDeselectedArea = function ( ) {
@@ -1063,7 +1148,7 @@ dc.lineChart = function(_parent) {
1063
1148
} )
1064
1149
. y ( function ( d , dataIndex ) {
1065
1150
var groupIndex = this [ dc . constants . GROUP_INDEX_NAME ] ;
1066
- return _chart . dataPointMatrix ( ) [ groupIndex ] [ dataIndex ] ;
1151
+ return _chart . getChartStack ( ) . getDataPoint ( groupIndex , dataIndex ) ;
1067
1152
} ) ;
1068
1153
1069
1154
dc . transition ( linePath , _chart . transitionDuration ( ) ,
@@ -1088,7 +1173,7 @@ dc.lineChart = function(_parent) {
1088
1173
. y0 ( function ( d , dataIndex ) {
1089
1174
var groupIndex = this [ dc . constants . GROUP_INDEX_NAME ] ;
1090
1175
if ( groupIndex == 0 ) return _chart . y ( ) ( 0 ) - AREA_BOTTOM_PADDING + _chart . margins ( ) . top ;
1091
- return _chart . dataPointMatrix ( ) [ groupIndex - 1 ] [ dataIndex ] ;
1176
+ return _chart . getChartStack ( ) . getDataPoint ( groupIndex - 1 , dataIndex ) ;
1092
1177
} ) ;
1093
1178
1094
1179
dc . transition ( areaPath , _chart . transitionDuration ( ) ,
0 commit comments