When creating a sunburst chart with NVD3 (version 1.8.1) and D3 (version 3.5.8), I find that when I click on some lowest-level slices, it zooms into the incorrect section of the graph:
nv.addGraph(function () {
chart = nv.models.sunburstChart();
chart.color(d3.scale.category10());
d3.select("#test1")
.datum(getData())
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
For instance, in this JSFiddle, when clicking on "Pug" it zooms to "Sparrow", but all other transitions seem to be working.
I have been unable to find the cause of this, as the x scale does seem to change domain to the correct values.
Additionally, the JSON data seems alright.
How would I correct for this?
Related
I was using nvd3.js to create a simple stacked bar chart as described here
I added the code mentioned in the link in an angular directive as follows:
app.directive('stackBar', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
nv.addGraph(function() {
var chart = nv.models.multiBarChart()
/*.transitionDuration(350)*/
.reduceXTicks(true) //If 'false', every single x-axis tick label will be rendered.
/*.rotateLabels(0) */ //Angle to rotate x-axis labels.
.showControls(true) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.1) //Distance between each group of bars.
chart.xAxis
.tickFormat(d3.format(',f'));
chart.yAxis
.tickFormat(d3.format(',.1f'));
d3.select(element[0])
.datum(exampleData())
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
//Generate some nice data.
function exampleData() {
return stream_layers(3,10+Math.random()*100,.1).map(function(data, i) {
return {
key: 'Stream #' + i,
values: data
};
});
}
}
}
});
Here's my HTML:
<td class="centered" colspan="5">
<div stack-bar>
</div>
</td>
But, I am getting the following error:
Uncaught ReferenceError: stream_layers is not defined
Any idea where I am going wrong?
Also, 'transitonDuration' was also not working so I commented it out. I initially thought, this maybe some problem related to the version of d3, but I am using the latest version and still the problem persists.
EDIT:
Huang Feng's answer helped me get rid of the error. But instead of getting any chart I am getting a lot of text. Here's a screenshot:
Any idea why?
Also, the directive is in an ng-repeat, and thats why there are multiple rows as in the screenshot.
This is because you don't define the stream_layers function, and it's also not a function in nvd3 lib.
It's defined here:
http://nvd3.org/assets/js/data/stream_layers.js
If you want to use it, you should include this lib in the html like:
<script src="../stream_layers.js"></script>
If you want a detail example, here is one for your reference:
http://bl.ocks.org/mbostock/3943967
I encountered similar output (and errors), and there were 3 things needed to fix this:
1. Add stream_layers.js to path
As mentioned by huan feng, you need to include the stream_layers.js function to generate fake data for the example. I downloaded the source code from nvd3.org, and the stream_layers.js file was located in novus-nvd3-8ceb270/test/stream_layers.js (you'll most likely need to update at least that first part of your path based on the latest shortened git hash.
2. Replace transitionDuration with duration
Another issue is that the API has changed for NVD3. After inspecting the source code (line 456 in novus-nvd3-8ceb270/src/models/multiBarChart.js), the transitionDuration method has been replaced with just duration. Here is a snippet from your code above with the duration option corrected:
var chart = nv.models.multiBarChart()
.duration(350)
.reduceXTicks(true) //If 'false', every single x-axis tick label will be rendered.
/*.rotateLabels(0) */ //Angle to rotate x-axis labels.
.showControls(true) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.1) //Distance between each group of bars.
3. Create an SVG
Lastly, your screen shot is only showing text. I think the reason for this is because you were trying to append your chart to a div when it needs to be appended to an SVG element. One way of correcting this is by appending an svg to element[0], and then selecting that svg to use with your vizualization:
var svg = d3.select(element[0])
.append('svg')
.attr('id', 'my-bar-chart-svg')
d3.select('#my-bar-chart-svg')
.datum(exampleData())
.call(chart);
If you're still not seeing anything, you might need to fiddle with the width and height of the SVG element you created to append your chart to. Here's one quick hack for testing:
var svg = d3.select(element[0])
.append('svg')
.attr('id', 'my-bar-chart-svg')
.attr('width', 800)
.attr('height', 400)
d3.select('#my-bar-chart-svg')
.datum(exampleData())
.call(chart);
I'm trying to replicate this Focus+Context via Brushing example. I'm including the same layout, but with a scatterplot instead of a line/area plot.
I started working off this example I found which combines the area plot and a scatterplot. However, when I scrap the area plot, I lose the zoom/focus capability.
My last step (thus far unsuccessful) is to make the brush (small focus bar on the bottom) actually respond to the main panel (make it adjust/zoom in when smaller time periods are selected in the brush). The brush adjusts the axis as it should, but I just haven't been able to make the brush actually adjust/zoom the points on the main scatterplot. I'm not trying plot anything in the brush - there will be a lot of points, so keeping the brush with a grey background and no points is fine.
here's my fiddle: http://jsfiddle.net/fuqzp580/3/
Sidenote: I can't quite get the jsfiddle to work with the way I'm using d3.csv, so I coded up a slightly altered version with dummy data in lieu of using d3.csv. However, I included the d3.csv code (commented out), just in case that could be a cause for my problem.
I'm new to d3 so any pointers or ideas welcome!
Here's an updated fiddle with the dots zooming on the points in the main panel: http://jsfiddle.net/henbox/3uwg92f8/1/
You were very close, I just made 3 small changes:
Firstly, uncommented the code you already had in function brushed() for selecting the dots
Secondly, defined mydots globally (since you were only doing it inside initialize() and it needs to be used beyond this scope). Added this on line 55:
var mydots = focus.append("g");
And last (and most importantly), I changed the definition for xMap from
xMap = function(d) { return x2(d.time); }
to
xMap = function(d) { return x(d.time); }
When brushing, it's the x scale that gets updated, not the x2
I'm using nv.d3.js and d3.v3.js and working off this model example.
I want to remove the Y2 axis and have the bar and line chart work off the same data. So, they should be working off the same scale.
Note: I have seen this very related post and tried the solution given there. The below code was provided in that link. I implemented into my code and it didn't work, apparently because I am working with d3.v3 and not d3.v2.
chart.y2Axis.scale().domain(chart.y1Axis.scale().domain());
This line of code made some difference though. If I hover my mouse over the displayed points, they no longer enlarge. If I hover my mouse over the bottom of the x-axis the points enlarge. This seems to hint that the line chart points are being re-scaled but not redrawn.
Any help is appreciated! Thank you!
EDIT / UPDATE: If anyone is trying to do the same thing, I simply used d3.json() twice! See below:
d3.json("data.json",function(error,data) {
nv.addGraph(function() {
var chart = nv.models.discreteBarChart()
....
....
return chart;
});
});
d3.json("data2.json",function(error,data) {
nv.addGraph(function() {
var chart = nv.models.linePlusBarChart()
....
....
return chart;
});
});
I'm using nvd3 for a multi-bar chart, and I'd like to make the chart redraw when the user clicks the other html on my page. I tried using jQuery to select the "Stream0" legend circle on the nvd3 homepage (http://nvd3.org/) and click it using this snippet in the console:
$($('g.nv-series')[0]).click()
For reasons that I hope will be immediately obvious to people more knowledgeable about javascript, nothing happens. Is it something to do with event delegation?
http://nvd3.org/
you can try this:
chart.legend.dispatch.legendClick = function(d, i){
//redraw
};
It will append your own method to the legend; it works for pie chart not sure if works for the line chart;
Maybe there is some help in this. Two charts, one pie, one stack but only showing legends on pie.
The data is not identical but the legends are..
Want to update both on clicking pie legends.
chart.legend.dispatch.on('stateChange.pie', function(d,i){
setTimeout(function() {
stackedAreaChart.dispatch.changeState(d,i);
stackedAreaChart.update();
}, 100);
});
Note: using the ".pie" will extend the (library) stateChange event (not overwrite it)
The other chart stackedAreaChart has to be in the scope.
Note there is a changeState event and a stateChange, best is to look at the un-minified nvd3 js file..
There are two things I want to achieve in nvd3 bullet chart.
I want the starting point to change the starting point from 0. As can be seen in the example, all my relevant data is in the higher side and it gets too crowded at the right end of bullet chart if I start from 0. View would be much better if starting point is around 2000.
I want to display something on mouse over on the markers. Is this possible?
This is my code:
var data = {
"title": "Price in Locality",
"subtitle": "US$, in thousands",
"ranges": [2500,2700,2900, 3000],
"measures": [2850],
"markers": [2800]
};
nv.addGraph(function() {
var chart = nv.models.bulletChart();
d3.select('#chart svg')
.datum(data)
.transition().duration(1000)
.call(chart);
return chart;
});
Here is my jsfiddle example.
Any help?
The answer to your question
2. I want to display something on mouse over on the markers. Is this possible?
Yes, its possible, make sure you pull the latest version on NVD3 from here, it has tooltip enabled. Shows the ranges,measures and markers on hover.
Not quite clear on the question 1 sorry about it.
Nearly a year late on this, but I figured I'd throw this up anyway.
Based on the source of the bullet chart, there doesn't seem to be a way to change the starting position from 0 to something higher, as in your first question. (In fact, there seems to be little you can change, except the ranges and the color.)
However, it looks like your ranges are in the 2000s. So you could divide all your numbers by 100 and make your subtitle property millions instead of thousands and format your number as a Fixed.