force.js
function force_layout() {
var width = 500,
height = 400,
padding = 3;
var circle = svg.selectAll("circle");
var nodes = circle
.each(function(d) {
var my = d3.select(this);
d.radius = parseFloat(my.attr("r"));
d.color = my.attr("fill");
d.x = parseFloat(my.attr("cx")) + Math.random();
d.y = parseFloat(my.attr("cy")) + Math.random();
})
.data();
var force = d3.layout.force()
.nodes(nodes)
.size([width, height])
.gravity(.02)
.charge(0)
.on("tick", tick)
.start();
circle.call(force.drag);
function tick(e) {
circle
.each(cluster(10 * e.alpha * e.alpha))
.each(collide(.5))
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
function cluster(alpha) {
var max = {};
nodes.forEach(function(d) {
if (!(d.color in max) || (d.radius > max[d.color].radius)) {
max[d.color] = d;
}
});
return function(d) {
var node = max[d.color],
l,
r,
x,
y,
i = -1;
if (node == d) return;
x = d.x - node.x;
y = d.y - node.y;
l = Math.sqrt(x * x + y * y);
r = d.radius + node.radius;
if (l != r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
node.x += x;
node.y += y;
}
};
}
function collide(alpha) {
var quadtree = d3.geom.quadtree(nodes);
return function(d) {
var r = d.radius + padding,
nx1 = d.x - r,
nx2 = d.x + r,
ny1 = d.y - r,
ny2 = d.y + r;
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = d.radius + quad.point.radius + (d.color !== quad.point.color) * padding;
if (l < r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2
|| x2 < nx1
|| y1 > ny2
|| y2 < ny1;
});
};
}
};
scatter.js
var m = [30, 10, 10, 10],
w = 500-m[1]-m[3],
h = 400-m[0]-m[2],
xcol = 0,
ycol = 1;
svg = d3.select('#chart')
.append("g")
.attr("transform", "translate(" + m[1] + "," + m[0] + ")");
d3.csv('nutrients.csv', function(data) {
var columns = d3.keys(data[0]),
excluded = ['name', 'group', 'id'];
var dimensions = _(columns)
.difference(excluded);
var extents = _(dimensions)
.map(function(col) {
return [0, d3.max(data, function(d) { return parseFloat(d[col]) })]
});
var x = d3.scale.linear().domain(extents[xcol]).range([0, w]),
y = d3.scale.linear().domain(extents[ycol]).range([h, 0]);
var color = {
"Baby Foods" : '#555555',
"Baked Products" : '#7f7f7f',
"Beverages" : '#c49c94',
"Breakfast Cereals" : '#9467bd',
"Cereal Grains and Pasta" : '#bcbd22',
"Dairy and Egg Products" : '#ff7f0e',
"Ethnic Foods" : '#e7ba52',
"Fast Foods" : '#dbdb8d',
"Fats and Oils" : '#ffbb78',
"Finfish and Shellfish Products" : '#e377c2',
"Fruits and Fruit Juices" : '#c5b0d5',
"Legumes and Legume Products" : '#f7b6d2',
"Meals, Entrees, and Sidedishes" : '#17becf',
"Nut and Seed Products" : '#8c564b',
"Pork Products" : "#00ee99",
"Poultry Products" : '#d62728',
"Restaurant Foods" : '#1f77b4',
"Sausages and Luncheon Meats" : '#ff9896',
"Snacks" : '#9edae5',
"Soups, Sauces, and Gravies" : '#98df8a',
"Spices and Herbs" : '#aec7e8',
"Sweets" : '#c7c7c7',
"Vegetables and Vegetable Products" : '#2ca02c'
};
svg.selectAll('circle')
.data(data)
.enter().append('circle')
.attr("fill", function(d) { return color[d.group]; })
.attr("cx", function(d) { return x(d[dimensions[xcol]]) || 0; })
.attr("cy", function(d) { return y(d[dimensions[ycol]]) || h; })
.attr("r", 2.5);
function xaxis(i) {
x.domain(extents[i]);
svg.selectAll('circle')
.transition()
.duration(1500)
.attr("cx", function(d) { return x(d[dimensions[i]]) || 0; });
};
function yaxis(i) {
y.domain(extents[i]);
svg.selectAll('circle')
.transition()
.duration(1500)
.attr("cy", function(d) { return y(d[dimensions[i]]) || h; })
};
d3.select("#xaxis")
.selectAll("option")
.data(dimensions)
.enter().append("option")
.attr("value", function(d,i) { return i; })
.text(function(d) { return d; })
.each(function(d,i) {
if (i == xcol) d3.select(this).attr("selected", "yes");
});
d3.select("#xaxis")
.on("change", function() { xaxis(this.selectedIndex) });
d3.select("#yaxis")
.selectAll("option")
.data(dimensions)
.enter().append("option")
.attr("value", function(d,i) { return i; })
.text(function(d) { return d; })
.each(function(d,i) {
if (i == ycol) d3.select(this).attr("selected", "yes");
});
d3.select("#yaxis")
.on("change", function() { yaxis(this.selectedIndex) });
window.data = data;
});