Kelsin-lilygraph 0.0.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/LICENSE +0 -0
- data/README +0 -0
- data/VERSION +1 -0
- data/lib/lilygraph.rb +176 -0
- data/lilygraph.gemspec +47 -0
- metadata +78 -0
data/LICENSE
ADDED
File without changes
|
data/README
ADDED
File without changes
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/lilygraph.rb
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
# This is the main graphing class used for generating svg graphs.
|
2
|
+
#
|
3
|
+
# :author: Christopher Giroir <kelsin@valefor.com>
|
4
|
+
|
5
|
+
class Lilygraph
|
6
|
+
# Default options for the initializer
|
7
|
+
DEFAULT_OPTIONS = {
|
8
|
+
:height => '100%',
|
9
|
+
:width => '100%',
|
10
|
+
:indent => 2,
|
11
|
+
:padding => 14,
|
12
|
+
:viewbox => {
|
13
|
+
:width => 800,
|
14
|
+
:height => 600
|
15
|
+
},
|
16
|
+
:margin => { :top => 50, :left => 50, :right => 50, :bottom => 100 }
|
17
|
+
}
|
18
|
+
|
19
|
+
# An array of labels to use on the y axis. Make sure you have the right number
|
20
|
+
# of labels. The size of this array should = the size of the data array.
|
21
|
+
attr_accessor :labels
|
22
|
+
|
23
|
+
# This is the data for the graph. It should be an array where every item is
|
24
|
+
# either a number or an array of numbers.
|
25
|
+
#
|
26
|
+
# Examples:
|
27
|
+
# For a simple bar graph: data=[1,2,3]
|
28
|
+
# For a grouped bar graph: data=[[1,10],[2,20],[3,30]]
|
29
|
+
attr_accessor :data
|
30
|
+
|
31
|
+
# Returns a new graph creator with some default options and other options that you pass.
|
32
|
+
#
|
33
|
+
# The options has includes:
|
34
|
+
# :height - String to use as height parameter on the svg tag. Default is '100%'.
|
35
|
+
# :width - String to use as width parameter on the svg tag. Default is '100%'.
|
36
|
+
# :indent - Indent option to the XmlMarkup object. Defaults to 2.
|
37
|
+
# :padding - Number of svg units in between two bars.
|
38
|
+
# :viewbox - Hash of :height and :width keys to use for the viewbox parameter of the svg tag. Defaults to { :height => 600, :width => 800 }.
|
39
|
+
# :margin - Hash of margins to use for graph (in svg units). Defaults to { :top => 50, :left => 50, :right => 50, :bottom => 100 }.
|
40
|
+
def initialize(options = {})
|
41
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
42
|
+
@data = []
|
43
|
+
@labels = []
|
44
|
+
end
|
45
|
+
|
46
|
+
# Updates the graph options with items from the passed in hash
|
47
|
+
def update_options(options = {})
|
48
|
+
@options = @options.merge(options)
|
49
|
+
end
|
50
|
+
|
51
|
+
# This returns a string of the graph as an svg. You can pass in a block in
|
52
|
+
# order to add your own items to the graph. Your block is passed the XmlMarkup
|
53
|
+
# object to use as well as the options hash in case you need to use some of
|
54
|
+
# that data.
|
55
|
+
def render
|
56
|
+
output = ""
|
57
|
+
xml = Builder::XmlMarkup.new(:target => output, :indent => @options[:indent])
|
58
|
+
|
59
|
+
# Output headers unless we specified otherwise
|
60
|
+
xml.instruct!
|
61
|
+
xml.declare! :DOCTYPE, :svg, :PUBLIC, "-//W3C//DTD SVG 1.1//EN", "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"
|
62
|
+
|
63
|
+
xml.svg(:viewBox => "0 0 #{@options[:viewbox][:width]} #{@options[:viewbox][:height]}",
|
64
|
+
:width => @options[:width], :height => @options[:height],
|
65
|
+
:xmlns => 'http://www.w3.org/2000/svg', :version => '1.1') do |xml|
|
66
|
+
|
67
|
+
xml.g(:fill => 'black', :stroke => 'black', 'stroke-width' => '2',
|
68
|
+
'font-family' => 'Helvetica, Arial, sans-serif', 'font-size' => '10px', 'font-weight' => 'medium') do |xml|
|
69
|
+
|
70
|
+
# Outline
|
71
|
+
xml.rect(:x => @options[:margin][:left], :y => @options[:margin][:top],
|
72
|
+
:width => graph_width,
|
73
|
+
:height => graph_height,
|
74
|
+
:fill => 'lightgray')
|
75
|
+
|
76
|
+
xml.g 'stroke-width' => '1' do |xml|
|
77
|
+
|
78
|
+
# Title
|
79
|
+
xml.text(@options[:title], 'font-size' => '24px', :x => (@options[:viewbox][:width] / 2.0).round, :y => (@options[:subtitle] ? 24 : 32), 'text-anchor' => 'middle') if @options[:title]
|
80
|
+
xml.text(@options[:subtitle], 'font-size' => '18px', :x => (@options[:viewbox][:width] / 2.0).round, :y => 34, 'text-anchor' => 'middle') if @options[:subtitle]
|
81
|
+
|
82
|
+
# Lines
|
83
|
+
xml.g 'font-size' => '10px' do |xml|
|
84
|
+
line_x1 = @options[:margin][:left] + 1
|
85
|
+
line_x2 = @options[:viewbox][:width] - @options[:margin][:right] - 1
|
86
|
+
|
87
|
+
text_x = @options[:margin][:left] - 25
|
88
|
+
|
89
|
+
xml.text 0, :x => text_x, :y => (@options[:viewbox][:height] - @options[:margin][:bottom] + 4), 'stroke-width' => 0.5
|
90
|
+
|
91
|
+
1.upto((max / 10) - 1) do |line_number|
|
92
|
+
y = (@options[:margin][:top] + (line_number * dy)).round
|
93
|
+
xml.line :x1 => line_x1, :y1 => y, :x2 => line_x2, :y2 => y, :stroke => '#666666'
|
94
|
+
xml.text max - line_number * 10, :x => text_x, :y => y + 4, 'stroke-width' => 0.5
|
95
|
+
|
96
|
+
# Smaller Line
|
97
|
+
xml.line(:x1 => line_x1, :y1 => y + (0.5 * dy), :x2 => line_x2, :y2 => y + (0.5 * dy), :stroke => '#999999') if max < 55
|
98
|
+
end
|
99
|
+
|
100
|
+
xml.text max, :x => text_x, :y => @options[:margin][:top] + 4, 'stroke-width' => 0.5
|
101
|
+
# Smaller Line
|
102
|
+
xml.line(:x1 => line_x1, :y1 => @options[:margin][:top] + (0.5 * dy), :x2 => line_x2, :y2 => @options[:margin][:top] + (0.5 * dy), :stroke => '#999999') if max < 55
|
103
|
+
end
|
104
|
+
|
105
|
+
# Labels
|
106
|
+
xml.g 'text-anchor' => 'end', 'font-size' => '12px', 'stroke-width' => 0.3 do |xml|
|
107
|
+
@labels.each_with_index do |label, index|
|
108
|
+
x = (@options[:margin][:left] + (dx * index) + (dx / 2.0)).round
|
109
|
+
y = @options[:viewbox][:height] - @options[:margin][:bottom] + 15
|
110
|
+
xml.text label, :x => x, :y => y, :transform => "rotate(-45 #{x} #{y})"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Bars
|
115
|
+
xml.g 'font-size' => '8px', 'stroke-width' => 0.3 do |xml|
|
116
|
+
@data.each_with_index do |data, data_index|
|
117
|
+
data = Array(data)
|
118
|
+
width = dx - @options[:padding]
|
119
|
+
bar_width = (width / Float(data.size)).round
|
120
|
+
|
121
|
+
x = (@options[:margin][:left] + (dx * data_index)).round
|
122
|
+
|
123
|
+
data.each_with_index do |number, number_index|
|
124
|
+
color = Color::HSL.from_fraction(data_index * (1.0 / @data.size),1.0, 0.4 + (number_index * 0.2)).to_rgb
|
125
|
+
height = ((dy / 10.0) * number).round
|
126
|
+
|
127
|
+
bar_x = (x + ((dx - width) / 2.0) + (number_index * bar_width)).round
|
128
|
+
text_x = (bar_x + (bar_width / 2.0)).round
|
129
|
+
|
130
|
+
bar_y = @options[:viewbox][:height] - @options[:margin][:bottom] - height
|
131
|
+
text_y = bar_y - 3
|
132
|
+
|
133
|
+
xml.rect :fill => color.html, :stroke => color.html, 'stroke-width' => 0, :x => bar_x, :width => bar_width, :y => bar_y, :height => height - 1
|
134
|
+
xml.text number, :x => text_x, :y => text_y, 'text-anchor' => 'middle'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Yield in case they want to do some custom drawing and have a block ready
|
140
|
+
yield xml, @options if block_given?
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
output
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def max
|
152
|
+
(((@data.map do |num|
|
153
|
+
num.respond_to?(:max) ? num.max : num
|
154
|
+
end.max + 5) / 10.0).ceil * 10).round
|
155
|
+
end
|
156
|
+
|
157
|
+
def graph_height
|
158
|
+
@options[:viewbox][:height] - (@options[:margin][:top] + @options[:margin][:bottom])
|
159
|
+
end
|
160
|
+
|
161
|
+
def graph_width
|
162
|
+
@options[:viewbox][:width] - (@options[:margin][:left] + @options[:margin][:right])
|
163
|
+
end
|
164
|
+
|
165
|
+
def number_of_slots
|
166
|
+
@data.size
|
167
|
+
end
|
168
|
+
|
169
|
+
def dx
|
170
|
+
700.0 / Float(number_of_slots)
|
171
|
+
end
|
172
|
+
|
173
|
+
def dy
|
174
|
+
4500.0 / Float(max)
|
175
|
+
end
|
176
|
+
end
|
data/lilygraph.gemspec
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{lilygraph}
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Christopher Giroir"]
|
12
|
+
s.date = %q{2009-08-19}
|
13
|
+
s.description = %q{Lilygraph is a Ruby library for creating svg charts and graphs based on XmlBuilder.}
|
14
|
+
s.email = %q{kelsin@valefor.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"LICENSE",
|
21
|
+
"README",
|
22
|
+
"VERSION",
|
23
|
+
"lib/lilygraph.rb",
|
24
|
+
"lilygraph.gemspec"
|
25
|
+
]
|
26
|
+
s.homepage = %q{http://github.com/Kelsin/lilygraph}
|
27
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
28
|
+
s.require_paths = ["lib"]
|
29
|
+
s.rubygems_version = %q{1.3.4}
|
30
|
+
s.summary = %q{Lilygraph is a Ruby library for creating svg charts and graphs based on XmlBuilder.}
|
31
|
+
|
32
|
+
if s.respond_to? :specification_version then
|
33
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
34
|
+
s.specification_version = 3
|
35
|
+
|
36
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
37
|
+
s.add_runtime_dependency(%q<builder>, [">= 2.1.2"])
|
38
|
+
s.add_runtime_dependency(%q<color-tools>, [">= 1.3.0"])
|
39
|
+
else
|
40
|
+
s.add_dependency(%q<builder>, [">= 2.1.2"])
|
41
|
+
s.add_dependency(%q<color-tools>, [">= 1.3.0"])
|
42
|
+
end
|
43
|
+
else
|
44
|
+
s.add_dependency(%q<builder>, [">= 2.1.2"])
|
45
|
+
s.add_dependency(%q<color-tools>, [">= 1.3.0"])
|
46
|
+
end
|
47
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: Kelsin-lilygraph
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Christopher Giroir
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-19 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: builder
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.1.2
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: color-tools
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.3.0
|
34
|
+
version:
|
35
|
+
description: Lilygraph is a Ruby library for creating svg charts and graphs based on XmlBuilder.
|
36
|
+
email: kelsin@valefor.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README
|
44
|
+
files:
|
45
|
+
- LICENSE
|
46
|
+
- README
|
47
|
+
- VERSION
|
48
|
+
- lib/lilygraph.rb
|
49
|
+
- lilygraph.gemspec
|
50
|
+
has_rdoc: false
|
51
|
+
homepage: http://github.com/Kelsin/lilygraph
|
52
|
+
licenses:
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options:
|
55
|
+
- --charset=UTF-8
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.3.5
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Lilygraph is a Ruby library for creating svg charts and graphs based on XmlBuilder.
|
77
|
+
test_files: []
|
78
|
+
|