diff --git a/draftlogs/6395_fix.md b/draftlogs/6395_fix.md new file mode 100644 index 00000000000..a418b52b6e8 --- /dev/null +++ b/draftlogs/6395_fix.md @@ -0,0 +1,2 @@ + - Fix react to config changes [[#6395](https://github.com/plotly/plotly.js/pull/6395)] + \ No newline at end of file diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index 77fd6ee9ccc..dfb19a76f34 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -2653,122 +2653,126 @@ function react(gd, data, layout, config) { configChanged = diffConfig(oldConfig, gd._context); } - gd.data = data || []; - helpers.cleanData(gd.data); - gd.layout = layout || {}; - helpers.cleanLayout(gd.layout); - - applyUIRevisions(gd.data, gd.layout, oldFullData, oldFullLayout); - - // "true" skips updating calcdata and remapping arrays from calcTransforms, - // which supplyDefaults usually does at the end, but we may need to NOT do - // if the diff (which we haven't determined yet) says we'll recalc - Plots.supplyDefaults(gd, {skipUpdateCalc: true}); - - var newFullData = gd._fullData; - var newFullLayout = gd._fullLayout; - var immutable = newFullLayout.datarevision === undefined; - var transition = newFullLayout.transition; - - var relayoutFlags = diffLayout(gd, oldFullLayout, newFullLayout, immutable, transition); - var newDataRevision = relayoutFlags.newDataRevision; - var restyleFlags = diffData(gd, oldFullData, newFullData, immutable, transition, newDataRevision); - - // TODO: how to translate this part of relayout to Plotly.react? - // // Setting width or height to null must reset the graph's width / height - // // back to its initial value as computed during the first pass in Plots.plotAutoSize. - // // - // // To do so, we must manually set them back here using the _initialAutoSize cache. - // if(['width', 'height'].indexOf(ai) !== -1 && vi === null) { - // fullLayout[ai] = gd._initialAutoSize[ai]; - // } - - if(updateAutosize(gd)) relayoutFlags.layoutReplot = true; - - // clear calcdata and empty categories if required - if(restyleFlags.calc || relayoutFlags.calc) { - gd.calcdata = undefined; - var allNames = Object.getOwnPropertyNames(newFullLayout); - for(var q = 0; q < allNames.length; q++) { - var name = allNames[q]; - var start = name.substring(0, 5); - if(start === 'xaxis' || start === 'yaxis') { - var emptyCategories = newFullLayout[name]._emptyCategories; - if(emptyCategories) emptyCategories(); + if(configChanged) { + plotDone = exports.newPlot(gd, data, layout, config); + } else { + gd.data = data || []; + helpers.cleanData(gd.data); + gd.layout = layout || {}; + helpers.cleanLayout(gd.layout); + + applyUIRevisions(gd.data, gd.layout, oldFullData, oldFullLayout); + + // "true" skips updating calcdata and remapping arrays from calcTransforms, + // which supplyDefaults usually does at the end, but we may need to NOT do + // if the diff (which we haven't determined yet) says we'll recalc + Plots.supplyDefaults(gd, {skipUpdateCalc: true}); + + var newFullData = gd._fullData; + var newFullLayout = gd._fullLayout; + var immutable = newFullLayout.datarevision === undefined; + var transition = newFullLayout.transition; + + var relayoutFlags = diffLayout(gd, oldFullLayout, newFullLayout, immutable, transition); + var newDataRevision = relayoutFlags.newDataRevision; + var restyleFlags = diffData(gd, oldFullData, newFullData, immutable, transition, newDataRevision); + + // TODO: how to translate this part of relayout to Plotly.react? + // // Setting width or height to null must reset the graph's width / height + // // back to its initial value as computed during the first pass in Plots.plotAutoSize. + // // + // // To do so, we must manually set them back here using the _initialAutoSize cache. + // if(['width', 'height'].indexOf(ai) !== -1 && vi === null) { + // fullLayout[ai] = gd._initialAutoSize[ai]; + // } + + if(updateAutosize(gd)) relayoutFlags.layoutReplot = true; + + // clear calcdata and empty categories if required + if(restyleFlags.calc || relayoutFlags.calc) { + gd.calcdata = undefined; + var allNames = Object.getOwnPropertyNames(newFullLayout); + for(var q = 0; q < allNames.length; q++) { + var name = allNames[q]; + var start = name.substring(0, 5); + if(start === 'xaxis' || start === 'yaxis') { + var emptyCategories = newFullLayout[name]._emptyCategories; + if(emptyCategories) emptyCategories(); + } } + // otherwise do the calcdata updates and calcTransform array remaps that we skipped earlier + } else { + Plots.supplyDefaultsUpdateCalc(gd.calcdata, newFullData); } - // otherwise do the calcdata updates and calcTransform array remaps that we skipped earlier - } else { - Plots.supplyDefaultsUpdateCalc(gd.calcdata, newFullData); - } - // Note: what restyle/relayout use impliedEdits and clearAxisTypes for - // must be handled by the user when using Plotly.react. + // Note: what restyle/relayout use impliedEdits and clearAxisTypes for + // must be handled by the user when using Plotly.react. - // fill in redraw sequence - var seq = []; + // fill in redraw sequence + var seq = []; - if(frames) { - gd._transitionData = {}; - Plots.createTransitionData(gd); - seq.push(addFrames); - } + if(frames) { + gd._transitionData = {}; + Plots.createTransitionData(gd); + seq.push(addFrames); + } - // Transition pathway, - // only used when 'transition' is set by user and - // when at least one animatable attribute has changed, - // N.B. config changed aren't animatable - if(newFullLayout.transition && !configChanged && (restyleFlags.anim || relayoutFlags.anim)) { - if(relayoutFlags.ticks) seq.push(subroutines.doTicksRelayout); + // Transition pathway, + // only used when 'transition' is set by user and + // when at least one animatable attribute has changed, + // N.B. config changed aren't animatable + if(newFullLayout.transition && (restyleFlags.anim || relayoutFlags.anim)) { + if(relayoutFlags.ticks) seq.push(subroutines.doTicksRelayout); - Plots.doCalcdata(gd); - subroutines.doAutoRangeAndConstraints(gd); + Plots.doCalcdata(gd); + subroutines.doAutoRangeAndConstraints(gd); - seq.push(function() { - return Plots.transitionFromReact(gd, restyleFlags, relayoutFlags, oldFullLayout); - }); - } else if(restyleFlags.fullReplot || relayoutFlags.layoutReplot || configChanged) { - gd._fullLayout._skipDefaults = true; - seq.push(exports._doPlot); - } else { - for(var componentType in relayoutFlags.arrays) { - var indices = relayoutFlags.arrays[componentType]; - if(indices.length) { - var drawOne = Registry.getComponentMethod(componentType, 'drawOne'); - if(drawOne !== Lib.noop) { - for(var i = 0; i < indices.length; i++) { - drawOne(gd, indices[i]); - } - } else { - var draw = Registry.getComponentMethod(componentType, 'draw'); - if(draw === Lib.noop) { - throw new Error('cannot draw components: ' + componentType); + seq.push(function() { + return Plots.transitionFromReact(gd, restyleFlags, relayoutFlags, oldFullLayout); + }); + } else if(restyleFlags.fullReplot || relayoutFlags.layoutReplot) { + gd._fullLayout._skipDefaults = true; + seq.push(exports._doPlot); + } else { + for(var componentType in relayoutFlags.arrays) { + var indices = relayoutFlags.arrays[componentType]; + if(indices.length) { + var drawOne = Registry.getComponentMethod(componentType, 'drawOne'); + if(drawOne !== Lib.noop) { + for(var i = 0; i < indices.length; i++) { + drawOne(gd, indices[i]); + } + } else { + var draw = Registry.getComponentMethod(componentType, 'draw'); + if(draw === Lib.noop) { + throw new Error('cannot draw components: ' + componentType); + } + draw(gd); } - draw(gd); } } - } - seq.push(Plots.previousPromises); - if(restyleFlags.style) seq.push(subroutines.doTraceStyle); - if(restyleFlags.colorbars || relayoutFlags.colorbars) seq.push(subroutines.doColorBars); - if(relayoutFlags.legend) seq.push(subroutines.doLegend); - if(relayoutFlags.layoutstyle) seq.push(subroutines.layoutStyles); - if(relayoutFlags.axrange) addAxRangeSequence(seq); - if(relayoutFlags.ticks) seq.push(subroutines.doTicksRelayout); - if(relayoutFlags.modebar) seq.push(subroutines.doModeBar); - if(relayoutFlags.camera) seq.push(subroutines.doCamera); - seq.push(emitAfterPlot); - } + seq.push(Plots.previousPromises); + if(restyleFlags.style) seq.push(subroutines.doTraceStyle); + if(restyleFlags.colorbars || relayoutFlags.colorbars) seq.push(subroutines.doColorBars); + if(relayoutFlags.legend) seq.push(subroutines.doLegend); + if(relayoutFlags.layoutstyle) seq.push(subroutines.layoutStyles); + if(relayoutFlags.axrange) addAxRangeSequence(seq); + if(relayoutFlags.ticks) seq.push(subroutines.doTicksRelayout); + if(relayoutFlags.modebar) seq.push(subroutines.doModeBar); + if(relayoutFlags.camera) seq.push(subroutines.doCamera); + seq.push(emitAfterPlot); + } - seq.push( - Plots.rehover, - Plots.redrag, - Plots.reselect - ); + seq.push( + Plots.rehover, + Plots.redrag, + Plots.reselect + ); - plotDone = Lib.syncOrAsync(seq, gd); - if(!plotDone || !plotDone.then) plotDone = Promise.resolve(gd); + plotDone = Lib.syncOrAsync(seq, gd); + if(!plotDone || !plotDone.then) plotDone = Promise.resolve(gd); + } } return plotDone.then(function() {