@@ -234,6 +234,8 @@ proto.updateLayout = function(fullLayout, polarLayout) {
234
234
var yOffset2 = _this . yOffset2 = gs . t + gs . h * ( 1 - yDomain2 [ 1 ] ) ;
235
235
// circle radius in px
236
236
var radius = _this . radius = xLength2 / dxSectorBBox ;
237
+ // 'inner' radius in px (when polar.hole is set)
238
+ var innerRadius = _this . innerRadius = polarLayout . hole * radius ;
237
239
// circle center position in px
238
240
var cx = _this . cx = xOffset2 - radius * sectorBBox [ 0 ] ;
239
241
var cy = _this . cy = yOffset2 + radius * sectorBBox [ 3 ] ;
@@ -252,7 +254,7 @@ proto.updateLayout = function(fullLayout, polarLayout) {
252
254
clockwise : 'bottom'
253
255
} [ radialLayout . side ] ,
254
256
// spans length 1 radius
255
- domain : [ 0 , radius / gs . w ]
257
+ domain : [ innerRadius / gs . w , radius / gs . w ]
256
258
} ) ;
257
259
258
260
_this . angularAxis = _this . mockAxis ( fullLayout , polarLayout , angularLayout , {
@@ -282,7 +284,7 @@ proto.updateLayout = function(fullLayout, polarLayout) {
282
284
domain : yDomain2
283
285
} ) ;
284
286
285
- var dPath = _this . pathSector ( ) ;
287
+ var dPath = _this . pathSubplot ( ) ;
286
288
287
289
_this . clipPaths . forTraces . select ( 'path' )
288
290
. attr ( 'd' , dPath )
@@ -333,9 +335,11 @@ proto.mockCartesianAxis = function(fullLayout, polarLayout, opts) {
333
335
334
336
ax . setRange = function ( ) {
335
337
var sectorBBox = _this . sectorBBox ;
336
- var rl = _this . radialAxis . _rl ;
337
- var drl = rl [ 1 ] - rl [ 0 ] ;
338
338
var ind = bboxIndices [ axId ] ;
339
+ var rl = _this . radialAxis . _rl ;
340
+ var radius = _this . radius ;
341
+ var innerRadius = _this . innerRadius ;
342
+ var drl = radius * ( rl [ 1 ] - rl [ 0 ] ) / ( radius - innerRadius ) ;
339
343
ax . range = [ sectorBBox [ ind [ 0 ] ] * drl , sectorBBox [ ind [ 1 ] ] * drl ] ;
340
344
} ;
341
345
@@ -371,6 +375,7 @@ proto.updateRadialAxis = function(fullLayout, polarLayout) {
371
375
var gd = _this . gd ;
372
376
var layers = _this . layers ;
373
377
var radius = _this . radius ;
378
+ var innerRadius = _this . innerRadius ;
374
379
var cx = _this . cx ;
375
380
var cy = _this . cy ;
376
381
var radialLayout = polarLayout . radialaxis ;
@@ -392,12 +397,12 @@ proto.updateRadialAxis = function(fullLayout, polarLayout) {
392
397
393
398
// easier to set rotate angle with custom translate function
394
399
ax . _transfn = function ( d ) {
395
- return 'translate(' + ax . l2p ( d . x ) + ',0)' ;
400
+ return 'translate(' + ( ax . l2p ( d . x ) + innerRadius ) + ',0)' ;
396
401
} ;
397
402
398
403
// set special grid path function
399
404
ax . _gridpath = function ( d ) {
400
- return _this . pathArc ( ax . r2p ( d . x ) ) ;
405
+ return _this . pathArc ( ax . r2p ( d . x ) + innerRadius ) ;
401
406
} ;
402
407
403
408
var newTickLayout = strTickLayout ( radialLayout ) ;
@@ -428,7 +433,7 @@ proto.updateRadialAxis = function(fullLayout, polarLayout) {
428
433
. selectAll ( 'path' ) . attr ( 'transform' , null ) ;
429
434
430
435
updateElement ( layers [ 'radial-line' ] . select ( 'line' ) , radialLayout . showline , {
431
- x1 : 0 ,
436
+ x1 : innerRadius ,
432
437
y1 : 0 ,
433
438
x2 : radius ,
434
439
y2 : 0 ,
@@ -479,6 +484,7 @@ proto.updateAngularAxis = function(fullLayout, polarLayout) {
479
484
var gd = _this . gd ;
480
485
var layers = _this . layers ;
481
486
var radius = _this . radius ;
487
+ var innerRadius = _this . innerRadius ;
482
488
var cx = _this . cx ;
483
489
var cy = _this . cy ;
484
490
var angularLayout = polarLayout . angularaxis ;
@@ -491,11 +497,6 @@ proto.updateAngularAxis = function(fullLayout, polarLayout) {
491
497
// 't'ick to 'g'eometric radians is used all over the place here
492
498
var t2g = function ( d ) { return ax . t2g ( d . x ) ; } ;
493
499
494
- // (x,y) at max radius
495
- function rad2xy ( rad ) {
496
- return [ radius * Math . cos ( rad ) , radius * Math . sin ( rad ) ] ;
497
- }
498
-
499
500
// run rad2deg on tick0 and ditck for thetaunit: 'radians' axes
500
501
if ( ax . type === 'linear' && ax . thetaunit === 'radians' ) {
501
502
ax . tick0 = rad2deg ( ax . tick0 ) ;
@@ -512,13 +513,17 @@ proto.updateAngularAxis = function(fullLayout, polarLayout) {
512
513
}
513
514
514
515
ax . _transfn = function ( d ) {
516
+ var sel = d3 . select ( this ) ;
517
+ var hasElement = sel && sel . node ( ) ;
518
+
519
+ // don't translate grid lines
520
+ if ( hasElement && sel . classed ( 'angularaxisgrid' ) ) return '' ;
521
+
515
522
var rad = t2g ( d ) ;
516
- var xy = rad2xy ( rad ) ;
517
- var out = strTranslate ( cx + xy [ 0 ] , cy - xy [ 1 ] ) ;
523
+ var out = strTranslate ( cx + radius * Math . cos ( rad ) , cy - radius * Math . sin ( rad ) ) ;
518
524
519
- // must also rotate ticks, but don't rotate labels and grid lines
520
- var sel = d3 . select ( this ) ;
521
- if ( sel && sel . node ( ) && sel . classed ( 'ticks' ) ) {
525
+ // must also rotate ticks, but don't rotate labels
526
+ if ( hasElement && sel . classed ( 'ticks' ) ) {
522
527
out += strRotate ( - rad2deg ( rad ) ) ;
523
528
}
524
529
@@ -527,8 +532,10 @@ proto.updateAngularAxis = function(fullLayout, polarLayout) {
527
532
528
533
ax . _gridpath = function ( d ) {
529
534
var rad = t2g ( d ) ;
530
- var xy = rad2xy ( rad ) ;
531
- return 'M0,0L' + ( - xy [ 0 ] ) + ',' + xy [ 1 ] ;
535
+ var cosRad = Math . cos ( rad ) ;
536
+ var sinRad = Math . sin ( rad ) ;
537
+ return 'M' + [ cx + innerRadius * cosRad , cy - innerRadius * sinRad ] +
538
+ 'L' + [ cx + radius * cosRad , cy - radius * sinRad ] ;
532
539
} ;
533
540
534
541
var offset4fontsize = ( angularLayout . ticks !== 'outside' ? 0.7 : 0.5 ) ;
@@ -591,7 +598,7 @@ proto.updateAngularAxis = function(fullLayout, polarLayout) {
591
598
_this . vangles = vangles ;
592
599
593
600
updateElement ( layers [ 'angular-line' ] . select ( 'path' ) , angularLayout . showline , {
594
- d : _this . pathSector ( ) ,
601
+ d : _this . pathSubplot ( ) ,
595
602
transform : strTranslate ( cx , cy )
596
603
} )
597
604
. attr ( 'stroke-width' , angularLayout . linewidth )
@@ -614,6 +621,7 @@ proto.updateMainDrag = function(fullLayout) {
614
621
var MINZOOM = constants . MINZOOM ;
615
622
var OFFEDGE = constants . OFFEDGE ;
616
623
var radius = _this . radius ;
624
+ var innerRadius = _this . innerRadius ;
617
625
var cx = _this . cx ;
618
626
var cy = _this . cy ;
619
627
var cxx = _this . cxx ;
@@ -629,7 +637,7 @@ proto.updateMainDrag = function(fullLayout) {
629
637
var mainDrag = dragBox . makeDragger ( layers , 'path' , 'maindrag' , 'crosshair' ) ;
630
638
631
639
d3 . select ( mainDrag )
632
- . attr ( 'd' , _this . pathSector ( ) )
640
+ . attr ( 'd' , _this . pathSubplot ( ) )
633
641
. attr ( 'transform' , strTranslate ( cx , cy ) ) ;
634
642
635
643
var dragOpts = {
@@ -727,7 +735,7 @@ proto.updateMainDrag = function(fullLayout) {
727
735
function zoomPrep ( ) {
728
736
r0 = null ;
729
737
r1 = null ;
730
- path0 = _this . pathSector ( ) ;
738
+ path0 = _this . pathSubplot ( ) ;
731
739
dimmed = false ;
732
740
733
741
var polarLayoutNow = gd . _fullLayout [ _this . id ] ;
@@ -742,7 +750,7 @@ proto.updateMainDrag = function(fullLayout) {
742
750
// N.B. this sets scoped 'r0' and 'r1'
743
751
// return true if 'valid' zoom distance, false otherwise
744
752
function clampAndSetR0R1 ( rr0 , rr1 ) {
745
- rr1 = Math . min ( rr1 , radius ) ;
753
+ rr1 = Math . max ( Math . min ( rr1 , radius ) , innerRadius ) ;
746
754
747
755
// starting or ending drag near center (outer edge),
748
756
// clamps radial distance at origin (at r=radius)
@@ -1193,15 +1201,13 @@ proto.isPtInside = function(d) {
1193
1201
} ;
1194
1202
1195
1203
proto . pathArc = function ( r ) {
1196
- r = r || this . radius ;
1197
1204
var sectorInRad = this . sectorInRad ;
1198
1205
var vangles = this . vangles ;
1199
1206
var fn = vangles ? helpers . pathPolygon : Lib . pathArc ;
1200
1207
return fn ( r , sectorInRad [ 0 ] , sectorInRad [ 1 ] , vangles ) ;
1201
1208
} ;
1202
1209
1203
1210
proto . pathSector = function ( r ) {
1204
- r = r || this . radius ;
1205
1211
var sectorInRad = this . sectorInRad ;
1206
1212
var vangles = this . vangles ;
1207
1213
var fn = vangles ? helpers . pathPolygon : Lib . pathSector ;
@@ -1215,6 +1221,12 @@ proto.pathAnnulus = function(r0, r1) {
1215
1221
return fn ( r0 , r1 , sectorInRad [ 0 ] , sectorInRad [ 1 ] , vangles ) ;
1216
1222
} ;
1217
1223
1224
+ proto . pathSubplot = function ( ) {
1225
+ var r0 = this . innerRadius ;
1226
+ var r1 = this . radius ;
1227
+ return r0 ? this . pathAnnulus ( r0 , r1 ) : this . pathSector ( r1 ) ;
1228
+ } ;
1229
+
1218
1230
proto . fillViewInitialKey = function ( key , val ) {
1219
1231
if ( ! ( key in this . viewInitial ) ) {
1220
1232
this . viewInitial [ key ] = val ;
0 commit comments