Skip to content

Instantly share code, notes, and snippets.

@sabman
Last active June 28, 2017 11:15
Show Gist options
  • Save sabman/5564051 to your computer and use it in GitHub Desktop.
Save sabman/5564051 to your computer and use it in GitHub Desktop.
Using DViz.js to visualize data on ActiveAdmin Dashboard https://github.com/akngs/dviz

Using DViz.js with ActiveAdmin (Rails)

At https://BringBee.ch we have an internal ActiveAdmin App that we use to keep tabs on the recent activity. It's dashboard could do with some pretty graphs showing the stats of orders processed each week.

Today I ran across https://github.com/akngs/dviz so I decided to give it a spin. What follows is not by any means best practice but it got the results I wanted. The steps were pretty simple:

Get the source

in your vendor/assets/javascripts:

$ wget http://akngs.github.io/js/dviz.js  
$ wget http://d3js.org/d3.v2.min.js

and vendor/assets/stylesheets:

$ wget http://akngs.github.io/css/dviz.css

Configure active Admin

in config/initializers/active_admin.rb add:

  # To load a stylesheet:
  config.register_stylesheet 'dviz.css'

  # To load a javascript file:
  config.register_javascript 'd3.v2.min.js'
  config.register_javascript 'dviz.js'

in your app/admin/dashboard.rb add:

script(type: "text/javascript") do
  "$(function() {dviz.run();});"
end

In production add the js to precompile list in config/environments/production.rb

config.assets.precompile += %w( active_admin.css active_admin.js dviz.css dviz.js d3.v2.min.js )

Get, Transform and Show the data

We when we process our orders at BringBee we store their state. They go from being listed (awaiting_pickup) to being delivered (awaiting_payment) and finally being closed.

To show the data I grouped the data for each state by week using the following SQL. Then re-grouped the data by week so that I could create a CSV that contained rows with "weeks" and columns with the number or orders in each state. Something like:

week, state1, state2, state3
W12, 2, 1, 4 
W13, 2, 2, 5 
W14, 1, 1, 3
# SQL to grab data
results = BringbeeBaseModel.connection.execute( "SELECT
  date_part('year', o.created_at) AS year,
  date_part('week', o.created_at) AS week,
  o.state, COUNT(*)
  FROM (SELECT * from orders WHERE created_at > '#{12.weeks.ago.utc.to_s(:db)}') AS o
  GROUP BY year, week, state;")

# Transform data to CSV
weeks = {}

results.collect do |row|
  weeks[row["week"].to_i] ||= {}
  weeks[row["week"].to_i].merge!( {row["state"] => row["count"]} )
end

states_of_interest = BringbeeBaseModel.connection.execute(
  "select distinct(state) from orders").collect { |rec| rec["state"] }

data = weeks.sort.collect do |week|
  "W#{week[0]}, " +states_of_interest.collect{ |state| week[1][state]||0 }.join(", ")
end

data.prepend("Week, #{states_of_interest.join(', ')}")

# show the data
div class: "dviz-content" do
  strong "Orders per week (12 Weeks):"
  para do
    "<code>
    #{data.join("\n")}
    </code>\n<p><code>(@column {isStacked:true})</code></p>".html_safe
  end
end

To show the graph you need to place everything in a div of class dviz-content. put the csv in a code tag followed by another code tag with (@column {isStacked:true}) in it.

<div class='dviz-content'>
  <code>
    week, state1, state2, state3
    W12, 2, 1, 4 
    W13, 2, 2, 5 
    W14, 1, 1, 3
  </code>
  <code>(@column {isStacked:true})</code>
</div>

Graph

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment