Merge branch 'master' of github.com:mbostock/d3

This commit is contained in:
Michael Bostock 2011-02-28 15:05:37 -08:00
Родитель 6b8839eab6 07fe0f5d90
Коммит 32c06207a2
11 изменённых файлов: 155 добавлений и 161 удалений

Просмотреть файл

@ -0,0 +1,20 @@
#chart {
width: 960px;
height: 500px;
}
.black path {
fill: none;
stroke: #ccc;
stroke-width: 3px;
}
.white path {
fill: #fff;
stroke: #fff;
}
.grey path {
fill: #ccc;
stroke: #666;
}

Просмотреть файл

@ -2,86 +2,14 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Non-Contiguous Cartogram</title>
<script type="text/javascript" src="../../d3.js"></script>
<script type="text/javascript" src="../../d3.geo.js"></script>
<script type="text/javascript" src="../../d3.geom.js"></script>
<style type="text/css">
svg {
width: 960px;
height: 500px;
}
.black path {
fill: none;
stroke: #ccc;
stroke-width: 3px;
}
.white path {
fill: #fff;
stroke: #fff;
}
.grey path {
fill: #ccc;
stroke: #666;
}
</style>
<link type="text/css" rel="stylesheet" href="cartogram.css"/>
</head>
<body>
<script type="text/javascript">
var data; // loaded asynchronously
var svg = d3.select("body")
.append("svg:svg");
d3.json("../../data/us-states.json", function(json) {
var path = d3.geo.path();
// Synthesize a random data variable to visualize…
// Note: This has a baked-in sqrt transform!
json.features.forEach(function(f) {
f.properties.value = Math.sqrt(.2 + .8 * Math.random());
});
// A thick black stroke for the exterior.
svg.append("svg:g")
.attr("class", "black")
.selectAll("path")
.data(json.features)
.enter().append("svg:path")
.attr("d", path);
// A white overlay to hide interior black strokes.
svg.append("svg:g")
.attr("class", "white")
.selectAll("path")
.data(json.features)
.enter().append("svg:path")
.attr("d", path);
// The polygons, scaled!
svg.append("svg:g")
.attr("class", "grey")
.selectAll("path")
.data(json.features)
.enter().append("svg:path")
.attr("transform", function(d) {
var centroid = path.centroid(d),
x = centroid[0],
y = centroid[1];
return "translate(" + x + "," + y + ")"
+ "scale(" + d.properties.value + ")"
+ "translate(" + -x + "," + -y + ")";
})
.attr("stroke-width", function(d) { return 1 / d.properties.value; })
.attr("d", path);
});
</script>
<div id="chart"></div>
<script type="text/javascript" src="cartogram.js"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,48 @@
var data; // loaded asynchronously
var svg = d3.select("#chart")
.append("svg:svg");
d3.json("us-states.json", function(json) {
var path = d3.geo.path();
// Synthesize a random data variable to visualize…
// Note: This has a baked-in sqrt transform!
json.features.forEach(function(f) {
f.properties.value = Math.sqrt(.2 + .8 * Math.random());
});
// A thick black stroke for the exterior.
svg.append("svg:g")
.attr("class", "black")
.selectAll("path")
.data(json.features)
.enter().append("svg:path")
.attr("d", path);
// A white overlay to hide interior black strokes.
svg.append("svg:g")
.attr("class", "white")
.selectAll("path")
.data(json.features)
.enter().append("svg:path")
.attr("d", path);
// The polygons, scaled!
svg.append("svg:g")
.attr("class", "grey")
.selectAll("path")
.data(json.features)
.enter().append("svg:path")
.attr("transform", function(d) {
var centroid = path.centroid(d),
x = centroid[0],
y = centroid[1];
return "translate(" + x + "," + y + ")"
+ "scale(" + d.properties.value + ")"
+ "translate(" + -x + "," + -y + ")";
})
.attr("stroke-width", function(d) { return 1 / d.properties.value; })
.attr("d", path);
});

Просмотреть файл

@ -0,0 +1 @@
../../data/us-states.json

Просмотреть файл

@ -178,6 +178,7 @@ function drag(n) {
var m = d3.svg.mouse(vis[0][0]);
active.x = m[0];
active.y = m[1];
force.resume(); // restart annealing
});
return false;
@ -221,8 +222,7 @@ function init() {
.nodes(net.nodes)
.links(net.links)
.size({x: w, y: h})
.nodeDistance(100)
.linkDistance(60)
.distance(60)
.start();
hullg.selectAll("path.hull").remove();

Просмотреть файл

@ -1,9 +1,9 @@
circle.node {
fill: lightsteelblue;
stroke: steelblue;
stroke: #fff;
stroke-width: 1.5px;
}
line.link {
stroke: #333;
stroke: #999;
stroke-opacity: .6;
}

Просмотреть файл

@ -1,5 +1,6 @@
var w = 960,
h = 500;
h = 500,
fill = d3.scale.category20();
var vis = d3.select("#chart")
.append("svg:svg")
@ -28,7 +29,8 @@ d3.json("miserables.json", function(json) {
.attr("class", "node")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", 4.5);
.attr("r", 5)
.style("fill", function(d) { return fill(d.group); });
vis.attr("opacity", 0)
.transition()

Просмотреть файл

@ -3,85 +3,53 @@ function layout_force() {
var force = {},
event = d3.dispatch("tick"),
size = {x: 1, y: 1},
alpha = .1,
nodeDistance = 60,
linkDistance = 30,
alpha = .5,
distance = 30,
interval,
nodes,
links;
// TODO
// slow the interval as the graph stabilizes
// allow the nodes to be dragged interactively
links,
distances;
function tick() {
var n = nodes.length,
m = links.length,
var n = distances.length,
i, // current index
j, // current index
o, // current link
s, // current source
t, // current target
l, // current distance
x,
y;
x, // x-distance
y; // y-distance
// repel nodes
// gauss-seidel relaxation
for (i = 0; i < n; ++i) {
s = nodes[i];
for (j = i + 1; j < n; ++j) {
t = nodes[j];
x = t.x - s.x;
y = t.y - s.y;
l = Math.sqrt(x * x + y * y);
if (l < nodeDistance) {
l = alpha * (l - nodeDistance) / l;
x *= l;
y *= l;
if (s.fixed) {
if (t.fixed) continue;
t.x -= x;
t.y -= y;
} else if (t.fixed) {
s.x += x;
s.y += y;
} else {
s.x += x;
s.y += y;
t.x -= x;
t.y -= y;
}
}
}
}
// position constraint for links
for (i = 0; i < m; ++i) {
o = links[i];
o = distances[i];
s = o.source;
t = o.target;
x = t.x - s.x;
y = t.y - s.y;
l = Math.sqrt(x * x + y * y);
if (l <= 0) l = 0.01;
l = alpha * (l - linkDistance) / l;
x *= l;
y *= l;
if (s.fixed) {
if (t.fixed) continue;
t.x -= x;
t.y -= y;
} else if (t.fixed) {
s.x += x;
s.y += y;
} else {
s.x += x;
s.y += y;
t.x -= x;
t.y -= y;
if (l = Math.sqrt(x * x + y * y)) {
l = alpha / (o.distance * o.distance) * (l - distance * o.distance) / l;
x *= l;
y *= l;
if (s.fixed) {
if (t.fixed) continue;
t.x -= x;
t.y -= y;
} else if (t.fixed) {
s.x += x;
s.y += y;
} else {
s.x += x;
s.y += y;
t.x -= x;
t.y -= y;
}
}
}
// simulated annealing, basically
if ((alpha *= .99) < 1e-6) force.stop();
event.tick.dispatch({type: "tick"});
}
@ -108,44 +76,75 @@ function layout_force() {
return force;
};
force.nodeDistance = function(d) {
if (!arguments.length) return nodeDistance;
nodeDistance = d;
return force;
};
force.linkDistance = function(d) {
if (!arguments.length) return linkDistance;
linkDistance = d;
force.distance = function(d) {
if (!arguments.length) return distance;
distance = d;
return force;
};
force.start = function() {
var i,
j,
k,
n = nodes.length,
m = links.length,
w = size.x,
h = size.y,
o;
var paths = [];
for (i = 0; i < n; ++i) {
o = nodes[i];
o.x = o.x || Math.random() * w;
o.y = o.y || Math.random() * h;
o.fixed = 0;
paths[i] = [];
for (j = 0; j < n; ++j) {
paths[i][j] = Infinity;
}
paths[i][i] = 0;
}
for (i = 0; i < m; ++i) {
o = links[i];
paths[o.source][o.target] = 1;
paths[o.target][o.source] = 1;
o.source = nodes[o.source];
o.target = nodes[o.target];
}
// Floyd-Warshall
for (k = 0; k < n; ++k) {
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
paths[i][j] = Math.min(paths[i][j], paths[i][k] + paths[k][j]);
}
}
}
distances = [];
for (i = 0; i < n; ++i) {
for (j = i + 1; j < n; ++j) {
distances.push({
source: nodes[i],
target: nodes[j],
distance: paths[i][j] * paths[i][j]
});
}
}
distances.sort(function(a, b) {
return a.distance - b.distance;
});
if (interval) clearInterval(interval);
interval = setInterval(tick, 24);
return force;
};
force.resume = function() {
if (interval) clearInterval(interval);
interval = setInterval(tick, 24);
alpha = .1;
if (!interval) interval = setInterval(tick, 24);
return force;
};

Просмотреть файл

@ -11,6 +11,7 @@
<li><a href="bar/bar.html">bar</a></li>
<li><a href="calendar/dji.html">calendar-dji</a></li>
<li><a href="calendar/vix.html">calendar-vix</a></li>
<li><a href="cartogram/cartogram.html">cartogram</a></li>
<li><a href="choropleth/choropleth.html">choropleth</a></li>
<li><a href="chord/chord.html">chord</a></li>
<li><a href="contour/contour.html">contour</a></li>

Просмотреть файл

@ -2,11 +2,6 @@
font: 10px sans-serif;
}
rect {
shape-rendering: crispEdges;
}
line {
stroke: black;
shape-rendering: crispEdges;
}

Просмотреть файл

@ -5,7 +5,7 @@ var n = 4, // number of layers
var p = 20,
w = 960,
h = 500 - p,
h = 500 - .5 - p,
mx = m,
my = d3.max(data, function(d) {
return d3.max(d, function(d) {