svg-graph 1.0.5 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/History.txt +18 -0
  3. data/README.markdown +90 -6
  4. data/Rakefile +26 -14
  5. data/lib/SVG/Graph/Bar.rb +2 -2
  6. data/lib/SVG/Graph/BarBase.rb +25 -24
  7. data/lib/SVG/Graph/BarHorizontal.rb +1 -1
  8. data/lib/SVG/Graph/ErrBar.rb +189 -0
  9. data/lib/SVG/Graph/Graph.rb +141 -64
  10. data/lib/SVG/Graph/Line.rb +1 -1
  11. data/lib/SVG/Graph/Pie.rb +76 -49
  12. data/lib/SVG/Graph/Plot.rb +2 -2
  13. data/lib/SVG/Graph/Schedule.rb +18 -19
  14. data/lib/SVG/Graph/TimeSeries.rb +26 -22
  15. data/lib/svggraph.rb +12 -10
  16. data/test/test_svg_graph.rb +48 -6
  17. metadata +41 -136
  18. data.tar.gz.sig +0 -2
  19. data/Manifest.txt +0 -56
  20. data/build.xml +0 -143
  21. data/dist.xml.in +0 -46
  22. data/images/bar.png +0 -0
  23. data/images/bar.svg +0 -76
  24. data/images/bar.svgz +0 -0
  25. data/images/barhorizontal.png +0 -0
  26. data/images/barhorizontal.svg +0 -76
  27. data/images/barhorizontal.svgz +0 -0
  28. data/images/line.png +0 -0
  29. data/images/line.svg +0 -80
  30. data/images/line.svgz +0 -0
  31. data/images/pie.png +0 -0
  32. data/images/pie.svg +0 -70
  33. data/images/pie.svgz +0 -0
  34. data/images/plot.png +0 -0
  35. data/images/plot.svg +0 -131
  36. data/images/plot.svgz +0 -0
  37. data/images/schedule.png +0 -0
  38. data/images/schedule.svg +0 -67
  39. data/images/timeseries.png +0 -0
  40. data/images/timeseries.svg +0 -179
  41. data/images/timeseries.svgz +0 -0
  42. data/index.xml +0 -281
  43. data/install.rb +0 -161
  44. data/screenshots.xml +0 -148
  45. data/style/common.xsl +0 -37
  46. data/style/release_html.xsl +0 -169
  47. data/style/release_txt.xsl +0 -25
  48. data/svg-graph.gemspec +0 -58
  49. data/test/data.txt +0 -4
  50. data/test/plot.rb +0 -51
  51. data/test/schedule.rb +0 -43
  52. data/test/single.rb +0 -33
  53. data/test/test.rb +0 -54
  54. data/test/test_data_point.rb +0 -67
  55. data/test/test_plot.rb +0 -282
  56. data/test/timeseries.rb +0 -58
  57. metadata.gz.sig +0 -1
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a0a6c4dcff26a2412d42bb11f392ca6292afde8d
4
+ data.tar.gz: b91765dbbf54900ffeba3f665af1b17429e72d05
5
+ SHA512:
6
+ metadata.gz: d63ea323203f76843f1ba2b07b1db9522b7619a871467064b7f06e87e9e4d55f94404a263d513c1d295e38f2377cec4beaba53549c30f4d8142a91cc6ef26550
7
+ data.tar.gz: e682a1ee1c37dfdad7f95a52942334ba3f0eee7a001779cf0fd696745f3a7cdb5a54f265312351365992a7602d984e1b003297e1987d4cae170b8c0c096f8032
data/History.txt CHANGED
@@ -1,3 +1,21 @@
1
+ TODO
2
+ * fix axis titles positioning for timeseries and schedule graphs
3
+
4
+ === 2.0.0 / 2016-08-09
5
+ * dropped support for ruby 1.8.7 [lumean]
6
+ * Merge ErrBar graph from https://github.com/mondhs/svg-graph
7
+ * Merge number formatting to have more readable floats from https://github.com/mondhs/svg-graph
8
+ * fix warnings [lumean]
9
+ * make TimeSeries and Schedule work with ruby >2.0 and the Date/DateTime stdlib [lumean]
10
+ * dropped support for 'parsedate', instead TimeSeries and Schedule now accept a template to parse the date or time representation [lumean]
11
+ * all ruby files in the test directory now run on ruby >2.0 and write output to files [lumean]
12
+ * changed from autoload to static loading due to issues with unit-testing when the gem is not installed [lumean]
13
+ * begin transition to minitest for tests [lumean]
14
+ * merged fix for 100% pie graphs from https://github.com/endersstocker/svg-graph
15
+ * fix wrong margins for labels after merge of number formatting [lumean]
16
+ * Add new option for locations for the axis titles (at the end of the axis instead of below / left from it) [lumean]
17
+ * improved x-axis label location when x-axis marks are vertical and long [lumean]
18
+
1
19
  === 1.0.5 / 2011-09-03
2
20
  * enabled all svg_graph tests[liehann]
3
21
 
data/README.markdown CHANGED
@@ -1,14 +1,98 @@
1
- SVG::Graph19
1
+ SVG::Graph
2
2
  ============
3
3
 
4
4
  Description
5
5
  -----------
6
- This is a minor revision of the [SVG::Graph library](http://www.germane-software.com/software/SVG/SVG::Graph/) by Sean Russell with few minor touch-ups to make it run on Ruby 1.9.x and to have it [gem-installable](http://gemcutter.org/gems/svg-graph19).
6
+ This is an effort to revive the [SVG::Graph library](http://www.germane-software.com/software/SVG/SVG::Graph/) by Sean Russell. I'd also like to thank Claudio Bustos for giving me permissions to continue publishing the gem under it's original name: [svg-graph](https://rubygems.org/gems/svg-graph)
7
7
 
8
- Warning
9
- -------
10
- I'm not sure that all the parts of the original SVG library work as expected under 1.9.x too. Please notify me (via github messages or on the Issues section) if you find any bug.
8
+ [Changelog](../master/History.txt)
9
+
10
+ I'm maintaing in my free time, so I can't promise on any deadlines. Please notify me (via github messages or on the Issues section) if you find any bug.
11
+
12
+ Contribute
13
+ -----
14
+ Pull requests are very welcome :-)
11
15
 
12
16
  Usage
13
17
  -----
14
- Yet to be written. Look at the original [SVG::Graph web page](http://www.germane-software.com/software/SVG/SVG::Graph/) for the moment (I'm not introducing new methods nor changing APIs, for the moment).
18
+
19
+ For a complete list of configuration options please have a look at the source - most important [Graph.rb](../master/lib/SVG/Graph/Graph.rb), also checkout the subclasses (Pie, Bar, etc.) as they might provide additional options.
20
+
21
+ You can require everything at once
22
+ ```ruby
23
+ require 'svggraph'
24
+ ```
25
+ or only the individual parts you need
26
+ ```ruby
27
+ require 'SVG/Graph/Bar'
28
+ require 'SVG/Graph/Line'
29
+ ...
30
+ ```
31
+
32
+ In the following some examples to get you up to speed.
33
+
34
+ ### Bar
35
+ ```ruby
36
+ require 'SVG/Graph/Bar'
37
+
38
+ x_axis = ['1-10', '10-30', '30-50', '50-70', 'older']
39
+
40
+ options = {
41
+ :width => 640,
42
+ :height => 300,
43
+ :stack => :side, # the stack option is valid for Bar graphs only
44
+ :fields => x_axis,
45
+ :graph_title => "kg per head and year chocolate consumption",
46
+ :show_graph_title => true,
47
+ :show_x_title => true,
48
+ :x_title => 'Age in years',
49
+ :show_y_title => true,
50
+ :y_title => 'kg/year',
51
+ :y_title_location => :end,
52
+ :no_css => true
53
+ }
54
+
55
+ male_data = [2, 4, 6, 4, 2]
56
+ female_data = [1, 5, 4, 5, 2.7]
57
+
58
+ g = SVG::Graph::Bar.new(options)
59
+
60
+ g.add_data( {
61
+ :data => female_data,
62
+ :title => "Female"
63
+ })
64
+ g.add_data( {
65
+ :data => male_data,
66
+ :title => "Male"
67
+ })
68
+
69
+ # graph.burn # this returns a full valid xml document containing the graph
70
+ # graph.burn_svg_only # this only returns the <svg>...</svg> node
71
+ File.open('bar.svg', 'w') {|f| f.write(g.burn_svg_only)}
72
+ ```
73
+ ![example bar graph](https://cdn.rawgit.com/lumean/svg-graph2/master/examples/bar.svg)
74
+
75
+ ### BarHorizontal
76
+
77
+ ### ErrBar
78
+
79
+ ### Line
80
+
81
+ ### Pie
82
+
83
+ ### Plot
84
+
85
+ ### Schedule
86
+
87
+ ### TimeSeries
88
+
89
+
90
+ Also have a look at the original [SVG::Graph web page](http://www.germane-software.com/software/SVG/SVG::Graph/), but note that this repository has already added some additional functionality, not available with the original.
91
+
92
+ Build
93
+ -----
94
+
95
+ * Build gem:
96
+ * gem build svg-graph.gemspec
97
+ * Install:
98
+ * gem install svg-graph-\<version>.gem
data/Rakefile CHANGED
@@ -1,19 +1,31 @@
1
1
  # -*- ruby -*-
2
2
  # -*- coding: utf-8 -*-
3
- $:.unshift(File.dirname(__FILE__)+"/lib/")
4
3
 
5
- require 'rubygems'
6
- require 'hoe'
4
+ # TODO
5
+ #
6
+ #require 'rubygems'
7
+ #require 'hoe'
8
+ #
9
+ #Hoe.plugin :git
10
+ #
11
+ #require_relative 'lib/svggraph'
12
+ #
13
+ #Hoe.spec 'svg-graph' do
14
+ # self.version=SVG::Graph::VERSION
15
+ # self.developer('Sean Russell', 'ser_AT_germane-software.com')
16
+ # self.developer('Claudio Bustos', 'clbustos_AT_gmail.com')
17
+ # self.developer('Liehann Loots','liehhanl_AT_gmail.com')
18
+ # self.developer('Piergiuliano Bossi','pgbossi_AT_gmail.com')
19
+ # self.developer('Manuel Widmer','m-widmer_AT_gmx.com')
20
+ # self.rubyforge_name = 'ruby-statsample' # if different than 'svg_graph'
21
+ # self.remote_rdoc_dir = 'svg-graph'
22
+ #end
7
23
 
8
- Hoe.plugin :git
9
- $:.unshift("./lib")
10
- require 'svggraph'
11
- Hoe.spec 'svg-graph' do
12
- self.version=SVG::Graph::VERSION
13
- self.developer('Sean Russell', 'ser_AT_germane-software.com')
14
- self.developer('Claudio Bustos', 'clbustos_AT_gmail.com')
15
- self.developer("Liehann Loots","liehhanl_AT_gmail.com")
16
- self.developer("Piergiuliano Bossi","pgbossi_AT_gmail.com")
17
- self.rubyforge_name = 'ruby-statsample' # if different than 'svg_graph'
18
- self.remote_rdoc_dir = 'svg-graph'
24
+ # run all unit tests with 'rake test'
25
+ task default: %w[test]
26
+
27
+ task :test do
28
+ ruby "test/test_data_point.rb"
29
+ ruby "test/test_plot.rb"
30
+ ruby "test/test_svg_graph.rb"
19
31
  end
data/lib/SVG/Graph/Bar.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rexml/document'
2
- require 'SVG/Graph/Graph'
3
- require 'SVG/Graph/BarBase'
2
+ require_relative 'Graph'
3
+ require_relative 'BarBase'
4
4
 
5
5
  module SVG
6
6
  module Graph
@@ -1,5 +1,5 @@
1
1
  require 'rexml/document'
2
- require 'SVG/Graph/Graph'
2
+ require_relative 'Graph'
3
3
 
4
4
  module SVG
5
5
  module Graph
@@ -17,37 +17,38 @@ module SVG
17
17
  #
18
18
  class BarBase < SVG::Graph::Graph
19
19
  # Ensures that :fields are provided in the configuration.
20
- def initialize config
21
- raise "fields was not supplied or is empty" unless config[:fields] &&
22
- config[:fields].kind_of?(Array) &&
23
- config[:fields].length > 0
24
- super
25
- end
20
+ def initialize config
21
+ raise "fields was not supplied or is empty" unless config[:fields] &&
22
+ config[:fields].kind_of?(Array) &&
23
+ config[:fields].length > 0
24
+ super
25
+ end
26
26
 
27
- # In addition to the defaults set in Graph::initialize, sets
28
- # [bar_gap] true
29
- # [stack] :overlap
30
- def set_defaults
31
- init_with( :bar_gap => true, :stack => :overlap )
32
- end
27
+ # In addition to the defaults set in Graph::initialize, sets
28
+ # [bar_gap] true
29
+ # [stack] :overlap
30
+ def set_defaults
31
+ init_with( :bar_gap => true, :stack => :overlap )
32
+ end
33
33
 
34
- # Whether to have a gap between the bars or not, default
35
- # is true, set to false if you don't want gaps.
36
- attr_accessor :bar_gap
37
- # How to stack data sets. :overlap overlaps bars with
38
- # transparent colors, :top stacks bars on top of one another,
39
- # :side stacks the bars side-by-side. Defaults to :overlap.
40
- attr_accessor :stack
41
- protected
42
-
43
- def max_value
34
+ # Whether to have a gap between the bars or not, default
35
+ # is true, set to false if you don't want gaps.
36
+ attr_accessor :bar_gap
37
+ # How to stack data sets. :overlap overlaps bars with
38
+ # transparent colors, :top stacks bars on top of one another,
39
+ # :side stacks the bars side-by-side. Defaults to :overlap.
40
+ attr_accessor :stack
41
+ protected
42
+
43
+ def max_value
44
44
  @data.collect{|x| x[:data].max}.max
45
- end
45
+ end
46
46
 
47
47
  def min_value
48
48
  min = 0
49
49
  if min_scale_value.nil?
50
50
  min = @data.collect{|x| x[:data].min}.min
51
+ # by default bar should always start from zero unless there are negative values
51
52
  min = min > 0 ? 0 : min
52
53
  else
53
54
  min = min_scale_value
@@ -1,5 +1,5 @@
1
1
  require 'rexml/document'
2
- require 'SVG/Graph/BarBase'
2
+ require_relative 'BarBase'
3
3
 
4
4
  module SVG
5
5
  module Graph
@@ -0,0 +1,189 @@
1
+ require 'rexml/document'
2
+ require_relative 'Graph'
3
+ require_relative 'BarBase'
4
+
5
+ module SVG
6
+ module Graph
7
+ # === Create presentation quality SVG bar graphs easily
8
+ #
9
+ # = Synopsis
10
+ #
11
+ # require 'SVG/Graph/Bar'
12
+ #
13
+ # fields = %w(Jan Feb Mar);
14
+ # data_sales_02 = [12, 45, 21]
15
+ #
16
+ # graph = SVG::Graph::Bar.new(
17
+ # :height => 500,
18
+ # :width => 300,
19
+ # :fields => fields
20
+ # )
21
+ #
22
+ # graph.add_data(
23
+ # :data => data_sales_02,
24
+ # :title => 'Sales 2002'
25
+ # )
26
+ #
27
+ # print "Content-type: image/svg+xml\r\n\r\n"
28
+ # print graph.burn
29
+ #
30
+ # = Description
31
+ #
32
+ # This object aims to allow you to easily create high quality
33
+ # SVG[http://www.w3c.org/tr/svg bar graphs. You can either use the default
34
+ # style sheet or supply your own. Either way there are many options which
35
+ # can be configured to give you control over how the graph is generated -
36
+ # with or without a key, data elements at each point, title, subtitle etc.
37
+ #
38
+ # = Notes
39
+ #
40
+ # The default stylesheet handles upto 12 data sets, if you
41
+ # use more you must create your own stylesheet and add the
42
+ # additional settings for the extra data sets. You will know
43
+ # if you go over 12 data sets as they will have no style and
44
+ # be in black.
45
+ #
46
+ # = Examples
47
+ #
48
+ # * http://germane-software.com/repositories/public/SVG/test/test.rb
49
+ #
50
+ # = See also
51
+ #
52
+ # * SVG::Graph::Graph
53
+ # * SVG::Graph::BarHorizontal
54
+ # * SVG::Graph::Line
55
+ # * SVG::Graph::Pie
56
+ # * SVG::Graph::Plot
57
+ # * SVG::Graph::TimeSeries
58
+ class ErrBar < BarBase
59
+ include REXML
60
+
61
+ def initialize config
62
+ raise "fields was not supplied or is empty" unless config[:errorBars] &&
63
+ config[:errorBars].kind_of?(Array) &&
64
+ config[:errorBars].length > 0
65
+ super
66
+ end
67
+
68
+
69
+ # See Graph::initialize and BarBase::set_defaults
70
+ def set_defaults
71
+ super
72
+ self.top_align = self.top_font = 1
73
+ end
74
+
75
+ protected
76
+
77
+ def get_x_labels
78
+ @config[:fields]
79
+ end
80
+
81
+ def get_y_labels
82
+ maxvalue = max_value
83
+ minvalue = min_value
84
+ range = maxvalue - minvalue
85
+
86
+ top_pad = range == 0 ? 10 : range / 20.0
87
+ scale_range = (maxvalue + top_pad) - minvalue
88
+
89
+ scale_division = scale_divisions || (scale_range / 10.0)
90
+
91
+ if scale_integers
92
+ scale_division = scale_division < 1 ? 1 : scale_division.round
93
+ end
94
+
95
+ rv = []
96
+ maxvalue = maxvalue%scale_division == 0 ?
97
+ maxvalue : maxvalue + scale_division
98
+ minvalue.step( maxvalue, scale_division ) {|v| rv << v}
99
+ return rv
100
+ end
101
+
102
+ def x_label_offset( width )
103
+ width / 2.0
104
+ end
105
+
106
+ def draw_data
107
+ minvalue = min_value
108
+ fieldwidth = field_width
109
+
110
+ unit_size = (@graph_height.to_f - font_size*2*top_font) /
111
+ (get_y_labels.max - get_y_labels.min)
112
+ bargap = bar_gap ? (fieldwidth < 10 ? fieldwidth / 2 : 10) : 0
113
+
114
+ bar_width = fieldwidth - (bargap *2)
115
+ bar_width /= @data.length if stack == :side
116
+ #x_mod = (@graph_width-bargap)/2 - (stack==:side ? bar_width/2 : 0)
117
+
118
+ bottom = @graph_height
119
+
120
+ field_count = 0
121
+ @config[:fields].each_index { |i|
122
+ dataset_count = 0
123
+ for dataset in @data
124
+
125
+ # cases (assume 0 = +ve):
126
+ # value min length
127
+ # +ve +ve value - min
128
+ # +ve -ve value - 0
129
+ # -ve -ve value.abs - 0
130
+
131
+ value = dataset[:data][i]
132
+
133
+ left = (fieldwidth * field_count)
134
+ left += bargap
135
+
136
+
137
+ length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size
138
+ # top is 0 if value is negative
139
+ top = bottom - (((value < 0 ? 0 : value) - minvalue) * unit_size)
140
+ left += bar_width * dataset_count if stack == :side
141
+
142
+ @graph.add_element( "rect", {
143
+ "x" => left.to_s,
144
+ "y" => top.to_s,
145
+ "width" => bar_width.to_s,
146
+ "height" => length.to_s,
147
+ "class" => "fill#{dataset_count+1}"
148
+ })
149
+
150
+
151
+
152
+ threshold = @config[:errorBars][i] * unit_size
153
+ middlePointErr = left+bar_width/2
154
+ upperErr = top+threshold
155
+ bottomErr = top-threshold
156
+ withthErr = bar_width/4
157
+
158
+ @graph.add_element( "line", {
159
+ "x1" => middlePointErr.to_s,
160
+ "y1" => upperErr.to_s,
161
+ "x2" => middlePointErr.to_s,
162
+ "y2" => bottomErr.to_s,
163
+ "style" => "stroke:rgb(0,0,0);stroke-width:1"
164
+ })
165
+
166
+ @graph.add_element( "line", {
167
+ "x1" => (middlePointErr-withthErr).to_s,
168
+ "y1" => upperErr.to_s,
169
+ "x2" => (middlePointErr+withthErr).to_s,
170
+ "y2" => upperErr.to_s,
171
+ "style" => "stroke:rgb(0,0,0);stroke-width:1"
172
+ })
173
+ @graph.add_element( "line", {
174
+ "x1" => (middlePointErr-withthErr).to_s,
175
+ "y1" => bottomErr.to_s,
176
+ "x2" => (middlePointErr+withthErr).to_s,
177
+ "y2" => bottomErr.to_s,
178
+ "style" => "stroke:rgb(0,0,0);stroke-width:1"
179
+ })
180
+
181
+ make_datapoint_text(left + bar_width/2.0, top - 6, value.to_s)
182
+ dataset_count += 1
183
+ end
184
+ field_count += 1
185
+ }
186
+ end
187
+ end
188
+ end
189
+ end