gruff 0.5.0-java → 0.9.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.editorconfig +14 -0
- data/.github/ISSUE_TEMPLATE.md +18 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +109 -0
- data/.rubocop_todo.yml +136 -0
- data/.travis.yml +24 -12
- data/.yardopts +1 -0
- data/{History.txt → CHANGELOG.md} +63 -24
- data/Gemfile +3 -7
- data/README.md +53 -25
- data/Rakefile +6 -201
- data/assets/plastik/blue.png +0 -0
- data/assets/plastik/green.png +0 -0
- data/assets/plastik/red.png +0 -0
- data/docker/Dockerfile +14 -0
- data/docker/build.sh +4 -0
- data/docker/launch.sh +4 -0
- data/gruff.gemspec +18 -14
- data/init.rb +2 -0
- data/lib/gruff.rb +25 -2
- data/lib/gruff/accumulator_bar.rb +7 -7
- data/lib/gruff/area.rb +12 -19
- data/lib/gruff/bar.rb +60 -44
- data/lib/gruff/base.rb +281 -585
- data/lib/gruff/bezier.rb +15 -18
- data/lib/gruff/bullet.rb +41 -62
- data/lib/gruff/dot.rb +26 -61
- data/lib/gruff/helper/bar_conversion.rb +47 -0
- data/lib/gruff/helper/bar_value_label_mixin.rb +30 -0
- data/lib/gruff/{stacked_mixin.rb → helper/stacked_mixin.rb} +8 -8
- data/lib/gruff/line.rb +126 -148
- data/lib/gruff/mini/bar.rb +8 -9
- data/lib/gruff/mini/legend.rb +24 -36
- data/lib/gruff/mini/pie.rb +10 -11
- data/lib/gruff/mini/side_bar.rb +9 -10
- data/lib/gruff/net.rb +37 -82
- data/lib/gruff/patch/rmagick.rb +33 -0
- data/lib/gruff/patch/string.rb +8 -0
- data/lib/gruff/photo_bar.rb +27 -30
- data/lib/gruff/pie.rb +185 -89
- data/lib/gruff/renderer/bezier.rb +21 -0
- data/lib/gruff/renderer/circle.rb +21 -0
- data/lib/gruff/renderer/dash_line.rb +22 -0
- data/lib/gruff/renderer/dot.rb +39 -0
- data/lib/gruff/renderer/ellipse.rb +21 -0
- data/lib/gruff/renderer/line.rb +34 -0
- data/lib/gruff/renderer/polygon.rb +23 -0
- data/lib/gruff/renderer/polyline.rb +21 -0
- data/lib/gruff/renderer/rectangle.rb +19 -0
- data/lib/gruff/renderer/renderer.rb +127 -0
- data/lib/gruff/renderer/text.rb +42 -0
- data/lib/gruff/scatter.rb +154 -179
- data/lib/gruff/scene.rb +31 -41
- data/lib/gruff/side_bar.rb +64 -63
- data/lib/gruff/side_stacked_bar.rb +61 -59
- data/lib/gruff/spider.rb +25 -49
- data/lib/gruff/stacked_area.rb +21 -29
- data/lib/gruff/stacked_bar.rb +77 -49
- data/lib/gruff/store/base_data.rb +34 -0
- data/lib/gruff/store/custom_data.rb +34 -0
- data/lib/gruff/store/store.rb +80 -0
- data/lib/gruff/store/xy_data.rb +55 -0
- data/lib/gruff/themes.rb +32 -33
- data/lib/gruff/version.rb +3 -1
- metadata +75 -1084
- data/Manifest.txt +0 -81
- data/RELEASE.md +0 -41
- data/assets/bubble.png +0 -0
- data/assets/city_scene/background/0000.png +0 -0
- data/assets/city_scene/background/0600.png +0 -0
- data/assets/city_scene/background/2000.png +0 -0
- data/assets/city_scene/clouds/cloudy.png +0 -0
- data/assets/city_scene/clouds/partly_cloudy.png +0 -0
- data/assets/city_scene/clouds/stormy.png +0 -0
- data/assets/city_scene/grass/default.png +0 -0
- data/assets/city_scene/haze/true.png +0 -0
- data/assets/city_scene/number_sample/1.png +0 -0
- data/assets/city_scene/number_sample/2.png +0 -0
- data/assets/city_scene/number_sample/default.png +0 -0
- data/assets/city_scene/sky/0000.png +0 -0
- data/assets/city_scene/sky/0200.png +0 -0
- data/assets/city_scene/sky/0400.png +0 -0
- data/assets/city_scene/sky/0600.png +0 -0
- data/assets/city_scene/sky/0800.png +0 -0
- data/assets/city_scene/sky/1000.png +0 -0
- data/assets/city_scene/sky/1200.png +0 -0
- data/assets/city_scene/sky/1400.png +0 -0
- data/assets/city_scene/sky/1500.png +0 -0
- data/assets/city_scene/sky/1700.png +0 -0
- data/assets/city_scene/sky/2000.png +0 -0
- data/assets/pc306715.jpg +0 -0
- data/lib/gruff/bar_conversion.rb +0 -46
- data/lib/gruff/deprecated.rb +0 -39
- data/test/gruff_test_case.rb +0 -154
- data/test/image_compare.rb +0 -58
- data/test/output/accum_bar.png +0 -0
- data/test/output/area_keynote.png +0 -0
- data/test/output/area_keynote_small.png +0 -0
- data/test/output/area_many.png +0 -0
- data/test/output/area_many_areas_small.png +0 -0
- data/test/output/area_tiny.png +0 -0
- data/test/output/area_wide.png +0 -0
- data/test/output/bar2_wrapped_legend_16_400.png +0 -0
- data/test/output/bar2_wrapped_legend_16_800.png +0 -0
- data/test/output/bar2_wrapped_legend_30_400.png +0 -0
- data/test/output/bar2_wrapped_legend_30_800.png +0 -0
- data/test/output/bar2_wrapped_legend_4_400.png +0 -0
- data/test/output/bar2_wrapped_legend_4_800.png +0 -0
- data/test/output/bar2_wrapped_legend__400.png +0 -0
- data/test/output/bar2_wrapped_legend__800.png +0 -0
- data/test/output/bar_background_gradient_bottom_top.png +0 -0
- data/test/output/bar_background_gradient_left_right.png +0 -0
- data/test/output/bar_background_gradient_right_left.png +0 -0
- data/test/output/bar_background_gradient_top_bottom.png +0 -0
- data/test/output/bar_background_gradient_topleft_bottomright.png +0 -0
- data/test/output/bar_background_gradient_topright_bottomleft.png +0 -0
- data/test/output/bar_formatted_numbers.png +0 -0
- data/test/output/bar_keynote.png +0 -0
- data/test/output/bar_keynote_small.png +0 -0
- data/test/output/bar_long_legend_text.png +0 -0
- data/test/output/bar_manual_colors.png +0 -0
- data/test/output/bar_marker_shadow.png +0 -0
- data/test/output/bar_nearly_zero_max_10.png +0 -0
- data/test/output/bar_no_legend.png +0 -0
- data/test/output/bar_no_line_markers.png +0 -0
- data/test/output/bar_no_title.png +0 -0
- data/test/output/bar_no_title_or_legend.png +0 -0
- data/test/output/bar_odeo.png +0 -0
- data/test/output/bar_one_value.png +0 -0
- data/test/output/bar_pos_neg.png +0 -0
- data/test/output/bar_rails_keynote.png +0 -0
- data/test/output/bar_set_absolute_trunc.png +0 -0
- data/test/output/bar_set_label_stagger_height.png +0 -0
- data/test/output/bar_set_legend_box_size_lg.png +0 -0
- data/test/output/bar_set_legend_box_size_sm.png +0 -0
- data/test/output/bar_set_marker.png +0 -0
- data/test/output/bar_set_trailing_dots_trunc.png +0 -0
- data/test/output/bar_spacing_full.png +0 -0
- data/test/output/bar_spacing_half.png +0 -0
- data/test/output/bar_spacing_none.png +0 -0
- data/test/output/bar_tall_graph.png +0 -0
- data/test/output/bar_tall_graph_small.png +0 -0
- data/test/output/bar_themed.png +0 -0
- data/test/output/bar_title_margin.png +0 -0
- data/test/output/bar_value_labels.png +0 -0
- data/test/output/bar_wide_graph.png +0 -0
- data/test/output/bar_wide_graph_small.png +0 -0
- data/test/output/bar_wrapped_legend_16_400.png +0 -0
- data/test/output/bar_wrapped_legend_16_800.png +0 -0
- data/test/output/bar_wrapped_legend_30_400.png +0 -0
- data/test/output/bar_wrapped_legend_30_800.png +0 -0
- data/test/output/bar_wrapped_legend_4_400.png +0 -0
- data/test/output/bar_wrapped_legend_4_800.png +0 -0
- data/test/output/bar_wrapped_legend__400.png +0 -0
- data/test/output/bar_wrapped_legend__800.png +0 -0
- data/test/output/bar_x_y_labels.png +0 -0
- data/test/output/bar_y_increment_1.png +0 -0
- data/test/output/bar_y_increment_2.0.png +0 -0
- data/test/output/bar_y_increment_20.png +0 -0
- data/test/output/bar_y_increment_5.png +0 -0
- data/test/output/bar_zero_marker_count.png +0 -0
- data/test/output/bar_zero_spacing.png +0 -0
- data/test/output/bezier.png +0 -0
- data/test/output/bezier_2.png +0 -0
- data/test/output/bezier_3.png +0 -0
- data/test/output/bullet_greyscale.png +0 -0
- data/test/output/bullet_no_options.png +0 -0
- data/test/output/dot.png +0 -0
- data/test/output/dot_manual_colors.png +0 -0
- data/test/output/dot_nearly_zero_max_10.png +0 -0
- data/test/output/dot_no_legend.png +0 -0
- data/test/output/dot_no_line_markers.png +0 -0
- data/test/output/dot_no_title.png +0 -0
- data/test/output/dot_no_title_or_legend.png +0 -0
- data/test/output/dot_one_value.png +0 -0
- data/test/output/dot_pos_neg.png +0 -0
- data/test/output/dot_set_legend_box_size_lg.png +0 -0
- data/test/output/dot_set_legend_box_size_sm.png +0 -0
- data/test/output/dot_set_marker.png +0 -0
- data/test/output/dot_small.png +0 -0
- data/test/output/dot_tall_graph.png +0 -0
- data/test/output/dot_tall_graph_small.png +0 -0
- data/test/output/dot_themed.png +0 -0
- data/test/output/dot_wide_graph.png +0 -0
- data/test/output/dot_wide_graph_small.png +0 -0
- data/test/output/dot_x_y_labels.png +0 -0
- data/test/output/dot_y_increment_1.png +0 -0
- data/test/output/dot_y_increment_2.0.png +0 -0
- data/test/output/dot_y_increment_20.png +0 -0
- data/test/output/dot_y_increment_5.png +0 -0
- data/test/output/enhancements-1.png +0 -0
- data/test/output/enhancements.png +0 -0
- data/test/output/line_all_neg.png +0 -0
- data/test/output/line_all_neg_400.png +0 -0
- data/test/output/line_all_neg_no_max.png +0 -0
- data/test/output/line_baseline.png +0 -0
- data/test/output/line_hang_value.png +0 -0
- data/test/output/line_hide_dots.png +0 -0
- data/test/output/line_hide_lines.png +0 -0
- data/test/output/line_jruby_error.png +0 -0
- data/test/output/line_large.png +0 -0
- data/test/output/line_large_baseline.png +0 -0
- data/test/output/line_legend_at_bottom.png +0 -0
- data/test/output/line_many.png +0 -0
- data/test/output/line_many_lines_small.png +0 -0
- data/test/output/line_many_numbers.png +0 -0
- data/test/output/line_marker_label_accuracy.png +0 -0
- data/test/output/line_more_sets_than_colors.png +0 -0
- data/test/output/line_no_data.png +0 -0
- data/test/output/line_no_data_msg.png +0 -0
- data/test/output/line_no_data_other.png +0 -0
- data/test/output/line_no_hide.png +0 -0
- data/test/output/line_no_legend.png +0 -0
- data/test/output/line_no_line_markers.png +0 -0
- data/test/output/line_no_title.png +0 -0
- data/test/output/line_nothing_but_the_graph.png +0 -0
- data/test/output/line_one_value.png +0 -0
- data/test/output/line_one_value_array.png +0 -0
- data/test/output/line_pos_neg.png +0 -0
- data/test/output/line_pos_neg_400.png +0 -0
- data/test/output/line_reference_lines.png +0 -0
- data/test/output/line_similar_high_end_values.png +0 -0
- data/test/output/line_similar_high_end_values_with_floor.png +0 -0
- data/test/output/line_small_small_zero.png +0 -0
- data/test/output/line_small_values.png +0 -0
- data/test/output/line_small_values_small.png +0 -0
- data/test/output/line_small_zero.png +0 -0
- data/test/output/line_some_nil_points.png +0 -0
- data/test/output/line_theme_37signals_.png +0 -0
- data/test/output/line_theme_37signals_400.png +0 -0
- data/test/output/line_theme_keynote_.png +0 -0
- data/test/output/line_theme_keynote_400.png +0 -0
- data/test/output/line_theme_odeo_.png +0 -0
- data/test/output/line_theme_odeo_400.png +0 -0
- data/test/output/line_theme_rails_keynote_.png +0 -0
- data/test/output/line_theme_rails_keynote_400.png +0 -0
- data/test/output/line_tiny.png +0 -0
- data/test/output/line_transparent.png +0 -0
- data/test/output/line_very_small.png +0 -0
- data/test/output/line_webp.webp +0 -0
- data/test/output/line_wide_graph.png +0 -0
- data/test/output/line_wide_graph_small.png +0 -0
- data/test/output/line_xy.png +0 -0
- data/test/output/line_xy_pairs.png +0 -0
- data/test/output/line_y_axis_increment.png +0 -0
- data/test/output/mini_bar.png +0 -0
- data/test/output/mini_pie.png +0 -0
- data/test/output/mini_pie_right_legend.png +0 -0
- data/test/output/mini_side_bar.png +0 -0
- data/test/output/mini_side_bar_multi_color.png +0 -0
- data/test/output/net_dots_tiny.png +0 -0
- data/test/output/net_large.png +0 -0
- data/test/output/net_many.png +0 -0
- data/test/output/net_many_nets_small.png +0 -0
- data/test/output/net_no_data.png +0 -0
- data/test/output/net_no_data_msg.png +0 -0
- data/test/output/net_no_data_other.png +0 -0
- data/test/output/net_no_legend.png +0 -0
- data/test/output/net_no_net_markers.png +0 -0
- data/test/output/net_no_title.png +0 -0
- data/test/output/net_nothing_but_the_graph.png +0 -0
- data/test/output/net_similar_high_end_values.png +0 -0
- data/test/output/net_small.png +0 -0
- data/test/output/net_small_small.png +0 -0
- data/test/output/net_small_small_zero.png +0 -0
- data/test/output/net_small_zero.png +0 -0
- data/test/output/net_wide_graph.png +0 -0
- data/test/output/net_wide_graph_small.png +0 -0
- data/test/output/pie_equal.png +0 -0
- data/test/output/pie_grey.png +0 -0
- data/test/output/pie_keynote.png +0 -0
- data/test/output/pie_keynote_small.png +0 -0
- data/test/output/pie_legend.png +0 -0
- data/test/output/pie_legend_small.png +0 -0
- data/test/output/pie_nearly_equal.png +0 -0
- data/test/output/pie_one_val.png +0 -0
- data/test/output/pie_pastel.png +0 -0
- data/test/output/pie_simple.png +0 -0
- data/test/output/pie_wide.png +0 -0
- data/test/output/pie_wrapped_legend_16_400.png +0 -0
- data/test/output/pie_wrapped_legend_16_800.png +0 -0
- data/test/output/pie_wrapped_legend_30_400.png +0 -0
- data/test/output/pie_wrapped_legend_30_800.png +0 -0
- data/test/output/pie_wrapped_legend_4_400.png +0 -0
- data/test/output/pie_wrapped_legend_4_800.png +0 -0
- data/test/output/pie_wrapped_legend__400.png +0 -0
- data/test/output/pie_wrapped_legend__800.png +0 -0
- data/test/output/pie_zero.png +0 -0
- data/test/output/scatter_all_neg.png +0 -0
- data/test/output/scatter_all_neg_400.png +0 -0
- data/test/output/scatter_basic.png +0 -0
- data/test/output/scatter_many.png +0 -0
- data/test/output/scatter_no_data.png +0 -0
- data/test/output/scatter_no_data_msg.png +0 -0
- data/test/output/scatter_no_data_other.png +0 -0
- data/test/output/scatter_no_hide.png +0 -0
- data/test/output/scatter_no_labels.png +0 -0
- data/test/output/scatter_no_legend.png +0 -0
- data/test/output/scatter_no_line_markers.png +0 -0
- data/test/output/scatter_no_title.png +0 -0
- data/test/output/scatter_nothing_but_the_graph.png +0 -0
- data/test/output/scatter_pos_neg.png +0 -0
- data/test/output/scatter_pos_neg_400.png +0 -0
- data/test/output/scatter_wide_graph.png +0 -0
- data/test/output/scatter_wide_graph_small.png +0 -0
- data/test/output/scene_hazy_night.png +0 -0
- data/test/output/scene_not_hazy_day.png +0 -0
- data/test/output/scene_partly_cloudy_day.png +0 -0
- data/test/output/scene_stormy_day.png +0 -0
- data/test/output/scene_stormy_night.png +0 -0
- data/test/output/side_bar.png +0 -0
- data/test/output/side_bar_data_range.png +0 -0
- data/test/output/side_bar_labels.png +0 -0
- data/test/output/side_bar_spacing_full.png +0 -0
- data/test/output/side_bar_spacing_half.png +0 -0
- data/test/output/side_bar_spacing_none.png +0 -0
- data/test/output/side_stacked_bar_keynote.png +0 -0
- data/test/output/side_stacked_bar_keynote_small.png +0 -0
- data/test/output/side_stacked_bar_labels.png +0 -0
- data/test/output/side_stacked_bar_long_label.png +0 -0
- data/test/output/side_stacked_bar_wide.png +0 -0
- data/test/output/spider_37signals.png +0 -0
- data/test/output/spider_equal.png +0 -0
- data/test/output/spider_keynote.png +0 -0
- data/test/output/spider_legend.png +0 -0
- data/test/output/spider_legend_small.png +0 -0
- data/test/output/spider_lots_of_data.png +0 -0
- data/test/output/spider_lots_of_data_normal_names.png +0 -0
- data/test/output/spider_nearly_equal.png +0 -0
- data/test/output/spider_no_axes.png +0 -0
- data/test/output/spider_no_background.png +0 -0
- data/test/output/spider_no_print.png +0 -0
- data/test/output/spider_overlay_1.png +0 -0
- data/test/output/spider_overlay_2.png +0 -0
- data/test/output/spider_rotation.png +0 -0
- data/test/output/spider_small.png +0 -0
- data/test/output/spider_wide.png +0 -0
- data/test/output/spider_zero.png +0 -0
- data/test/output/stacked_area_keynote.png +0 -0
- data/test/output/stacked_area_keynote_small.png +0 -0
- data/test/output/stacked_bar_keynote.png +0 -0
- data/test/output/stacked_bar_keynote_small.png +0 -0
- data/test/output_java/accum_bar.png +0 -0
- data/test/output_java/area_keynote.png +0 -0
- data/test/output_java/area_keynote_small.png +0 -0
- data/test/output_java/area_many.png +0 -0
- data/test/output_java/area_many_areas_small.png +0 -0
- data/test/output_java/area_tiny.png +0 -0
- data/test/output_java/area_wide.png +0 -0
- data/test/output_java/bar2_wrapped_legend_16_400.png +0 -0
- data/test/output_java/bar2_wrapped_legend_16_800.png +0 -0
- data/test/output_java/bar2_wrapped_legend_30_400.png +0 -0
- data/test/output_java/bar2_wrapped_legend_30_800.png +0 -0
- data/test/output_java/bar2_wrapped_legend_4_400.png +0 -0
- data/test/output_java/bar2_wrapped_legend_4_800.png +0 -0
- data/test/output_java/bar2_wrapped_legend__400.png +0 -0
- data/test/output_java/bar2_wrapped_legend__800.png +0 -0
- data/test/output_java/bar_background_gradient_bottom_top.png +0 -0
- data/test/output_java/bar_background_gradient_left_right.png +0 -0
- data/test/output_java/bar_background_gradient_right_left.png +0 -0
- data/test/output_java/bar_background_gradient_top_bottom.png +0 -0
- data/test/output_java/bar_background_gradient_topleft_bottomright.png +0 -0
- data/test/output_java/bar_background_gradient_topright_bottomleft.png +0 -0
- data/test/output_java/bar_formatted_numbers.png +0 -0
- data/test/output_java/bar_keynote.png +0 -0
- data/test/output_java/bar_keynote_small.png +0 -0
- data/test/output_java/bar_long_legend_text.png +0 -0
- data/test/output_java/bar_manual_colors.png +0 -0
- data/test/output_java/bar_marker_shadow.png +0 -0
- data/test/output_java/bar_nearly_zero_max_10.png +0 -0
- data/test/output_java/bar_no_legend.png +0 -0
- data/test/output_java/bar_no_line_markers.png +0 -0
- data/test/output_java/bar_no_title.png +0 -0
- data/test/output_java/bar_no_title_or_legend.png +0 -0
- data/test/output_java/bar_odeo.png +0 -0
- data/test/output_java/bar_one_value.png +0 -0
- data/test/output_java/bar_pos_neg.png +0 -0
- data/test/output_java/bar_rails_keynote.png +0 -0
- data/test/output_java/bar_set_absolute_trunc.png +0 -0
- data/test/output_java/bar_set_label_stagger_height.png +0 -0
- data/test/output_java/bar_set_legend_box_size_lg.png +0 -0
- data/test/output_java/bar_set_legend_box_size_sm.png +0 -0
- data/test/output_java/bar_set_marker.png +0 -0
- data/test/output_java/bar_set_trailing_dots_trunc.png +0 -0
- data/test/output_java/bar_spacing_full.png +0 -0
- data/test/output_java/bar_spacing_half.png +0 -0
- data/test/output_java/bar_spacing_none.png +0 -0
- data/test/output_java/bar_tall_graph.png +0 -0
- data/test/output_java/bar_tall_graph_small.png +0 -0
- data/test/output_java/bar_themed.png +0 -0
- data/test/output_java/bar_title_margin.png +0 -0
- data/test/output_java/bar_value_labels.png +0 -0
- data/test/output_java/bar_wide_graph.png +0 -0
- data/test/output_java/bar_wide_graph_small.png +0 -0
- data/test/output_java/bar_wrapped_legend_16_400.png +0 -0
- data/test/output_java/bar_wrapped_legend_16_800.png +0 -0
- data/test/output_java/bar_wrapped_legend_30_400.png +0 -0
- data/test/output_java/bar_wrapped_legend_30_800.png +0 -0
- data/test/output_java/bar_wrapped_legend_4_400.png +0 -0
- data/test/output_java/bar_wrapped_legend_4_800.png +0 -0
- data/test/output_java/bar_wrapped_legend__400.png +0 -0
- data/test/output_java/bar_wrapped_legend__800.png +0 -0
- data/test/output_java/bar_x_y_labels.png +0 -0
- data/test/output_java/bar_y_increment_1.png +0 -0
- data/test/output_java/bar_y_increment_2.0.png +0 -0
- data/test/output_java/bar_y_increment_20.png +0 -0
- data/test/output_java/bar_y_increment_5.png +0 -0
- data/test/output_java/bar_zero_marker_count.png +0 -0
- data/test/output_java/bar_zero_spacing.png +0 -0
- data/test/output_java/bezier.png +0 -0
- data/test/output_java/bezier_2.png +0 -0
- data/test/output_java/bezier_3.png +0 -0
- data/test/output_java/bullet_greyscale.png +0 -0
- data/test/output_java/bullet_no_options.png +0 -0
- data/test/output_java/dot.png +0 -0
- data/test/output_java/dot_manual_colors.png +0 -0
- data/test/output_java/dot_nearly_zero_max_10.png +0 -0
- data/test/output_java/dot_no_legend.png +0 -0
- data/test/output_java/dot_no_line_markers.png +0 -0
- data/test/output_java/dot_no_title.png +0 -0
- data/test/output_java/dot_no_title_or_legend.png +0 -0
- data/test/output_java/dot_one_value.png +0 -0
- data/test/output_java/dot_pos_neg.png +0 -0
- data/test/output_java/dot_set_legend_box_size_lg.png +0 -0
- data/test/output_java/dot_set_legend_box_size_sm.png +0 -0
- data/test/output_java/dot_set_marker.png +0 -0
- data/test/output_java/dot_small.png +0 -0
- data/test/output_java/dot_tall_graph.png +0 -0
- data/test/output_java/dot_tall_graph_small.png +0 -0
- data/test/output_java/dot_themed.png +0 -0
- data/test/output_java/dot_wide_graph.png +0 -0
- data/test/output_java/dot_wide_graph_small.png +0 -0
- data/test/output_java/dot_x_y_labels.png +0 -0
- data/test/output_java/dot_y_increment_1.png +0 -0
- data/test/output_java/dot_y_increment_2.0.png +0 -0
- data/test/output_java/dot_y_increment_20.png +0 -0
- data/test/output_java/dot_y_increment_5.png +0 -0
- data/test/output_java/enhancements-1.png +0 -0
- data/test/output_java/enhancements.png +0 -0
- data/test/output_java/line_all_neg.png +0 -0
- data/test/output_java/line_all_neg_400.png +0 -0
- data/test/output_java/line_all_neg_no_max.png +0 -0
- data/test/output_java/line_baseline.png +0 -0
- data/test/output_java/line_hang_value.png +0 -0
- data/test/output_java/line_hide_dots.png +0 -0
- data/test/output_java/line_hide_lines.png +0 -0
- data/test/output_java/line_jruby_error.png +0 -0
- data/test/output_java/line_large.png +0 -0
- data/test/output_java/line_large_baseline.png +0 -0
- data/test/output_java/line_legend_at_bottom.png +0 -0
- data/test/output_java/line_many.png +0 -0
- data/test/output_java/line_many_lines_small.png +0 -0
- data/test/output_java/line_many_numbers.png +0 -0
- data/test/output_java/line_marker_label_accuracy.png +0 -0
- data/test/output_java/line_more_sets_than_colors.png +0 -0
- data/test/output_java/line_no_data.png +0 -0
- data/test/output_java/line_no_data_msg.png +0 -0
- data/test/output_java/line_no_data_other.png +0 -0
- data/test/output_java/line_no_hide.png +0 -0
- data/test/output_java/line_no_legend.png +0 -0
- data/test/output_java/line_no_line_markers.png +0 -0
- data/test/output_java/line_no_title.png +0 -0
- data/test/output_java/line_nothing_but_the_graph.png +0 -0
- data/test/output_java/line_one_value.png +0 -0
- data/test/output_java/line_one_value_array.png +0 -0
- data/test/output_java/line_pos_neg.png +0 -0
- data/test/output_java/line_pos_neg_400.png +0 -0
- data/test/output_java/line_reference_lines.png +0 -0
- data/test/output_java/line_similar_high_end_values.png +0 -0
- data/test/output_java/line_similar_high_end_values_with_floor.png +0 -0
- data/test/output_java/line_small_small_zero.png +0 -0
- data/test/output_java/line_small_values.png +0 -0
- data/test/output_java/line_small_values_small.png +0 -0
- data/test/output_java/line_small_zero.png +0 -0
- data/test/output_java/line_some_nil_points.png +0 -0
- data/test/output_java/line_theme_37signals_.png +0 -0
- data/test/output_java/line_theme_37signals_400.png +0 -0
- data/test/output_java/line_theme_keynote_.png +0 -0
- data/test/output_java/line_theme_keynote_400.png +0 -0
- data/test/output_java/line_theme_odeo_.png +0 -0
- data/test/output_java/line_theme_odeo_400.png +0 -0
- data/test/output_java/line_theme_rails_keynote_.png +0 -0
- data/test/output_java/line_theme_rails_keynote_400.png +0 -0
- data/test/output_java/line_tiny.png +0 -0
- data/test/output_java/line_transparent.png +0 -0
- data/test/output_java/line_very_small.png +0 -0
- data/test/output_java/line_webp.webp +0 -0
- data/test/output_java/line_wide_graph.png +0 -0
- data/test/output_java/line_wide_graph_small.png +0 -0
- data/test/output_java/line_xy.png +0 -0
- data/test/output_java/line_xy_pairs.png +0 -0
- data/test/output_java/line_y_axis_increment.png +0 -0
- data/test/output_java/mini_bar.png +0 -0
- data/test/output_java/mini_pie.png +0 -0
- data/test/output_java/mini_pie_right_legend.png +0 -0
- data/test/output_java/mini_side_bar.png +0 -0
- data/test/output_java/mini_side_bar_multi_color.png +0 -0
- data/test/output_java/net_dots_tiny.png +0 -0
- data/test/output_java/net_large.png +0 -0
- data/test/output_java/net_many.png +0 -0
- data/test/output_java/net_many_nets_small.png +0 -0
- data/test/output_java/net_no_data.png +0 -0
- data/test/output_java/net_no_data_msg.png +0 -0
- data/test/output_java/net_no_data_other.png +0 -0
- data/test/output_java/net_no_legend.png +0 -0
- data/test/output_java/net_no_net_markers.png +0 -0
- data/test/output_java/net_no_title.png +0 -0
- data/test/output_java/net_nothing_but_the_graph.png +0 -0
- data/test/output_java/net_similar_high_end_values.png +0 -0
- data/test/output_java/net_small.png +0 -0
- data/test/output_java/net_small_small.png +0 -0
- data/test/output_java/net_small_small_zero.png +0 -0
- data/test/output_java/net_small_zero.png +0 -0
- data/test/output_java/net_wide_graph.png +0 -0
- data/test/output_java/net_wide_graph_small.png +0 -0
- data/test/output_java/pie_equal.png +0 -0
- data/test/output_java/pie_grey.png +0 -0
- data/test/output_java/pie_keynote.png +0 -0
- data/test/output_java/pie_keynote_small.png +0 -0
- data/test/output_java/pie_legend.png +0 -0
- data/test/output_java/pie_legend_small.png +0 -0
- data/test/output_java/pie_nearly_equal.png +0 -0
- data/test/output_java/pie_one_val.png +0 -0
- data/test/output_java/pie_pastel.png +0 -0
- data/test/output_java/pie_simple.png +0 -0
- data/test/output_java/pie_wide.png +0 -0
- data/test/output_java/pie_wrapped_legend_16_400.png +0 -0
- data/test/output_java/pie_wrapped_legend_16_800.png +0 -0
- data/test/output_java/pie_wrapped_legend_30_400.png +0 -0
- data/test/output_java/pie_wrapped_legend_30_800.png +0 -0
- data/test/output_java/pie_wrapped_legend_4_400.png +0 -0
- data/test/output_java/pie_wrapped_legend_4_800.png +0 -0
- data/test/output_java/pie_wrapped_legend__400.png +0 -0
- data/test/output_java/pie_wrapped_legend__800.png +0 -0
- data/test/output_java/pie_zero.png +0 -0
- data/test/output_java/scatter_all_neg.png +0 -0
- data/test/output_java/scatter_all_neg_400.png +0 -0
- data/test/output_java/scatter_basic.png +0 -0
- data/test/output_java/scatter_many.png +0 -0
- data/test/output_java/scatter_no_data.png +0 -0
- data/test/output_java/scatter_no_data_msg.png +0 -0
- data/test/output_java/scatter_no_data_other.png +0 -0
- data/test/output_java/scatter_no_hide.png +0 -0
- data/test/output_java/scatter_no_labels.png +0 -0
- data/test/output_java/scatter_no_legend.png +0 -0
- data/test/output_java/scatter_no_line_markers.png +0 -0
- data/test/output_java/scatter_no_title.png +0 -0
- data/test/output_java/scatter_nothing_but_the_graph.png +0 -0
- data/test/output_java/scatter_pos_neg.png +0 -0
- data/test/output_java/scatter_pos_neg_400.png +0 -0
- data/test/output_java/scatter_wide_graph.png +0 -0
- data/test/output_java/scatter_wide_graph_small.png +0 -0
- data/test/output_java/scene_hazy_night.png +0 -0
- data/test/output_java/scene_not_hazy_day.png +0 -0
- data/test/output_java/scene_partly_cloudy_day.png +0 -0
- data/test/output_java/scene_stormy_day.png +0 -0
- data/test/output_java/scene_stormy_night.png +0 -0
- data/test/output_java/side_bar.png +0 -0
- data/test/output_java/side_bar_data_range.png +0 -0
- data/test/output_java/side_bar_labels.png +0 -0
- data/test/output_java/side_bar_spacing_full.png +0 -0
- data/test/output_java/side_bar_spacing_half.png +0 -0
- data/test/output_java/side_bar_spacing_none.png +0 -0
- data/test/output_java/side_stacked_bar_keynote.png +0 -0
- data/test/output_java/side_stacked_bar_keynote_small.png +0 -0
- data/test/output_java/side_stacked_bar_labels.png +0 -0
- data/test/output_java/side_stacked_bar_long_label.png +0 -0
- data/test/output_java/side_stacked_bar_wide.png +0 -0
- data/test/output_java/spider_37signals.png +0 -0
- data/test/output_java/spider_equal.png +0 -0
- data/test/output_java/spider_keynote.png +0 -0
- data/test/output_java/spider_legend.png +0 -0
- data/test/output_java/spider_legend_small.png +0 -0
- data/test/output_java/spider_lots_of_data.png +0 -0
- data/test/output_java/spider_lots_of_data_normal_names.png +0 -0
- data/test/output_java/spider_nearly_equal.png +0 -0
- data/test/output_java/spider_no_axes.png +0 -0
- data/test/output_java/spider_no_background.png +0 -0
- data/test/output_java/spider_no_print.png +0 -0
- data/test/output_java/spider_overlay_1.png +0 -0
- data/test/output_java/spider_overlay_2.png +0 -0
- data/test/output_java/spider_rotation.png +0 -0
- data/test/output_java/spider_small.png +0 -0
- data/test/output_java/spider_wide.png +0 -0
- data/test/output_java/spider_zero.png +0 -0
- data/test/output_java/stacked_area_keynote.png +0 -0
- data/test/output_java/stacked_area_keynote_small.png +0 -0
- data/test/output_java/stacked_bar_keynote.png +0 -0
- data/test/output_java/stacked_bar_keynote_small.png +0 -0
- data/test/test_accumulator_bar.rb +0 -51
- data/test/test_area.rb +0 -134
- data/test/test_bar.rb +0 -505
- data/test/test_base.rb +0 -8
- data/test/test_bezier.rb +0 -33
- data/test/test_bullet.rb +0 -26
- data/test/test_dot.rb +0 -263
- data/test/test_legend.rb +0 -68
- data/test/test_line.rb +0 -657
- data/test/test_mini_bar.rb +0 -33
- data/test/test_mini_pie.rb +0 -25
- data/test/test_mini_side_bar.rb +0 -36
- data/test/test_net.rb +0 -231
- data/test/test_photo.rb +0 -41
- data/test/test_pie.rb +0 -154
- data/test/test_scatter.rb +0 -233
- data/test/test_scene.rb +0 -100
- data/test/test_side_bar.rb +0 -56
- data/test/test_sidestacked_bar.rb +0 -105
- data/test/test_spider.rb +0 -226
- data/test/test_stacked_area.rb +0 -52
- data/test/test_stacked_bar.rb +0 -52
data/lib/gruff/scene.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
|
|
2
|
-
require
|
|
3
|
-
require
|
|
3
|
+
require 'observer'
|
|
4
|
+
require 'gruff/base'
|
|
4
5
|
|
|
5
|
-
##
|
|
6
6
|
# A scene is a non-linear graph that assembles layers together to tell a story.
|
|
7
|
-
# Layers are folders with appropriately named files (see below). You can group
|
|
7
|
+
# Layers are folders with appropriately named files (see below). You can group
|
|
8
8
|
# layers and control them together or just set their values individually.
|
|
9
9
|
#
|
|
10
10
|
# Examples:
|
|
@@ -12,8 +12,6 @@ require File.dirname(__FILE__) + '/base'
|
|
|
12
12
|
# * A city scene that changes with the time of day and the weather conditions.
|
|
13
13
|
# * A traffic map that shows red lines on streets that are crowded and green on free-flowing ones.
|
|
14
14
|
#
|
|
15
|
-
# Usage:
|
|
16
|
-
#
|
|
17
15
|
# g = Gruff::Scene.new("500x100", "path/to/city_scene_directory")
|
|
18
16
|
#
|
|
19
17
|
# # Define order of layers, back to front
|
|
@@ -31,34 +29,31 @@ require File.dirname(__FILE__) + '/base'
|
|
|
31
29
|
# # Write the final graph to disk
|
|
32
30
|
# g.write "hazy_daytime_city_scene.png"
|
|
33
31
|
#
|
|
34
|
-
#
|
|
35
32
|
# There are several rules that will magically select a layer when possible.
|
|
36
33
|
#
|
|
37
34
|
# * Numbered files will be selected according to the closest value that is less than the input value.
|
|
38
|
-
# * 'true.png' and 'false.png' will be used as booleans.
|
|
35
|
+
# * +'true.png'+ and +'false.png'+ will be used as booleans.
|
|
39
36
|
# * Other named files will be used if the input matches the filename (without the filetype extension).
|
|
40
|
-
# * If there is a file named 'default.png'
|
|
41
|
-
|
|
37
|
+
# * If there is a file named +'default.png'+, it will be used unless other input values are set for the corresponding layer.
|
|
42
38
|
class Gruff::Scene < Gruff::Base
|
|
43
|
-
|
|
44
|
-
# An array listing the foldernames that will be rendered, from back to front.
|
|
45
|
-
#
|
|
46
|
-
# g.layers = %w(sky clouds buildings street people)
|
|
39
|
+
# An array listing the folder names that will be rendered, from back to front.
|
|
47
40
|
#
|
|
41
|
+
# @example
|
|
42
|
+
# g.layers = %w(sky clouds buildings street people)
|
|
48
43
|
attr_reader :layers
|
|
49
44
|
|
|
50
45
|
def initialize(target_width, base_dir)
|
|
51
46
|
@base_dir = base_dir
|
|
52
47
|
@groups = {}
|
|
53
|
-
@layers = []
|
|
48
|
+
@layers = []
|
|
54
49
|
super target_width
|
|
55
50
|
end
|
|
56
51
|
|
|
57
52
|
def draw
|
|
58
53
|
# Join all the custom paths and filter out the empty ones
|
|
59
|
-
image_paths = @layers.map
|
|
54
|
+
image_paths = @layers.map(&:path).reject(&:empty?)
|
|
60
55
|
images = Magick::ImageList.new(*image_paths)
|
|
61
|
-
|
|
56
|
+
Gruff::Renderer.background_image = images.flatten_images
|
|
62
57
|
end
|
|
63
58
|
|
|
64
59
|
def layers=(ordered_list)
|
|
@@ -78,10 +73,10 @@ class Gruff::Scene < Gruff::Base
|
|
|
78
73
|
def method_missing(method_name, *args)
|
|
79
74
|
case method_name.to_s
|
|
80
75
|
when /^(\w+)_group=$/
|
|
81
|
-
add_group
|
|
76
|
+
add_group Regexp.last_match(1), *args
|
|
82
77
|
return
|
|
83
78
|
when /^(\w+)=$/
|
|
84
|
-
set_input
|
|
79
|
+
set_input Regexp.last_match(1), args.first
|
|
85
80
|
return
|
|
86
81
|
end
|
|
87
82
|
super
|
|
@@ -94,20 +89,16 @@ private
|
|
|
94
89
|
end
|
|
95
90
|
|
|
96
91
|
def set_input(input_name, input_value)
|
|
97
|
-
if
|
|
92
|
+
if !@groups[input_name].nil?
|
|
98
93
|
@groups[input_name].send_updates(input_value)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
chosen_layer.update input_value
|
|
102
|
-
end
|
|
94
|
+
elsif chosen_layer = @layers.find { |layer| layer.name == input_name }
|
|
95
|
+
chosen_layer.update input_value
|
|
103
96
|
end
|
|
104
97
|
end
|
|
105
|
-
|
|
106
98
|
end
|
|
107
99
|
|
|
108
|
-
|
|
100
|
+
# @private
|
|
109
101
|
class Gruff::Group
|
|
110
|
-
|
|
111
102
|
include Observable
|
|
112
103
|
attr_reader :name
|
|
113
104
|
|
|
@@ -117,31 +108,29 @@ class Gruff::Group
|
|
|
117
108
|
layer.observe self
|
|
118
109
|
end
|
|
119
110
|
end
|
|
120
|
-
|
|
111
|
+
|
|
121
112
|
def send_updates(value)
|
|
122
113
|
changed
|
|
123
114
|
notify_observers value
|
|
124
115
|
end
|
|
125
|
-
|
|
126
116
|
end
|
|
127
117
|
|
|
128
|
-
|
|
118
|
+
# @private
|
|
129
119
|
class Gruff::Layer
|
|
130
|
-
|
|
131
120
|
attr_reader :name
|
|
132
|
-
|
|
121
|
+
|
|
133
122
|
def initialize(base_dir, folder_name)
|
|
134
123
|
@base_dir = base_dir.to_s
|
|
135
124
|
@name = folder_name.to_s
|
|
136
125
|
@filenames = Dir.open(File.join(base_dir, folder_name)).entries.select { |file| file =~ /^[^.]+\.png$/ }.sort
|
|
137
126
|
@selected_filename = select_default
|
|
138
127
|
end
|
|
139
|
-
|
|
128
|
+
|
|
140
129
|
# Register this layer so it receives updates from the group
|
|
141
130
|
def observe(obj)
|
|
142
131
|
obj.add_observer self
|
|
143
132
|
end
|
|
144
|
-
|
|
133
|
+
|
|
145
134
|
# Choose the appropriate filename for this layer, based on the input
|
|
146
135
|
def update(value)
|
|
147
136
|
@selected_filename = case value.to_s
|
|
@@ -152,7 +141,7 @@ class Gruff::Layer
|
|
|
152
141
|
when /^-?(\d+\.)?\d+$/
|
|
153
142
|
select_numeric value
|
|
154
143
|
when /(\d\d):(\d\d):\d\d/
|
|
155
|
-
select_time "#{
|
|
144
|
+
select_time "#{Regexp.last_match(1)}#{Regexp.last_match(2)}"
|
|
156
145
|
else
|
|
157
146
|
select_default
|
|
158
147
|
end
|
|
@@ -165,6 +154,7 @@ class Gruff::Layer
|
|
|
165
154
|
unless @selected_filename.nil? || @selected_filename.empty?
|
|
166
155
|
return File.join(@base_dir, @name, @selected_filename)
|
|
167
156
|
end
|
|
157
|
+
|
|
168
158
|
''
|
|
169
159
|
end
|
|
170
160
|
|
|
@@ -179,7 +169,7 @@ private
|
|
|
179
169
|
def select_numeric(value)
|
|
180
170
|
file_exists_or_blank value.to_s.gsub('-', '_')
|
|
181
171
|
end
|
|
182
|
-
|
|
172
|
+
|
|
183
173
|
def select_time(value)
|
|
184
174
|
times = @filenames.map { |filename| filename.gsub('.png', '') }
|
|
185
175
|
times.each_with_index do |time, index|
|
|
@@ -187,16 +177,17 @@ private
|
|
|
187
177
|
return "#{times[index - 1]}.png"
|
|
188
178
|
end
|
|
189
179
|
end
|
|
190
|
-
|
|
180
|
+
|
|
181
|
+
"#{times.last}.png"
|
|
191
182
|
end
|
|
192
|
-
|
|
183
|
+
|
|
193
184
|
# Match "partly cloudy" to "partly_cloudy.png"
|
|
194
185
|
def select_string(value)
|
|
195
186
|
file_exists_or_blank value.to_s.gsub(' ', '_')
|
|
196
187
|
end
|
|
197
|
-
|
|
188
|
+
|
|
198
189
|
def select_default
|
|
199
|
-
@filenames.include?(
|
|
190
|
+
@filenames.include?('default.png') ? 'default.png' : ''
|
|
200
191
|
end
|
|
201
192
|
|
|
202
193
|
# Returns the string "#{filename}.png", if it exists.
|
|
@@ -205,5 +196,4 @@ private
|
|
|
205
196
|
def file_exists_or_blank(filename)
|
|
206
197
|
@filenames.include?("#{filename}.png") ? "#{filename}.png" : select_default
|
|
207
198
|
end
|
|
208
|
-
|
|
209
199
|
end
|
data/lib/gruff/side_bar.rb
CHANGED
|
@@ -1,44 +1,61 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
# Graph with individual horizontal bars instead of vertical bars.
|
|
3
|
+
require 'gruff/base'
|
|
5
4
|
|
|
5
|
+
# Graph with individual horizontal bars instead of vertical bars.
|
|
6
6
|
class Gruff::SideBar < Gruff::Base
|
|
7
|
-
|
|
8
|
-
# Spacing factor applied between bars
|
|
7
|
+
# Spacing factor applied between bars.
|
|
9
8
|
attr_accessor :bar_spacing
|
|
10
9
|
|
|
10
|
+
# Spacing factor applied between a group of bars belonging to the same label.
|
|
11
|
+
attr_accessor :group_spacing
|
|
12
|
+
|
|
13
|
+
# Set the number output format for labels using sprintf.
|
|
14
|
+
# Default is +"%.2f"+.
|
|
15
|
+
attr_accessor :label_formatting
|
|
16
|
+
|
|
17
|
+
# Output the values for the bars on a bar graph.
|
|
18
|
+
# Default is +false+.
|
|
19
|
+
attr_accessor :show_labels_for_bar_values
|
|
20
|
+
|
|
21
|
+
def initialize_ivars
|
|
22
|
+
super
|
|
23
|
+
@label_formatting = nil
|
|
24
|
+
@show_labels_for_bar_values = false
|
|
25
|
+
end
|
|
26
|
+
private :initialize_ivars
|
|
27
|
+
|
|
11
28
|
def draw
|
|
12
29
|
@has_left_labels = true
|
|
13
30
|
super
|
|
14
31
|
|
|
15
|
-
return unless
|
|
32
|
+
return unless data_given?
|
|
33
|
+
|
|
16
34
|
draw_bars
|
|
17
35
|
end
|
|
18
36
|
|
|
19
|
-
|
|
37
|
+
private
|
|
20
38
|
|
|
21
39
|
def draw_bars
|
|
22
40
|
# Setup spacing.
|
|
23
41
|
#
|
|
24
42
|
@bar_spacing ||= 0.9
|
|
43
|
+
@group_spacing ||= 10
|
|
25
44
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
padding = (@bar_width * (1 - @bar_spacing)) / 2
|
|
45
|
+
bars_width = (@graph_height - calculate_spacing) / column_count.to_f
|
|
46
|
+
bar_width = bars_width / store.length
|
|
47
|
+
height = Array.new(column_count, 0)
|
|
48
|
+
length = Array.new(column_count, @graph_left)
|
|
49
|
+
padding = (bar_width * (1 - @bar_spacing)) / 2
|
|
32
50
|
|
|
33
51
|
# if we're a side stacked bar then we don't need to draw ourself at all
|
|
34
52
|
# because sometimes (due to different heights/min/max) you can actually
|
|
35
53
|
# see both graphs and it looks like crap
|
|
36
|
-
return if
|
|
54
|
+
return if is_a?(Gruff::SideStackedBar)
|
|
37
55
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
data_row[DATA_VALUES_INDEX].each_with_index do |data_point, point_index|
|
|
56
|
+
store.norm_data.each_with_index do |data_row, row_index|
|
|
57
|
+
data_row.points.each_with_index do |data_point, point_index|
|
|
58
|
+
group_spacing = @group_spacing * @scale * point_index
|
|
42
59
|
|
|
43
60
|
# Using the original calcs from the stacked bar chart
|
|
44
61
|
# to get the difference between
|
|
@@ -48,91 +65,75 @@ class Gruff::SideBar < Gruff::Base
|
|
|
48
65
|
difference = temp2 - temp1
|
|
49
66
|
|
|
50
67
|
left_x = length[point_index] - 1
|
|
51
|
-
left_y = @graph_top + (
|
|
68
|
+
left_y = @graph_top + (bars_width * point_index) + (bar_width * row_index) + padding + group_spacing
|
|
52
69
|
right_x = left_x + difference
|
|
53
|
-
right_y = left_y +
|
|
70
|
+
right_y = left_y + bar_width * @bar_spacing
|
|
54
71
|
|
|
55
72
|
height[point_index] += (data_point * @graph_width)
|
|
56
73
|
|
|
57
|
-
|
|
74
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(color: data_row.color)
|
|
75
|
+
rect_renderer.render(left_x, left_y, right_x, right_y)
|
|
58
76
|
|
|
59
77
|
# Calculate center based on bar_width and current row
|
|
60
78
|
|
|
61
79
|
if @use_data_label
|
|
62
|
-
label_center =
|
|
63
|
-
draw_label(label_center, row_index,
|
|
80
|
+
label_center = left_y + bar_width / 2
|
|
81
|
+
draw_label(label_center, row_index, store.norm_data[row_index].label)
|
|
64
82
|
else
|
|
65
|
-
label_center =
|
|
83
|
+
label_center = left_y + bars_width / 2
|
|
66
84
|
draw_label(label_center, point_index)
|
|
67
85
|
end
|
|
68
86
|
if @show_labels_for_bar_values
|
|
69
|
-
val = (@label_formatting || '%.2f') %
|
|
70
|
-
draw_value_label(right_x+40,
|
|
87
|
+
val = (@label_formatting || '%.2f') % store.data[row_index].points[point_index]
|
|
88
|
+
draw_value_label(right_x + 40, right_y - bar_width / 2, val.commify, true)
|
|
71
89
|
end
|
|
72
90
|
end
|
|
73
|
-
|
|
74
91
|
end
|
|
75
92
|
|
|
76
|
-
|
|
93
|
+
Gruff::Renderer.finish
|
|
77
94
|
end
|
|
78
95
|
|
|
79
96
|
# Instead of base class version, draws vertical background lines and label
|
|
80
97
|
def draw_line_markers
|
|
81
|
-
|
|
82
98
|
return if @hide_line_markers
|
|
83
99
|
|
|
84
|
-
@d = @d.stroke_antialias false
|
|
85
|
-
|
|
86
100
|
# Draw horizontal line markers and annotate with numbers
|
|
87
|
-
@d = @d.stroke(@marker_color)
|
|
88
|
-
@d = @d.stroke_width 1
|
|
89
101
|
number_of_lines = @marker_count || 5
|
|
90
102
|
number_of_lines = 1 if number_of_lines == 0
|
|
91
103
|
|
|
92
|
-
# TODO Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
|
|
104
|
+
# TODO: Round maximum marker value to a round number like 100, 0.1, 0.5, etc.
|
|
93
105
|
increment = significant(@spread.to_f / number_of_lines)
|
|
94
106
|
(0..number_of_lines).each do |index|
|
|
95
|
-
|
|
96
107
|
line_diff = (@graph_right - @graph_left) / number_of_lines
|
|
97
108
|
x = @graph_right - (line_diff * index) - 1
|
|
98
|
-
|
|
109
|
+
Gruff::Renderer::Line.new(color: @marker_color).render(x, @graph_bottom, x, @graph_top)
|
|
99
110
|
diff = index - number_of_lines
|
|
100
|
-
marker_label = diff.abs * increment +
|
|
111
|
+
marker_label = diff.abs * increment + minimum_value
|
|
101
112
|
|
|
102
113
|
unless @hide_line_numbers
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@d.pointsize = scale_fontsize(@marker_font_size)
|
|
107
|
-
@d.gravity = CenterGravity
|
|
108
|
-
# TODO Center text over line
|
|
109
|
-
@d = @d.annotate_scaled(@base_image,
|
|
110
|
-
0, 0, # Width of box to draw text in
|
|
111
|
-
x, @graph_bottom + (LABEL_MARGIN * 2.0), # Coordinates of text
|
|
112
|
-
marker_label.to_s, @scale)
|
|
113
|
-
end # unless
|
|
114
|
-
@d = @d.stroke_antialias true
|
|
114
|
+
text_renderer = Gruff::Renderer::Text.new(marker_label, font: @font, size: @marker_font_size, color: @font_color)
|
|
115
|
+
text_renderer.render(0, 0, x, @graph_bottom + (LABEL_MARGIN * 2.0), Magick::CenterGravity)
|
|
116
|
+
end
|
|
115
117
|
end
|
|
116
118
|
end
|
|
117
119
|
|
|
118
120
|
##
|
|
119
121
|
# Draw on the Y axis instead of the X
|
|
120
122
|
|
|
121
|
-
def draw_label(y_offset, index, label=nil)
|
|
122
|
-
|
|
123
|
-
lbl =
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
1, 1,
|
|
132
|
-
-@graph_left + LABEL_MARGIN * 2.0, y_offset,
|
|
133
|
-
lbl, @scale)
|
|
134
|
-
@labels_seen[index] = 1
|
|
123
|
+
def draw_label(y_offset, index, label = nil)
|
|
124
|
+
draw_unique_label(index) do
|
|
125
|
+
lbl = @use_data_label ? label : @labels[index]
|
|
126
|
+
|
|
127
|
+
text_renderer = Gruff::Renderer::Text.new(lbl, font: @font, size: @marker_font_size, color: @font_color)
|
|
128
|
+
if RUBY_PLATFORM == 'java'
|
|
129
|
+
text_renderer.render(1, 1, @graph_left - LABEL_MARGIN * 2.0, y_offset, Magick::EastGravity)
|
|
130
|
+
else
|
|
131
|
+
text_renderer.render(1, 1, -@graph_left + LABEL_MARGIN * 2.0, y_offset, Magick::EastGravity)
|
|
132
|
+
end
|
|
135
133
|
end
|
|
136
134
|
end
|
|
137
135
|
|
|
136
|
+
def calculate_spacing
|
|
137
|
+
@scale * @group_spacing * (column_count - 1)
|
|
138
|
+
end
|
|
138
139
|
end
|
|
@@ -1,97 +1,99 @@
|
|
|
1
|
-
|
|
2
|
-
require File.dirname(__FILE__) + '/side_bar'
|
|
3
|
-
require File.dirname(__FILE__) + '/stacked_mixin'
|
|
1
|
+
# frozen_string_literal: true
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
require 'gruff/side_bar'
|
|
4
|
+
require 'gruff/helper/stacked_mixin'
|
|
5
|
+
|
|
6
|
+
# New gruff graph type added to enable sideways stacking bar charts
|
|
7
7
|
# (basically looks like a x/y flip of a standard stacking bar chart)
|
|
8
8
|
#
|
|
9
|
-
# alun.eyre@googlemail.com
|
|
10
|
-
|
|
9
|
+
# alun.eyre@googlemail.com
|
|
11
10
|
class Gruff::SideStackedBar < Gruff::SideBar
|
|
12
11
|
include StackedMixin
|
|
12
|
+
include BarValueLabelMixin
|
|
13
13
|
|
|
14
|
-
# Spacing factor applied between bars
|
|
14
|
+
# Spacing factor applied between bars.
|
|
15
15
|
attr_accessor :bar_spacing
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
# Number of pixels between bar segments.
|
|
18
|
+
attr_accessor :segment_spacing
|
|
19
|
+
|
|
20
|
+
# Set the number output format for labels using sprintf.
|
|
21
|
+
# Default is +"%.2f"+.
|
|
22
|
+
attr_accessor :label_formatting
|
|
23
|
+
|
|
24
|
+
# Output the values for the bars on a bar graph.
|
|
25
|
+
# Default is +false+.
|
|
26
|
+
attr_accessor :show_labels_for_bar_values
|
|
27
|
+
|
|
28
|
+
def initialize_ivars
|
|
29
|
+
super
|
|
30
|
+
@label_formatting = nil
|
|
31
|
+
@show_labels_for_bar_values = false
|
|
32
|
+
end
|
|
33
|
+
private :initialize_ivars
|
|
34
|
+
|
|
17
35
|
def draw
|
|
18
36
|
@has_left_labels = true
|
|
19
37
|
get_maximum_by_stack
|
|
20
38
|
super
|
|
21
39
|
end
|
|
22
40
|
|
|
23
|
-
|
|
41
|
+
private
|
|
24
42
|
|
|
25
43
|
def draw_bars
|
|
26
44
|
# Setup spacing.
|
|
27
45
|
#
|
|
28
46
|
# Columns sit stacked.
|
|
29
47
|
@bar_spacing ||= 0.9
|
|
48
|
+
@segment_spacing ||= 2.0
|
|
30
49
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
left_x = length[point_index] #+ 1
|
|
54
|
-
left_y = @graph_top + (@bar_width * point_index) + padding
|
|
55
|
-
right_x = left_x + difference
|
|
56
|
-
right_y = left_y + @bar_width * @bar_spacing
|
|
57
|
-
length[point_index] += difference
|
|
50
|
+
bar_width = @graph_height / column_count.to_f
|
|
51
|
+
height = Array.new(column_count, 0)
|
|
52
|
+
length = Array.new(column_count, @graph_left)
|
|
53
|
+
padding = (bar_width * (1 - @bar_spacing)) / 2
|
|
54
|
+
bar_value_label = BarValueLabel.new(column_count, bar_width)
|
|
55
|
+
|
|
56
|
+
store.norm_data.each_with_index do |data_row, row_index|
|
|
57
|
+
data_row.points.each_with_index do |data_point, point_index|
|
|
58
|
+
## using the original calcs from the stacked bar chart to get the difference between
|
|
59
|
+
## part of the bart chart we wish to stack.
|
|
60
|
+
temp1 = @graph_left + (@graph_width -
|
|
61
|
+
data_point * @graph_width -
|
|
62
|
+
height[point_index]) + 1
|
|
63
|
+
temp2 = @graph_left + @graph_width - height[point_index] - 1
|
|
64
|
+
difference = temp2 - temp1
|
|
65
|
+
|
|
66
|
+
left_x = length[point_index]
|
|
67
|
+
left_y = @graph_top + (bar_width * point_index) + padding
|
|
68
|
+
right_x = left_x + difference - @segment_spacing
|
|
69
|
+
right_y = left_y + bar_width * @bar_spacing
|
|
70
|
+
length[point_index] += difference
|
|
58
71
|
height[point_index] += (data_point * @graph_width - 2)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
end
|
|
64
|
-
|
|
72
|
+
|
|
73
|
+
bar_value_label.coordinates[point_index] = [left_x, left_y, right_x, right_y]
|
|
74
|
+
bar_value_label.values[point_index] += store.data[row_index].points[point_index]
|
|
75
|
+
|
|
65
76
|
# if a data point is 0 it can result in weird really thing lines
|
|
66
77
|
# that shouldn't even be there being drawn on top of the existing
|
|
67
78
|
# bar - this is bad
|
|
68
79
|
if data_point != 0
|
|
69
|
-
|
|
80
|
+
rect_renderer = Gruff::Renderer::Rectangle.new(color: data_row.color)
|
|
81
|
+
rect_renderer.render(left_x, left_y, right_x, right_y)
|
|
70
82
|
# Calculate center based on bar_width and current row
|
|
71
83
|
end
|
|
72
84
|
# we still need to draw the labels
|
|
73
85
|
# Calculate center based on bar_width and current row
|
|
74
|
-
label_center =
|
|
86
|
+
label_center = left_y + bar_width / 2
|
|
75
87
|
draw_label(label_center, point_index)
|
|
76
88
|
end
|
|
77
|
-
|
|
78
89
|
end
|
|
90
|
+
|
|
79
91
|
if @show_labels_for_bar_values
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
draw_value_label(data[:right_x]+40, (@graph_top + (((i+1) * @bar_width) - (@bar_width / 2)))-12, val.commify, true)
|
|
92
|
+
bar_value_label.prepare_sidebar_rendering(@label_formatting) do |x, y, text|
|
|
93
|
+
draw_value_label(x, y, text, true)
|
|
83
94
|
end
|
|
84
95
|
end
|
|
85
|
-
|
|
86
|
-
@d.draw(@base_image)
|
|
87
|
-
end
|
|
88
96
|
|
|
89
|
-
|
|
90
|
-
max(data_point, index) > @maximum_value
|
|
97
|
+
Gruff::Renderer.finish
|
|
91
98
|
end
|
|
92
|
-
|
|
93
|
-
def max(data_point, index)
|
|
94
|
-
@data.inject(0) {|sum, item| sum + item[DATA_VALUES_INDEX][index]}
|
|
95
|
-
end
|
|
96
|
-
|
|
97
99
|
end
|