gruff 0.5.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (612) hide show
  1. checksums.yaml +5 -5
  2. data/.editorconfig +14 -0
  3. data/.github/ISSUE_TEMPLATE.md +18 -0
  4. data/.gitignore +3 -0
  5. data/.rubocop.yml +109 -0
  6. data/.rubocop_todo.yml +136 -0
  7. data/.travis.yml +24 -12
  8. data/.yardopts +1 -0
  9. data/{History.txt → CHANGELOG.md} +63 -24
  10. data/Gemfile +3 -7
  11. data/README.md +53 -25
  12. data/Rakefile +6 -201
  13. data/assets/plastik/blue.png +0 -0
  14. data/assets/plastik/green.png +0 -0
  15. data/assets/plastik/red.png +0 -0
  16. data/docker/Dockerfile +14 -0
  17. data/docker/build.sh +4 -0
  18. data/docker/launch.sh +4 -0
  19. data/gruff.gemspec +18 -14
  20. data/init.rb +2 -0
  21. data/lib/gruff.rb +25 -2
  22. data/lib/gruff/accumulator_bar.rb +7 -7
  23. data/lib/gruff/area.rb +12 -19
  24. data/lib/gruff/bar.rb +60 -44
  25. data/lib/gruff/base.rb +281 -585
  26. data/lib/gruff/bezier.rb +15 -18
  27. data/lib/gruff/bullet.rb +41 -62
  28. data/lib/gruff/dot.rb +26 -61
  29. data/lib/gruff/helper/bar_conversion.rb +47 -0
  30. data/lib/gruff/helper/bar_value_label_mixin.rb +30 -0
  31. data/lib/gruff/{stacked_mixin.rb → helper/stacked_mixin.rb} +8 -8
  32. data/lib/gruff/line.rb +126 -148
  33. data/lib/gruff/mini/bar.rb +8 -9
  34. data/lib/gruff/mini/legend.rb +24 -36
  35. data/lib/gruff/mini/pie.rb +10 -11
  36. data/lib/gruff/mini/side_bar.rb +9 -10
  37. data/lib/gruff/net.rb +37 -82
  38. data/lib/gruff/patch/rmagick.rb +33 -0
  39. data/lib/gruff/patch/string.rb +8 -0
  40. data/lib/gruff/photo_bar.rb +27 -30
  41. data/lib/gruff/pie.rb +185 -89
  42. data/lib/gruff/renderer/bezier.rb +21 -0
  43. data/lib/gruff/renderer/circle.rb +21 -0
  44. data/lib/gruff/renderer/dash_line.rb +22 -0
  45. data/lib/gruff/renderer/dot.rb +39 -0
  46. data/lib/gruff/renderer/ellipse.rb +21 -0
  47. data/lib/gruff/renderer/line.rb +34 -0
  48. data/lib/gruff/renderer/polygon.rb +23 -0
  49. data/lib/gruff/renderer/polyline.rb +21 -0
  50. data/lib/gruff/renderer/rectangle.rb +19 -0
  51. data/lib/gruff/renderer/renderer.rb +127 -0
  52. data/lib/gruff/renderer/text.rb +42 -0
  53. data/lib/gruff/scatter.rb +154 -179
  54. data/lib/gruff/scene.rb +31 -41
  55. data/lib/gruff/side_bar.rb +64 -63
  56. data/lib/gruff/side_stacked_bar.rb +61 -59
  57. data/lib/gruff/spider.rb +25 -49
  58. data/lib/gruff/stacked_area.rb +21 -29
  59. data/lib/gruff/stacked_bar.rb +77 -49
  60. data/lib/gruff/store/base_data.rb +34 -0
  61. data/lib/gruff/store/custom_data.rb +34 -0
  62. data/lib/gruff/store/store.rb +80 -0
  63. data/lib/gruff/store/xy_data.rb +55 -0
  64. data/lib/gruff/themes.rb +32 -33
  65. data/lib/gruff/version.rb +3 -1
  66. metadata +84 -1080
  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,4 +1,6 @@
1
- require File.dirname(__FILE__) + '/base'
1
+ # frozen_string_literal: true
2
+
3
+ require 'gruff/base'
2
4
 
3
5
  ##
4
6
  # Here's how to make a Pie graph:
@@ -10,115 +12,209 @@ require File.dirname(__FILE__) + '/base'
10
12
  # g.write("test/output/pie_keynote.png")
11
13
  #
12
14
  # To control where the pie chart starts creating slices, use #zero_degree.
13
-
14
15
  class Gruff::Pie < Gruff::Base
15
-
16
- TEXT_OFFSET_PERCENTAGE = 0.15
16
+ DEFAULT_TEXT_OFFSET_PERCENTAGE = 0.15
17
17
 
18
18
  # Can be used to make the pie start cutting slices at the top (-90.0)
19
- # or at another angle. Default is 0.0, which starts at 3 o'clock.
20
- attr_accessor :zero_degree
19
+ # or at another angle. Default is +0.0+, which starts at 3 o'clock.
20
+ attr_writer :zero_degree
21
+
21
22
  # Do not show labels for slices that are less than this percent. Use 0 to always show all labels.
22
- # Defaults to 0
23
- attr_accessor :hide_labels_less_than
23
+ # Defaults to +0+.
24
+ attr_writer :hide_labels_less_than
25
+
26
+ # Affect the distance between the percentages and the pie chart.
27
+ # Defaults to +0.15+.
28
+ attr_writer :text_offset_percentage
29
+
30
+ ## Use values instead of percentages.
31
+ attr_accessor :show_values_as_labels
24
32
 
25
33
  def initialize_ivars
26
34
  super
27
- @zero_degree = 0.0
28
- @hide_labels_less_than = 0.0
35
+
36
+ @show_values_as_labels = false
37
+
38
+ @store = Gruff::Store.new(Gruff::Store::CustomData)
39
+ end
40
+ private :initialize_ivars
41
+
42
+ def zero_degree
43
+ @zero_degree ||= 0.0
44
+ end
45
+
46
+ def hide_labels_less_than
47
+ @hide_labels_less_than ||= 0.0
48
+ end
49
+
50
+ def text_offset_percentage
51
+ @text_offset_percentage ||= DEFAULT_TEXT_OFFSET_PERCENTAGE
52
+ end
53
+
54
+ def options
55
+ {
56
+ zero_degree: zero_degree,
57
+ hide_labels_less_than: hide_labels_less_than,
58
+ text_offset_percentage: text_offset_percentage,
59
+ show_values_as_labels: show_values_as_labels
60
+ }
29
61
  end
30
62
 
31
63
  def draw
32
- @hide_line_markers = true
33
-
64
+ hide_line_markers
65
+
34
66
  super
35
67
 
36
- return unless @has_data
37
-
38
- diameter = @graph_height
39
- radius = ([@graph_width, @graph_height].min / 2.0) * 0.8
40
- center_x = @graph_left + (@graph_width / 2.0)
41
- center_y = @graph_top + (@graph_height / 2.0) - 10 # Move graph up a bit
42
- total_sum = sums_for_pie()
43
- prev_degrees = @zero_degree
44
-
45
- # Use full data since we can easily calculate percentages
46
- data = (@sort ? @data.sort{ |a, b| a[DATA_VALUES_INDEX].first <=> b[DATA_VALUES_INDEX].first } : @data)
47
- data.each do |data_row|
48
- if data_row[DATA_VALUES_INDEX].first > 0
49
- @d = @d.stroke data_row[DATA_COLOR_INDEX]
50
- @d = @d.fill 'transparent'
51
- @d.stroke_width(radius) # stroke width should be equal to radius. we'll draw centered on (radius / 2)
52
-
53
- current_degrees = (data_row[DATA_VALUES_INDEX].first / total_sum) * 360.0
54
-
55
- # ellipse will draw the the stroke centered on the first two parameters offset by the second two.
56
- # therefore, in order to draw a circle of the proper diameter we must center the stroke at
57
- # half the radius for both x and y
58
- @d = @d.ellipse(center_x, center_y,
59
- radius / 2.0, radius / 2.0,
60
- prev_degrees, prev_degrees + current_degrees + 0.5) # <= +0.5 'fudge factor' gets rid of the ugly gaps
61
-
62
- half_angle = prev_degrees + ((prev_degrees + current_degrees) - prev_degrees) / 2
63
-
64
- label_val = ((data_row[DATA_VALUES_INDEX].first / total_sum) * 100.0).round
65
- unless label_val < @hide_labels_less_than
66
- # RMagick must use sprintf with the string and % has special significance.
67
- label_string = label_val.to_s + '%'
68
- @d = draw_label(center_x,center_y, half_angle,
69
- radius + (radius * TEXT_OFFSET_PERCENTAGE),
70
- label_string)
71
- end
72
-
73
- prev_degrees += current_degrees
68
+ return unless data_given?
69
+
70
+ slices.each do |slice|
71
+ if slice.value > 0
72
+ Gruff::Renderer::Ellipse.new(color: slice.color, width: radius)
73
+ .render(center_x, center_y, radius / 2.0, radius / 2.0, chart_degrees, chart_degrees + slice.degrees + 0.5)
74
+ process_label_for slice
75
+ update_chart_degrees_with slice.degrees
74
76
  end
75
77
  end
76
78
 
77
- # TODO debug a circle where the text is drawn...
78
-
79
- @d.draw(@base_image)
79
+ Gruff::Renderer.finish
80
80
  end
81
81
 
82
82
  private
83
83
 
84
- ##
85
- # Labels are drawn around a slightly wider ellipse to give room for
86
- # labels on the left and right.
87
- def draw_label(center_x, center_y, angle, radius, amount)
88
- # TODO Don't use so many hard-coded numbers
89
- r_offset = 20.0 # The distance out from the center of the pie to get point
90
- x_offset = center_x # + 15.0 # The label points need to be tweaked slightly
91
- y_offset = center_y # This one doesn't though
92
- radius_offset = (radius + r_offset)
93
- ellipse_factor = radius_offset * TEXT_OFFSET_PERCENTAGE
94
- x = x_offset + ((radius_offset + ellipse_factor) * Math.cos(angle.deg2rad))
95
- y = y_offset + (radius_offset * Math.sin(angle.deg2rad))
96
-
97
- # Draw label
98
- @d.fill = @font_color
99
- @d.font = @font if @font
100
- @d.pointsize = scale_fontsize(@marker_font_size)
101
- @d.stroke = 'transparent'
102
- @d.font_weight = BoldWeight
103
- @d.gravity = CenterGravity
104
- @d.annotate_scaled( @base_image,
105
- 0, 0,
106
- x, y,
107
- amount, @scale)
108
- end
109
-
110
- def sums_for_pie
111
- total_sum = 0.0
112
- @data.collect {|data_row| total_sum += data_row[DATA_VALUES_INDEX].first }
113
- total_sum
84
+ def slices
85
+ @slices ||= begin
86
+ slices = store.data.map { |data| slice_class.new(data, options) }
87
+
88
+ slices.sort_by(&:value) if @sort
89
+
90
+ total = slices.map(&:value).inject(:+).to_f
91
+ slices.each { |slice| slice.total = total }
92
+ end
114
93
  end
115
94
 
116
- end
95
+ # General Helper Methods
96
+
97
+ def hide_line_markers
98
+ @hide_line_markers = true
99
+ end
117
100
 
118
- class Float
119
- # Used for degree => radian conversions
120
- def deg2rad
121
- self * (Math::PI/180.0)
101
+ def update_chart_degrees_with(degrees)
102
+ @chart_degrees = chart_degrees + degrees
103
+ end
104
+
105
+ def slice_class
106
+ PieSlice
107
+ end
108
+
109
+ # Spatial Value-Related Methods
110
+
111
+ def chart_degrees
112
+ @chart_degrees ||= zero_degree
113
+ end
114
+
115
+ attr_reader :graph_height
116
+
117
+ attr_reader :graph_width
118
+
119
+ def diameter
120
+ graph_height
121
+ end
122
+
123
+ def half_width
124
+ graph_width / 2.0
125
+ end
126
+
127
+ def half_height
128
+ graph_height / 2.0
129
+ end
130
+
131
+ def radius
132
+ @radius ||= ([graph_width, graph_height].min / 2.0) * 0.8
122
133
  end
123
- end
124
134
 
135
+ def center_x
136
+ @center_x ||= @graph_left + half_width
137
+ end
138
+
139
+ def center_y
140
+ @center_y ||= @graph_top + half_height - 10
141
+ end
142
+
143
+ def distance_from_center
144
+ 20.0
145
+ end
146
+
147
+ def radius_offset
148
+ radius + (radius * text_offset_percentage) + distance_from_center
149
+ end
150
+
151
+ def ellipse_factor
152
+ radius_offset * text_offset_percentage
153
+ end
154
+
155
+ # Label-Related Methods
156
+
157
+ def process_label_for(slice)
158
+ if slice.percentage >= hide_labels_less_than
159
+ x, y = label_coordinates_for slice
160
+
161
+ draw_label(x, y, slice.label)
162
+ end
163
+ end
164
+
165
+ def label_coordinates_for(slice)
166
+ angle = chart_degrees + slice.degrees / 2
167
+
168
+ [x_label_coordinate(angle), y_label_coordinate(angle)]
169
+ end
170
+
171
+ def x_label_coordinate(angle)
172
+ center_x + ((radius_offset + ellipse_factor) * Math.cos(deg2rad(angle)))
173
+ end
174
+
175
+ def y_label_coordinate(angle)
176
+ center_y + (radius_offset * Math.sin(deg2rad(angle)))
177
+ end
178
+
179
+ # Drawing-Related Methods
180
+
181
+ def draw_label(x, y, value)
182
+ text_renderer = Gruff::Renderer::Text.new(value, font: @font, size: @marker_font_size, color: @font_color, weight: Magick::BoldWeight)
183
+ text_renderer.render(0, 0, x, y, Magick::CenterGravity)
184
+ end
185
+
186
+ # Helper Classes
187
+ #
188
+ # @private
189
+ class PieSlice < Struct.new(:data_array, :options)
190
+ attr_accessor :total
191
+
192
+ def name
193
+ data_array[0]
194
+ end
195
+
196
+ def value
197
+ data_array[1].first
198
+ end
199
+
200
+ def color
201
+ data_array[2]
202
+ end
203
+
204
+ def size
205
+ @size ||= value / total
206
+ end
207
+
208
+ def percentage
209
+ @percentage ||= (size * 100.0).round
210
+ end
211
+
212
+ def degrees
213
+ @degrees ||= size * 360.0
214
+ end
215
+
216
+ def label
217
+ options[:show_values_as_labels] ? value.to_s : "#{percentage}%"
218
+ end
219
+ end
220
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gruff
4
+ class Renderer::Bezier
5
+ def initialize(args = {})
6
+ @color = args[:color]
7
+ @width = args[:width] || 1.0
8
+ end
9
+
10
+ def render(points)
11
+ draw = Renderer.instance.draw
12
+
13
+ draw.push
14
+ draw.stroke(@color)
15
+ draw.stroke_width(@width)
16
+ draw.fill_opacity(0.0)
17
+ draw.bezier(*points)
18
+ draw.pop
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gruff
4
+ class Renderer::Circle
5
+ def initialize(args = {})
6
+ @color = args[:color]
7
+ @width = args[:width] || 1.0
8
+ end
9
+
10
+ def render(origin_x, origin_y, perim_x, perim_y)
11
+ draw = Renderer.instance.draw
12
+
13
+ draw.push
14
+ draw.fill(@color)
15
+ draw.stroke(@color)
16
+ draw.stroke_width(@width)
17
+ draw.circle(origin_x, origin_y, perim_x, perim_y)
18
+ draw.pop
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gruff
4
+ class Renderer::DashLine
5
+ def initialize(args = {})
6
+ @color = args[:color]
7
+ @width = args[:width]
8
+ end
9
+
10
+ def render(start_x, start_y, end_x, end_y)
11
+ draw = Renderer.instance.draw
12
+
13
+ draw.push
14
+ draw.stroke_color(@color)
15
+ draw.fill_opacity(0.0)
16
+ draw.stroke_dasharray(10, 20)
17
+ draw.stroke_width(@width)
18
+ draw.line(start_x, start_y, end_x, end_y)
19
+ draw.pop
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gruff
4
+ class Renderer::Dot
5
+ def initialize(style, config)
6
+ @style = style
7
+ @color = config[:color]
8
+ @width = config[:width] || 1.0
9
+ end
10
+
11
+ def render(new_x, new_y, circle_radius)
12
+ draw = Renderer.instance.draw
13
+
14
+ # draw.push # TODO
15
+ draw.stroke_width(@width)
16
+ draw.stroke(@color)
17
+ draw.fill(@color)
18
+ if @style.to_s == 'square'
19
+ square(draw, new_x, new_y, circle_radius)
20
+ else
21
+ circle(draw, new_x, new_y, circle_radius)
22
+ end
23
+ # draw.pop # TODO
24
+ end
25
+
26
+ def circle(draw, new_x, new_y, circle_radius)
27
+ draw.circle(new_x, new_y, new_x - circle_radius, new_y)
28
+ end
29
+
30
+ def square(draw, new_x, new_y, circle_radius)
31
+ offset = (circle_radius * 0.8).to_i
32
+ corner1 = new_x - offset
33
+ corner2 = new_y - offset
34
+ corner3 = new_x + offset
35
+ corner4 = new_y + offset
36
+ draw.rectangle(corner1, corner2, corner3, corner4)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gruff
4
+ class Renderer::Ellipse
5
+ def initialize(args = {})
6
+ @color = args[:color]
7
+ @width = args[:width] || 1.0
8
+ end
9
+
10
+ def render(origin_x, origin_y, width, height, arc_start, arc_end)
11
+ draw = Renderer.instance.draw
12
+
13
+ draw.push
14
+ draw.stroke_width(@width)
15
+ draw.stroke(@color)
16
+ draw.fill('transparent')
17
+ draw.ellipse(origin_x, origin_y, width, height, arc_start, arc_end)
18
+ draw.pop
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gruff
4
+ class Renderer::Line
5
+ EPSILON = 0.001
6
+
7
+ def initialize(args = {})
8
+ @color = args[:color]
9
+ @width = args[:width]
10
+ end
11
+
12
+ def render(start_x, start_y, end_x, end_y)
13
+ # FIXME(uwe): Workaround for Issue #66
14
+ # https://github.com/topfunky/gruff/issues/66
15
+ # https://github.com/rmagick/rmagick/issues/82
16
+ # Remove if the issue gets fixed.
17
+ unless defined?(JRUBY_VERSION)
18
+ start_x += EPSILON
19
+ end_x += EPSILON
20
+ start_y += EPSILON
21
+ end_y += EPSILON
22
+ end
23
+
24
+ draw = Renderer.instance.draw
25
+
26
+ draw.push
27
+ draw.stroke(@color)
28
+ draw.fill(@color)
29
+ draw.stroke_width(@width) if @width
30
+ draw.line(start_x, start_y, end_x, end_y)
31
+ draw.pop
32
+ end
33
+ end
34
+ end