@@ -900,6 +900,20 @@ describe('Plotly.react and uirevision attributes', function() {
900
900
901
901
afterEach ( destroyGraphDiv ) ;
902
902
903
+ function checkCloseIfArray ( val1 , val2 , msg ) {
904
+ if ( Array . isArray ( val1 ) && Array . isArray ( val2 ) ) {
905
+ if ( Array . isArray ( val1 [ 0 ] ) && Array . isArray ( val2 [ 0 ] ) ) {
906
+ expect ( val1 ) . toBeCloseTo2DArray ( val2 , 2 , msg ) ;
907
+ }
908
+ else {
909
+ expect ( val1 ) . toBeCloseToArray ( val2 , 2 , msg ) ;
910
+ }
911
+ }
912
+ else {
913
+ expect ( val1 ) . toBe ( val2 , msg ) ;
914
+ }
915
+ }
916
+
903
917
function checkState ( dataKeys , layoutKeys , msg ) {
904
918
var np = Lib . nestedProperty ;
905
919
return function ( ) {
@@ -913,17 +927,19 @@ describe('Plotly.react and uirevision attributes', function() {
913
927
var val = traceKeys [ key ] ;
914
928
var valIn = Array . isArray ( val ) ? val [ 0 ] : val ;
915
929
var valOut = Array . isArray ( val ) ? val [ val . length - 1 ] : val ;
916
- expect ( np ( trace , key ) . get ( ) ) . toEqual ( valIn , msg + ': data[' + i + '].' + key ) ;
917
- expect ( np ( fullTrace , key ) . get ( ) ) . toEqual ( valOut , msg + ': _fullData[' + i + '].' + key ) ;
930
+ checkCloseIfArray ( np ( trace , key ) . get ( ) , valIn , msg + ': data[' + i + '].' + key ) ;
931
+ checkCloseIfArray ( np ( fullTrace , key ) . get ( ) , valOut , msg + ': _fullData[' + i + '].' + key ) ;
932
+ checkCloseIfArray ( np ( trace , key ) . get ( ) , valIn , msg + ': data[' + i + '].' + key ) ;
933
+ checkCloseIfArray ( np ( fullTrace , key ) . get ( ) , valOut , msg + ': _fullData[' + i + '].' + key ) ;
918
934
}
919
935
} ) ;
920
936
921
937
for ( var key in ( layoutKeys || { } ) ) {
922
938
var val = layoutKeys [ key ] ;
923
939
var valIn = Array . isArray ( val ) ? val [ 0 ] : val ;
924
940
var valOut = Array . isArray ( val ) ? val [ val . length - 1 ] : val ;
925
- expect ( np ( gd . layout , key ) . get ( ) ) . toEqual ( valIn , msg + ': layout.' + key ) ;
926
- expect ( np ( gd . _fullLayout , key ) . get ( ) ) . toEqual ( valOut , msg + ': _fullLayout.' + key ) ;
941
+ checkCloseIfArray ( np ( gd . layout , key ) . get ( ) , valIn , msg + ': layout.' + key ) ;
942
+ checkCloseIfArray ( np ( gd . _fullLayout , key ) . get ( ) , valOut , msg + ': _fullLayout.' + key ) ;
927
943
}
928
944
} ;
929
945
}
@@ -1499,4 +1515,137 @@ describe('Plotly.react and uirevision attributes', function() {
1499
1515
1500
1516
_run ( fig , editComponents , checkInitial , checkEdited ) . then ( done ) ;
1501
1517
} ) ;
1518
+
1519
+ it ( 'preserves editable: true plot title and legend & colorbar positions using editrevision' , function ( done ) {
1520
+ function fig ( mainRev , editRev ) {
1521
+ return {
1522
+ data : [ { y : [ 1 , 2 ] } , { y : [ 2 , 1 ] } , { z : [ [ 1 , 2 ] , [ 3 , 4 ] ] , type : 'heatmap' } ] ,
1523
+ layout : {
1524
+ uirevision : mainRev ,
1525
+ editrevision : editRev
1526
+ } ,
1527
+ config : { editable : true }
1528
+ } ;
1529
+ }
1530
+
1531
+ function editEditable ( ) {
1532
+ return Registry . call ( '_guiUpdate' , gd ,
1533
+ { 'colorbar.x' : 0.8 , 'colorbar.y' : 0.6 } ,
1534
+ { title : 'yep' , 'legend.x' : 1.1 , 'legend.y' : 0.9 } ,
1535
+ [ 2 ]
1536
+ ) ;
1537
+ }
1538
+
1539
+ function checkAttrs ( original ) {
1540
+ return checkState ( [ { } , { } , {
1541
+ 'colorbar.x' : original ? [ undefined , 1.02 ] : 0.8 ,
1542
+ 'colorbar.y' : original ? [ undefined , 0.5 ] : 0.6
1543
+ } ] , {
1544
+ title : original ? [ undefined , 'Click to enter Plot title' ] : 'yep' ,
1545
+ 'legend.x' : original ? [ undefined , 1.02 ] : 1.1 ,
1546
+ 'legend.y' : original ? [ undefined , 1 ] : 0.9
1547
+ } ) ;
1548
+ }
1549
+
1550
+ _run ( fig , editEditable , checkAttrs ( true ) , checkAttrs ) . then ( done ) ;
1551
+ } ) ;
1552
+
1553
+ it ( 'preserves editable: true name, colorbar title and parcoords constraint range via trace.uirevision' , function ( done ) {
1554
+ function fig ( mainRev , traceRev ) {
1555
+ return {
1556
+ data : [ {
1557
+ type : 'parcoords' ,
1558
+ dimensions : [
1559
+ { label : 'a' , values : [ 1 , 2 , 3 , 5 ] , constraintrange : [ 2.5 , 3.5 ] } ,
1560
+ { label : 'b' , values : [ 7 , 9 , 5 , 6 ] }
1561
+ ] ,
1562
+ line : { showscale : true , color : [ 1 , 2 , 3 , 4 ] } ,
1563
+ uirevision : traceRev
1564
+ } ] ,
1565
+ layout : {
1566
+ uirevision : mainRev ,
1567
+ width : 400 ,
1568
+ height : 400 ,
1569
+ margin : { l : 100 , r : 100 , t : 100 , b : 100 }
1570
+ } ,
1571
+ config : { editable : true }
1572
+ } ;
1573
+ }
1574
+
1575
+ function attrs ( original ) {
1576
+ return {
1577
+ 'dimensions[0].constraintrange' : original ? [ [ 2.5 , 3.5 ] ] : [ [ [ 1.5 , 2.5 ] , [ 2.938 , 3.979 ] ] ] ,
1578
+ 'dimensions[1].constraintrange' : original ? undefined : [ [ 6.937 , 7.979 ] ] ,
1579
+ 'line.colorbar.title' : original ? [ undefined , 'Click to enter Colorscale title' ] : 'color' ,
1580
+ name : original ? [ undefined , 'trace 0' ] : 'name'
1581
+ } ;
1582
+ }
1583
+
1584
+ function axisDragNode ( i ) {
1585
+ return document . querySelectorAll ( '.axis-brush .background' ) [ i ] ;
1586
+ }
1587
+
1588
+ function editTrace ( ) {
1589
+ var _ ;
1590
+ return Registry . call ( '_guiRestyle' , gd ,
1591
+ { 'line.colorbar.title' : 'color' , name : 'name' } ,
1592
+ [ 0 ]
1593
+ )
1594
+ . then ( function ( ) {
1595
+ return drag ( axisDragNode ( 0 ) , 0 , 50 , _ , _ , _ , _ , true ) ;
1596
+ } )
1597
+ . then ( function ( ) {
1598
+ return drag ( axisDragNode ( 0 ) , 0 , - 50 , _ , _ , _ , _ , true ) ;
1599
+ } )
1600
+ . then ( function ( ) {
1601
+ return drag ( axisDragNode ( 1 ) , 0 , - 50 , _ , _ , _ , _ , true ) ;
1602
+ } ) ;
1603
+ }
1604
+
1605
+ _run ( fig , editTrace , checkState ( [ attrs ( true ) ] ) , checkState ( [ attrs ( ) ] ) ) . then ( done ) ;
1606
+ } ) ;
1607
+
1608
+ it ( 'preserves editable: true axis titles using the axis uirevisions' , function ( done ) {
1609
+ function fig ( mainRev , axRev ) {
1610
+ return {
1611
+ data : [
1612
+ { y : [ 1 , 2 ] } ,
1613
+ { a : [ 1 , 2 ] , b : [ 2 , 1 ] , c : [ 1 , 1 ] , type : 'scatterternary' } ,
1614
+ { r : [ 1 , 2 ] , theta : [ 1 , 2 ] , type : 'scatterpolar' }
1615
+ ] ,
1616
+ layout : {
1617
+ uirevision : mainRev ,
1618
+ xaxis : { uirevision : axRev } ,
1619
+ yaxis : { uirevision : axRev } ,
1620
+ ternary : {
1621
+ aaxis : { uirevision : axRev } ,
1622
+ baxis : { uirevision : axRev } ,
1623
+ caxis : { uirevision : axRev }
1624
+ } ,
1625
+ polar : { radialaxis : { uirevision : axRev } }
1626
+ } ,
1627
+ config : { editable : true }
1628
+ } ;
1629
+ }
1630
+
1631
+ function attrs ( original ) {
1632
+ return {
1633
+ 'xaxis.title' : original ? [ undefined , 'Click to enter X axis title' ] : 'XXX' ,
1634
+ 'yaxis.title' : original ? [ undefined , 'Click to enter Y axis title' ] : 'YYY' ,
1635
+ 'ternary.aaxis.title' : original ? [ undefined , 'Component A' ] : 'AAA' ,
1636
+ 'ternary.baxis.title' : original ? [ undefined , 'Component B' ] : 'BBB' ,
1637
+ 'ternary.caxis.title' : original ? [ undefined , 'Component C' ] : 'CCC' ,
1638
+ 'polar.radialaxis.title' : original ? [ undefined , '' ] : 'RRR'
1639
+ } ;
1640
+ }
1641
+
1642
+ function editComponents ( ) {
1643
+ return Registry . call ( '_guiRelayout' , gd , attrs ( ) ) ;
1644
+ }
1645
+
1646
+ var checkInitial = checkState ( [ ] , attrs ( true ) ) ;
1647
+ var checkEdited = checkState ( [ ] , attrs ( ) ) ;
1648
+
1649
+ _run ( fig , editComponents , checkInitial , checkEdited ) . then ( done ) ;
1650
+ } ) ;
1502
1651
} ) ;
0 commit comments