gruff 0.5.0-java → 0.9.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (612) hide show
  1. checksums.yaml +5 -5
  2. data/.editorconfig +14 -0
  3. data/.github/ISSUE_TEMPLATE.md +18 -0
  4. data/.gitignore +3 -0
  5. data/.rubocop.yml +109 -0
  6. data/.rubocop_todo.yml +136 -0
  7. data/.travis.yml +24 -12
  8. data/.yardopts +1 -0
  9. data/{History.txt → CHANGELOG.md} +63 -24
  10. data/Gemfile +3 -7
  11. data/README.md +53 -25
  12. data/Rakefile +6 -201
  13. data/assets/plastik/blue.png +0 -0
  14. data/assets/plastik/green.png +0 -0
  15. data/assets/plastik/red.png +0 -0
  16. data/docker/Dockerfile +14 -0
  17. data/docker/build.sh +4 -0
  18. data/docker/launch.sh +4 -0
  19. data/gruff.gemspec +18 -14
  20. data/init.rb +2 -0
  21. data/lib/gruff.rb +25 -2
  22. data/lib/gruff/accumulator_bar.rb +7 -7
  23. data/lib/gruff/area.rb +12 -19
  24. data/lib/gruff/bar.rb +60 -44
  25. data/lib/gruff/base.rb +281 -585
  26. data/lib/gruff/bezier.rb +15 -18
  27. data/lib/gruff/bullet.rb +41 -62
  28. data/lib/gruff/dot.rb +26 -61
  29. data/lib/gruff/helper/bar_conversion.rb +47 -0
  30. data/lib/gruff/helper/bar_value_label_mixin.rb +30 -0
  31. data/lib/gruff/{stacked_mixin.rb → helper/stacked_mixin.rb} +8 -8
  32. data/lib/gruff/line.rb +126 -148
  33. data/lib/gruff/mini/bar.rb +8 -9
  34. data/lib/gruff/mini/legend.rb +24 -36
  35. data/lib/gruff/mini/pie.rb +10 -11
  36. data/lib/gruff/mini/side_bar.rb +9 -10
  37. data/lib/gruff/net.rb +37 -82
  38. data/lib/gruff/patch/rmagick.rb +33 -0
  39. data/lib/gruff/patch/string.rb +8 -0
  40. data/lib/gruff/photo_bar.rb +27 -30
  41. data/lib/gruff/pie.rb +185 -89
  42. data/lib/gruff/renderer/bezier.rb +21 -0
  43. data/lib/gruff/renderer/circle.rb +21 -0
  44. data/lib/gruff/renderer/dash_line.rb +22 -0
  45. data/lib/gruff/renderer/dot.rb +39 -0
  46. data/lib/gruff/renderer/ellipse.rb +21 -0
  47. data/lib/gruff/renderer/line.rb +34 -0
  48. data/lib/gruff/renderer/polygon.rb +23 -0
  49. data/lib/gruff/renderer/polyline.rb +21 -0
  50. data/lib/gruff/renderer/rectangle.rb +19 -0
  51. data/lib/gruff/renderer/renderer.rb +127 -0
  52. data/lib/gruff/renderer/text.rb +42 -0
  53. data/lib/gruff/scatter.rb +154 -179
  54. data/lib/gruff/scene.rb +31 -41
  55. data/lib/gruff/side_bar.rb +64 -63
  56. data/lib/gruff/side_stacked_bar.rb +61 -59
  57. data/lib/gruff/spider.rb +25 -49
  58. data/lib/gruff/stacked_area.rb +21 -29
  59. data/lib/gruff/stacked_bar.rb +77 -49
  60. data/lib/gruff/store/base_data.rb +34 -0
  61. data/lib/gruff/store/custom_data.rb +34 -0
  62. data/lib/gruff/store/store.rb +80 -0
  63. data/lib/gruff/store/xy_data.rb +55 -0
  64. data/lib/gruff/themes.rb +32 -33
  65. data/lib/gruff/version.rb +3 -1
  66. metadata +75 -1084
  67. data/Manifest.txt +0 -81
  68. data/RELEASE.md +0 -41
  69. data/assets/bubble.png +0 -0
  70. data/assets/city_scene/background/0000.png +0 -0
  71. data/assets/city_scene/background/0600.png +0 -0
  72. data/assets/city_scene/background/2000.png +0 -0
  73. data/assets/city_scene/clouds/cloudy.png +0 -0
  74. data/assets/city_scene/clouds/partly_cloudy.png +0 -0
  75. data/assets/city_scene/clouds/stormy.png +0 -0
  76. data/assets/city_scene/grass/default.png +0 -0
  77. data/assets/city_scene/haze/true.png +0 -0
  78. data/assets/city_scene/number_sample/1.png +0 -0
  79. data/assets/city_scene/number_sample/2.png +0 -0
  80. data/assets/city_scene/number_sample/default.png +0 -0
  81. data/assets/city_scene/sky/0000.png +0 -0
  82. data/assets/city_scene/sky/0200.png +0 -0
  83. data/assets/city_scene/sky/0400.png +0 -0
  84. data/assets/city_scene/sky/0600.png +0 -0
  85. data/assets/city_scene/sky/0800.png +0 -0
  86. data/assets/city_scene/sky/1000.png +0 -0
  87. data/assets/city_scene/sky/1200.png +0 -0
  88. data/assets/city_scene/sky/1400.png +0 -0
  89. data/assets/city_scene/sky/1500.png +0 -0
  90. data/assets/city_scene/sky/1700.png +0 -0
  91. data/assets/city_scene/sky/2000.png +0 -0
  92. data/assets/pc306715.jpg +0 -0
  93. data/lib/gruff/bar_conversion.rb +0 -46
  94. data/lib/gruff/deprecated.rb +0 -39
  95. data/test/gruff_test_case.rb +0 -154
  96. data/test/image_compare.rb +0 -58
  97. data/test/output/accum_bar.png +0 -0
  98. data/test/output/area_keynote.png +0 -0
  99. data/test/output/area_keynote_small.png +0 -0
  100. data/test/output/area_many.png +0 -0
  101. data/test/output/area_many_areas_small.png +0 -0
  102. data/test/output/area_tiny.png +0 -0
  103. data/test/output/area_wide.png +0 -0
  104. data/test/output/bar2_wrapped_legend_16_400.png +0 -0
  105. data/test/output/bar2_wrapped_legend_16_800.png +0 -0
  106. data/test/output/bar2_wrapped_legend_30_400.png +0 -0
  107. data/test/output/bar2_wrapped_legend_30_800.png +0 -0
  108. data/test/output/bar2_wrapped_legend_4_400.png +0 -0
  109. data/test/output/bar2_wrapped_legend_4_800.png +0 -0
  110. data/test/output/bar2_wrapped_legend__400.png +0 -0
  111. data/test/output/bar2_wrapped_legend__800.png +0 -0
  112. data/test/output/bar_background_gradient_bottom_top.png +0 -0
  113. data/test/output/bar_background_gradient_left_right.png +0 -0
  114. data/test/output/bar_background_gradient_right_left.png +0 -0
  115. data/test/output/bar_background_gradient_top_bottom.png +0 -0
  116. data/test/output/bar_background_gradient_topleft_bottomright.png +0 -0
  117. data/test/output/bar_background_gradient_topright_bottomleft.png +0 -0
  118. data/test/output/bar_formatted_numbers.png +0 -0
  119. data/test/output/bar_keynote.png +0 -0
  120. data/test/output/bar_keynote_small.png +0 -0
  121. data/test/output/bar_long_legend_text.png +0 -0
  122. data/test/output/bar_manual_colors.png +0 -0
  123. data/test/output/bar_marker_shadow.png +0 -0
  124. data/test/output/bar_nearly_zero_max_10.png +0 -0
  125. data/test/output/bar_no_legend.png +0 -0
  126. data/test/output/bar_no_line_markers.png +0 -0
  127. data/test/output/bar_no_title.png +0 -0
  128. data/test/output/bar_no_title_or_legend.png +0 -0
  129. data/test/output/bar_odeo.png +0 -0
  130. data/test/output/bar_one_value.png +0 -0
  131. data/test/output/bar_pos_neg.png +0 -0
  132. data/test/output/bar_rails_keynote.png +0 -0
  133. data/test/output/bar_set_absolute_trunc.png +0 -0
  134. data/test/output/bar_set_label_stagger_height.png +0 -0
  135. data/test/output/bar_set_legend_box_size_lg.png +0 -0
  136. data/test/output/bar_set_legend_box_size_sm.png +0 -0
  137. data/test/output/bar_set_marker.png +0 -0
  138. data/test/output/bar_set_trailing_dots_trunc.png +0 -0
  139. data/test/output/bar_spacing_full.png +0 -0
  140. data/test/output/bar_spacing_half.png +0 -0
  141. data/test/output/bar_spacing_none.png +0 -0
  142. data/test/output/bar_tall_graph.png +0 -0
  143. data/test/output/bar_tall_graph_small.png +0 -0
  144. data/test/output/bar_themed.png +0 -0
  145. data/test/output/bar_title_margin.png +0 -0
  146. data/test/output/bar_value_labels.png +0 -0
  147. data/test/output/bar_wide_graph.png +0 -0
  148. data/test/output/bar_wide_graph_small.png +0 -0
  149. data/test/output/bar_wrapped_legend_16_400.png +0 -0
  150. data/test/output/bar_wrapped_legend_16_800.png +0 -0
  151. data/test/output/bar_wrapped_legend_30_400.png +0 -0
  152. data/test/output/bar_wrapped_legend_30_800.png +0 -0
  153. data/test/output/bar_wrapped_legend_4_400.png +0 -0
  154. data/test/output/bar_wrapped_legend_4_800.png +0 -0
  155. data/test/output/bar_wrapped_legend__400.png +0 -0
  156. data/test/output/bar_wrapped_legend__800.png +0 -0
  157. data/test/output/bar_x_y_labels.png +0 -0
  158. data/test/output/bar_y_increment_1.png +0 -0
  159. data/test/output/bar_y_increment_2.0.png +0 -0
  160. data/test/output/bar_y_increment_20.png +0 -0
  161. data/test/output/bar_y_increment_5.png +0 -0
  162. data/test/output/bar_zero_marker_count.png +0 -0
  163. data/test/output/bar_zero_spacing.png +0 -0
  164. data/test/output/bezier.png +0 -0
  165. data/test/output/bezier_2.png +0 -0
  166. data/test/output/bezier_3.png +0 -0
  167. data/test/output/bullet_greyscale.png +0 -0
  168. data/test/output/bullet_no_options.png +0 -0
  169. data/test/output/dot.png +0 -0
  170. data/test/output/dot_manual_colors.png +0 -0
  171. data/test/output/dot_nearly_zero_max_10.png +0 -0
  172. data/test/output/dot_no_legend.png +0 -0
  173. data/test/output/dot_no_line_markers.png +0 -0
  174. data/test/output/dot_no_title.png +0 -0
  175. data/test/output/dot_no_title_or_legend.png +0 -0
  176. data/test/output/dot_one_value.png +0 -0
  177. data/test/output/dot_pos_neg.png +0 -0
  178. data/test/output/dot_set_legend_box_size_lg.png +0 -0
  179. data/test/output/dot_set_legend_box_size_sm.png +0 -0
  180. data/test/output/dot_set_marker.png +0 -0
  181. data/test/output/dot_small.png +0 -0
  182. data/test/output/dot_tall_graph.png +0 -0
  183. data/test/output/dot_tall_graph_small.png +0 -0
  184. data/test/output/dot_themed.png +0 -0
  185. data/test/output/dot_wide_graph.png +0 -0
  186. data/test/output/dot_wide_graph_small.png +0 -0
  187. data/test/output/dot_x_y_labels.png +0 -0
  188. data/test/output/dot_y_increment_1.png +0 -0
  189. data/test/output/dot_y_increment_2.0.png +0 -0
  190. data/test/output/dot_y_increment_20.png +0 -0
  191. data/test/output/dot_y_increment_5.png +0 -0
  192. data/test/output/enhancements-1.png +0 -0
  193. data/test/output/enhancements.png +0 -0
  194. data/test/output/line_all_neg.png +0 -0
  195. data/test/output/line_all_neg_400.png +0 -0
  196. data/test/output/line_all_neg_no_max.png +0 -0
  197. data/test/output/line_baseline.png +0 -0
  198. data/test/output/line_hang_value.png +0 -0
  199. data/test/output/line_hide_dots.png +0 -0
  200. data/test/output/line_hide_lines.png +0 -0
  201. data/test/output/line_jruby_error.png +0 -0
  202. data/test/output/line_large.png +0 -0
  203. data/test/output/line_large_baseline.png +0 -0
  204. data/test/output/line_legend_at_bottom.png +0 -0
  205. data/test/output/line_many.png +0 -0
  206. data/test/output/line_many_lines_small.png +0 -0
  207. data/test/output/line_many_numbers.png +0 -0
  208. data/test/output/line_marker_label_accuracy.png +0 -0
  209. data/test/output/line_more_sets_than_colors.png +0 -0
  210. data/test/output/line_no_data.png +0 -0
  211. data/test/output/line_no_data_msg.png +0 -0
  212. data/test/output/line_no_data_other.png +0 -0
  213. data/test/output/line_no_hide.png +0 -0
  214. data/test/output/line_no_legend.png +0 -0
  215. data/test/output/line_no_line_markers.png +0 -0
  216. data/test/output/line_no_title.png +0 -0
  217. data/test/output/line_nothing_but_the_graph.png +0 -0
  218. data/test/output/line_one_value.png +0 -0
  219. data/test/output/line_one_value_array.png +0 -0
  220. data/test/output/line_pos_neg.png +0 -0
  221. data/test/output/line_pos_neg_400.png +0 -0
  222. data/test/output/line_reference_lines.png +0 -0
  223. data/test/output/line_similar_high_end_values.png +0 -0
  224. data/test/output/line_similar_high_end_values_with_floor.png +0 -0
  225. data/test/output/line_small_small_zero.png +0 -0
  226. data/test/output/line_small_values.png +0 -0
  227. data/test/output/line_small_values_small.png +0 -0
  228. data/test/output/line_small_zero.png +0 -0
  229. data/test/output/line_some_nil_points.png +0 -0
  230. data/test/output/line_theme_37signals_.png +0 -0
  231. data/test/output/line_theme_37signals_400.png +0 -0
  232. data/test/output/line_theme_keynote_.png +0 -0
  233. data/test/output/line_theme_keynote_400.png +0 -0
  234. data/test/output/line_theme_odeo_.png +0 -0
  235. data/test/output/line_theme_odeo_400.png +0 -0
  236. data/test/output/line_theme_rails_keynote_.png +0 -0
  237. data/test/output/line_theme_rails_keynote_400.png +0 -0
  238. data/test/output/line_tiny.png +0 -0
  239. data/test/output/line_transparent.png +0 -0
  240. data/test/output/line_very_small.png +0 -0
  241. data/test/output/line_webp.webp +0 -0
  242. data/test/output/line_wide_graph.png +0 -0
  243. data/test/output/line_wide_graph_small.png +0 -0
  244. data/test/output/line_xy.png +0 -0
  245. data/test/output/line_xy_pairs.png +0 -0
  246. data/test/output/line_y_axis_increment.png +0 -0
  247. data/test/output/mini_bar.png +0 -0
  248. data/test/output/mini_pie.png +0 -0
  249. data/test/output/mini_pie_right_legend.png +0 -0
  250. data/test/output/mini_side_bar.png +0 -0
  251. data/test/output/mini_side_bar_multi_color.png +0 -0
  252. data/test/output/net_dots_tiny.png +0 -0
  253. data/test/output/net_large.png +0 -0
  254. data/test/output/net_many.png +0 -0
  255. data/test/output/net_many_nets_small.png +0 -0
  256. data/test/output/net_no_data.png +0 -0
  257. data/test/output/net_no_data_msg.png +0 -0
  258. data/test/output/net_no_data_other.png +0 -0
  259. data/test/output/net_no_legend.png +0 -0
  260. data/test/output/net_no_net_markers.png +0 -0
  261. data/test/output/net_no_title.png +0 -0
  262. data/test/output/net_nothing_but_the_graph.png +0 -0
  263. data/test/output/net_similar_high_end_values.png +0 -0
  264. data/test/output/net_small.png +0 -0
  265. data/test/output/net_small_small.png +0 -0
  266. data/test/output/net_small_small_zero.png +0 -0
  267. data/test/output/net_small_zero.png +0 -0
  268. data/test/output/net_wide_graph.png +0 -0
  269. data/test/output/net_wide_graph_small.png +0 -0
  270. data/test/output/pie_equal.png +0 -0
  271. data/test/output/pie_grey.png +0 -0
  272. data/test/output/pie_keynote.png +0 -0
  273. data/test/output/pie_keynote_small.png +0 -0
  274. data/test/output/pie_legend.png +0 -0
  275. data/test/output/pie_legend_small.png +0 -0
  276. data/test/output/pie_nearly_equal.png +0 -0
  277. data/test/output/pie_one_val.png +0 -0
  278. data/test/output/pie_pastel.png +0 -0
  279. data/test/output/pie_simple.png +0 -0
  280. data/test/output/pie_wide.png +0 -0
  281. data/test/output/pie_wrapped_legend_16_400.png +0 -0
  282. data/test/output/pie_wrapped_legend_16_800.png +0 -0
  283. data/test/output/pie_wrapped_legend_30_400.png +0 -0
  284. data/test/output/pie_wrapped_legend_30_800.png +0 -0
  285. data/test/output/pie_wrapped_legend_4_400.png +0 -0
  286. data/test/output/pie_wrapped_legend_4_800.png +0 -0
  287. data/test/output/pie_wrapped_legend__400.png +0 -0
  288. data/test/output/pie_wrapped_legend__800.png +0 -0
  289. data/test/output/pie_zero.png +0 -0
  290. data/test/output/scatter_all_neg.png +0 -0
  291. data/test/output/scatter_all_neg_400.png +0 -0
  292. data/test/output/scatter_basic.png +0 -0
  293. data/test/output/scatter_many.png +0 -0
  294. data/test/output/scatter_no_data.png +0 -0
  295. data/test/output/scatter_no_data_msg.png +0 -0
  296. data/test/output/scatter_no_data_other.png +0 -0
  297. data/test/output/scatter_no_hide.png +0 -0
  298. data/test/output/scatter_no_labels.png +0 -0
  299. data/test/output/scatter_no_legend.png +0 -0
  300. data/test/output/scatter_no_line_markers.png +0 -0
  301. data/test/output/scatter_no_title.png +0 -0
  302. data/test/output/scatter_nothing_but_the_graph.png +0 -0
  303. data/test/output/scatter_pos_neg.png +0 -0
  304. data/test/output/scatter_pos_neg_400.png +0 -0
  305. data/test/output/scatter_wide_graph.png +0 -0
  306. data/test/output/scatter_wide_graph_small.png +0 -0
  307. data/test/output/scene_hazy_night.png +0 -0
  308. data/test/output/scene_not_hazy_day.png +0 -0
  309. data/test/output/scene_partly_cloudy_day.png +0 -0
  310. data/test/output/scene_stormy_day.png +0 -0
  311. data/test/output/scene_stormy_night.png +0 -0
  312. data/test/output/side_bar.png +0 -0
  313. data/test/output/side_bar_data_range.png +0 -0
  314. data/test/output/side_bar_labels.png +0 -0
  315. data/test/output/side_bar_spacing_full.png +0 -0
  316. data/test/output/side_bar_spacing_half.png +0 -0
  317. data/test/output/side_bar_spacing_none.png +0 -0
  318. data/test/output/side_stacked_bar_keynote.png +0 -0
  319. data/test/output/side_stacked_bar_keynote_small.png +0 -0
  320. data/test/output/side_stacked_bar_labels.png +0 -0
  321. data/test/output/side_stacked_bar_long_label.png +0 -0
  322. data/test/output/side_stacked_bar_wide.png +0 -0
  323. data/test/output/spider_37signals.png +0 -0
  324. data/test/output/spider_equal.png +0 -0
  325. data/test/output/spider_keynote.png +0 -0
  326. data/test/output/spider_legend.png +0 -0
  327. data/test/output/spider_legend_small.png +0 -0
  328. data/test/output/spider_lots_of_data.png +0 -0
  329. data/test/output/spider_lots_of_data_normal_names.png +0 -0
  330. data/test/output/spider_nearly_equal.png +0 -0
  331. data/test/output/spider_no_axes.png +0 -0
  332. data/test/output/spider_no_background.png +0 -0
  333. data/test/output/spider_no_print.png +0 -0
  334. data/test/output/spider_overlay_1.png +0 -0
  335. data/test/output/spider_overlay_2.png +0 -0
  336. data/test/output/spider_rotation.png +0 -0
  337. data/test/output/spider_small.png +0 -0
  338. data/test/output/spider_wide.png +0 -0
  339. data/test/output/spider_zero.png +0 -0
  340. data/test/output/stacked_area_keynote.png +0 -0
  341. data/test/output/stacked_area_keynote_small.png +0 -0
  342. data/test/output/stacked_bar_keynote.png +0 -0
  343. data/test/output/stacked_bar_keynote_small.png +0 -0
  344. data/test/output_java/accum_bar.png +0 -0
  345. data/test/output_java/area_keynote.png +0 -0
  346. data/test/output_java/area_keynote_small.png +0 -0
  347. data/test/output_java/area_many.png +0 -0
  348. data/test/output_java/area_many_areas_small.png +0 -0
  349. data/test/output_java/area_tiny.png +0 -0
  350. data/test/output_java/area_wide.png +0 -0
  351. data/test/output_java/bar2_wrapped_legend_16_400.png +0 -0
  352. data/test/output_java/bar2_wrapped_legend_16_800.png +0 -0
  353. data/test/output_java/bar2_wrapped_legend_30_400.png +0 -0
  354. data/test/output_java/bar2_wrapped_legend_30_800.png +0 -0
  355. data/test/output_java/bar2_wrapped_legend_4_400.png +0 -0
  356. data/test/output_java/bar2_wrapped_legend_4_800.png +0 -0
  357. data/test/output_java/bar2_wrapped_legend__400.png +0 -0
  358. data/test/output_java/bar2_wrapped_legend__800.png +0 -0
  359. data/test/output_java/bar_background_gradient_bottom_top.png +0 -0
  360. data/test/output_java/bar_background_gradient_left_right.png +0 -0
  361. data/test/output_java/bar_background_gradient_right_left.png +0 -0
  362. data/test/output_java/bar_background_gradient_top_bottom.png +0 -0
  363. data/test/output_java/bar_background_gradient_topleft_bottomright.png +0 -0
  364. data/test/output_java/bar_background_gradient_topright_bottomleft.png +0 -0
  365. data/test/output_java/bar_formatted_numbers.png +0 -0
  366. data/test/output_java/bar_keynote.png +0 -0
  367. data/test/output_java/bar_keynote_small.png +0 -0
  368. data/test/output_java/bar_long_legend_text.png +0 -0
  369. data/test/output_java/bar_manual_colors.png +0 -0
  370. data/test/output_java/bar_marker_shadow.png +0 -0
  371. data/test/output_java/bar_nearly_zero_max_10.png +0 -0
  372. data/test/output_java/bar_no_legend.png +0 -0
  373. data/test/output_java/bar_no_line_markers.png +0 -0
  374. data/test/output_java/bar_no_title.png +0 -0
  375. data/test/output_java/bar_no_title_or_legend.png +0 -0
  376. data/test/output_java/bar_odeo.png +0 -0
  377. data/test/output_java/bar_one_value.png +0 -0
  378. data/test/output_java/bar_pos_neg.png +0 -0
  379. data/test/output_java/bar_rails_keynote.png +0 -0
  380. data/test/output_java/bar_set_absolute_trunc.png +0 -0
  381. data/test/output_java/bar_set_label_stagger_height.png +0 -0
  382. data/test/output_java/bar_set_legend_box_size_lg.png +0 -0
  383. data/test/output_java/bar_set_legend_box_size_sm.png +0 -0
  384. data/test/output_java/bar_set_marker.png +0 -0
  385. data/test/output_java/bar_set_trailing_dots_trunc.png +0 -0
  386. data/test/output_java/bar_spacing_full.png +0 -0
  387. data/test/output_java/bar_spacing_half.png +0 -0
  388. data/test/output_java/bar_spacing_none.png +0 -0
  389. data/test/output_java/bar_tall_graph.png +0 -0
  390. data/test/output_java/bar_tall_graph_small.png +0 -0
  391. data/test/output_java/bar_themed.png +0 -0
  392. data/test/output_java/bar_title_margin.png +0 -0
  393. data/test/output_java/bar_value_labels.png +0 -0
  394. data/test/output_java/bar_wide_graph.png +0 -0
  395. data/test/output_java/bar_wide_graph_small.png +0 -0
  396. data/test/output_java/bar_wrapped_legend_16_400.png +0 -0
  397. data/test/output_java/bar_wrapped_legend_16_800.png +0 -0
  398. data/test/output_java/bar_wrapped_legend_30_400.png +0 -0
  399. data/test/output_java/bar_wrapped_legend_30_800.png +0 -0
  400. data/test/output_java/bar_wrapped_legend_4_400.png +0 -0
  401. data/test/output_java/bar_wrapped_legend_4_800.png +0 -0
  402. data/test/output_java/bar_wrapped_legend__400.png +0 -0
  403. data/test/output_java/bar_wrapped_legend__800.png +0 -0
  404. data/test/output_java/bar_x_y_labels.png +0 -0
  405. data/test/output_java/bar_y_increment_1.png +0 -0
  406. data/test/output_java/bar_y_increment_2.0.png +0 -0
  407. data/test/output_java/bar_y_increment_20.png +0 -0
  408. data/test/output_java/bar_y_increment_5.png +0 -0
  409. data/test/output_java/bar_zero_marker_count.png +0 -0
  410. data/test/output_java/bar_zero_spacing.png +0 -0
  411. data/test/output_java/bezier.png +0 -0
  412. data/test/output_java/bezier_2.png +0 -0
  413. data/test/output_java/bezier_3.png +0 -0
  414. data/test/output_java/bullet_greyscale.png +0 -0
  415. data/test/output_java/bullet_no_options.png +0 -0
  416. data/test/output_java/dot.png +0 -0
  417. data/test/output_java/dot_manual_colors.png +0 -0
  418. data/test/output_java/dot_nearly_zero_max_10.png +0 -0
  419. data/test/output_java/dot_no_legend.png +0 -0
  420. data/test/output_java/dot_no_line_markers.png +0 -0
  421. data/test/output_java/dot_no_title.png +0 -0
  422. data/test/output_java/dot_no_title_or_legend.png +0 -0
  423. data/test/output_java/dot_one_value.png +0 -0
  424. data/test/output_java/dot_pos_neg.png +0 -0
  425. data/test/output_java/dot_set_legend_box_size_lg.png +0 -0
  426. data/test/output_java/dot_set_legend_box_size_sm.png +0 -0
  427. data/test/output_java/dot_set_marker.png +0 -0
  428. data/test/output_java/dot_small.png +0 -0
  429. data/test/output_java/dot_tall_graph.png +0 -0
  430. data/test/output_java/dot_tall_graph_small.png +0 -0
  431. data/test/output_java/dot_themed.png +0 -0
  432. data/test/output_java/dot_wide_graph.png +0 -0
  433. data/test/output_java/dot_wide_graph_small.png +0 -0
  434. data/test/output_java/dot_x_y_labels.png +0 -0
  435. data/test/output_java/dot_y_increment_1.png +0 -0
  436. data/test/output_java/dot_y_increment_2.0.png +0 -0
  437. data/test/output_java/dot_y_increment_20.png +0 -0
  438. data/test/output_java/dot_y_increment_5.png +0 -0
  439. data/test/output_java/enhancements-1.png +0 -0
  440. data/test/output_java/enhancements.png +0 -0
  441. data/test/output_java/line_all_neg.png +0 -0
  442. data/test/output_java/line_all_neg_400.png +0 -0
  443. data/test/output_java/line_all_neg_no_max.png +0 -0
  444. data/test/output_java/line_baseline.png +0 -0
  445. data/test/output_java/line_hang_value.png +0 -0
  446. data/test/output_java/line_hide_dots.png +0 -0
  447. data/test/output_java/line_hide_lines.png +0 -0
  448. data/test/output_java/line_jruby_error.png +0 -0
  449. data/test/output_java/line_large.png +0 -0
  450. data/test/output_java/line_large_baseline.png +0 -0
  451. data/test/output_java/line_legend_at_bottom.png +0 -0
  452. data/test/output_java/line_many.png +0 -0
  453. data/test/output_java/line_many_lines_small.png +0 -0
  454. data/test/output_java/line_many_numbers.png +0 -0
  455. data/test/output_java/line_marker_label_accuracy.png +0 -0
  456. data/test/output_java/line_more_sets_than_colors.png +0 -0
  457. data/test/output_java/line_no_data.png +0 -0
  458. data/test/output_java/line_no_data_msg.png +0 -0
  459. data/test/output_java/line_no_data_other.png +0 -0
  460. data/test/output_java/line_no_hide.png +0 -0
  461. data/test/output_java/line_no_legend.png +0 -0
  462. data/test/output_java/line_no_line_markers.png +0 -0
  463. data/test/output_java/line_no_title.png +0 -0
  464. data/test/output_java/line_nothing_but_the_graph.png +0 -0
  465. data/test/output_java/line_one_value.png +0 -0
  466. data/test/output_java/line_one_value_array.png +0 -0
  467. data/test/output_java/line_pos_neg.png +0 -0
  468. data/test/output_java/line_pos_neg_400.png +0 -0
  469. data/test/output_java/line_reference_lines.png +0 -0
  470. data/test/output_java/line_similar_high_end_values.png +0 -0
  471. data/test/output_java/line_similar_high_end_values_with_floor.png +0 -0
  472. data/test/output_java/line_small_small_zero.png +0 -0
  473. data/test/output_java/line_small_values.png +0 -0
  474. data/test/output_java/line_small_values_small.png +0 -0
  475. data/test/output_java/line_small_zero.png +0 -0
  476. data/test/output_java/line_some_nil_points.png +0 -0
  477. data/test/output_java/line_theme_37signals_.png +0 -0
  478. data/test/output_java/line_theme_37signals_400.png +0 -0
  479. data/test/output_java/line_theme_keynote_.png +0 -0
  480. data/test/output_java/line_theme_keynote_400.png +0 -0
  481. data/test/output_java/line_theme_odeo_.png +0 -0
  482. data/test/output_java/line_theme_odeo_400.png +0 -0
  483. data/test/output_java/line_theme_rails_keynote_.png +0 -0
  484. data/test/output_java/line_theme_rails_keynote_400.png +0 -0
  485. data/test/output_java/line_tiny.png +0 -0
  486. data/test/output_java/line_transparent.png +0 -0
  487. data/test/output_java/line_very_small.png +0 -0
  488. data/test/output_java/line_webp.webp +0 -0
  489. data/test/output_java/line_wide_graph.png +0 -0
  490. data/test/output_java/line_wide_graph_small.png +0 -0
  491. data/test/output_java/line_xy.png +0 -0
  492. data/test/output_java/line_xy_pairs.png +0 -0
  493. data/test/output_java/line_y_axis_increment.png +0 -0
  494. data/test/output_java/mini_bar.png +0 -0
  495. data/test/output_java/mini_pie.png +0 -0
  496. data/test/output_java/mini_pie_right_legend.png +0 -0
  497. data/test/output_java/mini_side_bar.png +0 -0
  498. data/test/output_java/mini_side_bar_multi_color.png +0 -0
  499. data/test/output_java/net_dots_tiny.png +0 -0
  500. data/test/output_java/net_large.png +0 -0
  501. data/test/output_java/net_many.png +0 -0
  502. data/test/output_java/net_many_nets_small.png +0 -0
  503. data/test/output_java/net_no_data.png +0 -0
  504. data/test/output_java/net_no_data_msg.png +0 -0
  505. data/test/output_java/net_no_data_other.png +0 -0
  506. data/test/output_java/net_no_legend.png +0 -0
  507. data/test/output_java/net_no_net_markers.png +0 -0
  508. data/test/output_java/net_no_title.png +0 -0
  509. data/test/output_java/net_nothing_but_the_graph.png +0 -0
  510. data/test/output_java/net_similar_high_end_values.png +0 -0
  511. data/test/output_java/net_small.png +0 -0
  512. data/test/output_java/net_small_small.png +0 -0
  513. data/test/output_java/net_small_small_zero.png +0 -0
  514. data/test/output_java/net_small_zero.png +0 -0
  515. data/test/output_java/net_wide_graph.png +0 -0
  516. data/test/output_java/net_wide_graph_small.png +0 -0
  517. data/test/output_java/pie_equal.png +0 -0
  518. data/test/output_java/pie_grey.png +0 -0
  519. data/test/output_java/pie_keynote.png +0 -0
  520. data/test/output_java/pie_keynote_small.png +0 -0
  521. data/test/output_java/pie_legend.png +0 -0
  522. data/test/output_java/pie_legend_small.png +0 -0
  523. data/test/output_java/pie_nearly_equal.png +0 -0
  524. data/test/output_java/pie_one_val.png +0 -0
  525. data/test/output_java/pie_pastel.png +0 -0
  526. data/test/output_java/pie_simple.png +0 -0
  527. data/test/output_java/pie_wide.png +0 -0
  528. data/test/output_java/pie_wrapped_legend_16_400.png +0 -0
  529. data/test/output_java/pie_wrapped_legend_16_800.png +0 -0
  530. data/test/output_java/pie_wrapped_legend_30_400.png +0 -0
  531. data/test/output_java/pie_wrapped_legend_30_800.png +0 -0
  532. data/test/output_java/pie_wrapped_legend_4_400.png +0 -0
  533. data/test/output_java/pie_wrapped_legend_4_800.png +0 -0
  534. data/test/output_java/pie_wrapped_legend__400.png +0 -0
  535. data/test/output_java/pie_wrapped_legend__800.png +0 -0
  536. data/test/output_java/pie_zero.png +0 -0
  537. data/test/output_java/scatter_all_neg.png +0 -0
  538. data/test/output_java/scatter_all_neg_400.png +0 -0
  539. data/test/output_java/scatter_basic.png +0 -0
  540. data/test/output_java/scatter_many.png +0 -0
  541. data/test/output_java/scatter_no_data.png +0 -0
  542. data/test/output_java/scatter_no_data_msg.png +0 -0
  543. data/test/output_java/scatter_no_data_other.png +0 -0
  544. data/test/output_java/scatter_no_hide.png +0 -0
  545. data/test/output_java/scatter_no_labels.png +0 -0
  546. data/test/output_java/scatter_no_legend.png +0 -0
  547. data/test/output_java/scatter_no_line_markers.png +0 -0
  548. data/test/output_java/scatter_no_title.png +0 -0
  549. data/test/output_java/scatter_nothing_but_the_graph.png +0 -0
  550. data/test/output_java/scatter_pos_neg.png +0 -0
  551. data/test/output_java/scatter_pos_neg_400.png +0 -0
  552. data/test/output_java/scatter_wide_graph.png +0 -0
  553. data/test/output_java/scatter_wide_graph_small.png +0 -0
  554. data/test/output_java/scene_hazy_night.png +0 -0
  555. data/test/output_java/scene_not_hazy_day.png +0 -0
  556. data/test/output_java/scene_partly_cloudy_day.png +0 -0
  557. data/test/output_java/scene_stormy_day.png +0 -0
  558. data/test/output_java/scene_stormy_night.png +0 -0
  559. data/test/output_java/side_bar.png +0 -0
  560. data/test/output_java/side_bar_data_range.png +0 -0
  561. data/test/output_java/side_bar_labels.png +0 -0
  562. data/test/output_java/side_bar_spacing_full.png +0 -0
  563. data/test/output_java/side_bar_spacing_half.png +0 -0
  564. data/test/output_java/side_bar_spacing_none.png +0 -0
  565. data/test/output_java/side_stacked_bar_keynote.png +0 -0
  566. data/test/output_java/side_stacked_bar_keynote_small.png +0 -0
  567. data/test/output_java/side_stacked_bar_labels.png +0 -0
  568. data/test/output_java/side_stacked_bar_long_label.png +0 -0
  569. data/test/output_java/side_stacked_bar_wide.png +0 -0
  570. data/test/output_java/spider_37signals.png +0 -0
  571. data/test/output_java/spider_equal.png +0 -0
  572. data/test/output_java/spider_keynote.png +0 -0
  573. data/test/output_java/spider_legend.png +0 -0
  574. data/test/output_java/spider_legend_small.png +0 -0
  575. data/test/output_java/spider_lots_of_data.png +0 -0
  576. data/test/output_java/spider_lots_of_data_normal_names.png +0 -0
  577. data/test/output_java/spider_nearly_equal.png +0 -0
  578. data/test/output_java/spider_no_axes.png +0 -0
  579. data/test/output_java/spider_no_background.png +0 -0
  580. data/test/output_java/spider_no_print.png +0 -0
  581. data/test/output_java/spider_overlay_1.png +0 -0
  582. data/test/output_java/spider_overlay_2.png +0 -0
  583. data/test/output_java/spider_rotation.png +0 -0
  584. data/test/output_java/spider_small.png +0 -0
  585. data/test/output_java/spider_wide.png +0 -0
  586. data/test/output_java/spider_zero.png +0 -0
  587. data/test/output_java/stacked_area_keynote.png +0 -0
  588. data/test/output_java/stacked_area_keynote_small.png +0 -0
  589. data/test/output_java/stacked_bar_keynote.png +0 -0
  590. data/test/output_java/stacked_bar_keynote_small.png +0 -0
  591. data/test/test_accumulator_bar.rb +0 -51
  592. data/test/test_area.rb +0 -134
  593. data/test/test_bar.rb +0 -505
  594. data/test/test_base.rb +0 -8
  595. data/test/test_bezier.rb +0 -33
  596. data/test/test_bullet.rb +0 -26
  597. data/test/test_dot.rb +0 -263
  598. data/test/test_legend.rb +0 -68
  599. data/test/test_line.rb +0 -657
  600. data/test/test_mini_bar.rb +0 -33
  601. data/test/test_mini_pie.rb +0 -25
  602. data/test/test_mini_side_bar.rb +0 -36
  603. data/test/test_net.rb +0 -231
  604. data/test/test_photo.rb +0 -41
  605. data/test/test_pie.rb +0 -154
  606. data/test/test_scatter.rb +0 -233
  607. data/test/test_scene.rb +0 -100
  608. data/test/test_side_bar.rb +0 -56
  609. data/test/test_sidestacked_bar.rb +0 -105
  610. data/test/test_spider.rb +0 -226
  611. data/test/test_stacked_area.rb +0 -52
  612. data/test/test_stacked_bar.rb +0 -52
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
1
2
 
2
- require "observer"
3
- require File.dirname(__FILE__) + '/base'
3
+ require 'observer'
4
+ require 'gruff/base'
4
5
 
5
- ##
6
6
  # A scene is a non-linear graph that assembles layers together to tell a story.
7
- # Layers are folders with appropriately named files (see below). You can group
7
+ # Layers are folders with appropriately named files (see below). You can group
8
8
  # layers and control them together or just set their values individually.
9
9
  #
10
10
  # Examples:
@@ -12,8 +12,6 @@ require File.dirname(__FILE__) + '/base'
12
12
  # * A city scene that changes with the time of day and the weather conditions.
13
13
  # * A traffic map that shows red lines on streets that are crowded and green on free-flowing ones.
14
14
  #
15
- # Usage:
16
- #
17
15
  # g = Gruff::Scene.new("500x100", "path/to/city_scene_directory")
18
16
  #
19
17
  # # Define order of layers, back to front
@@ -31,34 +29,31 @@ require File.dirname(__FILE__) + '/base'
31
29
  # # Write the final graph to disk
32
30
  # g.write "hazy_daytime_city_scene.png"
33
31
  #
34
- #
35
32
  # There are several rules that will magically select a layer when possible.
36
33
  #
37
34
  # * Numbered files will be selected according to the closest value that is less than the input value.
38
- # * 'true.png' and 'false.png' will be used as booleans.
35
+ # * +'true.png'+ and +'false.png'+ will be used as booleans.
39
36
  # * Other named files will be used if the input matches the filename (without the filetype extension).
40
- # * If there is a file named 'default.png', it will be used unless other input values are set for the corresponding layer.
41
-
37
+ # * If there is a file named +'default.png'+, it will be used unless other input values are set for the corresponding layer.
42
38
  class Gruff::Scene < Gruff::Base
43
-
44
- # An array listing the foldernames that will be rendered, from back to front.
45
- #
46
- # g.layers = %w(sky clouds buildings street people)
39
+ # An array listing the folder names that will be rendered, from back to front.
47
40
  #
41
+ # @example
42
+ # g.layers = %w(sky clouds buildings street people)
48
43
  attr_reader :layers
49
44
 
50
45
  def initialize(target_width, base_dir)
51
46
  @base_dir = base_dir
52
47
  @groups = {}
53
- @layers = []
48
+ @layers = []
54
49
  super target_width
55
50
  end
56
51
 
57
52
  def draw
58
53
  # Join all the custom paths and filter out the empty ones
59
- image_paths = @layers.map { |layer| layer.path }.select { |path| !path.empty? }
54
+ image_paths = @layers.map(&:path).reject(&:empty?)
60
55
  images = Magick::ImageList.new(*image_paths)
61
- @base_image = images.flatten_images
56
+ Gruff::Renderer.background_image = images.flatten_images
62
57
  end
63
58
 
64
59
  def layers=(ordered_list)
@@ -78,10 +73,10 @@ class Gruff::Scene < Gruff::Base
78
73
  def method_missing(method_name, *args)
79
74
  case method_name.to_s
80
75
  when /^(\w+)_group=$/
81
- add_group $1, *args
76
+ add_group Regexp.last_match(1), *args
82
77
  return
83
78
  when /^(\w+)=$/
84
- set_input $1, args.first
79
+ set_input Regexp.last_match(1), args.first
85
80
  return
86
81
  end
87
82
  super
@@ -94,20 +89,16 @@ private
94
89
  end
95
90
 
96
91
  def set_input(input_name, input_value)
97
- if not @groups[input_name].nil?
92
+ if !@groups[input_name].nil?
98
93
  @groups[input_name].send_updates(input_value)
99
- else
100
- if chosen_layer = @layers.detect { |layer| layer.name == input_name }
101
- chosen_layer.update input_value
102
- end
94
+ elsif chosen_layer = @layers.find { |layer| layer.name == input_name }
95
+ chosen_layer.update input_value
103
96
  end
104
97
  end
105
-
106
98
  end
107
99
 
108
-
100
+ # @private
109
101
  class Gruff::Group
110
-
111
102
  include Observable
112
103
  attr_reader :name
113
104
 
@@ -117,31 +108,29 @@ class Gruff::Group
117
108
  layer.observe self
118
109
  end
119
110
  end
120
-
111
+
121
112
  def send_updates(value)
122
113
  changed
123
114
  notify_observers value
124
115
  end
125
-
126
116
  end
127
117
 
128
-
118
+ # @private
129
119
  class Gruff::Layer
130
-
131
120
  attr_reader :name
132
-
121
+
133
122
  def initialize(base_dir, folder_name)
134
123
  @base_dir = base_dir.to_s
135
124
  @name = folder_name.to_s
136
125
  @filenames = Dir.open(File.join(base_dir, folder_name)).entries.select { |file| file =~ /^[^.]+\.png$/ }.sort
137
126
  @selected_filename = select_default
138
127
  end
139
-
128
+
140
129
  # Register this layer so it receives updates from the group
141
130
  def observe(obj)
142
131
  obj.add_observer self
143
132
  end
144
-
133
+
145
134
  # Choose the appropriate filename for this layer, based on the input
146
135
  def update(value)
147
136
  @selected_filename = case value.to_s
@@ -152,7 +141,7 @@ class Gruff::Layer
152
141
  when /^-?(\d+\.)?\d+$/
153
142
  select_numeric value
154
143
  when /(\d\d):(\d\d):\d\d/
155
- select_time "#{$1}#{$2}"
144
+ select_time "#{Regexp.last_match(1)}#{Regexp.last_match(2)}"
156
145
  else
157
146
  select_default
158
147
  end
@@ -165,6 +154,7 @@ class Gruff::Layer
165
154
  unless @selected_filename.nil? || @selected_filename.empty?
166
155
  return File.join(@base_dir, @name, @selected_filename)
167
156
  end
157
+
168
158
  ''
169
159
  end
170
160
 
@@ -179,7 +169,7 @@ private
179
169
  def select_numeric(value)
180
170
  file_exists_or_blank value.to_s.gsub('-', '_')
181
171
  end
182
-
172
+
183
173
  def select_time(value)
184
174
  times = @filenames.map { |filename| filename.gsub('.png', '') }
185
175
  times.each_with_index do |time, index|
@@ -187,16 +177,17 @@ private
187
177
  return "#{times[index - 1]}.png"
188
178
  end
189
179
  end
190
- return "#{times.last}.png"
180
+
181
+ "#{times.last}.png"
191
182
  end
192
-
183
+
193
184
  # Match "partly cloudy" to "partly_cloudy.png"
194
185
  def select_string(value)
195
186
  file_exists_or_blank value.to_s.gsub(' ', '_')
196
187
  end
197
-
188
+
198
189
  def select_default
199
- @filenames.include?("default.png") ? "default.png" : ''
190
+ @filenames.include?('default.png') ? 'default.png' : ''
200
191
  end
201
192
 
202
193
  # Returns the string "#{filename}.png", if it exists.
@@ -205,5 +196,4 @@ private
205
196
  def file_exists_or_blank(filename)
206
197
  @filenames.include?("#{filename}.png") ? "#{filename}.png" : select_default
207
198
  end
208
-
209
199
  end
@@ -1,44 +1,61 @@
1
- require File.dirname(__FILE__) + '/base'
1
+ # frozen_string_literal: true
2
2
 
3
- ##
4
- # Graph with individual horizontal bars instead of vertical bars.
3
+ require 'gruff/base'
5
4
 
5
+ # Graph with individual horizontal bars instead of vertical bars.
6
6
  class Gruff::SideBar < Gruff::Base
7
-
8
- # Spacing factor applied between bars
7
+ # Spacing factor applied between bars.
9
8
  attr_accessor :bar_spacing
10
9
 
10
+ # Spacing factor applied between a group of bars belonging to the same label.
11
+ attr_accessor :group_spacing
12
+
13
+ # Set the number output format for labels using sprintf.
14
+ # Default is +"%.2f"+.
15
+ attr_accessor :label_formatting
16
+
17
+ # Output the values for the bars on a bar graph.
18
+ # Default is +false+.
19
+ attr_accessor :show_labels_for_bar_values
20
+
21
+ def initialize_ivars
22
+ super
23
+ @label_formatting = nil
24
+ @show_labels_for_bar_values = false
25
+ end
26
+ private :initialize_ivars
27
+
11
28
  def draw
12
29
  @has_left_labels = true
13
30
  super
14
31
 
15
- return unless @has_data
32
+ return unless data_given?
33
+
16
34
  draw_bars
17
35
  end
18
36
 
19
- protected
37
+ private
20
38
 
21
39
  def draw_bars
22
40
  # Setup spacing.
23
41
  #
24
42
  @bar_spacing ||= 0.9
43
+ @group_spacing ||= 10
25
44
 
26
- @bars_width = @graph_height / @column_count.to_f
27
- @bar_width = @bars_width / @norm_data.size
28
- @d = @d.stroke_opacity 0.0
29
- height = Array.new(@column_count, 0)
30
- length = Array.new(@column_count, @graph_left)
31
- padding = (@bar_width * (1 - @bar_spacing)) / 2
45
+ bars_width = (@graph_height - calculate_spacing) / column_count.to_f
46
+ bar_width = bars_width / store.length
47
+ height = Array.new(column_count, 0)
48
+ length = Array.new(column_count, @graph_left)
49
+ padding = (bar_width * (1 - @bar_spacing)) / 2
32
50
 
33
51
  # if we're a side stacked bar then we don't need to draw ourself at all
34
52
  # because sometimes (due to different heights/min/max) you can actually
35
53
  # see both graphs and it looks like crap
36
- return if self.is_a?(Gruff::SideStackedBar)
54
+ return if is_a?(Gruff::SideStackedBar)
37
55
 
38
- @norm_data.each_with_index do |data_row, row_index|
39
- @d = @d.fill data_row[DATA_COLOR_INDEX]
40
-
41
- data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
56
+ store.norm_data.each_with_index do |data_row, row_index|
57
+ data_row.points.each_with_index do |data_point, point_index|
58
+ group_spacing = @group_spacing * @scale * point_index
42
59
 
43
60
  # Using the original calcs from the stacked bar chart
44
61
  # to get the difference between
@@ -48,91 +65,75 @@ class Gruff::SideBar < Gruff::Base
48
65
  difference = temp2 - temp1
49
66
 
50
67
  left_x = length[point_index] - 1
51
- left_y = @graph_top + (@bars_width * point_index) + (@bar_width * row_index) + padding
68
+ left_y = @graph_top + (bars_width * point_index) + (bar_width * row_index) + padding + group_spacing
52
69
  right_x = left_x + difference
53
- right_y = left_y + @bar_width * @bar_spacing
70
+ right_y = left_y + bar_width * @bar_spacing
54
71
 
55
72
  height[point_index] += (data_point * @graph_width)
56
73
 
57
- @d = @d.rectangle(left_x, left_y, right_x, right_y)
74
+ rect_renderer = Gruff::Renderer::Rectangle.new(color: data_row.color)
75
+ rect_renderer.render(left_x, left_y, right_x, right_y)
58
76
 
59
77
  # Calculate center based on bar_width and current row
60
78
 
61
79
  if @use_data_label
62
- label_center = @graph_top + (@bar_width * (row_index+point_index) + @bar_width / 2)
63
- draw_label(label_center, row_index, @norm_data[row_index][DATA_LABEL_INDEX])
80
+ label_center = left_y + bar_width / 2
81
+ draw_label(label_center, row_index, store.norm_data[row_index].label)
64
82
  else
65
- label_center = @graph_top + (@bars_width * point_index + @bars_width / 2)
83
+ label_center = left_y + bars_width / 2
66
84
  draw_label(label_center, point_index)
67
85
  end
68
86
  if @show_labels_for_bar_values
69
- val = (@label_formatting || '%.2f') % @norm_data[row_index][3][point_index]
70
- draw_value_label(right_x+40, (@graph_top + (((row_index+point_index+1) * @bar_width) - (@bar_width / 2)))-12, val.commify, true)
87
+ val = (@label_formatting || '%.2f') % store.data[row_index].points[point_index]
88
+ draw_value_label(right_x + 40, right_y - bar_width / 2, val.commify, true)
71
89
  end
72
90
  end
73
-
74
91
  end
75
92
 
76
- @d.draw(@base_image)
93
+ Gruff::Renderer.finish
77
94
  end
78
95
 
79
96
  # Instead of base class version, draws vertical background lines and label
80
97
  def draw_line_markers
81
-
82
98
  return if @hide_line_markers
83
99
 
84
- @d = @d.stroke_antialias false
85
-
86
100
  # Draw horizontal line markers and annotate with numbers
87
- @d = @d.stroke(@marker_color)
88
- @d = @d.stroke_width 1
89
101
  number_of_lines = @marker_count || 5
90
102
  number_of_lines = 1 if number_of_lines == 0
91
103
 
92
- # TODO Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
104
+ # TODO: Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
93
105
  increment = significant(@spread.to_f / number_of_lines)
94
106
  (0..number_of_lines).each do |index|
95
-
96
107
  line_diff = (@graph_right - @graph_left) / number_of_lines
97
108
  x = @graph_right - (line_diff * index) - 1
98
- @d = @d.line(x, @graph_bottom, x, @graph_top)
109
+ Gruff::Renderer::Line.new(color: @marker_color).render(x, @graph_bottom, x, @graph_top)
99
110
  diff = index - number_of_lines
100
- marker_label = diff.abs * increment + @minimum_value
111
+ marker_label = diff.abs * increment + minimum_value
101
112
 
102
113
  unless @hide_line_numbers
103
- @d.fill = @font_color
104
- @d.font = @font if @font
105
- @d.stroke = 'transparent'
106
- @d.pointsize = scale_fontsize(@marker_font_size)
107
- @d.gravity = CenterGravity
108
- # TODO Center text over line
109
- @d = @d.annotate_scaled(@base_image,
110
- 0, 0, # Width of box to draw text in
111
- x, @graph_bottom + (LABEL_MARGIN * 2.0), # Coordinates of text
112
- marker_label.to_s, @scale)
113
- end # unless
114
- @d = @d.stroke_antialias true
114
+ text_renderer = Gruff::Renderer::Text.new(marker_label, font: @font, size: @marker_font_size, color: @font_color)
115
+ text_renderer.render(0, 0, x, @graph_bottom + (LABEL_MARGIN * 2.0), Magick::CenterGravity)
116
+ end
115
117
  end
116
118
  end
117
119
 
118
120
  ##
119
121
  # Draw on the Y axis instead of the X
120
122
 
121
- def draw_label(y_offset, index, label=nil)
122
- if !@labels[index].nil? && @labels_seen[index].nil?
123
- lbl = (@use_data_label) ? label : @labels[index]
124
- @d.fill = @font_color
125
- @d.font = @font if @font
126
- @d.stroke = 'transparent'
127
- @d.font_weight = NormalWeight
128
- @d.pointsize = scale_fontsize(@marker_font_size)
129
- @d.gravity = EastGravity
130
- @d = @d.annotate_scaled(@base_image,
131
- 1, 1,
132
- -@graph_left + LABEL_MARGIN * 2.0, y_offset,
133
- lbl, @scale)
134
- @labels_seen[index] = 1
123
+ def draw_label(y_offset, index, label = nil)
124
+ draw_unique_label(index) do
125
+ lbl = @use_data_label ? label : @labels[index]
126
+
127
+ text_renderer = Gruff::Renderer::Text.new(lbl, font: @font, size: @marker_font_size, color: @font_color)
128
+ if RUBY_PLATFORM == 'java'
129
+ text_renderer.render(1, 1, @graph_left - LABEL_MARGIN * 2.0, y_offset, Magick::EastGravity)
130
+ else
131
+ text_renderer.render(1, 1, -@graph_left + LABEL_MARGIN * 2.0, y_offset, Magick::EastGravity)
132
+ end
135
133
  end
136
134
  end
137
135
 
136
+ def calculate_spacing
137
+ @scale * @group_spacing * (column_count - 1)
138
+ end
138
139
  end
@@ -1,97 +1,99 @@
1
- require File.dirname(__FILE__) + '/base'
2
- require File.dirname(__FILE__) + '/side_bar'
3
- require File.dirname(__FILE__) + '/stacked_mixin'
1
+ # frozen_string_literal: true
4
2
 
5
- ##
6
- # New gruff graph type added to enable sideways stacking bar charts
3
+ require 'gruff/side_bar'
4
+ require 'gruff/helper/stacked_mixin'
5
+
6
+ # New gruff graph type added to enable sideways stacking bar charts
7
7
  # (basically looks like a x/y flip of a standard stacking bar chart)
8
8
  #
9
- # alun.eyre@googlemail.com
10
-
9
+ # alun.eyre@googlemail.com
11
10
  class Gruff::SideStackedBar < Gruff::SideBar
12
11
  include StackedMixin
12
+ include BarValueLabelMixin
13
13
 
14
- # Spacing factor applied between bars
14
+ # Spacing factor applied between bars.
15
15
  attr_accessor :bar_spacing
16
-
16
+
17
+ # Number of pixels between bar segments.
18
+ attr_accessor :segment_spacing
19
+
20
+ # Set the number output format for labels using sprintf.
21
+ # Default is +"%.2f"+.
22
+ attr_accessor :label_formatting
23
+
24
+ # Output the values for the bars on a bar graph.
25
+ # Default is +false+.
26
+ attr_accessor :show_labels_for_bar_values
27
+
28
+ def initialize_ivars
29
+ super
30
+ @label_formatting = nil
31
+ @show_labels_for_bar_values = false
32
+ end
33
+ private :initialize_ivars
34
+
17
35
  def draw
18
36
  @has_left_labels = true
19
37
  get_maximum_by_stack
20
38
  super
21
39
  end
22
40
 
23
- protected
41
+ private
24
42
 
25
43
  def draw_bars
26
44
  # Setup spacing.
27
45
  #
28
46
  # Columns sit stacked.
29
47
  @bar_spacing ||= 0.9
48
+ @segment_spacing ||= 2.0
30
49
 
31
- @bar_width = @graph_height / @column_count.to_f
32
- @d = @d.stroke_opacity 0.0
33
- height = Array.new(@column_count, 0)
34
- length = Array.new(@column_count, @graph_left)
35
- padding = (@bar_width * (1 - @bar_spacing)) / 2
36
- if @show_labels_for_bar_values
37
- label_values = Array.new
38
- 0.upto(@column_count-1) {|i| label_values[i] = {:value => 0, :right_x => 0}}
39
- end
40
- @norm_data.each_with_index do |data_row, row_index|
41
- data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
42
-
43
- ## using the original calcs from the stacked bar chart to get the difference between
44
- ## part of the bart chart we wish to stack.
45
- temp1 = @graph_left + (@graph_width -
46
- data_point * @graph_width -
47
- height[point_index]) + 1
48
- temp2 = @graph_left + @graph_width - height[point_index] - 1
49
- difference = temp2 - temp1
50
-
51
- @d = @d.fill data_row[DATA_COLOR_INDEX]
52
-
53
- left_x = length[point_index] #+ 1
54
- left_y = @graph_top + (@bar_width * point_index) + padding
55
- right_x = left_x + difference
56
- right_y = left_y + @bar_width * @bar_spacing
57
- length[point_index] += difference
50
+ bar_width = @graph_height / column_count.to_f
51
+ height = Array.new(column_count, 0)
52
+ length = Array.new(column_count, @graph_left)
53
+ padding = (bar_width * (1 - @bar_spacing)) / 2
54
+ bar_value_label = BarValueLabel.new(column_count, bar_width)
55
+
56
+ store.norm_data.each_with_index do |data_row, row_index|
57
+ data_row.points.each_with_index do |data_point, point_index|
58
+ ## using the original calcs from the stacked bar chart to get the difference between
59
+ ## part of the bart chart we wish to stack.
60
+ temp1 = @graph_left + (@graph_width -
61
+ data_point * @graph_width -
62
+ height[point_index]) + 1
63
+ temp2 = @graph_left + @graph_width - height[point_index] - 1
64
+ difference = temp2 - temp1
65
+
66
+ left_x = length[point_index]
67
+ left_y = @graph_top + (bar_width * point_index) + padding
68
+ right_x = left_x + difference - @segment_spacing
69
+ right_y = left_y + bar_width * @bar_spacing
70
+ length[point_index] += difference
58
71
  height[point_index] += (data_point * @graph_width - 2)
59
-
60
- if @show_labels_for_bar_values
61
- label_values[point_index][:value] += @norm_data[row_index][3][point_index]
62
- label_values[point_index][:right_x] = right_x
63
- end
64
-
72
+
73
+ bar_value_label.coordinates[point_index] = [left_x, left_y, right_x, right_y]
74
+ bar_value_label.values[point_index] += store.data[row_index].points[point_index]
75
+
65
76
  # if a data point is 0 it can result in weird really thing lines
66
77
  # that shouldn't even be there being drawn on top of the existing
67
78
  # bar - this is bad
68
79
  if data_point != 0
69
- @d = @d.rectangle(left_x, left_y, right_x, right_y)
80
+ rect_renderer = Gruff::Renderer::Rectangle.new(color: data_row.color)
81
+ rect_renderer.render(left_x, left_y, right_x, right_y)
70
82
  # Calculate center based on bar_width and current row
71
83
  end
72
84
  # we still need to draw the labels
73
85
  # Calculate center based on bar_width and current row
74
- label_center = @graph_top + (@bar_width * point_index) + (@bar_width * @bar_spacing / 2.0)
86
+ label_center = left_y + bar_width / 2
75
87
  draw_label(label_center, point_index)
76
88
  end
77
-
78
89
  end
90
+
79
91
  if @show_labels_for_bar_values
80
- label_values.each_with_index do |data, i|
81
- val = (@label_formatting || "%.2f") % data[:value]
82
- draw_value_label(data[:right_x]+40, (@graph_top + (((i+1) * @bar_width) - (@bar_width / 2)))-12, val.commify, true)
92
+ bar_value_label.prepare_sidebar_rendering(@label_formatting) do |x, y, text|
93
+ draw_value_label(x, y, text, true)
83
94
  end
84
95
  end
85
-
86
- @d.draw(@base_image)
87
- end
88
96
 
89
- def larger_than_max?(data_point, index=0)
90
- max(data_point, index) > @maximum_value
97
+ Gruff::Renderer.finish
91
98
  end
92
-
93
- def max(data_point, index)
94
- @data.inject(0) {|sum, item| sum + item[DATA_VALUES_INDEX][index]}
95
- end
96
-
97
99
  end