rubyvis 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/History.txt +3 -0
- data/Manifest.txt +44 -0
- data/README.txt +64 -0
- data/Rakefile +16 -0
- data/examples/crimea-line.rb +64 -0
- data/examples/first.rb +17 -0
- data/examples/second.rb +14 -0
- data/lib/rubyvis.rb +43 -0
- data/lib/rubyvis/color/color.rb +241 -0
- data/lib/rubyvis/color/colors.rb +40 -0
- data/lib/rubyvis/color/ramp.rb +0 -0
- data/lib/rubyvis/format.rb +19 -0
- data/lib/rubyvis/format/date.rb +18 -0
- data/lib/rubyvis/format/number.rb +31 -0
- data/lib/rubyvis/internals.rb +215 -0
- data/lib/rubyvis/javascript_behaviour.rb +64 -0
- data/lib/rubyvis/label.rb +0 -0
- data/lib/rubyvis/mark.rb +528 -0
- data/lib/rubyvis/mark/anchor.rb +22 -0
- data/lib/rubyvis/mark/area.rb +34 -0
- data/lib/rubyvis/mark/bar.rb +23 -0
- data/lib/rubyvis/mark/label.rb +17 -0
- data/lib/rubyvis/mark/line.rb +14 -0
- data/lib/rubyvis/mark/panel.rb +87 -0
- data/lib/rubyvis/mark/rule.rb +28 -0
- data/lib/rubyvis/scale.rb +34 -0
- data/lib/rubyvis/scale/linear.rb +5 -0
- data/lib/rubyvis/scale/ordinal.rb +52 -0
- data/lib/rubyvis/scale/quantitative.rb +263 -0
- data/lib/rubyvis/scene/svg_bar.rb +31 -0
- data/lib/rubyvis/scene/svg_label.rb +51 -0
- data/lib/rubyvis/scene/svg_panel.rb +117 -0
- data/lib/rubyvis/scene/svg_rule.rb +29 -0
- data/lib/rubyvis/scene/svg_scene.rb +118 -0
- data/lib/rubyvis/sceneelement.rb +44 -0
- data/lib/rubyvis/transform.rb +25 -0
- data/spec/internal_spec.rb +146 -0
- data/spec/javascript_behaviour_spec.rb +64 -0
- data/spec/panel_spec.rb +8 -0
- data/spec/scale_linear_spec.rb +121 -0
- data/spec/scale_spec.rb +8 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +27 -0
- metadata +160 -0
- metadata.gz.sig +2 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rubyvis
|
2
|
+
module SvgScene
|
3
|
+
def self.bar(scenes)
|
4
|
+
e=scenes._g.elements[1]
|
5
|
+
scenes.each_with_index do |s,i|
|
6
|
+
next unless s.visible
|
7
|
+
fill=s.fill_style
|
8
|
+
stroke=s.stroke_style
|
9
|
+
next if(!fill.opacity and !stroke.opacity)
|
10
|
+
e=SvgScene.expect(e,'rect', {
|
11
|
+
"shape-rendering"=> s.antialias ? nil : "crispEdges",
|
12
|
+
"pointer-events"=> s.events,
|
13
|
+
"cursor"=> s.cursor,
|
14
|
+
"x"=> s.left,
|
15
|
+
"y"=> s.top,
|
16
|
+
"width"=> [1E-10, s.width].max,
|
17
|
+
"height"=> [1E-10, s.height].max,
|
18
|
+
"fill"=> fill.color,
|
19
|
+
"fill-opacity"=> (fill.opacity==0) ? nil : fill.opacity,
|
20
|
+
"stroke"=> stroke.color,
|
21
|
+
"stroke-opacity"=> (stroke.opacity==0) ? nil : stroke.opacity,
|
22
|
+
"stroke-width"=> stroke.opacity ? s.line_width / SvgScene.scale.to_f : nil
|
23
|
+
})
|
24
|
+
|
25
|
+
e=SvgScene.append(e,scenes,i)
|
26
|
+
|
27
|
+
end
|
28
|
+
e
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Rubyvis
|
2
|
+
module SvgScene
|
3
|
+
def self.label(scenes)
|
4
|
+
e=scenes._g.elements[1]
|
5
|
+
scenes.each_with_index do |s,i|
|
6
|
+
next unless s.visible
|
7
|
+
fill=s.text_style
|
8
|
+
next if(fill.opacity==0 or s.text.nil?)
|
9
|
+
x=0
|
10
|
+
y=0
|
11
|
+
dy=0
|
12
|
+
anchor='start'
|
13
|
+
case s.text_baseline
|
14
|
+
when 'middle'
|
15
|
+
dy=".35em"
|
16
|
+
when "top"
|
17
|
+
dy = ".71em"; y = s.text_margin
|
18
|
+
when "bottom"
|
19
|
+
y = "-" + s.text_margin.to_s
|
20
|
+
end
|
21
|
+
case s.text_align
|
22
|
+
when 'rigth'
|
23
|
+
anchor = "end"; x = "-" + s.text_margin.to_s
|
24
|
+
when "center"
|
25
|
+
anchor = "middle"
|
26
|
+
|
27
|
+
when "left"
|
28
|
+
x = s.text_margin
|
29
|
+
end
|
30
|
+
e=SvgScene.expect(e,'text', {
|
31
|
+
"pointer-events"=> s.events,
|
32
|
+
"cursor"=> s.cursor,
|
33
|
+
"x"=> x,
|
34
|
+
"y"=> y,
|
35
|
+
"dy"=> dy,
|
36
|
+
"transform"=> "translate(" + s.left.to_s + "," + s.top.to_s + ")" + (s.text_angle ? " rotate(" + (180 * s.text_angle / Math::PI).to_s + ")" : "") + (self.scale != 1 ? " scale(" + 1 / self.scale + ")" : ""),
|
37
|
+
"fill"=> fill.color,
|
38
|
+
"fill-opacity"=> fill.opacity || nil,
|
39
|
+
"text-anchor"=> anchor
|
40
|
+
}, {
|
41
|
+
"font"=> s.font, "text-shadow"=> s.text_shadow, "text-decoration"=> s.text_decoration })
|
42
|
+
e.text=s.text
|
43
|
+
|
44
|
+
|
45
|
+
e=SvgScene.append(e,scenes,i)
|
46
|
+
|
47
|
+
end
|
48
|
+
e
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Rubyvis
|
2
|
+
module SvgScene
|
3
|
+
def self.panel(scenes)
|
4
|
+
g=scenes._g
|
5
|
+
e=(@g.nil?) ? nil : @g.elements[1]
|
6
|
+
if g
|
7
|
+
e=g.elements[0]
|
8
|
+
end
|
9
|
+
scenes.each_with_index do |s,i|
|
10
|
+
next unless s.visible
|
11
|
+
|
12
|
+
if(!scenes.parent)
|
13
|
+
if g and g.parent!=s.canvas
|
14
|
+
g=s.canvas.elements[1]
|
15
|
+
e=(@g.nil?) ? nil : @g.elements[1]
|
16
|
+
end
|
17
|
+
if(!g)
|
18
|
+
g=s.canvas.add_element(self.create('svg'))
|
19
|
+
g.attributes["font-size"]="10px"
|
20
|
+
g.attributes["font-family"]="sans-serif"
|
21
|
+
g.attributes["fill"]="none"
|
22
|
+
g.attributes["stroke"]="none"
|
23
|
+
g.attributes["stroke-width"]=1.5
|
24
|
+
e=g.elements[1]
|
25
|
+
end
|
26
|
+
scenes._g=g
|
27
|
+
#p s
|
28
|
+
g.attributes['width']=s.width+s.left+s.right
|
29
|
+
g.attributes['height']=s.height+s.top+s.bottom
|
30
|
+
end
|
31
|
+
if s.overflow=='hidden'
|
32
|
+
id=Rubyvis.id.to_s(36)
|
33
|
+
c=self.expect(e,'g',{'clip-path'=>'url(#'+id+')'});
|
34
|
+
g.add_element(c) if(!c.parent)
|
35
|
+
scenes._g=g=c
|
36
|
+
e=c.elements[1]
|
37
|
+
e=self.expect(e,'clipPath',{'id'=>id})
|
38
|
+
r=(e.elements[1]) ? e.elements[1] : e.add_element(self.create('rect'))
|
39
|
+
r.attributes['x']=s.left
|
40
|
+
r.attributes['y']=s.top
|
41
|
+
r.attributes['width']=s.width
|
42
|
+
r.attributes['height']=s.height
|
43
|
+
g.add_element(e) if !e.parent
|
44
|
+
e=e.next_sibling_node
|
45
|
+
|
46
|
+
end
|
47
|
+
e=self.fill(e,scenes, i)
|
48
|
+
k=self.scale
|
49
|
+
t=s.transform
|
50
|
+
|
51
|
+
x=s.left+t.x
|
52
|
+
y=s.top+t.y
|
53
|
+
|
54
|
+
|
55
|
+
SvgScene.scale=SvgScene.scale*t.k
|
56
|
+
s.children.each_with_index {|child, i|
|
57
|
+
child._g=e=SvgScene.expect(e, "g", {
|
58
|
+
"transform"=> "translate(" + x.to_s + "," + y.to_s + ")" + (t.k != 1 ? " scale(" + t.k.to_s + ")" : "")
|
59
|
+
})
|
60
|
+
SvgScene.update_all(child)
|
61
|
+
g.add_element(e) if(!e.parent)
|
62
|
+
e=e.next_sibling_node
|
63
|
+
}
|
64
|
+
SvgScene.scale=k
|
65
|
+
e=SvgScene.stroke(e,scenes,i)
|
66
|
+
|
67
|
+
return e
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
def self.fill(e,scenes,i)
|
74
|
+
s=scenes[i]
|
75
|
+
fill=s.fill_style
|
76
|
+
if(fill.opacity>0 or s.events=='all')
|
77
|
+
e=SvgScene.expect(e,'rect', {
|
78
|
+
"shape-rendering"=> s.antialias ? nil : "crispEdges",
|
79
|
+
"pointer-events"=> s.events,
|
80
|
+
"cursor"=> s.cursor,
|
81
|
+
"x"=> s.left,
|
82
|
+
"y"=> s.top,
|
83
|
+
"width"=> s.width,
|
84
|
+
"height"=> s.height,
|
85
|
+
"fill"=> fill.color,
|
86
|
+
"fill-opacity"=> fill.opacity,
|
87
|
+
"stroke"=> nil
|
88
|
+
})
|
89
|
+
e=SvgScene.append(e,scenes, i)
|
90
|
+
end
|
91
|
+
e
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def self.stroke(e, scenes, i)
|
96
|
+
s = scenes[i]
|
97
|
+
stroke = s.stroke_style
|
98
|
+
if (stroke.opacity>0 or s.events == "all")
|
99
|
+
e = self.expect(e, "rect", {
|
100
|
+
"shape-rendering"=> s.antialias ? nil : "crispEdges",
|
101
|
+
"pointer-events"=> s.events == "all" ? "stroke" : s.events,
|
102
|
+
"cursor"=> s.cursor,
|
103
|
+
"x"=> s.left,
|
104
|
+
"y"=> s.top,
|
105
|
+
"width"=> [1E-10, s.width].max,
|
106
|
+
"height"=>[1E-10, s.height].max,
|
107
|
+
"fill"=>nil,
|
108
|
+
"stroke"=> stroke.color,
|
109
|
+
"stroke-opacity"=> stroke.opacity,
|
110
|
+
"stroke-width"=> s.line_width / self.scale.to_f
|
111
|
+
});
|
112
|
+
e = self.append(e, scenes, i);
|
113
|
+
end
|
114
|
+
return e
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Rubyvis
|
2
|
+
module SvgScene
|
3
|
+
def self.rule(scenes)
|
4
|
+
e=scenes._g.elements[1]
|
5
|
+
scenes.each_with_index do |s,i|
|
6
|
+
next unless s.visible
|
7
|
+
stroke=s.stroke_style
|
8
|
+
|
9
|
+
next if(!stroke.opacity)
|
10
|
+
e=SvgScene.expect(e,'line', {
|
11
|
+
"shape-rendering"=> s.antialias ? nil : "crispEdges",
|
12
|
+
"pointer-events"=> s.events,
|
13
|
+
"cursor"=> s.cursor,
|
14
|
+
"x1"=> s.left,
|
15
|
+
"y1"=> s.top,
|
16
|
+
'x2'=> s.left+s.width,
|
17
|
+
'y2'=>s.top+s.height,
|
18
|
+
"stroke"=> stroke.color,
|
19
|
+
"stroke-opacity"=> stroke.opacity,
|
20
|
+
"stroke-width"=> s.line_width/self.scale.to_f
|
21
|
+
})
|
22
|
+
|
23
|
+
e=SvgScene.append(e,scenes,i)
|
24
|
+
|
25
|
+
end
|
26
|
+
e
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'rubyvis/scene/svg_panel'
|
2
|
+
require 'rubyvis/scene/svg_bar'
|
3
|
+
require 'rubyvis/scene/svg_rule'
|
4
|
+
require 'rubyvis/scene/svg_label'
|
5
|
+
|
6
|
+
class REXML::Element
|
7
|
+
attr_accessor :_scene
|
8
|
+
end
|
9
|
+
|
10
|
+
module Rubyvis
|
11
|
+
def self.Scene
|
12
|
+
Rubyvis::SvgScene
|
13
|
+
end
|
14
|
+
module SvgScene
|
15
|
+
include REXML
|
16
|
+
def self.svg
|
17
|
+
"http://www.w3.org/2000/svg"
|
18
|
+
end;
|
19
|
+
def self.xmlns
|
20
|
+
"http://www.w3.org/2000/xmlns"
|
21
|
+
end
|
22
|
+
def self.xlink
|
23
|
+
"http://www.w3.org/1999/xlink"
|
24
|
+
end
|
25
|
+
def self.xhtml
|
26
|
+
"http://www.w3.org/1999/xhtml"
|
27
|
+
end
|
28
|
+
@scale=1
|
29
|
+
def self.scale
|
30
|
+
@scale
|
31
|
+
end
|
32
|
+
def self.scale=(v)
|
33
|
+
@scale=v
|
34
|
+
end
|
35
|
+
def self.implicit
|
36
|
+
svg={
|
37
|
+
"shape-rendering"=> "auto",
|
38
|
+
"pointer-events"=> "painted",
|
39
|
+
"x"=> 0,
|
40
|
+
"y"=> 0,
|
41
|
+
"dy"=> 0,
|
42
|
+
"text-anchor"=> "start",
|
43
|
+
"transform"=> "translate(0,0)",
|
44
|
+
"fill"=> "none",
|
45
|
+
"fill-opacity"=> 1,
|
46
|
+
"stroke"=> "none",
|
47
|
+
"stroke-opacity"=> 1,
|
48
|
+
"stroke-width"=> 1.5,
|
49
|
+
"stroke-linejoin"=> "miter"
|
50
|
+
}
|
51
|
+
css={"font"=>"10px sans-serif"}
|
52
|
+
|
53
|
+
{:svg=>svg,:css=>css}
|
54
|
+
end
|
55
|
+
def self.update_all(scenes)
|
56
|
+
if (scenes.size>0 and scenes[0].reverse and scenes.type!='line' and scenes.type!='area')
|
57
|
+
scenes=scenes.reverse
|
58
|
+
end
|
59
|
+
|
60
|
+
self.remove_siblings(self.send(scenes.type, scenes))
|
61
|
+
end
|
62
|
+
def self.remove_siblings(e)
|
63
|
+
while(e)
|
64
|
+
n=e.next_sibling_node
|
65
|
+
e.remove
|
66
|
+
e=n
|
67
|
+
end
|
68
|
+
end
|
69
|
+
def self.create(type)
|
70
|
+
el=Element.new "#{type}"
|
71
|
+
#el.add_namespace('svg',self.svg)
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.append(e,scenes,index)
|
75
|
+
e._scene=OpenStruct.new({:scenes=>scenes, :index=>index})
|
76
|
+
#e=self.title
|
77
|
+
|
78
|
+
if(!e.parent)
|
79
|
+
scenes._g.add_element(e)
|
80
|
+
end
|
81
|
+
return e.next_sibling_node
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.expect(e, type, attributes, style=nil)
|
85
|
+
|
86
|
+
if (e)
|
87
|
+
e = e.elements[1] if (e.name == "a")
|
88
|
+
if (e.name != type)
|
89
|
+
n = self.create(type);
|
90
|
+
e.parent.replace_child(e, n);
|
91
|
+
e = n
|
92
|
+
end
|
93
|
+
else
|
94
|
+
e = self.create(type)
|
95
|
+
end
|
96
|
+
attributes.each {|name,value|
|
97
|
+
value = nil if (value == self.implicit[:svg][name])
|
98
|
+
if (value.nil?)
|
99
|
+
e.delete_attribute(name)
|
100
|
+
else
|
101
|
+
e.attributes[name]=value
|
102
|
+
end
|
103
|
+
}
|
104
|
+
if(style)
|
105
|
+
style.each {|name,value|
|
106
|
+
value=nil if value==self.implicit[:css][name]
|
107
|
+
if (value.nil?)
|
108
|
+
e.delete_attribute(name)
|
109
|
+
else
|
110
|
+
e.style[name] = value;
|
111
|
+
end
|
112
|
+
}
|
113
|
+
end
|
114
|
+
e
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Rubyvis
|
2
|
+
class SceneElement
|
3
|
+
def initialize
|
4
|
+
@scenes=Array.new
|
5
|
+
end
|
6
|
+
include Enumerable
|
7
|
+
attr_accessor :visible
|
8
|
+
attr_accessor :mark, :type, :child_index, :parent, :parent_index, :target, :defs, :data, :antialias, :line_width, :fill_style, :overflow, :width, :height, :top, :bottom, :left, :right, :title, :reverse, :stroke_style, :transform, :canvas, :_g, :events, :cursor, :children, :id, :segmented, :interpolate, :tension, :name, :text_baseline, :text_align, :text, :font, :text_angle, :text_style, :text_margin, :text_decoration, :text_shadow
|
9
|
+
def []=(v,i)
|
10
|
+
if v.is_a? Numeric
|
11
|
+
@scenes[v]=i
|
12
|
+
elsif self.respond_to?(v.to_s+"=")
|
13
|
+
self.send(v.to_s+"=",i)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
def [](v)
|
17
|
+
if v.is_a? Numeric
|
18
|
+
@scenes[v]
|
19
|
+
elsif self.respond_to? v
|
20
|
+
self.send(v)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
def each
|
24
|
+
@scenes.each do |v|
|
25
|
+
yield v
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def push(v)
|
29
|
+
@scenes.push(v)
|
30
|
+
end
|
31
|
+
def size
|
32
|
+
@scenes.size
|
33
|
+
end
|
34
|
+
def size=(v)
|
35
|
+
if self.size==v
|
36
|
+
return true
|
37
|
+
elsif self.size<v
|
38
|
+
(v-self.size).times {push(nil)}
|
39
|
+
else
|
40
|
+
self.slice!(0,v)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Rubyvis
|
2
|
+
def self.Transform
|
3
|
+
Rubyvis::Transform
|
4
|
+
end
|
5
|
+
class Transform
|
6
|
+
attr_accessor :k,:x,:y
|
7
|
+
def initialize
|
8
|
+
@k=1
|
9
|
+
@x=0
|
10
|
+
@y=0
|
11
|
+
end
|
12
|
+
def translate(x,y)
|
13
|
+
v=Transform.new
|
14
|
+
v.k=self.k
|
15
|
+
v.x=self.k*x+self.x
|
16
|
+
v.y=self.k*y+self.y
|
17
|
+
v
|
18
|
+
|
19
|
+
end
|
20
|
+
def self.identity
|
21
|
+
Transform.new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require File.dirname(__FILE__)+"/spec_helper.rb"
|
2
|
+
describe "Rubyvis module methods" do
|
3
|
+
describe "from pv.js" do
|
4
|
+
it "method identify should always return the same value" do
|
5
|
+
f=Rubyvis.identity
|
6
|
+
a="a"
|
7
|
+
f.js_call(a, 5).should==5
|
8
|
+
end
|
9
|
+
it "method index should return index method from a object" do
|
10
|
+
o1=Rubyvis.o_index(1)
|
11
|
+
o2=Rubyvis.o_index(10)
|
12
|
+
Rubyvis.index.js_call(o1,1,2).should==1
|
13
|
+
Rubyvis.index.js_call(o2,1,2).should==10
|
14
|
+
end
|
15
|
+
end
|
16
|
+
describe "from pv-internal.js" do
|
17
|
+
it "should create a infinite succesion with id" do
|
18
|
+
f=Rubyvis.id
|
19
|
+
Rubyvis.id.should==f+1
|
20
|
+
end
|
21
|
+
it "should return a lambda with functor" do
|
22
|
+
Rubyvis.functor(5).call.should==5
|
23
|
+
end
|
24
|
+
end
|
25
|
+
describe "from data/Arrays.js" do
|
26
|
+
it "map method should map an array using a index based object" do
|
27
|
+
f=lambda {|d| "#{self.index}-#{d}"}
|
28
|
+
i=%w{a b c}
|
29
|
+
o=%w{0-a 1-b 2-c}
|
30
|
+
Rubyvis.map(i).should==i
|
31
|
+
Rubyvis.map(i,f).should==o
|
32
|
+
end
|
33
|
+
it "repeat method should repeat the specified array n times" do
|
34
|
+
Rubyvis.repeat([1,2]).should==[1,2,1,2]
|
35
|
+
Rubyvis.repeat([1,2],3).should==[1,2,1,2,1,2]
|
36
|
+
end
|
37
|
+
it "cross method should return an array of all posible pairs of element" do
|
38
|
+
Rubyvis.cross([1,2],[3,4]).should==[[1,3],[1,4],[2,3],[2,4]]
|
39
|
+
end
|
40
|
+
it "blend method should concatenates the arrays into a single array" do
|
41
|
+
Rubyvis.blend([[1,2,3],[4,5,6],[7,8,9]]).should==(1..9).to_a
|
42
|
+
end
|
43
|
+
it "transpose method should returns a transposed array of arrays" do
|
44
|
+
Rubyvis.transpose([[1,2,3],[4,5,6]]).should==[[1,4],[2,5],[3,6]]
|
45
|
+
end
|
46
|
+
it "normalize method should returns a normalized copy of array" do
|
47
|
+
Rubyvis.normalize([1,1,3]).should==[0.2,0.2,0.6]
|
48
|
+
a=%w{aa ccc ddddd}
|
49
|
+
f=lambda {|e| e.size}
|
50
|
+
Rubyvis.normalize(a,f).should==[0.2,0.3,0.5]
|
51
|
+
end
|
52
|
+
it "permute method allows to permute the order of elements" do
|
53
|
+
Rubyvis.permute(%w{a b c},[1,2,0]).should==%w{b c a}
|
54
|
+
f=lambda {|e| [self.index,e]}
|
55
|
+
Rubyvis.permute(%w{a b c},[1,2,0],f).should==[[1,"b"],[2,"c"],[0,"a"]]
|
56
|
+
end
|
57
|
+
it "numerate should map from key to index for the specified keys array" do
|
58
|
+
Rubyvis.numerate(["a", "b", "c"]).should=={"a"=>0,"b"=>1,"c"=>2}
|
59
|
+
end
|
60
|
+
it "method uniq returns the unique elements in the specified array" do
|
61
|
+
Rubyvis.uniq(["a", "b", "c","c"]).should==["a","b","c"]
|
62
|
+
Rubyvis.uniq(["a", "b", "c","c"], lambda{|e| e*2}).should==["aa","bb","cc"]
|
63
|
+
end
|
64
|
+
it "method search should return correct values" do
|
65
|
+
a=(0..9).to_a
|
66
|
+
Rubyvis.search(a,1).should==1
|
67
|
+
Rubyvis.search(a,20).should==-11
|
68
|
+
Rubyvis.search(a,5.5).should==-7
|
69
|
+
end
|
70
|
+
it "method search_index should return correct values" do
|
71
|
+
a=(0..9).to_a
|
72
|
+
Rubyvis.search_index(a,1).should==1
|
73
|
+
Rubyvis.search_index(a,20).should==10
|
74
|
+
Rubyvis.search_index(a,5.5).should==6
|
75
|
+
end
|
76
|
+
end
|
77
|
+
describe "from data/Numbers.js" do
|
78
|
+
it "method range should create range of numbers" do
|
79
|
+
Rubyvis.range(1,10).should==[1,2,3,4,5,6,7,8,9]
|
80
|
+
Rubyvis.range(1,10,0.5).should==[1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5,7,7.5,8,8.5,9,9.5]
|
81
|
+
Rubyvis.range(1,10,3).should==[1,4,7]
|
82
|
+
lambda {Rubyvis.range(1,10,0)}.should raise_exception
|
83
|
+
end
|
84
|
+
it "method random returns a random number between values" do
|
85
|
+
srand(10)
|
86
|
+
100.times.map{ Rubyvis.random(5)}.uniq.sort.should==(0..4).to_a
|
87
|
+
100.times.map{ Rubyvis.random(1,5)}.uniq.sort.should==(1..4).to_a
|
88
|
+
100.times.map{ Rubyvis.random(1,3,0.5)}.uniq.sort.should== [1.0,1.5,2.0,2.5]
|
89
|
+
end
|
90
|
+
it "methods sum returns a sum" do
|
91
|
+
Rubyvis.sum([1,2,3,4]).should==(1+2+3+4)
|
92
|
+
Rubyvis.sum(%w{1 4 3 2 5}, lambda {|v| v.to_i * self.index}).should==(4*1 + 3*2 + 2*3 + 5*4)
|
93
|
+
end
|
94
|
+
it "method max returns maximum value" do
|
95
|
+
Rubyvis.max([1,2,3,4]).should==4
|
96
|
+
Rubyvis.max([1,2,3,4], Rubyvis.index).should==3
|
97
|
+
Rubyvis.max(%w{1 4 3 2 5}, lambda {|v| v.to_i * self.index}).should==20
|
98
|
+
end
|
99
|
+
it "method max_index returns maximum value index" do
|
100
|
+
Rubyvis.max_index([1,2,4,3]).should==2
|
101
|
+
Rubyvis.max_index(%w{1 4 3 2 5}, lambda {|v| v.to_i * self.index}).should==4
|
102
|
+
end
|
103
|
+
it "method min returns minimum value" do
|
104
|
+
Rubyvis.min([1,2,3,4]).should==1
|
105
|
+
Rubyvis.min([1,2,3,4], Rubyvis.index).should==0
|
106
|
+
Rubyvis.min(%w{2 0 3 2 5}, lambda {|v| v.to_i + self.index}).should==1
|
107
|
+
end
|
108
|
+
it "method min_index returns minimum value index" do
|
109
|
+
Rubyvis.min_index([1,2,4,-1]).should==3
|
110
|
+
Rubyvis.min_index(%w{1 4 3 2 5}, lambda {|v| v.to_i * self.index}).should==0
|
111
|
+
end
|
112
|
+
it "method mean returns mean of values" do
|
113
|
+
a,b,c,d=rand,rand,rand,rand
|
114
|
+
#Rubyvis.mean([a,b,c,d]).should==(a+b+c+d).quo(4)
|
115
|
+
Rubyvis.mean([a,b,c,d].map {|x| x.to_s}, lambda {|v| v.to_f+1}).should==(a+b+c+d).quo(4)+1
|
116
|
+
end
|
117
|
+
it "method median returns median of values" do
|
118
|
+
Rubyvis.median([1,2,4,3]).should==2.5
|
119
|
+
Rubyvis.median([1,3,2,5,3]).should==3
|
120
|
+
Rubyvis.median([1,3,2,5,3].map(&:to_s), lambda(&:to_f)).should==3
|
121
|
+
end
|
122
|
+
it "method variance returns sum of squares" do
|
123
|
+
Rubyvis.variance([5,7,9,11]).should==20
|
124
|
+
Rubyvis.variance([5,7,9,11], lambda {|x| x+self.index}).should==45
|
125
|
+
end
|
126
|
+
it "method deviation returns standard deviation" do
|
127
|
+
Rubyvis.deviation([5,7,9,11]).should be_close(2.581, 0.001)
|
128
|
+
end
|
129
|
+
it "method log" do
|
130
|
+
Rubyvis.log(5,4).should be_close(1.16, 0.001)
|
131
|
+
end
|
132
|
+
it "method log_symmetric" do
|
133
|
+
Rubyvis.log_symmetric(-5,4).should be_close(-1.16, 0.001)
|
134
|
+
end
|
135
|
+
it "method log_adjusted" do
|
136
|
+
Rubyvis.log_adjusted(6,10).should be_close(0.806, 0.001)
|
137
|
+
end
|
138
|
+
it "method log_floor" do
|
139
|
+
Rubyvis.log_floor(-5,4).should be_close(16, 0.001)
|
140
|
+
end
|
141
|
+
it "method log_ceil" do
|
142
|
+
Rubyvis.log_ceil(-5,4).should be_close(-4, 0.001)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|