Conflicts:
	examples/historicalBarChart.html
	nv.d3.js
	nv.d3.min.js
	src/models/historicalBarChart.js
	src/nv.d3.css
master-patched
Robin Hu 11 years ago
commit c57626ad9b

3
.gitignore vendored

@ -22,3 +22,6 @@ _site
ehthumbs.db
Icon?
Thumbs.db
# nodejs packages #
######################
node_modules

@ -0,0 +1,3 @@
{
"asi": true
}

@ -0,0 +1,87 @@
module.exports = function(grunt) {
//Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ''
},
dist: {
src: [
'src/intro.js',
'src/core.js',
'src/tooltip.js',
'src/utils.js',
'src/models/axis.js',
'src/models/historicalBar.js',
'src/models/bullet.js',
'src/models/bulletChart.js',
'src/models/cumulativeLineChart.js',
'src/models/discreteBar.js',
'src/models/discreteBarChart.js',
'src/models/distribution.js',
'src/models/indentedTree.js',
'src/models/legend.js',
'src/models/line.js',
'src/models/lineChart.js',
'src/models/linePlusBarChart.js',
'src/models/lineWithFocusChart.js',
'src/models/linePlusBarWithFocusChart.js',
'src/models/multiBar.js',
'src/models/multiBarChart.js',
'src/models/multiBarHorizontal.js',
'src/models/multiBarHorizontalChart.js',
'src/models/multiChart.js',
'src/models/ohlcBar.js',
'src/models/pie.js',
'src/models/pieChart.js',
'src/models/scatter.js',
'src/models/scatterChart.js',
'src/models/scatterPlusLineChart.js',
'src/models/sparkline.js',
'src/models/sparklinePlus.js',
'src/models/stackedArea.js',
'src/models/stackedAreaChart.js',
'src/outro.js'
],
dest: 'nv.d3.js'
}
},
uglify: {
options: {
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */'
},
js: {
files: {
'nv.d3.min.js': ['nv.d3.js']
}
}
},
jshint: {
foo: {
src: "src/**/*.js"
},
options: {
jshintrc: '.jshintrc'
}
},
watch: {
js: {
files: ["src/**/*.js"],
tasks: ['concat']
}
},
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['concat']);
grunt.registerTask('production', ['concat', 'uglify']);
grunt.registerTask('lint', ['jshint']);
};

@ -3,7 +3,7 @@ apology, and commitment to its permanent status as an open-source
project.
[http://nvd3.org/statement.html](http://nvd3.org/statement.html)
# nvd3 - v0.9
# nvd3 - v1.0.0-beta
A reusable chart library for d3.JS.
@ -13,30 +13,29 @@ You can also check out the [examples page](http://nvd3.org/ghpages/examples.html
---
# Current Improvement focus
# Current development focus
Upgrade to d3.v3 in progress!
-Error bars in bar charts
-Unifying common API functions between charts
-Bug fixes all around
---
# Installation Instructions
d3.v2.js is a dependency of nv.d3.js. Be sure to include in in your project, then:
d3.v3.js is a dependency of nv.d3.js. Be sure to include in in your project, then:
Add a script tag to include nv.d3.js OR nv.d3.min.js in your project.
Also add a link to the nv.d3.css file.
Python & Django-wrapped versions available:
https://github.com/areski/python-nvd3
https://github.com/areski/django-nvd3
R package version available:
http://ramnathv.github.io/rCharts/r2js/
See wiki -> Documentation for more detail
---
If one of [the existing models](https://github.com/novus/nvd3/tree/master/src/models) doesn't meet your needs, fork the project, implement the model and an example using it, send us a pull request, for consideration for inclusion in the project.
Please do not aggregate pull requests. Aggregated pull requests are actually more difficult to review!
We cannot honor all pull requests, but we will review all of them.
Please do not aggregate pull requests. Aggregated pull requests are actually more difficult to review.
We are currently changing our branch structure so that master will be gauranteed stable. In addition, there is now a "development" branch. This branch reflects the latest changes to nvd3 and is not necessarily stable.
@ -56,6 +55,19 @@ fork's root directory will rebuild both `nv.d3.js` and `nv.d3.min.js`.
Without UglifyJS, you won't get the minified version when running make.
## use grunt
You can use grunt insteadof makefile to build js file. See more about [grunt](http://gruntjs.com/).
***[Nodejs](http://nodejs.org/) must be installed before you can use grunt.***
Run `npm install` in root dir to install grunt and it's dependencies.
Then, you can use these commands:
grunt # build nv.d3.js
grunt production # build nv.d3.js and nv.d3.min.js
grunt watch # watch file changes in src/, and rebuild nv.d3.js, it's very helpful when delevop nvd3
grunt lint # run jshint on src/**/*.js
**We ask that you DO NOT minify pull requests...
If you need to minify please build pull request in separate branch, and
merge and minify in your master.

@ -54,7 +54,7 @@ nv.models.scatterChart = function() {
that = this;
//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() { container.transition().call(chart) };
var availableWidth = (width || parseInt(container.style('width')) || 960)
@ -169,8 +169,8 @@ nv.models.scatterChart = function() {
return d;
});
}
selection.transition().call(chart)
chart.update();
});
/*

@ -14,7 +14,7 @@ body {
<div class="gallery" id="chart"></div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/bullet.js"></script>
<script>

@ -14,7 +14,7 @@ body {
<div class="gallery" id="chart"></div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/bullet.js"></script>
<script src="../src/models/bulletChart.js"></script>

@ -36,7 +36,7 @@ svg {
<svg style="height: 500px;"></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../lib/crossfilter.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>

@ -36,7 +36,7 @@ svg {
<svg style="height: 500px;"></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../lib/crossfilter.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>

@ -45,7 +45,7 @@ svg {
<div><h1>Stream #3</h1></div>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../lib/crossfilter.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>

@ -36,7 +36,7 @@ svg {
<svg style="height: 500px;"></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
<script src="../src/utils.js"></script>

@ -36,7 +36,7 @@ svg {
<svg></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<!-- including all the components so I don't have to minify every time I test in development -->
<script src="../src/tooltip.js"></script>

@ -16,7 +16,7 @@ text {
<svg id="test1"></svg>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/historicalBar.js"></script>
<script src="../src/utils.js"></script>

@ -40,6 +40,8 @@ nv.addGraph({
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(d3.format(',.2f'));
chart.showXAxis(true).showYAxis(true);
d3.select("#test1")
.attr('width', width)

@ -13,7 +13,7 @@ body {
<div id="example1" style="width:600px"></div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/indentedTree.js"></script>
<script>

@ -8,7 +8,7 @@
<svg id="test1"></svg>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/legend.js"></script>
<script>

@ -12,7 +12,7 @@ body {
<svg id="test1"></svg>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/legend.js"></script>
<script src="../src/models/line.js"></script>

@ -36,7 +36,7 @@ svg {
<svg style="height: 500px;"></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
<script src="../src/utils.js"></script>
@ -67,6 +67,8 @@ nv.addGraph(function() {
.axisLabel('Voltage (v)')
.tickFormat(d3.format(',.2f'));
chart.showXAxis(true);
d3.select('#chart1 svg')
//.datum([]) //for testing noData
.datum(sinAndCos())

@ -27,7 +27,7 @@ svg {
<svg></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
<script src="../src/utils.js"></script>

@ -32,7 +32,7 @@ text {
<svg> </svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/utils.js"></script>
<script src="../src/tooltip.js"></script>
@ -89,7 +89,8 @@ nv.addGraph(function() {
chart.xAxis.tickFormat(function(d) {
var dx = testdata[0].values[d] && testdata[0].values[d].x || 0;
return dx ? d3.time.format('%x')(new Date(dx)) : '';
});
})
.showMaxMin(false);
chart.y1Axis
.tickFormat(d3.format(',f'));
@ -97,7 +98,7 @@ nv.addGraph(function() {
chart.y2Axis
.tickFormat(function(d) { return '$' + d3.format(',.2f')(d) });
chart.bars.forceY([0]);
chart.bars.forceY([0]).padData(false);
//chart.lines.forceY([0]);
d3.select('#chart1 svg')

@ -32,7 +32,7 @@ text {
<svg> </svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/utils.js"></script>
<script src="../src/tooltip.js"></script>

@ -36,7 +36,7 @@ svg {
<svg style="height: 500px;"></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../lib/fisheye.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>

@ -36,7 +36,7 @@ svg {
<svg style="height: 500px;"></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
<script src="../src/utils.js"></script>

@ -21,7 +21,7 @@ text {
<svg></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
<script src="../src/models/legend.js"></script>

@ -32,7 +32,7 @@ text {
<svg></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
<script src="../src/utils.js"></script>

@ -35,7 +35,7 @@ text {
<svg></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/utils.js"></script>
<script src="../src/tooltip.js"></script>

@ -1,4 +1,5 @@
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<link href="../src/nv.d3.css" rel="stylesheet" type="text/css">
@ -32,7 +33,7 @@ text {
<svg> </svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
<script src="../src/models/legend.js"></script>
@ -91,3 +92,4 @@ nv.addGraph(function() {
});
</script>
</html>

@ -1,11 +1,8 @@
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<link href="../src/nv.d3.css" rel="stylesheet" type="text/css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="../lib/d3.v2.js"></script>
<script src="../nv.d3.js"></script>
<script type="text/javascript" src="../src/utils.js"></script>
<style>
body {
@ -32,7 +29,9 @@ svg {
<svg></svg>
</div>
<script type="text/javascript" src="../lib/d3.v3.js"></script>
<script type="text/javascript" src="../nv.d3.js"></script>
<script type="text/javascript" src="../src/utils.js"></script>
<script type="text/javascript" src="../src/models/parallelCoordinates.js"></script>
<script>
@ -46,9 +45,9 @@ svg {
.datum(data)
.call(chart);
chart.dispatch.on('brush', function(e) {
nv.log(e);
});
// chart.dispatch.on('brush', function(e) {
// nv.log(e);
// });
nv.utils.windowResize(chart.update);

@ -18,7 +18,7 @@ text {
<svg id="test2"></svg>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/pie.js"></script>
<script>

@ -24,7 +24,7 @@ text {
<h2>Test2</h2>
<svg id="test2" class="mypiechart"></svg>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/legend.js"></script>
<script src="../src/models/pie.js"></script>

@ -12,7 +12,7 @@ body {
<svg id="test1"></svg>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../lib/fisheye.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/legend.js"></script>

@ -46,7 +46,7 @@ div {
</div>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<!--<script src="../lib/fisheye.js"></script>-->
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
@ -80,7 +80,7 @@ nv.addGraph(function() {
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
chart.dispatch.on('stateChange', function(e) { ('New State:', JSON.stringify(e)); });
return chart;
});

@ -46,7 +46,7 @@ div {
</div>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../lib/fisheye.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
@ -73,7 +73,7 @@ nv.addGraph(function() {
chart.yAxis.tickFormat(d3.format('.02f'))
d3.select('#test1 svg')
.datum(randomData(4,40))
.datum(nv.log(randomData(4,40)))
.transition().duration(500)
.call(chart);

@ -22,7 +22,7 @@ text {
<h2>Sparkline: <svg id="chart1" class="sparkline"></svg></h2>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/models/sparkline.js"></script>
<script src="../src/utils.js"></script>

@ -20,7 +20,7 @@ h2, p {
<h2>SparklinePlus:</h2>
<p><svg id="chart1" class="sparkline"></svg></p>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/utils.js"></script>
<script src="../src/models/sparkline.js"></script>

@ -20,7 +20,7 @@ text {
<svg></svg>
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/tooltip.js"></script>
<script src="../src/models/stackedArea.js"></script>

@ -28,7 +28,7 @@ text {
<!--<svg id="chart2"></svg>-->
</div>
<script src="../lib/d3.v2.js"></script>
<script src="../lib/d3.v3.js"></script>
<script src="../nv.d3.js"></script>
<script src="../src/utils.js"></script>
<script src="../src/models/axis.js"></script>

1035
nv.d3.js

File diff suppressed because it is too large Load Diff

12
nv.d3.min.js vendored

File diff suppressed because one or more lines are too long

@ -0,0 +1,11 @@
{
"name": "nvd3",
"version": "0.0.1",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.3.0",
"grunt-contrib-watch": "~0.3.1",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-concat": "~0.2.0"
}
}

@ -295,8 +295,8 @@ nv.models.axis = function() {
//highlight zero line ... Maybe should not be an option and should just be in CSS?
if (highlightZero)
g.selectAll('line.tick')
.filter(function(d) { return !parseFloat(Math.round(d*100000)/1000000) }) //this is because sometimes the 0 tick is a very small fraction, TODO: think of cleaner technique
g.selectAll('.tick')
.filter(function(d) { return !parseFloat(Math.round(d.__data__*100000)/1000000) && (d.__data__ !== undefined) }) //this is because sometimes the 0 tick is a very small fraction, TODO: think of cleaner technique
.classed('zero', true);
//store old scales for use in transitions on update

@ -104,7 +104,7 @@ nv.models.cumulativeLineChart = function() {
- margin.top - margin.bottom;
chart.update = function() { chart(selection) };
chart.update = function() { container.transition().call(chart) };
chart.container = this;
//set state.disabled
@ -405,7 +405,7 @@ nv.models.cumulativeLineChart = function() {
indexLine
.data([index]);
chart.update();
container.call(chart);
}
g.select('.nv-background rect')
@ -439,7 +439,7 @@ nv.models.cumulativeLineChart = function() {
dispatch.stateChange(state);
//selection.transition().call(chart);
selection.call(chart);
chart.update();
});
@ -458,9 +458,22 @@ nv.models.cumulativeLineChart = function() {
dispatch.stateChange(state);
//selection.transition().call(chart);
selection.call(chart);
chart.update();
});
legend.dispatch.on('legendDblclick', function(d) {
//Double clicking should always enable current series, and disabled all others.
data.forEach(function(d) {
d.disabled = true;
});
d.disabled = false;
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart.update();
});
/*
//
legend.dispatch.on('legendMouseover', function(d, i) {
@ -506,7 +519,7 @@ nv.models.cumulativeLineChart = function() {
rescaleY = e.rescaleY;
}
selection.call(chart);
chart.update();
});
//============================================================

@ -68,7 +68,7 @@ nv.models.discreteBarChart = function() {
- margin.top - margin.bottom;
chart.update = function() { dispatch.beforeUpdate(); selection.transition().call(chart); };
chart.update = function() { dispatch.beforeUpdate(); container.transition().call(chart); };
chart.container = this;

@ -11,12 +11,15 @@ nv.models.historicalBarChart = function() {
, legend = nv.models.legend()
;
//set margin.right to 23 to fit dates on the x-axis within the chart
var margin = {top: 30, right: 20, bottom: 50, left: 60}
var margin = {top: 30, right: 90, bottom: 50, left: 90}
, color = nv.utils.defaultColor()
, width = null
, height = null
, showLegend = false
, showXAxis = true
, showYAxis = true
, rightAlignYAxis = false
, tooltips = true
, tooltip = function(key, x, y, e, graph) {
return '<h3>' + key + '</h3>' +
@ -35,7 +38,7 @@ nv.models.historicalBarChart = function() {
.tickPadding(7)
;
yAxis
.orient('left')
.orient( (rightAlignYAxis) ? 'right' : 'left')
;
//============================================================
@ -171,6 +174,11 @@ nv.models.historicalBarChart = function() {
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
if (rightAlignYAxis) {
g.select(".nv-y.nv-axis")
.attr("transform", "translate(" + availableWidth + ",0)");
}
//------------------------------------------------------------
// Main Chart Component(s)
@ -194,25 +202,28 @@ nv.models.historicalBarChart = function() {
//------------------------------------------------------------
// Setup Axes
xAxis
.scale(x)
.ticks( availableWidth / 100 )
.tickSize(-availableHeight, 0);
g.select('.nv-x.nv-axis')
.attr('transform', 'translate(0,' + y.range()[0] + ')');
d3.transition(g.select('.nv-x.nv-axis'))
.call(xAxis);
if (showXAxis) {
xAxis
.scale(x)
.tickSize(-availableHeight, 0);
yAxis
.scale(y)
.ticks( availableHeight / 36 )
.tickSize( -availableWidth, 0);
g.select('.nv-x.nv-axis')
.attr('transform', 'translate(0,' + y.range()[0] + ')');
g.select('.nv-x.nv-axis')
.transition()
.call(xAxis);
}
d3.transition(g.select('.nv-y.nv-axis'))
.call(yAxis);
if (showYAxis) {
yAxis
.scale(y)
.ticks( availableHeight / 36 )
.tickSize( -availableWidth, 0);
g.select('.nv-y.nv-axis')
.transition().duration(0)
.call(yAxis);
}
//------------------------------------------------------------
@ -237,6 +248,18 @@ nv.models.historicalBarChart = function() {
selection.transition().call(chart);
});
legend.dispatch.on('legendDblclick', function(d) {
//Double clicking should always enable current series, and disabled all others.
data.forEach(function(d) {
d.disabled = true;
});
d.disabled = false;
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart.update();
});
/*
legend.dispatch.on('legendMouseover', function(d, i) {
d.hover = true;
@ -342,6 +365,25 @@ nv.models.historicalBarChart = function() {
return chart;
};
chart.showXAxis = function(_) {
if (!arguments.length) return showXAxis;
showXAxis = _;
return chart;
};
chart.showYAxis = function(_) {
if (!arguments.length) return showYAxis;
showYAxis = _;
return chart;
};
chart.rightAlignYAxis = function(_) {
if(!arguments.length) return rightAlignYAxis;
rightAlignYAxis = _;
yAxis.orient( (_) ? 'right' : 'left');
return chart;
};
chart.tooltips = function(_) {
if (!arguments.length) return tooltips;
tooltips = _;

@ -1,317 +1,317 @@
nv.models.indentedTree = function() {
//============================================================
// Public Variables with Default Settings
//------------------------------------------------------------
var margin = {top: 0, right: 0, bottom: 0, left: 0} //TODO: implement, maybe as margin on the containing div
, width = 960
, height = 500
, color = nv.utils.defaultColor()
, id = Math.floor(Math.random() * 10000)
, header = true
, filterZero = false
, noData = "No Data Available."
, childIndent = 20
, columns = [{key:'key', label: 'Name', type:'text'}] //TODO: consider functions like chart.addColumn, chart.removeColumn, instead of a block like this
, tableClass = null
, iconOpen = 'images/grey-plus.png' //TODO: consider removing this and replacing with a '+' or '-' unless user defines images
, iconClose = 'images/grey-minus.png'
, dispatch = d3.dispatch('elementClick', 'elementDblclick', 'elementMouseover', 'elementMouseout')
;
//============================================================
var idx = 0;
function chart(selection) {
selection.each(function(data) {
var depth = 1,
container = d3.select(this);
var tree = d3.layout.tree()
.children(function(d) { return d.values })
.size([height, childIndent]); //Not sure if this is needed now that the result is HTML
chart.update = function() { container.transition().duration(600).call(chart) };
//------------------------------------------------------------
// Display No Data message if there's nothing to show.
if (!data[0]) data[0] = {key: noData};
//------------------------------------------------------------
var nodes = tree.nodes(data[0]);
// nodes.map(function(d) {
// d.id = i++;
// })
//------------------------------------------------------------
// Setup containers and skeleton of chart
var wrap = d3.select(this).selectAll('div').data([[nodes]]);
var wrapEnter = wrap.enter().append('div').attr('class', 'nvd3 nv-wrap nv-indentedtree');
var tableEnter = wrapEnter.append('table');
var table = wrap.select('table').attr('width', '100%').attr('class', tableClass);
//------------------------------------------------------------
if (header) {
var thead = tableEnter.append('thead');
var theadRow1 = thead.append('tr');
columns.forEach(function(column) {
theadRow1
.append('th')
.attr('width', column.width ? column.width : '10%')
.style('text-align', column.type == 'numeric' ? 'right' : 'left')
.append('span')
.text(column.label);
});
}
var tbody = table.selectAll('tbody')
.data(function(d) { return d });
tbody.enter().append('tbody');
//compute max generations
depth = d3.max(nodes, function(node) { return node.depth });
tree.size([height, depth * childIndent]); //TODO: see if this is necessary at all
// Update the nodes…
var node = tbody.selectAll('tr')
// .data(function(d) { return d; }, function(d) { return d.id || (d.id == ++i)});
.data(function(d) { return d.filter(function(d) { return (filterZero && !d.children) ? filterZero(d) : true; } )}, function(d,i) { return d.id || (d.id || ++idx)});
//.style('display', 'table-row'); //TODO: see if this does anything
node.exit().remove();
node.select('img.nv-treeicon')
.attr('src', icon)
.classed('folded', folded);
var nodeEnter = node.enter().append('tr');
columns.forEach(function(column, index) {
var nodeName = nodeEnter.append('td')
.style('padding-left', function(d) { return (index ? 0 : d.depth * childIndent + 12 + (icon(d) ? 0 : 16)) + 'px' }, 'important') //TODO: check why I did the ternary here
.style('text-align', column.type == 'numeric' ? 'right' : 'left');
if (index == 0) {
nodeName.append('img')
.classed('nv-treeicon', true)
.classed('nv-folded', folded)
.attr('src', icon)
.style('width', '14px')
.style('height', '14px')
.style('padding', '0 1px')
.style('display', function(d) { return icon(d) ? 'inline-block' : 'none'; })
.on('click', click);
}
nodeName.append('span')
.attr('class', d3.functor(column.classes) )
.text(function(d) { return column.format ? column.format(d) :
(d[column.key] || '-') });
if (column.showCount) {
nodeName.append('span')
.attr('class', 'nv-childrenCount');
node.selectAll('span.nv-childrenCount').text(function(d) {
return ((d.values && d.values.length) || (d._values && d._values.length)) ? //If this is a parent
'(' + ((d.values && (d.values.filter(function(d) { return filterZero ? filterZero(d) : true; }).length)) //If children are in values check its children and filter
|| (d._values && d._values.filter(function(d) { return filterZero ? filterZero(d) : true; }).length) //Otherwise, do the same, but with the other name, _values...
|| 0) + ')' //This is the catch-all in case there are no children after a filter
: '' //If this is not a parent, just give an empty string
});
}
if (column.click)
nodeName.select('span').on('click', column.click);
});
node
.order()
.on('click', function(d) {
dispatch.elementClick({
row: this, //TODO: decide whether or not this should be consistent with scatter/line events or should be an html link (a href)
data: d,
pos: [d.x, d.y]
});
})
.on('dblclick', function(d) {
dispatch.elementDblclick({
row: this,
data: d,
pos: [d.x, d.y]
});
})
.on('mouseover', function(d) {
dispatch.elementMouseover({
row: this,
data: d,
pos: [d.x, d.y]
});
})
.on('mouseout', function(d) {
dispatch.elementMouseout({
row: this,
data: d,
pos: [d.x, d.y]
});
});
// Toggle children on click.
function click(d, _, unshift) {
d3.event.stopPropagation();
if(d3.event.shiftKey && !unshift) {
//If you shift-click, it'll toggle fold all the children, instead of itself
d3.event.shiftKey = false;
d.values && d.values.forEach(function(node){
if (node.values || node._values) {
click(node, 0, true);
}
});
return true;
}
if(!hasChildren(d)) {
//download file
//window.location.href = d.url;
return true;
}
if (d.values) {
d._values = d.values;
d.values = null;
} else {
d.values = d._values;
d._values = null;
}
chart.update();
}
function icon(d) {
return (d._values && d._values.length) ? iconOpen : (d.values && d.values.length) ? iconClose : '';
}
function folded(d) {
return (d._values && d._values.length);
}
function hasChildren(d) {
var values = d.values || d._values;
return (values && values.length);
}
});
return chart;
}
//============================================================
// Expose Public Variables
//------------------------------------------------------------
chart.margin = function(_) {
if (!arguments.length) return margin;
margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
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 = nv.utils.getColor(_);
scatter.color(color);
return chart;
};
chart.id = function(_) {
if (!arguments.length) return id;
id = _;
return chart;
};
chart.header = function(_) {
if (!arguments.length) return header;
header = _;
return chart;
};
chart.noData = function(_) {
if (!arguments.length) return noData;
noData = _;
return chart;
};
chart.filterZero = function(_) {
if (!arguments.length) return filterZero;
filterZero = _;
return chart;
};
chart.columns = function(_) {
if (!arguments.length) return columns;
columns = _;
return chart;
};
chart.tableClass = function(_) {
if (!arguments.length) return tableClass;
tableClass = _;
return chart;
};
chart.iconOpen = function(_){
if (!arguments.length) return iconOpen;
iconOpen = _;
return chart;
}
chart.iconClose = function(_){
if (!arguments.length) return iconClose;
iconClose = _;
return chart;
}
//============================================================
return chart;
nv.models.indentedTree = function() {
//============================================================
// Public Variables with Default Settings
//------------------------------------------------------------
var margin = {top: 0, right: 0, bottom: 0, left: 0} //TODO: implement, maybe as margin on the containing div
, width = 960
, height = 500
, color = nv.utils.defaultColor()
, id = Math.floor(Math.random() * 10000)
, header = true
, filterZero = false
, noData = "No Data Available."
, childIndent = 20
, columns = [{key:'key', label: 'Name', type:'text'}] //TODO: consider functions like chart.addColumn, chart.removeColumn, instead of a block like this
, tableClass = null
, iconOpen = 'images/grey-plus.png' //TODO: consider removing this and replacing with a '+' or '-' unless user defines images
, iconClose = 'images/grey-minus.png'
, dispatch = d3.dispatch('elementClick', 'elementDblclick', 'elementMouseover', 'elementMouseout')
;
//============================================================
var idx = 0;
function chart(selection) {
selection.each(function(data) {
var depth = 1,
container = d3.select(this);
var tree = d3.layout.tree()
.children(function(d) { return d.values })
.size([height, childIndent]); //Not sure if this is needed now that the result is HTML
chart.update = function() { container.transition().duration(600).call(chart) };
//------------------------------------------------------------
// Display No Data message if there's nothing to show.
if (!data[0]) data[0] = {key: noData};
//------------------------------------------------------------
var nodes = tree.nodes(data[0]);
// nodes.map(function(d) {
// d.id = i++;
// })
//------------------------------------------------------------
// Setup containers and skeleton of chart
var wrap = d3.select(this).selectAll('div').data([[nodes]]);
var wrapEnter = wrap.enter().append('div').attr('class', 'nvd3 nv-wrap nv-indentedtree');
var tableEnter = wrapEnter.append('table');
var table = wrap.select('table').attr('width', '100%').attr('class', tableClass);
//------------------------------------------------------------
if (header) {
var thead = tableEnter.append('thead');
var theadRow1 = thead.append('tr');
columns.forEach(function(column) {
theadRow1
.append('th')
.attr('width', column.width ? column.width : '10%')
.style('text-align', column.type == 'numeric' ? 'right' : 'left')
.append('span')
.text(column.label);
});
}
var tbody = table.selectAll('tbody')
.data(function(d) { return d });
tbody.enter().append('tbody');
//compute max generations
depth = d3.max(nodes, function(node) { return node.depth });
tree.size([height, depth * childIndent]); //TODO: see if this is necessary at all
// Update the nodes…
var node = tbody.selectAll('tr')
// .data(function(d) { return d; }, function(d) { return d.id || (d.id == ++i)});
.data(function(d) { return d.filter(function(d) { return (filterZero && !d.children) ? filterZero(d) : true; } )}, function(d,i) { return d.id || (d.id || ++idx)});
//.style('display', 'table-row'); //TODO: see if this does anything
node.exit().remove();
node.select('img.nv-treeicon')
.attr('src', icon)
.classed('folded', folded);
var nodeEnter = node.enter().append('tr');
columns.forEach(function(column, index) {
var nodeName = nodeEnter.append('td')
.style('padding-left', function(d) { return (index ? 0 : d.depth * childIndent + 12 + (icon(d) ? 0 : 16)) + 'px' }, 'important') //TODO: check why I did the ternary here
.style('text-align', column.type == 'numeric' ? 'right' : 'left');
if (index == 0) {
nodeName.append('img')
.classed('nv-treeicon', true)
.classed('nv-folded', folded)
.attr('src', icon)
.style('width', '14px')
.style('height', '14px')
.style('padding', '0 1px')
.style('display', function(d) { return icon(d) ? 'inline-block' : 'none'; })
.on('click', click);
}
nodeName.append('span')
.attr('class', d3.functor(column.classes) )
.text(function(d) { return column.format ? column.format(d) :
(d[column.key] || '-') });
if (column.showCount) {
nodeName.append('span')
.attr('class', 'nv-childrenCount');
node.selectAll('span.nv-childrenCount').text(function(d) {
return ((d.values && d.values.length) || (d._values && d._values.length)) ? //If this is a parent
'(' + ((d.values && (d.values.filter(function(d) { return filterZero ? filterZero(d) : true; }).length)) //If children are in values check its children and filter
|| (d._values && d._values.filter(function(d) { return filterZero ? filterZero(d) : true; }).length) //Otherwise, do the same, but with the other name, _values...
|| 0) + ')' //This is the catch-all in case there are no children after a filter
: '' //If this is not a parent, just give an empty string
});
}
if (column.click)
nodeName.select('span').on('click', column.click);
});
node
.order()
.on('click', function(d) {
dispatch.elementClick({
row: this, //TODO: decide whether or not this should be consistent with scatter/line events or should be an html link (a href)
data: d,
pos: [d.x, d.y]
});
})
.on('dblclick', function(d) {
dispatch.elementDblclick({
row: this,
data: d,
pos: [d.x, d.y]
});
})
.on('mouseover', function(d) {
dispatch.elementMouseover({
row: this,
data: d,
pos: [d.x, d.y]
});
})
.on('mouseout', function(d) {
dispatch.elementMouseout({
row: this,
data: d,
pos: [d.x, d.y]
});
});
// Toggle children on click.
function click(d, _, unshift) {
d3.event.stopPropagation();
if(d3.event.shiftKey && !unshift) {
//If you shift-click, it'll toggle fold all the children, instead of itself
d3.event.shiftKey = false;
d.values && d.values.forEach(function(node){
if (node.values || node._values) {
click(node, 0, true);
}
});
return true;
}
if(!hasChildren(d)) {
//download file
//window.location.href = d.url;
return true;
}
if (d.values) {
d._values = d.values;
d.values = null;
} else {
d.values = d._values;
d._values = null;
}
chart.update();
}
function icon(d) {
return (d._values && d._values.length) ? iconOpen : (d.values && d.values.length) ? iconClose : '';
}
function folded(d) {
return (d._values && d._values.length);
}
function hasChildren(d) {
var values = d.values || d._values;
return (values && values.length);
}
});
return chart;
}
//============================================================
// Expose Public Variables
//------------------------------------------------------------
chart.margin = function(_) {
if (!arguments.length) return margin;
margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
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 = nv.utils.getColor(_);
scatter.color(color);
return chart;
};
chart.id = function(_) {
if (!arguments.length) return id;
id = _;
return chart;
};
chart.header = function(_) {
if (!arguments.length) return header;
header = _;
return chart;
};
chart.noData = function(_) {
if (!arguments.length) return noData;
noData = _;
return chart;
};
chart.filterZero = function(_) {
if (!arguments.length) return filterZero;
filterZero = _;
return chart;
};
chart.columns = function(_) {
if (!arguments.length) return columns;
columns = _;
return chart;
};
chart.tableClass = function(_) {
if (!arguments.length) return tableClass;
tableClass = _;
return chart;
};
chart.iconOpen = function(_){
if (!arguments.length) return iconOpen;
iconOpen = _;
return chart;
}
chart.iconClose = function(_){
if (!arguments.length) return iconClose;
iconClose = _;
return chart;
}
//============================================================
return chart;
};

@ -26,7 +26,7 @@ nv.models.line = function() {
.size(16) // default size
.sizeDomain([16,256]) //set to speed up calculation, needs to be unset if there is a custom size accessor
;
//============================================================

@ -17,6 +17,9 @@ nv.models.lineChart = function() {
, width = null
, height = null
, showLegend = true
, showXAxis = true
, showYAxis = true
, rightAlignYAxis = false
, tooltips = true
, tooltip = function(key, x, y, e, graph) {
return '<h3>' + key + '</h3>' +
@ -35,7 +38,7 @@ nv.models.lineChart = function() {
.tickPadding(7)
;
yAxis
.orient('left')
.orient((rightAlignYAxis) ? 'right' : 'left')
;
//============================================================
@ -82,7 +85,7 @@ nv.models.lineChart = function() {
- margin.top - margin.bottom;
chart.update = function() { chart(selection) };
chart.update = function() { container.transition().call(chart) };
chart.container = this;
//set state.disabled
@ -171,6 +174,10 @@ nv.models.lineChart = function() {
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
if (rightAlignYAxis) {
g.select(".nv-y.nv-axis")
.attr("transform", "translate(" + availableWidth + ",0)");
}
//------------------------------------------------------------
// Main Chart Component(s)
@ -194,25 +201,27 @@ nv.models.lineChart = function() {
//------------------------------------------------------------
// Setup Axes
xAxis
.scale(x)
.ticks( availableWidth / 100 )
.tickSize(-availableHeight, 0);
g.select('.nv-x.nv-axis')
.attr('transform', 'translate(0,' + y.range()[0] + ')');
d3.transition(g.select('.nv-x.nv-axis'))
.call(xAxis);
if (showXAxis) {
xAxis
.scale(x)
.ticks( availableWidth / 100 )
.tickSize(-availableHeight, 0);
yAxis
.scale(y)
.ticks( availableHeight / 36 )
.tickSize( -availableWidth, 0);
g.select('.nv-x.nv-axis')
.attr('transform', 'translate(0,' + y.range()[0] + ')');
d3.transition(g.select('.nv-x.nv-axis'))
.call(xAxis);
}
d3.transition(g.select('.nv-y.nv-axis'))
.call(yAxis);
if (showYAxis) {
yAxis
.scale(y)
.ticks( availableHeight / 36 )
.tickSize( -availableWidth, 0);
d3.transition(g.select('.nv-y.nv-axis'))
.call(yAxis);
}
//------------------------------------------------------------
@ -234,9 +243,23 @@ nv.models.lineChart = function() {
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
selection.transition().call(chart);
// container.transition().call(chart);
chart.update();
});
legend.dispatch.on('legendDblclick', function(d) {
//Double clicking should always enable current series, and disabled all others.
data.forEach(function(d) {
d.disabled = true;
});
d.disabled = false;
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart.update();
});
/*
legend.dispatch.on('legendMouseover', function(d, i) {
d.hover = true;
@ -264,7 +287,7 @@ nv.models.lineChart = function() {
state.disabled = e.disabled;
}
selection.call(chart);
chart.update();
});
//============================================================
@ -342,6 +365,25 @@ nv.models.lineChart = function() {
return chart;
};
chart.showXAxis = function(_) {
if (!arguments.length) return showXAxis;
showXAxis = _;
return chart;
};
chart.showYAxis = function(_) {
if (!arguments.length) return showYAxis;
showYAxis = _;
return chart;
};
chart.rightAlignYAxis = function(_) {
if(!arguments.length) return rightAlignYAxis;
rightAlignYAxis = _;
yAxis.orient( (_) ? 'right' : 'left');
return chart;
};
chart.tooltips = function(_) {
if (!arguments.length) return tooltips;
tooltips = _;

@ -85,8 +85,8 @@ nv.models.linePlusBarChart = function() {
availableHeight = (height || parseInt(container.style('height')) || 400)
- margin.top - margin.bottom;
chart.update = function() { chart(selection) };
chart.container = this;
chart.update = function() { container.transition().call(chart); };
// chart.container = this;
//set state.disabled
state.disabled = data.map(function(d) { return !!d.disabled });
@ -278,9 +278,22 @@ nv.models.linePlusBarChart = function() {
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
selection.transition().call(chart);
chart.update();
});
legend.dispatch.on('legendDblclick', function(d) {
//Double clicking should always enable current series, and disabled all others.
data.forEach(function(d) {
d.disabled = true;
});
d.disabled = false;
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart.update();
});
dispatch.on('tooltipShow', function(e) {
if (tooltips) showTooltip(e, that.parentNode);
});
@ -297,7 +310,7 @@ nv.models.linePlusBarChart = function() {
state.disabled = e.disabled;
}
selection.call(chart);
chart.update();
});
//============================================================

@ -107,7 +107,7 @@ nv.models.linePlusBarWithFocusChart = function() {
- margin.top - margin.bottom - height2,
availableHeight2 = height2 - margin2.top - margin2.bottom;
chart.update = function() { chart(selection) };
chart.update = function() { container.transition().call(chart); };
chart.container = this;
@ -356,7 +356,7 @@ nv.models.linePlusBarWithFocusChart = function() {
});
}
selection.call(chart);
chart.update();
});
dispatch.on('tooltipShow', function(e) {

@ -55,7 +55,8 @@ nv.models.lineChart = function() {
availableHeight = (height || parseInt(container.style('height')) || 400)
- margin.top - margin.bottom;
chart.update = function() { container.transition().call(chart) };
chart.container = this; // I need a reference to the container in order to have outside code check if the chart is visible or not
//------------------------------------------------------------
// Display No Data message if there's nothing to show.
@ -207,7 +208,7 @@ nv.models.lineChart = function() {
pauseFisheye = false;
}
selection.transition().call(chart);
chart.update();
});
@ -223,7 +224,7 @@ nv.models.lineChart = function() {
});
}
selection.transition().call(chart);
chart.update();
});
/*
@ -252,12 +253,6 @@ nv.models.lineChart = function() {
});
//TODO: decide if this is a good idea, and if it should be in all models
chart.update = function() { chart(selection) };
chart.container = this; // I need a reference to the container in order to have outside code check if the chart is visible or not
return chart;
}

@ -87,7 +87,7 @@ nv.models.lineWithFocusChart = function() {
- margin.top - margin.bottom - height2,
availableHeight2 = height2 - margin2.top - margin2.bottom;
chart.update = function() { chart(selection) };
chart.update = function() { container.transition().call(chart) };
chart.container = this;
@ -326,7 +326,7 @@ nv.models.lineWithFocusChart = function() {
});
}
selection.transition().call(chart);
container.transition().call(chart);
});
dispatch.on('tooltipShow', function(e) {

@ -21,6 +21,7 @@ nv.models.multiBar = function() {
, barColor = null // adding the ability to set the color for each rather than the whole group
, disabled // used in conjunction with barColor to communicate from multiBarHorizontalChart what series are disabled
, delay = 1200
, drawTime = 500
, xDomain
, yDomain
, dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout')
@ -263,6 +264,7 @@ nv.models.multiBar = function() {
if (stacked)
bars.transition()
.delay(function(d,i) { return i * delay / data[0].values.length })
.attr('y', function(d,i) {
@ -272,21 +274,21 @@ nv.models.multiBar = function() {
return Math.max(Math.abs(y(d.y + (stacked ? d.y0 : 0)) - y((stacked ? d.y0 : 0))),1);
})
.each('end', function() {
d3.transition(d3.select(this))
d3.select(this).transition().duration(drawTime)
.attr('x', function(d,i) {
return stacked ? 0 : (d.series * x.rangeBand() / data.length )
})
.attr('width', x.rangeBand() / (stacked ? 1 : data.length) );
})
else
d3.transition(bars)
d3.transition(bars).duration(drawTime)
.delay(function(d,i) { return i * delay/ data[0].values.length })
.attr('x', function(d,i) {
return d.series * x.rangeBand() / data.length
})
.attr('width', x.rangeBand() / data.length)
.each('end', function() {
d3.transition(d3.select(this))
d3.select(this).transition().duration(drawTime)
.attr('y', function(d,i) {
return getY(d,i) < 0 ?
y(0) :
@ -427,6 +429,12 @@ nv.models.multiBar = function() {
return chart;
};
chart.drawTime = function(_) {
if (!arguments.length) return drawTime;
drawTime = _;
return chart;
};
//============================================================

@ -41,7 +41,7 @@ nv.models.multiBarChart = function() {
xAxis
.orient('bottom')
.tickPadding(7)
.highlightZero(false)
.highlightZero(true)
.showMaxMin(false)
.tickFormat(function(d) { return d })
;
@ -80,7 +80,7 @@ nv.models.multiBarChart = function() {
availableHeight = (height || parseInt(container.style('height')) || 400)
- margin.top - margin.bottom;
chart.update = function() { selection.transition().call(chart) };
chart.update = function() { container.transition().call(chart) };
chart.container = this;
//set state.disabled
@ -302,9 +302,22 @@ nv.models.multiBarChart = function() {
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
selection.transition().call(chart);
chart.update();
});
legend.dispatch.on('legendDblclick', function(d) {
//Double clicking should always enable current series, and disabled all others.
data.forEach(function(d) {
d.disabled = true;
});
d.disabled = false;
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart.update();
});
controls.dispatch.on('legendClick', function(d,i) {
if (!d.disabled) return;
controlsData = controlsData.map(function(s) {
@ -325,7 +338,7 @@ nv.models.multiBarChart = function() {
state.stacked = multibar.stacked();
dispatch.stateChange(state);
selection.transition().call(chart);
chart.update();
});
dispatch.on('tooltipShow', function(e) {
@ -348,7 +361,7 @@ nv.models.multiBarChart = function() {
state.stacked = e.stacked;
}
selection.call(chart);
chart.update();
});
//============================================================

@ -78,7 +78,7 @@ nv.models.multiBarHorizontalChart = function() {
availableHeight = (height || parseInt(container.style('height')) || 400)
- margin.top - margin.bottom;
chart.update = function() { selection.transition().call(chart) };
chart.update = function() { container.transition().call(chart) };
chart.container = this;
//set state.disabled
@ -264,7 +264,19 @@ nv.models.multiBarHorizontalChart = function() {
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
selection.transition().call(chart);
chart.update();
});
legend.dispatch.on('legendDblclick', function(d) {
//Double clicking should always enable current series, and disabled all others.
data.forEach(function(d) {
d.disabled = true;
});
d.disabled = false;
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart.update();
});
controls.dispatch.on('legendClick', function(d,i) {
@ -287,7 +299,7 @@ nv.models.multiBarHorizontalChart = function() {
state.stacked = multibar.stacked();
dispatch.stateChange(state);
selection.transition().call(chart);
chart.update();
});
dispatch.on('tooltipShow', function(e) {

@ -55,6 +55,9 @@ nv.models.multiChart = function() {
var container = d3.select(this),
that = this;
chart.update = function() { container.transition().call(chart); };
chart.container = this;
var availableWidth = (width || parseInt(container.style('width')) || 960)
- margin.left - margin.right,
availableHeight = (height || parseInt(container.style('height')) || 400)
@ -253,7 +256,7 @@ nv.models.multiChart = function() {
return d;
});
}
selection.transition().call(chart);
chart.update();
});
dispatch.on('tooltipShow', function(e) {
@ -262,9 +265,6 @@ nv.models.multiChart = function() {
});
chart.update = function() { chart(selection) };
chart.container = this;
return chart;
}

@ -233,6 +233,8 @@ nv.models.pie = function() {
}
function arcTween(a) {
a.endAngle = isNaN(a.endAngle) ? 0 : a.endAngle;
a.startAngle = isNaN(a.startAngle) ? 0 : a.startAngle;
if (!donut) a.innerRadius = 0;
var i = d3.interpolate(this._current, a);
this._current = i(0);

@ -54,7 +54,7 @@ nv.models.pieChart = function() {
availableHeight = (height || parseInt(container.style('height')) || 400)
- margin.top - margin.bottom;
chart.update = function() { chart(selection); };
chart.update = function() { container.transition().call(chart); };
chart.container = this;
//set state.disabled
@ -170,7 +170,7 @@ nv.models.pieChart = function() {
state.disabled = data[0].map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
selection.transition().call(chart)
chart.update();
});
pie.dispatch.on('elementMouseout.tooltip', function(e) {
@ -188,7 +188,7 @@ nv.models.pieChart = function() {
state.disabled = e.disabled;
}
selection.call(chart);
chart.update();
});
//============================================================

@ -22,6 +22,7 @@ nv.models.scatter = function() {
, forceY = [] // List of numbers to Force into the Y scale
, forceSize = [] // List of numbers to Force into the Size scale
, interactive = true // If true, plots a voronoi overlay for advanced point intersection
, pointKey = null
, pointActive = function(d) { return !d.notActive } // any points that return false will be filtered out
, padData = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart
, padDataOuter = .1 //outerPadding to imitate ordinal scale outer padding
@ -205,13 +206,13 @@ nv.models.scatter = function() {
}
// if(vertices.length < 3) {
if(vertices.length) {
// Issue #283 - Adding 2 dummy points to the voronoi b/c voronoi requires min 3 points to work
vertices.push([x.range()[0] - 20, y.range()[0] - 20, null, null]);
vertices.push([x.range()[1] + 20, y.range()[1] + 20, null, null]);
vertices.push([x.range()[0] - 20, y.range()[0] + 20, null, null]);
vertices.push([x.range()[1] + 20, y.range()[1] - 20, null, null]);
// }
}
var bounds = d3.geom.polygon([
[-10,-10],
@ -229,7 +230,6 @@ nv.models.scatter = function() {
});
var pointPaths = wrap.select('.nv-point-paths').selectAll('path')
.data(voronoi);
pointPaths.enter().append('path')
@ -369,18 +369,22 @@ nv.models.scatter = function() {
if (onlyCircles) {
var points = groups.selectAll('circle.nv-point')
.data(function(d) { return d.values });
.data(function(d) { return d.values }, pointKey);
points.enter().append('circle')
.attr('cx', function(d,i) { return x0(getX(d,i)) })
.attr('cy', function(d,i) { return y0(getY(d,i)) })
.attr('r', function(d,i) { return Math.sqrt(z(getSize(d,i))/Math.PI) });
points.exit().remove();
d3.transition(groups.exit().selectAll('path.nv-point'))
groups.exit().selectAll('path.nv-point').transition()
.attr('cx', function(d,i) { return x(getX(d,i)) })
.attr('cy', function(d,i) { return y(getY(d,i)) })
.remove();
points.attr('class', function(d,i) { return 'nv-point nv-point-' + i });
d3.transition(points)
points.each(function(d,i) {
d3.select(this)
.classed('nv-point', true)
.classed('nv-point-' + i, true);
});
points.transition()
.attr('cx', function(d,i) { return x(getX(d,i)) })
.attr('cy', function(d,i) { return y(getY(d,i)) })
.attr('r', function(d,i) { return Math.sqrt(z(getSize(d,i))/Math.PI) });
@ -404,8 +408,12 @@ nv.models.scatter = function() {
return 'translate(' + x(getX(d,i)) + ',' + y(getY(d,i)) + ')'
})
.remove();
points.attr('class', function(d,i) { return 'nv-point nv-point-' + i });
d3.transition(points)
points.each(function(d,i) {
d3.select(this)
.classed('nv-point', true)
.classed('nv-point-' + i, true);
});
points.transition()
.attr('transform', function(d,i) {
//nv.log(d,i,getX(d,i), x(getX(d,i)));
return 'translate(' + x(getX(d,i)) + ',' + y(getY(d,i)) + ')'
@ -564,6 +572,12 @@ nv.models.scatter = function() {
return chart;
};
chart.pointKey = function(_) {
if (!arguments.length) return pointKey;
pointKey = _;
return chart;
};
chart.pointActive = function(_) {
if (!arguments.length) return pointActive;
pointActive = _;

@ -104,8 +104,8 @@ nv.models.scatterChart = function() {
availableHeight = (height || parseInt(container.style('height')) || 400)
- margin.top - margin.bottom;
chart.update = function() { chart(selection) };
chart.container = this;
chart.update = function() { container.transition().call(chart); };
// chart.container = this;
//set state.disabled
state.disabled = data.map(function(d) { return !!d.disabled });
@ -224,6 +224,8 @@ nv.models.scatterChart = function() {
.color(data.map(function(d,i) {
return d.color || color(d, i);
}).filter(function(d,i) { return !data[i].disabled }))
.xDomain(null)
.yDomain(null)
wrap.select('.nv-scatterWrap')
.datum(data.filter(function(d) { return !d.disabled }))
@ -233,14 +235,18 @@ nv.models.scatterChart = function() {
//Adjust for x and y padding
if (xPadding) {
var xRange = x.domain()[1] - x.domain()[0];
x.domain([x.domain()[0] - (xPadding * xRange), x.domain()[1] + (xPadding * xRange)]);
scatter.xDomain([x.domain()[0] - (xPadding * xRange), x.domain()[1] + (xPadding * xRange)]);
}
if (yPadding) {
var yRange = y.domain()[1] - y.domain()[0];
y.domain([y.domain()[0] - (yPadding * yRange), y.domain()[1] + (yPadding * yRange)]);
scatter.yDomain([y.domain()[0] - (yPadding * yRange), y.domain()[1] + (yPadding * yRange)]);
}
wrap.select('.nv-scatterWrap')
.datum(data.filter(function(d) { return !d.disabled }))
.call(scatter);
//------------------------------------------------------------
@ -365,7 +371,7 @@ nv.models.scatterChart = function() {
pauseFisheye = false;
}
chart(selection);
chart.update();
});
legend.dispatch.on('legendClick', function(d,i, that) {
@ -382,9 +388,22 @@ nv.models.scatterChart = function() {
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart(selection);
chart.update();
});
legend.dispatch.on('legendDblclick', function(d) {
//Double clicking should always enable current series, and disabled all others.
data.forEach(function(d) {
d.disabled = true;
});
d.disabled = false;
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart.update();
});
/*
legend.dispatch.on('legendMouseover', function(d, i) {
d.hover = true;
@ -399,7 +418,7 @@ nv.models.scatterChart = function() {
scatter.dispatch.on('elementMouseover.tooltip', function(e) {
d3.select('.nv-chart-' + scatter.id() + ' .nv-series-' + e.seriesIndex + ' .nv-distx-' + e.pointIndex)
.attr('y1', e.pos[1] - availableHeight);
.attr('y1', function(d,i) { return e.pos[1] - availableHeight;});
d3.select('.nv-chart-' + scatter.id() + ' .nv-series-' + e.seriesIndex + ' .nv-disty-' + e.pointIndex)
.attr('x2', e.pos[0] + distX.size());
@ -422,7 +441,7 @@ nv.models.scatterChart = function() {
state.disabled = e.disabled;
}
selection.call(chart);
chart.update();
});
//============================================================

@ -103,7 +103,7 @@ nv.models.scatterPlusLineChart = function() {
availableHeight = (height || parseInt(container.style('height')) || 400)
- margin.top - margin.bottom;
chart.update = function() { chart(selection) };
chart.update = function() { container.transition().call(chart); };
chart.container = this;
//set state.disabled
@ -379,7 +379,7 @@ nv.models.scatterPlusLineChart = function() {
pauseFisheye = false;
}
chart(selection);
chart.update();
});
legend.dispatch.on('legendClick', function(d,i, that) {
@ -396,9 +396,22 @@ nv.models.scatterPlusLineChart = function() {
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart(selection);
chart.update();
});
legend.dispatch.on('legendDblclick', function(d) {
//Double clicking should always enable current series, and disabled all others.
data.forEach(function(d) {
d.disabled = true;
});
d.disabled = false;
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart.update();
});
/*
legend.dispatch.on('legendMouseover', function(d, i) {
d.hover = true;
@ -436,7 +449,7 @@ nv.models.scatterPlusLineChart = function() {
state.disabled = e.disabled;
}
selection.call(chart);
chart.update();
});
//============================================================

@ -77,7 +77,7 @@ nv.models.stackedAreaChart = function() {
availableHeight = (height || parseInt(container.style('height')) || 400)
- margin.top - margin.bottom;
chart.update = function() { chart(selection) };
chart.update = function() { container.transition().call(chart); };
chart.container = this;
//set state.disabled
@ -267,7 +267,7 @@ nv.models.stackedAreaChart = function() {
dispatch.stateChange(state);
//selection.transition().call(chart);
chart(selection);
chart.update();
});
legend.dispatch.on('legendClick', function(d,i) {
@ -284,7 +284,19 @@ nv.models.stackedAreaChart = function() {
dispatch.stateChange(state);
//selection.transition().call(chart);
chart(selection);
chart.update();
});
legend.dispatch.on('legendDblclick', function(d) {
//Double clicking should always enable current series, and disabled all others.
data.forEach(function(d) {
d.disabled = true;
});
d.disabled = false;
state.disabled = data.map(function(d) { return !!d.disabled });
dispatch.stateChange(state);
chart.update();
});
controls.dispatch.on('legendClick', function(d,i) {
@ -312,7 +324,7 @@ nv.models.stackedAreaChart = function() {
dispatch.stateChange(state);
//selection.transition().call(chart);
chart(selection);
chart.update();
});
dispatch.on('tooltipShow', function(e) {
@ -334,7 +346,7 @@ nv.models.stackedAreaChart = function() {
stacked.style(e.style);
}
selection.call(chart);
chart.update();
});
});

@ -17,7 +17,7 @@
.nvtooltip {
position: absolute;
background-color: rgba(255,255,255,1);
background-color: rgba(255,255,255,0.75);
padding: 1px;
border: 1px solid rgba(0,0,0,.2);
z-index: 10000;
@ -32,7 +32,9 @@
transition-delay: 500ms;
-moz-transition-delay: 500ms;
-webkit-transition-delay: 500ms;
*/
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
box-shadow: 0 5px 10px rgba(0,0,0,.2);
@ -61,7 +63,7 @@
padding: 4px 14px;
line-height: 18px;
font-weight: normal;
background-color: #f7f7f7;
background-color: rgba(247,247,247,0.75);
text-align: center;
border-bottom: 1px solid #ebebeb;
@ -179,7 +181,8 @@ svg .title {
shape-rendering: crispEdges;
}
.nvd3 .nv-axis line.zero {
.nvd3 .nv-axis .zero line,
/*this selector may not be necessary*/ .nvd3 .nv-axis line.zero {
stroke-opacity: .75;
}
@ -698,4 +701,4 @@ svg .title {
.nvd3 .axis text {
text-shadow: 0 1px 0 #fff;
}
}

Loading…
Cancel
Save