rubicus 0.1.0

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/CHANGES ADDED
@@ -0,0 +1,6 @@
1
+ = Rubicus Changelog
2
+
3
+ == Version 0.1.0
4
+ (August 24th, 2006)
5
+
6
+ * Initial release.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006 Jonathan Younger (jonathan@daikini.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,11 @@
1
+ ==Rubicus
2
+
3
+ Author:: Jonathan Younger (jonathan@daikini.com)
4
+ Date:: August 24th, 2006
5
+
6
+ Rubicus is a pure Ruby wrapper around the ploticus http://ploticus.sourceforge.net graphing library.
7
+
8
+ For basic usage instructions, refer to the documentation for Rubicus::Graph.
9
+
10
+ Based on the design of Scruffy Graphs (a beautiful graphing library for Ruby) by Brasten Sager. http://scruffy.rubyforge.org/
11
+ Custom ploticus graph code taken from ploticus.rb by Mike Neumann. http://www.ntecs.de/blog-old/Blog/RubyPloticus.rdoc
@@ -0,0 +1,84 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+ require 'lib/rubicus'
9
+
10
+ PKG_NAME = "rubicus"
11
+ PKG_VERSION = Rubicus::VERSION
12
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
13
+ PKG_FILES = FileList[
14
+ '[A-Z]*',
15
+ 'lib/**/*.rb',
16
+ 'test/**/*.rb'
17
+ ]
18
+
19
+ desc "Deploy docs to RubyForge"
20
+ task :rdoc_deploy => [:rdoc] do
21
+ dirs = %w{doc}
22
+ onserver = "poogle@rubyforge.org:/var/www/gforge-projects/rubicus"
23
+ dirs.each do | dir|
24
+ `scp -r "#{`pwd`.chomp}/#{dir}" "#{onserver}"`
25
+ end
26
+ end
27
+
28
+ # Genereate the RDoc documentation
29
+ Rake::RDocTask.new { |rdoc|
30
+ rdoc.rdoc_dir = 'doc'
31
+ rdoc.title = "Rubicus - Graphing Library for Ruby using the ploticus backend."
32
+ rdoc.rdoc_files.include("README", "CHANGELOG", "MIT-LICENSE")
33
+ rdoc.rdoc_files.include("lib/rubicus.rb")
34
+ rdoc.rdoc_files.include("lib/rubicus/*.rb")
35
+ rdoc.rdoc_files.include("lib/rubicus/layers/*.rb")
36
+ }
37
+
38
+ spec = Gem::Specification.new do |s|
39
+ s.name = PKG_NAME
40
+ s.version = PKG_VERSION
41
+ s.author = "Jonathan Younger"
42
+ s.email = "jonathan@daikini.com"
43
+ s.homepage = "http://rubicus.rubyforge.org"
44
+ s.summary = "Graphing library for Ruby using the ploticus backend."
45
+ s.description = "Rubicus is a pure Ruby wrapper around the ploticus http://ploticus.sourceforge.net graphing library."
46
+ s.files = PKG_FILES.to_a
47
+ s.has_rdoc = false
48
+ s.rubyforge_project = "rubicus"
49
+ end
50
+
51
+ Rake::GemPackageTask.new(spec) do |pkg|
52
+ pkg.need_zip = true
53
+ pkg.need_tar = true
54
+ end
55
+
56
+ task :verify_user do
57
+ raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
58
+ end
59
+
60
+ task :verify_password do
61
+ raise "RUBYFORGE_PASSWORD environment variable not set!" unless ENV['RUBYFORGE_PASSWORD']
62
+ end
63
+
64
+ desc "Publish gem+tgz+zip on RubyForge. You must make sure lib/version.rb is aligned with the CHANGELOG file"
65
+ task :publish_packages => [:verify_user, :verify_password, :package] do
66
+ require 'meta_project'
67
+ require 'rake/contrib/xforge'
68
+ release_files = FileList[
69
+ "pkg/#{PKG_FILE_NAME}.gem",
70
+ "pkg/#{PKG_FILE_NAME}.tgz",
71
+ "pkg/#{PKG_FILE_NAME}.zip",
72
+ "pkg/#{PKG_FILE_NAME}.gem.md5",
73
+ "pkg/#{PKG_FILE_NAME}.tgz.md5",
74
+ "pkg/#{PKG_FILE_NAME}.zip.md5"
75
+ ]
76
+
77
+ Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new(PKG_NAME)) do |xf|
78
+ # Never hardcode user name and password in the Rakefile!
79
+ xf.user_name = ENV['RUBYFORGE_USER']
80
+ xf.password = ENV['RUBYFORGE_PASSWORD']
81
+ xf.files = release_files.to_a
82
+ xf.release_name = "Rubicus #{PKG_VERSION}"
83
+ end
84
+ end
@@ -0,0 +1,8 @@
1
+ module Rubicus; end
2
+
3
+ $:.unshift(File.dirname(__FILE__)) unless
4
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
5
+
6
+ require 'rubicus/version'
7
+ require 'rubicus/graph'
8
+ require 'rubicus/layers'
@@ -0,0 +1,125 @@
1
+ require 'tempfile'
2
+
3
+ module Rubicus
4
+
5
+ # ==Rubicus Graph
6
+ #
7
+ # Author:: Jonathan Younger
8
+ # Date:: August 24th, 2006
9
+ #
10
+ #
11
+ # ====Graphs vs. Layers (Graph Types)
12
+ #
13
+ # Rubicus::Graph is the primary class you will use to generate your graphs. A Graph does not
14
+ # define a graph type nor does it directly hold any data. Instead, a Graph object can be thought
15
+ # of as a canvas on which other graphs are draw. (The actual graphs themselves are subclasses of Rubicus::Layers::Base)
16
+ # Despite the technical distinction, we will refer to Rubicus::Graph objects as 'graphs' and Rubicus::Layers as
17
+ # 'layers' or 'graph types.'
18
+ #
19
+ #
20
+ # ==== Creating a Graph
21
+ #
22
+ # You can begin building a graph by instantiating a Graph object
23
+ #
24
+ # graph = Rubicus::Graph.new
25
+ #
26
+ # Once you have a Graph object you can begin adding graph layers.
27
+ # You can add a graph layer to a graph by using the Graph#add or Graph#<< methods.
28
+ # The two methods are identical and used to accommodate syntax preferences.
29
+ #
30
+ # graph.add :lines, [[10, 20], [20, 30], [30, 40], [40, 50]], :title => "Jack", :x => 1, :y => 2, :pointsym => :none, :rectangle => [1, 1, 3, 3]
31
+ # graph.add :lines, [[10, 20], [20, 30], [30, 40], [40, 50]], :title => "Jill", :x => 1, :y => 2, :pointsym => :none, :rectangle => [4, 1, 6, 3]
32
+ #
33
+ # Now that we've created our graph and added a layer to it, we're ready to render! You can render the graph
34
+ # directly to PNG or any other image format (supported by ploticus) with the Graph#render method:
35
+ #
36
+ # # Defaults to PNG
37
+ # graph.render
38
+ #
39
+ # # For image formats other than PNG:
40
+ # graph.render(:as => 'GIF')
41
+ #
42
+ # # To render directly to a file:
43
+ # graph.render(:to => '<filename>')
44
+ #
45
+ # graph.render(:as => 'GIF', :to => '<filename>')
46
+ #
47
+ # And that's your basic Rubicus graph! Please check the ploticus documentation for the various methods and
48
+ # classes you'll be using, as there are a bunch of options not demonstrated here.
49
+ #
50
+ # A couple final things worth noting:
51
+ # * You can call Graph#render as often as you wish with different rendering options. In
52
+ # fact, you can modify the graph any way you wish between renders.
53
+ #
54
+ #
55
+ # * There are no restrictions to the combination of graph layers you can add. It is perfectly
56
+ # valid to do something like:
57
+ # graph.add(:lines, [100, 200, 300])
58
+ # graph.add(:vbars, [200, 150, 150])
59
+ class Graph
60
+ attr_accessor :layers
61
+ attr_accessor :default_type
62
+ attr_accessor :options
63
+
64
+ def initialize(options = {})
65
+ @default_type = options.delete(:type)
66
+ @options = options
67
+ @layers ||= []
68
+ end
69
+
70
+ def <<(*args, &block)
71
+ if args[0].kind_of?(Rubicus::Layers::Base)
72
+ layers << args[0]
73
+ else
74
+ type = args.first.is_a?(Symbol) ? args.shift : @default_type
75
+ data = args.first.is_a?(Array) ? args.shift : []
76
+ options = args.first.is_a?(Hash) ? args.shift : {}
77
+
78
+ raise ArgumentError, "You must specify a graph type (:scat, :lines, :pie, etc) if you do not have a default type specified." if type.nil?
79
+
80
+ unless Rubicus::Layers.const_defined? to_camelcase(type.to_s)
81
+ layer = Rubicus::Layers::Prefab.new(options.merge({ :prefab => type, :data => data }))
82
+ else
83
+ layer = Kernel::module_eval("Rubicus::Layers::#{to_camelcase(type.to_s)}").new(options.merge({ :data => data }), &block)
84
+ end
85
+
86
+ layers << layer
87
+ end
88
+ layer
89
+ end
90
+
91
+ alias :add :<<
92
+
93
+ # Renders the graph in it's current state to an PNG object.
94
+ #
95
+ # Options:
96
+ # as:: File format to render to ('PNG', 'JPG', etc)
97
+ # to:: Name of file to save graph to, if desired. If not provided, image is returned as blob/string.
98
+ def render(options = {})
99
+ options[:o] ||= "stdout"
100
+ image_type = options.delete(:as) || "png"
101
+ to = options.delete(:to)
102
+
103
+ image = case layers.size
104
+ when 0
105
+ raise "You haven't specified any layers to render."
106
+ when 1
107
+ layers.first.draw(image_type, @options.merge(options))
108
+ else
109
+ dump_file = Tempfile.new("rubicus_dump_file")
110
+ layers.each { |layer| layer.draw(nil, :drawdumpa => dump_file.path) }
111
+ layer = Rubicus::Layers::Prefab.new(:prefab => :draw, :dumpfile => dump_file.path)
112
+ layer.draw(image_type, @options.merge(options))
113
+ end
114
+
115
+ File.open(to, "w") { |file| file.write(image) } if to
116
+
117
+ image
118
+ end
119
+
120
+ protected
121
+ def to_camelcase(type) # :nodoc:
122
+ type.split("_").map { |e| e.capitalize }.join("")
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubicus/layers/base'
2
+ require 'rubicus/layers/custom'
3
+ require 'rubicus/layers/prefab'
@@ -0,0 +1,46 @@
1
+ module Rubicus::Layers
2
+ class Base
3
+ protected
4
+ def convert_options(obj)
5
+ case obj
6
+ when String
7
+ obj.gsub("\n", "\\n")
8
+ when Array
9
+ if obj[0].kind_of? Array
10
+ obj.map { |row| row.join(" ") }.join
11
+ else
12
+ obj.join(" ")
13
+ end
14
+ when Hash
15
+ obj.map { |k,v| "#{k}=#{convert_options(v)}" }.join(" ")
16
+ when true
17
+ 'yes'
18
+ when false
19
+ 'no'
20
+ else
21
+ obj.to_s
22
+ end
23
+ end
24
+
25
+ def convert(obj)
26
+ case obj
27
+ when String
28
+ obj.gsub("\n", "\\n") + "\n"
29
+ when Array
30
+ if obj[0].kind_of? Array
31
+ obj.map {|row| row.join(" ") + "\n"}.join
32
+ else
33
+ obj.join(" ")
34
+ end
35
+ when Hash
36
+ obj.map {|k,v| "#{ k }=#{ convert(v) }" }.join(" ")
37
+ when true
38
+ 'yes'
39
+ when false
40
+ 'no'
41
+ else
42
+ obj.to_s
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,68 @@
1
+ # Most of this code is from the ploticus.rb file by Mike Neumann http://www.ntecs.de/blog-old/Blog/RubyPloticus.rdoc
2
+
3
+ module Rubicus::Layers
4
+ class Custom < Base
5
+ def initialize
6
+ reset!
7
+ end
8
+
9
+ def data=(rows)
10
+ data {|a| a.data = rows }
11
+ end
12
+
13
+ def draw(image_type = "png", options = {})
14
+ options[image_type] = nil if image_type
15
+ ploticus_options = options.map { |key, option| "-#{key} #{convert_options(option)}" }.join(" ")
16
+ io = IO.popen("ploticus -stdin #{ploticus_options}", "w+")
17
+ io.write @s
18
+ io.close_write
19
+ img = io.read
20
+ io.close
21
+ img
22
+ end
23
+
24
+ def reset!
25
+ @s = ""
26
+ end
27
+
28
+ PROCS = [
29
+ [:data, :getdata],
30
+ [:area, :areadef],
31
+ ]
32
+
33
+ PROCS.each do |m, mp|
34
+ mp ||= m
35
+ eval %[ def #{ m }(&block) do_block("#{ mp }", &block) end ]
36
+ end
37
+
38
+ def method_missing(id, &block)
39
+ do_block(id.to_s, &block)
40
+ end
41
+
42
+ private
43
+ def do_block(mp, &block)
44
+ @s << "#proc #{ mp }\n"
45
+ AttrWriter.new(&block).__attrs__.each do |k, v|
46
+ @s << "#{ k }: #{ convert(v) }\n"
47
+ end
48
+ @s << "\n"
49
+ end
50
+
51
+ class AttrWriter
52
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
53
+
54
+ def __attrs__
55
+ @attrs
56
+ end
57
+
58
+ def initialize(&block)
59
+ @attrs = {}
60
+ block.call(self)
61
+ end
62
+
63
+ def method_missing(id, value)
64
+ @attrs[id.to_s.gsub("=", "")] = value
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,49 @@
1
+ module Rubicus::Layers
2
+ class Prefab < Base
3
+ def initialize(options = {})
4
+ @type = options.delete(:prefab)
5
+ @data = options.delete(:data)
6
+ @options = options
7
+ @options[:delim] ||= :comma
8
+ end
9
+
10
+ def draw(image_type = "png", options = {})
11
+ options[image_type] = nil if image_type
12
+ options[:prefab] ||= @type
13
+
14
+ if @data
15
+ data = if @data[0].kind_of? Array
16
+ @data.map {|row| row.join(delimiter_for_delim(@options[:delim])) }.join("\n")
17
+ else
18
+ @data.join(",")
19
+ end
20
+ else
21
+ data = nil
22
+ end
23
+
24
+ ploticus_options = options.map { |key, option| "-#{key} #{convert_options(option)}" }.join(" ")
25
+ prefab_options = @options.map { |key, option| "#{key}=\"#{convert_options(option)}\"" }.join(" ")
26
+ io = IO.popen("ploticus #{@data ? "data=stdin" : ""} #{ploticus_options} #{prefab_options}", "w+")
27
+ if @data
28
+ io.write data
29
+ io.close_write
30
+ end
31
+ img = io.read
32
+ io.close
33
+ img
34
+ end
35
+
36
+
37
+ protected
38
+ def delimiter_for_delim(delim)
39
+ case delim
40
+ when :comma
41
+ ","
42
+ when :tab
43
+ "\t"
44
+ else
45
+ " "
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module Rubicus
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,131 @@
1
+ #/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../lib/rubicus'
3
+
4
+ data = [
5
+ ["Name", "Concentration", "PeakArea"],
6
+ ["A", 1, 2],
7
+ ["B", 2, 3],
8
+ ["C", 2, 4],
9
+ ["D", 1, 4],
10
+ ["E", 6, 7]
11
+ ]
12
+
13
+ # layer = Rubicus::Layers::Scat.new(:data => data, :xgrid => { :width => "0.1", :color => "gray(0.9)"}, :x => 2, :y => 3, :corr => true)
14
+
15
+ g = Rubicus::Graph.new
16
+ g.add :scat, data, :xgrid => { :width => "0.1", :color => "gray(0.9)" }, :x => 2, :y => 3, :corr => true, :rectangle => [1, 1, 3, 3]
17
+ g.add :scat, data, :xgrid => { :width => "0.6", :color => "gray(2.5)" }, :x => 2, :y => 3, :corr => true, :rectangle => [4, 1, 6, 3]
18
+ # g.add layer
19
+ g.render(:to => "bob.png")
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+ layer = Rubicus::Layers::Custom.new
48
+
49
+ layer.data = [
50
+ [2000, 750],
51
+ [2010, 1700],
52
+ [2015, 2000],
53
+ [2020, 1800],
54
+ [2025, 1300],
55
+ [2030, 400]
56
+ ]
57
+
58
+ layer.area {|a|
59
+ a.title = "Social Security trust fund asset estimates, in $ billions\nhallo\nsuper"
60
+ a.titledetails = {:adjust => "0,0.1"}
61
+ a.rectangle = [1, 1, 5, 2]
62
+ a.xrange = [2000, 2035]
63
+ a.yrange = [0, 2000]
64
+ }
65
+
66
+ layer.xaxis {|a|
67
+ a.stubs = "inc 5"
68
+ a.label = "Year"
69
+ }
70
+
71
+ layer.lineplot {|a|
72
+ a.xfield = 1
73
+ a.yfield = 2
74
+ a.fill = "pink"
75
+ }
76
+
77
+ layer.lineplot {|a|
78
+ a.xfield = 1
79
+ a.yfield = 2
80
+ a.fill = "rgb(.7,.3,.3)"
81
+ a.linerange = [2010, 2020]
82
+ }
83
+
84
+ layer.lineplot {|a|
85
+ a.xfield = 1
86
+ a.yfield = 2
87
+ a.linedetails = {:color => 'red'}
88
+ a.fill = "rgb(.7,.3,.3)"
89
+ a.linerange = [2010, 2020]
90
+ }
91
+
92
+ layer.yaxis {|a|
93
+ a.stubs = "incremental 500"
94
+ a.grid = {:color=> 'blue'}
95
+ a.axisline = 'none'
96
+ }
97
+
98
+ g = Rubicus::Graph.new
99
+ g.add layer
100
+ g.render(:to => "bob2.png")
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+ g = Rubicus::Graph.new
110
+ g.add :lines, [[10, 20], [20, 30], [30, 40], [40, 50]], :title => "Jack", :x => 1, :y => 2, :pointsym => :none, :rectangle => [1, 1, 3, 3]
111
+ g.add :lines, [[10, 20], [20, 30], [30, 40], [40, 50]], :title => "Jill", :x => 1, :y => 2, :pointsym => :none, :rectangle => [4, 1, 6, 3]
112
+ g.render :to => "hmm.png"
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+ data = (1..12).collect { |i| ["Test #{i}", rand(110), rand(20)] }
121
+
122
+ g = Rubicus::Graph.new
123
+ g.add :vbars, data, :x => 1, :y => 2, :autow => false, :errunder => true, :ygrid => true, :barwidth => :line, :stubvert => true, :xaxis => :none, :yaxis => :none, :rectangle => [0, 0, 0.5, 0.2], :legend => false, :header => false, :yrange => 110
124
+ g.render(:to => "sweet.png")
125
+
126
+
127
+ # data = (1..12).collect { |i| [i, rand(20)] }
128
+ #
129
+ # g = Rubicus::Graph.new
130
+ # g.add :line, data, :x => 1, :y => 2, :pointsym => :none, :xaxis => :none
131
+ # g.render(:to => "sweet.png")
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: rubicus
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2006-08-30 00:00:00 -07:00
8
+ summary: Graphing library for Ruby using the ploticus backend.
9
+ require_paths:
10
+ - lib
11
+ email: jonathan@daikini.com
12
+ homepage: http://rubicus.rubyforge.org
13
+ rubyforge_project: rubicus
14
+ description: Rubicus is a pure Ruby wrapper around the ploticus http://ploticus.sourceforge.net graphing library.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Jonathan Younger
31
+ files:
32
+ - CHANGES
33
+ - MIT-LICENSE
34
+ - Rakefile
35
+ - README
36
+ - lib/rubicus.rb
37
+ - lib/rubicus/graph.rb
38
+ - lib/rubicus/layers.rb
39
+ - lib/rubicus/version.rb
40
+ - lib/rubicus/layers/base.rb
41
+ - lib/rubicus/layers/custom.rb
42
+ - lib/rubicus/layers/prefab.rb
43
+ - test/test.rb
44
+ test_files: []
45
+
46
+ rdoc_options: []
47
+
48
+ extra_rdoc_files: []
49
+
50
+ executables: []
51
+
52
+ extensions: []
53
+
54
+ requirements: []
55
+
56
+ dependencies: []
57
+