@@ -116,43 +116,23 @@ exports.supplyDefaults = function(transformIn) {
116116 * array of transformed traces
117117 */
118118exports . transform = function ( data , state ) {
119+ var newTraces , i , j ;
119120 var newData = [ ] ;
120121
121- for ( var i = 0 ; i < data . length ; i ++ ) {
122- newData = newData . concat ( transformOne ( data [ i ] , state ) ) ;
122+ for ( i = 0 ; i < data . length ; i ++ ) {
123+ newTraces = transformOne ( data [ i ] , state ) ;
124+
125+ for ( j = 0 ; j < newTraces . length ; j ++ ) {
126+ newData . push ( newTraces [ j ] ) ;
127+ }
123128 }
124129
125130 return newData ;
126131} ;
127132
128- function initializeArray ( newTrace , a ) {
129- Lib . nestedProperty ( newTrace , a ) . set ( [ ] ) ;
130- }
131-
132- function pasteArray ( newTrace , trace , j , a ) {
133- Lib . nestedProperty ( newTrace , a ) . set (
134- Lib . nestedProperty ( newTrace , a ) . get ( ) . concat ( [
135- Lib . nestedProperty ( trace , a ) . get ( ) [ j ]
136- ] )
137- ) ;
138- }
139-
140- // In order for groups to apply correctly to other transform data (e.g.
141- // a filter transform), we have to break the connection and clone the
142- // transforms so that each group writes grouped values into a different
143- // destination. This function does not break the array reference
144- // connection between the split transforms it creates. That's handled in
145- // initialize, which creates a new empty array for each arrayAttr.
146- function cloneTransforms ( newTrace ) {
147- var transforms = newTrace . transforms ;
148- newTrace . transforms = [ ] ;
149- for ( var j = 0 ; j < transforms . length ; j ++ ) {
150- newTrace . transforms [ j ] = Lib . extendDeepNoArrays ( { } , transforms [ j ] ) ;
151- }
152- }
153133
154134function transformOne ( trace , state ) {
155- var i , j ;
135+ var i , j , k , attr , srcArray , groupName , newTrace , transforms ;
156136 var opts = state . transform ;
157137 var groups = trace . transforms [ state . transformIndex ] . groups ;
158138
@@ -172,22 +152,31 @@ function transformOne(trace, state) {
172152 styleLookup [ styles [ i ] . target ] = styles [ i ] . value ;
173153 }
174154
175- for ( i = 0 ; i < groupNames . length ; i ++ ) {
176- var groupName = groupNames [ i ] ;
177-
178- var newTrace = newData [ i ] = Lib . extendDeepNoArrays ( { } , trace ) ;
179-
180- cloneTransforms ( newTrace ) ;
155+ var newDataByGroup = { } ;
181156
182- arrayAttrs . forEach ( initializeArray . bind ( null , newTrace ) ) ;
157+ for ( i = 0 ; i < groupNames . length ; i ++ ) {
158+ groupName = groupNames [ i ] ;
183159
184- for ( j = 0 ; j < len ; j ++ ) {
185- if ( groups [ j ] !== groupName ) continue ;
160+ // Start with a deep extend that just copies array references.
161+ newTrace = newData [ i ] = newDataByGroup [ groupName ] = Lib . extendDeepNoArrays ( { } , trace ) ;
162+ newTrace . name = groupName ;
186163
187- arrayAttrs . forEach ( pasteArray . bind ( null , newTrace , trace , j ) ) ;
164+ // In order for groups to apply correctly to other transform data (e.g.
165+ // a filter transform), we have to break the connection and clone the
166+ // transforms so that each group writes grouped values into a different
167+ // destination. This function does not break the array reference
168+ // connection between the split transforms it creates. That's handled in
169+ // initialize, which creates a new empty array for each arrayAttr.
170+ transforms = newTrace . transforms ;
171+ newTrace . transforms = [ ] ;
172+ for ( j = 0 ; j < transforms . length ; j ++ ) {
173+ newTrace . transforms [ j ] = Lib . extendDeepNoArrays ( { } , transforms [ j ] ) ;
188174 }
189175
190- newTrace . name = groupName ;
176+ // Initialize empty arrays for the arrayAttrs, to be split in the next step
177+ for ( j = 0 ; j < arrayAttrs . length ; j ++ ) {
178+ Lib . nestedProperty ( newTrace , arrayAttrs [ j ] ) . set ( [ ] ) ;
179+ }
191180
192181 Plots . clearExpandedTraceDefaultColors ( newTrace ) ;
193182
@@ -196,5 +185,21 @@ function transformOne(trace, state) {
196185 newTrace = Lib . extendDeepNoArrays ( newTrace , styleLookup [ groupName ] || { } ) ;
197186 }
198187
188+
189+ // For each array attribute including those nested inside this and other
190+ // transforms (small note that we technically only need to do this for
191+ // transforms that have not yet been applied):
192+ for ( k = 0 ; k < arrayAttrs . length ; k ++ ) {
193+ attr = arrayAttrs [ k ] ;
194+
195+ // Get the input data:
196+ srcArray = Lib . nestedProperty ( trace , attr ) . get ( ) ;
197+
198+ // And push each value onto the appropriate destination for this group:
199+ for ( j = 0 ; j < len ; j ++ ) {
200+ Lib . nestedProperty ( newDataByGroup [ groups [ j ] ] , attr ) . get ( ) . push ( srcArray [ j ] ) ;
201+ }
202+ }
203+
199204 return newData ;
200205}
0 commit comments