Reputation: 4132
I used this code as my starting point: https://github.com/lucasfilippi/d3-radar
My JSFiddle is here: http://jsfiddle.net/gingerbeardman/Cdg58/
Here's a sample radar chart that it draws:
The original binds data using an external JSON file, but I prefer to bind a dynamically generated JSON object. I randomly generate some data for the purposes of this proof-of-conept demo.
However, I'm stuck with how to get the chart to show the new/updated data.
function refresh() {
var data = rndData();
d3.select("#container")
.datum(data)
.call(chart);
}
function rndData() {
var newData = [...];
return newData;
}
I have set up a function on click event to draw a new chart with random data, but there is no visual change when it is called. I've verified that the data is different and that the call happens.
The code does not use the update() and exit() calls, perhaps that's not so bad given no points on the line are actually being added or removed. I simply want each point on the SVG line to transition to new co-ordinates.
Upvotes: 1
Views: 2134
Reputation: 109242
The way the current code is set up is not really compatible with being able to update. To do this, quite substantial changes have to be made.
The first problem is that the code only operates on new SVGs. Everything happens on gEnter
, which is an empty selection if the SVG is there already. This is easy enough to fix though by reselecting the g
element after appending it and then operating on that. This will select both newly-appended g
s and those that were there before.
var g = svg.select("g");
Furthermore, the way appending elements is done throughout the code usually looks like this:
var something = foo.selectAll(".bar").data(data).enter().append();
This only handles the enter selection and doesn't even allow access to the other selections. Refactoring this to look like
var something = foo.selectAll(".bar").data(data);
something.enter().append();
something... // change update selection
fixes the problem.
Complete, working example here. Note that I'm not handling the exit selection in there as it is not necessary for this example.
Upvotes: 4
Reputation: 5015
The way the original code is setup, the svg
element is really the pivotal element for the enter/update/exit pattern. Here are some excerpts from the code changes I made:
// Select the svg element, if it exists.
var svg = d3.select(this)
.selectAll('svg')
.data([metrics]);
// --> svg exit selection
svg.exit().remove();
// --> svg enter selection
svg.enter().append('svg');
// create the skeletal chart.
var svgAppend = svg
.append('g')
.attr('transform', 'translate(' + (side / 2) + ', ' + (side / 2) + ')');
...
// --> svg update selection
svg.selectAll('.radar')
.each(function (d, n) {
chart.drawArea(d3.select(this), n);
})
I renamed the gEnter
variable to svgAppend
because it more clearly expresses what is happening.
Here is the complete working fiddle.
Upvotes: 3
Reputation: 17362
Actually, it looks like you need to pass in your data like this:
d3.json("radar.json", function(error, data) { d3.select("#container") .datum(data) .call(chart); });
so, I'd place your data object variable in lieu of "radar.json" in the example and just make sure that it is formatted correctly according to the doc. Did you try that already?
Upvotes: 1