Declarative web data visualization using ClojureScript

5,128 views
4,459 views

Published on

Published in: Technology

Declarative web data visualization using ClojureScript

  1. Declarative web data visualization using ClojureScript Kevin Lynagh 2012 July 20 Keming Labs @lynaghk OSCONFriday, July 20, 12
  2. AgendaFriday, July 20, 12
  3. 1 ? Agenda What is VisualizationFriday, July 20, 12
  4. Agenda 2Friday, July 20, 12 doin’ it on the Internets
  5. Agenda 3Friday, July 20, 12 an Example
  6. Agenda Why 4Friday, July 20, 12 (not) Clojure
  7. Anti-Agenda 0 Tech Talk ideasFriday, July 20, 12
  8. Friday, July 20, 12
  9. 1 ? What is VisualizationFriday, July 20, 12
  10. BioinformaticsFriday, July 20, 12
  11. Wind energyFriday, July 20, 12
  12. Doc & patient, meet DataFriday, July 20, 12
  13. Friday, July 20, 12
  14. Friday, July 20, 12
  15. (didn’t make this, just ♥ it)Friday, July 20, 12
  16. ? What do these things have in commonFriday, July 20, 12
  17. DataFriday, July 20, 12 Visual
  18. Data: [17, 26, 53, 96] 0 25 50 75 100Friday, July 20, 12
  19. Data: [[1, 2] [3, 4] [5, 5] [6, 8] [8, 13] [9, 16] [11, 18]] 20 15 10 5 0 0 3 6 9 12 15Friday, July 20, 12
  20. Agenda 2Friday, July 20, 12 doin’ it on the Internets
  21. D3: Data Driven Documents (2011) Mike Bostock Jeffrey Heer Vadim Ogievetsky +Friday, July 20, 12
  22. D3 (JavaScript) d3.select("body").selectAll("div")   .data([17, 26, 53, 96])   .enter().append("div")   .style("width", function(d){d+"px";}); DOMFriday, July 20, 12
  23. Awesome Declarative Easy to think, explore Optimizable Familiar representation HTML, CSS, SVG; dev tools No reinvented wheelsFriday, July 20, 12
  24. Awesomer Clojure(Script) Rich data structures Namespaces Deliberate state/mutationFriday, July 20, 12
  25. Clojure PhilosophyFriday, July 20, 12
  26. Treat your data like Data It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures. Alan PerlisFriday, July 20, 12
  27. D3 (JavaScript) d3.select("body").selectAll("div")   .data([17, 26, 53, 96])   .enter().append("div")   .style("width", function(d){d+"px";});Friday, July 20, 12
  28. D3 (JavaScript) d3.select("body").selectAll("div")   .data([17, 26, 53, 96])   .enter().append("div")   .style("width", function(d){d+"px";});Friday, July 20, 12
  29. D3 (JavaScript) d3.select("body").selectAll("div")   .data([17, 26, 53, 96])   .enter().append("div")   .style("width", function(d){d+"px";}); Can we do better?Friday, July 20, 12
  30. Agenda 3Friday, July 20, 12 an Example
  31. Friday, July 20, 12
  32. Friday, July 20, 12
  33. Start with your data [{:flight-no 2, :price 106, :carrier "Alaska" :depart 16.91, :arrive 21.42} {:flight-no 1, :price 190, :carrier "United" :depart 6.20, :arrive 10.87} {:flight-no 5, :price 213, :carrier "United" :depart 4.73, :arrive 9.48} ... ]Friday, July 20, 12
  34. Friday, July 20, 12
  35. Friday, July 20, 12
  36. (unify! "#chart" flight-data (fn [{:keys [price carrier depart arrive]} idx] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  37. (unify! "#chart" flight-data (fn [{:keys [price carrier depart arrive]} idx] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  38. (unify! "#chart" flight-data (fn [{:keys [price carrier depart arrive]} idx] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  39. (unify! "#chart" flight-data (fn [{:keys [price carrier depart arrive]} idx] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  40. (unify! "#chart" flight-data (fn(let [time-scale carrier depart :domain [0 24] [{:keys [price (scale/linear arrive]} idx] [:div.row :range :percent)] [:button.price (str "$" price)] [:div.flight ;=> “0%” (time-scale 0) {:style {:left (time-scale depart) (time-scale 12) ;=> “50%” :width (time-scale (- arrive depart))} (time-scale 24) ;=> “100%” ) :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  41. (unify! "#chart" flight-data (fn [{:keys [price carrier depart arrive]} idx] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  42. (unify! "#chart" flight-data (fn [{:keys [price carrier depart arrive]} idx] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  43. (unify! "#chart" flight-data (fn [{:keys [price carrier depart arrive]} idx] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  44. (unify! "#chart" flight-data (fn [{:keys [price carrier depart arrive]} idx] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  45. (unify! "#chart" flight-data (fn [{:keys [price carrier depart arrive]}] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  46. (map flight-data (fn [{:keys [price carrier depart arrive]}] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  47. (map flight-data (fn [{:keys [price carrier depart arrive]}] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]]))Friday, July 20, 12
  48. C2 http://keminglabs.com/c2 http://github.com/lynaghk/c2Friday, July 20, 12
  49. Advantages of the dataapproachFriday, July 20, 12
  50. Declarative (fn [{:keys [price carrier depart arrive]}] [:div.row [:button.price (str "$" price)] [:div.flight {:style {:left (time-scale depart) :width (time-scale (- arrive depart))} :carrier carrier} [:span carrier]]])Friday, July 20, 12
  51. Declarative (fn [{:keys [price carrier depart arrive]}] [:div.row [:button.price (str "$" price)] [:div.flight {:style (flight-style depart arrive) :carrier carrier} [:span carrier]]])Friday, July 20, 12
  52. Declarative (fn [{:keys [price carrier depart arrive]}] [:div.row [:button.price (str "$" price)] [:div.flight {:style (merge {:background-color "blue"} (flight-style depart arrive)) :carrier carrier} [:span carrier]]])Friday, July 20, 12
  53. De co 1) construction 2) rendering upleFriday, July 20, 12 d
  54. Agenda Why 4Friday, July 20, 12 (not) Clojure
  55. Why Clojure OpinionatedFriday, July 20, 12 & Sane
  56. Why Clojure Runtimes: JVM JavaScript CLR Lua CFriday, July 20, 12
  57. NotFriday, July 20, 12 Clojure
  58. Why not Clojure WTF is Clojure?Friday, July 20, 12
  59. Why not Clojure Clojure is the #23 most popular language on GitHubFriday, July 20, 12
  60. Why not Clojure Assembly is the #18 most popular language on GitHubFriday, July 20, 12
  61. Why not Clojure 900+ forksFriday, July 20, 12
  62. Friday, July 20, 12
  63. Kevin Lynagh Keming Labs @lynaghkFriday, July 20, 12

×