@ -48,9 +48,11 @@ nv.models.pie = function() {
var g = wrap . select ( 'g' ) ;
gEnter . append ( 'g' ) . attr ( 'class' , 'nv-pie' ) ;
gEnter . append ( 'g' ) . attr ( 'class' , 'nv-pieLabels' ) ;
wrap . attr ( 'transform' , 'translate(' + margin . left + ',' + margin . top + ')' ) ;
g . select ( '.nv-pie' ) . attr ( 'transform' , 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')' ) ;
g . select ( '.nv-pieLabels' ) . attr ( 'transform' , 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')' ) ;
//------------------------------------------------------------
@ -81,7 +83,11 @@ nv.models.pie = function() {
var slices = wrap . select ( '.nv-pie' ) . selectAll ( '.nv-slice' )
. data ( pie ) ;
var pieLabels = wrap . select ( '.nv-pieLabels' ) . selectAll ( '.nv-label' )
. data ( pie ) ;
slices . exit ( ) . remove ( ) ;
pieLabels . exit ( ) . remove ( ) ;
var ae = slices . enter ( ) . append ( 'g' )
. attr ( 'class' , 'nv-slice' )
@ -150,66 +156,79 @@ nv.models.pie = function() {
if ( donutLabelsOutside ) { labelsArc = d3 . svg . arc ( ) . outerRadius ( arc . outerRadius ( ) ) ; }
ae . append ( "g" ) . classed ( "nv-label" , true )
. each ( function ( d , i ) {
var group = d3 . select ( this ) ;
group
. attr ( 'transform' , function ( d ) {
if ( labelSunbeamLayout ) {
d . outerRadius = arcRadius + 10 ; // Set Outer Coordinate
d . innerRadius = arcRadius + 15 ; // Set Inner Coordinate
var rotateAngle = ( d . startAngle + d . endAngle ) / 2 * ( 180 / Math . PI ) ;
if ( ( d . startAngle + d . endAngle ) / 2 < Math . PI ) {
rotateAngle -= 90 ;
pieLabels . enter ( ) . append ( "g" ) . classed ( "nv-label" , true )
. each ( function ( d , i ) {
var group = d3 . select ( this ) ;
group
. attr ( 'transform' , function ( d ) {
if ( labelSunbeamLayout ) {
d . outerRadius = arcRadius + 10 ; // Set Outer Coordinate
d . innerRadius = arcRadius + 15 ; // Set Inner Coordinate
var rotateAngle = ( d . startAngle + d . endAngle ) / 2 * ( 180 / Math . PI ) ;
if ( ( d . startAngle + d . endAngle ) / 2 < Math . PI ) {
rotateAngle -= 90 ;
} else {
rotateAngle += 90 ;
}
return 'translate(' + labelsArc . centroid ( d ) + ') rotate(' + rotateAngle + ')' ;
} else {
rotateAngle += 90 ;
d . outerRadius = radius + 10 ; // Set Outer Coordinate
d . innerRadius = radius + 15 ; // Set Inner Coordinate
return 'translate(' + labelsArc . centroid ( d ) + ')'
}
return 'translate(' + labelsArc . centroid ( d ) + ') rotate(' + rotateAngle + ')' ;
} else {
d . outerRadius = radius + 10 ; // Set Outer Coordinate
d . innerRadius = radius + 15 ; // Set Inner Coordinate
return 'translate(' + labelsArc . centroid ( d ) + ')'
}
} ) ;
group . append ( 'rect' )
. style ( 'stroke' , '#fff' )
. style ( 'fill' , '#fff' )
. attr ( "rx" , 3 )
. attr ( "ry" , 3 ) ;
group . append ( 'text' )
. style ( 'text-anchor' , labelSunbeamLayout ? ( ( d . startAngle + d . endAngle ) / 2 < Math . PI ? 'start' : 'end' ) : 'middle' ) //center the text on it's origin or begin/end if orthogonal aligned
. style ( 'fill' , '#000' )
} ) ;
group . append ( 'rect' )
. style ( 'stroke' , '#fff' )
. style ( 'fill' , '#fff' )
. attr ( "rx" , 3 )
. attr ( "ry" , 3 ) ;
} ) ;
group . append ( 'text' )
. style ( 'text-anchor' , labelSunbeamLayout ? ( ( d . startAngle + d . endAngle ) / 2 < Math . PI ? 'start' : 'end' ) : 'middle' ) //center the text on it's origin or begin/end if orthogonal aligned
. style ( 'fill' , '#000' )
slices . select ( ".nv-label" ) . transition ( )
. attr ( 'transform' , function ( d ) {
if ( labelSunbeamLayout ) {
d . outerRadius = arcRadius + 10 ; // Set Outer Coordinate
d . innerRadius = arcRadius + 15 ; // Set Inner Coordinate
var rotateAngle = ( d . startAngle + d . endAngle ) / 2 * ( 180 / Math . PI ) ;
if ( ( d . startAngle + d . endAngle ) / 2 < Math . PI ) {
rotateAngle -= 90 ;
} else {
rotateAngle += 90 ;
}
return 'translate(' + labelsArc . centroid ( d ) + ') rotate(' + rotateAngle + ')' ;
} else {
d . outerRadius = radius + 10 ; // Set Outer Coordinate
d . innerRadius = radius + 15 ; // Set Inner Coordinate
return 'translate(' + labelsArc . centroid ( d ) + ')'
}
} ) ;
slices . each ( function ( d , i ) {
var slice = d3 . select ( this ) ;
var labelLocationHash = { } ;
var avgHeight = 14 ;
var avgWidth = 140 ;
var createHashKey = function ( coordinates ) {
slice
. select ( ".nv-label text" )
return Math . floor ( coordinates [ 0 ] / avgWidth ) * avgWidth + ',' + Math . floor ( coordinates [ 1 ] / avgHeight ) * avgHeight ;
} ;
pieLabels . transition ( )
. attr ( 'transform' , function ( d ) {
if ( labelSunbeamLayout ) {
d . outerRadius = arcRadius + 10 ; // Set Outer Coordinate
d . innerRadius = arcRadius + 15 ; // Set Inner Coordinate
var rotateAngle = ( d . startAngle + d . endAngle ) / 2 * ( 180 / Math . PI ) ;
if ( ( d . startAngle + d . endAngle ) / 2 < Math . PI ) {
rotateAngle -= 90 ;
} else {
rotateAngle += 90 ;
}
return 'translate(' + labelsArc . centroid ( d ) + ') rotate(' + rotateAngle + ')' ;
} else {
d . outerRadius = radius + 10 ; // Set Outer Coordinate
d . innerRadius = radius + 15 ; // Set Inner Coordinate
/ *
Overlapping pie labels are not good . What this attempts to do is , prevent overlapping .
Each label location is hashed , and if a hash collision occurs , we assume an overlap .
Adjust the label ' s y - position to remove the overlap .
* /
var center = labelsArc . centroid ( d ) ;
var hashKey = createHashKey ( center ) ;
if ( labelLocationHash [ hashKey ] ) {
center [ 1 ] -= avgHeight ;
}
labelLocationHash [ createHashKey ( center ) ] = true ;
return 'translate(' + center + ')'
}
} ) ;
pieLabels . select ( ".nv-label text" )
. style ( 'text-anchor' , labelSunbeamLayout ? ( ( d . startAngle + d . endAngle ) / 2 < Math . PI ? 'start' : 'end' ) : 'middle' ) //center the text on it's origin or begin/end if orthogonal aligned
. text ( function ( d , i ) {
var percent = ( d . endAngle - d . startAngle ) / ( 2 * Math . PI ) ;
@ -220,15 +239,6 @@ nv.models.pie = function() {
} ;
return ( d . value && percent > labelThreshold ) ? labelTypes [ labelType ] : '' ;
} ) ;
var textBox = slice . select ( 'text' ) . node ( ) . getBBox ( ) ;
slice . select ( ".nv-label rect" )
. attr ( "width" , textBox . width + 10 )
. attr ( "height" , textBox . height + 10 )
. attr ( "transform" , function ( ) {
return "translate(" + [ textBox . x - 5 , textBox . y - 5 ] + ")" ;
} ) ;
} ) ;
}