Developing a chart which will provide a user a visual for who has viewed them. The inner circle shows matches (user following/being followed), the next ring - user following
"LATEST CODE" - http://jsfiddle.net/NYEaX/336/ (Note: Merely conceptual, highly non-optimized!)
I'm not sure if d3 can do this automatically somehow, but you can always just figure out the x and y positions of your dots yourself with some math:
One way to do it is to just place each dot randomly until it sits correctly. This is definitely not the fastest approach, but if you don't have too many dots to place, it might still be way good enough.
Let's say your smallest circle has radius rs and center point (xs, ys) and your middle circle rm and (xm, ym) and your largest circle rl and (xl, yl), then you can check which circle a dot does or does not fall into by comparing its distance from the center-point of the circle to the radius of that circle:
For example, if you want to place a dot into the middle circle:
Now you have some random point that is inside the middle circle, but not the small one. Placing one into the larger circle works the same way (just replace xm, ym, and rm with xl, yl, and rl as well as xs, ys, and rs with xm, ym, and rm). To place a dot into the smallest circle, you only need to check the first condition (with xm, ym, and rm replaced by xs, ys, and rs).
Now, you can either stop here (but depending on your dot-density, this might not be the prettiest picture) or, you can try to space the dots a little nicer relative to each other. One way to do this is the following:
By adjusting the two check-equations above, you can also add a little bit of clearance around the borders of your circles that the dots will avoid, by replacing rm2 with (rm - d)2 and rs2 with (rs + d)2.
There are definitely a bunch of ways to optimize this simple approach: For example you can pick your initial (x, y) position in polar coordinates by choosing r and α instead and then calculating x and y from them to make sure that you never pick a dot that is not inside the circle you want. Just make sure you pick r from a correctly weighted distribution so that x and y turn out to be uniformly distributed. Also, you can check the distance from a newly placed dot to all its neighbors immediately when placing the dot rather than in a second step at the end. For example, find 10 places for each dot and then always pick the one out of those with the largest distance to its closest neighbor.
UPDATE
And this is what it looks like without worrying about dot spacing: http://jsfiddle.net/NYEaX/328/
The relevant section implementing the dot placement is here (variable names changed to match above):
function getXCoordinateInCircleSection(i, xm, ym, rm, xs, ys, rs) {
done = false;
while (!done) {
x = getRandomCoordinate(xm-rm, xm+rm);
y = getRandomCoordinate(ym-rm, ym+rm);
done = true;
if ((x-xm)*(x-xm)+(y-ym)*(y-ym) > (rm-10)*(rm-10)) done = false;
if ((x-xs)*(x-xs)+(y-ys)*(y-ys) <= (rs+10)*(rs+10)) done = false;
}
window.ys[i] = y;
return x;
}
function getYCoordinateInCircleSection(i) {
return window.ys[i];
}
And with improved dot spacing: http://jsfiddle.net/NYEaX/329/
(Both of these are based on http://jsfiddle.net/NYEaX/326/ created by @TheOldCounty)