While reflecting on the state of my GitHub repos yesterday, I was thinking how cool things would be if I used D3.
Previously I came across Mike Irvine's personal website and I really like how he made the dynamic D3 visual, showcasing the spread of disease in a community (ie. related to his work), as the first thing one notices when they come across his page.
I want to do something similar for my personal website.
Before I begin, I want an interactive development environment (IDE) for D3. In my search I came across the following:
| IDE | Rating |
|---|---|
| D3.js playground | |
| Tributary | |
| JSFiddle |
I also came across embedding D3 in Jupyter Notebooks with py_d3.
pip install py_d3%load_ext py_d3 in Jupyter Notebook for Jupyter notebook D3 block magic
In [1]:
%load_ext py_d3
Include D3 script:
In [2]:
%%d3
<script src="https://d3js.org/d3.v3.js"></script>
In [4]:
%%d3
<div></div>
<script>
d3.select("div").text("Hello world")
</script>
In [5]:
%%d3
<g></g>
<script>
d3.select("g").append("svg").append("rect")
.attr("x", 150)
.attr("y", 50)
.attr("width", 50)
.attr("height", 140);
</script>
In [6]:
%%d3
<g></g>
<script>
function CalculateStarPoints(centerX, centerY, arms, outerRadius, innerRadius) {
var results = "";
var angle = Math.PI / arms * 2;
for (var i = 0; i < 2 * arms; i++) {
var r = (i & 1) == 0 ? outerRadius : innerRadius;
var pointX = centerX + Math.cos(i * angle) * r;
var pointY = centerY + Math.sin(i * angle) * r;
// Our first time we simply append the coordinates, subsequet times
// we append a ", " to distinguish each coordinate pair.
if (i == 0) {
results = pointX + "," + pointY;
} else {
results += ", " + pointX + "," + pointY;
}
}
return results;
}
d3.select("g").append("svg")
.append("polygon")
.attr("visibility", "visible")
.attr("points", CalculateStarPoints(100, 100, 5, 30, 15));
d3.select("g").append("svg")
.append("polygon")
.attr("visibility", "visible")
.attr("points", CalculateStarPoints(100, 100, 5, 30, 15))
.style("fill", "lime")
.style("stroke", "purple")
.style("stroke-width", "5")
.style("fill-rule","evenodd");
</script>
When I load the Collision Detection example by Mike Bostock in the Jupyter Notebook, it doesn't work. Nothing is rendered (see following). However, this is not an issue with JSFiddle.
In [7]:
%%d3
<script src="https://d3js.org/d3.v3.js"></script>
This example is modified from <a href="https://bl.ocks.org/mbostock/3231298">https://bl.ocks.org/mbostock/3231298</a>
<body></body>
<script>
var width = 500,
height = 500;
var nodes = d3.range(200).map(function() {
return {
radius: Math.random() * 12 + 4
};
}),
root = nodes[0],
color = d3.scale.category10();
root.radius = 0;
root.fixed = true;
var force = d3.layout.force()
.gravity(0.05)
.charge(function(d, i) {
return i ? 0 : -1500;
})
.nodes(nodes)
.size([width, height]);
force.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.selectAll("circle")
.data(nodes.slice(1))
.enter().append("circle")
.attr("r", function(d) {
return d.radius;
})
.style("fill", function(d, i) {
return color(i % 3);
});
force.on("tick", function(e) {
var q = d3.geom.quadtree(nodes),
i = 0,
n = nodes.length;
while (++i < n) q.visit(collide(nodes[i]));
svg.selectAll("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
});
svg.on("mousemove", function() {
var p1 = d3.mouse(this);
root.px = p1[0];
root.py = p1[1];
force.resume();
});
function collide(node) {
var r = node.radius + 16,
nx1 = node.x - r,
nx2 = node.x + r,
ny1 = node.y - r,
ny2 = node.y + r;
return function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = node.radius + quad.point.radius;
if (l < r) {
l = (l - r) / l * .5;
node.x -= x *= l;
node.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
};
}
</script>