I need to place circles in the sunburst arcs, close to the outer radius either in the middle or in the sides as in the mock-up in the B Unit slice.
Please use this sunburst example to play around: jsfiddle
var circles = g.append("circle")
.attr("cx",
function(d) {
return arc.centroid(d)[0];
})
.attr("cy",
function(d) {
return arc.centroid(d)[1];
})
.attr("r", 8)
.attr("stroke", "black")
.attr("stroke-width", 2)
.style("fill", "blue");
Related
The following code should show a scatter plot but the when I check the elements in the developer tools of chrome I only see 1 circle. The full code can be seen here:
https://bl.ocks.org/centem/db547f011997e64ebf2544e9e22c33ce
I'm creating the circles like this:
svg.selectAll("circle")
.data(d3.values(data))
.enter()
.append("circle")
.attr("cx", function(d) { return x_scale(d["export_val_2010"]); })
.attr("cy", function(d) { return y_scale(d["export_val_2011"]); })
.attr("r", 5);
I wanted to draw a pulsating warbling circle on a geomap using d3, using this example for guidance. However—and I know this is a very basic question, so apologies—I can't seem to get the selector to fire right. Here is the relevant code:
layer2
.attr("id", "locations")
.selectAll(".state")
.data(columbia.features)
.enter().append("circle")
.attr("class", "location")
.attr("r", "4px")
.attr("cx", function(d) { return proj(d['geometry']['coordinates'])[0]; })
.attr("cy", function(d) { return proj(d['geometry']['coordinates'])[1]; })
.attr("d", path)
.each(pulse);
function pulse() {
var circle = svg.select(".location");
console.log(circle);
(function repeat() {
circle = circle.transition()
.duration(2000)
.attr("stroke-width", 20)
.attr("r", 10)
.transition()
.duration(2000)
.attr('stroke-width', 0.5)
.attr("r", 200)
.ease('sine')
.each("end", repeat);
})();
}
Right now I have:
var circle = svg.select(".location");
What should I have instead of .location?
Here is the full file.
Edit: got it; I need selectAll, notselect.
The effect I'm going for in a map based visualisation is:
Red circles on a map represent data (things at locations)
When something happens at a location, we briefly (2 seconds) show another, blue circle fading out over the top.
I'm trying to work out how to do this in the D3 paradigm. Specifically: how do you represent the same thing twice?
The problem I run into is that when I try to add the same dataset twice to a given SVG canvas group, nothing gets added. That is, using code like this:
g = svg.append("g");
var feature = g.selectAll("circle")
.data(stations)
.enter().append("circle")
.style("stroke", "black")
.style("opacity", .6)
.style("fill", "red")
.attr("r", function(d, i) { return d.free_bikes; });
var emphasis = g.selectAll("circle")
.data(stations)
.enter().append("circle")
.style("stroke", "black")
.style("opacity", .6)
.style("fill", "blue")
.attr("r", function(d, i) { return d.free_bikes; });
This workaround is ok, but kludgy and potentially limiting:
g2 = svg.append("g");
var emphasis = g2.selectAll("circle")
That is, adding the second group of elements to a different SVG group.
The proper way to do this is to use classes to select the circles (and applying that class when you create them). So you create the features like so:
var feature = g.selectAll("circle.feature")
.data(stations, function (d) { return d.id; } )
.enter().append("circle")
.attr("class", "feature") // <- assign the class
....
Similarly, for the emphasis:
var feature = g.selectAll("circle.emphasis")
.data(stations, function (d) { return d.id; } )
.enter().append("circle")
.attr("class", "emphasis") // <- assign the class
....
I've finally (sort of) figured it out. The two sets of data are treated as one because they share the same key, according to the rules of D3 constancy. So an easy way around is to give each set a key that can't overlap:
var feature = g.selectAll("circle")
.data(stations, function (d) { return d.id; } )
.enter().append("circle")
.style("stroke", "black")
.style("opacity", .6)
.style("fill", "red")
.attr("r", function(d, i) { return d.free_bikes * 1; });
var emphasis = g.selectAll("notathing")
.data(stations, function (d) { return d.id + " cannot possibly overlap"; } )
.enter().append("circle")
.style("stroke", "black")
.style("opacity", .6)
.style("fill", "blue")
.attr("r", function(d, i) { return d.free_bikes * 1; });
The only slight quirk is I have to modify the second selector (g.selectAll("notathing")) so it doesn't match any of the circles created by the first one.
I have a scatter plot made in D3 with circles denoting each data point. Here's my code:
viz.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr("cx", function(d) {return x(d.x)})
.attr("cy", function(d) {return y(d.y)})
.attr("r", 5)
.attr("fill", function(d) {return d.color})
.on('mouseover', function(d){
console.log(d.color)
})
What I would like to do is, when a given circle is hovered on, connect all circles through a line that have the same color. How can I do this? I can get the color logged into the console, but I don't understand how I can connect all points with the same color through a line upon mouse click?
You can assign a class with color code to your circles. Use d3.selectAll to retrieve all of them on mouseover. Then retrieve their coordinates and pass the coordinates to draw d3.svg.line.
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", function(d) {
return 'dot color-' + color(d.species).replace('#','');
})
.attr("r", 3.5)
.attr("cx", function(d) { return x(d.sepalWidth); })
.attr("cy", function(d) { return y(d.sepalLength); })
.attr("dot-color", function(d) { return color(d.species).replace('#',''); })
.style("fill", function(d) { return color(d.species); })
.on("mouseover", function() {
d3.selectAll(".color-" + $(this).attr("dot-color"))
.attr("r", 5.5);
})
.on("mouseout", function() {
d3.selectAll(".color-" + $(this).attr("dot-color"))
.attr("r", 3.5);
});
Here's an example with color hover:
http://vida.io/documents/KinEKRkSPSfStA4Eu
You can also do it without relying on a common class attribute. In the mouseover handler:
d3.selectAll('.dot')
.filter(function (dOther) { return d.color == dOther.color })
.attr('r', 3.5)
I am building an epidemic simulation using D3's force-directed diagram.
When a transmission event occurs, I want to move a circle from the transmitter to the newly infected individual.
PROBLEM: Only the first element is created and moved according to the bound data.
First, I gather the coordinates:
xyCoords = getPathogen_xyCoords(newInfections);
Where xyCoords looks like the following:
{receiverX: newInfections[i].x, receiverY: newInfections[i].y, transmitterX: newInfections[i].infectedBy.x, transmitterY: newInfections[i].infectedBy.y}
Then I create the circles and bind them to xyCoords:
d3.select(".svg").append("circle")
.attr("class", "pathogen")
d3.selectAll(".pathogen")
.data(xyCoords)
.attr("cx", function(d) { return d.transmitterX})
.attr("cy", function(d) { return d.transmitterY})
.attr("r", 4)
.style("fill", "green")
Finally, the circle is moved with a transition:
d3.selectAll(".pathogen")
.transition()
.duration(500)
.attr("cx", function(d) { return d.receiverX} )
.attr("cy", function(d) { return d.receiverY} );
EDIT: The game has been up for a few months now and doing quite well! Check it out at http://vax.herokuapp.com!
I've solved my problem...
At creation of the circles, I was not "entering" new circles to be associated with the newly bound data.
It was displaying only the first element on bind because there was only one circle to begin with.
Creation of the circles now looks like this:
xyCoords = getPathogen_xyCoords(newInfections);
var pathogen = svg.selectAll(".pathogen")
.data(xyCoords)
.enter()
.append("circle")
.attr("class", "pathogen")
.attr("cx", function(d) { return d.transmitterX })
.attr("cy", function(d) { return d.transmitterY })
.attr("r", 4)
.style("fill", "green")