rubyvis 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.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
|