@ -1,5 +1,10 @@
nv . models . discreteBar = function ( ) {
//============================================================
// Public Variables with Default Settings
//------------------------------------------------------------
var margin = { top : 0 , right : 0 , bottom : 0 , left : 0 } ,
width = 960 ,
height = 500 ,
@ -12,20 +17,23 @@ nv.models.discreteBar = function() {
color = d3 . scale . category20 ( ) . range ( ) ,
showValues = false ,
valueFormat = d3 . format ( ',.2f' ) ,
xDomain , yDomain ,
x0 , y0 ;
xDomain , yDomain ;
var dispatch = d3 . dispatch ( 'chartClick' , 'elementClick' , 'elementDblClick' , 'elementMouseover' , 'elementMouseout' ) ;
//============================================================
// Private Variables
//------------------------------------------------------------
var dispatch = d3 . dispatch ( 'chartClick' , 'elementClick' , 'elementDblClick' , 'elementMouseover' , 'elementMouseout' ) ,
x0 , y0 ;
//TODO: remove all the code taht deals with multiple series
function chart ( selection ) {
selection . each ( function ( data ) {
var availableWidth = width - margin . left - margin . right ,
availableHeight = height - margin . top - margin . bottom ;
//add series index to each data point for reference
data = data . map ( function ( series , i ) {
series . values = series . values . map ( function ( point ) {
@ -37,7 +45,7 @@ nv.models.discreteBar = function() {
var seriesData = ( xDomain && yDomain ) ? [ ] : // if we know xDomain and yDomain, no need to calculate
data . map ( function ( d ) {
data . map ( function ( d ) {
return d . values . map ( function ( d , i ) {
return { x : getX ( d , i ) , y : getY ( d , i ) , y0 : d . y0 }
} )
@ -46,16 +54,17 @@ nv.models.discreteBar = function() {
x . domain ( xDomain || d3 . merge ( seriesData ) . map ( function ( d ) { return d . x } ) )
. rangeBands ( [ 0 , availableWidth ] , . 1 ) ;
y . domain ( yDomain || d3 . extent ( d3 . merge ( seriesData ) . map ( function ( d ) { return d . y } ) . concat ( forceY ) ) )
//.range([availableHeight, 0]);
y . domain ( yDomain || d3 . extent ( d3 . merge ( seriesData ) . map ( function ( d ) { return d . y } ) . concat ( forceY ) ) ) ;
// If showValues, pad the Y axis range to account for label height
if ( showValues ) y . range ( [ availableHeight - ( y . domain ( ) [ 0 ] < 0 ? 12 : 0 ) , y . domain ( ) [ 1 ] > 0 ? 12 : 0 ] ) ;
else y . range ( [ availableHeight , 0 ] ) ;
//store old scales if they exist
x0 = x0 || x ; //TODO: decide whether or not to keep
y0 = y0 || d3 . scale . linear ( ) . domain ( y . domain ( ) ) . range ( [ y ( 0 ) , y ( 0 ) ] ) ;
x0 = x0 || x ;
y0 = y0 || y . copy ( ) . range ( [ y ( 0 ) , y ( 0 ) ] ) ;
var wrap = d3 . select ( this ) . selectAll ( 'g.wrap.discretebar' ) . data ( [ data ] ) ;
var wrapEnter = wrap . enter ( ) . append ( 'g' ) . attr ( 'class' , 'wrap nvd3 discretebar' ) ;
@ -68,21 +77,19 @@ nv.models.discreteBar = function() {
//TODO: by definiteion, the discrete bar should not have multiple groups, will modify/remove later
//TODO: by definition, the discrete bar should not have multiple groups, will modify/remove later
var groups = wrap . select ( '.groups' ) . selectAll ( '.group' )
. data ( function ( d ) { return d } , function ( d ) { return d . key } ) ;
groups . enter ( ) . append ( 'g' )
. style ( 'stroke-opacity' , 1e-6 )
. style ( 'fill-opacity' , 1e-6 )
. style ( 'fill-opacity' , 1e-6 ) ;
d3 . transition ( groups . exit ( ) )
. style ( 'stroke-opacity' , 1e-6 )
. style ( 'fill-opacity' , 1e-6 )
. remove ( ) ;
groups
. attr ( 'class' , function ( d , i ) { return 'group series-' + i } )
. classed ( 'hover' , function ( d ) { return d . hover } )
. classed ( 'hover' , function ( d ) { return d . hover } ) ;
d3 . transition ( groups )
. style ( 'stroke-opacity' , 1 )
. style ( 'fill-opacity' , . 75 ) ;
@ -150,7 +157,7 @@ nv.models.discreteBar = function() {
. attr ( 'height' , 0 )
. attr ( 'width' , x . rangeBand ( ) / data . length )
. style ( 'fill' , function ( d , i ) { return d . color || color [ i % color . length ] } ) //this is a 'hack' to allow multiple colors in a single series... will need to rethink this methodology
. style ( 'stroke' , function ( d , i ) { return d . color || color [ i % color . length ] } )
. style ( 'stroke' , function ( d , i ) { return d . color || color [ i % color . length ] } ) ;
if ( showValues ) {
barsEnter . append ( 'text' )
@ -158,7 +165,7 @@ nv.models.discreteBar = function() {
bars . selectAll ( 'text' )
. attr ( 'x' , x . rangeBand ( ) / 2 )
. attr ( 'y' , function ( d , i ) { return getY ( d , i ) < 0 ? y ( getY ( d , i ) ) - y ( 0 ) + 12 : - 4 } )
. text ( function ( d , i ) { return valueFormat ( getY ( d , i ) ) } )
. text ( function ( d , i ) { return valueFormat ( getY ( d , i ) ) } ) ;
} else {
bars . selectAll ( 'text' ) . remove ( ) ;
}
@ -170,25 +177,21 @@ nv.models.discreteBar = function() {
return 'translate(' + x ( getX ( d , i ) ) + ', ' + ( getY ( d , i ) < 0 ? y0 ( 0 ) : y0 ( getY ( d , i ) ) ) + ')'
} )
. selectAll ( 'rect' )
. attr ( 'width' , x . rangeBand ( ) / data . length )
. attr ( 'width' , x . rangeBand ( ) / data . length ) ;
d3 . transition ( bars )
//.delay(function(d,i) { return i * 1200 / data[0].values.length })
. attr ( 'transform' , function ( d , i ) {
return 'translate(' + x ( getX ( d , i ) ) + ', ' + ( getY ( d , i ) < 0 ? y ( 0 ) : y ( getY ( d , i ) ) ) + ')'
} )
. selectAll ( 'rect' )
//.attr('width', x.rangeBand() / data.length)
. attr ( 'height' , function ( d , i ) {
return Math . abs ( y ( getY ( d , i ) ) - y ( 0 ) )
} ) ;
//TODO: decide if this makes sense to add into all the models for ease of updating (updating without needing the selection)
chart . update = function ( ) {
selection . transition ( ) . call ( chart ) ;
}
chart . update = function ( ) { chart ( selection ) } ;
//store old scales for use in transitions on update, to animate from old to new positions, and sizes
x0 = x . copy ( ) ;