Day46: Editing D3

Posted by csiu on April 11, 2017 | with: 100daysofcode,

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 (reflective of his work) – as the first thing one notices when they come across his page.

I want to do something similar for my personal website.

The Jupyter Notebook for this little project is found here.

Editor for D3

Before I begin, I want an interactive development environment (IDE) for D3. In my search I came across the following:

IDE My rating
Tributary Simple, but no capability for customizing HTML/CSS
D3.js playground - easy to use
JSFiddle - easy to use and looks nice

I also came across embedding D3 in Jupyter Notebooks with py_d3.

  • 1. Install py_d3 with pip install py_d3
  • 2. Run %load_ext py_d3 in Jupyter Notebook for block magic
%load_ext py_d3
  • 3. Include D3 script:
%%d3
<script src="https://d3js.org/d3.v3.js"></script>

Alternatively, it seems you can use IPython.core.display (see “IPython and Jupyter Notebook with embedded D3.js”) to embed D3 in Jupyter Notebooks.


Example 01: Hello world

%%d3

<div></div>

<script>
d3.select("div").text("Hello world")
</script>

Example 02: Simple rectangle

%%d3

<g></g>

<script>
    d3.select("g").append("svg").append("rect")
      .attr("x", 150)
      .attr("y", 50)
      .attr("width", 50)
      .attr("height", 140);
</script>

Example 03: Using functions, adding style, and making polygons

%%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>

Kink with using Jupyter Notebook

When I load the Collision Detection example by Mike Bostock in the Jupyter Notebook, it doesn’t work i.e. nothing is rendered (see notebook). However, using the same example in JSFiddle it works. Thus, I’ll probably use JSFiddle for major future D3 developments.