@@ -42,6 +42,8 @@ var enforceAxisConstraints = axisConstraints.enforce;
4242var cleanAxisConstraints = axisConstraints . clean ;
4343var axisIds = require ( '../plots/cartesian/axis_ids' ) ;
4444
45+ var numericNameWarningCount = 0 ;
46+ var numericNameWarningCountLimit = 5 ;
4547
4648/**
4749 * Main plot-creation function
@@ -2592,16 +2594,14 @@ Plotly.animate = function(gd, frameOrGroupNameOrFrameList, animationOpts) {
25922594 * - traces {array} trace indices
25932595 * - baseframe {string} name of frame from which this frame gets defaults
25942596 *
2595- * @param {array of integers) indices
2597+ * @param {array of integers } indices
25962598 * an array of integer indices matching the respective frames in `frameList`. If not
25972599 * provided, an index will be provided in serial order. If already used, the frame
25982600 * will be overwritten.
25992601 */
26002602Plotly . addFrames = function ( gd , frameList , indices ) {
26012603 gd = Lib . getGraphDiv ( gd ) ;
26022604
2603- var numericNameWarningCount = 0 ;
2604-
26052605 if ( frameList === null || frameList === undefined ) {
26062606 return Promise . resolve ( ) ;
26072607 }
@@ -2616,7 +2616,7 @@ Plotly.addFrames = function(gd, frameList, indices) {
26162616
26172617 var i , frame , j , idx ;
26182618 var _frames = gd . _transitionData . _frames ;
2619- var _hash = gd . _transitionData . _frameHash ;
2619+ var _frameHash = gd . _transitionData . _frameHash ;
26202620
26212621
26222622 if ( ! Array . isArray ( frameList ) ) {
@@ -2631,28 +2631,35 @@ Plotly.addFrames = function(gd, frameList, indices) {
26312631 var bigIndex = _frames . length + frameList . length * 2 ;
26322632
26332633 var insertions = [ ] ;
2634+ var _frameHashLocal = { } ;
26342635 for ( i = frameList . length - 1 ; i >= 0 ; i -- ) {
26352636 if ( ! Lib . isPlainObject ( frameList [ i ] ) ) continue ;
26362637
2637- var name = ( _hash [ frameList [ i ] . name ] || { } ) . name ;
2638+ // The entire logic for checking for this type of name collision can be removed once we migrate to ES6 and
2639+ // use a Map instead of an Object instance, as Map keys aren't converted to strings.
2640+ var lookupName = frameList [ i ] . name ;
2641+ var name = ( _frameHash [ lookupName ] || _frameHashLocal [ lookupName ] || { } ) . name ;
26382642 var newName = frameList [ i ] . name ;
2643+ var collisionPresent = _frameHash [ name ] || _frameHashLocal [ name ] ;
26392644
2640- if ( name && newName && typeof newName === 'number' && _hash [ name ] ) {
2645+ if ( name && newName && typeof newName === 'number' && collisionPresent && numericNameWarningCount < numericNameWarningCountLimit ) {
26412646 numericNameWarningCount ++ ;
26422647
2643- Lib . warn ( 'addFrames: overwriting frame "' + _hash [ name ] . name +
2648+ Lib . warn ( 'addFrames: overwriting frame "' + ( _frameHash [ name ] || _frameHashLocal [ name ] ) . name +
26442649 '" with a frame whose name of type "number" also equates to "' +
26452650 name + '". This is valid but may potentially lead to unexpected ' +
26462651 'behavior since all plotly.js frame names are stored internally ' +
26472652 'as strings.' ) ;
26482653
2649- if ( numericNameWarningCount > 5 ) {
2650- Lib . warn ( 'addFrames: This API call has yielded too many warnings. ' +
2654+ if ( numericNameWarningCount === numericNameWarningCountLimit ) {
2655+ Lib . warn ( 'addFrames: This API call has yielded too many of these warnings. ' +
26512656 'For the rest of this call, further warnings about numeric frame ' +
26522657 'names will be suppressed.' ) ;
26532658 }
26542659 }
26552660
2661+ _frameHashLocal [ lookupName ] = { name : lookupName } ;
2662+
26562663 insertions . push ( {
26572664 frame : Plots . supplyFrameDefaults ( frameList [ i ] ) ,
26582665 index : ( indices && indices [ i ] !== undefined && indices [ i ] !== null ) ? indices [ i ] : bigIndex + i
@@ -2682,10 +2689,10 @@ Plotly.addFrames = function(gd, frameList, indices) {
26822689 if ( ! frame . name ) {
26832690 // Repeatedly assign a default name, incrementing the counter each time until
26842691 // we get a name that's not in the hashed lookup table:
2685- while ( _hash [ ( frame . name = 'frame ' + gd . _transitionData . _counter ++ ) ] ) ;
2692+ while ( _frameHash [ ( frame . name = 'frame ' + gd . _transitionData . _counter ++ ) ] ) ;
26862693 }
26872694
2688- if ( _hash [ frame . name ] ) {
2695+ if ( _frameHash [ frame . name ] ) {
26892696 // If frame is present, overwrite its definition:
26902697 for ( j = 0 ; j < _frames . length ; j ++ ) {
26912698 if ( ( _frames [ j ] || { } ) . name === frame . name ) break ;
0 commit comments