gerbilcharts 0.0.3

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