svg_graph 0.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.
@@ -0,0 +1,161 @@
1
+ #! /usr/bin/env ruby
2
+ ################################################################################
3
+ # #
4
+ # Name: install.rb #
5
+ # Author: Sean E Russell <ser@germane-software.com> #
6
+ # Version: $Id: $
7
+ # Date: *2002-174 #
8
+ # Description: #
9
+ # This is a generic installation script for pure ruby sources. Features #
10
+ # include: #
11
+ # * Clean uninstall #
12
+ # * Installation into an absolute path #
13
+ # * Installation into a temp path (useful for systems like Portage) #
14
+ # * Noop mode, for testing #
15
+ # To set for a different system, change the SRC directory to point to the #
16
+ # package name / source directory for the project. #
17
+ # #
18
+ ################################################################################
19
+
20
+ # CHANGE THIS
21
+ SRC = ['SVG' ]
22
+ STRIP = ''
23
+ SETVERSION = 'SVG'
24
+ SRCVERSION = '0.6.1'
25
+ DATE = '+2005/058'
26
+
27
+ ################################################################################
28
+ # CHANGE NOTHING BELOW THIS LINE
29
+
30
+ Dir.chdir ".." if Dir.pwd =~ /bin.?$/
31
+
32
+ require 'getoptlong'
33
+ require 'rbconfig'
34
+ require 'ftools'
35
+ require 'find'
36
+
37
+ opts = GetoptLong.new( [ '--uninstall', '-u', GetoptLong::NO_ARGUMENT],
38
+ [ '--destdir', '-d', GetoptLong::REQUIRED_ARGUMENT ],
39
+ [ '--target', '-t', GetoptLong::REQUIRED_ARGUMENT ],
40
+ [ '--concurrent', '-c', GetoptLong::NO_ARGUMENT],
41
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT],
42
+ [ '--noop', '-n', GetoptLong::NO_ARGUMENT])
43
+
44
+
45
+ destdir = File.join(Config::CONFIG['sitedir'],
46
+ "#{Config::CONFIG['MAJOR']}.#{Config::CONFIG['MINOR']}")
47
+
48
+ uninstall = false
49
+ prepend = nil
50
+ help = false
51
+ opts.each do |opt,arg|
52
+ case opt
53
+ when '--concurrent'
54
+ CONCURRENT = true
55
+ when '--destdir'
56
+ prepend = arg
57
+ when '--uninstall'
58
+ uninstall = true
59
+ when '--target'
60
+ destdir = arg
61
+ when '--help'
62
+ help = true
63
+ when '--noop'
64
+ NOOP = true
65
+ end
66
+ end
67
+
68
+ destdir = File.join prepend, destdir if prepend
69
+
70
+ def transmogrify( dir )
71
+ dir = dir.sub( /^#{STRIP}\//, '' )
72
+ if defined? CONCURRENT
73
+ dir.sub( /#{SETVERSION}/, "#{SETVERSION}-#{SRCVERSION}")
74
+ else
75
+ dir
76
+ end
77
+ end
78
+
79
+ if help
80
+ puts "Installs #{SRC.inspect}.\nUsage: #$0 [[-u] [-n] [-c] [-t <dir>|-d <dir>]|-h]"
81
+ puts " -u --uninstall\n Uninstalls the package"
82
+ puts " -c --concurrent\n Install concurrently, IE, into"
83
+ for d in SRC
84
+ puts " #{destdir}/#{transmogrify( d )}"
85
+ end
86
+ puts " The default behavior is to upgrade the current installation,"
87
+ puts " by installing into"
88
+ for d in SRC
89
+ puts " #{destdir}/#{transmogrify( d )}"
90
+ end
91
+ puts " -t --target\n Installs the software at an absolute location, EG:"
92
+ puts " #$0 -t /usr/local/lib/ruby"
93
+ puts " will put the software directly underneath /usr/local/lib/ruby;"
94
+ for d in SRC
95
+ puts " /usr/local/lib/ruby/#{transmogrify( d )}"
96
+ end
97
+ puts " -d --destdir\n Installs the software at a relative location, EG:"
98
+ puts " #$0 -d /tmp"
99
+ puts " will put the software under tmp, using your ruby environment."
100
+ for d in SRC
101
+ puts " /tmp#{destdir}/#{transmogrify( d )}"
102
+ end
103
+ puts " -n --noop\n Don't actually do anything; just print out what it"
104
+ puts " would do."
105
+ exit 0
106
+ end
107
+
108
+ def install destdir
109
+ puts "Installing in #{destdir}"
110
+ begin
111
+ for src in SRC
112
+ Find.find(src) { |file|
113
+ dstfile = transmogrify( file )
114
+ next if file =~ /CVS|\.svn/
115
+ dst = File.join( destdir, dstfile )
116
+ if defined? NOOP
117
+ puts ">> #{dst}" if file =~ /\.rb$/
118
+ else
119
+ File.makedirs( File.dirname(dst) )
120
+ File.install(file, dst, 0644, true) if file =~ /\.rb$/
121
+ end
122
+ }
123
+ end
124
+ rescue
125
+ puts $!
126
+ end
127
+ end
128
+
129
+ def uninstall destdir
130
+ puts "Uninstalling in #{destdir}"
131
+ begin
132
+ puts "Deleting:"
133
+ dirs = []
134
+ Find.find(File.join(destdir,SRC)) do |file|
135
+ file.sub!( /#{SRC}/, "#{SRC}-#{SRCVERSION}") if defined? CONCURRENT
136
+ if defined? NOOP
137
+ puts "-- #{file}" if File.file? file
138
+ else
139
+ File.rm_f file,true if File.file? file
140
+ end
141
+ dirs << file if File.directory? file
142
+ end
143
+ dirs.sort { |x,y|
144
+ y.length <=> x.length
145
+ }.each { |d|
146
+ if defined? NOOP
147
+ puts "-- #{d}"
148
+ else
149
+ puts d
150
+ Dir.delete d
151
+ end
152
+ }
153
+ rescue
154
+ end
155
+ end
156
+
157
+ if uninstall
158
+ uninstall destdir
159
+ else
160
+ install destdir
161
+ end
@@ -0,0 +1,11 @@
1
+
2
+ require 'svg_graph/BarHorizontal'
3
+ require 'svg_graph/Graph'
4
+ require 'svg_graph/Line'
5
+ require 'svg_graph/Pie'
6
+ require 'svg_graph/Plot'
7
+ require 'svg_graph/Schedule'
8
+ require 'svg_graph/TimeSeries'
9
+ require 'svg_graph/version'
10
+
11
+ SvgGraph = SVG::Graph
@@ -0,0 +1,148 @@
1
+ require 'rexml/document'
2
+ require 'svg_graph/Graph'
3
+ require 'svg_graph/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 Bar < BarBase
59
+ include REXML
60
+
61
+ # See Graph::initialize and BarBase::set_defaults
62
+ def set_defaults
63
+ super
64
+ self.top_align = self.top_font = 1
65
+ end
66
+
67
+ protected
68
+
69
+ def get_x_labels
70
+ @config[:fields]
71
+ end
72
+
73
+ def get_y_labels
74
+ maxvalue = max_value
75
+ minvalue = min_value
76
+ range = maxvalue - minvalue
77
+
78
+ top_pad = range == 0 ? 10 : range / 20.0
79
+ scale_range = (maxvalue + top_pad) - minvalue
80
+
81
+ scale_division = scale_divisions || (scale_range / 10.0)
82
+
83
+ if scale_integers
84
+ scale_division = scale_division < 1 ? 1 : scale_division.round
85
+ end
86
+
87
+ rv = []
88
+ maxvalue = maxvalue%scale_division == 0 ?
89
+ maxvalue : maxvalue + scale_division
90
+ minvalue.step( maxvalue, scale_division ) {|v| rv << v}
91
+ return rv
92
+ end
93
+
94
+ def x_label_offset( width )
95
+ width / 2.0
96
+ end
97
+
98
+ def draw_data
99
+ minvalue = min_value
100
+ fieldwidth = field_width
101
+
102
+ unit_size = (@graph_height.to_f - font_size*2*top_font) /
103
+ (get_y_labels.max - get_y_labels.min)
104
+ bargap = bar_gap ? (fieldwidth < 10 ? fieldwidth / 2 : 10) : 0
105
+
106
+ bar_width = fieldwidth - bargap
107
+ bar_width /= @data.length if stack == :side
108
+ x_mod = (@graph_width-bargap)/2 - (stack==:side ? bar_width/2 : 0)
109
+
110
+ bottom = @graph_height
111
+
112
+ field_count = 0
113
+ @config[:fields].each_index { |i|
114
+ dataset_count = 0
115
+ for dataset in @data
116
+
117
+ # cases (assume 0 = +ve):
118
+ # value min length
119
+ # +ve +ve value - min
120
+ # +ve -ve value - 0
121
+ # -ve -ve value.abs - 0
122
+
123
+ value = dataset[:data][i]
124
+
125
+ left = (fieldwidth * field_count)
126
+
127
+ length = (value.abs - (minvalue > 0 ? minvalue : 0)) * unit_size
128
+ # top is 0 if value is negative
129
+ top = bottom - (((value < 0 ? 0 : value) - minvalue) * unit_size)
130
+ left += bar_width * dataset_count if stack == :side
131
+
132
+ @graph.add_element( "rect", {
133
+ "x" => left.to_s,
134
+ "y" => top.to_s,
135
+ "width" => bar_width.to_s,
136
+ "height" => length.to_s,
137
+ "class" => "fill#{dataset_count+1}"
138
+ })
139
+
140
+ make_datapoint_text(left + bar_width/2.0, top - 6, value.to_s)
141
+ dataset_count += 1
142
+ end
143
+ field_count += 1
144
+ }
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,139 @@
1
+ require 'rexml/document'
2
+ require 'svg_graph/Graph'
3
+
4
+ module SVG
5
+ module Graph
6
+ # = Synopsis
7
+ #
8
+ # A superclass for bar-style graphs. Do not attempt to instantiate
9
+ # directly; use one of the subclasses instead.
10
+ #
11
+ # = Author
12
+ #
13
+ # Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom>
14
+ #
15
+ # Copyright 2004 Sean E. Russell
16
+ # This software is available under the Ruby license[LICENSE.txt]
17
+ #
18
+ class BarBase < SVG::Graph::Graph
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
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
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
+
42
+
43
+ protected
44
+
45
+ def max_value
46
+ @data.collect{|x| x[:data].max}.max
47
+ end
48
+
49
+ def min_value
50
+ min = 0
51
+ if min_scale_value.nil?
52
+ min = @data.collect{|x| x[:data].min}.min
53
+ min = min > 0 ? 0 : min
54
+ else
55
+ min = min_scale_value
56
+ end
57
+ return min
58
+ end
59
+
60
+ def get_css
61
+ return <<EOL
62
+ /* default fill styles for multiple datasets (probably only use a single dataset on this graph though) */
63
+ .key1,.fill1{
64
+ fill: #ff0000;
65
+ fill-opacity: 0.5;
66
+ stroke: none;
67
+ stroke-width: 0.5px;
68
+ }
69
+ .key2,.fill2{
70
+ fill: #0000ff;
71
+ fill-opacity: 0.5;
72
+ stroke: none;
73
+ stroke-width: 1px;
74
+ }
75
+ .key3,.fill3{
76
+ fill: #00ff00;
77
+ fill-opacity: 0.5;
78
+ stroke: none;
79
+ stroke-width: 1px;
80
+ }
81
+ .key4,.fill4{
82
+ fill: #ffcc00;
83
+ fill-opacity: 0.5;
84
+ stroke: none;
85
+ stroke-width: 1px;
86
+ }
87
+ .key5,.fill5{
88
+ fill: #00ccff;
89
+ fill-opacity: 0.5;
90
+ stroke: none;
91
+ stroke-width: 1px;
92
+ }
93
+ .key6,.fill6{
94
+ fill: #ff00ff;
95
+ fill-opacity: 0.5;
96
+ stroke: none;
97
+ stroke-width: 1px;
98
+ }
99
+ .key7,.fill7{
100
+ fill: #00ffff;
101
+ fill-opacity: 0.5;
102
+ stroke: none;
103
+ stroke-width: 1px;
104
+ }
105
+ .key8,.fill8{
106
+ fill: #ffff00;
107
+ fill-opacity: 0.5;
108
+ stroke: none;
109
+ stroke-width: 1px;
110
+ }
111
+ .key9,.fill9{
112
+ fill: #cc6666;
113
+ fill-opacity: 0.5;
114
+ stroke: none;
115
+ stroke-width: 1px;
116
+ }
117
+ .key10,.fill10{
118
+ fill: #663399;
119
+ fill-opacity: 0.5;
120
+ stroke: none;
121
+ stroke-width: 1px;
122
+ }
123
+ .key11,.fill11{
124
+ fill: #339900;
125
+ fill-opacity: 0.5;
126
+ stroke: none;
127
+ stroke-width: 1px;
128
+ }
129
+ .key12,.fill12{
130
+ fill: #9966FF;
131
+ fill-opacity: 0.5;
132
+ stroke: none;
133
+ stroke-width: 1px;
134
+ }
135
+ EOL
136
+ end
137
+ end
138
+ end
139
+ end