@@ -148,7 +148,14 @@ plots.registerSubplot = function(subplotType, attr, idRoot, attributes) {
148
148
} ;
149
149
} ;
150
150
151
+ // TODO separate the 'find subplot' step from the 'get subplot ids' step
151
152
plots . getSubplotIds = function getSubplotIds ( layout , type ) {
153
+
154
+ // layout must be 'fullLayout' here
155
+ if ( type === 'cartesian' ) {
156
+ return Object . keys ( layout . _plots ) ;
157
+ }
158
+
152
159
var idRegex = plots . subplotsRegistry [ type ] . idRegex ,
153
160
layoutKeys = Object . keys ( layout ) ,
154
161
subplotIds = [ ] ,
@@ -560,22 +567,23 @@ Plotly.plot = function(gd, data, layout, config) {
560
567
}
561
568
562
569
function positionAndAutorange ( ) {
563
- var i , j , subplots , subplotInfo , modules , module ;
564
-
565
570
if ( ! recalc ) return ;
566
571
572
+ var subplots = plots . getSubplotIds ( fullLayout , 'cartesian' ) ,
573
+ modules = gd . _modules ;
574
+
567
575
// position and range calculations for traces that
568
576
// depend on each other ie bars (stacked or grouped)
569
577
// and boxes (grouped) push each other out of the way
570
- subplots = Plotly . Axes . getSubplots ( gd ) ;
571
- modules = gd . _modules ;
572
- for ( i = 0 ; i < subplots . length ; i ++ ) {
573
- subplotInfo = gd . _fullLayout . _plots [ subplots [ i ] ] ;
574
- for ( j = 0 ; j < modules . length ; j ++ ) {
575
- module = modules [ j ] ;
576
- if ( module . setPositions ) {
577
- module . setPositions ( gd , subplotInfo ) ;
578
- }
578
+
579
+ var subplotInfo , _module ;
580
+
581
+ for ( var i = 0 ; i < subplots . length ; i ++ ) {
582
+ subplotInfo = fullLayout . _plots [ subplots [ i ] ] ;
583
+
584
+ for ( var j = 0 ; j < modules . length ; j ++ ) {
585
+ _module = modules [ j ] ;
586
+ if ( _module . setPositions ) _module . setPositions ( gd , subplotInfo ) ;
579
587
}
580
588
}
581
589
@@ -607,10 +615,10 @@ Plotly.plot = function(gd, data, layout, config) {
607
615
return Plotly . Axes . doTicks ( gd , 'redraw' ) ;
608
616
}
609
617
610
- function drawData ( ) {
618
+ function drawData ( ) {
611
619
// Now plot the data
612
620
var calcdata = gd . calcdata ,
613
- subplots = Plotly . Axes . getSubplots ( gd ) ,
621
+ subplots = plots . getSubplotIds ( fullLayout , 'cartesian' ) ,
614
622
modules = gd . _modules ;
615
623
616
624
var i , j , cd , trace , uid , subplot , subplotInfo ,
@@ -666,7 +674,7 @@ Plotly.plot = function(gd, data, layout, config) {
666
674
// remove old traces, then redraw everything
667
675
// TODO: use enter/exit appropriately in the plot functions
668
676
// so we don't need this - should sometimes be a big speedup
669
- subplotInfo . plot . selectAll ( 'g.trace' ) . remove ( ) ;
677
+ if ( subplotInfo . plot ) subplotInfo . plot . selectAll ( 'g.trace' ) . remove ( ) ;
670
678
671
679
for ( j = 0 ; j < modules . length ; j ++ ) {
672
680
module = modules [ j ] ;
@@ -684,7 +692,7 @@ Plotly.plot = function(gd, data, layout, config) {
684
692
}
685
693
686
694
// finally do all error bars at once
687
- if ( Plotly . ErrorBars ) {
695
+ if ( gd . _fullLayout . _hasCartesian && Plotly . ErrorBars ) {
688
696
Plotly . ErrorBars . plot ( gd , subplotInfo , cdError ) ;
689
697
Plotly . Lib . markTime ( 'done ErrorBars' ) ;
690
698
}
@@ -3527,7 +3535,6 @@ function getGraphDiv(gd) {
3527
3535
// -------------------------------------------------------
3528
3536
function makePlotFramework ( gd ) {
3529
3537
var gd3 = d3 . select ( gd ) ,
3530
- subplots = Plotly . Axes . getSubplots ( gd ) ,
3531
3538
fullLayout = gd . _fullLayout ;
3532
3539
3533
3540
/*
@@ -3598,6 +3605,75 @@ function makePlotFramework(gd) {
3598
3605
fullLayout . _draggers = fullLayout . _paper . append ( 'g' )
3599
3606
. classed ( 'draglayer' , true ) ;
3600
3607
3608
+ var subplots = Plotly . Axes . getSubplots ( gd ) ;
3609
+ makeSubplots ( gd , subplots ) ;
3610
+
3611
+ if ( fullLayout . _hasCartesian ) makeCartesianPlotFramwork ( gd , subplots ) ;
3612
+
3613
+ // single shape and pie layers for the whole plot
3614
+ fullLayout . _shapelayer = fullLayout . _paper . append ( 'g' ) . classed ( 'shapelayer' , true ) ;
3615
+ fullLayout . _pielayer = fullLayout . _paper . append ( 'g' ) . classed ( 'pielayer' , true ) ;
3616
+
3617
+ // fill in image server scrape-svg
3618
+ fullLayout . _glimages = fullLayout . _paper . append ( 'g' ) . classed ( 'glimages' , true ) ;
3619
+ fullLayout . _geoimages = fullLayout . _paper . append ( 'g' ) . classed ( 'geoimages' , true ) ;
3620
+
3621
+ // lastly info (legend, annotations) and hover layers go on top
3622
+ // these are in a different svg element normally, but get collapsed into a single
3623
+ // svg when exporting (after inserting 3D)
3624
+ fullLayout . _infolayer = fullLayout . _toppaper . append ( 'g' ) . classed ( 'infolayer' , true ) ;
3625
+ fullLayout . _hoverlayer = fullLayout . _toppaper . append ( 'g' ) . classed ( 'hoverlayer' , true ) ;
3626
+
3627
+ $ ( gd ) . trigger ( 'plotly_framework' ) ;
3628
+
3629
+ // position and style the containers, make main title
3630
+ var frameWorkDone = Plotly . Lib . syncOrAsync ( [
3631
+ layoutStyles ,
3632
+ function goAxes ( ) { return Plotly . Axes . doTicks ( gd , 'redraw' ) ; } ,
3633
+ Plotly . Fx . init
3634
+ ] , gd ) ;
3635
+
3636
+ if ( frameWorkDone && frameWorkDone . then ) {
3637
+ gd . _promises . push ( frameWorkDone ) ;
3638
+ }
3639
+
3640
+ return frameWorkDone ;
3641
+ }
3642
+
3643
+ // create '_plots' object grouping x/y axes into subplots
3644
+ // to be better manage subplots
3645
+ function makeSubplots ( gd , subplots ) {
3646
+ var _plots = gd . _fullLayout . _plots = { } ;
3647
+
3648
+ var subplot , plotinfo ;
3649
+
3650
+ function getAxisFunc ( subplot , axLetter ) {
3651
+ return function ( ) {
3652
+ return Plotly . Axes . getFromId ( gd , subplot , axLetter ) ;
3653
+ } ;
3654
+ }
3655
+
3656
+ for ( var i = 0 ; i < subplots . length ; i ++ ) {
3657
+ subplot = subplots [ i ] ;
3658
+ plotinfo = _plots [ subplot ] = { } ;
3659
+
3660
+ plotinfo . id = subplot ;
3661
+
3662
+ // references to the axis objects controlling this subplot
3663
+ plotinfo . x = getAxisFunc ( subplot , 'x' ) ;
3664
+ plotinfo . y = getAxisFunc ( subplot , 'y' ) ;
3665
+
3666
+ // TODO investigate why replacing calls to .x and .y
3667
+ // for .xaxis and .yaxis makes the `pseudo_html`
3668
+ // test image fail
3669
+ plotinfo . xaxis = plotinfo . x ( ) ;
3670
+ plotinfo . yaxis = plotinfo . y ( ) ;
3671
+ }
3672
+ }
3673
+
3674
+ function makeCartesianPlotFramwork ( gd , subplots ) {
3675
+ var fullLayout = gd . _fullLayout ;
3676
+
3601
3677
// Layers to keep plot types in the right order.
3602
3678
// from back to front:
3603
3679
// 1. heatmaps, 2D histos and contour maps
@@ -3615,23 +3691,16 @@ function makePlotFramework(gd) {
3615
3691
3616
3692
// create all the layers in order, so we know they'll stay in order
3617
3693
var overlays = [ ] ;
3618
- fullLayout . _plots = { } ;
3694
+
3619
3695
fullLayout . _paper . selectAll ( 'g.subplot' ) . data ( subplots )
3620
3696
. enter ( ) . append ( 'g' )
3621
- . classed ( 'subplot' , true )
3622
- . each ( function ( subplot ) {
3623
- var plotinfo = fullLayout . _plots [ subplot ] = { } ,
3624
- plotgroup = d3 . select ( this ) . classed ( subplot , true ) ;
3625
- plotinfo . id = subplot ;
3626
- // references to the axis objects controlling this subplot
3627
- plotinfo . x = function ( ) {
3628
- return Plotly . Axes . getFromId ( gd , subplot , 'x' ) ;
3629
- } ;
3630
- plotinfo . y = function ( ) {
3631
- return Plotly . Axes . getFromId ( gd , subplot , 'y' ) ;
3632
- } ;
3633
- var xa = plotinfo . x ( ) ,
3634
- ya = plotinfo . y ( ) ;
3697
+ . classed ( 'subplot' , true )
3698
+ . each ( function ( subplot ) {
3699
+ var plotinfo = fullLayout . _plots [ subplot ] ,
3700
+ plotgroup = plotinfo . plotgroup = d3 . select ( this ) . classed ( subplot , true ) ,
3701
+ xa = plotinfo . xaxis ,
3702
+ ya = plotinfo . yaxis ;
3703
+
3635
3704
// references to any subplots overlaid on this one
3636
3705
plotinfo . overlays = [ ] ;
3637
3706
@@ -3670,7 +3739,7 @@ function makePlotFramework(gd) {
3670
3739
// main subplot - make the components of
3671
3740
// the plot and containers for overlays
3672
3741
plotinfo . bg = plotgroup . append ( 'rect' )
3673
- . style ( 'stroke-width' , 0 ) ;
3742
+ . style ( 'stroke-width' , 0 ) ;
3674
3743
plotinfo . gridlayer = plotgroup . append ( 'g' ) ;
3675
3744
plotinfo . overgrid = plotgroup . append ( 'g' ) ;
3676
3745
plotinfo . zerolinelayer = plotgroup . append ( 'g' ) ;
@@ -3691,6 +3760,7 @@ function makePlotFramework(gd) {
3691
3760
plotinfo . draglayer = fullLayout . _draggers . append ( 'g' ) ;
3692
3761
} ) ;
3693
3762
3763
+
3694
3764
// now make the components of overlaid subplots
3695
3765
// overlays don't have backgrounds, and append all
3696
3766
// their other components to the corresponding
@@ -3711,6 +3781,7 @@ function makePlotFramework(gd) {
3711
3781
// common attributes for all subplots, overlays or not
3712
3782
subplots . forEach ( function ( subplot ) {
3713
3783
var plotinfo = fullLayout . _plots [ subplot ] ;
3784
+
3714
3785
plotinfo . plot
3715
3786
. attr ( 'preserveAspectRatio' , 'none' )
3716
3787
. style ( 'fill' , 'none' ) ;
@@ -3721,35 +3792,6 @@ function makePlotFramework(gd) {
3721
3792
. style ( 'fill' , 'none' )
3722
3793
. classed ( 'crisp' , true ) ;
3723
3794
} ) ;
3724
-
3725
- // single shape and pie layers for the whole plot
3726
- fullLayout . _shapelayer = fullLayout . _paper . append ( 'g' ) . classed ( 'shapelayer' , true ) ;
3727
- fullLayout . _pielayer = fullLayout . _paper . append ( 'g' ) . classed ( 'pielayer' , true ) ;
3728
-
3729
- // fill in image server scrape-svg
3730
- fullLayout . _glimages = fullLayout . _paper . append ( 'g' ) . classed ( 'glimages' , true ) ;
3731
- fullLayout . _geoimages = fullLayout . _paper . append ( 'g' ) . classed ( 'geoimages' , true ) ;
3732
-
3733
- // lastly info (legend, annotations) and hover layers go on top
3734
- // these are in a different svg element normally, but get collapsed into a single
3735
- // svg when exporting (after inserting 3D)
3736
- fullLayout . _infolayer = fullLayout . _toppaper . append ( 'g' ) . classed ( 'infolayer' , true ) ;
3737
- fullLayout . _hoverlayer = fullLayout . _toppaper . append ( 'g' ) . classed ( 'hoverlayer' , true ) ;
3738
-
3739
- $ ( gd ) . trigger ( 'plotly_framework' ) ;
3740
-
3741
- // position and style the containers, make main title
3742
- var frameWorkDone = Plotly . Lib . syncOrAsync ( [
3743
- layoutStyles ,
3744
- function goAxes ( ) { return Plotly . Axes . doTicks ( gd , 'redraw' ) ; } ,
3745
- Plotly . Fx . init
3746
- ] , gd ) ;
3747
-
3748
- if ( frameWorkDone && frameWorkDone . then ) {
3749
- gd . _promises . push ( frameWorkDone ) ;
3750
- }
3751
-
3752
- return frameWorkDone ;
3753
3795
}
3754
3796
3755
3797
// called by legend and colorbar routines to see if we need to
0 commit comments