in mc/Scripts/nv.d3.js [3854:4017]
function chart(selection) {
renderWatch.reset();
selection.each(function(data) {
var availableWidth = width - margin.left - margin.right,
availableHeight = height - margin.top - margin.bottom;
container = d3.select(this);
nv.utils.initSVG(container);
//add series index to each data point for reference
data.forEach(function(series, i) {
series.values.forEach(function(point) {
point.series = i;
});
});
// Setup Scales
// remap and flatten the data for use in calculating the scales' domains
var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate
data.map(function(d) {
return d.values.map(function(d,i) {
return { x: getX(d,i), y: getY(d,i), y0: d.y0 }
})
});
x .domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))
.rangeBands(xRange || [0, availableWidth], .1);
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(yRange || [availableHeight - (y.domain()[0] < 0 ? 12 : 0), y.domain()[1] > 0 ? 12 : 0]);
else y.range(yRange || [availableHeight, 0]);
//store old scales if they exist
x0 = x0 || x;
y0 = y0 || y.copy().range([y(0),y(0)]);
// Setup containers and skeleton of chart
var wrap = container.selectAll('g.nv-wrap.nv-discretebar').data([data]);
var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-discretebar');
var gEnter = wrapEnter.append('g');
var g = wrap.select('g');
gEnter.append('g').attr('class', 'nv-groups');
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
//TODO: by definition, the discrete bar should not have multiple groups, will modify/remove later
var groups = wrap.select('.nv-groups').selectAll('.nv-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);
groups.exit()
.watchTransition(renderWatch, 'discreteBar: exit groups')
.style('stroke-opacity', 1e-6)
.style('fill-opacity', 1e-6)
.remove();
groups
.attr('class', function(d,i) { return 'nv-group nv-series-' + i })
.classed('hover', function(d) { return d.hover });
groups
.watchTransition(renderWatch, 'discreteBar: groups')
.style('stroke-opacity', 1)
.style('fill-opacity', .75);
var bars = groups.selectAll('g.nv-bar')
.data(function(d) { return d.values });
bars.exit().remove();
var barsEnter = bars.enter().append('g')
.attr('transform', function(d,i,j) {
return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05 ) + ', ' + y(0) + ')'
})
.on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here
d3.select(this).classed('hover', true);
dispatch.elementMouseover({
data: d,
index: i,
color: d3.select(this).style("fill")
});
})
.on('mouseout', function(d,i) {
d3.select(this).classed('hover', false);
dispatch.elementMouseout({
data: d,
index: i,
color: d3.select(this).style("fill")
});
})
.on('mousemove', function(d,i) {
dispatch.elementMousemove({
data: d,
index: i,
color: d3.select(this).style("fill")
});
})
.on('click', function(d,i) {
dispatch.elementClick({
data: d,
index: i,
color: d3.select(this).style("fill")
});
d3.event.stopPropagation();
})
.on('dblclick', function(d,i) {
dispatch.elementDblClick({
data: d,
index: i,
color: d3.select(this).style("fill")
});
d3.event.stopPropagation();
});
barsEnter.append('rect')
.attr('height', 0)
.attr('width', x.rangeBand() * .9 / data.length )
if (showValues) {
barsEnter.append('text')
.attr('text-anchor', 'middle')
;
bars.select('text')
.text(function(d,i) { return valueFormat(getY(d,i)) })
.watchTransition(renderWatch, 'discreteBar: bars text')
.attr('x', x.rangeBand() * .9 / 2)
.attr('y', function(d,i) { return getY(d,i) < 0 ? y(getY(d,i)) - y(0) + 12 : -4 })
;
} else {
bars.selectAll('text').remove();
}
bars
.attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive' })
.style('fill', function(d,i) { return d.color || color(d,i) })
.style('stroke', function(d,i) { return d.color || color(d,i) })
.select('rect')
.attr('class', rectClass)
.watchTransition(renderWatch, 'discreteBar: bars rect')
.attr('width', x.rangeBand() * .9 / data.length);
bars.watchTransition(renderWatch, 'discreteBar: bars')
//.delay(function(d,i) { return i * 1200 / data[0].values.length })
.attr('transform', function(d,i) {
var left = x(getX(d,i)) + x.rangeBand() * .05,
top = getY(d,i) < 0 ?
y(0) :
y(0) - y(getY(d,i)) < 1 ?
y(0) - 1 : //make 1 px positive bars show up above y=0
y(getY(d,i));
return 'translate(' + left + ', ' + top + ')'
})
.select('rect')
.attr('height', function(d,i) {
return Math.max(Math.abs(y(getY(d,i)) - y((yDomain && yDomain[0]) || 0)) || 1)
});
//store old scales for use in transitions on update
x0 = x.copy();
y0 = y.copy();
});