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,105 @@
1
+ module GerbilCharts::Models
2
+
3
+ #
4
+ # rounded time range - Rounds the max to a nice preset
5
+ # This class allows for labels at clean intervals instead of
6
+ # "Jan 17 2008 11:27:92"
7
+ #
8
+ class RoundTimeRange < RawRange
9
+
10
+ attr_reader :ldelta # label delta seconds (eg label every = 2 hrs)
11
+ attr_reader :rdelta # range delta seconds (eg chart span = 6 hrs)
12
+
13
+ # given a raw range, we calculate a round range
14
+ def initialize(raw_range)
15
+ super()
16
+ @rdelta,@ldelta=round_delta(raw_range.delta)
17
+ @rmin=raw_range.rmin
18
+ @rmax=round_max(raw_range.rmax,@rdelta)
19
+ @gmhalfhour = Time.now.gmt_offset%3600
20
+ end
21
+
22
+ # provide labels
23
+ # Yields two items (value - seconds since Jan 1 1970, string label)
24
+ def each_label
25
+
26
+ raise "Range not aligned with presets (call round range first)" if not @ldelta
27
+
28
+ return if @ldelta == 0
29
+
30
+ if (@rmin.tv_sec % @ldelta) != @gmhalfhour
31
+ ni_sec = (@rmin.tv_sec+@ldelta)/@ldelta
32
+
33
+ # if labeling hours, make sure you account tz weirdness like india GMT +5:30
34
+ if @ldelta >= 3600
35
+ v = Time.at(@ldelta * ni_sec.to_i - @gmhalfhour)
36
+ else
37
+ v = Time.at(@ldelta * ni_sec.to_i)
38
+ end
39
+ else
40
+ v = @rmin
41
+ end
42
+
43
+ while (v<=@rmax) do
44
+ yield v, format_timeval(v,@rdelta)
45
+ v = v+@ldelta
46
+ end
47
+ end
48
+
49
+ # provide ticks (per label interval)
50
+ def each_tick(tpl)
51
+ raise "Range not aligned with presets (call round range first)" if not @ldelta
52
+
53
+ lint = @lmax/tpl
54
+ if @rmin % lint != 0
55
+ v = (@rmin+lint) - (@rmin%lint)
56
+ else
57
+ v = @rmin
58
+ end
59
+ while (v<@rmax) do
60
+ yield v
61
+ v = v+lint
62
+ end
63
+ end
64
+
65
+ # format min value completely
66
+ def format_min_value
67
+ t = Time.at(@rmin).getlocal
68
+ return t.to_s
69
+ end
70
+
71
+ private
72
+ # round_max (ceiling)
73
+ def round_max(raw, interval)
74
+ return 0 if interval == 0
75
+ ni_secs = (raw.tv_sec+interval)/interval
76
+ return Time.at(interval * ni_secs.to_i)
77
+ end
78
+
79
+ # round_min (floor)
80
+ def round_min(raw, interval)
81
+ ni_secs = (raw.tv_sec-interval)/interval
82
+ return Time.at(interval * ni_secs.to_i )
83
+ end
84
+
85
+ # rounded delta time
86
+ def round_delta(raw_delta)
87
+
88
+ last_pre=1
89
+ last_lab=1
90
+ if raw_delta > TIMEPRESETS.last[0]
91
+ return raw_delta,raw_delta/10
92
+ else
93
+ TIMEPRESETS.reverse_each do |pre|
94
+ break if pre[0] < raw_delta
95
+ last_pre=pre[0]
96
+ last_lab=pre[1]
97
+ end
98
+ end
99
+ return last_pre,last_lab
100
+ end
101
+
102
+
103
+ end
104
+
105
+ end
@@ -0,0 +1,80 @@
1
+ module GerbilCharts::Models
2
+
3
+
4
+ # = SampledTimeSeriesGraphModel
5
+ # Time series graph model with sample polling interval
6
+ # we expect discrete points at approx regular intervals
7
+ # a missing interval implies zero value !
8
+ #
9
+ # This class is mainly used for its sweep methods.
10
+ # TODO: Example here
11
+ #
12
+ class SampledTimeSeriesGraphModel < TimeSeriesGraphModel
13
+
14
+ attr_reader :bucketsize # sample interval (polling interval)
15
+
16
+ def initialize(name,bucketsize,opt={})
17
+ super(name,opt)
18
+ raise "Sampled time series model : required param bucketsize missing" unless opt[:bucketsize]
19
+ @bucketsize = opt[:bucketsize]
20
+ end
21
+
22
+ def sweep_interval
23
+ return @bucketsize
24
+ end
25
+
26
+ # begin a sweep session
27
+ def begin_sweep
28
+ @last_sweep_pos=0
29
+ end
30
+
31
+ # sweep this bucket
32
+ def sweep2(tval)
33
+
34
+ return 0 if @xarr.length == 0
35
+ return 0 if @last_sweep_pos >= @xarr.length
36
+
37
+ p "Sweep at tval = #{tval}"
38
+
39
+ xv=@xarr[@last_sweep_pos]
40
+ if bucket_diff(tval,xv) < 1
41
+ @last_sweep_pos+=1
42
+ return @yarr[@last_sweep_pos-1]
43
+ else
44
+ return 0
45
+ end
46
+ end
47
+
48
+ # sweep this bucket
49
+ def sweep(tval)
50
+
51
+ return 0 if @xarr.length == 0
52
+ return 0 if @last_sweep_pos >= @xarr.length
53
+
54
+
55
+ xv=@xarr[@last_sweep_pos]
56
+
57
+ if tval < xv
58
+ return 0
59
+ end
60
+
61
+ nBucks=bucket_diff(xv,tval)
62
+ if nBucks <= 1
63
+ @last_sweep_pos+=1
64
+ rval = @yarr[@last_sweep_pos-1]
65
+ else
66
+ @last_sweep_pos+= nBucks
67
+ end
68
+ return rval.nil? ? 0:rval
69
+
70
+ end
71
+
72
+ # how many buckets separate the two buckettimes
73
+ def bucket_diff(tv1,tv2)
74
+ return (tv2-tv1).abs / @bucketsize
75
+ end
76
+
77
+ end
78
+
79
+ end
80
+
@@ -0,0 +1,68 @@
1
+ module GerbilCharts::Models
2
+
3
+ # = SimpleTimeSeriesModelGroup
4
+ # A quick way to create a model group and models using a single statement.
5
+ # This works if all models have data points at fixed times.
6
+ #
7
+ # Example code :
8
+ #
9
+ # my_modelgroup = GerbilCharts::Models::SimpleTimeSeriesModelGroup.new
10
+ # (
11
+ # :title => "Sales figures",
12
+ # :timeseries => (1..6).collect { |month| Time.local(2008,month) },
13
+ # :models => [ ["Bruce", 1, 10, 18, 28, 80, 122],
14
+ # ["Rex" , 12,22, 45, 70, 218, 109],
15
+ # ["Buzo" , 0, 23, 25, 40, 18, 59]
16
+ # ]
17
+ # )
18
+ #
19
+ #
20
+ class SimpleTimeSeriesModelGroup < GraphModelGroup
21
+
22
+ attr_reader :discrete_range
23
+
24
+ # Create the model group
25
+ #
26
+ # [+title+] The name of the modelgroup, shows up as chart title (eg, "Sales Figures")
27
+ # [+timeseries+] An array of Time objects representing each datapoint
28
+ # [+models+] An array of models (array of name followed by values) eg, [ "Bruce", 0.1, 2.3, etc]
29
+ #
30
+ # All three are required parameters. If you want more flexibility then use a GraphModelGroup
31
+ # object directly. See SimpleTimeseriesModelGroup documentation for an example.
32
+ #
33
+ def initialize(opts)
34
+
35
+ raise "Required parameter :title missing" unless opts[:title]
36
+ raise "Required array parameter :timeseries missing" unless opts[:timeseries]
37
+ raise "Required models missing" unless opts[:models]
38
+
39
+ super(opts[:title])
40
+
41
+ # user supplied
42
+ tvals = opts[:timeseries]
43
+ modelitems = opts[:models]
44
+
45
+ # create a timeseries graph model using user supplied data
46
+ modelitems.each do |mitem|
47
+ mod = TimeSeriesGraphModel.new( mitem.shift )
48
+ mitem.each_with_index do | datapt, idx |
49
+ mod.add(tvals[idx], datapt) if idx < tvals.size
50
+ end
51
+ add(mod)
52
+ end
53
+
54
+ # a discrete range object
55
+ @discrete_range = DiscreteTimeRange.new(tvals)
56
+
57
+ end
58
+
59
+ # return a discrete range for the X items (timeseries)
60
+ def effective_round_range_x
61
+ return @discrete_range
62
+ end
63
+
64
+
65
+ end
66
+
67
+ end
68
+
@@ -0,0 +1,34 @@
1
+ module GerbilCharts::Models
2
+
3
+ # = TimeSeriesGraphModel
4
+ # time series graph model (special case of monotonous)
5
+ # we expect discrete points, mainly the x_values are interpreted as timestamp
6
+ # therefore we can construct the appropriate preset axis labels.
7
+ #
8
+ # Eg. We can create round labels such as 8:15 instead of 8:16:47
9
+ #
10
+ class TimeSeriesGraphModel < MonotonousGraphModel
11
+
12
+ def initialize(name,opt={})
13
+ super(name,opt)
14
+ @rounderx=RoundTimeRange
15
+ @roundery=RoundRange
16
+ end
17
+
18
+ def add(timeobj, val)
19
+ super timeobj, val
20
+ end
21
+
22
+ # crop older than the given timestamp
23
+ def crop_older(cutofftime)
24
+ crop_at(cutofftime)
25
+ end
26
+
27
+ # just a check if we need time series
28
+ def is_timeseries?
29
+ return true
30
+ end
31
+
32
+ end
33
+
34
+ end
@@ -0,0 +1,197 @@
1
+ .surfacepanel
2
+ {
3
+ fill: none;
4
+ stroke-width: 1;
5
+ stroke: black;
6
+ }
7
+ .gridlineh
8
+ {
9
+ stroke-width: 1;
10
+ stroke: lightgray;
11
+ }
12
+ .gridlinev
13
+ {
14
+ stroke-width: 1;
15
+ stroke: lightgray;
16
+ }
17
+ .surfaceback
18
+ {
19
+ fill: url(#vertgrad);
20
+ }
21
+ .axispanel
22
+ {
23
+ fill: lightgray;
24
+ }
25
+ .axistickmajor
26
+ {
27
+ stroke-width: 2;
28
+ stroke: black;
29
+ }
30
+ .axistickminor
31
+ {
32
+ stroke-width: 1;
33
+ stroke: black;
34
+ }
35
+ .panel
36
+ {
37
+ fill: white;
38
+ }
39
+ .legend
40
+ {
41
+ fill: red;
42
+ }
43
+ #item0
44
+ {
45
+ stroke: blue;
46
+ fill: blue;
47
+ }
48
+ #item1
49
+ {
50
+ stroke: red;
51
+ fill: red;
52
+ }
53
+ #item2
54
+ {
55
+ stroke: yellow;
56
+ fill: yellow ;
57
+ }
58
+ #item3
59
+ {
60
+ stroke: aqua;
61
+ fill: magenta;
62
+ }
63
+ #item4
64
+ {
65
+ stroke: gray;
66
+ fill: blue;
67
+ }
68
+ #item5
69
+ {
70
+ stroke: green;
71
+ fill: green;
72
+ }
73
+ #item6
74
+ {
75
+ stroke: orange;
76
+ fill: orange;
77
+ }
78
+ #item7
79
+ {
80
+ stroke: lime;
81
+ fill: violet;
82
+ }
83
+ #item8
84
+ {
85
+ stroke: brown;
86
+ fill: navy;
87
+ }
88
+ #lineitem0
89
+ {
90
+ stroke: blue;
91
+ stroke-width: 2;
92
+ }
93
+ #lineitem1
94
+ {
95
+ stroke: red;
96
+ stroke-width: 2;
97
+ }
98
+ #lineitem2
99
+ {
100
+ stroke: yellow;
101
+ stroke-width: 2;
102
+ }
103
+ #lineitem3
104
+ {
105
+ stroke: aqua;
106
+ stroke-width: 2;
107
+ }
108
+ #lineitem4
109
+ {
110
+ stroke: gray;
111
+ stroke-width: 2;
112
+ }
113
+ #lineitem5
114
+ {
115
+ stroke: green;
116
+ stroke-width: 2;
117
+ }
118
+ #lineitem6
119
+ {
120
+ stroke: orange;
121
+ stroke-width: 2;
122
+ }
123
+ #lineitem7
124
+ {
125
+ stroke: lime;
126
+ stroke-width: 2;
127
+ }
128
+ #lineitem8
129
+ {
130
+ stroke: brown;
131
+ stroke-width: 2;
132
+ }
133
+ .axislabel
134
+ {
135
+ font-family: sans;
136
+ font-size: 10px;
137
+ fill: black;
138
+ stroke: none;
139
+ }
140
+
141
+ .axislabelt0
142
+ {
143
+ font-family: sans;
144
+ font-size: 8px;
145
+ fill: black;
146
+ stroke: none;
147
+ }
148
+ .titletext
149
+ {
150
+ fill: gray;
151
+ stroke: none;
152
+ font-family: Arial, Helvetica, sans-serif;;
153
+ font-size: 24px;
154
+ font-weight: bold;
155
+ }
156
+ .titlepanel
157
+ {
158
+ fill: white;
159
+ fill-opacity: 0.5;
160
+ }
161
+ .legendpanel
162
+ {
163
+ fill: white;
164
+ fill-opacity: 0.5;
165
+ }
166
+ .legendtext
167
+ {
168
+ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
169
+ font-size: 10px;
170
+ fill: black;
171
+ stroke: none;
172
+ }
173
+ .elementlabel
174
+ {
175
+ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
176
+ font-size: 10px;
177
+ }
178
+ .trackerpanel
179
+ {
180
+ fill: yellow;
181
+ fill-opacity: 0.5;
182
+ }
183
+ .trackerrect
184
+ {
185
+ fill: red;
186
+ fill-opacity: 0.2;
187
+ }
188
+ .trackertextinterval
189
+ {
190
+ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
191
+ font-size: 14px;
192
+ }
193
+ .trackertextfromts
194
+ {
195
+ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
196
+ font-size: 10px;
197
+ }