@@ -1193,8 +1193,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1193
1193
gd = helpers . getGraphDiv ( gd ) ;
1194
1194
helpers . clearPromiseQueue ( gd ) ;
1195
1195
1196
- var i , fullLayout = gd . _fullLayout ,
1197
- aobj = { } ;
1196
+ var aobj = { } ;
1198
1197
1199
1198
if ( typeof astr === 'string' ) aobj [ astr ] = val ;
1200
1199
else if ( Lib . isPlainObject ( astr ) ) {
@@ -1208,10 +1207,71 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1208
1207
1209
1208
if ( Object . keys ( aobj ) . length ) gd . changed = true ;
1210
1209
1210
+ var specs = _restyle ( gd , aobj , traces ) ,
1211
+ flags = specs . flags ;
1212
+
1213
+ // clear calcdata if required
1214
+ if ( flags . clearCalc ) gd . calcdata = undefined ;
1215
+
1216
+ // fill in redraw sequence
1217
+ var seq = [ ] ;
1218
+
1219
+ if ( flags . fullReplot ) {
1220
+ seq . push ( Plotly . plot ) ;
1221
+ }
1222
+ else {
1223
+ seq . push ( Plots . previousPromises ) ;
1224
+
1225
+ Plots . supplyDefaults ( gd ) ;
1226
+
1227
+ if ( flags . dostyle ) seq . push ( subroutines . doTraceStyle ) ;
1228
+ if ( flags . docolorbars ) seq . push ( subroutines . doColorBars ) ;
1229
+ }
1230
+
1231
+ Queue . add ( gd ,
1232
+ restyle , [ gd , specs . undoit , specs . traces ] ,
1233
+ restyle , [ gd , specs . redoit , specs . traces ]
1234
+ ) ;
1235
+
1236
+ var plotDone = Lib . syncOrAsync ( seq , gd ) ;
1237
+ if ( ! plotDone || ! plotDone . then ) plotDone = Promise . resolve ( ) ;
1238
+
1239
+ return plotDone . then ( function ( ) {
1240
+ gd . emit ( 'plotly_restyle' , specs . eventData ) ;
1241
+ return gd ;
1242
+ } ) ;
1243
+ } ;
1244
+
1245
+ function _restyle ( gd , aobj , traces ) {
1246
+ var fullLayout = gd . _fullLayout ,
1247
+ fullData = gd . _fullData ,
1248
+ data = gd . data ,
1249
+ i ;
1250
+
1251
+ // fill up traces
1211
1252
if ( isNumeric ( traces ) ) traces = [ traces ] ;
1212
1253
else if ( ! Array . isArray ( traces ) || ! traces . length ) {
1213
- traces = gd . data . map ( function ( v , i ) { return i ; } ) ;
1214
- }
1254
+ traces = data . map ( function ( _ , i ) { return i ; } ) ;
1255
+ }
1256
+
1257
+ // initialize flags
1258
+ var flags = {
1259
+ docalc : false ,
1260
+ docalcAutorange : false ,
1261
+ doplot : false ,
1262
+ dostyle : false ,
1263
+ docolorbars : false ,
1264
+ autorangeOn : false ,
1265
+ clearCalc : false ,
1266
+ fullReplot : false
1267
+ } ;
1268
+
1269
+ // copies of the change (and previous values of anything affected)
1270
+ // for the undo / redo queue
1271
+ var redoit = { } ,
1272
+ undoit = { } ,
1273
+ axlist ,
1274
+ flagAxForDelete = { } ;
1215
1275
1216
1276
// recalcAttrs attributes need a full regeneration of calcdata
1217
1277
// as well as a replot, because the right objects may not exist,
@@ -1251,8 +1311,9 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1251
1311
'line.showscale' , 'line.cauto' , 'line.autocolorscale' , 'line.reversescale' ,
1252
1312
'marker.line.showscale' , 'marker.line.cauto' , 'marker.line.autocolorscale' , 'marker.line.reversescale'
1253
1313
] ;
1314
+
1254
1315
for ( i = 0 ; i < traces . length ; i ++ ) {
1255
- if ( Registry . traceIs ( gd . _fullData [ traces [ i ] ] , 'box' ) ) {
1316
+ if ( Registry . traceIs ( fullData [ traces [ i ] ] , 'box' ) ) {
1256
1317
recalcAttrs . push ( 'name' ) ;
1257
1318
break ;
1258
1319
}
@@ -1266,6 +1327,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1266
1327
'marker' , 'marker.size' , 'textfont' ,
1267
1328
'boxpoints' , 'jitter' , 'pointpos' , 'whiskerwidth' , 'boxmean'
1268
1329
] ;
1330
+
1269
1331
// replotAttrs attributes need a replot (because different
1270
1332
// objects need to be made) but not a recalc
1271
1333
var replotAttrs = [
@@ -1286,24 +1348,16 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1286
1348
'type' , 'x' , 'y' , 'x0' , 'y0' , 'orientation' , 'xaxis' , 'yaxis'
1287
1349
] ;
1288
1350
1289
- // flags for which kind of update we need to do
1290
- var docalc = false ,
1291
- docalcAutorange = false ,
1292
- doplot = false ,
1293
- dostyle = false ,
1294
- docolorbars = false ;
1295
- // copies of the change (and previous values of anything affected)
1296
- // for the undo / redo queue
1297
- var redoit = { } ,
1298
- undoit = { } ,
1299
- axlist ,
1300
- flagAxForDelete = { } ;
1351
+ var zscl = [ 'zmin' , 'zmax' ] ,
1352
+ xbins = [ 'xbins.start' , 'xbins.end' , 'xbins.size' ] ,
1353
+ ybins = [ 'ybins.start' , 'ybins.end' , 'ybins.size' ] ,
1354
+ contourAttrs = [ 'contours.start' , 'contours.end' , 'contours.size' ] ;
1301
1355
1302
1356
// At the moment, only cartesian, pie and ternary plot types can afford
1303
1357
// to not go through a full replot
1304
1358
var doPlotWhiteList = [ 'cartesian' , 'pie' , 'ternary' ] ;
1305
1359
fullLayout . _basePlotModules . forEach ( function ( _module ) {
1306
- if ( doPlotWhiteList . indexOf ( _module . name ) === - 1 ) docalc = true ;
1360
+ if ( doPlotWhiteList . indexOf ( _module . name ) === - 1 ) flags . docalc = true ;
1307
1361
} ) ;
1308
1362
1309
1363
// make a new empty vals array for undoit
@@ -1312,9 +1366,11 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1312
1366
// for autoranging multiple axes
1313
1367
function addToAxlist ( axid ) {
1314
1368
var axName = Plotly . Axes . id2name ( axid ) ;
1315
- if ( axlist . indexOf ( axName ) === - 1 ) { axlist . push ( axName ) ; }
1369
+ if ( axlist . indexOf ( axName ) === - 1 ) axlist . push ( axName ) ;
1316
1370
}
1371
+
1317
1372
function autorangeAttr ( axName ) { return 'LAYOUT' + axName + '.autorange' ; }
1373
+
1318
1374
function rangeAttr ( axName ) { return 'LAYOUT' + axName + '.range' ; }
1319
1375
1320
1376
// for attrs that interact (like scales & autoscales), save the
@@ -1334,7 +1390,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1334
1390
if ( attr . substr ( 0 , 6 ) === 'LAYOUT' ) {
1335
1391
extraparam = Lib . nestedProperty ( gd . layout , attr . replace ( 'LAYOUT' , '' ) ) ;
1336
1392
} else {
1337
- extraparam = Lib . nestedProperty ( gd . data [ traces [ i ] ] , attr ) ;
1393
+ extraparam = Lib . nestedProperty ( data [ traces [ i ] ] , attr ) ;
1338
1394
}
1339
1395
1340
1396
if ( ! ( attr in undoit ) ) {
@@ -1347,10 +1403,6 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1347
1403
extraparam . set ( val ) ;
1348
1404
}
1349
1405
}
1350
- var zscl = [ 'zmin' , 'zmax' ] ,
1351
- xbins = [ 'xbins.start' , 'xbins.end' , 'xbins.size' ] ,
1352
- ybins = [ 'ybins.start' , 'ybins.end' , 'ybins.size' ] ,
1353
- contourAttrs = [ 'contours.start' , 'contours.end' , 'contours.size' ] ;
1354
1406
1355
1407
// now make the changes to gd.data (and occasionally gd.layout)
1356
1408
// and figure out what kind of graphics update we need to do
@@ -1361,6 +1413,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1361
1413
param ,
1362
1414
oldVal ,
1363
1415
newVal ;
1416
+
1364
1417
redoit [ ai ] = vi ;
1365
1418
1366
1419
if ( ai . substr ( 0 , 6 ) === 'LAYOUT' ) {
@@ -1371,18 +1424,18 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1371
1424
param . set ( Array . isArray ( vi ) ? vi [ 0 ] : vi ) ;
1372
1425
// ironically, the layout attrs in restyle only require replot,
1373
1426
// not relayout
1374
- docalc = true ;
1427
+ flags . docalc = true ;
1375
1428
continue ;
1376
1429
}
1377
1430
1378
1431
// take no chances on transforms
1379
- if ( ai . substr ( 0 , 10 ) === 'transforms' ) docalc = true ;
1432
+ if ( ai . substr ( 0 , 10 ) === 'transforms' ) flags . docalc = true ;
1380
1433
1381
1434
// set attribute in gd.data
1382
1435
undoit [ ai ] = a0 ( ) ;
1383
1436
for ( i = 0 ; i < traces . length ; i ++ ) {
1384
- cont = gd . data [ traces [ i ] ] ;
1385
- contFull = gd . _fullData [ traces [ i ] ] ;
1437
+ cont = data [ traces [ i ] ] ;
1438
+ contFull = fullData [ traces [ i ] ] ;
1386
1439
param = Lib . nestedProperty ( cont , ai ) ;
1387
1440
oldVal = param . get ( ) ;
1388
1441
newVal = Array . isArray ( vi ) ? vi [ i % vi . length ] : vi ;
@@ -1540,19 +1593,19 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1540
1593
// check if we need to call axis type
1541
1594
if ( ( traces . indexOf ( 0 ) !== - 1 ) && ( axtypeAttrs . indexOf ( ai ) !== - 1 ) ) {
1542
1595
Plotly . Axes . clearTypes ( gd , traces ) ;
1543
- docalc = true ;
1596
+ flags . docalc = true ;
1544
1597
}
1545
1598
1546
1599
// switching from auto to manual binning or z scaling doesn't
1547
1600
// actually do anything but change what you see in the styling
1548
1601
// box. everything else at least needs to apply styles
1549
1602
if ( ( [ 'autobinx' , 'autobiny' , 'zauto' ] . indexOf ( ai ) === - 1 ) ||
1550
1603
newVal !== false ) {
1551
- dostyle = true ;
1604
+ flags . dostyle = true ;
1552
1605
}
1553
1606
if ( [ 'colorbar' , 'line' ] . indexOf ( param . parts [ 0 ] ) !== - 1 ||
1554
1607
param . parts [ 0 ] === 'marker' && param . parts [ 1 ] === 'colorbar' ) {
1555
- docolorbars = true ;
1608
+ flags . docolorbars = true ;
1556
1609
}
1557
1610
1558
1611
if ( recalcAttrs . indexOf ( ai ) !== - 1 ) {
@@ -1561,13 +1614,13 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1561
1614
if ( [ 'orientation' , 'type' ] . indexOf ( ai ) !== - 1 ) {
1562
1615
axlist = [ ] ;
1563
1616
for ( i = 0 ; i < traces . length ; i ++ ) {
1564
- var trace = gd . data [ traces [ i ] ] ;
1617
+ var trace = data [ traces [ i ] ] ;
1565
1618
1566
1619
if ( Registry . traceIs ( trace , 'cartesian' ) ) {
1567
1620
addToAxlist ( trace . xaxis || 'x' ) ;
1568
1621
addToAxlist ( trace . yaxis || 'y' ) ;
1569
1622
1570
- if ( astr === 'type' ) {
1623
+ if ( ai === 'type' ) {
1571
1624
doextra ( [ 'autobinx' , 'autobiny' ] , true , i ) ;
1572
1625
}
1573
1626
}
@@ -1576,12 +1629,17 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1576
1629
doextra ( axlist . map ( autorangeAttr ) , true , 0 ) ;
1577
1630
doextra ( axlist . map ( rangeAttr ) , [ 0 , 1 ] , 0 ) ;
1578
1631
}
1579
- docalc = true ;
1632
+ flags . docalc = true ;
1580
1633
}
1581
- else if ( replotAttrs . indexOf ( ai ) !== - 1 ) doplot = true ;
1582
- else if ( autorangeAttrs . indexOf ( ai ) !== - 1 ) docalcAutorange = true ;
1634
+ else if ( replotAttrs . indexOf ( ai ) !== - 1 ) flags . doplot = true ;
1635
+ else if ( autorangeAttrs . indexOf ( ai ) !== - 1 ) flags . docalcAutorange = true ;
1583
1636
}
1584
1637
1638
+ // do we need to force a recalc?
1639
+ Plotly . Axes . list ( gd ) . forEach ( function ( ax ) {
1640
+ if ( ax . autorange ) flags . autorangeOn = true ;
1641
+ } ) ;
1642
+
1585
1643
// check axes we've flagged for possible deletion
1586
1644
// flagAxForDelete is a hash so we can make sure we only get each axis once
1587
1645
var axListForDelete = Object . keys ( flagAxForDelete ) ;
@@ -1590,9 +1648,10 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1590
1648
var axId = axListForDelete [ i ] ,
1591
1649
axLetter = axId . charAt ( 0 ) ,
1592
1650
axAttr = axLetter + 'axis' ;
1593
- for ( var j = 0 ; j < gd . data . length ; j ++ ) {
1594
- if ( Registry . traceIs ( gd . data [ j ] , 'cartesian' ) &&
1595
- ( gd . data [ j ] [ axAttr ] || axLetter ) === axId ) {
1651
+
1652
+ for ( var j = 0 ; j < data . length ; j ++ ) {
1653
+ if ( Registry . traceIs ( data [ j ] , 'cartesian' ) &&
1654
+ ( data [ j ] [ axAttr ] || axLetter ) === axId ) {
1596
1655
continue axisLoop;
1597
1656
}
1598
1657
}
@@ -1601,83 +1660,21 @@ Plotly.restyle = function restyle(gd, astr, val, traces) {
1601
1660
doextra ( 'LAYOUT' + Plotly . Axes . id2name ( axId ) , null , 0 ) ;
1602
1661
}
1603
1662
1604
- // now all attribute mods are done, as are redo and undo
1605
- // so we can save them
1606
- Queue . add ( gd , restyle , [ gd , undoit , traces ] , restyle , [ gd , redoit , traces ] ) ;
1607
-
1608
- // do we need to force a recalc?
1609
- var autorangeOn = false ;
1610
- Plotly . Axes . list ( gd ) . forEach ( function ( ax ) {
1611
- if ( ax . autorange ) autorangeOn = true ;
1612
- } ) ;
1613
- if ( docalc || dolayout || ( docalcAutorange && autorangeOn ) ) {
1614
- gd . calcdata = undefined ;
1663
+ // combine a few flags together;
1664
+ if ( flags . docalc || ( flags . docalcAutorange && flags . autorangeOn ) ) {
1665
+ flags . clearCalc = true ;
1615
1666
}
1616
-
1617
- // now update the graphics
1618
- // a complete layout redraw takes care of plot and
1619
- var seq ;
1620
- }
1621
- else if ( docalc || doplot || docalcAutorange ) {
1622
- seq = [ Plotly . plot ] ;
1623
- }
1624
- else {
1625
- Plots . supplyDefaults ( gd ) ;
1626
- seq = [ Plots . previousPromises ] ;
1627
- if ( dostyle ) {
1628
- seq . push ( function doStyle ( ) {
1629
- // first see if we need to do arraysToCalcdata
1630
- // call it regardless of what change we made, in case
1631
- // supplyDefaults brought in an array that was already
1632
- // in gd.data but not in gd._fullData previously
1633
- var i , cdi , arraysToCalcdata ;
1634
- for ( i = 0 ; i < gd . calcdata . length ; i ++ ) {
1635
- cdi = gd . calcdata [ i ] ;
1636
- arraysToCalcdata = ( ( ( cdi [ 0 ] || { } ) . trace || { } ) . _module || { } ) . arraysToCalcdata ;
1637
- if ( arraysToCalcdata ) arraysToCalcdata ( cdi ) ;
1638
- }
1639
-
1640
- Plots . style ( gd ) ;
1641
- Registry . getComponentMethod ( 'legend' , 'draw' ) ( gd ) ;
1642
-
1643
- return Plots . previousPromises ( gd ) ;
1644
- } ) ;
1645
- }
1646
- if ( docolorbars ) {
1647
- seq . push ( function doColorBars ( ) {
1648
- gd . calcdata . forEach ( function ( cd ) {
1649
- if ( ( cd [ 0 ] . t || { } ) . cb ) {
1650
- var trace = cd [ 0 ] . trace ,
1651
- cb = cd [ 0 ] . t . cb ;
1652
-
1653
- if ( Registry . traceIs ( trace , 'contour' ) ) {
1654
- cb . line ( {
1655
- width : trace . contours . showlines !== false ?
1656
- trace . line . width : 0 ,
1657
- dash : trace . line . dash ,
1658
- color : trace . contours . coloring === 'line' ?
1659
- cb . _opts . line . color : trace . line . color
1660
- } ) ;
1661
- }
1662
- if ( Registry . traceIs ( trace , 'markerColorscale' ) ) {
1663
- cb . options ( trace . marker . colorbar ) ( ) ;
1664
- }
1665
- else cb . options ( trace . colorbar ) ( ) ;
1666
- }
1667
- } ) ;
1668
- return Plots . previousPromises ( gd ) ;
1669
- } ) ;
1670
- }
1667
+ if ( flags . docalc || flags . doplot || flags . docalcAutorange ) {
1668
+ flags . fullReplot = true ;
1671
1669
}
1672
1670
1673
- var plotDone = Lib . syncOrAsync ( seq , gd ) ;
1674
-
1675
- if ( ! plotDone || ! plotDone . then ) plotDone = Promise . resolve ( ) ;
1676
-
1677
- return plotDone . then ( function ( ) {
1678
- gd . emit ( 'plotly_restyle' , Lib . extendDeepNoArrays ( [ ] , [ redoit , traces ] ) ) ;
1679
- return gd ;
1680
- } ) ;
1671
+ return {
1672
+ flags : flags ,
1673
+ undoit : undoit ,
1674
+ redoit : redoit ,
1675
+ traces : traces ,
1676
+ eventData : Lib . extendDeepNoArrays ( [ ] , [ redoit , traces ] )
1677
+ } ;
1681
1678
}
1682
1679
1683
1680
/**
0 commit comments