A d3 experiment on my Tinkerer blog

This blog uses Tinkerer, which is based on the Sphinx documentation framework, to create static html pages from rest (rst) markup. If you are familiar with the Python world you’ve probably created documentation using Sphinx, or at the very least, you have read documenation created in Sphinx. Because the setup is Python-focused, it is not straightforward to write posts that employ javascript libraries like d3. This post describes my method for doing javascript examples in Tinkerer blog posts or Sphinx docs, as well as how to do some d3.

Raw javascript

First, let’s consider a simple javascript example without using d3. I will create a html-div as well as two buttons that use javascript to insert some text. In the rst markup the div and buttons are created using

.. raw:: html

    <div id="js_ex"
         style="padding: 20px 0px;">

      <p id="js_ex_text"
         style="padding: 10px; background: #111; color: #eee;">
         -- click write and clear ---
      </p>

      <button id="js_ex_write">
       write
      </button>
      <button id="js_ex_clear">
       clear
      </button>
    </div>

The result of the above code is shown below:

-- click write and clear ---

The raw:: html tag in the rst markup makes Tinkerer/Sphinx insert the html into the document. Next, we can use javascript to change the text using some click events. In the rst document I have:

.. raw:: html

    <script type='text/javascript'>
      p = document.getElementById('js_ex_text');

      buttonWrite = document.getElementById('js_ex_write');
      buttonWrite.onclick = function() {
        p.innerHTML = 'Hello <strong>js</strong> world!';
      };

      buttonClear = document.getElementById('js_ex_clear');
      buttonClear.onclick = function() {
        p.innerHTML = ' -- nothing here, click write --';
      };
    </script>

Notice that the raw:: html tag is used again and the javascript is surrounded by the <script></script> tags – just as you would have to do in normal, inline html markup.

Okay, now let’s integrate some d3 into a Tinkerer post or Sphinx document.

Using d3

Linking d3

The first step in using d3 is to link to the library. I’m sure there are a variety of ways to do this, but I chose to link to the library on all pages – if you have a slick way to link per page/post please leave a comment below!

Given this choice, there is a standard way to add external javascript files – see Enabling Google Analytics for an example of adding google analytics js to a Tinkerer blog. In my case, I added d3.min.js (you can get the latest version here: d3 at github) to the _static directory and modified the page.html template in my theme – see page template example – to include the following:

{%- extends "layout.html" -%}

{% set script_files = script_files + ["_static/d3.min.js"] %}

This tells Tinkerer to link the d3.min.js in the header of each page. If you are not working with a theme, create a directory _templates and add the file page.html with the above content. The organization would be something like this (where conf.py and master.rst are in the base directory of the blog):

├── conf.py
├── master.rst
├── _static
│   ├── d3.min.js
├── _templates
    ├── page.html

That should work as well.

Using d3 in a post

Finally, here’s a little experiment using d3 that is motivated by the classic three little circles example. As with the simple javascript example we have to setup an html-div that will be used:

.. raw:: html

   <div id='vizdiv' style="padding: 20px 0px;">
   </div>

Let’s put it here:

Next, we use the following d3 code to draw some circles using data:

var data = [{r: 5, cy: 100, cx: 100},
            {r: 10, cy: 100, cx: 200},
            {r: 15, cy: 100, cx: 300}];

var root = d3.select('#vizdiv').append('svg')
    .attr('width', 400)
    .attr('height', 200);

root.selectAll('circle')
    .data(data).enter()
  .append('circle')
    .attr('r', function(d) {return d.r;})
    .attr('cx', function(d) {return d.cx;})
    .attr('cy', function(d) {return d.cy;})
    .attr('fill', 'steelblue');

In the rst markup for the post, this actually has to look like this:

.. raw:: html

   <script type='text/javascript'>
   var data = [{r: 5, cy: 100, cx: 100},
               {r: 10, cy: 100, cx: 200},
               {r: 15, cy: 100, cx: 300}];

   var root = d3.select('#vizdiv').append('svg')
       .attr('width', 400)
       .attr('height', 200);

   root.selectAll('circle')
       .data(data).enter()
     .append('circle')
       .attr('r', function(d) {return d.r;})
       .attr('cx', function(d) {return d.cx;})
       .attr('cy', function(d) {return d.cy;})
       .attr('fill', 'steelblue');
   </script>

Notice that we have to use raw:: html and the <script></script> tags!

Okay, that’s it. Now I’m setup to talk more about javascript and d3 on the blog – very nice! If you have other ways to do this, again, please leave a comment!

Tags

api [1]   arduino [1]   audio [2]   audio features [1]   babel [1]   Bayesian [7]   Beta [1]   blog setup [1]   bootstrap [1]   bottleneck [1]   c++ [1]   caret [1]   cmpy [1]   conditional probability [6]   coursera [1]   coursera intro to data science [3]   css [1]   cython [1]   d3 [2]   decision trees [2]   diy [1]   dropbox [1]   dsp [1]   e1071 [1]   essentia [1]   garmin [1]   geojson [1]   ggplot2 [1]   gis [2]   git [1]   gnuplot [1]   graphs [1]   html5 [1]   igraph [1]   ipython [1]   javascript [7]   joint probability [6]   json [1]   LaTeX [2]   LDA [1]   Lea [2]   machine learning [3]   marginal probability [6]   matplotlib [1]   meteor [2]   mir [1]   MongoDB [3]   music [2]   my python setup [5]   my ubuntu setup [10]   mysql [3]   networks [1]   networkx [1]   nodejs [5]   npm [3]   numexpr [1]   numpy [1]   octave [1]   Open Oakland [2]   openpyxl [1]   pandas [3]   patsy [1]   pip [2]   pweave [1]   pygraphviz [1]   pymc [1]   PySoundFile [2]   python [15]   Python [1]   python 2.7 [5]   python 3.4 [2]   pyyaml [1]   qgis [1]   R [1]   randomForest [1]   restview [1]   resume [1]   rpart [1]   running [1]   scikit-learn [3]   scipy [1]   screen [1]   server setup [1]   shapefile [1]   social networks [1]   Socrata [1]   sound [2]   sphinx [1]   sql [4]   sqlite3 [1]   ssh [1]   ssh keys [1]   statsmodels [1]   supervised learning [2]   sympy [1]   tableau [1]   tinkerer [2]   topic models [1]   tree [1]   ubuntu 14.04 [13]   Ubuntu 14.04 [3]   ubuntu 16.04 [4]   vim [2]   virtualbox [1]   virtualenv [4]   virtualenvwrapper [3]   VPS [1]   vundle [1]   webpack [1]   yaml [1]