gruff 0.3.7 → 0.4.0

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 (540) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -1
  3. data/.travis.yml +6 -0
  4. data/Gemfile +2 -8
  5. data/History.txt +76 -0
  6. data/MIT-LICENSE +3 -2
  7. data/README.md +96 -6
  8. data/RELEASE.md +92 -0
  9. data/Rakefile +203 -23
  10. data/gruff.gemspec +13 -10
  11. data/lib/gruff.rb +8 -7
  12. data/lib/gruff/accumulator_bar.rb +4 -13
  13. data/lib/gruff/area.rb +6 -13
  14. data/lib/gruff/bar.rb +24 -3
  15. data/lib/gruff/bar_conversion.rb +31 -31
  16. data/lib/gruff/base.rb +310 -267
  17. data/lib/gruff/bezier.rb +46 -0
  18. data/lib/gruff/bullet.rb +3 -1
  19. data/lib/gruff/dot.rb +56 -44
  20. data/lib/gruff/line.rb +83 -69
  21. data/lib/gruff/net.rb +7 -9
  22. data/lib/gruff/pie.rb +2 -4
  23. data/lib/gruff/scatter.rb +25 -29
  24. data/lib/gruff/side_bar.rb +54 -37
  25. data/lib/gruff/side_stacked_bar.rb +25 -5
  26. data/lib/gruff/spider.rb +22 -21
  27. data/lib/gruff/themes.rb +102 -0
  28. data/lib/gruff/version.rb +1 -1
  29. data/test/gruff_test_case.rb +68 -38
  30. data/test/image_compare.rb +58 -0
  31. data/test/output/accum_bar.png +0 -0
  32. data/test/output/area_keynote.png +0 -0
  33. data/test/output/area_keynote_small.png +0 -0
  34. data/test/output/area_many.png +0 -0
  35. data/test/output/area_many_areas_small.png +0 -0
  36. data/test/output/area_tiny.png +0 -0
  37. data/test/output/area_wide.png +0 -0
  38. data/test/output/bar2_wrapped_legend_16_400.png +0 -0
  39. data/test/output/bar2_wrapped_legend_16_800.png +0 -0
  40. data/test/output/bar2_wrapped_legend_30_400.png +0 -0
  41. data/test/output/bar2_wrapped_legend_30_800.png +0 -0
  42. data/test/output/bar2_wrapped_legend_4_400.png +0 -0
  43. data/test/output/bar2_wrapped_legend_4_800.png +0 -0
  44. data/test/output/bar2_wrapped_legend__400.png +0 -0
  45. data/test/output/bar2_wrapped_legend__800.png +0 -0
  46. data/test/output/bar_background_gradient_bottom_top.png +0 -0
  47. data/test/output/bar_background_gradient_left_right.png +0 -0
  48. data/test/output/bar_background_gradient_right_left.png +0 -0
  49. data/test/output/bar_background_gradient_top_bottom.png +0 -0
  50. data/test/output/bar_background_gradient_topleft_bottomright.png +0 -0
  51. data/test/output/bar_background_gradient_topright_bottomleft.png +0 -0
  52. data/test/output/bar_formatted_numbers.png +0 -0
  53. data/test/output/bar_keynote.png +0 -0
  54. data/test/output/bar_keynote_small.png +0 -0
  55. data/test/output/bar_long_legend_text.png +0 -0
  56. data/test/output/bar_manual_colors.png +0 -0
  57. data/test/output/bar_marker_shadow.png +0 -0
  58. data/test/output/bar_nearly_zero_max_10.png +0 -0
  59. data/test/output/bar_no_legend.png +0 -0
  60. data/test/output/bar_no_line_markers.png +0 -0
  61. data/test/output/bar_no_title.png +0 -0
  62. data/test/output/bar_no_title_or_legend.png +0 -0
  63. data/test/output/bar_odeo.png +0 -0
  64. data/test/output/bar_one_value.png +0 -0
  65. data/test/output/bar_pos_neg.png +0 -0
  66. data/test/output/bar_rails_keynote.png +0 -0
  67. data/test/output/bar_set_absolute_trunc.png +0 -0
  68. data/test/output/bar_set_label_stagger_height.png +0 -0
  69. data/test/output/bar_set_legend_box_size_lg.png +0 -0
  70. data/test/output/bar_set_legend_box_size_sm.png +0 -0
  71. data/test/output/bar_set_marker.png +0 -0
  72. data/test/output/bar_set_trailing_dots_trunc.png +0 -0
  73. data/test/output/bar_spacing_full.png +0 -0
  74. data/test/output/bar_spacing_half.png +0 -0
  75. data/test/output/bar_spacing_none.png +0 -0
  76. data/test/output/bar_tall_graph.png +0 -0
  77. data/test/output/bar_tall_graph_small.png +0 -0
  78. data/test/output/bar_themed.png +0 -0
  79. data/test/output/bar_title_margin.png +0 -0
  80. data/test/output/bar_value_labels.png +0 -0
  81. data/test/output/bar_wide_graph.png +0 -0
  82. data/test/output/bar_wide_graph_small.png +0 -0
  83. data/test/output/bar_wrapped_legend_16_400.png +0 -0
  84. data/test/output/bar_wrapped_legend_16_800.png +0 -0
  85. data/test/output/bar_wrapped_legend_30_400.png +0 -0
  86. data/test/output/bar_wrapped_legend_30_800.png +0 -0
  87. data/test/output/bar_wrapped_legend_4_400.png +0 -0
  88. data/test/output/bar_wrapped_legend_4_800.png +0 -0
  89. data/test/output/bar_wrapped_legend__400.png +0 -0
  90. data/test/output/bar_wrapped_legend__800.png +0 -0
  91. data/test/output/bar_x_y_labels.png +0 -0
  92. data/test/output/bar_y_increment_1.png +0 -0
  93. data/test/output/bar_y_increment_2.0.png +0 -0
  94. data/test/output/bar_y_increment_20.png +0 -0
  95. data/test/output/bar_y_increment_5.png +0 -0
  96. data/test/output/bar_zero_marker_count.png +0 -0
  97. data/test/output/bar_zero_spacing.png +0 -0
  98. data/test/output/bezier.png +0 -0
  99. data/test/output/bezier_2.png +0 -0
  100. data/test/output/bezier_3.png +0 -0
  101. data/test/output/bullet_greyscale.png +0 -0
  102. data/test/output/bullet_no_options.png +0 -0
  103. data/test/output/dot.png +0 -0
  104. data/test/output/dot_manual_colors.png +0 -0
  105. data/test/output/dot_nearly_zero_max_10.png +0 -0
  106. data/test/output/dot_no_legend.png +0 -0
  107. data/test/output/dot_no_line_markers.png +0 -0
  108. data/test/output/dot_no_title.png +0 -0
  109. data/test/output/dot_no_title_or_legend.png +0 -0
  110. data/test/output/dot_one_value.png +0 -0
  111. data/test/output/dot_pos_neg.png +0 -0
  112. data/test/output/dot_set_legend_box_size_lg.png +0 -0
  113. data/test/output/dot_set_legend_box_size_sm.png +0 -0
  114. data/test/output/dot_set_marker.png +0 -0
  115. data/test/output/dot_small.png +0 -0
  116. data/test/output/dot_tall_graph.png +0 -0
  117. data/test/output/dot_tall_graph_small.png +0 -0
  118. data/test/output/dot_themed.png +0 -0
  119. data/test/output/dot_wide_graph.png +0 -0
  120. data/test/output/dot_wide_graph_small.png +0 -0
  121. data/test/output/dot_x_y_labels.png +0 -0
  122. data/test/output/dot_y_increment_1.png +0 -0
  123. data/test/output/dot_y_increment_2.0.png +0 -0
  124. data/test/output/dot_y_increment_20.png +0 -0
  125. data/test/output/dot_y_increment_5.png +0 -0
  126. data/test/output/enhancements-1.png +0 -0
  127. data/test/output/enhancements.png +0 -0
  128. data/test/output/line_all_neg.png +0 -0
  129. data/test/output/line_all_neg_400.png +0 -0
  130. data/test/output/line_all_neg_no_max.png +0 -0
  131. data/test/output/line_baseline.png +0 -0
  132. data/test/output/line_hang_value.png +0 -0
  133. data/test/output/line_hide_dots.png +0 -0
  134. data/test/output/line_hide_lines.png +0 -0
  135. data/test/output/line_jruby_error.png +0 -0
  136. data/test/output/line_large.png +0 -0
  137. data/test/output/line_large_baseline.png +0 -0
  138. data/test/output/line_legend_at_bottom.png +0 -0
  139. data/test/output/line_many.png +0 -0
  140. data/test/output/line_many_lines_small.png +0 -0
  141. data/test/output/line_many_numbers.png +0 -0
  142. data/test/output/line_marker_label_accuracy.png +0 -0
  143. data/test/output/line_more_sets_than_colors.png +0 -0
  144. data/test/output/line_no_data.png +0 -0
  145. data/test/output/line_no_data_msg.png +0 -0
  146. data/test/output/line_no_data_other.png +0 -0
  147. data/test/output/line_no_hide.png +0 -0
  148. data/test/output/line_no_legend.png +0 -0
  149. data/test/output/line_no_line_markers.png +0 -0
  150. data/test/output/line_no_title.png +0 -0
  151. data/test/output/line_nothing_but_the_graph.png +0 -0
  152. data/test/output/line_one_value.png +0 -0
  153. data/test/output/line_one_value_array.png +0 -0
  154. data/test/output/line_pos_neg.png +0 -0
  155. data/test/output/line_pos_neg_400.png +0 -0
  156. data/test/output/line_similar_high_end_values.png +0 -0
  157. data/test/output/line_similar_high_end_values_with_floor.png +0 -0
  158. data/test/output/line_small_small_zero.png +0 -0
  159. data/test/output/line_small_values.png +0 -0
  160. data/test/output/line_small_values_small.png +0 -0
  161. data/test/output/line_small_zero.png +0 -0
  162. data/test/output/line_some_nil_points.png +0 -0
  163. data/test/output/line_theme_37signals_.png +0 -0
  164. data/test/output/line_theme_37signals_400.png +0 -0
  165. data/test/output/line_theme_keynote_.png +0 -0
  166. data/test/output/line_theme_keynote_400.png +0 -0
  167. data/test/output/line_theme_odeo_.png +0 -0
  168. data/test/output/line_theme_odeo_400.png +0 -0
  169. data/test/output/line_theme_rails_keynote_.png +0 -0
  170. data/test/output/line_theme_rails_keynote_400.png +0 -0
  171. data/test/output/line_tiny.png +0 -0
  172. data/test/output/line_transparent.png +0 -0
  173. data/test/output/line_very_small.png +0 -0
  174. data/test/output/line_wide_graph.png +0 -0
  175. data/test/output/line_wide_graph_small.png +0 -0
  176. data/test/output/line_xy.png +0 -0
  177. data/test/output/line_xy_pairs.png +0 -0
  178. data/test/output/line_y_axis_increment.png +0 -0
  179. data/test/output/mini_bar.png +0 -0
  180. data/test/output/mini_pie.png +0 -0
  181. data/test/output/mini_pie_right_legend.png +0 -0
  182. data/test/output/mini_side_bar.png +0 -0
  183. data/test/output/mini_side_bar_multi_color.png +0 -0
  184. data/test/output/net_dots_tiny.png +0 -0
  185. data/test/output/net_large.png +0 -0
  186. data/test/output/net_many.png +0 -0
  187. data/test/output/net_many_nets_small.png +0 -0
  188. data/test/output/net_no_data.png +0 -0
  189. data/test/output/net_no_data_msg.png +0 -0
  190. data/test/output/net_no_data_other.png +0 -0
  191. data/test/output/net_no_legend.png +0 -0
  192. data/test/output/net_no_net_markers.png +0 -0
  193. data/test/output/net_no_title.png +0 -0
  194. data/test/output/net_nothing_but_the_graph.png +0 -0
  195. data/test/output/net_similar_high_end_values.png +0 -0
  196. data/test/output/net_small.png +0 -0
  197. data/test/output/net_small_small.png +0 -0
  198. data/test/output/net_small_small_zero.png +0 -0
  199. data/test/output/net_small_zero.png +0 -0
  200. data/test/output/net_wide_graph.png +0 -0
  201. data/test/output/net_wide_graph_small.png +0 -0
  202. data/test/output/pie_equal.png +0 -0
  203. data/test/output/pie_grey.png +0 -0
  204. data/test/output/pie_keynote.png +0 -0
  205. data/test/output/pie_keynote_small.png +0 -0
  206. data/test/output/pie_legend.png +0 -0
  207. data/test/output/pie_legend_small.png +0 -0
  208. data/test/output/pie_nearly_equal.png +0 -0
  209. data/test/output/pie_one_val.png +0 -0
  210. data/test/output/pie_pastel.png +0 -0
  211. data/test/output/pie_simple.png +0 -0
  212. data/test/output/pie_wide.png +0 -0
  213. data/test/output/pie_wrapped_legend_16_400.png +0 -0
  214. data/test/output/pie_wrapped_legend_16_800.png +0 -0
  215. data/test/output/pie_wrapped_legend_30_400.png +0 -0
  216. data/test/output/pie_wrapped_legend_30_800.png +0 -0
  217. data/test/output/pie_wrapped_legend_4_400.png +0 -0
  218. data/test/output/pie_wrapped_legend_4_800.png +0 -0
  219. data/test/output/pie_wrapped_legend__400.png +0 -0
  220. data/test/output/pie_wrapped_legend__800.png +0 -0
  221. data/test/output/pie_zero.png +0 -0
  222. data/test/output/scatter_all_neg.png +0 -0
  223. data/test/output/scatter_all_neg_400.png +0 -0
  224. data/test/output/scatter_basic.png +0 -0
  225. data/test/output/scatter_many.png +0 -0
  226. data/test/output/scatter_no_data.png +0 -0
  227. data/test/output/scatter_no_data_msg.png +0 -0
  228. data/test/output/scatter_no_data_other.png +0 -0
  229. data/test/output/scatter_no_hide.png +0 -0
  230. data/test/output/scatter_no_labels.png +0 -0
  231. data/test/output/scatter_no_legend.png +0 -0
  232. data/test/output/scatter_no_line_markers.png +0 -0
  233. data/test/output/scatter_no_title.png +0 -0
  234. data/test/output/scatter_nothing_but_the_graph.png +0 -0
  235. data/test/output/scatter_pos_neg.png +0 -0
  236. data/test/output/scatter_pos_neg_400.png +0 -0
  237. data/test/output/scatter_wide_graph.png +0 -0
  238. data/test/output/scatter_wide_graph_small.png +0 -0
  239. data/test/output/scene_hazy_night.png +0 -0
  240. data/test/output/scene_not_hazy_day.png +0 -0
  241. data/test/output/scene_partly_cloudy_day.png +0 -0
  242. data/test/output/scene_stormy_day.png +0 -0
  243. data/test/output/scene_stormy_night.png +0 -0
  244. data/test/output/side_bar.png +0 -0
  245. data/test/output/side_bar_data_range.png +0 -0
  246. data/test/output/side_bar_labels.png +0 -0
  247. data/test/output/side_bar_spacing_full.png +0 -0
  248. data/test/output/side_bar_spacing_half.png +0 -0
  249. data/test/output/side_bar_spacing_none.png +0 -0
  250. data/test/output/side_stacked_bar_keynote.png +0 -0
  251. data/test/output/side_stacked_bar_keynote_small.png +0 -0
  252. data/test/output/side_stacked_bar_labels.png +0 -0
  253. data/test/output/side_stacked_bar_long_label.png +0 -0
  254. data/test/output/side_stacked_bar_wide.png +0 -0
  255. data/test/output/spider_37signals.png +0 -0
  256. data/test/output/spider_equal.png +0 -0
  257. data/test/output/spider_keynote.png +0 -0
  258. data/test/output/spider_legend.png +0 -0
  259. data/test/output/spider_legend_small.png +0 -0
  260. data/test/output/spider_lots_of_data.png +0 -0
  261. data/test/output/spider_lots_of_data_normal_names.png +0 -0
  262. data/test/output/spider_nearly_equal.png +0 -0
  263. data/test/output/spider_no_axes.png +0 -0
  264. data/test/output/spider_no_background.png +0 -0
  265. data/test/output/spider_no_print.png +0 -0
  266. data/test/output/spider_overlay_1.png +0 -0
  267. data/test/output/spider_overlay_2.png +0 -0
  268. data/test/output/spider_rotation.png +0 -0
  269. data/test/output/spider_small.png +0 -0
  270. data/test/output/spider_wide.png +0 -0
  271. data/test/output/spider_zero.png +0 -0
  272. data/test/output/stacked_area_keynote.png +0 -0
  273. data/test/output/stacked_area_keynote_small.png +0 -0
  274. data/test/output/stacked_bar_keynote.png +0 -0
  275. data/test/output/stacked_bar_keynote_small.png +0 -0
  276. data/test/output_java/accum_bar.png +0 -0
  277. data/test/output_java/area_keynote.png +0 -0
  278. data/test/output_java/area_keynote_small.png +0 -0
  279. data/test/output_java/area_many.png +0 -0
  280. data/test/output_java/area_many_areas_small.png +0 -0
  281. data/test/output_java/area_tiny.png +0 -0
  282. data/test/output_java/area_wide.png +0 -0
  283. data/test/output_java/bar2_wrapped_legend_16_400.png +0 -0
  284. data/test/output_java/bar2_wrapped_legend_16_800.png +0 -0
  285. data/test/output_java/bar2_wrapped_legend_30_400.png +0 -0
  286. data/test/output_java/bar2_wrapped_legend_30_800.png +0 -0
  287. data/test/output_java/bar2_wrapped_legend_4_400.png +0 -0
  288. data/test/output_java/bar2_wrapped_legend_4_800.png +0 -0
  289. data/test/output_java/bar2_wrapped_legend__400.png +0 -0
  290. data/test/output_java/bar2_wrapped_legend__800.png +0 -0
  291. data/test/output_java/bar_background_gradient_bottom_top.png +0 -0
  292. data/test/output_java/bar_background_gradient_left_right.png +0 -0
  293. data/test/output_java/bar_background_gradient_right_left.png +0 -0
  294. data/test/output_java/bar_background_gradient_top_bottom.png +0 -0
  295. data/test/output_java/bar_background_gradient_topleft_bottomright.png +0 -0
  296. data/test/output_java/bar_background_gradient_topright_bottomleft.png +0 -0
  297. data/test/output_java/bar_formatted_numbers.png +0 -0
  298. data/test/output_java/bar_keynote.png +0 -0
  299. data/test/output_java/bar_keynote_small.png +0 -0
  300. data/test/output_java/bar_long_legend_text.png +0 -0
  301. data/test/output_java/bar_manual_colors.png +0 -0
  302. data/test/output_java/bar_marker_shadow.png +0 -0
  303. data/test/output_java/bar_nearly_zero_max_10.png +0 -0
  304. data/test/output_java/bar_no_legend.png +0 -0
  305. data/test/output_java/bar_no_line_markers.png +0 -0
  306. data/test/output_java/bar_no_title.png +0 -0
  307. data/test/output_java/bar_no_title_or_legend.png +0 -0
  308. data/test/output_java/bar_odeo.png +0 -0
  309. data/test/output_java/bar_one_value.png +0 -0
  310. data/test/output_java/bar_pos_neg.png +0 -0
  311. data/test/output_java/bar_rails_keynote.png +0 -0
  312. data/test/output_java/bar_set_absolute_trunc.png +0 -0
  313. data/test/output_java/bar_set_label_stagger_height.png +0 -0
  314. data/test/output_java/bar_set_legend_box_size_lg.png +0 -0
  315. data/test/output_java/bar_set_legend_box_size_sm.png +0 -0
  316. data/test/output_java/bar_set_marker.png +0 -0
  317. data/test/output_java/bar_set_trailing_dots_trunc.png +0 -0
  318. data/test/output_java/bar_spacing_full.png +0 -0
  319. data/test/output_java/bar_spacing_half.png +0 -0
  320. data/test/output_java/bar_spacing_none.png +0 -0
  321. data/test/output_java/bar_tall_graph.png +0 -0
  322. data/test/output_java/bar_tall_graph_small.png +0 -0
  323. data/test/output_java/bar_themed.png +0 -0
  324. data/test/output_java/bar_title_margin.png +0 -0
  325. data/test/output_java/bar_value_labels.png +0 -0
  326. data/test/output_java/bar_wide_graph.png +0 -0
  327. data/test/output_java/bar_wide_graph_small.png +0 -0
  328. data/test/output_java/bar_wrapped_legend_16_400.png +0 -0
  329. data/test/output_java/bar_wrapped_legend_16_800.png +0 -0
  330. data/test/output_java/bar_wrapped_legend_30_400.png +0 -0
  331. data/test/output_java/bar_wrapped_legend_30_800.png +0 -0
  332. data/test/output_java/bar_wrapped_legend_4_400.png +0 -0
  333. data/test/output_java/bar_wrapped_legend_4_800.png +0 -0
  334. data/test/output_java/bar_wrapped_legend__400.png +0 -0
  335. data/test/output_java/bar_wrapped_legend__800.png +0 -0
  336. data/test/output_java/bar_x_y_labels.png +0 -0
  337. data/test/output_java/bar_y_increment_1.png +0 -0
  338. data/test/output_java/bar_y_increment_2.0.png +0 -0
  339. data/test/output_java/bar_y_increment_20.png +0 -0
  340. data/test/output_java/bar_y_increment_5.png +0 -0
  341. data/test/output_java/bar_zero_marker_count.png +0 -0
  342. data/test/output_java/bar_zero_spacing.png +0 -0
  343. data/test/output_java/bezier.png +0 -0
  344. data/test/output_java/bezier_2.png +0 -0
  345. data/test/output_java/bezier_3.png +0 -0
  346. data/test/output_java/bullet_greyscale.png +0 -0
  347. data/test/output_java/bullet_no_options.png +0 -0
  348. data/test/output_java/dot.png +0 -0
  349. data/test/output_java/dot_manual_colors.png +0 -0
  350. data/test/output_java/dot_nearly_zero_max_10.png +0 -0
  351. data/test/output_java/dot_no_legend.png +0 -0
  352. data/test/output_java/dot_no_line_markers.png +0 -0
  353. data/test/output_java/dot_no_title.png +0 -0
  354. data/test/output_java/dot_no_title_or_legend.png +0 -0
  355. data/test/output_java/dot_one_value.png +0 -0
  356. data/test/output_java/dot_pos_neg.png +0 -0
  357. data/test/output_java/dot_set_legend_box_size_lg.png +0 -0
  358. data/test/output_java/dot_set_legend_box_size_sm.png +0 -0
  359. data/test/output_java/dot_set_marker.png +0 -0
  360. data/test/output_java/dot_small.png +0 -0
  361. data/test/output_java/dot_tall_graph.png +0 -0
  362. data/test/output_java/dot_tall_graph_small.png +0 -0
  363. data/test/output_java/dot_themed.png +0 -0
  364. data/test/output_java/dot_wide_graph.png +0 -0
  365. data/test/output_java/dot_wide_graph_small.png +0 -0
  366. data/test/output_java/dot_x_y_labels.png +0 -0
  367. data/test/output_java/dot_y_increment_1.png +0 -0
  368. data/test/output_java/dot_y_increment_2.0.png +0 -0
  369. data/test/output_java/dot_y_increment_20.png +0 -0
  370. data/test/output_java/dot_y_increment_5.png +0 -0
  371. data/test/output_java/enhancements-1.png +0 -0
  372. data/test/output_java/enhancements.png +0 -0
  373. data/test/output_java/line_all_neg.png +0 -0
  374. data/test/output_java/line_all_neg_400.png +0 -0
  375. data/test/output_java/line_all_neg_no_max.png +0 -0
  376. data/test/output_java/line_baseline.png +0 -0
  377. data/test/output_java/line_hang_value.png +0 -0
  378. data/test/output_java/line_hide_dots.png +0 -0
  379. data/test/output_java/line_hide_lines.png +0 -0
  380. data/test/output_java/line_jruby_error.png +0 -0
  381. data/test/output_java/line_large.png +0 -0
  382. data/test/output_java/line_large_baseline.png +0 -0
  383. data/test/output_java/line_legend_at_bottom.png +0 -0
  384. data/test/output_java/line_many.png +0 -0
  385. data/test/output_java/line_many_lines_small.png +0 -0
  386. data/test/output_java/line_many_numbers.png +0 -0
  387. data/test/output_java/line_marker_label_accuracy.png +0 -0
  388. data/test/output_java/line_more_sets_than_colors.png +0 -0
  389. data/test/output_java/line_no_data.png +0 -0
  390. data/test/output_java/line_no_data_msg.png +0 -0
  391. data/test/output_java/line_no_data_other.png +0 -0
  392. data/test/output_java/line_no_hide.png +0 -0
  393. data/test/output_java/line_no_legend.png +0 -0
  394. data/test/output_java/line_no_line_markers.png +0 -0
  395. data/test/output_java/line_no_title.png +0 -0
  396. data/test/output_java/line_nothing_but_the_graph.png +0 -0
  397. data/test/output_java/line_one_value.png +0 -0
  398. data/test/output_java/line_one_value_array.png +0 -0
  399. data/test/output_java/line_pos_neg.png +0 -0
  400. data/test/output_java/line_pos_neg_400.png +0 -0
  401. data/test/output_java/line_similar_high_end_values.png +0 -0
  402. data/test/output_java/line_similar_high_end_values_with_floor.png +0 -0
  403. data/test/output_java/line_small_small_zero.png +0 -0
  404. data/test/output_java/line_small_values.png +0 -0
  405. data/test/output_java/line_small_values_small.png +0 -0
  406. data/test/output_java/line_small_zero.png +0 -0
  407. data/test/output_java/line_some_nil_points.png +0 -0
  408. data/test/output_java/line_theme_37signals_.png +0 -0
  409. data/test/output_java/line_theme_37signals_400.png +0 -0
  410. data/test/output_java/line_theme_keynote_.png +0 -0
  411. data/test/output_java/line_theme_keynote_400.png +0 -0
  412. data/test/output_java/line_theme_odeo_.png +0 -0
  413. data/test/output_java/line_theme_odeo_400.png +0 -0
  414. data/test/output_java/line_theme_rails_keynote_.png +0 -0
  415. data/test/output_java/line_theme_rails_keynote_400.png +0 -0
  416. data/test/output_java/line_tiny.png +0 -0
  417. data/test/output_java/line_transparent.png +0 -0
  418. data/test/output_java/line_very_small.png +0 -0
  419. data/test/output_java/line_wide_graph.png +0 -0
  420. data/test/output_java/line_wide_graph_small.png +0 -0
  421. data/test/output_java/line_xy.png +0 -0
  422. data/test/output_java/line_xy_pairs.png +0 -0
  423. data/test/output_java/line_y_axis_increment.png +0 -0
  424. data/test/output_java/mini_bar.png +0 -0
  425. data/test/output_java/mini_pie.png +0 -0
  426. data/test/output_java/mini_pie_right_legend.png +0 -0
  427. data/test/output_java/mini_side_bar.png +0 -0
  428. data/test/output_java/mini_side_bar_multi_color.png +0 -0
  429. data/test/output_java/net_dots_tiny.png +0 -0
  430. data/test/output_java/net_large.png +0 -0
  431. data/test/output_java/net_many.png +0 -0
  432. data/test/output_java/net_many_nets_small.png +0 -0
  433. data/test/output_java/net_no_data.png +0 -0
  434. data/test/output_java/net_no_data_msg.png +0 -0
  435. data/test/output_java/net_no_data_other.png +0 -0
  436. data/test/output_java/net_no_legend.png +0 -0
  437. data/test/output_java/net_no_net_markers.png +0 -0
  438. data/test/output_java/net_no_title.png +0 -0
  439. data/test/output_java/net_nothing_but_the_graph.png +0 -0
  440. data/test/output_java/net_similar_high_end_values.png +0 -0
  441. data/test/output_java/net_small.png +0 -0
  442. data/test/output_java/net_small_small.png +0 -0
  443. data/test/output_java/net_small_small_zero.png +0 -0
  444. data/test/output_java/net_small_zero.png +0 -0
  445. data/test/output_java/net_wide_graph.png +0 -0
  446. data/test/output_java/net_wide_graph_small.png +0 -0
  447. data/test/output_java/pie_equal.png +0 -0
  448. data/test/output_java/pie_grey.png +0 -0
  449. data/test/output_java/pie_keynote.png +0 -0
  450. data/test/output_java/pie_keynote_small.png +0 -0
  451. data/test/output_java/pie_legend.png +0 -0
  452. data/test/output_java/pie_legend_small.png +0 -0
  453. data/test/output_java/pie_nearly_equal.png +0 -0
  454. data/test/output_java/pie_one_val.png +0 -0
  455. data/test/output_java/pie_pastel.png +0 -0
  456. data/test/output_java/pie_simple.png +0 -0
  457. data/test/output_java/pie_wide.png +0 -0
  458. data/test/output_java/pie_wrapped_legend_16_400.png +0 -0
  459. data/test/output_java/pie_wrapped_legend_16_800.png +0 -0
  460. data/test/output_java/pie_wrapped_legend_30_400.png +0 -0
  461. data/test/output_java/pie_wrapped_legend_30_800.png +0 -0
  462. data/test/output_java/pie_wrapped_legend_4_400.png +0 -0
  463. data/test/output_java/pie_wrapped_legend_4_800.png +0 -0
  464. data/test/output_java/pie_wrapped_legend__400.png +0 -0
  465. data/test/output_java/pie_wrapped_legend__800.png +0 -0
  466. data/test/output_java/pie_zero.png +0 -0
  467. data/test/output_java/scatter_all_neg.png +0 -0
  468. data/test/output_java/scatter_all_neg_400.png +0 -0
  469. data/test/output_java/scatter_basic.png +0 -0
  470. data/test/output_java/scatter_many.png +0 -0
  471. data/test/output_java/scatter_no_data.png +0 -0
  472. data/test/output_java/scatter_no_data_msg.png +0 -0
  473. data/test/output_java/scatter_no_data_other.png +0 -0
  474. data/test/output_java/scatter_no_hide.png +0 -0
  475. data/test/output_java/scatter_no_labels.png +0 -0
  476. data/test/output_java/scatter_no_legend.png +0 -0
  477. data/test/output_java/scatter_no_line_markers.png +0 -0
  478. data/test/output_java/scatter_no_title.png +0 -0
  479. data/test/output_java/scatter_nothing_but_the_graph.png +0 -0
  480. data/test/output_java/scatter_pos_neg.png +0 -0
  481. data/test/output_java/scatter_pos_neg_400.png +0 -0
  482. data/test/output_java/scatter_wide_graph.png +0 -0
  483. data/test/output_java/scatter_wide_graph_small.png +0 -0
  484. data/test/output_java/scene_hazy_night.png +0 -0
  485. data/test/output_java/scene_not_hazy_day.png +0 -0
  486. data/test/output_java/scene_partly_cloudy_day.png +0 -0
  487. data/test/output_java/scene_stormy_day.png +0 -0
  488. data/test/output_java/scene_stormy_night.png +0 -0
  489. data/test/output_java/side_bar.png +0 -0
  490. data/test/output_java/side_bar_data_range.png +0 -0
  491. data/test/output_java/side_bar_labels.png +0 -0
  492. data/test/output_java/side_bar_spacing_full.png +0 -0
  493. data/test/output_java/side_bar_spacing_half.png +0 -0
  494. data/test/output_java/side_bar_spacing_none.png +0 -0
  495. data/test/output_java/side_stacked_bar_keynote.png +0 -0
  496. data/test/output_java/side_stacked_bar_keynote_small.png +0 -0
  497. data/test/output_java/side_stacked_bar_labels.png +0 -0
  498. data/test/output_java/side_stacked_bar_long_label.png +0 -0
  499. data/test/output_java/side_stacked_bar_wide.png +0 -0
  500. data/test/output_java/spider_37signals.png +0 -0
  501. data/test/output_java/spider_equal.png +0 -0
  502. data/test/output_java/spider_keynote.png +0 -0
  503. data/test/output_java/spider_legend.png +0 -0
  504. data/test/output_java/spider_legend_small.png +0 -0
  505. data/test/output_java/spider_lots_of_data.png +0 -0
  506. data/test/output_java/spider_lots_of_data_normal_names.png +0 -0
  507. data/test/output_java/spider_nearly_equal.png +0 -0
  508. data/test/output_java/spider_no_axes.png +0 -0
  509. data/test/output_java/spider_no_background.png +0 -0
  510. data/test/output_java/spider_no_print.png +0 -0
  511. data/test/output_java/spider_overlay_1.png +0 -0
  512. data/test/output_java/spider_overlay_2.png +0 -0
  513. data/test/output_java/spider_rotation.png +0 -0
  514. data/test/output_java/spider_small.png +0 -0
  515. data/test/output_java/spider_wide.png +0 -0
  516. data/test/output_java/spider_zero.png +0 -0
  517. data/test/output_java/stacked_area_keynote.png +0 -0
  518. data/test/output_java/stacked_area_keynote_small.png +0 -0
  519. data/test/output_java/stacked_bar_keynote.png +0 -0
  520. data/test/output_java/stacked_bar_keynote_small.png +0 -0
  521. data/test/test_accumulator_bar.rb +7 -6
  522. data/test/test_area.rb +2 -2
  523. data/test/test_bar.rb +296 -112
  524. data/test/test_bezier.rb +33 -0
  525. data/test/test_bullet.rb +26 -26
  526. data/test/test_dot.rb +44 -54
  527. data/test/test_legend.rb +29 -29
  528. data/test/test_line.rb +250 -218
  529. data/test/test_net.rb +2 -1
  530. data/test/test_pie.rb +2 -2
  531. data/test/test_scatter.rb +85 -85
  532. data/test/test_side_bar.rb +13 -0
  533. data/test/test_sidestacked_bar.rb +16 -0
  534. data/test/test_spider.rb +11 -1
  535. data/test/test_stacked_area.rb +5 -5
  536. metadata +1041 -49
  537. data/.rvmrc +0 -5
  538. data/Gemfile.lock +0 -20
  539. data/LICENSE.txt +0 -22
  540. data/README.txt +0 -43
data/lib/gruff/net.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  require File.dirname(__FILE__) + '/base'
3
2
 
4
3
  # Experimental!!! See also the Spider graph.
@@ -6,20 +5,20 @@ class Gruff::Net < Gruff::Base
6
5
 
7
6
  # Hide parts of the graph to fit more datapoints, or for a different appearance.
8
7
  attr_accessor :hide_dots
9
-
8
+
10
9
  # Dimensions of lines and dots; calculated based on dataset size if left unspecified
11
10
  attr_accessor :line_width
12
11
  attr_accessor :dot_radius
13
12
 
14
13
  def initialize(*args)
15
14
  super
16
-
15
+
17
16
  @hide_dots = false
18
17
  @hide_line_numbers = true
18
+ @sorted_drawing = true
19
19
  end
20
20
 
21
21
  def draw
22
-
23
22
  super
24
23
 
25
24
  return unless @has_data
@@ -30,13 +29,13 @@ class Gruff::Net < Gruff::Base
30
29
 
31
30
  @x_increment = @graph_width / (@column_count - 1).to_f
32
31
  circle_radius = dot_radius ||
33
- clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 2.5), 5.0)
32
+ clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 2.5), 5.0)
34
33
 
35
34
  @d = @d.stroke_opacity 1.0
36
35
  @d = @d.stroke_width line_width ||
37
- clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 4), 5.0)
36
+ clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 4), 5.0)
38
37
 
39
- if (defined?(@norm_baseline)) then
38
+ if defined?(@norm_baseline)
40
39
  level = @graph_top + (@graph_height - @norm_baseline * @graph_height)
41
40
  @d = @d.push
42
41
  @d.stroke_color @baseline_color
@@ -48,7 +47,6 @@ class Gruff::Net < Gruff::Base
48
47
  end
49
48
 
50
49
  @norm_data.each do |data_row|
51
- prev_x = prev_y = nil
52
50
  @d = @d.stroke data_row[DATA_COLOR_INDEX]
53
51
  @d = @d.fill data_row[DATA_COLOR_INDEX]
54
52
 
@@ -107,7 +105,7 @@ class Gruff::Net < Gruff::Base
107
105
  end
108
106
  end
109
107
 
110
- private
108
+ private
111
109
 
112
110
  def draw_label(center_x, center_y, angle, radius, amount)
113
111
  r_offset = 1.1
data/lib/gruff/pie.rb CHANGED
@@ -37,7 +37,6 @@ class Gruff::Pie < Gruff::Base
37
37
 
38
38
  diameter = @graph_height
39
39
  radius = ([@graph_width, @graph_height].min / 2.0) * 0.8
40
- top_x = @graph_left + (@graph_width - diameter) / 2.0
41
40
  center_x = @graph_left + (@graph_width / 2.0)
42
41
  center_y = @graph_top + (@graph_height / 2.0) - 10 # Move graph up a bit
43
42
  total_sum = sums_for_pie()
@@ -64,9 +63,8 @@ class Gruff::Pie < Gruff::Base
64
63
 
65
64
  label_val = ((data_row[DATA_VALUES_INDEX].first / total_sum) * 100.0).round
66
65
  unless label_val < @hide_labels_less_than
67
- # End the string with %% to escape the single %.
68
66
  # RMagick must use sprintf with the string and % has special significance.
69
- label_string = label_val.to_s + '%%'
67
+ label_string = label_val.to_s + '%'
70
68
  @d = draw_label(center_x,center_y, half_angle,
71
69
  radius + (radius * TEXT_OFFSET_PERCENTAGE),
72
70
  label_string)
@@ -92,7 +90,7 @@ private
92
90
  x_offset = center_x # + 15.0 # The label points need to be tweaked slightly
93
91
  y_offset = center_y # This one doesn't though
94
92
  radius_offset = (radius + r_offset)
95
- ellipse_factor = radius_offset * 0.15
93
+ ellipse_factor = radius_offset * TEXT_OFFSET_PERCENTAGE
96
94
  x = x_offset + ((radius_offset + ellipse_factor) * Math.cos(angle.deg2rad))
97
95
  y = y_offset + (radius_offset * Math.sin(angle.deg2rad))
98
96
 
data/lib/gruff/scatter.rb CHANGED
@@ -48,19 +48,20 @@ class Gruff::Scatter < Gruff::Base
48
48
  @baseline_x_value = @baseline_y_value = nil
49
49
  @marker_x_count = nil
50
50
  end
51
-
52
- def draw
53
- calculate_spread
54
- @sort = false
55
-
51
+
52
+ def setup_drawing
56
53
  # TODO Need to get x-axis labels working. Current behavior will be to not allow.
57
54
  @labels = {}
58
-
55
+
56
+ super
57
+
59
58
  # Translate our values so that we can use the base methods for drawing
60
59
  # the standard chart stuff
61
60
  @column_count = @x_spread
61
+ end
62
62
 
63
- super
63
+ def draw
64
+ super
64
65
  return unless @has_data
65
66
 
66
67
  # Check to see if more than one datapoint was given. NaN can result otherwise.
@@ -82,13 +83,11 @@ class Gruff::Scatter < Gruff::Base
82
83
  #~ end
83
84
 
84
85
  @norm_data.each do |data_row|
85
- prev_x = prev_y = nil
86
-
87
86
  data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
88
87
  x_value = data_row[DATA_VALUES_X_INDEX][index]
89
88
  next if data_point.nil? || x_value.nil?
90
89
 
91
- new_x = getXCoord(x_value, @graph_width, @graph_left)
90
+ new_x = get_x_coord(x_value, @graph_width, @graph_left)
92
91
  new_y = @graph_top + (@graph_height - data_point * @graph_height)
93
92
 
94
93
  # Reset each time to avoid thin-line errors
@@ -99,9 +98,6 @@ class Gruff::Scatter < Gruff::Base
99
98
 
100
99
  circle_radius = clip_value_if_greater_than(@columns / (@norm_data.first[1].size * 2.5), 5.0)
101
100
  @d = @d.circle(new_x, new_y, new_x - circle_radius, new_y)
102
-
103
- prev_x = new_x
104
- prev_y = new_y
105
101
  end
106
102
  end
107
103
 
@@ -147,17 +143,17 @@ class Gruff::Scatter < Gruff::Base
147
143
  #
148
144
  def data(name, x_data_points=[], y_data_points=[], color=nil)
149
145
 
150
- raise ArgumentError, "Data Points contain nil Value!" if x_data_points.include?(nil) || y_data_points.include?(nil)
151
- raise ArgumentError, "x_data_points is empty!" if x_data_points.empty?
152
- raise ArgumentError, "y_data_points is empty!" if y_data_points.empty?
153
- raise ArgumentError, "x_data_points.length != y_data_points.length!" if x_data_points.length != y_data_points.length
146
+ raise ArgumentError, 'Data Points contain nil Value!' if x_data_points.include?(nil) || y_data_points.include?(nil)
147
+ raise ArgumentError, 'x_data_points is empty!' if x_data_points.empty?
148
+ raise ArgumentError, 'y_data_points is empty!' if y_data_points.empty?
149
+ raise ArgumentError, 'x_data_points.length != y_data_points.length!' if x_data_points.length != y_data_points.length
154
150
 
155
151
  # Call the existing data routine for the y axis data
156
152
  super(name, y_data_points, color)
157
153
 
158
154
  #append the x data to the last entry that was just added in the @data member
159
- lastElem = @data.length()-1
160
- @data[lastElem] << x_data_points
155
+ last_elem = @data.length()-1
156
+ @data[last_elem] << x_data_points
161
157
 
162
158
  if @maximum_x_value.nil? && @minimum_x_value.nil?
163
159
  @maximum_x_value = @minimum_x_value = x_data_points.first
@@ -231,17 +227,17 @@ protected
231
227
 
232
228
  # Draw vertical line markers and annotate with numbers
233
229
  (0..@marker_x_count).each do |index|
234
- x = @graph_left + @graph_width - index.to_f * @increment_x_scaled
235
-
230
+
236
231
  # TODO Fix the vertical lines. Not pretty when they don't match up with top y-axis line
237
- #~ @d = @d.stroke(@marker_color)
238
- #~ @d = @d.stroke_width 1
239
- #~ @d = @d.line(x, @graph_top, x, @graph_bottom)
232
+ # x = @graph_left + @graph_width - index.to_f * @increment_x_scaled
233
+ # @d = @d.stroke(@marker_color)
234
+ # @d = @d.stroke_width 1
235
+ # @d = @d.line(x, @graph_top, x, @graph_bottom)
240
236
 
241
237
  unless @hide_line_numbers
242
238
  marker_label = index * @x_increment + @minimum_x_value.to_f
243
239
  y_offset = @graph_bottom + LABEL_MARGIN
244
- x_offset = getXCoord(index.to_f, @increment_x_scaled, @graph_left)
240
+ x_offset = get_x_coord(index.to_f, @increment_x_scaled, @graph_left)
245
241
 
246
242
  @d.fill = @font_color
247
243
  @d.font = @font if @font
@@ -252,7 +248,7 @@ protected
252
248
  @d = @d.annotate_scaled(@base_image,
253
249
  1.0, 1.0,
254
250
  x_offset, y_offset,
255
- label(marker_label), @scale)
251
+ label(marker_label, @x_increment), @scale)
256
252
  end
257
253
  end
258
254
 
@@ -261,8 +257,8 @@ protected
261
257
 
262
258
  private
263
259
 
264
- def getXCoord(x_data_point, width, offset) #:nodoc:
265
- return(x_data_point * width + offset)
260
+ def get_x_coord(x_data_point, width, offset) #:nodoc:
261
+ x_data_point * width + offset
266
262
  end
267
263
 
268
- end # end Gruff::Scatter
264
+ end # end Gruff::Scatter
@@ -7,7 +7,7 @@ class Gruff::SideBar < Gruff::Base
7
7
 
8
8
  # Spacing factor applied between bars
9
9
  attr_accessor :bar_spacing
10
-
10
+
11
11
  def draw
12
12
  @has_left_labels = true
13
13
  super
@@ -16,7 +16,7 @@ class Gruff::SideBar < Gruff::Base
16
16
  draw_bars
17
17
  end
18
18
 
19
- protected
19
+ protected
20
20
 
21
21
  def draw_bars
22
22
  # Setup spacing.
@@ -25,10 +25,15 @@ protected
25
25
 
26
26
  @bars_width = @graph_height / @column_count.to_f
27
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
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
32
+
33
+ # if we're a side stacked bar then we don't need to draw ourself at all
34
+ # because sometimes (due to different heights/min/max) you can actually
35
+ # see both graphs and it looks like crap
36
+ return if self.is_a?(Gruff::SideStackedBar)
32
37
 
33
38
  @norm_data.each_with_index do |data_row, row_index|
34
39
  @d = @d.fill data_row[DATA_COLOR_INDEX]
@@ -38,22 +43,32 @@ protected
38
43
  # Using the original calcs from the stacked bar chart
39
44
  # to get the difference between
40
45
  # part of the bart chart we wish to stack.
41
- temp1 = @graph_left + (@graph_width - data_point * @graph_width - height[point_index])
42
- temp2 = @graph_left + @graph_width - height[point_index]
46
+ temp1 = @graph_left + (@graph_width - data_point * @graph_width - height[point_index])
47
+ temp2 = @graph_left + @graph_width - height[point_index]
43
48
  difference = temp2 - temp1
44
49
 
45
- left_x = length[point_index] - 1
46
- left_y = @graph_top + (@bars_width * point_index) + (@bar_width * row_index) + padding
47
- right_x = left_x + difference
48
- right_y = left_y + @bar_width * @bar_spacing
50
+ left_x = length[point_index] - 1
51
+ left_y = @graph_top + (@bars_width * point_index) + (@bar_width * row_index) + padding
52
+ right_x = left_x + difference
53
+ right_y = left_y + @bar_width * @bar_spacing
49
54
 
50
55
  height[point_index] += (data_point * @graph_width)
51
56
 
52
- @d = @d.rectangle(left_x, left_y, right_x, right_y)
57
+ @d = @d.rectangle(left_x, left_y, right_x, right_y)
53
58
 
54
59
  # Calculate center based on bar_width and current row
55
- label_center = @graph_top + (@bars_width * point_index + @bars_width / 2)
56
- draw_label(label_center, point_index)
60
+
61
+ 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])
64
+ else
65
+ label_center = @graph_top + (@bars_width * point_index + @bars_width / 2)
66
+ draw_label(label_center, point_index)
67
+ end
68
+ 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)
71
+ end
57
72
  end
58
73
 
59
74
  end
@@ -71,29 +86,30 @@ protected
71
86
  # Draw horizontal line markers and annotate with numbers
72
87
  @d = @d.stroke(@marker_color)
73
88
  @d = @d.stroke_width 1
74
- number_of_lines = 5
89
+ number_of_lines = @marker_count || 5
90
+ number_of_lines = 1 if number_of_lines == 0
75
91
 
76
92
  # TODO Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
77
93
  increment = significant(@spread.to_f / number_of_lines)
78
94
  (0..number_of_lines).each do |index|
79
95
 
80
- line_diff = (@graph_right - @graph_left) / number_of_lines
81
- x = @graph_right - (line_diff * index) - 1
82
- @d = @d.line(x, @graph_bottom, x, @graph_top)
83
- diff = index - number_of_lines
96
+ line_diff = (@graph_right - @graph_left) / number_of_lines
97
+ x = @graph_right - (line_diff * index) - 1
98
+ @d = @d.line(x, @graph_bottom, x, @graph_top)
99
+ diff = index - number_of_lines
84
100
  marker_label = diff.abs * increment + @minimum_value
85
101
 
86
102
  unless @hide_line_numbers
87
- @d.fill = @font_color
88
- @d.font = @font if @font
89
- @d.stroke = 'transparent'
103
+ @d.fill = @font_color
104
+ @d.font = @font if @font
105
+ @d.stroke = 'transparent'
90
106
  @d.pointsize = scale_fontsize(@marker_font_size)
91
- @d.gravity = CenterGravity
107
+ @d.gravity = CenterGravity
92
108
  # TODO Center text over line
93
- @d = @d.annotate_scaled( @base_image,
94
- 0, 0, # Width of box to draw text in
95
- x, @graph_bottom + (LABEL_MARGIN * 2.0), # Coordinates of text
96
- marker_label.to_s, @scale)
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)
97
113
  end # unless
98
114
  @d = @d.stroke_antialias true
99
115
  end
@@ -102,18 +118,19 @@ protected
102
118
  ##
103
119
  # Draw on the Y axis instead of the X
104
120
 
105
- def draw_label(y_offset, index)
121
+ def draw_label(y_offset, index, label=nil)
106
122
  if !@labels[index].nil? && @labels_seen[index].nil?
107
- @d.fill = @font_color
108
- @d.font = @font if @font
109
- @d.stroke = 'transparent'
110
- @d.font_weight = NormalWeight
111
- @d.pointsize = scale_fontsize(@marker_font_size)
112
- @d.gravity = EastGravity
113
- @d = @d.annotate_scaled(@base_image,
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,
114
131
  1, 1,
115
132
  -@graph_left + LABEL_MARGIN * 2.0, y_offset,
116
- @labels[index], @scale)
133
+ lbl, @scale)
117
134
  @labels_seen[index] = 1
118
135
  end
119
136
  end
@@ -33,7 +33,10 @@ class Gruff::SideStackedBar < Gruff::SideBar
33
33
  height = Array.new(@column_count, 0)
34
34
  length = Array.new(@column_count, @graph_left)
35
35
  padding = (@bar_width * (1 - @bar_spacing)) / 2
36
-
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
37
40
  @norm_data.each_with_index do |data_row, row_index|
38
41
  data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
39
42
 
@@ -53,16 +56,33 @@ class Gruff::SideStackedBar < Gruff::SideBar
53
56
  right_y = left_y + @bar_width * @bar_spacing
54
57
  length[point_index] += difference
55
58
  height[point_index] += (data_point * @graph_width - 2)
56
-
57
- @d = @d.rectangle(left_x, left_y, right_x, right_y)
58
-
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
+
65
+ # if a data point is 0 it can result in weird really thing lines
66
+ # that shouldn't even be there being drawn on top of the existing
67
+ # bar - this is bad
68
+ if data_point != 0
69
+ @d = @d.rectangle(left_x, left_y, right_x, right_y)
70
+ # Calculate center based on bar_width and current row
71
+ end
72
+ # we still need to draw the labels
59
73
  # Calculate center based on bar_width and current row
60
74
  label_center = @graph_top + (@bar_width * point_index) + (@bar_width * @bar_spacing / 2.0)
61
75
  draw_label(label_center, point_index)
62
76
  end
63
77
 
64
78
  end
65
-
79
+ 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)
83
+ end
84
+ end
85
+
66
86
  @d.draw(@base_image)
67
87
  end
68
88
 
data/lib/gruff/spider.rb CHANGED
@@ -10,6 +10,7 @@ class Gruff::Spider < Gruff::Base
10
10
  attr_reader :hide_text
11
11
  attr_accessor :hide_axes
12
12
  attr_reader :transparent_background
13
+ attr_accessor :rotation
13
14
 
14
15
  def transparent_background=(value)
15
16
  @transparent_background = value
@@ -19,11 +20,12 @@ class Gruff::Spider < Gruff::Base
19
20
  def hide_text=(value)
20
21
  @hide_title = @hide_text = value
21
22
  end
22
-
23
+
23
24
  def initialize(max_value, target_width = 800)
24
25
  super(target_width)
25
26
  @max_value = max_value
26
27
  @hide_legend = true;
28
+ @rotation = 0
27
29
  end
28
30
 
29
31
  def draw
@@ -39,39 +41,37 @@ class Gruff::Spider < Gruff::Base
39
41
  top_x = @graph_left + (@graph_width - diameter) / 2.0
40
42
  center_x = @graph_left + (@graph_width / 2.0)
41
43
  center_y = @graph_top + (@graph_height / 2.0) - 25 # Move graph up a bit
42
-
44
+
43
45
  @unit_length = radius / @max_value
44
-
45
46
 
46
47
  total_sum = sums_for_spider
47
48
  prev_degrees = 0.0
48
49
  additive_angle = (2 * Math::PI)/ @data.size
49
50
 
50
- current_angle = 0.0
51
+ current_angle = rotation * Math::PI / 180.0
51
52
 
52
53
  # Draw axes
53
54
  draw_axes(center_x, center_y, radius, additive_angle) unless hide_axes
54
-
55
+
55
56
  # Draw polygon
56
57
  draw_polygon(center_x, center_y, additive_angle)
57
-
58
-
58
+
59
59
  @d.draw(@base_image)
60
60
  end
61
61
 
62
62
  private
63
-
63
+
64
64
  def normalize_points(value)
65
65
  value * @unit_length
66
66
  end
67
-
67
+
68
68
  def draw_label(center_x, center_y, angle, radius, amount)
69
69
  r_offset = 50 # The distance out from the center of the pie to get point
70
70
  x_offset = center_x # The label points need to be tweaked slightly
71
71
  y_offset = center_y + 0 # This one doesn't though
72
72
  x = x_offset + ((radius + r_offset) * Math.cos(angle))
73
73
  y = y_offset + ((radius + r_offset) * Math.sin(angle))
74
-
74
+
75
75
  # Draw label
76
76
  @d.fill = @marker_color
77
77
  @d.font = @font if @font
@@ -84,45 +84,46 @@ private
84
84
  x, y,
85
85
  amount, @scale)
86
86
  end
87
-
87
+
88
88
  def draw_axes(center_x, center_y, radius, additive_angle, line_color = nil)
89
89
  return if hide_axes
90
-
91
- current_angle = 0.0
92
-
90
+
91
+ current_angle = rotation * Math::PI / 180.0
92
+
93
93
  @data.each do |data_row|
94
94
  @d.stroke(line_color || data_row[DATA_COLOR_INDEX])
95
95
  @d.stroke_width 5.0
96
-
96
+
97
97
  x_offset = radius * Math.cos(current_angle)
98
98
  y_offset = radius * Math.sin(current_angle)
99
99
 
100
100
  @d.line(center_x, center_y,
101
101
  center_x + x_offset,
102
102
  center_y + y_offset)
103
-
103
+
104
104
  draw_label(center_x, center_y, current_angle, radius, data_row[DATA_LABEL_INDEX].to_s) unless hide_text
105
-
105
+
106
106
  current_angle += additive_angle
107
107
  end
108
108
  end
109
-
109
+
110
110
  def draw_polygon(center_x, center_y, additive_angle, color = nil)
111
111
  points = []
112
- current_angle = 0.0
112
+ current_angle = rotation * Math::PI / 180.0
113
+
113
114
  @data.each do |data_row|
114
115
  points << center_x + normalize_points(data_row[DATA_VALUES_INDEX].first) * Math.cos(current_angle)
115
116
  points << center_y + normalize_points(data_row[DATA_VALUES_INDEX].first) * Math.sin(current_angle)
116
117
  current_angle += additive_angle
117
118
  end
118
-
119
+
119
120
  @d.stroke_width 1.0
120
121
  @d.stroke(color || @marker_color)
121
122
  @d.fill(color || @marker_color)
122
123
  @d.fill_opacity 0.4
123
124
  @d.polygon(*points)
124
125
  end
125
-
126
+
126
127
  def sums_for_spider
127
128
  @data.inject(0.0) {|sum, data_row| sum += data_row[DATA_VALUES_INDEX].first}
128
129
  end