@ -612,11 +612,6 @@ nv.models.bar = function() {
return chart ;
}
/ * * *
* multiBar will likely be used instead of this , wherever this would have been useful ,
* multiBar lets you view 1 or more bars per an x value , either grouped ( side by side )
* or stacked ( layered on top of each other ) .
* /
nv . models . historicalBar = function ( ) {
var margin = { top : 0 , right : 0 , bottom : 0 , left : 0 } ,
width = 960 ,
@ -787,19 +782,25 @@ nv.models.historicalBar = function() {
chart . width = function ( _ ) {
if ( ! arguments . length ) return width ;
if ( margin . left + margin . right + 20 > _ )
width = margin . left + margin . right + 20 ; // Min width.... while this is a good idea, I may move this somewhere else.. OR need to implement in all other logical spots
else
width = _ ;
width = _ ;
return chart ;
} ;
chart . height = function ( _ ) {
if ( ! arguments . length ) return height ;
if ( margin . top + margin . bottom + 20 > _ )
height = margin . top + margin . bottom + 20 ; // Min height
else
height = _ ;
height = _ ;
return chart ;
} ;
chart . xScale = function ( _ ) {
if ( ! arguments . length ) return x ;
x = _ ;
return chart ;
} ;
chart . yScale = function ( _ ) {
if ( ! arguments . length ) return y ;
y = _ ;
return chart ;
} ;
@ -1953,13 +1954,13 @@ nv.models.discreteBarChart = function() {
chart . width = function ( _ ) {
if ( ! arguments . length ) return width ;
width = d3. functor ( _) ;
width = _;
return chart ;
} ;
chart . height = function ( _ ) {
if ( ! arguments . length ) return height ;
height = d3. functor ( _) ;
height = _;
return chart ;
} ;
@ -2614,14 +2615,12 @@ nv.models.lineChart = function() {
chart . width = function ( _ ) {
if ( ! arguments . length ) return width ;
width = _ ;
//width = d3.functor(_);
return chart ;
} ;
chart . height = function ( _ ) {
if ( ! arguments . length ) return height ;
height = _ ;
//height = d3.functor(_);
return chart ;
} ;
@ -2904,6 +2903,318 @@ nv.models.linePlusBar = function() {
return chart ;
}
nv . models . linePlusBarChart = function ( ) {
var margin = { top : 30 , right : 60 , bottom : 50 , left : 60 } ,
width = null ,
height = null ,
dotRadius = function ( ) { return 2.5 } ,
getX = function ( d ) { return d . x } ,
getY = function ( d ) { return d . y } ,
color = d3 . scale . category20 ( ) . range ( ) ,
showLegend = true ,
tooltips = true ,
tooltip = function ( key , x , y , e , graph ) {
return '<h3>' + key + '</h3>' +
'<p>' + y + ' at ' + x + '</p>'
} ;
var lines = nv . models . line ( ) ,
bars = nv . models . historicalBar ( ) ,
x = d3 . scale . linear ( ) , // needs to be both line and historicalBar x Axis
y1 = bars . yScale ( ) ,
y2 = lines . yScale ( ) ,
xAxis = nv . models . axis ( ) . scale ( x ) . orient ( 'bottom' ) ,
yAxis1 = nv . models . axis ( ) . scale ( y1 ) . orient ( 'left' ) ,
yAxis2 = nv . models . axis ( ) . scale ( y2 ) . orient ( 'right' ) ,
legend = nv . models . legend ( ) . height ( 30 ) ,
dispatch = d3 . dispatch ( 'tooltipShow' , 'tooltipHide' ) ;
var showTooltip = function ( e , offsetElement ) {
//console.log('left: ' + offsetElement.offsetLeft);
//console.log('top: ' + offsetElement.offsetLeft);
//TODO: FIX offsetLeft and offSet top do not work if container is shifted anywhere
//var offsetElement = document.getElementById(selector.substr(1)),
var left = e . pos [ 0 ] + ( offsetElement . offsetLeft || 0 ) ,
top = e . pos [ 1 ] + ( offsetElement . offsetTop || 0 ) ,
x = xAxis . tickFormat ( ) ( lines . x ( ) ( e . point ) ) ,
y = yAxis1 . tickFormat ( ) ( lines . y ( ) ( e . point ) ) ,
content = tooltip ( e . series . key , x , y , e , chart ) ;
nv . tooltip . show ( [ left , top ] , content , e . value < 0 ? 'n' : 's' ) ;
} ;
function chart ( selection ) {
selection . each ( function ( data ) {
var container = d3 . select ( this ) ;
var availableWidth = ( width || parseInt ( container . style ( 'width' ) ) || 960 )
- margin . left - margin . right ,
availableHeight = ( height || parseInt ( container . style ( 'height' ) ) || 400 )
- margin . top - margin . bottom ;
var dataBars = data . filter ( function ( d ) { return ! d . disabled && d . bar } ) ;
var dataLines = data . filter ( function ( d ) { return ! d . disabled && ! d . bar } ) ;
//TODO: try to remove x scale computation from this layer
var series1 = data . filter ( function ( d ) { return ! d . disabled && d . bar } )
. map ( function ( d ) {
return d . values . map ( function ( d , i ) {
return { x : getX ( d , i ) , y : getY ( d , i ) }
} )
} ) ;
var series2 = data . filter ( function ( d ) { return ! d . disabled && ! d . bar } )
. map ( function ( d ) {
return d . values . map ( function ( d , i ) {
return { x : getX ( d , i ) , y : getY ( d , i ) }
} )
} ) ;
x . domain ( d3 . extent ( d3 . merge ( series1 . concat ( series2 ) ) , function ( d ) { return d . x } ) )
. range ( [ 0 , availableWidth ] ) ;
/ *
x . domain ( d3 . extent ( d3 . merge ( data . map ( function ( d ) { return d . values } ) ) , getX ) )
. range ( [ 0 , availableWidth ] ) ;
y1 . domain ( d3 . extent ( d3 . merge ( dataBars ) , function ( d ) { return d . y } ) )
. range ( [ availableHeight , 0 ] ) ;
y2 . domain ( d3 . extent ( d3 . merge ( dataLines ) , function ( d ) { return d . y } ) )
. range ( [ availableHeight , 0 ] ) ;
* /
lines
. width ( availableWidth )
. height ( availableHeight )
. color ( data . map ( function ( d , i ) {
return d . color || color [ i % 10 ] ;
} ) . filter ( function ( d , i ) { return ! data [ i ] . disabled && ! data [ i ] . bar } ) )
bars
. width ( availableWidth )
. height ( availableHeight )
. color ( data . map ( function ( d , i ) {
return d . color || color [ i % 10 ] ;
} ) . filter ( function ( d , i ) { return ! data [ i ] . disabled && data [ i ] . bar } ) )
var wrap = d3 . select ( this ) . selectAll ( 'g.wrap.linePlusBar' ) . data ( [ data ] ) ;
var gEnter = wrap . enter ( ) . append ( 'g' ) . attr ( 'class' , 'wrap nvd3 linePlusBar' ) . append ( 'g' ) ;
gEnter . append ( 'g' ) . attr ( 'class' , 'x axis' ) ;
gEnter . append ( 'g' ) . attr ( 'class' , 'y1 axis' ) ;
gEnter . append ( 'g' ) . attr ( 'class' , 'y2 axis' ) ;
gEnter . append ( 'g' ) . attr ( 'class' , 'barsWrap' ) ;
gEnter . append ( 'g' ) . attr ( 'class' , 'linesWrap' ) ;
gEnter . append ( 'g' ) . attr ( 'class' , 'legendWrap' ) ;
var g = wrap . select ( 'g' ) ;
if ( showLegend ) {
legend . width ( availableWidth ) ;
g . select ( '.legendWrap' )
. datum ( data . map ( function ( series ) {
series . key = series . key + ( series . bar ? ' (left axis)' : ' (right axis)' ) ;
return series ;
} ) )
. call ( legend ) ;
if ( margin . top != legend . height ( ) ) {
margin . top = legend . height ( ) ;
availableHeight = ( height || parseInt ( container . style ( 'height' ) ) || 400 )
- margin . top - margin . bottom ;
}
g . select ( '.legendWrap' )
. attr ( 'transform' , 'translate(0,' + ( - margin . top ) + ')' ) ;
}
var barsWrap = g . select ( '.barsWrap' )
. datum ( dataBars . length ? dataBars : [ { values : [ ] } ] )
var linesWrap = g . select ( '.linesWrap' )
. datum ( dataLines . length ? dataLines : [ { values : [ ] } ] )
d3 . transition ( barsWrap ) . call ( bars ) ;
d3 . transition ( linesWrap ) . call ( lines ) ;
g . attr ( 'transform' , 'translate(' + margin . left + ',' + margin . top + ')' ) ;
xAxis
. ticks ( availableWidth / 100 )
. tickSize ( - availableHeight , 0 ) ;
g . select ( '.x.axis' )
. attr ( 'transform' , 'translate(0,' + y1 . range ( ) [ 0 ] + ')' ) ;
d3 . transition ( g . select ( '.x.axis' ) )
. call ( xAxis ) ;
yAxis1
. ticks ( availableHeight / 36 )
. tickSize ( - availableWidth , 0 ) ;
d3 . transition ( g . select ( '.y1.axis' ) )
. call ( yAxis1 ) ;
yAxis2
. ticks ( availableHeight / 36 )
. tickSize ( dataBars . length ? 0 : - availableWidth , 0 ) ; // Show the y2 rules only if y1 has none
g . select ( '.y2.axis' )
. attr ( 'transform' , 'translate(' + x . range ( ) [ 1 ] + ',0)' ) ;
d3 . transition ( g . select ( '.y2.axis' ) )
. call ( yAxis2 ) ;
legend . dispatch . on ( 'legendClick' , function ( d , i ) {
d . disabled = ! d . disabled ;
if ( ! data . filter ( function ( d ) { return ! d . disabled } ) . length ) {
data . map ( function ( d ) {
d . disabled = false ;
wrap . selectAll ( '.series' ) . classed ( 'disabled' , false ) ;
return d ;
} ) ;
}
selection . transition ( ) . call ( chart ) ;
} ) ;
lines . dispatch . on ( 'elementMouseover.tooltip' , function ( e ) {
e . pos = [ e . pos [ 0 ] + margin . left , e . pos [ 1 ] + margin . top ] ;
dispatch . tooltipShow ( e ) ;
} ) ;
if ( tooltips ) dispatch . on ( 'tooltipShow' , function ( e ) { showTooltip ( e , container [ 0 ] [ 0 ] ) } ) ; // TODO: maybe merge with above?
lines . dispatch . on ( 'elementMouseout.tooltip' , function ( e ) {
dispatch . tooltipHide ( e ) ;
} ) ;
if ( tooltips ) dispatch . on ( 'tooltipHide' , nv . tooltip . cleanup ) ;
bars . dispatch . on ( 'elementMouseover.tooltip' , function ( e ) {
e . pos = [ e . pos [ 0 ] + margin . left , e . pos [ 1 ] + margin . top ] ;
dispatch . tooltipShow ( e ) ;
} ) ;
if ( tooltips ) dispatch . on ( 'tooltipShow' , function ( e ) { showTooltip ( e , container [ 0 ] [ 0 ] ) } ) ; // TODO: maybe merge with above?
bars . dispatch . on ( 'elementMouseout.tooltip' , function ( e ) {
dispatch . tooltipHide ( e ) ;
} ) ;
if ( tooltips ) dispatch . on ( 'tooltipHide' , nv . tooltip . cleanup ) ;
chart . update = function ( ) { selection . transition ( ) . call ( chart ) } ;
} ) ;
return chart ;
}
chart . dispatch = dispatch ;
chart . legend = legend ;
chart . lines = lines ;
chart . bars = bars ;
chart . xAxis = xAxis ;
chart . yAxis1 = yAxis1 ;
chart . yAxis2 = yAxis2 ;
d3 . rebind ( chart , lines , 'size' , 'clipVoronoi' ) ;
//d3.rebind(chart, lines, 'x', 'y', 'size', 'xDomain', 'yDomain', 'forceX', 'forceY', 'interactive', 'clipEdge', 'clipVoronoi', 'id');
//d3.rebind(chart, lines, 'interactive');
//consider rebinding x and y as well
chart . x = function ( _ ) {
if ( ! arguments . length ) return getX ;
getX = _ ;
lines . x ( _ ) ;
bars . x ( _ ) ;
return chart ;
} ;
chart . y = function ( _ ) {
if ( ! arguments . length ) return getY ;
getY = _ ;
lines . y ( _ ) ;
bars . y ( _ ) ;
return chart ;
} ;
chart . margin = function ( _ ) {
if ( ! arguments . length ) return margin ;
margin = _ ;
return chart ;
} ;
chart . width = function ( _ ) {
if ( ! arguments . length ) return width ;
width = _ ;
return chart ;
} ;
chart . height = function ( _ ) {
if ( ! arguments . length ) return height ;
height = _ ;
return chart ;
} ;
chart . color = function ( _ ) {
if ( ! arguments . length ) return color ;
color = _ ;
legend . color ( _ ) ;
return chart ;
} ;
chart . showLegend = function ( _ ) {
if ( ! arguments . length ) return showLegend ;
showLegend = _ ;
return chart ;
} ;
chart . tooltips = function ( _ ) {
if ( ! arguments . length ) return tooltips ;
tooltips = _ ;
return chart ;
} ;
chart . tooltipContent = function ( _ ) {
if ( ! arguments . length ) return tooltip ;
tooltip = _ ;
return chart ;
} ;
return chart ;
}
nv . models . lineWithFocus = function ( ) {
var margin = { top : 30 , right : 20 , bottom : 30 , left : 60 } ,
margin2 = { top : 0 , right : 20 , bottom : 20 , left : 60 } ,
@ -4001,13 +4312,13 @@ nv.models.multiBarChart = function() {
chart . width = function ( _ ) {
if ( ! arguments . length ) return width ;
width = d3. functor ( _) ;
width = _;
return chart ;
} ;
chart . height = function ( _ ) {
if ( ! arguments . length ) return height ;
height = d3. functor ( _) ;
height = _;
return chart ;
} ;
@ -6036,13 +6347,13 @@ nv.models.scatterChart = function() {
chart . width = function ( _ ) {
if ( ! arguments . length ) return width ;
width = d3. functor ( _) ;
width = _;
return chart ;
} ;
chart . height = function ( _ ) {
if ( ! arguments . length ) return height ;
height = d3. functor ( _) ;
height = _;
return chart ;
} ;