@@ -2329,7 +2329,11 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
23292329 var newFrame = trans . _currentFrame = trans . _frameQueue . shift ( ) ;
23302330
23312331 if ( newFrame ) {
2332- gd . _fullLayout . _currentFrame = newFrame . name ;
2332+ // Since it's sometimes necessary to do deep digging into frame data,
2333+ // we'll consider it not 100% impossible for nulls or numbers to sneak through,
2334+ // so check when casting the name, just to be absolutely certain:
2335+ var stringName = newFrame . name ? newFrame . name . toString ( ) : null ;
2336+ gd . _fullLayout . _currentFrame = stringName ;
23332337
23342338 trans . _lastFrameAt = Date . now ( ) ;
23352339 trans . _timeToNext = newFrame . frameOpts . duration ;
@@ -2351,7 +2355,7 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
23512355 } ) ;
23522356
23532357 gd . emit ( 'plotly_animatingframe' , {
2354- name : newFrame . name ,
2358+ name : stringName ,
23552359 frame : newFrame . frame ,
23562360 animation : {
23572361 frame : newFrame . frameOpts ,
@@ -2418,18 +2422,18 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
24182422 type : 'object' ,
24192423 data : setTransitionConfig ( Lib . extendFlat ( { } , frameOrGroupNameOrFrameList ) )
24202424 } ) ;
2421- } else if ( allFrames || typeof frameOrGroupNameOrFrameList === 'string' ) {
2425+ } else if ( allFrames || [ 'string' , 'number' ] . indexOf ( typeof frameOrGroupNameOrFrameList ) !== - 1 ) {
24222426 // In this case, null or undefined has been passed so that we want to
24232427 // animate *all* currently defined frames
24242428 for ( i = 0 ; i < trans . _frames . length ; i ++ ) {
24252429 frame = trans . _frames [ i ] ;
24262430
24272431 if ( ! frame ) continue ;
24282432
2429- if ( allFrames || frame . group === frameOrGroupNameOrFrameList ) {
2433+ if ( allFrames || String ( frame . group ) === String ( frameOrGroupNameOrFrameList ) ) {
24302434 frameList . push ( {
24312435 type : 'byname' ,
2432- name : frame . name ,
2436+ name : String ( frame . name ) ,
24332437 data : setTransitionConfig ( { name : frame . name } )
24342438 } ) ;
24352439 }
@@ -2530,6 +2534,8 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
25302534Plotly . addFrames = function ( gd , frameList , indices ) {
25312535 gd = helpers . getGraphDiv ( gd ) ;
25322536
2537+ var numericNameWarningCount = 0 ;
2538+
25332539 if ( frameList === null || frameList === undefined ) {
25342540 return Promise . resolve ( ) ;
25352541 }
@@ -2560,6 +2566,25 @@ Plotly.addFrames = function(gd, frameList, indices) {
25602566
25612567 var insertions = [ ] ;
25622568 for ( i = frameList . length - 1 ; i >= 0 ; i -- ) {
2569+ var name = ( _hash [ frameList [ i ] . name ] || { } ) . name ;
2570+ var newName = frameList [ i ] . name ;
2571+
2572+ if ( name && newName && typeof newName === 'number' && _hash [ name ] ) {
2573+ numericNameWarningCount ++ ;
2574+
2575+ Lib . warn ( 'addFrames: overwriting frame "' + _hash [ name ] . name +
2576+ '" with a frame whose name of type "number" also equates to "' +
2577+ name + '". This is valid but may potentially lead to unexpected ' +
2578+ 'behavior since all plotly.js frame names are stored internally ' +
2579+ 'as strings.' ) ;
2580+
2581+ if ( numericNameWarningCount > 5 ) {
2582+ Lib . warn ( 'addFrames: This API call has yielded too many warnings. ' +
2583+ 'For the rest of this call, further warnings about numeric frame ' +
2584+ 'names will be suppressed.' ) ;
2585+ }
2586+ }
2587+
25632588 insertions . push ( {
25642589 frame : Plots . supplyFrameDefaults ( frameList [ i ] ) ,
25652590 index : ( indices && indices [ i ] !== undefined && indices [ i ] !== null ) ? indices [ i ] : bigIndex + i
@@ -2580,6 +2605,12 @@ Plotly.addFrames = function(gd, frameList, indices) {
25802605 for ( i = insertions . length - 1 ; i >= 0 ; i -- ) {
25812606 frame = insertions [ i ] . frame ;
25822607
2608+ if ( typeof frame . name === 'number' ) {
2609+ Lib . warn ( 'Warning: addFrames accepts frames with numeric names, but the numbers are' +
2610+ 'implicitly cast to strings' ) ;
2611+
2612+ }
2613+
25832614 if ( ! frame . name ) {
25842615 // Repeatedly assign a default name, incrementing the counter each time until
25852616 // we get a name that's not in the hashed lookup table:
0 commit comments