gruff 0.5.0-java → 0.9.0-java

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 (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