@@ -2327,7 +2327,11 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
23272327 var newFrame = trans . _currentFrame = trans . _frameQueue . shift ( ) ;
23282328
23292329 if ( newFrame ) {
2330- gd . _fullLayout . _currentFrame = newFrame . name ;
2330+ // Since it's sometimes necessary to do deep digging into frame data,
2331+ // we'll consider it not 100% impossible for nulls or numbers to sneak through,
2332+ // so check when casting the name, just to be absolutely certain:
2333+ var stringName = newFrame . name ? newFrame . name . toString ( ) : null ;
2334+ gd . _fullLayout . _currentFrame = stringName ;
23312335
23322336 trans . _lastFrameAt = Date . now ( ) ;
23332337 trans . _timeToNext = newFrame . frameOpts . duration ;
@@ -2349,7 +2353,7 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
23492353 } ) ;
23502354
23512355 gd . emit ( 'plotly_animatingframe' , {
2352- name : newFrame . name ,
2356+ name : stringName ,
23532357 frame : newFrame . frame ,
23542358 animation : {
23552359 frame : newFrame . frameOpts ,
@@ -2416,18 +2420,18 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
24162420 type : 'object' ,
24172421 data : setTransitionConfig ( Lib . extendFlat ( { } , frameOrGroupNameOrFrameList ) )
24182422 } ) ;
2419- } else if ( allFrames || typeof frameOrGroupNameOrFrameList === 'string' ) {
2423+ } else if ( allFrames || [ 'string' , 'number' ] . indexOf ( typeof frameOrGroupNameOrFrameList ) !== - 1 ) {
24202424 // In this case, null or undefined has been passed so that we want to
24212425 // animate *all* currently defined frames
24222426 for ( i = 0 ; i < trans . _frames . length ; i ++ ) {
24232427 frame = trans . _frames [ i ] ;
24242428
24252429 if ( ! frame ) continue ;
24262430
2427- if ( allFrames || frame . group === frameOrGroupNameOrFrameList ) {
2431+ if ( allFrames || String ( frame . group ) === String ( frameOrGroupNameOrFrameList ) ) {
24282432 frameList . push ( {
24292433 type : 'byname' ,
2430- name : frame . name ,
2434+ name : String ( frame . name ) ,
24312435 data : setTransitionConfig ( { name : frame . name } )
24322436 } ) ;
24332437 }
@@ -2528,6 +2532,8 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
25282532Plotly . addFrames = function ( gd , frameList , indices ) {
25292533 gd = helpers . getGraphDiv ( gd ) ;
25302534
2535+ var numericNameWarningCount = 0 ;
2536+
25312537 if ( frameList === null || frameList === undefined ) {
25322538 return Promise . resolve ( ) ;
25332539 }
@@ -2558,6 +2564,25 @@ Plotly.addFrames = function(gd, frameList, indices) {
25582564
25592565 var insertions = [ ] ;
25602566 for ( i = frameList . length - 1 ; i >= 0 ; i -- ) {
2567+ var name = ( _hash [ frameList [ i ] . name ] || { } ) . name ;
2568+ var newName = frameList [ i ] . name ;
2569+
2570+ if ( name && newName && typeof newName === 'number' && _hash [ name ] ) {
2571+ numericNameWarningCount ++ ;
2572+
2573+ Lib . warn ( 'addFrames: overwriting frame "' + _hash [ name ] . name +
2574+ '" with a frame whose name of type "number" also equates to "' +
2575+ name + '". This is valid but may potentially lead to unexpected ' +
2576+ 'behavior since all plotly.js frame names are stored internally ' +
2577+ 'as strings.' ) ;
2578+
2579+ if ( numericNameWarningCount > 5 ) {
2580+ Lib . warn ( 'addFrames: This API call has yielded too many warnings. ' +
2581+ 'For the rest of this call, further warnings about numeric frame ' +
2582+ 'names will be suppressed.' ) ;
2583+ }
2584+ }
2585+
25612586 insertions . push ( {
25622587 frame : Plots . supplyFrameDefaults ( frameList [ i ] ) ,
25632588 index : ( indices && indices [ i ] !== undefined && indices [ i ] !== null ) ? indices [ i ] : bigIndex + i
@@ -2578,6 +2603,12 @@ Plotly.addFrames = function(gd, frameList, indices) {
25782603 for ( i = insertions . length - 1 ; i >= 0 ; i -- ) {
25792604 frame = insertions [ i ] . frame ;
25802605
2606+ if ( typeof frame . name === 'number' ) {
2607+ Lib . warn ( 'Warning: addFrames accepts frames with numeric names, but the numbers are' +
2608+ 'implicitly cast to strings' ) ;
2609+
2610+ }
2611+
25812612 if ( ! frame . name ) {
25822613 // Repeatedly assign a default name, incrementing the counter each time until
25832614 // we get a name that's not in the hashed lookup table:
0 commit comments