gerbilcharts 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/History.txt +11 -0
  2. data/License.txt +21 -0
  3. data/Manifest.txt +75 -0
  4. data/PostInstall.txt +7 -0
  5. data/README.txt +174 -0
  6. data/Rakefile +4 -0
  7. data/lib/gerbilcharts.rb +18 -0
  8. data/lib/gerbilcharts/charts.rb +16 -0
  9. data/lib/gerbilcharts/charts/area_chart.rb +36 -0
  10. data/lib/gerbilcharts/charts/bar_chart.rb +33 -0
  11. data/lib/gerbilcharts/charts/bar_chart_compact.rb +26 -0
  12. data/lib/gerbilcharts/charts/chart_base.rb +123 -0
  13. data/lib/gerbilcharts/charts/impulse_chart.rb +30 -0
  14. data/lib/gerbilcharts/charts/line_chart.rb +35 -0
  15. data/lib/gerbilcharts/charts/stacked_area_chart.rb +31 -0
  16. data/lib/gerbilcharts/models.rb +19 -0
  17. data/lib/gerbilcharts/models/bucketized_timeseries_graph_model.rb +138 -0
  18. data/lib/gerbilcharts/models/discrete_time_range.rb +63 -0
  19. data/lib/gerbilcharts/models/graph_model.rb +89 -0
  20. data/lib/gerbilcharts/models/graph_model_group.rb +240 -0
  21. data/lib/gerbilcharts/models/monotonous_graph_model.rb +192 -0
  22. data/lib/gerbilcharts/models/presets.rb +94 -0
  23. data/lib/gerbilcharts/models/raw_range.rb +68 -0
  24. data/lib/gerbilcharts/models/round_range.rb +104 -0
  25. data/lib/gerbilcharts/models/round_time_range.rb +105 -0
  26. data/lib/gerbilcharts/models/sampled_timeseries_graph_model.rb +80 -0
  27. data/lib/gerbilcharts/models/simple_timeseries_model_group.rb +68 -0
  28. data/lib/gerbilcharts/models/time_series_graph_model.rb +34 -0
  29. data/lib/gerbilcharts/public/brushmetal.css +197 -0
  30. data/lib/gerbilcharts/public/gerbil.js +327 -0
  31. data/lib/gerbilcharts/surfaces.rb +32 -0
  32. data/lib/gerbilcharts/surfaces/area_surface.rb +46 -0
  33. data/lib/gerbilcharts/surfaces/axis.rb +31 -0
  34. data/lib/gerbilcharts/surfaces/bar_surface.rb +62 -0
  35. data/lib/gerbilcharts/surfaces/basic_grid.rb +17 -0
  36. data/lib/gerbilcharts/surfaces/chart.rb +132 -0
  37. data/lib/gerbilcharts/surfaces/graph_element.rb +170 -0
  38. data/lib/gerbilcharts/surfaces/grid.rb +38 -0
  39. data/lib/gerbilcharts/surfaces/horizontal_axis.rb +32 -0
  40. data/lib/gerbilcharts/surfaces/horizontal_name_axis.rb +28 -0
  41. data/lib/gerbilcharts/surfaces/horizontal_time_axis.rb +25 -0
  42. data/lib/gerbilcharts/surfaces/impulse_surface.rb +47 -0
  43. data/lib/gerbilcharts/surfaces/legend.rb +59 -0
  44. data/lib/gerbilcharts/surfaces/line_surface.rb +53 -0
  45. data/lib/gerbilcharts/surfaces/mark_band.rb +17 -0
  46. data/lib/gerbilcharts/surfaces/panel.rb +17 -0
  47. data/lib/gerbilcharts/surfaces/pie_surface.rb +16 -0
  48. data/lib/gerbilcharts/surfaces/rect.rb +86 -0
  49. data/lib/gerbilcharts/surfaces/stacked_area_surface.rb +66 -0
  50. data/lib/gerbilcharts/surfaces/stacked_grid.rb +15 -0
  51. data/lib/gerbilcharts/surfaces/surface.rb +20 -0
  52. data/lib/gerbilcharts/surfaces/surface_background.rb +13 -0
  53. data/lib/gerbilcharts/surfaces/title_panel.rb +44 -0
  54. data/lib/gerbilcharts/surfaces/tracker.rb +62 -0
  55. data/lib/gerbilcharts/surfaces/vertical_axis.rb +46 -0
  56. data/lib/gerbilcharts/svgdc.rb +22 -0
  57. data/lib/gerbilcharts/svgdc/filters.rb +40 -0
  58. data/lib/gerbilcharts/svgdc/presentation_attributes.rb +50 -0
  59. data/lib/gerbilcharts/svgdc/svg_circle.rb +22 -0
  60. data/lib/gerbilcharts/svgdc/svg_custom_win.rb +36 -0
  61. data/lib/gerbilcharts/svgdc/svg_element.rb +87 -0
  62. data/lib/gerbilcharts/svgdc/svg_line.rb +26 -0
  63. data/lib/gerbilcharts/svgdc/svg_polygon.rb +34 -0
  64. data/lib/gerbilcharts/svgdc/svg_polyline.rb +27 -0
  65. data/lib/gerbilcharts/svgdc/svg_rect.rb +29 -0
  66. data/lib/gerbilcharts/svgdc/svg_shape.rb +10 -0
  67. data/lib/gerbilcharts/svgdc/svg_text.rb +21 -0
  68. data/lib/gerbilcharts/svgdc/svg_win.rb +52 -0
  69. data/lib/gerbilcharts/svgdc/svgdc.rb +335 -0
  70. data/lib/gerbilcharts/svgdc/transformations.rb +66 -0
  71. data/lib/gerbilcharts/version.rb +9 -0
  72. data/setup.rb +1585 -0
  73. data/test/test_Scratch.rb +21 -0
  74. data/test/test_charts.rb +119 -0
  75. data/test/test_gerbilcharts.rb +11 -0
  76. data/test/test_helper.rb +2 -0
  77. data/test/test_models.rb +118 -0
  78. data/test/test_noob.rb +81 -0
  79. data/test/test_ranges.rb +135 -0
  80. data/test/test_svgdc.rb +221 -0
  81. data/test/trafgen.rb +25 -0
  82. metadata +156 -0
@@ -0,0 +1,192 @@
1
+ module GerbilCharts::Models
2
+
3
+ # = MonotonousGraphModel
4
+ # simple graph model (x increases monotonously)
5
+ # All timeseries models are derived from this class
6
+ #
7
+ class MonotonousGraphModel < GraphModel
8
+
9
+ attr_reader :xarr # the x values
10
+ attr_reader :yarr # the y values
11
+ attr_reader :xrange,:yrange # raw ranges
12
+ attr_reader :rounderx, :roundery # rounded ranges according to presets
13
+
14
+ def initialize(name,opt={})
15
+ super(name)
16
+ @xrange = RawRange.new
17
+ @yrange = RawRange.new
18
+ @rounderx = RoundRange
19
+ @roundery = RoundRange
20
+ @xarr=[]
21
+ @yarr=[]
22
+ end
23
+
24
+ # add a tuple, apply a transformer lambda is supplied by the user
25
+ #
26
+ # A new datapoint must have a x_val greater than the previous one
27
+ def add(x_val,y_val)
28
+
29
+
30
+ if @xarr.length > 0 and @xarr.last > x_val
31
+ raise "Expecting monotonous series data"
32
+ end
33
+
34
+ @xrange.update x_val
35
+
36
+ @xarr<<x_val
37
+
38
+ if @transformer
39
+ trval = @transformer.xform(y_val)
40
+ @yarr << trval
41
+ @yrange.update trval
42
+ else
43
+ @yarr << y_val
44
+ @yrange.update y_val
45
+ end
46
+
47
+ end
48
+
49
+ # add an array of values at once (just a convenience method)
50
+ def add_tuples tarr
51
+ tarr.each do |t|
52
+ add t[0],t[1]
53
+ end
54
+ end
55
+
56
+ def clear
57
+ @xrange.reset
58
+ @yrange.reset
59
+ @xarr=[]
60
+ @yarr=[]
61
+ end
62
+
63
+ def count
64
+ @xarr.size
65
+ end
66
+
67
+
68
+ def latest
69
+ yield @xarr.last, @yarr.last
70
+ end
71
+
72
+ def latest_x
73
+ return @xarr.last
74
+ end
75
+
76
+ def latest_val
77
+ return @yarr.last
78
+ end
79
+
80
+ def latest_x_dbtime
81
+ return @xarr.last<<32
82
+ end
83
+
84
+ def first
85
+ yield @xarr[0],@yarr[0]
86
+ end
87
+
88
+ def latest_formatted_val
89
+ return @yrange.format_value(@yarr.last)
90
+ end
91
+
92
+ def ranges
93
+ yield @xrange, @yrange if block_given?
94
+ return @xrange,@yrange
95
+ end
96
+
97
+ def round_ranges
98
+ if block_given?
99
+ yield @rounderx.new(@xrange), @roundery.new(@yrange)
100
+ else
101
+ return @rounderx.new(@xrange), @roundery.new(@yrange)
102
+ end
103
+ end
104
+
105
+ def round_given_x(rx)
106
+ return @rounderx.new(rx)
107
+ end
108
+
109
+ def round_given_y(ry)
110
+ return @roundery.new(ry)
111
+ end
112
+
113
+ def each_tuple
114
+ for i in (0 .. @xarr.length-1)
115
+ yield @xarr[i],@yarr[i]
116
+ end
117
+ end
118
+
119
+ # crop all tuples older than a cutoff window
120
+ #
121
+ # [+cutoffwindow+] older than a number of seconds
122
+ #
123
+ def crop_window(cutoffwindow)
124
+ xcutoff = latest_x - cutoffwindow
125
+ crop_at(xcutoff)
126
+ end
127
+
128
+ # crop all tuples less than an absolute cutoff
129
+ # [+cutoff+] Cutoff value
130
+ #
131
+ def crop_at(cutoff)
132
+ until @xarr.empty? or @xarr.first >= cutoff
133
+ @xarr.shift
134
+ @yarr.shift
135
+ end
136
+ recompute_ranges
137
+ end
138
+
139
+ # all data points newer than a cut off
140
+ def tuples_since(x_last)
141
+ istart = binarySearch(@xarr,x_last,0,@xarr.length)
142
+ for i in istart..@xarr.length-1
143
+ yield @xarr[i],@yarr[i]
144
+ end
145
+ end
146
+
147
+ # for test purposes
148
+ def randomizeLastValue
149
+ v=@yarr.last
150
+ @yarr[@yarr.size-1]=v * ( 0.5 + rand())
151
+ end
152
+
153
+
154
+ private
155
+ # recompute ranges
156
+ def recompute_ranges
157
+ @xrange.reset
158
+ @yrange.reset
159
+
160
+ each_tuple do |x,y|
161
+ @xrange.update x
162
+ @yrange.update y
163
+ end
164
+
165
+ end
166
+
167
+
168
+ # rudimentary binary search
169
+ def binarySearch(array, target, i, n)
170
+ case n
171
+ when 0
172
+ raise ArgumentError
173
+ when 1
174
+ if array[i] == target
175
+ return i
176
+ elsif i+1 < array.length and array[i] < target && array[i+1]>target
177
+ return i
178
+ else
179
+ raise ArgumentError
180
+ end
181
+ else
182
+ j = i + n / 2
183
+ if array[j] <= target
184
+ return binarySearch(array, target, j, n - n/2)
185
+ else
186
+ return binarySearch(array, target, i, n/2)
187
+ end
188
+ end
189
+ end
190
+ end
191
+
192
+ end
@@ -0,0 +1,94 @@
1
+ module GerbilCharts::Models
2
+
3
+ # Presets base class for all ranges
4
+ #
5
+ # Preset values for ranges. So we do not scale charts arbitrarily
6
+ # and the label values are neat and clean
7
+ #
8
+ class Presets
9
+
10
+ protected
11
+ PRESETS = [
12
+ [0,0], [1,0.2], [5,1], [10,1],[20,5],
13
+ [50,10],[100,25],[200,50], [500,100], [1000,200],
14
+ [2000,500], [5000,1000], [8000,2000], [10000,2000],
15
+ [20000,5000], [50000,10000], [100000,25000], [200000,50000],
16
+ [500000,100000],[800000,200000],
17
+ [1000000,200000],[2000000,500000], [3000000,500000], [4000000,1000000],
18
+ [5000000,1000000],[6000000, 1500000],
19
+ [10000000,2500000], [20000000,4000000], [50000000, 10000000],
20
+ [100000000,25000000], [500000000,100000000],
21
+ [1000000000,250000000]
22
+ ]
23
+
24
+ TIMEPRESETS = [
25
+ [0,0], [1,0.2], [5,1], [10,1],[20,5],
26
+ [30,10],[60,10],[120,15], [300,60], [600,120],
27
+ [900,300], [1800,300],
28
+ [3600,900], [7200,1800],[10800,3600], [14400,3600], [21600,7200],
29
+ [43200, 10800], [86400,21600],
30
+ [172800, 43200], [259200,86400],
31
+ [604800, 86400], [1209600,172800],
32
+ [2419200, 604800],
33
+ [7257600, 2419200],
34
+ [14515200,7257600],
35
+ [29030400,7257600],
36
+ ]
37
+
38
+ UNITPRESETS = [
39
+ [1e+12, "T"],
40
+ [1e+09, "G"],
41
+ [1e+06, "M"],
42
+ [1e+03, "K"],
43
+ [1, ""],
44
+ [1e-03, "m"],
45
+ [1e-06, "u"],
46
+ [1e-09, "n"],
47
+ [1e-12, "p"],
48
+ ]
49
+
50
+ PRESET_VAL_POS=0
51
+ PRESET_LABEL_POS=1
52
+
53
+
54
+ # Formats a number with a units suffix
55
+ # So a number like 11899833 = 11.90 M
56
+ def format_suffix raw_value
57
+ return "0" if raw_value == 0
58
+ UNITPRESETS.each do |unit|
59
+ if raw_value >= unit[0]
60
+ retval = raw_value / unit[0]
61
+ sout=format("%.2f %s", retval, unit[1])
62
+ sout.gsub! ".00",""
63
+ return sout
64
+ end
65
+ end
66
+ return raw_value.to_s
67
+ end
68
+
69
+ # Formats a time value : based on available interval
70
+ # tvsec = seconds since Jan 1 1970
71
+ # interval = desired window in seconds
72
+ def format_timeval ( tvsec, interval)
73
+ t = Time.at(tvsec).getlocal
74
+ if interval < 60
75
+ return t.strftime("%M:%S")
76
+ elsif interval < 300
77
+ return t.strftime("%M:%S")
78
+ elsif interval < 3600
79
+ return t.strftime("%H:%M")
80
+ elsif interval < 86400
81
+ return t.strftime("%H:%M")
82
+ elsif interval < 259200
83
+ return t.strftime("%a-%H:%M")
84
+ elsif interval < 604800
85
+ return t.strtime("%b-%d")
86
+ elsif interval < 2419200
87
+ return t.strftime("%b-%d")
88
+ else
89
+ return t.strftime("%b")
90
+ end
91
+ end
92
+ end
93
+
94
+ end
@@ -0,0 +1,68 @@
1
+ module GerbilCharts::Models
2
+
3
+ # RawRange
4
+ # Maintains a range when values are added to a model
5
+ # This tracks the raw min/max values
6
+ class RawRange < Presets
7
+
8
+ attr_reader :rmax,:rmin
9
+
10
+ def initialize
11
+ @rmax,@rmin=nil,nil
12
+ end
13
+
14
+ # update - updates the range
15
+ # newval - new incoming value
16
+ #
17
+ def update(newval)
18
+ @rmax=newval if @rmax.nil? or newval > @rmax
19
+ @rmin=newval if @rmin.nil? or newval < @rmin
20
+ end
21
+
22
+ # update - updates the range (using another range)
23
+ # newval - new range
24
+ #
25
+ def update_r(range)
26
+ update(range.rmax)
27
+ update(range.rmin)
28
+ end
29
+
30
+
31
+ # returns the min/max
32
+ #
33
+ def min_max
34
+ yield @rmin,@rmax if block_given?
35
+ return @rmin,@rmax
36
+ end
37
+
38
+ def reset
39
+ @rmin,@rmax=nil,nil
40
+ end
41
+
42
+ def to_s
43
+ "Min = #{@rmin} Max=#{@rmax}"
44
+ end
45
+
46
+ def delta
47
+ return @rmax-@rmin
48
+ end
49
+
50
+ # scales a value with respect to the range
51
+ # val = scale this value
52
+ def scale_factor(val)
53
+ f = (val-@rmin).to_f/(@rmax-@rmin).to_f
54
+ return f
55
+ end
56
+
57
+ def zeromin
58
+ @rmin=0
59
+ end
60
+
61
+ def format_value(val)
62
+ return format_suffix(val)
63
+ end
64
+
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,104 @@
1
+ module GerbilCharts::Models
2
+
3
+ # A rounded range from a raw range
4
+ # Example : RawRange (102,8991) = RoundRange (100,10K)
5
+ #
6
+ class RoundRange < RawRange
7
+
8
+ attr_reader :lmax
9
+
10
+ # given a raw range, we calculate a round range
11
+ def initialize(raw_range)
12
+ super()
13
+ @rmin=round_min(raw_range.rmin)
14
+ @rmax=round_max(raw_range.rmax)
15
+ @lmax=label_step
16
+ end
17
+
18
+ # provide labels
19
+ # yields two items (value,string label)
20
+ #
21
+ # Usage example:
22
+ # r.each_label do |v,s|
23
+ # p "Value = #{v} Label String = #{s}"
24
+ # end
25
+ #
26
+ def each_label
27
+
28
+ raise "Range not aligned with presets (call round range first)" if not @lmax
29
+ raise "No data points in model" if @rmax == -1
30
+ return if @lmax == 0
31
+
32
+ if @rmin % @lmax != 0
33
+ v = (@rmin+@lmax) - (@rmin%@lmax)
34
+ else
35
+ v = @rmin
36
+ end
37
+ while (v<=@rmax) do
38
+ yield v, format_suffix(v)
39
+ v = v+@lmax
40
+ end
41
+ end
42
+
43
+ # provide ticks (per label interval)
44
+ def each_tick(tpl)
45
+
46
+ raise "Range not aligned with presets (call round range first)" if not @lmax
47
+
48
+ lint = @lmax/tpl
49
+ if @rmin % lint != 0
50
+ v = (@rmin+lint) - (@rmin%lint)
51
+ else
52
+ v = @rmin
53
+ end
54
+ while (v<@rmax) do
55
+ yield v
56
+ v = v+lint
57
+ end
58
+ end
59
+
60
+ private
61
+ # round_max (ceiling)
62
+ def round_max(raw)
63
+ last_pre=1
64
+ if raw > PRESETS.last[0]
65
+ return raw
66
+ else
67
+ PRESETS.reverse_each do |pre|
68
+ break if pre[0] < raw
69
+ last_pre=pre[0]
70
+ end
71
+ end
72
+ return last_pre
73
+ end
74
+
75
+ # round_min (floor)
76
+ def round_min(raw)
77
+ last_pre=0
78
+ PRESETS.each do |pre|
79
+ break if pre[0] > raw
80
+ last_pre=pre[0]
81
+ end
82
+ return last_pre
83
+ end
84
+
85
+ # labels
86
+ def label_step
87
+ del = @rmax-@rmin
88
+
89
+ last_pre=0.2
90
+ if del > PRESETS.last[0]
91
+ return del/10
92
+ else
93
+ PRESETS.reverse_each do |pre|
94
+ break if pre[0] < del
95
+ last_pre=pre[1]
96
+ end
97
+ end
98
+ return last_pre
99
+ end
100
+
101
+ end
102
+
103
+ end
104
+