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,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
+ }