rubyvis 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/History.txt +9 -1
  2. data/Manifest.txt +9 -4
  3. data/README.txt +59 -8
  4. data/examples/antibiotics/antibiotics.rb +16 -8
  5. data/examples/area.rb +6 -49
  6. data/examples/bar_column_chart.rb +4 -0
  7. data/examples/crimea/{crimea.rb → crimea_data.rb} +0 -0
  8. data/examples/crimea/crimea_grouped_bar.rb +2 -2
  9. data/examples/crimea/crimea_line.rb +1 -1
  10. data/examples/dot.rb +7 -8
  11. data/examples/first.rb +4 -0
  12. data/examples/grouped_charts.rb +3 -0
  13. data/examples/line.rb +19 -61
  14. data/examples/line_and_step.rb +4 -0
  15. data/examples/nested_grid.rb +53 -0
  16. data/examples/scatterplot.rb +2 -0
  17. data/examples/second.rb +14 -2
  18. data/examples/third.rb +9 -6
  19. data/lib/rubyvis/color/color.rb +8 -6
  20. data/lib/rubyvis/color/colors.rb +4 -6
  21. data/lib/rubyvis/format/number.rb +2 -2
  22. data/lib/rubyvis/internals.rb +15 -3
  23. data/lib/rubyvis/javascript_behaviour.rb +20 -8
  24. data/lib/rubyvis/layout/stack.rb +13 -16
  25. data/lib/rubyvis/mark/anchor.rb +64 -2
  26. data/lib/rubyvis/mark/area.rb +4 -3
  27. data/lib/rubyvis/mark/bar.rb +51 -2
  28. data/lib/rubyvis/mark/dot.rb +88 -5
  29. data/lib/rubyvis/mark/label.rb +94 -3
  30. data/lib/rubyvis/mark/line.rb +3 -2
  31. data/lib/rubyvis/mark/panel.rb +1 -0
  32. data/lib/rubyvis/mark/rule.rb +2 -1
  33. data/lib/rubyvis/mark/wedge.rb +2 -1
  34. data/lib/rubyvis/mark.rb +419 -54
  35. data/lib/rubyvis/nest.rb +20 -20
  36. data/lib/rubyvis/scale/linear.rb +1 -1
  37. data/lib/rubyvis/scale/log.rb +1 -1
  38. data/lib/rubyvis/scale/ordinal.rb +120 -8
  39. data/lib/rubyvis/scale/quantitative.rb +159 -15
  40. data/lib/rubyvis/scale.rb +1 -1
  41. data/lib/rubyvis/scene/svg_area.rb +12 -12
  42. data/lib/rubyvis/scene/svg_line.rb +5 -5
  43. data/lib/rubyvis/scene/svg_panel.rb +1 -1
  44. data/lib/rubyvis/scene/svg_scene.rb +1 -1
  45. data/lib/rubyvis.rb +35 -6
  46. data/spec/anchor_spec.rb +15 -15
  47. data/web/Rakefile +34 -0
  48. data/web/build_site.rb +86 -0
  49. data/web/examples.haml +26 -0
  50. data/web/index.haml +97 -0
  51. data/web/style.css +82 -0
  52. data.tar.gz.sig +0 -0
  53. metadata +14 -9
  54. metadata.gz.sig +0 -0
  55. data/lib/rubyvis/label.rb +0 -1
  56. data/web/first.svg +0 -1
  57. data/web/index.html +0 -48
data/lib/rubyvis/nest.rb CHANGED
@@ -1,15 +1,16 @@
1
1
  module Rubyvis
2
2
  ##
3
- # Returns a {@link pv.Nest} operator for the specified array. This is a
4
- # convenience factory method, equivalent to <tt>new pv.Nest(array)</tt>.
3
+ # Returns a Nest operator for the specified array. This is a
4
+ # convenience factory method, equivalent to <tt>Nest.new(array)</tt>.
5
5
  #
6
- # @see pv.Nest
6
+ # @see Rubyvis::Nest
7
7
  # @param {array} array an array of elements to nest.
8
8
  # @returns {Nest} a nest operator for the specified array.
9
9
  ##
10
10
  def self.nest(array)
11
11
  Nest.new(array)
12
12
  end
13
+ # :stopdoc:
13
14
  class NestedArray
14
15
  attr_accessor :key, :values
15
16
  def initialize(opts)
@@ -20,20 +21,18 @@ module Rubyvis
20
21
  key==var.key and values=var.values
21
22
  end
22
23
  end
23
- ##
24
- # Constructs a nest operator for the specified array. This constructor should
25
- # not be invoked directly; use {@link pv.nest} instead.
26
- #
27
- # @class Represents a {@link Nest} operator for the specified array. Nesting
24
+ # :startdoc:
25
+
26
+ # Represents a Nest operator for the specified array. Nesting
28
27
  # allows elements in an array to be grouped into a hierarchical tree
29
28
  # structure. The levels in the tree are specified by <i>key</i> functions. The
30
29
  # leaf nodes of the tree can be sorted by value, while the internal nodes can
31
30
  # be sorted by key. Finally, the tree can be returned either has a
32
- # multidimensional array via {@link #entries}, or as a hierarchical map via
33
- # {@link #map}. The {@link #rollup} routine similarly returns a map, collapsing
31
+ # multidimensional array via Nest.entries, or as a hierarchical map via
32
+ # Nest.map. The Nest.rollup routine similarly returns a map, collapsing
34
33
  # the elements in each leaf node using a summary function.
35
34
  #
36
- # <p>For example, consider the following tabular data structure of Barley
35
+ # For example, consider the following tabular data structure of Barley
37
36
  # yields, from various sites in Minnesota during 1931-2:
38
37
  #
39
38
  # { yield: 27.00, variety: "Manchuria", year: 1931, site: "University Farm" },
@@ -43,10 +42,10 @@ module Rubyvis
43
42
  # To facilitate visualization, it may be useful to nest the elements first by
44
43
  # year, and then by variety, as follows:
45
44
  #
46
- # <pre>var nest = pv.nest(yields)
47
- # .key(function(d) d.year)
48
- # .key(function(d) d.variety)
49
- # .entries();</pre>
45
+ # var nest = Rubyvis.nest(yields)
46
+ # .key(lambda {|d| d.year})
47
+ # .key(lambda {|d| d.variety})
48
+ # .entries();
50
49
  #
51
50
  # This returns a nested array. Each element of the outer array is a key-values
52
51
  # pair, listing the values for each distinct key:
@@ -68,11 +67,12 @@ module Rubyvis
68
67
  #
69
68
  # Further details, including sorting and rollup, is provided below on the
70
69
  # corresponding methods.
71
- #
72
- # @param {array} array an array of elements to nest.
73
- #/
74
70
  class Nest
75
71
  attr_accessor :array, :keys, :order
72
+ ##
73
+ # Constructs a nest operator for the specified array. This constructor should
74
+ # not be invoked directly; use Rubyvis.nest instead.
75
+
76
76
  def initialize(array)
77
77
  @array=array
78
78
  @keys=[]
@@ -83,11 +83,11 @@ module Rubyvis
83
83
  return self
84
84
  end
85
85
  def sort_keys(order=nil)
86
- keys[keys.size-1].order = order.nil? ? pv.natural_order : order
86
+ keys[keys.size-1].order = order.nil? ? Rubyvis.natural_order : order
87
87
  return self
88
88
  end
89
89
  def sort_values(order=nil)
90
- @order = order.nil? ? pv.natural_order : order
90
+ @order = order.nil? ? Rubyvis.natural_order : order
91
91
  return self
92
92
  end
93
93
  def map
@@ -1,5 +1,5 @@
1
1
  module Rubyvis
2
-
2
+ # See Quantitative for complete description of features
3
3
  class Scale::Linear < Rubyvis::Scale::Quantitative
4
4
  end
5
5
  end
@@ -25,7 +25,7 @@ module Rubyvis
25
25
  end
26
26
  def nice
27
27
  d=domain
28
- domain(pv.log_floor(d[0],@b), pv.log_ceil(d[1],@b))
28
+ domain(Rubyvis.log_floor(d[0],@b), Rubyvis.log_ceil(d[1],@b))
29
29
  end
30
30
  def ticks
31
31
  d = domain
@@ -1,7 +1,60 @@
1
1
  module Rubyvis
2
+ # Represents an ordinal scale. <style
3
+ # type="text/css">sub{line-height:0}</style> An ordinal scale represents a
4
+ # pairwise mapping from <i>n</i> discrete values in the input domain to
5
+ # <i>n</i> discrete values in the output range. For example, an ordinal scale
6
+ # might map a domain of species ["setosa", "versicolor", "virginica"] to colors
7
+ # ["red", "green", "blue"]. Thus, saying
8
+ #
9
+ # .fill_style(lambda {|d|
10
+ # case (d.species)
11
+ # when "setosa"
12
+ # "red"
13
+ # when "versicolor"
14
+ # "green"
15
+ # when "virginica"
16
+ # "blue"
17
+ # }
18
+ # )
19
+ #
20
+ # is equivalent to
21
+ #
22
+ # .fill_style(Rubyvis::Scale.ordinal("setosa", "versicolor", "virginica")
23
+ # .range("red", "green", "blue")
24
+ # .by(lambda {|d| d.species}))</pre>
25
+ #
26
+ # If the mapping from species to color does not need to be specified
27
+ # explicitly, the domain can be omitted. In this case it will be inferred
28
+ # lazily from the data:
29
+ #
30
+ # .fill_style(Rubyvis.colors("red", "green", "blue")
31
+ # .by(lambda {|d| d.species}))</pre>
32
+ #
33
+ # When the domain is inferred, the first time the scale is invoked, the first
34
+ # element from the range will be returned. Subsequent calls with unique values
35
+ # will return subsequent elements from the range. If the inferred domain grows
36
+ # larger than the range, range values will be reused. However, it is strongly
37
+ # recommended that the domain and the range contain the same number of
38
+ # elements.
39
+ #
40
+ # A range can be discretized from a continuous interval (e.g., for pixel
41
+ # positioning) by using split, split_flush or
42
+ # split_banded after the domain has been set. For example, if
43
+ # <tt>states</tt> is an array of the fifty U.S. state names, the state name can
44
+ # be encoded in the left position:
45
+ #
46
+ # .left(Rubyvis::Scale.ordinal(states)
47
+ # .split(0, 640)
48
+ # .by(lambda {|d| d.state}))
49
+ #
50
+ # N.B.: ordinal scales are not invertible (at least not yet), since the
51
+ # domain and range and discontinuous. A workaround is to use a linear scale.
2
52
  class Scale::Ordinal
3
- #include Rubyvis::Scale
53
+ # range band, after use split_banded
54
+ # equivalen to protovis scale.range().band
4
55
  attr_reader :range_band
56
+ # Returns an ordinal scale for the specified domain. The arguments to this
57
+ # constructor are optional, and equivalent to calling domain
5
58
  def initialize(*args)
6
59
  @d=[] # domain
7
60
  @i={}
@@ -10,6 +63,14 @@ module Rubyvis
10
63
  @band=0
11
64
  domain(*args)
12
65
  end
66
+
67
+ # Return
68
+ # lambda {|d| scale_object.scale(d)}
69
+ # Useful as value on dynamic properties
70
+ # scale=Rubyvis.ordinal("red","blue","green")
71
+ # bar.fill_style(scale)
72
+ # is the same as
73
+ # bar.fill_style(lambda {|x| scale.scale(x)})
13
74
  def to_proc
14
75
  that=self
15
76
  lambda {|*args| args[0] ? that.scale(args[0]) : nil }
@@ -21,17 +82,60 @@ module Rubyvis
21
82
  end
22
83
  @r[@i[x] % @r.size]
23
84
  end
85
+ # Sets or gets the input domain. This method can be invoked several ways:
86
+ #
87
+ # <p>1. <tt>domain(values...)</tt>
88
+ #
89
+ # <p>Specifying the domain as a series of values is the most explicit and
90
+ # recommended approach. However, if the domain values are derived from data,
91
+ # you may find the second method more appropriate.
92
+ #
93
+ # <p>2. <tt>domain(array, f)</tt>
94
+ #
95
+ # <p>Rather than enumerating the domain values as explicit arguments to this
96
+ # method, you can specify a single argument of an array. In addition, you can
97
+ # specify an optional accessor function to extract the domain values from the
98
+ # array.
99
+ #
100
+ # <p>3. <tt>domain()</tt>
101
+ #
102
+ # <p>Invoking the <tt>domain</tt> method with no arguments returns the
103
+ # current domain as an array.
24
104
  def domain(*arguments)
25
105
  array, f=arguments[0],arguments[1]
26
106
  if(arguments.size>0)
27
- array= (array.is_a? Array) ? ((arguments.size>1) ? pv.map(array,f) : array) : arguments.dup
107
+ array= (array.is_a? Array) ? ((arguments.size>1) ? Rubyvis.map(array,f) : array) : arguments.dup
28
108
  @d=array.uniq
29
- @i=pv.numerate(@d)
109
+ @i=Rubyvis.numerate(@d)
30
110
  return self
31
111
  end
32
112
  @d
33
113
  end
34
- def split_banded(*arguments)
114
+
115
+ # Sets the range from the given continuous interval. The interval [<i>
116
+ # min</i>, <i>max</i>] is subdivided into <i>n</i> equispaced bands,
117
+ # where <i>n</i> is the number of (unique) values in the domain. The first
118
+ # and last band are offset from the edge of the range by the distance between
119
+ # bands.
120
+ #
121
+ # <p>The band width argument, <tt>band</tt>, is typically in the range [0, 1]
122
+ # and defaults to 1. This fraction corresponds to the amount of space in the
123
+ # range to allocate to the bands, as opposed to padding. A value of 0.5 means
124
+ # that the band width will be equal to the padding width. The computed
125
+ # absolute band width can be retrieved from the range as
126
+ # <tt>scale.range_band</tt>.
127
+ #
128
+ # <p>If the band width argument is negative, this method will allocate bands
129
+ # of a <i>fixed</i> width <tt>-band</tt>, rather than a relative fraction of
130
+ # the available space.
131
+ #
132
+ # <p>Tip: to inset the bands by a fixed amount <tt>p</tt>, specify a minimum
133
+ # value of <tt>min + p</tt> (or simply <tt>p</tt>, if <tt>min</tt> is
134
+ # 0). Then set the mark width to <tt>scale.range_band - p</tt>.
135
+ #
136
+ # <p>This method must be called <i>after</i> the domain is set.
137
+
138
+ def split_banded(*arguments) # :args: (min,max,band=1)
35
139
  min,max,band=arguments
36
140
  band=1 if (arguments.size < 3)
37
141
  if (band < 0)
@@ -40,11 +144,11 @@ module Rubyvis
40
144
  total = -band * n
41
145
  remaining = max - min - total
42
146
  padding = remaining / (n + 1).to_f
43
- @r = pv.range(min + padding, max, padding - band);
147
+ @r = Rubyvis.range(min + padding, max, padding - band);
44
148
  @range_band = -band;
45
149
  else
46
150
  step = (max - min) / (self.domain().size + (1 - band))
47
- @r = pv.range(min + step * (1 - band), max, step);
151
+ @r = Rubyvis.range(min + step * (1 - band), max, step);
48
152
  @range_band = step * band;
49
153
  end
50
154
  return self
@@ -54,15 +158,23 @@ module Rubyvis
54
158
  if(arguments.size>0)
55
159
  @r=(array.is_a? Array) ? ((arguments.size>1) ? array.map(&f) : array) : arguments.dup
56
160
  if @r[0].is_a? String
57
- @r=@r.map {|i| pv.color(i)}
161
+ @r=@r.map {|i| Rubyvis.color(i)}
58
162
  end
59
163
  return self
60
164
  end
61
165
  @r
62
166
  end
167
+
168
+ # Sets the range from the given continuous interval. The interval [<i>
169
+ # min</i>, <i>max</i>] is subdivided into <i>n</i> equispaced points,
170
+ # where <i>n</i> is the number of (unique) values in the domain. The first
171
+ # and last point are offset from the edge of the range by half the distance
172
+ # between points.
173
+ #
174
+ # <p>This method must be called <i>after</i> the domain is set.
63
175
  def split(min,max)
64
176
  step=(max-min).quo(domain().size)
65
- @r=pv.range(min+step.quo(2),max,step)
177
+ @r=Rubyvis.range(min+step.quo(2),max,step)
66
178
  self
67
179
  end
68
180
  def by(f)
@@ -1,7 +1,61 @@
1
1
  module Rubyvis
2
+ # Represents an abstract quantitative scale; a function that performs a
3
+ # numeric transformation. This class is typically not used directly; see one of
4
+ # the quantitative scale implementations (linear, log, root, etc.)
5
+ # instead. <style type="text/css">sub{line-height:0}</style> A quantitative
6
+ # scale represents a 1-dimensional transformation from a numeric domain of
7
+ # input data [<i>d<sub>0</sub></i>, <i>d<sub>1</sub></i>] to a numeric range of
8
+ # pixels [<i>r<sub>0</sub></i>, <i>r<sub>1</sub></i>]. In addition to
9
+ # readability, scales offer several useful features:
10
+ #
11
+ # <p>1. The range can be expressed in colors, rather than pixels. For example:
12
+ #
13
+ # .fill_style(Scale.linear(0, 100).range("red", "green"))
14
+ #
15
+ # will fill the marks "red" on an input value of 0, "green" on an input value
16
+ # of 100, and some color in-between for intermediate values.
17
+ #
18
+ # <p>2. The domain and range can be subdivided for a non-uniform
19
+ # transformation. For example, you may want a diverging color scale that is
20
+ # increasingly red for negative values, and increasingly green for positive
21
+ # values:
22
+ #
23
+ # .fill_style(Scale.linear(-1, 0, 1).range("red", "white", "green"))</pre>
24
+ #
25
+ # The domain can be specified as a series of <i>n</i> monotonically-increasing
26
+ # values; the range must also be specified as <i>n</i> values, resulting in
27
+ # <i>n - 1</i> contiguous linear scales.
28
+ #
29
+ # <p>3. Quantitative scales can be inverted for interaction. The
30
+ # invert() method takes a value in the output range, and returns the
31
+ # corresponding value in the input domain. This is frequently used to convert
32
+ # the mouse location (see Mark#mouse) to a value in the input
33
+ # domain. Note that inversion is only supported for numeric ranges, and not
34
+ # colors.
35
+ #
36
+ # <p>4. A scale can be queried for reasonable "tick" values. The ticks()
37
+ # method provides a convenient way to get a series of evenly-spaced rounded
38
+ # values in the input domain. Frequently these are used in conjunction with
39
+ # Rule to display tick marks or grid lines.
40
+ #
41
+ # <p>5. A scale can be "niced" to extend the domain to suitable rounded
42
+ # numbers. If the minimum and maximum of the domain are messy because they are
43
+ # derived from data, you can use nice() to round these values down and
44
+ # up to even numbers.
45
+ #
46
+ # @see Scale.linear
47
+ # @see Scale.log
48
+ # @see Scale.root
2
49
  class Scale::Quantitative
3
50
  include Rubyvis::Scale
4
51
  attr_reader :l
52
+ # Returns a default quantitative, linear, scale for the specified domain. The
53
+ # arguments to this constructor are optional, and equivalent to calling
54
+ # domain. The default domain and range are [0,1].
55
+ #
56
+ # This constructor is typically not used directly; see one of the
57
+ # quantitative scale implementations instead.
58
+ # @param {number...} domain... optional domain values.
5
59
  def initialize(*args)
6
60
  @d=[0,1] # domain
7
61
  @l=[0,1] # transformed domain
@@ -20,13 +74,23 @@ module Rubyvis
20
74
  }
21
75
  domain(*args)
22
76
  end
23
- def new_date(x=nil)
77
+
78
+ # Deprecated
79
+ def new_date(x=nil) # :nodoc:
24
80
  x.nil? ? Time.new() : Time.at(x)
25
81
  end
82
+ # Return
83
+ # lambda {|d| scale_object.scale(d)}
84
+ # Useful as value on dynamic properties
85
+ # scale=Rubyvis.linear(0,1000)
86
+ # bar.width(scale)
87
+ # is the same as
88
+ # bar.width(lambda {|x| scale.scale(x)})
26
89
  def to_proc
27
90
  that=self
28
91
  lambda {|*args| args[0] ? that.scale(args[0]) : nil }
29
92
  end
93
+ # Transform value +x+ according to domain and range
30
94
  def scale(x)
31
95
  x=x.to_f
32
96
  j=Rubyvis.search(@d, x)
@@ -37,6 +101,7 @@ module Rubyvis
37
101
  # puts "Segundo #{(@l[j + 1] - @l[j])}"
38
102
  @i[j].call((@f.call(x) - @l[j]) .quo(@l[j + 1] - @l[j]));
39
103
  end
104
+ # Alias for scale(x)
40
105
  def [](x)
41
106
  scale(x)
42
107
  end
@@ -46,14 +111,51 @@ module Rubyvis
46
111
  @l=@d.map{|v| @f.call(v)}
47
112
  self
48
113
  end
49
-
50
-
114
+ private :transform
115
+ # Sets or gets the input domain. This method can be invoked several ways:
116
+ #
117
+ # <p>1. <tt>domain(min, ..., max)</tt>
118
+ #
119
+ # <p>Specifying the domain as a series of numbers is the most explicit and
120
+ # recommended approach. Most commonly, two numbers are specified: the minimum
121
+ # and maximum value. However, for a diverging scale, or other subdivided
122
+ # non-uniform scales, multiple values can be specified. Values can be derived
123
+ # from data using Rubyvis.min and Rubyvis.max. For example:
124
+ #
125
+ # .domain(0, Rubyvis.max(array))
126
+ #
127
+ # An alternative method for deriving minimum and maximum values from data
128
+ # follows.
129
+ #
130
+ # <p>2. <tt>domain(array, minf, maxf)</tt>
131
+ #
132
+ # <p>When both the minimum and maximum value are derived from data, the
133
+ # arguments to the <tt>domain</tt> method can be specified as the array of
134
+ # data, followed by zero, one or two accessor functions. For example, if the
135
+ # array of data is just an array of numbers:
136
+ #
137
+ # .domain(array)
138
+ #
139
+ # On the other hand, if the array elements are objects representing stock
140
+ # values per day, and the domain should consider the stock's daily low and
141
+ # daily high:
142
+ #
143
+ # .domain(array, lambda {|d| d.low}, lambda {|d| d.high})
144
+ #
145
+ # The first method of setting the domain is preferred because it is more
146
+ # explicit; setting the domain using this second method should be used only
147
+ # if brevity is required.
148
+ #
149
+ # <p>3. <tt>domain()</tt>
150
+ #
151
+ # <p>Invoking the <tt>domain</tt> method with no arguments returns the
152
+ # current domain as an array of numbers.
51
153
  def domain(*arguments)
52
154
  array,min,max=arguments
53
155
  o=nil
54
156
  if (arguments.size>0)
55
157
  if array.is_a? Array
56
- min = pv.identity if (arguments.size < 2)
158
+ min = Rubyvis.identity if (arguments.size < 2)
57
159
  max = min if (arguments.size < 3)
58
160
  o = [array[0]].min if array.size>0
59
161
  @d = array.size>0 ? [Rubyvis.min(array, min), Rubyvis.max(array, max)] : []
@@ -87,7 +189,29 @@ module Rubyvis
87
189
  }
88
190
  end
89
191
 
90
-
192
+ # Sets or gets the output range. This method can be invoked several ways:
193
+ #
194
+ # <p>1. <tt>range(min, ..., max)</tt>
195
+ #
196
+ # <p>The range may be specified as a series of numbers or colors. Most
197
+ # commonly, two numbers are specified: the minimum and maximum pixel values.
198
+ # For a color scale, values may be specified as {@link Rubyvis.Color}s or
199
+ # equivalent strings. For a diverging scale, or other subdivided non-uniform
200
+ # scales, multiple values can be specified. For example:
201
+ #
202
+ # .range("red", "white", "green")
203
+ #
204
+ # <p>Currently, only numbers and colors are supported as range values. The
205
+ # number of range values must exactly match the number of domain values, or
206
+ # the behavior of the scale is undefined.
207
+ #
208
+ # <p>2. <tt>range()</tt>
209
+ #
210
+ # <p>Invoking the <tt>range</tt> method with no arguments returns the current
211
+ # range as an array of numbers or colors.
212
+ # :call-seq:
213
+ # range(min,...,max)
214
+ # range()
91
215
  def range(*arguments)
92
216
  if (arguments.size>0)
93
217
  @r = arguments.dup
@@ -122,7 +246,7 @@ module Rubyvis
122
246
  raise "Not implemented yet"
123
247
  end
124
248
  end
125
- def ticks_floor(d,prec)
249
+ def ticks_floor(d,prec) # :nodoc:
126
250
  ar=d.to_a
127
251
  #p ar
128
252
  # [ sec, min, hour, day, month, year, wday, yday, isdst, zone ]
@@ -145,12 +269,19 @@ module Rubyvis
145
269
  to_date(ar)
146
270
  end
147
271
 
148
- def to_date(d)
272
+ private :ticks_floor
273
+
274
+ def to_date(d) # :nodoc:
149
275
 
150
276
  Time.utc(*d)
151
277
  end
152
- # TODO: FIX this func
153
- def ticks(*arguments)
278
+ # Returns an array of evenly-spaced, suitably-rounded values in the input
279
+ # domain. This method attempts to return between 5 and 10 tick values. These
280
+ # values are frequently used in conjunction with Rule to display
281
+ # tick marks or grid lines.
282
+ #
283
+ # @todo: fix for dates and n>10
284
+ def ticks(*arguments) # :args: (number_of_ticks=nil)
154
285
  m = arguments[0]
155
286
  start = @d.first
156
287
  _end = @d.last
@@ -163,7 +294,7 @@ module Rubyvis
163
294
  @tick_format= Rubyvis.Format.date("%x") if (@type == newDate)
164
295
  return [type(min)];
165
296
  end
166
- # From here, �chaos!
297
+
167
298
  #/* Special case: dates. */
168
299
  if (@type == :time)
169
300
  #/* Floor the date d given the precision p. */
@@ -202,12 +333,13 @@ module Rubyvis
202
333
  increment = lambda {|d| Time.at(d.to_f+(step/1000.0)) }
203
334
  end
204
335
 
205
- @tick_format = pv.Format.date(format);
336
+ @tick_format = Rubyvis.Format.date(format);
206
337
  date = Time.at(min.to_f)
207
338
  dates = []
208
339
  date = ticks_floor(date,precision)
209
340
  # If we'd generate too many ticks, skip some!.
210
341
  n = span / (precision/1000.0)
342
+ # FIX FROM HERE
211
343
  if (n > 10)
212
344
  case (precision)
213
345
  when 36e5
@@ -228,7 +360,7 @@ module Rubyvis
228
360
  step = (n > 1000) ? 250 : ((n > 200) ? 100 : ((n > 100) ? 50 : ((n > 50) ? 25 : 5)));
229
361
  date.setMilliseconds(Math.floor(date.getMilliseconds() / step) * step);
230
362
  else
231
- step = pv.logCeil(n / 15, 10);
363
+ step = Rubyvis.logCeil(n / 15, 10);
232
364
  if (n / step < 2)
233
365
  step =step.quo(5)
234
366
  elsif (n / step < 5)
@@ -249,7 +381,7 @@ module Rubyvis
249
381
  # Normal case: numbers.
250
382
  m = 10 if (arguments.size==0)
251
383
 
252
- step = pv.log_floor(span.quo(m), 10)
384
+ step = Rubyvis.log_floor(span.quo(m), 10)
253
385
  err = m.quo(span.quo(step))
254
386
  if (err <= 0.15)
255
387
  step = step*10
@@ -260,15 +392,27 @@ module Rubyvis
260
392
  end
261
393
  start = (min.quo(step)).ceil * step
262
394
  _end = (max.quo(step)).floor * step
263
- @tick_format= pv.Format.number.fraction_digits([0, -(pv.log(step, 10) + 0.01).floor].max)
264
- ticks = pv.range(start, _end + step, step);
395
+ @tick_format= Rubyvis.Format.number.fraction_digits([0, -(Rubyvis.log(step, 10) + 0.01).floor].max)
396
+ ticks = Rubyvis.range(start, _end + step, step);
265
397
  return reverse ? ticks.reverse() : ticks;
266
398
  end
267
399
 
400
+ # Returns a Proc that formats the specified tick value using the appropriate precision, based on
401
+ # the step interval between tick marks. If ticks() has not been called,
402
+ # the argument is converted to a string, but no formatting is applied.
403
+ # scale.tick_format.call(value)
404
+ #
268
405
  def tick_format
269
406
  @tick_format
270
407
  end
271
408
 
409
+ # "Nices" this scale, extending the bounds of the input domain to
410
+ # evenly-rounded values. Nicing is useful if the domain is computed
411
+ # dynamically from data, and may be irregular. For example, given a domain of
412
+ # [0.20147987687960267, 0.996679553296417], a call to <tt>nice()</tt> might
413
+ # extend the domain to [0.2, 1].
414
+ #
415
+ # This method must be invoked each time after setting the domain.
272
416
  def nice
273
417
  if (@d.size!=2)
274
418
  return self;
data/lib/rubyvis/scale.rb CHANGED
@@ -24,7 +24,7 @@ module Rubyvis
24
24
  return lambda {|t|
25
25
  a=start.a*(1-t)+_end.a*t
26
26
  a=0 if a<1e-5
27
- return (start.a == 0) ? Rubyvis.rgb(_end.r, _end.g, _end.b, a) : ((_end.a == 0) ? pv.rgb(start.r, start.g, start.b, a) : Rubyvis.rgb(
27
+ return (start.a == 0) ? Rubyvis.rgb(_end.r, _end.g, _end.b, a) : ((_end.a == 0) ? Rubyvis.rgb(start.r, start.g, start.b, a) : Rubyvis.rgb(
28
28
  (start.r * (1 - t) + _end.r * t).round,
29
29
  (start.g * (1 - t) + _end.g * t).round,
30
30
  (start.b * (1 - t) + _end.b * t).round, a))
@@ -64,14 +64,14 @@ module Rubyvis
64
64
  }
65
65
 
66
66
  if (s.interpolate == "basis")
67
- pathT = pv.SvgScene.curve_basis(pointsT);
68
- pathB = pv.SvgScene.curve_basis(pointsB);
67
+ pathT = Rubyvis.SvgScene.curve_basis(pointsT);
68
+ pathB = Rubyvis.SvgScene.curve_basis(pointsB);
69
69
  elsif (s.interpolate == "cardinal")
70
- pathT = pv.SvgScene.curve_cardinal(pointsT, s.tension);
71
- pathB = pv.SvgScene.curve_cardinal(pointsB, s.tension);
70
+ pathT = Rubyvis.SvgScene.curve_cardinal(pointsT, s.tension);
71
+ pathB = Rubyvis.SvgScene.curve_cardinal(pointsB, s.tension);
72
72
  elsif # monotone
73
- pathT = pv.SvgScene.curve_monotone(pointsT);
74
- pathB = pv.SvgScene.curve_monotone(pointsB);
73
+ pathT = Rubyvis.SvgScene.curve_monotone(pointsT);
74
+ pathB = Rubyvis.SvgScene.curve_monotone(pointsB);
75
75
  end
76
76
 
77
77
  "#{pointsT[0].left },#{ pointsT[0].top }#{ pathT }L#{ pointsB[0].left},#{pointsB[0].top}#{pathB}"
@@ -132,14 +132,14 @@ module Rubyvis
132
132
  }
133
133
 
134
134
  if (s.interpolate == "basis")
135
- pathT = pv.SvgScene.curve_basis_segments(pointsT);
136
- pathB = pv.SvgScene.curve_basis_segments(pointsB);
135
+ pathT = Rubyvis.SvgScene.curve_basis_segments(pointsT);
136
+ pathB = Rubyvis.SvgScene.curve_basis_segments(pointsB);
137
137
  elsif (s.interpolate == "cardinal")
138
- pathT = pv.SvgScene.curve_cardinal_segments(pointsT, s.tension);
139
- pathB = pv.SvgScene.curve_cardinal_segments(pointsB, s.tension);
138
+ pathT = Rubyvis.SvgScene.curve_cardinal_segments(pointsT, s.tension);
139
+ pathB = Rubyvis.SvgScene.curve_cardinal_segments(pointsB, s.tension);
140
140
  elsif # monotone
141
- pathT = pv.SvgScene.curve_monotone_segments(pointsT);
142
- pathB = pv.SvgScene.curve_monotone_segments(pointsB);
141
+ pathT = Rubyvis.SvgScene.curve_monotone_segments(pointsT);
142
+ pathB = Rubyvis.SvgScene.curve_monotone_segments(pointsB);
143
143
  end
144
144
  end
145
145
  n=scenes.size-1
@@ -72,7 +72,7 @@ module Rubyvis
72
72
  next if (!s1.visible and !s2.visible)
73
73
 
74
74
  stroke = s1.stroke_style
75
- fill = pv.Color.transparent
75
+ fill = Rubyvis.Color.transparent
76
76
 
77
77
  next if stroke.opacity==0.0
78
78
 
@@ -80,7 +80,7 @@ module Rubyvis
80
80
  d=nil
81
81
  if ((s1.interpolate == "linear") and (s1.lineJoin == "miter"))
82
82
  fill = stroke;
83
- stroke = pv.Color.transparent;
83
+ stroke = Rubyvis.Color.transparent;
84
84
  d = path_join(scenes[i - 1], s1, s2, scenes[i + 2]);
85
85
  elsif(paths)
86
86
  d = paths[i];
@@ -142,9 +142,9 @@ module Rubyvis
142
142
  # no joins).
143
143
  #
144
144
 
145
- p1 = pv.vector(s1.left, s1.top)
145
+ p1 = Rubyvis.vector(s1.left, s1.top)
146
146
 
147
- p2 = pv.vector(s2.left, s2.top)
147
+ p2 = Rubyvis.vector(s2.left, s2.top)
148
148
 
149
149
  p = p2.minus(p1)
150
150
 
@@ -172,7 +172,7 @@ module Rubyvis
172
172
 
173
173
  #/* Similarly, for end join. */
174
174
  if (s3 && s3.visible)
175
- v2 = pv.vector(s3.left, s3.top).minus(p2).perp().norm().plus(v);
175
+ v2 = Rubyvis.vector(s3.left, s3.top).minus(p2).perp().norm().plus(v);
176
176
  c = line_intersect(p2, v2, c, p);
177
177
  b = line_intersect(p2, v2, b, p);
178
178
  end
@@ -110,7 +110,7 @@ module Rubyvis
110
110
  "y"=> s.top,
111
111
  "width"=> [1E-10, s.width].max,
112
112
  "height"=>[1E-10, s.height].max,
113
- "fill"=>nil,
113
+ "fill"=>"none",
114
114
  "stroke"=> stroke.color,
115
115
  "stroke-opacity"=> stroke.opacity,
116
116
  "stroke-width"=> s.line_width / self.scale.to_f
@@ -45,7 +45,7 @@ module Rubyvis
45
45
  "dy"=> 0,
46
46
  "text-anchor"=> "start",
47
47
  "transform"=> "translate(0,0)",
48
- "fill"=> "none",
48
+ #"fill"=> "none",
49
49
  "fill-opacity"=> 1,
50
50
  "stroke"=> "none",
51
51
  "stroke-opacity"=> 1,