@@ -1330,6 +1330,7 @@ plots.supplyDefaults = function(gd) {
1330
1330
if ( plots . traceIs ( fullTrace , 'cartesian' ) ) newFullLayout . _hasCartesian = true ;
1331
1331
else if ( plots . traceIs ( fullTrace , 'gl3d' ) ) newFullLayout . _hasGL3D = true ;
1332
1332
else if ( plots . traceIs ( fullTrace , 'geo' ) ) newFullLayout . _hasGeo = true ;
1333
+ else if ( plots . traceIs ( fullTrace , 'pie' ) ) newFullLayout . _hasPie = true ;
1333
1334
else if ( 'r' in fullTrace ) newFullLayout . _hasPolar = true ;
1334
1335
1335
1336
module = fullTrace . _module ;
@@ -1596,6 +1597,10 @@ plots.layoutAttributes = {
1596
1597
_hasGeo : {
1597
1598
type : 'boolean' ,
1598
1599
dflt : false
1600
+ } ,
1601
+ _hasPie : {
1602
+ type : 'boolean' ,
1603
+ dflt : false
1599
1604
}
1600
1605
} ;
1601
1606
@@ -1635,6 +1640,7 @@ plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut) {
1635
1640
coerce ( '_hasCartesian' ) ;
1636
1641
coerce ( '_hasGL3D' ) ;
1637
1642
coerce ( '_hasGeo' ) ;
1643
+ coerce ( '_hasPie' ) ;
1638
1644
} ;
1639
1645
1640
1646
plots . supplyLayoutModuleDefaults = function ( layoutIn , layoutOut , fullData ) {
@@ -2487,7 +2493,8 @@ Plotly.restyle = function restyle (gd,astr,val,traces) {
2487
2493
// for the undo / redo queue
2488
2494
var redoit = { } ,
2489
2495
undoit = { } ,
2490
- axlist ;
2496
+ axlist ,
2497
+ flagAxForDelete = [ ] ;
2491
2498
2492
2499
// for now, if we detect 3D or geo stuff, just re-do the plot
2493
2500
if ( fullLayout . _hasGL3D || fullLayout . _hasGeo ) doplot = true ;
@@ -2506,6 +2513,7 @@ Plotly.restyle = function restyle (gd,astr,val,traces) {
2506
2513
// for attrs that interact (like scales & autoscales), save the
2507
2514
// old vals before making the change
2508
2515
// val=undefined will not set a value, just record what the value was.
2516
+ // val=null will delete the attribute
2509
2517
// attr can be an array to set several at once (all to the same val)
2510
2518
function doextra ( cont , attr , val , i ) {
2511
2519
if ( Array . isArray ( attr ) ) {
@@ -2536,7 +2544,8 @@ Plotly.restyle = function restyle (gd,astr,val,traces) {
2536
2544
var vi = aobj [ ai ] ,
2537
2545
cont ,
2538
2546
contFull ,
2539
- param ;
2547
+ param ,
2548
+ oldVal ;
2540
2549
redoit [ ai ] = vi ;
2541
2550
2542
2551
if ( layoutAttrs . indexOf ( ai . replace ( / [ x y z ] a x i s [ 0 - 9 ] * / g, '?axis' ) ) !== - 1 ) {
@@ -2557,6 +2566,7 @@ Plotly.restyle = function restyle (gd,astr,val,traces) {
2557
2566
cont = gd . data [ traces [ i ] ] ;
2558
2567
contFull = gd . _fullData [ traces [ i ] ] ;
2559
2568
param = Plotly . Lib . nestedProperty ( cont , ai ) ;
2569
+ oldVal = param . get ( ) ;
2560
2570
2561
2571
// setting bin or z settings should turn off auto
2562
2572
// and setting auto should save bin or z settings
@@ -2638,8 +2648,29 @@ Plotly.restyle = function restyle (gd,astr,val,traces) {
2638
2648
doextra ( cont , [ 'colorbar.tick0' , 'colorbar.dtick' ] , undefined ) ;
2639
2649
}
2640
2650
2641
- // save the old value
2642
- undoit [ ai ] [ i ] = param . get ( ) ;
2651
+
2652
+ if ( ai === 'type' && ( vi === 'pie' ) !== ( oldVal === 'pie' ) ) {
2653
+ var labelsTo = 'x' ,
2654
+ valuesTo = 'y' ;
2655
+ if ( ( vi === 'bar' || oldVal === 'bar' ) && cont . orientation === 'h' ) {
2656
+ labelsTo = 'y' ;
2657
+ valuesTo = 'x' ;
2658
+ }
2659
+ Plotly . Lib . swapAttrs ( cont , [ '?' , '?src' ] , 'labels' , labelsTo ) ;
2660
+ Plotly . Lib . swapAttrs ( cont , [ 'd?' , '?0' ] , 'label' , labelsTo ) ;
2661
+ Plotly . Lib . swapAttrs ( cont , [ '?' , '?src' ] , 'values' , valuesTo ) ;
2662
+
2663
+ if ( oldVal === 'pie' ) {
2664
+ // super kludgy - but if all pies are gone we won't remove them otherwise
2665
+ fullLayout . _pielayer . selectAll ( 'g.trace' ) . remove ( ) ;
2666
+ } else if ( plots . traceIs ( cont , 'cartesian' ) ) {
2667
+ //look for axes that are no longer in use and delete them
2668
+ flagAxForDelete . push ( cont . xaxis || 'x' ) ;
2669
+ flagAxForDelete . push ( cont . yaxis || 'y' ) ;
2670
+ }
2671
+ }
2672
+
2673
+ undoit [ ai ] [ i ] = oldVal ;
2643
2674
// set the new value - if val is an array, it's one el per trace
2644
2675
// first check for attributes that get more complex alterations
2645
2676
var swapAttrs = [
@@ -2706,12 +2737,14 @@ Plotly.restyle = function restyle (gd,astr,val,traces) {
2706
2737
for ( i = 0 ; i < traces . length ; i ++ ) {
2707
2738
var trace = gd . data [ traces [ i ] ] ;
2708
2739
2709
- addToAxlist ( trace . xaxis || 'x' ) ;
2710
- addToAxlist ( trace . yaxis || 'y' ) ;
2740
+ if ( plots . traceIs ( trace , 'cartesian' ) ) {
2741
+ addToAxlist ( trace . xaxis || 'x' ) ;
2742
+ addToAxlist ( trace . yaxis || 'y' ) ;
2711
2743
2712
- if ( astr === 'type' ) {
2713
- doextra ( gd . data [ traces [ i ] ] ,
2714
- [ 'autobinx' , 'autobiny' ] , true , i ) ;
2744
+ if ( astr === 'type' ) {
2745
+ doextra ( gd . data [ traces [ i ] ] ,
2746
+ [ 'autobinx' , 'autobiny' ] , true , i ) ;
2747
+ }
2715
2748
}
2716
2749
}
2717
2750
@@ -2723,6 +2756,24 @@ Plotly.restyle = function restyle (gd,astr,val,traces) {
2723
2756
else if ( replotAttrs . indexOf ( ai ) !== - 1 ) doplot = true ;
2724
2757
else if ( autorangeAttrs . indexOf ( ai ) !== - 1 ) docalcAutorange = true ;
2725
2758
}
2759
+
2760
+ // check axes we've flagged for possible deletion
2761
+ axisLoop:
2762
+ for ( i = 0 ; i < flagAxForDelete . length ; i ++ ) {
2763
+ var axId = flagAxForDelete [ i ] ,
2764
+ axLetter = axId . charAt ( 0 ) ,
2765
+ axAttr = axLetter + 'axis' ;
2766
+ for ( var j = 0 ; j < gd . data . length ; j ++ ) {
2767
+ if ( plots . traceIs ( gd . data [ j ] , 'cartesian' ) &&
2768
+ ( gd . data [ j ] [ axAttr ] || axLetter ) === axId ) {
2769
+ continue axisLoop;
2770
+ }
2771
+ }
2772
+
2773
+ // no data on this axis - delete it.
2774
+ doextra ( gd . layout , Plotly . Axes . id2name ( axId ) , null , 0 ) ;
2775
+ }
2776
+
2726
2777
// now all attribute mods are done, as are redo and undo
2727
2778
// so we can save them
2728
2779
if ( Plotly . Queue ) {
@@ -2809,7 +2860,7 @@ Plotly.restyle = function restyle (gd,astr,val,traces) {
2809
2860
// swap all the data and data attributes associated with x and y
2810
2861
function swapXYData ( trace ) {
2811
2862
var i ;
2812
- Plotly . Lib . swapXYAttrs ( trace , [ '?' , '?0' , 'd?' , '?bins' , 'nbins?' , 'autobin?' , '?src' , 'error_?' ] ) ;
2863
+ Plotly . Lib . swapAttrs ( trace , [ '?' , '?0' , 'd?' , '?bins' , 'nbins?' , 'autobin?' , '?src' , 'error_?' ] ) ;
2813
2864
if ( Array . isArray ( trace . z ) && Array . isArray ( trace . z [ 0 ] ) ) {
2814
2865
if ( trace . transpose ) delete trace . transpose ;
2815
2866
else trace . transpose = true ;
@@ -2818,9 +2869,9 @@ function swapXYData(trace) {
2818
2869
var errorY = trace . error_y ,
2819
2870
copyYstyle = ( 'copy_ystyle' in errorY ) ? errorY . copy_ystyle :
2820
2871
! ( errorY . color || errorY . thickness || errorY . width ) ;
2821
- Plotly . Lib . swapXYAttrs ( trace , [ 'error_?.copy_ystyle' ] ) ;
2872
+ Plotly . Lib . swapAttrs ( trace , [ 'error_?.copy_ystyle' ] ) ;
2822
2873
if ( copyYstyle ) {
2823
- Plotly . Lib . swapXYAttrs ( trace , [ 'error_?.color' , 'error_?.thickness' , 'error_?.width' ] ) ;
2874
+ Plotly . Lib . swapAttrs ( trace , [ 'error_?.color' , 'error_?.thickness' , 'error_?.width' ] ) ;
2824
2875
}
2825
2876
}
2826
2877
if ( trace . hoverinfo ) {
0 commit comments