rubyvis 0.4.1 → 0.5.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/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 0.5.0 / 2011-02-04
2
+ * Nokogiri used as XML builder. Fall back to REXML if nokogiri is not available or $rubyvis_no_nokogiri=true
3
+
4
+
1
5
  === 0.4.1 / 2011-01-26
2
6
  * All tests run on ruby 1.8.7. Not all pass, because on ruby<1.9 hash order are not preserved
3
7
  * Removed warnings for Ruby 1.9+
data/README.txt CHANGED
@@ -41,6 +41,8 @@ I try to maintain, when posible, complete compatibility with Javascript API, inc
41
41
 
42
42
  User could use +pv+ freely, cause is defined as a global method which call Rubyvis.
43
43
 
44
+ Nokogiri is used as XML library. If not available, or $rubyvis_no_nokogiri is set to true, REXML is used. Nokogiri is 30%-35% faster that REXML on our test.
45
+
44
46
  == CURRENT PROGRESS
45
47
 
46
48
  * pv.js
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ require 'hoe'
7
7
  require 'rubyvis'
8
8
  require 'rspec'
9
9
  require 'rspec/core/rake_task'
10
-
10
+ require 'rubyforge'
11
11
 
12
12
  Hoe.plugin :git
13
13
 
@@ -77,11 +77,17 @@ module Rubyvis
77
77
  end
78
78
 
79
79
  def to_svg
80
- @_canvas.sort.map {|v|
81
- bar = REXML::Formatters::Default.new
82
- out = String.new
83
- bar.write(v[1].elements[1], out)
84
- }.join
80
+ if Rubyvis.xml_engine==:nokogiri
81
+ @_canvas.sort.map {|v|
82
+ v[1].get_element(1).to_xml(:indent => 5, :encoding => 'UTF-8')
83
+ }.join
84
+ else
85
+ @_canvas.sort.map {|v|
86
+ bar = REXML::Formatters::Default.new
87
+ out = String.new
88
+ bar.write(v[1].elements[1], out)
89
+ }.join
90
+ end
85
91
  end
86
92
  def build_implied(s)
87
93
  panel_build_implied(s)
@@ -107,8 +113,15 @@ module Rubyvis
107
113
  @_canvas||={}
108
114
  cache=@_canvas
109
115
  if(!(c=cache[self.index]))
116
+
117
+ if Rubyvis.xml_engine==:nokogiri
118
+ document=Nokogiri::XML::Document.new
119
+ document.root=document.create_element('document')
120
+ Rubyvis.nokogiri_document(document)
121
+ else
110
122
  document=REXML::Document.new
111
- document.add_element("document")
123
+ document.add_element("document")
124
+ end
112
125
  cache[self.index]=document.root
113
126
  c=cache[self.index]
114
127
 
@@ -1,7 +1,8 @@
1
1
  module Rubyvis
2
2
  module SvgScene
3
3
  def self.area(scenes)
4
- e = scenes._g.elements[1]
4
+ #e = scenes._g.elements[1]
5
+ e=scenes._g.get_element(1)
5
6
  return e if scenes.size==0
6
7
  s=scenes[0]
7
8
  # segmented
@@ -127,7 +128,8 @@ module Rubyvis
127
128
  end
128
129
 
129
130
  def self.area_segment(scenes)
130
- e = scenes._g.elements[1]
131
+ e=scenes._g.get_element(1)
132
+ #e = scenes._g.elements[1]
131
133
  s = scenes[0]
132
134
  pathsT=nil
133
135
  pathsB=nil
@@ -1,13 +1,14 @@
1
1
  module Rubyvis
2
2
  module SvgScene
3
3
  def self.bar(scenes)
4
- e=scenes._g.elements[1]
4
+ #e=scenes._g.elements[1]
5
+ e=scenes._g.get_element(1)
5
6
  scenes.each_with_index do |s,i|
6
7
  next unless s.visible
7
8
  fill=s.fill_style
8
9
  stroke=s.stroke_style
9
10
  next if(fill.opacity==0 and stroke.opacity==0)
10
- e=SvgScene.expect(e,'rect', {
11
+ e=SvgScene.expect(e, 'rect', {
11
12
  "shape-rendering"=> s.antialias ? nil : "crispEdges",
12
13
  "pointer-events"=> s.events,
13
14
  "cursor"=> s.cursor,
@@ -1,7 +1,8 @@
1
1
  module Rubyvis
2
2
  module SvgScene
3
3
  def self.dot(scenes)
4
- e = scenes._g.elements[1]
4
+ #e = scenes._g.elements[1]
5
+ e=scenes._g.get_element(1)
5
6
  scenes.each_with_index {|s,i|
6
7
  s = scenes[i];
7
8
 
@@ -1,7 +1,8 @@
1
1
  module Rubyvis
2
2
  module SvgScene
3
3
  def self.image(scenes)
4
- e=scenes._g.elements[1]
4
+ #e=scenes._g.elements[1]
5
+ e=scenes._g.get_element(1)
5
6
  scenes.each_with_index do |s,i|
6
7
  next unless s.visible
7
8
  e=self.fill(e,scenes,i)
@@ -1,7 +1,8 @@
1
1
  module Rubyvis
2
2
  module SvgScene
3
3
  def self.label(scenes)
4
- e=scenes._g.elements[1]
4
+ #e=scenes._g.elements[1]
5
+ e=scenes._g.get_element(1)
5
6
  scenes.each_with_index do |s,i|
6
7
  next unless s.visible
7
8
  fill=s.text_style
@@ -1,7 +1,8 @@
1
1
  module Rubyvis
2
2
  module SvgScene
3
3
  def self.line(scenes)
4
- e=scenes._g.elements[1]
4
+ #e=scenes._g.elements[1]
5
+ e=scenes._g.get_element(1)
5
6
  return e if (scenes.size < 2)
6
7
  s = scenes[0]
7
8
  # segmented */
@@ -50,8 +51,8 @@ module Rubyvis
50
51
 
51
52
  def self.line_segment(scenes)
52
53
 
53
- e=scenes._g.elements[1]
54
-
54
+ #e=scenes._g.elements[1]
55
+ e=scenes._g.get_element(1)
55
56
  s = scenes[0];
56
57
  paths=nil
57
58
  case s.interpolate
@@ -3,44 +3,70 @@ module Rubyvis
3
3
  def self.panel(scenes)
4
4
  puts " -> panel: #{scenes.inspect}" if $DEBUG
5
5
  g=scenes._g
6
- e=(g.nil?) ? nil : g.elements[1]
6
+ #e=(g.nil?) ? nil : g.elements[1]
7
+ e=(g.nil?) ? nil : g.get_element(1)
7
8
  if g
8
- e=g.elements[1]
9
+ #e=g.elements[1]
10
+ e=g.get_element(1)
9
11
  end
10
12
  scenes.each_with_index do |s,i|
11
13
  next unless s.visible
12
14
 
13
15
  if(!scenes.parent)
14
16
  if g and g.parent!=s.canvas
15
- g=s.canvas.elements[1]
16
- e=(@g.nil?) ? nil : @g.elements[1]
17
+ #g=s.canvas.elements[1]
18
+ g=s.canvas.get_element(1)
19
+ #e=(@g.nil?) ? nil : @g.elements[1]
20
+ e=(@g.nil?) ? nil : @g.get_element(1)
17
21
  end
18
22
  if(!g)
19
23
  g=s.canvas.add_element(self.create('svg'))
20
- g.attributes["font-size"]="10px"
21
- g.attributes["font-family"]="sans-serif"
22
- g.attributes["fill"]="none"
23
- g.attributes["stroke"]="none"
24
- g.attributes["stroke-width"]=1.5
25
- e=g.elements[1]
24
+ g.set_attributes(
25
+ {
26
+ 'font-size'=>"10px",
27
+ 'font-family'=>'sans-serif',
28
+ 'fill'=>'none',
29
+ 'stroke'=>'none',
30
+ 'stroke-width'=>1.5
31
+ }
32
+ )
33
+ e=g.get_element(1)
34
+ # g.attributes["font-size"]="10px"
35
+ # g.attributes["font-family"]="sans-serif"
36
+ # g.attributes["fill"]="none"
37
+ # g.attributes["stroke"]="none"
38
+ # g.attributes["stroke-width"]=1.5
39
+ # e=g.elements[1]
26
40
  end
27
41
  scenes._g=g
28
42
  #p s
29
- g.attributes['width']=s.width+s.left+s.right
30
- g.attributes['height']=s.height+s.top+s.bottom
43
+ g.set_attributes({
44
+ 'width'=>s.width+s.left+s.right,
45
+ 'height'=>s.height+s.top+s.bottom
46
+ })
47
+ #g.attributes['width']=s.width+s.left+s.right
48
+ #g.attributes['height']=s.height+s.top+s.bottom
31
49
  end
32
50
  if s.overflow=='hidden'
33
51
  id=Rubyvis.id.to_s(36)
34
52
  c=self.expect(e,'g',{'clip-path'=>'url(#'+id+')'});
35
53
  g.add_element(c) if(!c.parent)
36
54
  scenes._g=g=c
37
- e=c.elements[1]
55
+ #e=c.elements[1]
56
+ e=c.get_element(1)
38
57
  e=self.expect(e,'clipPath',{'id'=>id})
39
- r=(e.elements[1]) ? e.elements[1] : e.add_element(self.create('rect'))
40
- r.attributes['x']=s.left
41
- r.attributes['y']=s.top
42
- r.attributes['width']=s.width
43
- r.attributes['height']=s.height
58
+ #r=(e.elements[1]) ? e.elements[1] : e.add_element(self.create('rect'))
59
+ r=(e.get_element(1)) ? e.get_element(1) : e.add_element(self.create('rect'))
60
+ r.set_attributes({
61
+ 'x'=>s.left,
62
+ 'y'=>s.top,
63
+ 'width'=>s.width,
64
+ 'height'=>s.height
65
+ })
66
+ #r.attributes['x']=s.left
67
+ #r.attributes['y']=s.top
68
+ #r.attributes['width']=s.width
69
+ #r.attributes['height']=s.height
44
70
  g.add_element(e) if !e.parent
45
71
  e=e.next_sibling_node
46
72
 
@@ -1,7 +1,8 @@
1
1
  module Rubyvis
2
2
  module SvgScene
3
3
  def self.rule(scenes)
4
- e=scenes._g.elements[1]
4
+ #e=scenes._g.elements[1]
5
+ e=scenes._g.get_element(1)
5
6
  scenes.each_with_index do |s,i|
6
7
  next unless s.visible
7
8
  stroke=s.stroke_style
@@ -11,6 +11,51 @@ require 'rubyvis/scene/svg_curve'
11
11
 
12
12
  class REXML::Element #:nodoc:
13
13
  attr_accessor :_scene
14
+ # 1 number based
15
+ def get_element(i)
16
+ elements[i]
17
+ end
18
+ def set_attributes(h)
19
+ h.each do |k,v|
20
+ attributes[k]=v
21
+ end
22
+ end
23
+ #private :attributes
24
+ #private :elements
25
+ end
26
+
27
+ module Nokogiri
28
+ module XML
29
+ class Node
30
+ attr_accessor :_scene
31
+ def add_element(c)
32
+ add_child(c)
33
+ end
34
+
35
+ def set_attributes(h)
36
+ h.each do |k,v|
37
+ set_attribute(k,v.to_s)
38
+ end
39
+ end
40
+ def get_element(i)
41
+ elements[i-1]
42
+ end
43
+ #private :elements
44
+ #private :attributes
45
+ def next_sibling_node
46
+ next_sibling
47
+ end
48
+ def delete_attribute(name)
49
+ remove_attribute(name)
50
+ end
51
+ def text
52
+ content
53
+ end
54
+ def text=(v)
55
+ self.content=v
56
+ end
57
+ end
58
+ end
14
59
  end
15
60
 
16
61
  module Rubyvis
@@ -67,11 +112,19 @@ module Rubyvis
67
112
  end
68
113
  end
69
114
  def self.create(type)
70
- el=REXML::Element.new "#{type}"
71
- if type=='svg'
72
- el.add_namespace(self.svg)
73
- #el.add_namespace("xmlns:xmlns", self.xmlns)
74
- el.add_namespace("xmlns:xlink", self.xlink)
115
+ if Rubyvis.xml_engine==:nokogiri
116
+ el=Rubyvis.nokogiri_document.create_element("#{type}")
117
+ if type=='svg'
118
+ el.add_namespace(nil, self.svg)
119
+ el.add_namespace('xlink', self.xlink)
120
+ end
121
+ else
122
+ el=REXML::Element.new "#{type}"
123
+ if type=='svg'
124
+ el.add_namespace(self.svg)
125
+ #el.add_namespace("xmlns:xmlns", self.xmlns)
126
+ el.add_namespace("xmlns:xlink", self.xlink)
127
+ end
75
128
  end
76
129
  el
77
130
  end
@@ -104,7 +157,9 @@ module Rubyvis
104
157
  e.parent.replace_child(a, e) if (e.parent)
105
158
  a.add_element(e)
106
159
  end
107
- a.add_attribute('xlink:title',s.title)
160
+ #a.add_attribute('xlink:title',s.title)
161
+ a.set_attributes('xlink:title' => s.title)
162
+
108
163
  return a;
109
164
  end
110
165
  a.parent_node.replace_child(e, a) if (a)
@@ -114,7 +169,8 @@ module Rubyvis
114
169
  def self.expect(e, type, attributes, style=nil)
115
170
 
116
171
  if (e)
117
- e = e.elements[1] if (e.name == "a")
172
+ #e = e.elements[1] if (e.name == "a")
173
+ e=e.get_element(1) if (e.name == 'a')
118
174
  if (e.name != type)
119
175
  n = self.create(type);
120
176
  e.parent.replace_child(e, n);
@@ -128,7 +184,8 @@ module Rubyvis
128
184
  if (value.nil?)
129
185
  e.delete_attribute(name)
130
186
  else
131
- e.attributes[name]=value
187
+ e.set_attributes(name=>value)
188
+ #e.attributes[name]=value
132
189
  end
133
190
  }
134
191
 
@@ -145,12 +202,12 @@ module Rubyvis
145
202
  if (value.nil?)
146
203
  array_styles.delete(name)
147
204
  else
148
-
149
205
  array_styles[name]=value
150
206
  end
151
207
  }
152
208
  if array_styles.size>0
153
- e.attributes["style"]=array_styles.map {|k,v| "#{k}:#{v}"}.join(";")
209
+ #e.attributes["style"]=array_styles.map {|k,v| "#{k}:#{v}"}.join(";")
210
+ e.set_attributes('style'=> array_styles.map {|k,v| "#{k}:#{v}"}.join(";"))
154
211
  end
155
212
  end
156
213
  e
@@ -1,7 +1,8 @@
1
1
  module Rubyvis
2
2
  module SvgScene
3
3
  def self.wedge(scenes)
4
- e=scenes._g.elements[1]
4
+ #e=scenes._g.elements[1]
5
+ e=scenes._g.get_element(1)
5
6
  scenes.each_with_index do |s,i|
6
7
  next unless s.visible
7
8
  fill=s.fill_style
data/lib/rubyvis.rb CHANGED
@@ -28,11 +28,13 @@ require 'rubyvis/scene/svg_scene'
28
28
  require 'rubyvis/transform'
29
29
  require 'rubyvis/mark/shorcut_methods'
30
30
 
31
-
31
+ # = Rubyvis
32
+ # Ruby port of Protovis
33
+ #
32
34
  module Rubyvis
33
- @document=nil
35
+ @@nokogiri=nil
34
36
  # Rubyvis version
35
- VERSION = '0.4.1'
37
+ VERSION = '0.5.0'
36
38
  # Protovis API on which current Rubyvis is based
37
39
  PROTOVIS_API_VERSION='3.3'
38
40
  # You actually can do it! http://snipplr.com/view/2137/uses-for-infinity-in-ruby/
@@ -50,7 +52,33 @@ module Rubyvis
50
52
  def self.identity
51
53
  lambda {|x,*args| x}
52
54
  end
55
+ def self.has_nokogiri?
56
+ if @@nokogiri.nil?
57
+ begin
58
+ require 'nokogiri'
59
+ @@nokogiri=true
60
+ rescue LoadError
61
+ @@nokogiri=false
62
+ end
63
+ end
64
+ @@nokogiri
65
+ end
66
+ def self.xml_engine
67
+ if has_nokogiri? and !$rubyvis_no_nokogiri
68
+ :nokogiri
69
+ else
70
+ puts "rexml"
71
+ :rexml
72
+ end
73
+ end
74
+
53
75
 
76
+ def self.nokogiri_document(v=nil)
77
+ if !v.nil?
78
+ @@nokogiri_document=v
79
+ end
80
+ @@nokogiri_document
81
+ end
54
82
  # Returns <tt>self.index</tt>. This method is provided for convenience for use
55
83
  # with scales. For example, to color bars by their index, say:
56
84
  #
@@ -1,5 +1,5 @@
1
1
  require File.expand_path(File.dirname(__FILE__)+"/spec_helper.rb")
2
- describe "Ruby API for Rubyvis" do
2
+ shared_examples_for "Ruby API for Rubyvis" do
3
3
  before do
4
4
  @h=200
5
5
  @w=200
@@ -44,4 +44,27 @@ describe "Ruby API for Rubyvis" do
44
44
  svg1.should==svg2
45
45
 
46
46
  end
47
- end
47
+ end
48
+
49
+ describe "Rubyvis with REXML" do
50
+ before(:all) do
51
+ $rubyvis_no_nokogiri=true
52
+ end
53
+ after(:all) do
54
+ $rubyvis_no_nokogiri=false
55
+ end
56
+ it_should_behave_like "Ruby API for Rubyvis"
57
+ end
58
+
59
+ if Rubyvis.has_nokogiri?
60
+ describe "Rubyvis with Nokogiri" do
61
+
62
+ before(:all) do
63
+ $rubyvis_no_nokogiri=false
64
+ end
65
+
66
+ it_should_behave_like "Ruby API for Rubyvis"
67
+
68
+
69
+ end
70
+ end
data/spec/spec_helper.rb CHANGED
@@ -94,6 +94,7 @@ end
94
94
  RSpec::Matchers.define :have_svg_attributes do |exp|
95
95
  match do |obs|
96
96
  exp.each {|k,v|
97
+ obs.attributes[k].should be_true
97
98
  obs.attributes[k].value.should==v
98
99
  }
99
100
  end
@@ -193,7 +194,7 @@ Rspec::Matchers.define :have_same_svg_elements do |exp|
193
194
  correct
194
195
  end
195
196
  failure_message_for_should do |obs|
196
- "#{@error[:type]}: #{@error[:exp].to_s} expected, but #{@error[:obs]} retrieved, on attr #{@error[:attr]} -> #{@error[:i]} : #{@error[:exp_attr]} <> #{@error[:obs_attr]}"
197
+ "#{@error[:type]}: #{@error[:exp].to_s} expected, but #{@error[:obs]} retrieved, on #{@error[:attr]} -> #{@error[:i]} : '#{@error[:exp_attr]}' <> '#{@error[:obs_attr]}'"
197
198
  end
198
199
 
199
200
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 4
8
- - 1
9
- version: 0.4.1
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Claudio Bustos
@@ -35,7 +35,7 @@ cert_chain:
35
35
  rpP0jjs0
36
36
  -----END CERTIFICATE-----
37
37
 
38
- date: 2011-01-26 00:00:00 -03:00
38
+ date: 2011-02-04 00:00:00 -03:00
39
39
  default_executable:
40
40
  dependencies:
41
41
  - !ruby/object:Gem::Dependency
metadata.gz.sig CHANGED
Binary file