@@ -1299,7 +1299,7 @@ plots.modifyFrames = function(gd, operations) {
12991299 */
13001300plots . computeFrame = function ( gd , frameName ) {
13011301 var frameLookup = gd . _transitionData . _frameHash ;
1302- var i , traceIndices , traceIndex , expandedObj , destIndex , copy ;
1302+ var i , traceIndices , traceIndex , destIndex ;
13031303
13041304 var framePtr = frameLookup [ frameName ] ;
13051305
@@ -1361,49 +1361,94 @@ plots.computeFrame = function(gd, frameName) {
13611361 result . traces [ destIndex ] = traceIndex ;
13621362 }
13631363
1364- try {
1365- result . data [ destIndex ] = plots . extendTrace ( result . data [ destIndex ] , framePtr . data [ i ] ) ;
1366- } catch ( e ) {
1367- console . error ( e ) ;
1368- }
1364+ result . data [ destIndex ] = plots . extendTrace ( result . data [ destIndex ] , framePtr . data [ i ] ) ;
13691365 }
13701366 }
13711367 }
13721368
13731369 return result ;
13741370} ;
13751371
1376- plots . extendObjectWithContainers = function ( dest , src , containerPaths ) {
1372+ /**
1373+ * Extend an object, treating container arrays very differently by extracting
1374+ * their contents and merging them separately.
1375+ *
1376+ * This exists so that we can extendDeepNoArrays and avoid stepping into data
1377+ * arrays without knowledge of the plot schema, but so that we may also manually
1378+ * recurse into known container arrays, such as transforms.
1379+ *
1380+ * See extendTrace and extendLayout below for usage.
1381+ */
1382+ plots . extendObjectWithContainers = function ( dest , src , containerPaths ) {
1383+ var containerProp , containerVal , i , j , srcProp , destProp , srcContainer , destContainer ;
13771384 var copy = Lib . extendDeepNoArrays ( { } , src || { } ) ;
13781385 var expandedObj = Lib . expandObjectPaths ( copy ) ;
1386+ var containerObj = { } ;
1387+
1388+ // Step through and extract any container properties. Otherwise extendDeepNoArrays
1389+ // will clobber any existing properties with an empty array and then supplyDefaults
1390+ // will reset everything to defaults.
1391+ if ( containerPaths && containerPaths . length ) {
1392+ for ( i = 0 ; i < containerPaths . length ; i ++ ) {
1393+ containerProp = Lib . nestedProperty ( expandedObj , containerPaths [ i ] ) ;
1394+ containerVal = containerProp . get ( ) ;
1395+ containerProp . set ( null ) ;
1396+ Lib . nestedProperty ( containerObj , containerPaths [ i ] ) . set ( containerVal ) ;
1397+ }
1398+ }
13791399
1380- if ( containerPaths && containerPaths . length ) {
1381- for ( var i = 0 ; i < containerPaths . length ; i ++ ) {
1382- var srcProp = Lib . nestedProperty ( src , containerPaths [ i ] ) ;
1383- var srcVal = srcProp . get ( ) ;
1384-
1385- console . log ( 'src, containerPaths[i], srcVal:' , src , containerPaths [ i ] , srcVal ) ;
1386-
1400+ dest = Lib . extendDeepNoArrays ( dest || { } , expandedObj ) ;
13871401
1388- if ( ! srcVal ) continue ;
1402+ if ( containerPaths && containerPaths . length ) {
1403+ for ( i = 0 ; i < containerPaths . length ; i ++ ) {
1404+ srcProp = Lib . nestedProperty ( containerObj , containerPaths [ i ] ) ;
1405+ srcContainer = srcProp . get ( ) ;
13891406
1390- var destProp = Lib . nestedProperty ( src , containerPaths [ i ] ) ;
1391- var destVal = destProp . get ( ) ;
1407+ if ( ! srcContainer ) continue ;
13921408
1409+ destProp = Lib . nestedProperty ( dest , containerPaths [ i ] ) ;
13931410
1411+ destContainer = destProp . get ( ) ;
1412+ if ( ! Array . isArray ( destContainer ) ) {
1413+ destContainer = [ ] ;
1414+ destProp . set ( destContainer ) ;
1415+ }
13941416
1417+ for ( j = 0 ; j < srcContainer . length ; j ++ ) {
1418+ destContainer [ j ] = plots . extendObjectWithContainers ( destContainer [ j ] , srcContainer [ j ] ) ;
1419+ }
13951420 }
13961421 }
13971422
1398- return Lib . extendDeepNoArrays ( dest || { } , expandedObj ) ;
1423+ return dest ;
13991424} ;
14001425
1401- plots . extendTrace = function ( destTrace , srcTrace ) {
1426+ /*
1427+ * Extend a trace definition. This method:
1428+ *
1429+ * 1. directly transfers any array references
1430+ * 2. manually recurses into container arrays like transforms
1431+ *
1432+ * The result is the original object reference with the new contents merged in.
1433+ */
1434+ plots . extendTrace = function ( destTrace , srcTrace ) {
14021435 return plots . extendObjectWithContainers ( destTrace , srcTrace , [ 'transforms' ] ) ;
14031436} ;
14041437
1405- plots . extendLayout = function ( destLayout , srcLayout ) {
1406- return plots . extendObjectWithContainers ( destLayout , srcLayout , [ ] ) ;
1438+ /*
1439+ * Extend a layout definition. This method:
1440+ *
1441+ * 1. directly transfers any array references (not critically important for
1442+ * layout since there aren't really data arrays)
1443+ * 2. manually recurses into container arrays like annotations
1444+ *
1445+ * The result is the original object reference with the new contents merged in.
1446+ */
1447+ plots . extendLayout = function ( destLayout , srcLayout ) {
1448+ return plots . extendObjectWithContainers ( destLayout , srcLayout , [
1449+ 'annotations' ,
1450+ 'shapes'
1451+ ] ) ;
14071452} ;
14081453
14091454/**
0 commit comments