syntax.us Let the syntax do the talking
Blog Contact Posts Questions Tags Hire Me

Question:
In Rails how do I use D3.js to plot CSV file?

Most Rails use-cases which require the serving of data from a data-store, result in me connecting my Rails app to a database server like Postgres.

Sometimes though the data-store is a CSV file rather than a database.

I can think of two ways to deal with this.

One way is to copy the CSV data into a database and then connect Rails to the database.

This post describes another way, which is to serve the data directly from the CSV file.

I start the demo by creating a new Rails app on my laptop:
cd /tmp/
rails new d3plot -d postgresql
cd d3plot
sed -i '1a gem "rails_12factor","0.0.3"' Gemfile
sed -i '1a gem "thin",          "1.6.3"' Gemfile
sed -i '1a gem "haml-rails",    "0.5.3"' Gemfile
sed -i '1a gem "haml",          "4.0.5"' Gemfile
sed -i '1a ruby "2.1.5"'                 Gemfile
bundle install
bundle binstub thin
bin/rails g controller charts eur_usd
bin/rake db:create
bin/rake db:migrate
bin/thin -p 3004 start
Next, I create the CSV file. I call it small.csv and put it in /tmp/d3plot/db/:
dan@hp ~ $
dan@hp ~ $ cd /tmp/d3plot/db/
dan@hp /tmp/d3plot/db $
dan@hp /tmp/d3plot/db $ vi small.csv
dan@hp /tmp/d3plot/db $
dan@hp /tmp/d3plot/db $ cat small.csv
1241136000,1.325
1241136300,1.329
1241136600,1.320
1241136900,1.325
1241137200,1.327
1241137500,1.329
1241137800,1.323
1241138100,1.320
1241138400,1.326
1241138700,1.320
dan@hp /tmp/d3plot/db $
dan@hp /tmp/d3plot/db $
HAML is a great DSL syntax for Rails demos. I use it to act as a container of different interpreted languages. It cannot support a heavy request load but it can really shine when I use it to serve prototypes. The page you are reading now is written in HAML.

So for this demo, I work on the HAML file which I use to glue together several types of syntax:
  • HTML
  • CSS
  • Ruby
  • Javascript
  • D3.js


The HAML file I want to work with was generated for me when I used a bin/rails command above to create the charts controller.

When I started on the file, it looked like this:

%h1 Charts#eur_usd
%p Find me in app/views/charts/eur_usd.html.haml
I enhanced it:
%h1 Charts#eur_usd
%p Find me in app/views/charts/eur_usd.html.haml

%link(href='/myassets/rickshaw.css' rel='stylesheet' type='text/css')
%script(src='/myassets/d3.min.js')
%script(src='/myassets/rickshaw.min.js' type='text/javascript')
%script(src='/myassets/Rickshaw.Graph.Axis.Time.js' type='text/javascript')

:css
  #chart_container_eur_usd {
          margin-top: 21px;
          position: relative;
          font-family: Arial, Helvetica, sans-serif;
  }
  #chart_eur_usd {
          position: relative;
          left: 40px;
          background-color: white;
          width: 600px;
  }
  #chart_y_axis_eur_usd {
          position: absolute;
          top: 0;
          bottom: 0;
          width: 40px;
  }

#chart_container_eur_usd
  #chart_y_axis_eur_usd
  #chart_eur_usd

:ruby
  require 'csv'
  csvrows = CSV.read("#{Rails.root}/db/small.csv")
  @rows4json = csvrows.map{|row| {:x =>row[0],:y =>row[1]} }

:javascript
  var my_hardcoded_data = [{x:1241136000,y:1.325},{x:1241136300,y:1.329}]

  var mydata = #{@rows4json.to_json.gsub(/"/,'').sub(/"/,'')}

  var graph = new Rickshaw.Graph( {
    element: document.querySelector("#chart_eur_usd"),
    min: 1.310,
    max: 1.340,
    renderer: 'line',
    interpolation: 'linear',
    width: 600,
    height: 400,
    series: [{
      color: 'darkgreen',
      data: mydata
      }]
  });

  var x_axis_eur_usd = new Rickshaw.Graph.Axis.Time( { graph: graph } );

  var chart_y_axis_eur_usd = new Rickshaw.Graph.Axis.Y( {
    graph: graph,
    orientation: 'left',
    tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
    element: document.getElementById('chart_y_axis_eur_usd'),
  } );

  graph.render();
  // end of :javascript

Then, I copied files into /tmp/d3plot/public/myassets/
dan@hp /tmp/d3plot $ 
dan@hp /tmp/d3plot $ 
dan@hp /tmp/d3plot $ cd public/
dan@hp /tmp/d3plot/public $ 
dan@hp /tmp/d3plot/public $ mkdir -p myassets
dan@hp /tmp/d3plot/public $ 
dan@hp /tmp/d3plot/public $ cd myassets/
dan@hp /tmp/d3plot/public/myassets $ 
dan@hp /tmp/d3plot/public/myassets $ wget https://github.com/mbostock/d3/releases/download/v3.5.2/d3.zip

dan@hp /tmp/d3plot/public/myassets $ 
dan@hp /tmp/d3plot/public/myassets $ 
dan@hp /tmp/d3plot/public/myassets $ unzip d3.zip
Archive:  d3.zip
  inflating: LICENSE                 
  inflating: d3.js                   
  inflating: d3.min.js               
dan@hp /tmp/d3plot/public/myassets $ 
dan@hp /tmp/d3plot/public/myassets $ 

dan@hp /tmp/d3plot/public/myassets $ 
dan@hp /tmp/d3plot/public/myassets $ 

dan@hp /tmp/d3plot/public/myassets $ unzip master.zip 
Archive:  master.zip
a240899625c2d83961b3e682cd77ab8e5199a866
   creating: rickshaw-master/
snip ...

dan@hp /tmp/d3plot/public/myassets $ 
dan@hp /tmp/d3plot/public/myassets $ cp rickshaw-master/rickshaw.css .
dan@hp /tmp/d3plot/public/myassets $ cp rickshaw-master/rickshaw.min.js .
dan@hp /tmp/d3plot/public/myassets $ cp rickshaw-master/src/js/Rickshaw.Graph.Axis.Time.js .
dan@hp /tmp/d3plot/public/myassets $ 
dan@hp /tmp/d3plot/public/myassets $ 


Next, I visited the HAML page with my browser: localhost:3004/charts/eur_usd I saw this:

Then, I deployed it to heroku.
cd /tmp/d3plot/
git init .
git add .
git commit hi
heroku apps:create d3plot
git push heroku master
Now, we can see it here:

http://d3plot.herokuapp.com/charts/eur_usd


syntax.us Let the syntax do the talking
Blog Contact Posts Questions Tags Hire Me