Zoomable sunburst visualization comes out messed up - javascript

I am reading a spreadsheet using sheetsee.js (and tabletop.js) and trying to create a zoomable sunburst with labels visualization. However, it is only creating one level and the text is rotated either +90 or -90. The URL to my html page is http://www.wyzpubs.com/dataviz/sheetsee/dita_users_sb.html
Can someone tell me what could be causing this? I think the way I am creating the JSON with size information is OK and it is exactly like in metmajer's zoomable sunburst with labels.
Thanks,
Jayaram

The bug is here in sheetsee.sunburst.js
var partition = d3.layout.partition()
.value(function(d) { return d.size; });
Your data has nothing like size(in the json) thus everything gets collapsed.
It should have been some value to decide the arc length size
I did something like this(but you can change it to some biz logic of yours):
var partition = d3.layout.partition()
.value(function(d) { return d.parent.children.length; });
Working code here
Hope this helps!

Related

Not able to get the Zoom/Pan and States name appear in India Map - D3?

I am new to D3.js. However after being practiced the examples of this site, I tried to play ahead with Mr.John Coogan's map given here. The output that I found in his site is as under
But when I am trying to do the same thing by placing his .js,css,.json and index.html in plunker it is coming as
Problems
a) No States are getting displayed
b) Zoom and Pan is not working
In another word, at this point of time I am looking only for the Indian map to work exactly as the example shown by Mr. Coogan.
What needs to be done for this?
Here's the working plunk: http://plnkr.co/1EqpIFecwJmkbvypTyQD?p=preview
You needed to uncomment this line:
.call(d3.behavior.zoom().on("zoom", redraw))
on line 40 of the index.html in your plunk, and then zoom and pan will work.
The state colors (based on wealth) are not showing because of various, more complex errors. The error shown in the console (svg is not defined referencing line 78) is just the start (you need to replace svg with india, which is defined).
In fact the whole original gist your example is based on is really just a work in progress, but most of the answers for how to fix it can be found in this thread from the google group, from Mike Bostock himself.
Essentially, the json data loads asynchronously, so need to be loaded in series.
// load the two JSON files in series
d3.json("states.json", function(states) {
d3.json("wealth.json", function(wealthdata) {
...
});
});
Then you can just apend the relevant colorbrewer CSS class when you first create each path:
india.selectAll("path")
.data(states.features)
.enter().append("path")
.attr("d", path)
.attr("class", function(d) {
return "q" + quantize(wealthdata[d.id]) + "-9";
})
.attr("d", path);
But you also need to define the quantize scale, range...:
var quantize = d3.scale.quantize()
.range(d3.range(9));
... and domain (which you can only do once the data has been loaded:
quantize.domain([0, d3.max(d3.values(wealthdata))]);

how to use string values as axis ticks properly in d3js? Not able to map data correctly can't figure out whats wrong in this code

I am new to D3. In my scatterplot i need to plot usernames for y-axis but data and axis tick values are out of order can anybody help me find out what's wrong with this code ?
Full link to my code : Scatterplot code
I don't see anything major in your code. A couple of things:
1.) The sorting on your y-axis is fine. It's sorted in the order they appear in your data. As #mdml says in the comments, you can sort them differently if you desire.
2.) You have an "odd" point in your data. Everything is occurring around Nov-27-2014-12:33 except for one point on the 28th. This is causing d3 to pick a larger range for the x-axis and plotting most your data points on top of each other.
3.) You should probably "center" your points in relation to you y-axis:
.attr("cy", function(d) { return y(d.user) + y.rangeBand() / 2; })
Here's an example tweaking some things.

How to make multiple charts with d3.chart using nested data

I'm trying to create several charts using the d3.chart framework. This seems like it would be a common use case: the whole point of d3.chart is for the charts to be reusable after all! If you can just point me to an example that would be awesome (:
I went through this (https://github.com/misoproject/d3.chart/wiki/quickstart) tutorial to create a very basic "circle graph". (I copied the code exactly). Now what I want to do is create a separate chart for several sets of data.
I edited it slightly.
Before editing, to set up the chart we called:
var data = [1,3,4,6,10];
var chart = d3.select("body")
.append("svg")
.chart("Circles")
.width(100)
.height(50)
.radius(5);
chart.draw(data);
I tried to change it to:
var data = [{key:1, values:[1,3,4,6,10]},
{key:2, values:[5,2,10,8,11]},
{key:3, values:[1,5,9,16,12]}]
var chart = d3.select("body")
.selectAll("chart)
.data(data)
.enter()
.append("svg")
.chart("Circles")
.width(100)
.height(50)
.radius(5);
chart.draw(function(d) { return d.values; });
This doesn't work however. You can see the corner of a circle in 3 diferent places, but
the rest of it is cut off. However if replace
chart.draw(function(d) { return d.values; });
with
chart.draw([1,3,4,6,10]);
it correctly generates 3 circle graphs, all with that one dataset. And when I add
chart.draw(function(d) { console.log(d.values) return d.values; });
The console shows the 3 arrays I'm trying to pass it! I don't understand what is happening here that's breaking the code. Shouldn't it be the exact same thing as passing the actual arrays to 3 separate charts?
Here's a link to the JS bin with it set up: http://jsbin.com/jenofovogoke/1/edit?html,js,console,output Feel free to mess around with it!
The code is wayyy at the bottom.
I'm pretty new to java script and d3, and entirely new to d3.chart. Any help would be super appreciated!
I asked Irene Ros, who helps run d3.chart, and she informed me that the problem is that d3.chart's draw method can only take an array or a data object- it cannot take a function. She gave me a few helpful hints for ways to get around this: by using a transform function to edit my data within the chart, rather than using a function, or by creating a chart that holds multiple charts (see https://gist.github.com/jugglinmike/6004102 for a great example of this).
However in the end I found the simplest solution for me was to manually set the data. It feels like a bit off a hack because D3 does this for you already, but it was much simpler than changing the whole set up of my chart, and allows for nested data (yay!).
var svg = d3.select("body")
.selectAll("svg")
.data(data)
.enter()
.append("svg");
svg.each(function(d, i) {
var chart = d3.select(this)
.chart("Circles")
.height(50)
.width(100)
.radius(5)
var data = d.values;
chart.draw(data);
});

Sunburst partition data overwritten by second sunburst on same page

Posting both question & answer here to save somebody else the same trouble later...
When I create two sunburst charts using d3.layout.partition, the first sunburst's slice proportions are overwritten by the second sunburst's slice proportions upon resize of the slices.
The two charts pass different .value accessor functions into the partition layout, e.g.
d3.layout.partition()
.sort(null)
.value(function(d) { return 1; });
vs.
d3.layout.partition()
.sort(null)
.value(function(d) { return d.size; });
And they generate their own list of nodes that are not shared between the two sunbursts. However, if I re-call the d3.svg.arc generator to resize to larger radius (but not change overall proportions), the slice angles are suddenly overwritten.
See the example here: http://bl.ocks.org/explunit/ab8cf15534f7fec5ac6d
The problem is that while partition.nodes() seems to generate a new data structure (e.g if you give it some .key functions, it writes the extra properties (e.g. .x, .y, .dx, dy) to the underlying data and does not make a copy of the data. Thus if the data structure is shared between the two charts, these .x, .y, .dx, dy properties will bleed through to the other graphs.
This seems like a bug to me, but in reading this old GitHub issue it seems to be treated as "by design". Perhaps it will be reconsidered in future versions.
One workaround is to use something like Lodash/Underscore cloneDeep or Angular's copy to make each chart have it's own copy of the data.
makeSunburst(null, _.cloneDeep(root), countAccessorFn);
makeSunburst(null, _.cloneDeep(root), sizeAccessorFn);
See example here: http://bl.ocks.org/explunit/e9efb830439247eea1be
An alternative to copying the whole dataset for each chart would be to simply recompute the partition before re-rendering.
Instead of having makeSunburst() be a function of the accessor, make it a function of the partition. Pass a different partition function to each chart:
// create separate partition variables
var countPartition = d3.layout.partition().sort(null).value(countAccessorFn);
var sizePartition = d3.layout.partition().sort(null).value(sizeAccessorFn);
// make the charts as a function of partition
charts.push(makeSunburst(root, countPartition));
charts.push(makeSunburst(root, sizePartition));
Then before applying the transition, simply update the nodes variable to reflect the associated partition:
addToRadius: function(radiusChange) {
radius += radiusChange;
ringRadiusScale.range([0, radius]);
// update the data before re-rendering each chart
nodes = partition.nodes(dataRoot);
path.transition().attr('d', arc);
}
Now when you update each chart, it is using the correct partition.
Here's an updated example.

Circles aren't updating in a multiline graph

I have a D3.js multiline graph with circles added on every path peak. When I update my graph, the paths update just fine with the new data but the circles don't seem to get updated at all. Here's my code: http://jsbin.com/eMuQOHoV/3/edit
Does anyone know what I'm doing wrong?
You need to update the data point circles in the same way that you've created them. In particular, you're using a nested selection when creating them, but not when updating. This means that the data won't get matched correctly on update and nothing happens.
The code for the update should look like this.
var sel = svg.selectAll('.series')
.data(sources);
sel.select('path')
.transition()
// etc
// update circles
sel.selectAll('.datapoint')
.data(function (d) {
return d.values;
})
// etc
Complete jsbin here.

Categories

Resources