gruff 0.3.6 → 0.3.7
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.
- data/.gitignore +6 -0
- data/.rvmrc +5 -0
- data/.travis.yml +8 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +20 -0
- data/LICENSE.txt +22 -0
- data/README.md +49 -0
- data/README.txt +3 -0
- data/Rakefile +17 -34
- data/gruff.gemspec +33 -0
- data/lib/gruff.rb +3 -0
- data/lib/gruff/base.rb +17 -14
- data/lib/gruff/line.rb +104 -11
- data/lib/gruff/mini/legend.rb +50 -23
- data/lib/gruff/pie.rb +8 -6
- data/lib/gruff/scatter.rb +268 -0
- data/lib/gruff/scene.rb +1 -1
- data/lib/gruff/side_bar.rb +13 -7
- data/lib/gruff/side_stacked_bar.rb +9 -6
- data/lib/gruff/stacked_bar.rb +3 -0
- data/lib/gruff/version.rb +3 -0
- data/test/gruff_test_case.rb +2 -0
- data/test/test_bar.rb +16 -1
- data/test/test_line.rb +102 -64
- data/test/test_mini_bar.rb +1 -1
- data/test/test_mini_pie.rb +7 -2
- data/test/test_mini_side_bar.rb +1 -2
- data/test/test_scatter.rb +233 -0
- data/test/test_scene.rb +1 -1
- data/test/test_side_bar.rb +31 -0
- metadata +41 -27
data/.gitignore
ADDED
data/.rvmrc
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Uwe Kubosch
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Gruff Graphs
|
2
|
+
|
3
|
+
A library for making beautiful graphs.
|
4
|
+
|
5
|
+
## WARNING
|
6
|
+
|
7
|
+
This is beta-quality software. It works well according to our tests,
|
8
|
+
but the API may change and other features will be added.
|
9
|
+
We are working to make Gruff production quality software.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'gruff'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install gruff
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
See the test suite in test/line_test.rb for examples.
|
28
|
+
|
29
|
+
## Samples
|
30
|
+
|
31
|
+
http://nubyonrails.com/pages/gruff
|
32
|
+
|
33
|
+
## Documentation
|
34
|
+
|
35
|
+
http://gruff.rubyforge.org
|
36
|
+
|
37
|
+
## Contributing
|
38
|
+
|
39
|
+
== Source
|
40
|
+
|
41
|
+
The source for this project is now kept at GitHub:
|
42
|
+
|
43
|
+
http://github.com/topfunky/gruff/tree/master
|
44
|
+
|
45
|
+
1. Fork it
|
46
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
47
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
48
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
49
|
+
5. Create new Pull Request
|
data/README.txt
CHANGED
data/Rakefile
CHANGED
@@ -1,55 +1,38 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
require 'rake/clean'
|
3
6
|
$:.unshift(File.dirname(__FILE__) + "/lib")
|
4
|
-
require 'gruff'
|
5
7
|
|
6
|
-
|
7
|
-
p.name = "gruff"
|
8
|
-
p.author = "Geoffrey Grosenbach"
|
9
|
-
p.description = "Beautiful graphs for one or multiple datasets. Can be used on websites or in documents."
|
10
|
-
p.email = 'boss@topfunky.com'
|
11
|
-
p.summary = "Beautiful graphs for one or multiple datasets."
|
12
|
-
p.url = "http://nubyonrails.com/pages/gruff"
|
13
|
-
p.clean_globs = ['test/output/*.png']
|
14
|
-
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
15
|
-
p.remote_rdoc_dir = '' # Release to root
|
16
|
-
end
|
8
|
+
CLEAN << ['pkg', 'test/output/*']
|
17
9
|
|
18
|
-
desc "
|
19
|
-
task :
|
20
|
-
# An error message will be displayed if files are missing
|
21
|
-
if system %(ruby -e "require 'pkg/gruff-#{Gruff::VERSION}/lib/gruff'")
|
22
|
-
puts "\nThe library files are present"
|
23
|
-
end
|
24
|
-
raise "\n*** Gruff::Base::DEBUG must be set to false for releases ***\n\n" if Gruff::Base::DEBUG
|
25
|
-
end
|
10
|
+
desc "Run tests"
|
11
|
+
task :default => :test
|
26
12
|
|
27
|
-
|
13
|
+
Rake::TestTask.new do |t|
|
14
|
+
t.libs << 'test'
|
15
|
+
end
|
28
16
|
|
29
17
|
namespace :test do
|
30
|
-
|
31
18
|
desc "Run mini tests"
|
32
19
|
task :mini => :clean do
|
33
20
|
Dir['test/test_mini*'].each do |file|
|
34
21
|
system "ruby #{file}"
|
35
22
|
end
|
36
|
-
|
37
23
|
end
|
38
|
-
|
39
24
|
end
|
40
25
|
|
41
26
|
##
|
42
27
|
# Catch unmatched tasks and run them as a unit test.
|
43
|
-
#
|
44
28
|
# Makes it possible to do
|
45
29
|
#
|
46
30
|
# rake pie
|
47
31
|
#
|
48
32
|
# To run the +test/test_pie+ and +test/test_mini_pie+ files.
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
33
|
+
#rule '' do |t|
|
34
|
+
# # Rake::Task["clean"].invoke
|
35
|
+
# Dir["test/test_*#{t.name}*.rb"].each do |filename|
|
36
|
+
# system "ruby #{filename}"
|
37
|
+
# end
|
38
|
+
#end
|
data/gruff.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'gruff/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{gruff}
|
8
|
+
s.version = Gruff::VERSION
|
9
|
+
|
10
|
+
# s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ['Geoffrey Grosenbach', 'Uwe Kubosch']
|
12
|
+
# s.date = Date.today.to_s
|
13
|
+
s.description = %q{Beautiful graphs for one or multiple datasets. Can be used on websites or in documents.}
|
14
|
+
s.email = %q{boss@topfunky.com}
|
15
|
+
# s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
|
16
|
+
# s.files = ["History.txt", "MIT-LICENSE", "Manifest.txt", "README.txt", "Rakefile", "assets/bubble.png", "assets/city_scene/background/0000.png", "assets/city_scene/background/0600.png", "assets/city_scene/background/2000.png", "assets/city_scene/clouds/cloudy.png", "assets/city_scene/clouds/partly_cloudy.png", "assets/city_scene/clouds/stormy.png", "assets/city_scene/grass/default.png", "assets/city_scene/haze/true.png", "assets/city_scene/number_sample/1.png", "assets/city_scene/number_sample/2.png", "assets/city_scene/number_sample/default.png", "assets/city_scene/sky/0000.png", "assets/city_scene/sky/0200.png", "assets/city_scene/sky/0400.png", "assets/city_scene/sky/0600.png", "assets/city_scene/sky/0800.png", "assets/city_scene/sky/1000.png", "assets/city_scene/sky/1200.png", "assets/city_scene/sky/1400.png", "assets/city_scene/sky/1500.png", "assets/city_scene/sky/1700.png", "assets/city_scene/sky/2000.png", "assets/pc306715.jpg", "assets/plastik/blue.png", "assets/plastik/green.png", "assets/plastik/red.png", "init.rb", "lib/gruff.rb", "lib/gruff/accumulator_bar.rb", "lib/gruff/area.rb", "lib/gruff/bar.rb", "lib/gruff/bar_conversion.rb", "lib/gruff/base.rb", "lib/gruff/bullet.rb", "lib/gruff/deprecated.rb", "lib/gruff/dot.rb", "lib/gruff/line.rb", "lib/gruff/mini/bar.rb", "lib/gruff/mini/legend.rb", "lib/gruff/mini/pie.rb", "lib/gruff/mini/side_bar.rb", "lib/gruff/net.rb", "lib/gruff/photo_bar.rb", "lib/gruff/pie.rb", "lib/gruff/scene.rb", "lib/gruff/side_bar.rb", "lib/gruff/side_stacked_bar.rb", "lib/gruff/spider.rb", "lib/gruff/stacked_area.rb", "lib/gruff/stacked_bar.rb", "lib/gruff/stacked_mixin.rb", "rails_generators/gruff/gruff_generator.rb", "rails_generators/gruff/templates/controller.rb", "rails_generators/gruff/templates/functional_test.rb", "test/gruff_test_case.rb", "test/test_accumulator_bar.rb", "test/test_area.rb", "test/test_bar.rb", "test/test_base.rb", "test/test_bullet.rb", "test/test_dot.rb", "test/test_legend.rb", "test/test_line.rb", "test/test_mini_bar.rb", "test/test_mini_pie.rb", "test/test_mini_side_bar.rb", "test/test_net.rb", "test/test_photo.rb", "test/test_pie.rb", "test/test_scene.rb", "test/test_side_bar.rb", "test/test_sidestacked_bar.rb", "test/test_spider.rb", "test/test_stacked_area.rb", "test/test_stacked_bar.rb"]
|
17
|
+
s.files = `git ls-files`.split($/)
|
18
|
+
# s.has_rdoc = true
|
19
|
+
s.homepage = %q{http://nubyonrails.com/pages/gruff}
|
20
|
+
# s.rdoc_options = ["--main", "README.txt"]
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
# s.rubyforge_project = %q{gruff}
|
23
|
+
# s.rubygems_version = %q{1.3.1}
|
24
|
+
s.summary = %q{Beautiful graphs for one or multiple datasets.}
|
25
|
+
# s.test_files = ["test/test_accumulator_bar.rb", "test/test_area.rb", "test/test_bar.rb", "test/test_base.rb", "test/test_bullet.rb", "test/test_dot.rb", "test/test_legend.rb", "test/test_line.rb", "test/test_mini_bar.rb", "test/test_mini_pie.rb", "test/test_mini_side_bar.rb", "test/test_net.rb", "test/test_photo.rb", "test/test_pie.rb", "test/test_scene.rb", "test/test_side_bar.rb", "test/test_sidestacked_bar.rb", "test/test_spider.rb", "test/test_stacked_area.rb", "test/test_stacked_bar.rb"]
|
26
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
27
|
+
|
28
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
29
|
+
|
30
|
+
# s.specification_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
31
|
+
# s.add_development_dependency(%q<hoe>, [">= 1.8.2"])
|
32
|
+
# s.add_dependency(%q<rmagick>, [">= 2.12.2"])
|
33
|
+
end
|
data/lib/gruff.rb
CHANGED
data/lib/gruff/base.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'RMagick'
|
3
|
+
require 'bigdecimal'
|
3
4
|
|
4
5
|
require File.dirname(__FILE__) + '/deprecated'
|
5
6
|
|
@@ -18,10 +19,6 @@ require File.dirname(__FILE__) + '/deprecated'
|
|
18
19
|
# See Gruff::Base#theme= for setting themes.
|
19
20
|
|
20
21
|
module Gruff
|
21
|
-
|
22
|
-
# This is the version of Gruff you are using.
|
23
|
-
VERSION = '0.3.6'
|
24
|
-
|
25
22
|
class Base
|
26
23
|
|
27
24
|
include Magick
|
@@ -34,6 +31,7 @@ module Gruff
|
|
34
31
|
DATA_LABEL_INDEX = 0
|
35
32
|
DATA_VALUES_INDEX = 1
|
36
33
|
DATA_COLOR_INDEX = 2
|
34
|
+
DATA_VALUES_X_INDEX = 3
|
37
35
|
|
38
36
|
# Space around text elements. Mostly used for vertical spacing
|
39
37
|
LEGEND_MARGIN = TITLE_MARGIN = 20.0
|
@@ -41,7 +39,7 @@ module Gruff
|
|
41
39
|
DEFAULT_MARGIN = 20.0
|
42
40
|
|
43
41
|
DEFAULT_TARGET_WIDTH = 800
|
44
|
-
|
42
|
+
|
45
43
|
THOUSAND_SEPARATOR = ','
|
46
44
|
|
47
45
|
# Blank space above the graph
|
@@ -55,10 +53,10 @@ module Gruff
|
|
55
53
|
|
56
54
|
# Blank space to the left of the graph
|
57
55
|
attr_accessor :left_margin
|
58
|
-
|
56
|
+
|
59
57
|
# Blank space below the title
|
60
58
|
attr_accessor :title_margin
|
61
|
-
|
59
|
+
|
62
60
|
# Blank space below the legend
|
63
61
|
attr_accessor :legend_margin
|
64
62
|
|
@@ -223,7 +221,7 @@ module Gruff
|
|
223
221
|
@marker_font_size = 21.0
|
224
222
|
@legend_font_size = 20.0
|
225
223
|
@title_font_size = 36.0
|
226
|
-
|
224
|
+
|
227
225
|
@top_margin = @bottom_margin = @left_margin = @right_margin = DEFAULT_MARGIN
|
228
226
|
@legend_margin = LEGEND_MARGIN
|
229
227
|
@title_margin = TITLE_MARGIN
|
@@ -698,7 +696,8 @@ module Gruff
|
|
698
696
|
@d = @d.fill(@marker_color)
|
699
697
|
@d = @d.line(@graph_left, y, @graph_right, y)
|
700
698
|
|
701
|
-
marker_label = index * @increment +
|
699
|
+
marker_label = BigDecimal(index.to_s) * BigDecimal(@increment.to_s) +
|
700
|
+
BigDecimal(@minimum_value.to_s)
|
702
701
|
|
703
702
|
unless @hide_line_numbers
|
704
703
|
@d.fill = @font_color
|
@@ -977,9 +976,10 @@ module Gruff
|
|
977
976
|
data_point
|
978
977
|
end
|
979
978
|
|
980
|
-
def significant(
|
981
|
-
return 1.0 if
|
982
|
-
|
979
|
+
def significant(i) # :nodoc:
|
980
|
+
return 1.0 if i == 0 # Keep from going into infinite loop
|
981
|
+
inc = BigDecimal(i.to_s)
|
982
|
+
factor = BigDecimal('1.0')
|
983
983
|
while (inc < 10)
|
984
984
|
inc *= 10
|
985
985
|
factor /= 10
|
@@ -1063,7 +1063,7 @@ module Gruff
|
|
1063
1063
|
# Return a formatted string representing a number value that should be
|
1064
1064
|
# printed as a label.
|
1065
1065
|
def label(value)
|
1066
|
-
label = if (@spread.to_f % @marker_count.to_f == 0) || !@y_axis_increment.nil?
|
1066
|
+
label = if (@spread.to_f % (@marker_count.to_f==0 ? 1 : @marker_count.to_f) == 0) || !@y_axis_increment.nil?
|
1067
1067
|
value.to_i.to_s
|
1068
1068
|
elsif @spread > 10.0
|
1069
1069
|
sprintf("%0i", value)
|
@@ -1072,7 +1072,7 @@ module Gruff
|
|
1072
1072
|
else
|
1073
1073
|
value.to_s
|
1074
1074
|
end
|
1075
|
-
|
1075
|
+
|
1076
1076
|
parts = label.split('.')
|
1077
1077
|
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{THOUSAND_SEPARATOR}")
|
1078
1078
|
parts.join('.')
|
@@ -1085,6 +1085,7 @@ module Gruff
|
|
1085
1085
|
# handle.
|
1086
1086
|
def calculate_caps_height(font_size)
|
1087
1087
|
@d.pointsize = font_size
|
1088
|
+
@d.font = @font if @font
|
1088
1089
|
@d.get_type_metrics(@base_image, 'X').height
|
1089
1090
|
end
|
1090
1091
|
|
@@ -1093,7 +1094,9 @@ module Gruff
|
|
1093
1094
|
# Not scaled since it deals with dimensions that the regular
|
1094
1095
|
# scaling will handle.
|
1095
1096
|
def calculate_width(font_size, text)
|
1097
|
+
return 0 if text.nil?
|
1096
1098
|
@d.pointsize = font_size
|
1099
|
+
@d.font = @font if @font
|
1097
1100
|
@d.get_type_metrics(@base_image, text.to_s).width
|
1098
1101
|
end
|
1099
1102
|
|
data/lib/gruff/line.rb
CHANGED
@@ -16,7 +16,7 @@ class Gruff::Line < Gruff::Base
|
|
16
16
|
|
17
17
|
# Draw a dashed line at the given value
|
18
18
|
attr_accessor :baseline_value
|
19
|
-
|
19
|
+
|
20
20
|
# Color of the baseline
|
21
21
|
attr_accessor :baseline_color
|
22
22
|
|
@@ -26,6 +26,10 @@ class Gruff::Line < Gruff::Base
|
|
26
26
|
|
27
27
|
# Hide parts of the graph to fit more datapoints, or for a different appearance.
|
28
28
|
attr_accessor :hide_dots, :hide_lines
|
29
|
+
|
30
|
+
#accessors for support of xy data
|
31
|
+
attr_accessor :minimum_x_value
|
32
|
+
attr_accessor :maximum_x_value
|
29
33
|
|
30
34
|
# Call with target pixel width of graph (800, 400, 300), and/or 'false' to omit lines (points only).
|
31
35
|
#
|
@@ -34,7 +38,7 @@ class Gruff::Line < Gruff::Base
|
|
34
38
|
# g = Gruff::Line.new(400, false) # 400px wide, no lines (for backwards compatibility)
|
35
39
|
#
|
36
40
|
# g = Gruff::Line.new(false) # Defaults to 800px wide, no lines (for backwards compatibility)
|
37
|
-
#
|
41
|
+
#
|
38
42
|
# The preferred way is to call hide_dots or hide_lines instead.
|
39
43
|
def initialize(*args)
|
40
44
|
raise ArgumentError, "Wrong number of arguments" if args.length > 2
|
@@ -43,20 +47,95 @@ class Gruff::Line < Gruff::Base
|
|
43
47
|
else
|
44
48
|
super args.shift
|
45
49
|
end
|
46
|
-
|
50
|
+
|
47
51
|
@hide_dots = @hide_lines = false
|
48
52
|
@baseline_color = 'red'
|
49
53
|
@baseline_value = nil
|
54
|
+
@maximum_x_value = nil
|
55
|
+
@minimum_x_value = nil
|
56
|
+
end
|
57
|
+
|
58
|
+
# This method allows one to plot a dataset with both X and Y data.
|
59
|
+
#
|
60
|
+
# Parameters are as follows:
|
61
|
+
# name: string, the title of the dataset
|
62
|
+
# x_data_points: an array containing the x data points for the graph
|
63
|
+
# y_data_points: an array containing the y data points for the graph
|
64
|
+
# color: hex number indicating the line color as an RGB triplet
|
65
|
+
#
|
66
|
+
# Notes:
|
67
|
+
# -if (x_data_points.length != y_data_points.length) an error is
|
68
|
+
# returned.
|
69
|
+
# -if the color argument is nil, the next color from the default theme will
|
70
|
+
# be used.
|
71
|
+
# -if you want to use a preset theme, you must set it before calling
|
72
|
+
# dataxy().
|
73
|
+
#
|
74
|
+
# Example:
|
75
|
+
# g = Gruff::Line.new
|
76
|
+
# g.title = "X/Y Dataset"
|
77
|
+
# g.dataxy("Apples", [1,3,4,5,6,10], [1, 2, 3, 4, 4, 3])
|
78
|
+
# g.dataxy("Bapples", [1,3,4,5,7,9], [1, 1, 2, 2, 3, 3])
|
79
|
+
# #you can still use the old data method too if you want:
|
80
|
+
# g.data("Capples", [1, 1, 2, 2, 3, 3])
|
81
|
+
# #labels will be drawn at the x locations of the 1st dataset that you
|
82
|
+
# #passed in. In this example the lables are drawn at x locations 1,4,6
|
83
|
+
# g.labels = {0 => '2003', 2 => '2004', 4 => '2005'} #labels
|
84
|
+
|
85
|
+
def dataxy(name, x_data_points=[], y_data_points=[], color=nil)
|
86
|
+
raise ArgumentError, "x_data_points is nil!" if x_data_points.length == 0
|
87
|
+
|
88
|
+
if x_data_points.all?{|p| p.size == 2}
|
89
|
+
x_data_points, y_data_points = x_data_points.map{|p| p[0]}, x_data_points.map{|p| p[1]}
|
90
|
+
end
|
91
|
+
|
92
|
+
raise ArgumentError, "x_data_points.length != y_data_points.length!" if x_data_points.length != y_data_points.length
|
93
|
+
|
94
|
+
#call the existing data routine for the y data.
|
95
|
+
self.data(name, y_data_points, color)
|
96
|
+
|
97
|
+
x_data_points = Array(x_data_points) # make sure it's an array
|
98
|
+
#append the x data to the last entry that was just added in the @data member
|
99
|
+
lastElem = @data.length()-1
|
100
|
+
@data[lastElem][DATA_VALUES_X_INDEX] = x_data_points
|
101
|
+
|
102
|
+
# Update the global min/max values for the x data
|
103
|
+
x_data_points.each_with_index do |x_data_point, index|
|
104
|
+
next if x_data_point.nil?
|
105
|
+
|
106
|
+
# Setup max/min so spread starts at the low end of the data points
|
107
|
+
if @maximum_x_value.nil? && @minimum_x_value.nil?
|
108
|
+
@maximum_x_value = @minimum_x_value = x_data_point
|
109
|
+
end
|
110
|
+
|
111
|
+
@maximum_x_value = (x_data_point > @maximum_x_value) ?
|
112
|
+
x_data_point : @maximum_x_value
|
113
|
+
@minimum_x_value = (x_data_point < @minimum_x_value) ?
|
114
|
+
x_data_point : @minimum_x_value
|
115
|
+
end
|
116
|
+
|
50
117
|
end
|
51
118
|
|
52
119
|
def draw
|
53
120
|
super
|
54
121
|
|
55
122
|
return unless @has_data
|
56
|
-
|
57
|
-
# Check to see if more than one datapoint was given. NaN can result otherwise.
|
123
|
+
|
124
|
+
# Check to see if more than one datapoint was given. NaN can result otherwise.
|
58
125
|
@x_increment = (@column_count > 1) ? (@graph_width / (@column_count - 1).to_f) : @graph_width
|
59
126
|
|
127
|
+
#normalize the x data if it is specified
|
128
|
+
@data.each_with_index do |data_row, index|
|
129
|
+
norm_x_data_points = []
|
130
|
+
if (data_row[DATA_VALUES_X_INDEX] != nil)
|
131
|
+
data_row[DATA_VALUES_X_INDEX].each do |x_data_point|
|
132
|
+
norm_x_data_points << ( (x_data_point.to_f - @minimum_x_value.to_f ) /
|
133
|
+
(@maximum_x_value.to_f - @minimum_x_value.to_f) )
|
134
|
+
end
|
135
|
+
@norm_data[index] << norm_x_data_points
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
60
139
|
if (defined?(@norm_baseline)) then
|
61
140
|
level = @graph_top + (@graph_height - @norm_baseline * @graph_height)
|
62
141
|
@d = @d.push
|
@@ -68,15 +147,22 @@ class Gruff::Line < Gruff::Base
|
|
68
147
|
@d = @d.pop
|
69
148
|
end
|
70
149
|
|
71
|
-
@norm_data.
|
150
|
+
@norm_data.each_with_index do |data_row, dr_index|
|
72
151
|
prev_x = prev_y = nil
|
73
152
|
|
74
153
|
@one_point = contains_one_point_only?(data_row)
|
75
154
|
|
76
155
|
data_row[DATA_VALUES_INDEX].each_with_index do |data_point, index|
|
77
|
-
new_x = @graph_left + (@x_increment * index)
|
78
156
|
next if data_point.nil?
|
79
157
|
|
158
|
+
x_data = data_row[DATA_VALUES_X_INDEX]
|
159
|
+
if (x_data == nil)
|
160
|
+
#use the old method: equally spaced points along the x-axis
|
161
|
+
new_x = @graph_left + (@x_increment * index)
|
162
|
+
else
|
163
|
+
new_x = getXCoord(x_data[index], @graph_width, @graph_left)
|
164
|
+
end
|
165
|
+
|
80
166
|
draw_label(new_x, index)
|
81
167
|
|
82
168
|
new_y = @graph_top + (@graph_height - data_point * @graph_height)
|
@@ -92,7 +178,7 @@ class Gruff::Line < Gruff::Base
|
|
92
178
|
circle_radius = dot_radius ||
|
93
179
|
clip_value_if_greater_than(@columns / (@norm_data.first[DATA_VALUES_INDEX].size * 2.5), 5.0)
|
94
180
|
|
95
|
-
if !@hide_lines and !prev_x.nil? and !prev_y.nil? then
|
181
|
+
if !@hide_lines and !prev_x.nil? and !prev_y.nil? then
|
96
182
|
@d = @d.line(prev_x, prev_y, new_x, new_y)
|
97
183
|
elsif @one_point
|
98
184
|
# Show a circle if there's just one_point
|
@@ -114,6 +200,14 @@ class Gruff::Line < Gruff::Base
|
|
114
200
|
super
|
115
201
|
@norm_baseline = (@baseline_value.to_f / @maximum_value.to_f) if @baseline_value
|
116
202
|
end
|
203
|
+
|
204
|
+
def sort_norm_data
|
205
|
+
super unless @data.any?{|d| d[DATA_VALUES_X_INDEX]}
|
206
|
+
end
|
207
|
+
|
208
|
+
def getXCoord(x_data_point, width, offset)
|
209
|
+
return(x_data_point * width + offset)
|
210
|
+
end
|
117
211
|
|
118
212
|
def contains_one_point_only?(data_row)
|
119
213
|
# Spin through data to determine if there is just one_value present.
|
@@ -123,10 +217,9 @@ class Gruff::Line < Gruff::Base
|
|
123
217
|
if one_point
|
124
218
|
# more than one point, bail
|
125
219
|
return false
|
126
|
-
else
|
127
|
-
# there is at least one data point
|
128
|
-
return true
|
129
220
|
end
|
221
|
+
# there is at least one data point
|
222
|
+
one_point = true
|
130
223
|
end
|
131
224
|
end
|
132
225
|
return one_point
|