diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index 76d051c5a23..61e26cd5ff0 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -1580,6 +1580,12 @@ function _restyle(gd, aobj, _traces) { var moduleAttrs = (contFull._module || {}).attributes || {}; var valObject = Lib.nestedProperty(moduleAttrs, ai).get() || {}; + // if restyling entire attribute container, assume worse case + if(!valObject.valType) { + flags.docalc = true; + } + + // must redo calcdata when restyling array values of arrayOk attributes if(valObject.arrayOk && (Array.isArray(newVal) || Array.isArray(oldVal))) { flags.docalc = true; } diff --git a/test/jasmine/tests/plot_api_test.js b/test/jasmine/tests/plot_api_test.js index d768f3b99b4..eee008c4a4f 100644 --- a/test/jasmine/tests/plot_api_test.js +++ b/test/jasmine/tests/plot_api_test.js @@ -330,6 +330,25 @@ describe('Test plot api', function() { expect(PlotlyInternal.plot).toHaveBeenCalled(); }); + it('should do full replot when attribute container are updated', function() { + var gd = { + data: [{x: [1, 2, 3], y: [1, 2, 3]}], + layout: { + xaxis: { range: [0, 4] }, + yaxis: { range: [0, 4] } + } + }; + + mockDefaultsAndCalc(gd); + Plotly.restyle(gd, { + marker: { + color: ['red', 'blue', 'green'] + } + }); + expect(gd.calcdata).toBeUndefined(); + expect(PlotlyInternal.plot).toHaveBeenCalled(); + }); + it('calls plot on xgap and ygap styling', function() { var gd = { data: [{z: [[1, 2, 3], [4, 5, 6], [7, 8, 9]], showscale: false, type: 'heatmap'}],