I'm having trouble getting the area portions of a difference chart to properly execute transitions.
As I am still learning, the chart is based on Mike Bostock's Difference Chart example and the transitions were guided by d3noob's transitions post.
Relevant bits:
svgchin.select("#clip-above-chin path")
.duration(750)
.attr("d", area.y0(0));
svgchin.select("#clip-below-chin path")
.duration(750)
.attr("d", area.y0(height));
svgchin.select(".area.above")
.duration(750)
.attr("d", area.y0(function(d) { return y(d["Post"]); }));
svgchin.select(".area.below")
.duration(750)
.attr("d", area);
Full jsFiddle here: http://jsfiddle.net/uxb3yq9g/6/
As you can see, the lines and axes update as intended. The areas, however, are not yet on board.
Any ideas?
You haven't actually updated the data bound to the elements. Just do
var svgchin = d3.select("#chinook").datum(data).transition();
and everything works fine. Complete demo here.
Related
I have been trying to create a dynamic line chart in d3.js, using the tutorial here. I have almost got it working, but there is a slight problem. When I choose a date interval using the viewport and redraw the chart, it draws the line outside of the axis too. See the left of the graphic below.
Normally, I draw the line as below:
var valueline = d3.svg.line()
.x(function (d) {
return xScale(d.timestamp);
})
.y(function (d) {
return yScale(d.value);
});
plotChart.append("path")
.attr("class", "line")
.attr("id", "lineGraphId")
.attr("d", valueline(data));
And my redraw chart function is as below:
function redrawChart() {
plotChart.select("#lineGraphId").remove();
plotChart.append("path")
.attr("class", "line")
.attr("id", "lineGraphId")
.attr("d", valueline(data));
plotChart.select('.x.axis').call(xAxis);
}
I could not find a solution for drawing outside of the axis. I could not host my code in jsfiddle because I needed to load a csv data, but you can see all source code here.
Apparently, I needed to add this line of code to redrawChart function:
.attr('clip-path', 'url(#plotAreaClip)')
I'm trying to teach myself D3 with examples from http://bl.ocks.org/mbostock.
I took the scatterchart and I'm trying to load various data depending on what menu-item is active.
Everything is working fine, but I got one problem I just can't solve.
The xAxis should update itself depending on the values from the data linked to the menu item.
I was searching the web for an answer, but couldn't find one that worked for me.
I think the problem (and solution) lies in this part of the code;
function updateChart() {
svg.selectAll('.dot')
.transition()
.duration(1000)
.attr('cx', function(d) {
return x(d.data[parameter]);
})
svg.select(".x.axis")
.call(xAxis);
}
I made this JSFiddle to make it more understandable.
Here's what's going on.
You successfully generated your xAxis with the correct x scale in the first go around, however
You didn't update your xAxis with the new domain of data
You were right in that you had to re-update your scales whenever you click on your labels.
I've done a couple of things:
Add a sourceData variable after you've coerced your numbers, for all your functions to reference
Add a updateXScale(data) function that will simply update your x scale's domain
Have it called every time you click a label. Not only will this fix your x scale, it will also enable the correct scaling of your x-coordinates for your .dot's.
Here's what it looks like all together. I've created a fiddle that has a working version of your example.
And here's your updateChart function for reference:
function updateChart() {
updateXScale(sourceData);
svg.selectAll('.dot')
.transition()
.duration(1000)
.attr('cx', function(d) {
return x(d.data[parameter]);
});
svg.select(".x.axis")
.call(xAxis);
}
I started from a sample Map app at: http://bl.ocks.org/d3noob/raw/5193723/
I want to place a custom pie chart, as shown in the fig below. I created one by adding the code snippet just after the creation of circles is done.
Pie-chart Snippet:
var r=10;
var p = Math.PI*2;
var arc = d3.svg.arc()
.innerRadius(r-3)
.outerRadius(r)
.startAngle(0)
.endAngle(p* d.value1);
var arc2 = d3.svg.arc()
.innerRadius(r-7)
.outerRadius(r-4)
.startAngle(0)
.endAngle(p* d.value2);
g.append("path")
.attr("d", arc)
.attr("fill", "red")
.attr("transform", "translate(400,500)");
g.append("path")
.attr("d", arc2)
.attr("fill", "orange")
.attr("transform", "translate(400,500)");
It comes out nicely as shown in the pic below near Thailand:
Problem
When I zoom or move the map, the pie-chart disappears but the circles remain intact. Can someone help me understand it?
One can notice a very crude way the arcs are plotted. The pie-chart is expected to be plotted for each of the city. I am looking for a cleaner way just like the way circles are drawn.
The code that runs when zoom takes place
g.selectAll("path")
.attr("d", path.projection(projection));
is selecting all paths and modifying their "d" attribute. Since it's "generically" just looking for pathss, then it's also grabbing the donut paths you created and modifying them (probably setting them to empty strings or NaNs).
You can fix this either by taking the donuts out of the same g of the geo paths, so that they don't get selected. OR, you can make your "path" selector more specific, by adding some class (e.g. "geo") to all the geo paths and using that class whenever you select them (e.g. g.selectAll("path.geo")).
I'm using a D3 brush to update the arcs of a donut chart, but the update is occurring only after I release the brush. I know that D3 is capable of brush-based continuous updating as Mike has done in this example; what part of that code have I missed in my adaptation?
Here's the function that I currently use to do the updating:
function brushended() {
path.select('.donutPath')
.data(pie([brush.extent()[1],100 - brush.extent()[1]]))
.enter().append("path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", arc);
}
The event you need to listen to is .on("brush",..., like:
var brush = d3.svg.brush()
.x(x)
.extent([0,40])
.on("brush", brushended);
You should change the name of the function to better reflect the situation, but this alone will make it work.
FIDDLE with the listener changes, but also with changes to the way the update selection was being handled.
I have a doughnut chart and I wanted to have an svg circle that serves as a button and scale the doughnut chart down as well as the circle in the middle, how to I target the the other element when I.
nav.on("click", function(d){
nav.transition()
.duration(1000)
.ease("elastic")
.attr("r", 60);
});
Lastly, is there a shorter way to do what I have done so far, here is the fiddle
Well, you simply run the code in the handler that affects the other elements, e.g.
nav.on("click", function(d){
nav.transition()
.duration(1000)
.ease("elastic")
.attr("r", 60);
arc.outerRadius(radius/2);
chart.transition().duration(1000).ease("elastic").attr("d", arc);
});
Jsfiddle here. The code itself looks fine to me.