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,327 @@
1
+ var SVGDocument = null;
2
+ var SVGRoot = null;
3
+ var SVGViewBox = null;
4
+ var svgns = 'http://www.w3.org/2000/svg';
5
+ var xlinkns = 'http://www.w3.org/1999/xlink';
6
+ var toolTip = null;
7
+ var TrueCoords = null;
8
+ var tipBox = null;
9
+ var tipText = null;
10
+ var tipTitle = null;
11
+ var tipDesc = null;
12
+ var ajaxPE = null;
13
+ var lastElement = null;
14
+ var titleText = '';
15
+ var titleDesc = '';
16
+
17
+ function OpacityDown(mouseover_evt)
18
+ {
19
+ var obj=mouseover_evt.target;
20
+ obj.style.setProperty("opacity","0.5","");
21
+ }
22
+
23
+
24
+ function OpacityUp(mouseout_evt)
25
+ {
26
+ var obj=mouseout_evt.target;
27
+ obj.style.setProperty("opacity","1.0","");
28
+ }
29
+
30
+ function GerbilNavigate()
31
+ {
32
+ window.top.location='/dashboard/show';
33
+ }
34
+
35
+ function parseXMLFromString(text)
36
+ {
37
+ if (typeof DOMParser != "undefined")
38
+ {
39
+ // Mozilla, Firefox, and related browsers
40
+ return (new DOMParser()).parseFromString(text, "application/xml");
41
+ }
42
+ else if (typeof ActiveXObject != "undefined")
43
+ {
44
+ // Internet Explorer.
45
+ var xmlDOM = new ActiveXObject("Microsoft.XMLDOM");
46
+ var doc = xmlDOM.newDocument();
47
+ doc.loadXML(text);
48
+ return doc.documentElement;
49
+ }
50
+ return null;
51
+ }
52
+
53
+
54
+ function TestUpdates1(evt)
55
+ {
56
+ var tnode=SVGDocument.getElementById("graphtitle");
57
+ tnode.firstChild.nodeValue="Changed by Ajax2";
58
+ }
59
+
60
+ function TestAjaxUpdates()
61
+ {
62
+ var gerbilAjaxBlock=SVGDocument.getElementById("GerbilAjaxBlock");
63
+ var gerbilAjaxOptions=SVGDocument.getElementById("GerbilAjaxOptions");
64
+ var gerbilAjaxContext=SVGDocument.getElementById("GerbilAjaxContext");
65
+
66
+ // extract the URL & other ajax options from the Gerbil Ajax Block
67
+ var url = gerbilAjaxOptions.attributes.getNamedItem('axurl').nodeValue;
68
+ var freq = gerbilAjaxOptions.attributes.getNamedItem('axfrequency').nodeValue;
69
+ var decay = gerbilAjaxOptions.attributes.getNamedItem('axdecay').nodeValue;
70
+
71
+ // return the entire ajax context in request
72
+ var aa = $A(gerbilAjaxContext.attributes);
73
+ var hContext = new Hash();
74
+ aa.each(function (at){
75
+ hContext[at.localName]=at.nodeValue;
76
+ });
77
+
78
+ // console.log ("URL = "+ url );
79
+
80
+ new Ajax.Request(url, {
81
+ method: 'get',
82
+ parameters: hContext,
83
+ onSuccess: function(transport) {
84
+ updateSVG(transport.responseXML)
85
+ }
86
+ });
87
+
88
+ }
89
+ ///////////////////////////////////////////////////////////////////////////////
90
+ // Squirell Release 1.0 - uses Gerbil Charts that donot yet do delta replace !
91
+ ///////////////////////////////////////////////////////////////////////////////
92
+ function updateSVG(node)
93
+ {
94
+ var cmd = '';
95
+
96
+ cmd = node.documentElement.getAttribute("command")
97
+
98
+ if (cmd == "noop")
99
+ {
100
+ // do nothing (we got a noop ajax response)
101
+ }
102
+ else if (cmd=="full_replace")
103
+ {
104
+ var newnode = node.documentElement.childNodes[1];
105
+ var currnode = SVGDocument.getElementById('GerbilSVGGraph');
106
+ var par = currnode.parentNode;
107
+ var newLayer = SVGDocument.importNode(newnode,true);
108
+ par.appendChild(newLayer);
109
+ par.removeChild(currnode);
110
+
111
+ // move tooltip to top of rendering stack
112
+ par.removeChild(toolTip);
113
+ par.appendChild(toolTip);
114
+ }
115
+ }
116
+
117
+ function Init(evt)
118
+ {
119
+ SVGDocument = evt.target.ownerDocument;
120
+ SVGRoot = SVGDocument.documentElement;
121
+ TrueCoords = SVGRoot.createSVGPoint();
122
+
123
+ toolTip = SVGDocument.getElementById('ToolTip');
124
+ tipBox = SVGDocument.getElementById('tipbox');
125
+ tipText = SVGDocument.getElementById('tipText');
126
+ tipTitle = SVGDocument.getElementById('tipTitle');
127
+ tipDesc = SVGDocument.getElementById('tipDesc');
128
+ //window.status = (TrueCoords);
129
+
130
+ //create event for object
131
+ SVGRoot.addEventListener('mousemove', ShowTooltip, false);
132
+ SVGRoot.addEventListener('mouseout', HideTooltip, false);
133
+
134
+ // periodical executor
135
+ var gerbilAjaxOptions=SVGDocument.getElementById("GerbilAjaxOptions");
136
+ if (gerbilAjaxOptions!=null)
137
+ {
138
+ var ajaxInterval = gerbilAjaxOptions.getAttribute('axfrequency')
139
+ ajaxPE = new PeriodicalExecuter(TestAjaxUpdates,parseInt(ajaxInterval))
140
+ // for Adobe SVG later setTimeout("TestAjaxUpdates()",3)
141
+ }
142
+ };
143
+
144
+
145
+ function GetTrueCoords(evt)
146
+ {
147
+ // zoom / pan adjustment
148
+ var newScale = SVGRoot.currentScale;
149
+ var translation = SVGRoot.currentTranslate;
150
+ TrueCoords.x = (evt.clientX - translation.x)/newScale;
151
+ TrueCoords.y = (evt.clientY - translation.y)/newScale;
152
+ };
153
+
154
+
155
+ function HideTooltip( evt )
156
+ {
157
+ toolTip.setAttributeNS(null, 'visibility', 'hidden');
158
+ };
159
+
160
+
161
+ function ShowTooltip( evt )
162
+ {
163
+ // bail out early, if same target
164
+ var targetElement = evt.target;
165
+ if ( lastElement == targetElement )
166
+ {
167
+ return
168
+ }
169
+
170
+ // bail out early, if no 'gerbiltooltipX' tags
171
+ // tooltip1 is the heading (appears in bold face)
172
+ // tooltip2 is the tip text
173
+ var tooltip1 = '';
174
+ var tooltip2 = '';
175
+ tooltip1 = targetElement.getAttributeNS(null, 'gerbiltooltip1');
176
+ tooltip2 = targetElement.getAttributeNS(null, 'gerbiltooltip2');
177
+ if (tooltip1=='' && tooltip2 == '')
178
+ {
179
+ return;
180
+ }
181
+
182
+ // Positon the tooltip box relative to the mouse pos
183
+ GetTrueCoords( evt );
184
+ var tipScale = 1/SVGRoot.currentScale;
185
+ var textWidth = 0;
186
+ var tspanWidth = 0;
187
+ var boxHeight = 20;
188
+ tipBox.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
189
+ tipText.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
190
+
191
+ // Values for tooltip text
192
+ tipTitle.firstChild.nodeValue = tooltip1;
193
+ tipTitle.setAttributeNS(null, 'display', 'inline' );
194
+ tipDesc.firstChild.nodeValue = tooltip2;
195
+ tipDesc.setAttributeNS(null, 'display', 'inline' );
196
+
197
+
198
+ // Box size
199
+ var outline = tipText.getBBox();
200
+ tipBox.setAttributeNS(null, 'width', Number(outline.width) + 10);
201
+ tipBox.setAttributeNS(null, 'height', Number(outline.height));
202
+
203
+
204
+ // Update position (keep tooltip inside client area ! )
205
+ var yPos = TrueCoords.y + (10 * tipScale);
206
+ if (yPos+Number(outline.height)>SVGRoot.height.baseVal.value)
207
+ {
208
+ yPos = SVGRoot.height.baseVal.value - Number(outline.height)
209
+ }
210
+ var xPos = TrueCoords.x + (10 * tipScale);
211
+ if (xPos+Number(outline.width)>SVGRoot.width.baseVal.value)
212
+ {
213
+ xPos = SVGRoot.width.baseVal.value - Number(outline.width)
214
+ }
215
+
216
+ toolTip.setAttributeNS(null, 'transform', 'translate(' + xPos + ',' + yPos + ')');
217
+ toolTip.setAttributeNS(null, 'visibility', 'visible');
218
+ }
219
+
220
+
221
+
222
+ //////////////////////////////////////
223
+ // Tracker - for SVG
224
+ var fTracking=0;
225
+ var nTrackBegin=0;
226
+ var nTrackEnd=0;
227
+ var nTrackCurrent=0;
228
+ var pGTrackingRect=null;
229
+ var pTrackingRect=null;
230
+ var pTrackFromTS=null;
231
+ var nTrackScale=0;
232
+ var pTrackTextFromTS=null;
233
+ var pTrackTextInterval=null;
234
+ var pTrackerData=null;
235
+
236
+ function TrackerMouseDown( evt )
237
+ {
238
+ fTracking=1;
239
+ nTrackBegin=evt.clientX;
240
+ nTrackCurrent=evt.clientX;
241
+
242
+ SVGDocument = evt.target.ownerDocument;
243
+
244
+ pGTrackingRect= SVGDocument.getElementById('gtrackerrect');
245
+ pTrackingRect= SVGDocument.getElementById('trackerrect');
246
+ pTrackingRect.setAttributeNS(null,"x",nTrackCurrent);
247
+ pTrackingRect.setAttributeNS(null,"width",1);
248
+
249
+ pTrackingText= SVGDocument.getElementById('gtrackertext');
250
+ pTrackingText.setAttributeNS(null,"transform","translate(" + nTrackBegin + ',' + 150 + ')');
251
+
252
+ // compute begin state
253
+ pTrackerData = SVGDocument.getElementById('gtrackerdata');
254
+ nTrackScale = parseInt(pTrackerData.getAttributeNS(null,"gerb_scale"));
255
+ var from_secs = parseInt(pTrackerData.getAttributeNS(null,"gerb_fromts"));
256
+
257
+ // clicked to time delta
258
+ var xbegin = parseInt(SVGDocument.getElementById('trackerpanel').getAttributeNS(null,"x"));
259
+ pTrackFromTS = new Date();
260
+ pTrackFromTS.setTime(1000* (from_secs + (nTrackBegin-xbegin)*nTrackScale));
261
+
262
+ // text svg elements
263
+ pTrackTextFromTS=SVGDocument.getElementById('trackertextfromts');
264
+ pTrackTextInterval=SVGDocument.getElementById('trackertextinterval');
265
+
266
+ // visibility off (move 5-10 pixels to turn it on)
267
+ pGTrackingRect.setAttributeNS(null,"visibility","hidden");
268
+ pTrackingText.setAttributeNS(null,"visibility","hidden");
269
+
270
+ }
271
+
272
+ function TrackerMouseMove(evt)
273
+ {
274
+ if (fTracking==2 && evt.clientX > nTrackBegin)
275
+ {
276
+ var delta = nTrackCurrent-nTrackBegin;
277
+ var mid = nTrackBegin+(delta)/2;
278
+ nTrackCurrent=evt.clientX;
279
+ pTrackingRect.setAttributeNS(null,"width",delta);
280
+ pTrackingText.setAttributeNS(null,"transform","translate(" + mid + ')');
281
+
282
+ // text box
283
+ var szwin = FormatSecs(delta*nTrackScale)
284
+ var szbegin = "Starting : " + pTrackFromTS.toLocaleString();
285
+ pTrackTextInterval.firstChild.nodeValue = szwin;
286
+ pTrackTextFromTS.firstChild.nodeValue = szbegin;
287
+ }
288
+ else if (fTracking==1 && (evt.clientX-nTrackBegin) > 5 )
289
+ {
290
+ // we need to move atleast 5 pixels to turn on tracking
291
+ fTracking=2;
292
+
293
+ // visibility on
294
+ pGTrackingRect.setAttributeNS(null,"visibility","visible");
295
+ pTrackingText.setAttributeNS(null,"visibility","visible");
296
+ }
297
+ }
298
+ function TrackerMouseUp(evt)
299
+ {
300
+ if (fTracking==2)
301
+ {
302
+ pTrackingRect=null;
303
+ nTrackEnd=evt.clientX;
304
+
305
+ pTrackerData.setAttributeNS(null,"gerb_selsecs",(nTrackEnd-nTrackBegin)*nTrackScale);
306
+ pTrackerData.setAttributeNS(null,"gerb_selts", pTrackFromTS.getTime()/1000);
307
+
308
+ }
309
+ fTracking=0;
310
+ }
311
+
312
+ function FormatSecs(secs)
313
+ {
314
+ if (secs>86400)
315
+ {
316
+ return "" + Math.round(secs/86400) + " Days" + (secs%86400)/3600 + " Hrs" + Math.round((secs%3600)/60) + " Mins";
317
+ }
318
+ else if (secs>3600)
319
+ {
320
+ return "" + Math.round(secs/3600) + " Hrs " + Math.round((secs%3600)/60) + " Mins";
321
+ }
322
+ else if (secs>60)
323
+ {
324
+ return "" + Math.round(secs/60) + " Mins " + secs%60 + " Secs";
325
+ }
326
+ return "" + secs + " Secs";
327
+ }
@@ -0,0 +1,32 @@
1
+ # = GerbilCharts surfaces
2
+ #
3
+ # Surfaces use the facilities in the svg module to create
4
+ # bar, pie, line, area, and all other types of charts
5
+
6
+ module GerbilCharts::Surfaces
7
+ end
8
+
9
+ require 'gerbilcharts/surfaces/rect'
10
+ require 'gerbilcharts/surfaces/graph_element'
11
+ require 'gerbilcharts/surfaces/surface'
12
+ require 'gerbilcharts/surfaces/panel'
13
+ require 'gerbilcharts/surfaces/legend'
14
+ require 'gerbilcharts/surfaces/title_panel'
15
+ require 'gerbilcharts/surfaces/axis'
16
+ require 'gerbilcharts/surfaces/vertical_axis'
17
+ require 'gerbilcharts/surfaces/horizontal_axis'
18
+ require 'gerbilcharts/surfaces/horizontal_name_axis'
19
+ require 'gerbilcharts/surfaces/horizontal_time_axis'
20
+ require 'gerbilcharts/surfaces/grid'
21
+ require 'gerbilcharts/surfaces/basic_grid'
22
+ require 'gerbilcharts/surfaces/stacked_grid'
23
+ require 'gerbilcharts/surfaces/mark_band'
24
+ require 'gerbilcharts/surfaces/chart'
25
+ require 'gerbilcharts/surfaces/bar_surface'
26
+ require 'gerbilcharts/surfaces/area_surface'
27
+ require 'gerbilcharts/surfaces/impulse_surface'
28
+ require 'gerbilcharts/surfaces/line_surface'
29
+ require 'gerbilcharts/surfaces/pie_surface'
30
+ require 'gerbilcharts/surfaces/stacked_area_surface'
31
+ require 'gerbilcharts/surfaces/surface_background'
32
+ require 'gerbilcharts/surfaces/tracker'
@@ -0,0 +1,46 @@
1
+ module GerbilCharts::Surfaces
2
+
3
+ # == Area Surface w/ transparency
4
+ # The transparency kind of allows hidden items to be shown
5
+ #
6
+ class AreaSurface < Surface
7
+ def initialize(opts={})
8
+ super(opts)
9
+ end
10
+
11
+ def int_render(g)
12
+ rx = parent.modelgroup.effective_round_range_x
13
+ ry = parent.modelgroup.effective_round_range_y0
14
+
15
+ # ajax if used
16
+ if parent.usesAjax?
17
+ set_ajaxSurfaceContext(rx.rmax,ry.rmax,"AREA")
18
+ end
19
+
20
+
21
+ parent.modelgroup.each_model_with_index do | mod, i|
22
+
23
+ g.begin_polygon
24
+ firstpoint=true
25
+ xpos=0
26
+ ypos=0
27
+ mod.each_tuple do |x,y|
28
+ xpos = scale_x x,rx
29
+ ypos = scale_y y,ry
30
+ if firstpoint
31
+ g.polygon_point xpos,@bounds.bottom
32
+ firstpoint=false
33
+ end
34
+ g.polygon_point xpos,ypos
35
+ end
36
+ g.polygon_point xpos,@bounds.bottom
37
+ g.end_polygon(:id => "item#{i}", "opacity"=>"0.3")
38
+ g.rectangle(xpos+2*i,ypos,(i+1)*2,@bounds.bottom-ypos,{:id => "item#{i}"})
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+
46
+ end
@@ -0,0 +1,31 @@
1
+ module GerbilCharts::Surfaces
2
+
3
+ # == Axis - base for all axis types (attach to model)
4
+ #
5
+ class Axis < GraphElement
6
+ attr_reader :stagger_levels
7
+
8
+ def initialize(opts={})
9
+ super(opts)
10
+ set_defaults()
11
+ @stagger_levels = opts[:stagger] if opts[:stagger]
12
+ end
13
+
14
+ def set_defaults
15
+ @class = "axispanel"
16
+ @stagger_levels=1
17
+ end
18
+
19
+
20
+ def int_render(g)
21
+ g.rectangle_r(@bounds, {:class => @class})
22
+ end
23
+
24
+ def get_stagger_off(level, offset)
25
+ p "stager levles = #{@stagger_levels}"
26
+ return (level % @stagger_levels) * offset
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,62 @@
1
+ module GerbilCharts::Surfaces
2
+
3
+ # = Bar Surface
4
+ # Draws latest values from models in a bar chart
5
+ #
6
+ class BarSurface < Surface
7
+
8
+ attr_reader :element_width # optimum width of bar
9
+ attr_reader :element_spacing # optimum spacing between bars
10
+
11
+ def initialize(opts={})
12
+ super(opts)
13
+ @element_width = 20
14
+ @element_spacing = 25
15
+ end
16
+
17
+ def int_render(g)
18
+
19
+ # bail out of empty models quickly
20
+ if parent.modelgroup.empty?
21
+ g.textout(@bounds.left + @bounds.width/2, @bounds.height/2,
22
+ parent.modelgroup.empty_caption,{"text-anchor" => "middle"})
23
+ return
24
+ end
25
+
26
+ # see if the element spacing or width need to be adjusted to fit
27
+ nmodels = parent.modelgroup.count
28
+ delta = @bounds.width - (nmodels * (@element_width + @element_spacing) + @element_spacing)
29
+ p "delta = #{delta} width = #{@bounds.width}"
30
+ if delta < 0
31
+ delta_per_item = delta/(nmodels+1)
32
+ @element_width += delta_per_item
33
+ @element_spacing += delta_per_item
34
+ end
35
+ #p "Spacing = #{parent.anchor.element_spacing} spacing"
36
+
37
+ # atleast one model is present, chhug along
38
+ ry = parent.modelgroup.effective_round_range_y0
39
+ set_ajaxSurfaceContext(0,ry.rmax,"BAR") if parent.usesAjax?
40
+
41
+ xpos = @bounds.left + @element_spacing
42
+ parent.modelgroup.each_model_with_index do | mod, i|
43
+
44
+ y=mod.latest_val
45
+ ypos = scale_y y,ry
46
+
47
+ opts = {:id => "item#{i}", :onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)"}
48
+ opts.store(:href, mod.href) if mod.hasHref?
49
+ opts.store(:gerbiltooltip1, mod.userlabel1) if mod.hasUserTips?
50
+ opts.store(:gerbiltooltip2, mod.userlabel2) if mod.hasUserTips?
51
+
52
+ g.rectangle(xpos, ypos, @element_width, @bounds.bottom - ypos, opts)
53
+ g.textout(xpos+@element_width/2,ypos-5,mod.latest_formatted_val,{:class => "elementlabel", "text-anchor" => "middle"})
54
+ xpos += @element_spacing + @element_width
55
+
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+ end