plotrb 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +38 -0
- data/README.rdoc +77 -0
- data/Rakefile +7 -0
- data/examples/arc.rb +31 -0
- data/examples/area.rb +48 -0
- data/examples/bar.rb +44 -0
- data/examples/barley.rb +66 -0
- data/examples/choropleth.rb +48 -0
- data/examples/lifelines.rb +106 -0
- data/examples/scatter.rb +43 -0
- data/lib/plotrb.rb +25 -0
- data/lib/plotrb/axes.rb +208 -0
- data/lib/plotrb/base.rb +193 -0
- data/lib/plotrb/data.rb +232 -0
- data/lib/plotrb/kernel.rb +136 -0
- data/lib/plotrb/legends.rb +168 -0
- data/lib/plotrb/marks.rb +459 -0
- data/lib/plotrb/scales.rb +346 -0
- data/lib/plotrb/simple.rb +197 -0
- data/lib/plotrb/transforms.rb +592 -0
- data/lib/plotrb/version.rb +3 -0
- data/lib/plotrb/visualization.rb +55 -0
- data/plotrb.gemspec +27 -0
- data/spec/plotrb/axes_spec.rb +227 -0
- data/spec/plotrb/base_spec.rb +321 -0
- data/spec/plotrb/data_spec.rb +258 -0
- data/spec/plotrb/kernel_spec.rb +54 -0
- data/spec/plotrb/legends_spec.rb +157 -0
- data/spec/plotrb/marks_spec.rb +46 -0
- data/spec/plotrb/scales_spec.rb +187 -0
- data/spec/plotrb/simple_spec.rb +61 -0
- data/spec/plotrb/transforms_spec.rb +248 -0
- data/spec/plotrb/visualization_spec.rb +93 -0
- data/spec/plotrb_spec.rb +5 -0
- data/spec/spec_helper.rb +12 -0
- metadata +180 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe 'Mark' do
|
4
|
+
|
5
|
+
subject { ::Plotrb::Mark.rect }
|
6
|
+
|
7
|
+
describe '#initialize' do
|
8
|
+
|
9
|
+
context 'when type is group' do
|
10
|
+
|
11
|
+
subject { ::Plotrb::Mark.group }
|
12
|
+
|
13
|
+
it 'has additional scales, axes, and marks attribute' do
|
14
|
+
subject.attributes.should include(:scales, :axes, :marks)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'properties' do
|
22
|
+
|
23
|
+
it 'allows multiple properties' do
|
24
|
+
::Plotrb::Kernel.stub(:find_data).with('some_data').and_return(true)
|
25
|
+
subject.from('some_data')
|
26
|
+
subject.enter
|
27
|
+
subject.exit
|
28
|
+
subject.properties.keys.should match_array([:enter, :exit])
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#from' do
|
34
|
+
|
35
|
+
it 'recognizes Data and Transform objects' do
|
36
|
+
foo = ::Plotrb::Transform.facet
|
37
|
+
bar = ::Plotrb::Transform.filter
|
38
|
+
::Plotrb::Kernel.stub(:find_data).with('some_data').and_return(true)
|
39
|
+
subject.from('some_data', foo, bar)
|
40
|
+
subject.send(:process_from)
|
41
|
+
subject.from.should == {:data => 'some_data', :transform => [foo, bar]}
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe 'Scale' do
|
4
|
+
|
5
|
+
subject { ::Plotrb::Scale.new }
|
6
|
+
|
7
|
+
describe '#name' do
|
8
|
+
|
9
|
+
it 'sets name of the scale' do
|
10
|
+
subject.name 'foo_scale'
|
11
|
+
subject.name.should == 'foo_scale'
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'raises error if the name is not unique' do
|
15
|
+
subject.name 'foo'
|
16
|
+
::Plotrb::Kernel.stub(:duplicate_scale?).and_return(true)
|
17
|
+
expect { subject.send(:process_name) }.to raise_error(ArgumentError)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#type' do
|
23
|
+
|
24
|
+
it 'does not allow changing type once initialized' do
|
25
|
+
expect { subject.type(:other_type) }.to raise_error(ArgumentError)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#domain' do
|
31
|
+
|
32
|
+
context 'when domain is a string reference to a data source' do
|
33
|
+
|
34
|
+
before(:each) do
|
35
|
+
::Plotrb::Kernel.stub(:find_data).and_return(::Plotrb::Data.new)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'separates data source and data field' do
|
39
|
+
subject.from('some_data.some_field')
|
40
|
+
::Plotrb::Data.any_instance.stub(:extra_fields).and_return([])
|
41
|
+
subject.send(:process_domain)
|
42
|
+
subject.domain.data.should == 'some_data'
|
43
|
+
subject.domain.field.should == 'data.some_field'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'defaults field to index if not provided' do
|
47
|
+
subject.from('some_data')
|
48
|
+
::Plotrb::Data.any_instance.stub(:extra_fields).and_return([])
|
49
|
+
subject.send(:process_domain)
|
50
|
+
subject.domain.data.should == 'some_data'
|
51
|
+
subject.domain.field.should == 'index'
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'deals with index field properly' do
|
55
|
+
subject.from('some_data.index')
|
56
|
+
::Plotrb::Data.any_instance.stub(:extra_fields).and_return([])
|
57
|
+
subject.send(:process_domain)
|
58
|
+
subject.domain.data.should == 'some_data'
|
59
|
+
subject.domain.field.should == 'index'
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'recognizes extra fields added by transform' do
|
63
|
+
subject.from('some_data.field')
|
64
|
+
::Plotrb::Data.any_instance.stub(:extra_fields).and_return([:field])
|
65
|
+
subject.send(:process_domain)
|
66
|
+
subject.domain.data.should == 'some_data'
|
67
|
+
subject.domain.field.should == 'field'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when domain is actual ordinal/categorical data' do
|
72
|
+
|
73
|
+
it 'sets domain directly' do
|
74
|
+
data_set = %w(foo bar baz qux)
|
75
|
+
subject.from(data_set)
|
76
|
+
subject.domain.should == data_set
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when domain is a quantitative range' do
|
82
|
+
|
83
|
+
it 'sets domain as a two-element array' do
|
84
|
+
subject.from([1,100])
|
85
|
+
subject.domain.should == [1,100]
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#range' do
|
93
|
+
|
94
|
+
context 'when range is numeric' do
|
95
|
+
|
96
|
+
it 'sets range as a two-element array' do
|
97
|
+
subject.to([1,100])
|
98
|
+
subject.send(:process_range)
|
99
|
+
subject.range.should == [1,100]
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when range is ordinal' do
|
105
|
+
|
106
|
+
it 'sets range directly' do
|
107
|
+
range_set = %w(foo bar baz qux)
|
108
|
+
subject.to(range_set)
|
109
|
+
subject.send(:process_range)
|
110
|
+
subject.range.should == range_set
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'when range is special literal' do
|
116
|
+
|
117
|
+
it 'sets correct range literal' do
|
118
|
+
subject.to_more_colors
|
119
|
+
subject.send(:process_range)
|
120
|
+
subject.range.should == :category20
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'does not set invalid range literal' do
|
124
|
+
expect { subject.to_foo_bar_range }.to raise_error(NoMethodError)
|
125
|
+
subject.range.should be_nil
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
describe '#exponent' do
|
133
|
+
|
134
|
+
it 'sets the exponent of scale transformation' do
|
135
|
+
subject.in_exponent(10)
|
136
|
+
subject.exponent.should == 10
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
describe '#nice' do
|
142
|
+
|
143
|
+
context 'when scale is time or utc' do
|
144
|
+
|
145
|
+
subject { ::Plotrb::Scale.time }
|
146
|
+
|
147
|
+
it 'sets valid nice literal' do
|
148
|
+
subject.in_seconds
|
149
|
+
subject.nice.should == :second
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'does not set invalid nice literal' do
|
153
|
+
expect { subject.in_millennium }.to raise_error(NoMethodError)
|
154
|
+
subject.nice.should be_nil
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'when scale is quantitative' do
|
160
|
+
|
161
|
+
subject { ::Plotrb::Scale.linear }
|
162
|
+
|
163
|
+
it 'sets nice to true' do
|
164
|
+
subject.nicely
|
165
|
+
subject.nice?.should be_true
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
describe '#method_missing' do
|
173
|
+
|
174
|
+
it 'calls nice if in_foo is called' do
|
175
|
+
subject.type = :time
|
176
|
+
subject.should_receive(:nice).with(:second)
|
177
|
+
subject.in_seconds
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'calls range if to_foo is called' do
|
181
|
+
subject.should_receive(:range).with(:colors)
|
182
|
+
subject.to_colors
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#--
|
2
|
+
# simple_spec.rb: specs for simple plot shortcuts
|
3
|
+
# Copyright (c) 2013 Colin J. Fuller and the Ruby Science Foundation
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions
|
8
|
+
# are met:
|
9
|
+
# - Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# - Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in the
|
14
|
+
# documentation and/or other materials provided with the
|
15
|
+
# distribution.
|
16
|
+
#
|
17
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
18
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
19
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
20
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
21
|
+
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
22
|
+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
23
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
24
|
+
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
25
|
+
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
26
|
+
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
|
27
|
+
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
#++
|
30
|
+
|
31
|
+
require 'spec_helper'
|
32
|
+
require 'plotrb/simple'
|
33
|
+
|
34
|
+
describe Plotrb::Simple do
|
35
|
+
|
36
|
+
context "scatter plots" do
|
37
|
+
before :each do
|
38
|
+
@xdata = [0,1,2,3,4,5]
|
39
|
+
@ydata = [[0,1,4,9,16,25],[0,1,8,27,64,125]]
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should correctly make a scatter plot with supplied options" do
|
43
|
+
Plotrb::Simple.scatter(@xdata, @ydata, markersize: 40, domain: [0,10], range: [0,125], color: ['red', 'blue'], width: 1000, height: 1000, symbol: ['triangle-up', 'triangle-down']).generate_spec.should eq '{"width":1000,"height":1000,"data":[{"name":"scatter","values":[{"x0":0,"y0":0,"y1":0},{"x0":1,"y0":1,"y1":1},{"x0":2,"y0":4,"y1":8},{"x0":3,"y0":9,"y1":27},{"x0":4,"y0":16,"y1":64},{"x0":5,"y0":25,"y1":125}]}],"scales":[{"name":"scatter_x","type":"linear","domain":[0,10],"range":"width"},{"name":"scatter_y","type":"linear","domain":[0,125],"range":"height"}],"marks":[{"type":"symbol","from":{"data":"scatter"},"properties":{"enter":{"size":{"value":40},"shape":{"value":"triangle-up"},"x":{"field":"data.x0","scale":"scatter_x"},"y":{"field":"data.y0","scale":"scatter_y"},"fill":{"value":"red"}}}},{"type":"symbol","from":{"data":"scatter"},"properties":{"enter":{"size":{"value":40},"shape":{"value":"triangle-down"},"x":{"field":"data.x0","scale":"scatter_x"},"y":{"field":"data.y1","scale":"scatter_y"},"fill":{"value":"blue"}}}}],"axes":[{"type":"x","scale":"scatter_x"},{"type":"y","scale":"scatter_y"}]}'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should correctly make a scatter plot with default options and multiple data series" do
|
47
|
+
Plotrb::Simple.scatter(@xdata, @ydata).generate_spec.should eq '{"width":640,"height":480,"data":[{"name":"scatter","values":[{"x0":0,"y0":0,"y1":0},{"x0":1,"y0":1,"y1":1},{"x0":2,"y0":4,"y1":8},{"x0":3,"y0":9,"y1":27},{"x0":4,"y0":16,"y1":64},{"x0":5,"y0":25,"y1":125}]}],"scales":[{"name":"scatter_x","type":"linear","domain":{"data":"scatter","field":"data.x0"},"range":"width"},{"name":"scatter_y","type":"linear","domain":{"data":"scatter","field":"data.y0"},"range":"height"}],"marks":[{"type":"symbol","from":{"data":"scatter"},"properties":{"enter":{"size":{"value":20},"shape":{"value":"circle"},"x":{"field":"data.x0","scale":"scatter_x"},"y":{"field":"data.y0","scale":"scatter_y"},"fill":{"value":"blue"}}}},{"type":"symbol","from":{"data":"scatter"},"properties":{"enter":{"size":{"value":20},"shape":{"value":"circle"},"x":{"field":"data.x0","scale":"scatter_x"},"y":{"field":"data.y1","scale":"scatter_y"},"fill":{"value":"blue"}}}}],"axes":[{"type":"x","scale":"scatter_x"},{"type":"y","scale":"scatter_y"}]}'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should correctly make a scatter plot with default options and a single data series" do
|
51
|
+
Plotrb::Simple.scatter(@xdata, [0,1,4,9,16,25]).generate_spec.should eq '{"width":640,"height":480,"data":[{"name":"scatter","values":[{"x0":0,"y0":0},{"x0":1,"y0":1},{"x0":2,"y0":4},{"x0":3,"y0":9},{"x0":4,"y0":16},{"x0":5,"y0":25}]}],"scales":[{"name":"scatter_x","type":"linear","domain":{"data":"scatter","field":"data.x0"},"range":"width"},{"name":"scatter_y","type":"linear","domain":{"data":"scatter","field":"data.y0"},"range":"height"}],"marks":[{"type":"symbol","from":{"data":"scatter"},"properties":{"enter":{"size":{"value":20},"shape":{"value":"circle"},"x":{"field":"data.x0","scale":"scatter_x"},"y":{"field":"data.y0","scale":"scatter_y"},"fill":{"value":"blue"}}}}],"axes":[{"type":"x","scale":"scatter_x"},{"type":"y","scale":"scatter_y"}]}'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should correctly make a scatter plot with default options and multiple x and y data series" do
|
55
|
+
@xdata = [[0,1,2,3,4,16], [10,11,12,13,14,15]]
|
56
|
+
Plotrb::Simple.scatter(@xdata, @ydata).generate_spec.should eq '{"width":640,"height":480,"data":[{"name":"scatter","values":[{"x0":0,"y0":0,"x1":10,"y1":0},{"x0":1,"y0":1,"x1":11,"y1":1},{"x0":2,"y0":4,"x1":12,"y1":8},{"x0":3,"y0":9,"x1":13,"y1":27},{"x0":4,"y0":16,"x1":14,"y1":64},{"x0":16,"y0":25,"x1":15,"y1":125}]}],"scales":[{"name":"scatter_x","type":"linear","domain":{"data":"scatter","field":"data.x0"},"range":"width"},{"name":"scatter_y","type":"linear","domain":{"data":"scatter","field":"data.y0"},"range":"height"}],"marks":[{"type":"symbol","from":{"data":"scatter"},"properties":{"enter":{"size":{"value":20},"shape":{"value":"circle"},"x":{"field":"data.x0","scale":"scatter_x"},"y":{"field":"data.y0","scale":"scatter_y"},"fill":{"value":"blue"}}}},{"type":"symbol","from":{"data":"scatter"},"properties":{"enter":{"size":{"value":20},"shape":{"value":"circle"},"x":{"field":"data.x1","scale":"scatter_x"},"y":{"field":"data.y1","scale":"scatter_y"},"fill":{"value":"blue"}}}}],"axes":[{"type":"x","scale":"scatter_x"},{"type":"y","scale":"scatter_y"}]}'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
@@ -0,0 +1,248 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe 'Transform' do
|
4
|
+
|
5
|
+
describe '#initialize' do
|
6
|
+
|
7
|
+
subject { Plotrb::Transform }
|
8
|
+
|
9
|
+
it 'calls respective type method to initialize attributes' do
|
10
|
+
subject.any_instance.should_receive(:send).with(:foo)
|
11
|
+
subject.new(:foo)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'raises error if type is not recognized' do
|
15
|
+
expect { subject.new(:foo) }.to raise_error(NoMethodError)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#array' do
|
21
|
+
|
22
|
+
subject { Plotrb::Transform.new(:array) }
|
23
|
+
|
24
|
+
it 'responds to #take' do
|
25
|
+
subject.take('foo', 'bar')
|
26
|
+
subject.send(:process_array_fields)
|
27
|
+
subject.fields.should match_array(['data.foo', 'data.bar'])
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#copy' do
|
33
|
+
|
34
|
+
subject { Plotrb::Transform.new(:copy) }
|
35
|
+
|
36
|
+
it 'responds to #take' do
|
37
|
+
subject.take('foo_field', 'bar_field').from('some_data').as('foo', 'bar')
|
38
|
+
subject.fields.should match_array(['foo_field', 'bar_field'])
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'raises error if as and fields are of different size' do
|
42
|
+
subject.take('foo', 'bar').from('data').as('baz')
|
43
|
+
expect { subject.send(:process_copy_as) }.to raise_error(ArgumentError)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#cross' do
|
49
|
+
|
50
|
+
subject { Plotrb::Transform.new(:cross) }
|
51
|
+
|
52
|
+
it 'raises error if the secondary data does not exist' do
|
53
|
+
subject.with('foo')
|
54
|
+
::Plotrb::Kernel.stub(:find_data).and_return(nil)
|
55
|
+
expect { subject.send(:process_cross_with) }.to raise_error(ArgumentError)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#facet' do
|
61
|
+
|
62
|
+
subject { Plotrb::Transform.new(:facet) }
|
63
|
+
|
64
|
+
it 'responds to #group_by' do
|
65
|
+
subject.group_by('foo', 'bar')
|
66
|
+
subject.send(:process_facet_keys)
|
67
|
+
subject.keys.should match_array(['data.foo', 'data.bar'])
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#filter' do
|
73
|
+
|
74
|
+
subject { Plotrb::Transform.new(:filter) }
|
75
|
+
|
76
|
+
it 'adds variable d if not present in the test expression' do
|
77
|
+
subject.test('x>10')
|
78
|
+
expect { subject.send(:process_filter_test) }.to raise_error(ArgumentError)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#flatten' do
|
84
|
+
|
85
|
+
subject { Plotrb::Transform.new(:flatten) }
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#fold' do
|
90
|
+
|
91
|
+
subject { Plotrb::Transform.new(:fold) }
|
92
|
+
|
93
|
+
it 'responds to #into' do
|
94
|
+
subject.into('foo', 'bar')
|
95
|
+
subject.send(:process_fold_fields)
|
96
|
+
subject.fields.should match_array(['data.foo', 'data.bar'])
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#formula' do
|
102
|
+
|
103
|
+
subject { Plotrb::Transform.new(:formula) }
|
104
|
+
|
105
|
+
it 'responds to #apply and #into' do
|
106
|
+
subject.apply('some_expression').into('some_field')
|
107
|
+
subject.field.should == 'some_field'
|
108
|
+
subject.expr.should == 'some_expression'
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '#slice' do
|
114
|
+
|
115
|
+
subject { Plotrb::Transform.new(:slice) }
|
116
|
+
|
117
|
+
it 'slices by a single value'
|
118
|
+
|
119
|
+
it 'slices by a range'
|
120
|
+
|
121
|
+
it 'slices by special positions'
|
122
|
+
|
123
|
+
it 'raises error otherwise'
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
describe '#sort' do
|
128
|
+
|
129
|
+
subject { Plotrb::Transform.new(:sort) }
|
130
|
+
|
131
|
+
it 'adds - in front for reverse sort'
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#stats' do
|
136
|
+
|
137
|
+
subject { Plotrb::Transform.new(:stats) }
|
138
|
+
|
139
|
+
it 'responds to #from, #include_median, and #store_stats' do
|
140
|
+
subject.from('foo').include_median.store_stats
|
141
|
+
subject.value.should == 'foo'
|
142
|
+
subject.median.should be_true
|
143
|
+
subject.assign.should be_true
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
describe '#truncate' do
|
149
|
+
|
150
|
+
subject { Plotrb::Transform.new(:truncate) }
|
151
|
+
|
152
|
+
it 'responds to #from, #to, and #max_length' do
|
153
|
+
subject.from('foo').to('bar').max_length(5)
|
154
|
+
subject.send(:process_truncate_value)
|
155
|
+
subject.value.should == 'data.foo'
|
156
|
+
subject.output.should == 'bar'
|
157
|
+
subject.limit.should == 5
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'responds to #in_position' do
|
161
|
+
subject.in_front
|
162
|
+
subject.position.should == :front
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
describe '#unique' do
|
168
|
+
|
169
|
+
subject { Plotrb::Transform.new(:unique) }
|
170
|
+
|
171
|
+
it 'responds to #from and #to' do
|
172
|
+
subject.from('foo').to('bar')
|
173
|
+
subject.send(:process_unique_field)
|
174
|
+
subject.field.should == 'data.foo'
|
175
|
+
subject.as.should == 'bar'
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
describe '#window' do
|
181
|
+
|
182
|
+
subject { Plotrb::Transform.new(:window) }
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
describe '#zip' do
|
187
|
+
|
188
|
+
subject { Plotrb::Transform.new(:zip) }
|
189
|
+
|
190
|
+
it 'responds to #match and #against' do
|
191
|
+
subject.with('foo').as('bar').match('foo_field').against('bar_field')
|
192
|
+
subject.send(:process_zip_key)
|
193
|
+
subject.send(:process_zip_with_key)
|
194
|
+
subject.key.should == 'data.foo_field'
|
195
|
+
subject.with_key.should == 'data.bar_field'
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
describe '#force' do
|
201
|
+
|
202
|
+
subject { Plotrb::Transform.new(:force) }
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
describe '#geo' do
|
207
|
+
|
208
|
+
subject { Plotrb::Transform.new(:geo) }
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
describe '#geopath' do
|
213
|
+
|
214
|
+
subject { Plotrb::Transform.new(:geopath) }
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
describe '#link' do
|
219
|
+
|
220
|
+
subject { Plotrb::Transform.new(:link) }
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
describe '#pie' do
|
225
|
+
|
226
|
+
subject { Plotrb::Transform.new(:pie) }
|
227
|
+
|
228
|
+
end
|
229
|
+
|
230
|
+
describe '#stack' do
|
231
|
+
|
232
|
+
subject { Plotrb::Transform.new(:stack) }
|
233
|
+
|
234
|
+
end
|
235
|
+
|
236
|
+
describe '#treemap' do
|
237
|
+
|
238
|
+
subject { Plotrb::Transform.new(:treemap) }
|
239
|
+
|
240
|
+
end
|
241
|
+
|
242
|
+
describe '#wordcloud' do
|
243
|
+
|
244
|
+
subject { Plotrb::Transform.new(:wordcloud) }
|
245
|
+
|
246
|
+
end
|
247
|
+
|
248
|
+
end
|