hyper-d3 1.0.0.lap23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +313 -0
  5. data/README.md +118 -0
  6. data/Rakefile +31 -0
  7. data/hyper-d3.gemspec +27 -0
  8. data/lib/d3.rb +68 -0
  9. data/lib/d3/arc.rb +29 -0
  10. data/lib/d3/area.rb +53 -0
  11. data/lib/d3/axis.rb +79 -0
  12. data/lib/d3/band_scale.rb +30 -0
  13. data/lib/d3/collections.rb +9 -0
  14. data/lib/d3/color.rb +76 -0
  15. data/lib/d3/color_schemes.rb +34 -0
  16. data/lib/d3/continuous_scale.rb +60 -0
  17. data/lib/d3/creator.rb +11 -0
  18. data/lib/d3/curve.rb +74 -0
  19. data/lib/d3/dsv.rb +103 -0
  20. data/lib/d3/ease.rb +319 -0
  21. data/lib/d3/format.rb +95 -0
  22. data/lib/d3/histograms.rb +46 -0
  23. data/lib/d3/interpolate.rb +125 -0
  24. data/lib/d3/line.rb +27 -0
  25. data/lib/d3/map.rb +48 -0
  26. data/lib/d3/misc.rb +15 -0
  27. data/lib/d3/native.rb +112 -0
  28. data/lib/d3/nest.rb +100 -0
  29. data/lib/d3/ordinal_scale.rb +39 -0
  30. data/lib/d3/path.rb +24 -0
  31. data/lib/d3/pie.rb +25 -0
  32. data/lib/d3/point_scale.rb +27 -0
  33. data/lib/d3/polygon.rb +18 -0
  34. data/lib/d3/quadtree.rb +89 -0
  35. data/lib/d3/quantile_scale.rb +19 -0
  36. data/lib/d3/quantize_scale.rb +20 -0
  37. data/lib/d3/radial_area.rb +55 -0
  38. data/lib/d3/radial_line.rb +27 -0
  39. data/lib/d3/random.rb +14 -0
  40. data/lib/d3/search.rb +30 -0
  41. data/lib/d3/selection.rb +151 -0
  42. data/lib/d3/sequential_scale.rb +31 -0
  43. data/lib/d3/set.rb +30 -0
  44. data/lib/d3/source/d3-drag.js +234 -0
  45. data/lib/d3/source/d3-scale-chromatic.js +484 -0
  46. data/lib/d3/source/d3.js +17178 -0
  47. data/lib/d3/stack.rb +13 -0
  48. data/lib/d3/statistics.rb +81 -0
  49. data/lib/d3/symbol.rb +70 -0
  50. data/lib/d3/threshold_scale.rb +22 -0
  51. data/lib/d3/time_format.rb +47 -0
  52. data/lib/d3/time_interval.rb +85 -0
  53. data/lib/d3/transformations.rb +16 -0
  54. data/lib/hyper-d3.rb +17 -0
  55. data/lib/hyperloop/d3/component.rb +12 -0
  56. data/lib/hyperloop/d3/mixin.rb +59 -0
  57. data/lib/hyperloop/d3/version.rb +5 -0
  58. data/spec/arc_spec.rb +80 -0
  59. data/spec/area_spec.rb +98 -0
  60. data/spec/axis_spec.rb +174 -0
  61. data/spec/band_scale_spec.rb +73 -0
  62. data/spec/color_spec.rb +74 -0
  63. data/spec/continuous_scale_spec.rb +217 -0
  64. data/spec/coverage_spec.rb +16 -0
  65. data/spec/creator_spec.rb +15 -0
  66. data/spec/curve_spec.rb +206 -0
  67. data/spec/dsv_spec.rb +194 -0
  68. data/spec/ease_spec.rb +370 -0
  69. data/spec/format_spec.rb +87 -0
  70. data/spec/histograms_spec.rb +61 -0
  71. data/spec/html/index.html.erb +11 -0
  72. data/spec/interpolate_spec.rb +152 -0
  73. data/spec/line_spec.rb +54 -0
  74. data/spec/map_spec.rb +80 -0
  75. data/spec/misc_spec.rb +21 -0
  76. data/spec/nest_spec.rb +89 -0
  77. data/spec/objects_spec.rb +22 -0
  78. data/spec/ordinal_scale_spec.rb +59 -0
  79. data/spec/path_spec.rb +65 -0
  80. data/spec/pie_spec.rb +114 -0
  81. data/spec/point_scale_spec.rb +58 -0
  82. data/spec/polygon_spec.rb +51 -0
  83. data/spec/quadtree_spec.rb +128 -0
  84. data/spec/quantile_scale_spec.rb +24 -0
  85. data/spec/quantize_scale_spec.rb +40 -0
  86. data/spec/radial_area_spec.rb +123 -0
  87. data/spec/radial_line_spec.rb +50 -0
  88. data/spec/random_spec.rb +34 -0
  89. data/spec/search_spec.rb +69 -0
  90. data/spec/selection_data_spec.rb +64 -0
  91. data/spec/selection_manipulation_spec.rb +166 -0
  92. data/spec/selection_spec.rb +187 -0
  93. data/spec/sequential_scale_spec.rb +90 -0
  94. data/spec/set_spec.rb +57 -0
  95. data/spec/spec_helper.rb +1 -0
  96. data/spec/stack_spec.rb +5 -0
  97. data/spec/statistics_spec.rb +65 -0
  98. data/spec/symbol_spec.rb +116 -0
  99. data/spec/test_app/.gitignore +23 -0
  100. data/spec/test_app/Gemfile +7 -0
  101. data/spec/test_app/Gemfile.lock +206 -0
  102. data/spec/test_app/README.md +9 -0
  103. data/spec/test_app/Rakefile +6 -0
  104. data/spec/test_app/app/assets/config/manifest.js +3 -0
  105. data/spec/test_app/app/assets/images/.keep +0 -0
  106. data/spec/test_app/app/assets/javascripts/application.js +13 -0
  107. data/spec/test_app/app/assets/javascripts/cable.js +13 -0
  108. data/spec/test_app/app/assets/javascripts/channels/.keep +0 -0
  109. data/spec/test_app/app/assets/javascripts/data/elections_2016.rb +10 -0
  110. data/spec/test_app/app/assets/javascripts/data/harry_potter.rb +19 -0
  111. data/spec/test_app/app/assets/javascripts/data/iphones.rb +29 -0
  112. data/spec/test_app/app/assets/javascripts/data/london_population.rb +26 -0
  113. data/spec/test_app/app/assets/javascripts/data/man_vs_horse.rb +55 -0
  114. data/spec/test_app/app/assets/javascripts/data/mtg_modern_colors.rb +96 -0
  115. data/spec/test_app/app/assets/javascripts/data/mtg_modern_creatures.rb +116 -0
  116. data/spec/test_app/app/assets/javascripts/data/olympics_2016_medals.rb +100 -0
  117. data/spec/test_app/app/assets/javascripts/data/paradox.rb +60 -0
  118. data/spec/test_app/app/assets/javascripts/data/polish_pms.rb +28 -0
  119. data/spec/test_app/app/assets/javascripts/data/star_trek_voyager.rb +183 -0
  120. data/spec/test_app/app/assets/javascripts/data/weather_in_london.rb +381 -0
  121. data/spec/test_app/app/assets/javascripts/elections_2016.rb +27 -0
  122. data/spec/test_app/app/assets/javascripts/harry_potter.rb +42 -0
  123. data/spec/test_app/app/assets/javascripts/iphones.rb +54 -0
  124. data/spec/test_app/app/assets/javascripts/london_population.rb +53 -0
  125. data/spec/test_app/app/assets/javascripts/london_population_area.rb +49 -0
  126. data/spec/test_app/app/assets/javascripts/man_vs_horse.rb +60 -0
  127. data/spec/test_app/app/assets/javascripts/mtg_modern_colors.rb +56 -0
  128. data/spec/test_app/app/assets/javascripts/mtg_modern_creatures.rb +70 -0
  129. data/spec/test_app/app/assets/javascripts/olympics_2016_medals.rb +62 -0
  130. data/spec/test_app/app/assets/javascripts/paradox.rb +64 -0
  131. data/spec/test_app/app/assets/javascripts/polish_pms.rb +60 -0
  132. data/spec/test_app/app/assets/javascripts/star_trek_voyager.rb +44 -0
  133. data/spec/test_app/app/assets/javascripts/weather_in_london.rb +69 -0
  134. data/spec/test_app/app/assets/stylesheets/application.css +15 -0
  135. data/spec/test_app/app/channels/application_cable/channel.rb +4 -0
  136. data/spec/test_app/app/channels/application_cable/connection.rb +4 -0
  137. data/spec/test_app/app/controllers/application_controller.rb +27 -0
  138. data/spec/test_app/app/controllers/concerns/.keep +0 -0
  139. data/spec/test_app/app/helpers/application_helper.rb +2 -0
  140. data/spec/test_app/app/jobs/application_job.rb +2 -0
  141. data/spec/test_app/app/mailers/application_mailer.rb +4 -0
  142. data/spec/test_app/app/models/application_record.rb +3 -0
  143. data/spec/test_app/app/models/concerns/.keep +0 -0
  144. data/spec/test_app/app/views/application/index.erb +18 -0
  145. data/spec/test_app/app/views/application/visualization.erb +28 -0
  146. data/spec/test_app/app/views/layouts/application.html.erb +13 -0
  147. data/spec/test_app/bin/bundle +3 -0
  148. data/spec/test_app/bin/rails +4 -0
  149. data/spec/test_app/bin/rake +4 -0
  150. data/spec/test_app/bin/setup +38 -0
  151. data/spec/test_app/bin/update +29 -0
  152. data/spec/test_app/bin/yarn +11 -0
  153. data/spec/test_app/config.ru +5 -0
  154. data/spec/test_app/config/application.rb +18 -0
  155. data/spec/test_app/config/boot.rb +3 -0
  156. data/spec/test_app/config/cable.yml +10 -0
  157. data/spec/test_app/config/database.yml +25 -0
  158. data/spec/test_app/config/environment.rb +5 -0
  159. data/spec/test_app/config/environments/development.rb +54 -0
  160. data/spec/test_app/config/environments/production.rb +91 -0
  161. data/spec/test_app/config/environments/test.rb +42 -0
  162. data/spec/test_app/config/initializers/application_controller_renderer.rb +8 -0
  163. data/spec/test_app/config/initializers/assets.rb +14 -0
  164. data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
  165. data/spec/test_app/config/initializers/cookies_serializer.rb +5 -0
  166. data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
  167. data/spec/test_app/config/initializers/inflections.rb +16 -0
  168. data/spec/test_app/config/initializers/mime_types.rb +4 -0
  169. data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
  170. data/spec/test_app/config/locales/en.yml +33 -0
  171. data/spec/test_app/config/puma.rb +56 -0
  172. data/spec/test_app/config/routes.rb +5 -0
  173. data/spec/test_app/config/secrets.yml +32 -0
  174. data/spec/test_app/config/spring.rb +6 -0
  175. data/spec/test_app/db/seeds.rb +7 -0
  176. data/spec/test_app/lib/assets/.keep +0 -0
  177. data/spec/test_app/lib/tasks/.keep +0 -0
  178. data/spec/test_app/log/.keep +0 -0
  179. data/spec/test_app/package.json +5 -0
  180. data/spec/test_app/public/404.html +67 -0
  181. data/spec/test_app/public/422.html +67 -0
  182. data/spec/test_app/public/500.html +66 -0
  183. data/spec/test_app/public/apple-touch-icon-precomposed.png +0 -0
  184. data/spec/test_app/public/apple-touch-icon.png +0 -0
  185. data/spec/test_app/public/favicon.ico +0 -0
  186. data/spec/test_app/public/robots.txt +1 -0
  187. data/spec/test_app/test/application_system_test_case.rb +5 -0
  188. data/spec/test_app/test/controllers/.keep +0 -0
  189. data/spec/test_app/test/fixtures/.keep +0 -0
  190. data/spec/test_app/test/fixtures/files/.keep +0 -0
  191. data/spec/test_app/test/helpers/.keep +0 -0
  192. data/spec/test_app/test/integration/.keep +0 -0
  193. data/spec/test_app/test/mailers/.keep +0 -0
  194. data/spec/test_app/test/models/.keep +0 -0
  195. data/spec/test_app/test/system/.keep +0 -0
  196. data/spec/test_app/test/test_helper.rb +10 -0
  197. data/spec/test_app/tmp/.keep +0 -0
  198. data/spec/test_app/vendor/.keep +0 -0
  199. data/spec/threshold_scale_spec.rb +28 -0
  200. data/spec/time_format_spec.rb +100 -0
  201. data/spec/time_interval_spec.rb +314 -0
  202. data/spec/transformations_spec.rb +51 -0
  203. data/startrekvoyager.png +0 -0
  204. metadata +529 -0
@@ -0,0 +1,27 @@
1
+ require "react/test/utils" # just for mounting manually here, please ignore
2
+ require "data/elections_2016"
3
+
4
+ class ElectionComponent
5
+ include Hyperloop::D3::Mixin
6
+
7
+ render_with_selection('DIV') do |selection, election_data|
8
+ list = selection.append("ul")
9
+ max_votes = election_data.map(&:votes).max
10
+
11
+ election_data.each do |candidate|
12
+ item = list.append("li")
13
+ .style("position", "relative")
14
+ item.append("span")
15
+ .style("background-color", candidate.color)
16
+ .style("position", "absolute")
17
+ .style("width", "#{100.0 * candidate.votes / max_votes}%")
18
+ .style("height", "100%")
19
+ item.append("span")
20
+ .style("position", "absolute")
21
+ .text("#{candidate.name} - #{candidate.votes} votes")
22
+ end
23
+ end
24
+ end
25
+
26
+ # manual mount of component, usually you would use the react_component view helper for example
27
+ React.render(React.create_element(ElectionComponent, data: Elections2016), `document.body.querySelector("#visualization")`)
@@ -0,0 +1,42 @@
1
+ require "react/test/utils" # just for mounting manually here, please ignore
2
+ require "data/harry_potter"
3
+
4
+ class HarryPotterComponent
5
+ include Hyperloop::D3::Mixin
6
+
7
+ render_with_selection do |selection, hp_data|
8
+ svg = selection
9
+ .attr("height", "400px")
10
+ .attr("width", "100%")
11
+ width = svg.style("width").to_i
12
+
13
+ bar_size = (400-40-20) / (hp_data.size)
14
+
15
+ x = D3.scale_linear.domain(hp_data.map(&:date).minmax).range([200,width-90])
16
+ y = D3.scale_ordinal.range(hp_data.size.times.map{|i| 40+i*bar_size}.reverse)
17
+ s = D3.scale_sqrt.domain([0, hp_data.map(&:pages).max]).range([0,50])
18
+
19
+ hp_data.each do |book|
20
+ svg.append("text")
21
+ .attr("x", x.(book.date))
22
+ .attr("y", y.(book.title) + bar_size/2)
23
+ .attr("font-size", s.(book.pages))
24
+ .text("📖")
25
+ .attr("text-anchor", "middle")
26
+ svg.append("text")
27
+ .attr("x", 0)
28
+ .attr("y", y.(book.title) + bar_size/2)
29
+ .text(book.title)
30
+ end
31
+
32
+ axis_bottom = D3.axis_bottom(x)
33
+ .tick_format(D3.time_format("%Y-%m-%d"))
34
+ .tick_values(hp_data.map(&:date))
35
+ svg.append("g")
36
+ .attr("transform", "translate(0, 380)")
37
+ .call(axis_bottom)
38
+ end
39
+ end
40
+
41
+ # manual mount of component, usually you would use the react_component view helper for example
42
+ React.render(React.create_element(HarryPotterComponent, data: HarryPotterBooks), `document.body.querySelector("#visualization")`)
@@ -0,0 +1,54 @@
1
+ require "react/test/utils" # just for mounting manually here, please ignore
2
+ require "data/iphones"
3
+
4
+ class IPhonesComponent
5
+ include Hyperloop::D3::Mixin
6
+
7
+ render_with_selection do |selection, i_data|
8
+ svg = selection
9
+ .attr("height", "500px")
10
+ .attr("width", "100%")
11
+ width = svg.style("width").to_i
12
+
13
+ x = D3.scale_linear.domain(i_data.map(&:released).minmax).range([20,width-90]).nice
14
+ y = D3.scale_log.domain(i_data.map(&:size).minmax).range([380,20])
15
+ c = D3.scale_ordinal.range(D3.scheme_category_20)
16
+
17
+ # If there are multiple points on same date/size combination,
18
+ # move any duplicates 15px right (or 30px for triplicates etc.)
19
+ duplicates = Hash.new(0)
20
+
21
+ graph_area = svg.append("g")
22
+ .attr("transform", "translate(60, 20)")
23
+ graph_area.select_all("circle")
24
+ .data(i_data).enter
25
+ .append("circle")
26
+ .attr("cx"){|d|
27
+ count = duplicates[[d.released, d.size]]
28
+ duplicates[[d.released, d.size]] += 1
29
+ x.(d.released) + 15 * count
30
+ }
31
+ .attr("cy"){|d| y.(d.size)}
32
+ .attr("r", 10)
33
+ .attr("fill"){|d| c.(d.name)}
34
+
35
+ axis_bottom = D3.axis_bottom(x)
36
+ .tick_format(D3.time_format("%Y-%m-%d"))
37
+ axis_left = D3.axis_left(y)
38
+ .tick_values([4,8,16,32,64,128,256])
39
+ .tick_format{|v| "#{v} GB"}
40
+ graph_area.call(axis_left)
41
+ graph_area.append("g").attr("transform", "translate(0, 400)").call(axis_bottom)
42
+
43
+ D3.select("#visualization").append("table")
44
+ .select_all("tr")
45
+ .data(IPhones).enter
46
+ .append("tr")
47
+ .append("td")
48
+ .text{|d| d.name}
49
+ .style("background"){|d| c.(d.name)}
50
+ end
51
+ end
52
+
53
+ # manual mount of component, usually you would use the react_component view helper for example
54
+ React.render(React.create_element(IPhonesComponent, data: IPhoneVariants), `document.body.querySelector("#visualization")`)
@@ -0,0 +1,53 @@
1
+ require "react/test/utils" # just for mounting manually here, please ignore
2
+ require "data/london_population"
3
+
4
+ class LondonPopComponent
5
+ include Hyperloop::D3::Mixin
6
+
7
+ render_with_selection do |selection, lp_data|
8
+ svg = selection
9
+ .attr("height", "400px")
10
+ .attr("width", "100%")
11
+
12
+ svg.append("g").select_all("rect")
13
+ .data(lp_data)
14
+ .enter().append("rect")
15
+ .attr("width", 30)
16
+ .attr("height"){|d| d.greater/100_000 }
17
+ .attr("y"){|d| 200 - d.greater/100_000 }
18
+ .attr("x"){|d| (d.year-1800)*4 }
19
+ .attr("fill", "pink")
20
+
21
+ svg.append("g").select_all("rect")
22
+ .data(lp_data)
23
+ .enter().append("rect")
24
+ .attr("width", 30)
25
+ .attr("height"){|d| d.inner/100_000 }
26
+ .attr("y"){|d| 200 - d.inner/100_000 }
27
+ .attr("x"){|d| (d.year-1800)*4 }
28
+ .attr("fill", "steelblue")
29
+
30
+ svg.append("g").select_all("circle")
31
+ .data(lp_data)
32
+ .enter().append("circle")
33
+ .attr("fill", "pink")
34
+ .attr("cx"){|d| 15 + (d.year-1800)*4 }
35
+ .attr("cy", 300)
36
+ .attr("r"){|d| (d.greater**0.5)/150.0 }
37
+
38
+ svg.append("g").select_all("circle")
39
+ .data(lp_data)
40
+ .enter().append("circle")
41
+ .attr("fill", "steelblue")
42
+ .attr("cx"){|d| 15 + (d.year-1800)*4 }
43
+ .attr("cy", 300)
44
+ .attr("r"){|d| (d.inner**0.5)/150.0 }
45
+
46
+ list = D3.select("#visualization").append("table")
47
+ list.append("tr").append("td").text("Outer London").style("background", "pink")
48
+ list.append("tr").append("td").text("Inner London").style("background", "steelblue")
49
+ end
50
+ end
51
+
52
+ # manual mount of component, usually you would use the react_component view helper for example
53
+ React.render(React.create_element(LondonPopComponent, data: LondonPopulation), `document.body.querySelector("#visualization")`)
@@ -0,0 +1,49 @@
1
+ require "react/test/utils" # just for mounting manually here, please ignore
2
+ require "data/london_population"
3
+
4
+ class LondonPopAreaComponent
5
+ include Hyperloop::D3::Mixin
6
+
7
+ render_with_selection do |selection, lp_data|
8
+ svg = selection
9
+ .attr("height", "500px")
10
+ .attr("width", "100%")
11
+ width = svg.style("width").to_i
12
+
13
+ x = D3.scale_linear.domain([1801, 2011]).range([0, width-60])
14
+ y = D3.scale_linear.domain([0, 9_000_000]).range([400, 0])
15
+
16
+ greater_area = D3.area
17
+ .x{|d| x.(d.year) }
18
+ .y0(400)
19
+ .y1{|d| y.(d.greater)}
20
+ .curve(D3.curve_natural)
21
+
22
+ inner_area = D3.area
23
+ .x{|d| x.(d.year) }
24
+ .y0(400)
25
+ .y1{|d| y.(d.inner)}
26
+ .curve(D3.curve_natural)
27
+
28
+ graph_area = svg.append("g")
29
+ .attr("transform", "translate(60, 20)")
30
+ graph_area.append("path")
31
+ .attr("d", greater_area.(lp_data))
32
+ .attr("fill", "pink")
33
+ graph_area.append("path")
34
+ .attr("d", inner_area.(lp_data))
35
+ .attr("fill", "steelblue")
36
+
37
+ axis_bottom = D3.axis_bottom(x).tick_format(D3.format("d"))
38
+ axis_left = D3.axis_left(y).tick_format{|d| "#{d/1_000_000}M"}
39
+ graph_area.call(axis_left)
40
+ graph_area.append("g").attr("transform", "translate(0, 400)").call(axis_bottom)
41
+
42
+ list = D3.select("#visualization").append("table")
43
+ list.append("tr").append("td").text("Outer London").style("background", "pink")
44
+ list.append("tr").append("td").text("Inner London").style("background", "steelblue")
45
+ end
46
+ end
47
+
48
+ # manual mount of component, usually you would use the react_component view helper for example
49
+ React.render(React.create_element(LondonPopAreaComponent, data: LondonPopulation), `document.body.querySelector("#visualization")`)
@@ -0,0 +1,60 @@
1
+ require "react/test/utils" # just for mounting manually here, please ignore
2
+ require "data/man_vs_horse"
3
+
4
+ class ManHorseComponent
5
+ include Hyperloop::D3::Mixin
6
+
7
+ render_with_selection do |selection, mh_data|
8
+ svg = selection
9
+ .attr("height", "1200px")
10
+ .attr("width", "100%")
11
+ width = svg.style("width").to_i
12
+
13
+ max_time = mh_data.flat_map{|d| [d.horse_time, d.human_time]}.max
14
+ min_year = mh_data.map(&:year).min
15
+ max_year = mh_data.map(&:year).max
16
+
17
+ x = D3.scale_linear.domain([0, max_time]).range([0,width-90]).nice
18
+ y = D3.scale_linear.domain([min_year, max_year+1]).range([0, 1160])
19
+ c = D3.scale_ordinal.range(D3.scheme_category_10)
20
+
21
+ graph_area = svg.append("g")
22
+ .attr("transform", "translate(60, 20)")
23
+
24
+ graph_area.append("g")
25
+ .select_all("rect")
26
+ .data(mh_data).enter
27
+ .append("rect")
28
+ .attr("x"){|d| 0 }
29
+ .attr("y"){|d| y.(d.year) }
30
+ .attr("width"){|d| x.(d.horse_time) }
31
+ .attr("height"){|d,i| 0.35 * (y.(i+1) - y.(i)) }
32
+ .attr("fill"){|d| c.("horse") }
33
+
34
+ graph_area.append("g")
35
+ .select_all("rect")
36
+ .data(mh_data).enter
37
+ .append("rect")
38
+ .attr("x"){|d| 0 }
39
+ .attr("y"){|d| y.(d.year+0.45) }
40
+ .attr("width"){|d| x.(d.human_time) }
41
+ .attr("height"){|d,i| 0.35 * (y.(i+1) - y.(i)) }
42
+ .attr("fill"){|d| c.("man") }
43
+
44
+ svg.append("g")
45
+ .attr("transform", "translate(0, 20)")
46
+ .select_all("text")
47
+ .data(mh_data).enter
48
+ .append("text")
49
+ .attr("x"){|d| 0 }
50
+ .attr("y"){|d| y.(d.year+0.5) }
51
+ .text{|d| (d.winner == "Horse" ? "🐎" : "🏃") + " #{d.year}" }
52
+
53
+ axis_bottom = D3.axis_bottom(x)
54
+ .tick_format{|v| h = (v / 60).floor; m = (v % 60).floor; "%d:%02d" % [h,m] }
55
+ graph_area.append("g").attr("transform", "translate(0, 1160)").call(axis_bottom)
56
+ end
57
+ end
58
+
59
+ # manual mount of component, usually you would use the react_component view helper for example
60
+ React.render(React.create_element(ManHorseComponent, data: ManVsHorse), `document.body.querySelector("#visualization")`)
@@ -0,0 +1,56 @@
1
+ require "hyper-d3"
2
+ require "data/mtg_modern_colors"
3
+
4
+ class ModernColorsComponent
5
+ include Hyperloop::D3::Mixin
6
+
7
+ render_with_selection('DIV') do |selection, colors_data|
8
+ flex = selection
9
+ .style("display", "flex")
10
+ .style("flex-wrap", "wrap")
11
+
12
+ colors_data.group_by(&:cmc).sort.each do |cmc, cards|
13
+ svg = flex.append("svg")
14
+ .attr("height", "200px")
15
+ .attr("width", "200px")
16
+ graph_area = svg
17
+ .append("g")
18
+ .attr("transform", "translate(100,100)")
19
+ graph_area.append("text")
20
+ .attr("text-anchor", "middle")
21
+ .attr("y", 10)
22
+ .text(cmc)
23
+ .attr("font-size", "30px")
24
+
25
+ cards.sort_by!{|c| "wubrgxm".index(c.color)}
26
+ pie = D3.pie.value(&:count).sort(nil)
27
+
28
+ pie.(cards).each do |arc_data|
29
+ arc = D3.arc
30
+ .inner_radius(40)
31
+ .outer_radius(90)
32
+ .start_angle(arc_data[:start_angle])
33
+ .end_angle(arc_data[:end_angle])
34
+
35
+ color = {
36
+ w: "white",
37
+ u: "blue",
38
+ b: "black",
39
+ r: "red",
40
+ g: "green",
41
+ x: "grey",
42
+ m: "yellow",
43
+ }[arc_data[:data].color]
44
+
45
+ graph_area.append("path")
46
+ .attr("d", arc.())
47
+ .attr("fill", color)
48
+ .attr("stroke", "black")
49
+ .attr("stroke-width", "1px")
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ # manual mount of component, usually you would use the react_component view helper for example
56
+ React.render(React.create_element(ModernColorsComponent, data: MtgModernColors), `document.body.querySelector("#visualization")`)
@@ -0,0 +1,70 @@
1
+ require "hyper-d3"
2
+ require "data/mtg_modern_creatures"
3
+
4
+ class ModernCreaturesComponent
5
+ include Hyperloop::D3::Mixin
6
+
7
+ render_with_selection do |selection, creatures_data|
8
+ svg = selection
9
+ .attr("height", "600px")
10
+ .attr("width", "600px")
11
+
12
+ # Use one scale not two so it's a square
13
+ min, max = creatures_data.flat_map{|c| [c.power, c.toughness]}.minmax
14
+
15
+ pt = D3.scale_linear.domain([min-1, max+1]).range([0, 580])
16
+ box_size = pt.(1) - pt.(0)
17
+ c = D3.scale_log
18
+ .domain([1, creatures_data.map(&:count).max])
19
+ .range(["rgb(128, 255, 128)", "rgb(128, 128, 255)"])
20
+
21
+ graph_area = svg.append("g").attr("transform", "translate(0,0)")
22
+
23
+ creatures_data.each do |cards|
24
+ graph_area.append("rect")
25
+ .attr("x", pt.(cards.toughness))
26
+ .attr("y", pt.(cards.power))
27
+ .attr("height", box_size)
28
+ .attr("width", box_size)
29
+ .attr("fill", c.(cards.count))
30
+ graph_area.append("text")
31
+ .attr("x", pt.(cards.toughness) + box_size/2)
32
+ .attr("y", pt.(cards.power) + box_size/2 + 5)
33
+ .attr("text-anchor", "middle")
34
+ .text(cards.count)
35
+ end
36
+
37
+ (min..max).each do |v|
38
+ graph_area.append("text")
39
+ .attr("x", pt.(v) + box_size/2)
40
+ .attr("y", pt.(min-1) + box_size/2 + 5)
41
+ .attr("text-anchor", "middle")
42
+ .text(v)
43
+
44
+ graph_area.append("text")
45
+ .attr("y", pt.(v) + box_size/2 + 5)
46
+ .attr("x", pt.(min-1) + box_size/2)
47
+ .attr("text-anchor", "middle")
48
+ .text(v)
49
+ end
50
+
51
+ (min..max+1).each do |v|
52
+ graph_area.append("line")
53
+ .attr("x1", pt.(min))
54
+ .attr("x2", pt.(max+1))
55
+ .attr("y1", pt.(v))
56
+ .attr("y2", pt.(v))
57
+ .attr("stroke", "black")
58
+
59
+ graph_area.append("line")
60
+ .attr("y1", pt.(min))
61
+ .attr("y2", pt.(max+1))
62
+ .attr("x1", pt.(v))
63
+ .attr("x2", pt.(v))
64
+ .attr("stroke", "black")
65
+ end
66
+ end
67
+ end
68
+
69
+ # manual mount of component, usually you would use the react_component view helper for example
70
+ React.render(React.create_element(ModernCreaturesComponent, data: MtgModernCreatures), `document.body.querySelector("#visualization")`)
@@ -0,0 +1,62 @@
1
+ require "react/test/utils" # just for mounting manually here, please ignore
2
+ require "data/olympics_2016_medals"
3
+
4
+ class OlympicsMedalsComponent
5
+ include Hyperloop::D3::Mixin
6
+
7
+ render_with_selection do |selection, medals2016_data|
8
+ height = medals2016_data.size * 24
9
+ svg = selection
10
+ .attr("height", "#{height}px")
11
+ .attr("width", "100%")
12
+
13
+ width = svg.style("width").to_i
14
+ max_medals = medals2016_data.map(&:total).max
15
+
16
+ x = D3.scale_linear.domain([0, max_medals]).range([0, width-50])
17
+ y = D3.scale_linear.domain([0, medals2016_data.size]).range([0, height])
18
+
19
+ svg.append("g").attr("transform", "translate(50, 0)")
20
+ .select_all("rect")
21
+ .data(medals2016_data)
22
+ .enter.append("rect")
23
+ .attr("height", 20)
24
+ .attr("width"){|d| x.(d.gold)}
25
+ .attr("x", 0)
26
+ .attr("y"){|d,i| y.(i)}
27
+ .attr("fill", "gold")
28
+
29
+ svg.append("g").attr("transform", "translate(50, 0)")
30
+ .select_all("rect")
31
+ .data(medals2016_data)
32
+ .enter.append("rect")
33
+ .attr("height", 20)
34
+ .attr("width"){|d| x.(d.silver)}
35
+ .attr("x"){|d| x.(d.gold) }
36
+ .attr("y"){|d,i| y.(i)}
37
+ .attr("fill", "silver")
38
+
39
+ svg.append("g").attr("transform", "translate(50, 0)")
40
+ .select_all("rect")
41
+ .data(medals2016_data)
42
+ .enter.append("rect")
43
+ .attr("height", 20)
44
+ .attr("width"){|d| x.(d.bronze)}
45
+ .attr("x"){|d| x.(d.gold + d.silver) }
46
+ .attr("y"){|d,i| y.(i)}
47
+ .attr("fill", "#CD7F32")
48
+
49
+ svg.append("g")
50
+ .select_all("text")
51
+ .data(medals2016_data)
52
+ .enter.append("text")
53
+ .attr("x", 0)
54
+ .attr("y"){|d,i| y.(i) + 16}
55
+ .text{|d| d.acronym}
56
+ .style("font-size", "20px")
57
+ end
58
+ end
59
+
60
+ # manual mount of component, usually you would use the react_component view helper for example
61
+ React.render(React.create_element(OlympicsMedalsComponent, data: Olympics2016Medals), `document.body.querySelector("#visualization")`)
62
+