No circles for Scatter Plot - d3.js

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);

Related

Placing circles in Sunburst arcs

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");

Lack of motion in my loco motion chart

I'm trying to adapt Mike Bostock's Wealth of Nations motion chart example to my own data set. Funny enough, I'm using GPS lata/long from train locomotives as the axes and datetimes instead of years.
Have a look at my jsfiddle (link).
This seems to be the key part to actually move the dots, but I'm not actually getting any motion.
// Add a dot per loco. Initialize the data at min(starttime), and set the colors.
var dot = svg.append("g")
.attr("class", "dots")
.selectAll(".dot")
.data(interpolateData(minDateInt))
.enter().append("circle")
.attr("class", "dot")
.style("fill", function(d) { return colorScale(color(d)); })
.call(position)
.sort(order);
// Positions the dots based on data.
function position(dot) {
dot .attr("cx", function(d) { return xScale(x(d)); })
.attr("cy", function(d) { return yScale(y(d)); })
.attr("r", function(d) { return radiusScale(radius(d)); });
Does anyone know what's wrong with my code?

Create a line connecting circles upon mouse hover

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)

.data() binding only first element

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")

circle radius not updating on transition in d3

I am having trouble with a transtion in d3. This jsfiddle illustrates the problem: http://jsfiddle.net/3bzsE/
When the page loads, dataset01 is used to create a circle for each person in the array. d.name is used as the key.
The blue rectangles below the chart are buttons that update the data on click.
Here is the update funciton:
function updateVis(data) {
var points = svg.selectAll('.nameinfo')
.data(data, function(d) { return d.name;});
var pointsEnter = points
.enter()
.append('g')
.attr('class', 'nameinfo');
pointsEnter
.append('circle')
.attr('cx', function(d) { return 10 + d.position * 100; })
.attr('cy', width/2)
.attr('r', 0)
.style('fill', function(d) { return z(d.position); })
.style('fill-opacity', 0.5)
.style('stroke', '#232323')
.append("title")
.text(function(d) { return d.name; });
pointsEnter
.append('text')
.attr('x', function(d) { return 10 + d.position * 100; })
.attr('y', width/2)
.attr("dy", "0.35em")
.style("text-anchor", "middle")
.style("font-size", "11px")
.text(function(d, i) { return d.name; });
pointsUpdate = points
.selectAll('circle')
.transition().duration(500)
.attr('r', function(d){ return d.value/2;});
var pointsExit = points.exit().transition().duration(500).remove();
pointsExit
.selectAll('circle')
.attr('r', 0);
}
The enter and exits are behaving as expected, but circle radius is not changing for names that are present in the entering and exiting datasets.
An example using the values for Jim:
clicking on button three with button one active:
Joe, Janet and Julie exit
Jane and John enter
But, the radius of Jim does not change (it should shrink because d.value changes from 130 to 50)
Clicking on two with three active causes Jim to exit. Clicking on three from two causes Jim to enter with the proper radius from dataset03.
The same behavior can be see with the other names. In all cases enters and exits work, but if two datasets have an element with the same name, radius is not updated on transition
You might have to specifically select the circles for your transition rather than trying to do it on the outer group element. So instead of this:
pointsUpdate = points
.selectAll('circle')
.transition().duration(500)
.attr('r', function(d){ return d.value/2;});
Do this:
svg.selectAll('.nameinfo circle')
.data(data, function(d) { return d.name;})
.transition().duration(500)
.attr('r', function(d){ return d.value/2;});
UPDATE: Below is another way that fits better with the overall D3 philosophy of reusing the existing data/selection:
points
.select('circle').transition().duration(500)
.attr('r', function(d){ return d.value/2;});

Resources