gerbilcharts 0.2.13 → 0.5.9

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 (57) hide show
  1. data/History.txt +35 -0
  2. data/Manifest.txt +8 -0
  3. data/README.txt +8 -8
  4. data/lib/gerbilcharts/charts.rb +3 -0
  5. data/lib/gerbilcharts/charts/bubble_chart.rb +30 -0
  6. data/lib/gerbilcharts/charts/conversation_ring.rb +31 -0
  7. data/lib/gerbilcharts/charts/line_chart.rb +1 -0
  8. data/lib/gerbilcharts/charts/matrix_chart.rb +32 -0
  9. data/lib/gerbilcharts/charts/square_line_chart.rb +7 -0
  10. data/lib/gerbilcharts/models.rb +1 -0
  11. data/lib/gerbilcharts/models/bucketized_timeseries_graph_model.rb +1 -1
  12. data/lib/gerbilcharts/models/graph_model_group.rb +19 -2
  13. data/lib/gerbilcharts/models/matrix_model.rb +85 -0
  14. data/lib/gerbilcharts/models/monotonous_graph_model.rb +5 -1
  15. data/lib/gerbilcharts/models/presets.rb +18 -11
  16. data/lib/gerbilcharts/models/raw_range.rb +1 -1
  17. data/lib/gerbilcharts/models/round_range.rb +3 -1
  18. data/lib/gerbilcharts/models/round_time_range.rb +19 -29
  19. data/lib/gerbilcharts/models/sampled_timeseries_graph_model.rb +1 -1
  20. data/lib/gerbilcharts/public/brushmetal.css +123 -74
  21. data/lib/gerbilcharts/public/gerbil.js +104 -64
  22. data/lib/gerbilcharts/surfaces.rb +3 -0
  23. data/lib/gerbilcharts/surfaces/bubble_surface.rb +105 -0
  24. data/lib/gerbilcharts/surfaces/chart.rb +4 -2
  25. data/lib/gerbilcharts/surfaces/conversation_ring.rb +64 -0
  26. data/lib/gerbilcharts/surfaces/detailed_legend.rb +35 -13
  27. data/lib/gerbilcharts/surfaces/graph_element.rb +8 -1
  28. data/lib/gerbilcharts/surfaces/grid.rb +8 -2
  29. data/lib/gerbilcharts/surfaces/horizontal_axis.rb +12 -3
  30. data/lib/gerbilcharts/surfaces/horizontal_time_axis.rb +5 -4
  31. data/lib/gerbilcharts/surfaces/impulse_surface.rb +1 -1
  32. data/lib/gerbilcharts/surfaces/legend.rb +43 -6
  33. data/lib/gerbilcharts/surfaces/mark_band.rb +17 -1
  34. data/lib/gerbilcharts/surfaces/matrix_surface.rb +87 -0
  35. data/lib/gerbilcharts/surfaces/pie_surface.rb +109 -96
  36. data/lib/gerbilcharts/surfaces/rect.rb +18 -0
  37. data/lib/gerbilcharts/surfaces/stacked_area_surface.rb +42 -2
  38. data/lib/gerbilcharts/surfaces/stacked_grid.rb +1 -3
  39. data/lib/gerbilcharts/surfaces/title_panel.rb +7 -2
  40. data/lib/gerbilcharts/surfaces/tracker.rb +4 -1
  41. data/lib/gerbilcharts/surfaces/vertical_axis.rb +2 -2
  42. data/lib/gerbilcharts/svgdc.rb +1 -0
  43. data/lib/gerbilcharts/svgdc/css_inliner.rb +2 -2
  44. data/lib/gerbilcharts/svgdc/svg_ellipse.rb +21 -0
  45. data/lib/gerbilcharts/svgdc/svg_polygon.rb +19 -0
  46. data/lib/gerbilcharts/svgdc/svgdc.rb +4 -1
  47. data/lib/gerbilcharts/version.rb +2 -3
  48. data/test/test_bar.rb +1 -1
  49. data/test/test_bubble.rb +52 -0
  50. data/test/test_conversation.rb +34 -0
  51. data/test/test_lines.rb +3 -3
  52. data/test/test_matrix.rb +34 -0
  53. data/test/test_noob.rb +9 -6
  54. data/test/test_pie.rb +2 -2
  55. data/test/test_ranges.rb +15 -2
  56. data/test/test_sa.rb +88 -0
  57. metadata +14 -2
@@ -19,14 +19,22 @@ function OpacityDown(mouseover_evt)
19
19
  var obj=mouseover_evt.target;
20
20
  obj.style.setProperty("opacity","0.5","");
21
21
  }
22
-
23
-
24
22
  function OpacityUp(mouseout_evt)
25
23
  {
26
24
  var obj=mouseout_evt.target;
27
25
  obj.style.setProperty("opacity","1.0","");
28
26
  }
29
-
27
+ function ToggleVisibility(id)
28
+ {
29
+ var worker = function(ai) {
30
+ var cv=ai.getAttributeNS(null,"visibility");
31
+ ai.setAttributeNS(null,"visibility",cv=="hidden"?"":"hidden");
32
+ $("lbx"+id).setAttributeNS(null,"fill",cv=="hidden"?"gray":"red");
33
+ };
34
+
35
+ $$("#item"+id).each(worker);
36
+ $$("#lineitem"+id).each(worker);
37
+ }
30
38
  function GerbilNavigate()
31
39
  {
32
40
  window.top.location='/dashboard/show';
@@ -86,6 +94,20 @@ function showDetailedLegend()
86
94
  l_show.setAttributeNS(null, 'visibility', 'visible');
87
95
  }
88
96
  }
97
+ // Move legend panel
98
+ function shiftLegend(xoffset)
99
+ {
100
+ var l_det = SVGDocument.getElementById("legendpanel_detail");
101
+ if (l_det)
102
+ {
103
+ l_det.setAttributeNS(null, 'transform', 'translate('+xoffset+')');
104
+ }
105
+ var l_mini= SVGDocument.getElementById("legendpanel_mini");
106
+ if (l_mini)
107
+ {
108
+ l_mini.setAttributeNS(null, 'transform', 'translate('+xoffset+')');
109
+ }
110
+ }
89
111
 
90
112
  // The chart needs to fill in the following options
91
113
  // axurl , response will either do noop/full/delta replacement
@@ -108,17 +130,17 @@ function SvgAjaxUpdate()
108
130
  });
109
131
  hContext.unset('_object');
110
132
 
111
- // console.log ("URL = "+ url );
112
133
  new Ajax.Request(url, {
113
134
  method: 'post',
114
- parameters: { 'resource': hContext['resource'] },
135
+ parameters: {'resource': hContext['resource']},
115
136
  onSuccess: function(transport) {
116
- updateSVG(transport.responseXML)
137
+ updateSVG(transport.responseXML);
117
138
  }
118
139
  });
119
140
 
141
+ SVGRoot.setAttributeNS(null, 'lastupdategmt', parseInt(new Date().getTime()/1000) );
120
142
  }
121
- // For WebTrisul 1.0, we don't yet support delta replace,
143
+ // For WebTrisul 1.x, we don't yet support delta replace,
122
144
  // full replace seems to be fast enough (caching on server side)
123
145
  function updateSVG(node)
124
146
  {
@@ -162,10 +184,9 @@ function Uninit(evt)
162
184
  hContext[at.localName]=at.nodeValue;
163
185
  });
164
186
 
165
- // console.log ("URL = "+ url );
166
187
  new Ajax.Request("/axupdate/gerbilUnload", {
167
188
  method: 'post',
168
- parameters: { 'resource': hContext['resource'] },
189
+ parameters: {'resource': hContext['resource']}
169
190
  });
170
191
  }
171
192
 
@@ -198,7 +219,7 @@ function Init(evt)
198
219
  // for Adobe SVG later
199
220
  // setTimeout("SvgAjaxUpdate()",parseInt(ajaxInterval));
200
221
  }
201
- };
222
+ }
202
223
 
203
224
 
204
225
  function GetTrueCoords(evt)
@@ -208,69 +229,69 @@ function GetTrueCoords(evt)
208
229
  var translation = SVGRoot.currentTranslate;
209
230
  TrueCoords.x = (evt.clientX - translation.x)/newScale;
210
231
  TrueCoords.y = (evt.clientY - translation.y)/newScale;
211
- };
232
+ }
212
233
 
213
234
 
214
235
  function HideTooltip( evt )
215
236
  {
216
237
  toolTip.setAttributeNS(null, 'visibility', 'hidden');
217
- };
238
+ }
218
239
 
219
240
 
220
241
  function ShowTooltip( evt )
221
242
  {
222
- // bail out early, if same target
223
- var targetElement = evt.target;
224
- if ( lastElement == targetElement )
225
- {
226
- return
227
- }
243
+ // bail out early, if same target
244
+ var targetElement = evt.target;
245
+ if ( lastElement == targetElement )
246
+ {
247
+ return
248
+ }
228
249
 
229
- // bail out early, if no 'gerbiltooltipX' tags
230
- // tooltip1 is the heading (appears in bold face)
231
- // tooltip2 is the tip text
232
- var tooltip1 = '';
233
- var tooltip2 = '';
234
- tooltip1 = targetElement.getAttributeNS(null, 'gerbiltooltip1');
235
- tooltip2 = targetElement.getAttributeNS(null, 'gerbiltooltip2');
236
- if (tooltip1=='' && tooltip2 == '')
237
- {
238
- return;
239
- }
250
+ // bail out early, if no 'gerbiltooltipX' tags
251
+ // tooltip1 is the heading (appears in bold face)
252
+ // tooltip2 is the tip text
253
+ var tooltip1 = '';
254
+ var tooltip2 = '';
255
+ tooltip1 = targetElement.getAttributeNS(null, 'gerbiltooltip1');
256
+ tooltip2 = targetElement.getAttributeNS(null, 'gerbiltooltip2');
257
+ if (tooltip1=='' && tooltip2 == '')
258
+ {
259
+ return;
260
+ }
240
261
 
241
- // Positon the tooltip box relative to the mouse pos
242
- GetTrueCoords( evt );
243
- var tipScale = 1/SVGRoot.currentScale;
244
- var textWidth = 0;
245
- var tspanWidth = 0;
246
- var boxHeight = 20;
247
- tipBox.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
248
- tipText.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
262
+ // Positon the tooltip box relative to the mouse pos
263
+ GetTrueCoords( evt );
264
+ var tipScale = 1/SVGRoot.currentScale;
265
+ var textWidth = 0;
266
+ var tspanWidth = 0;
267
+ var boxHeight = 20;
268
+ tipBox.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
269
+ tipText.setAttributeNS(null, 'transform', 'scale(' + tipScale + ',' + tipScale + ')' );
249
270
 
250
- // Values for tooltip text
251
- tipTitle.firstChild.nodeValue = tooltip1;
252
- tipTitle.setAttributeNS(null, 'display', 'inline' );
253
- tipDesc.firstChild.nodeValue = tooltip2;
254
- tipDesc.setAttributeNS(null, 'display', 'inline' );
271
+ // Values for tooltip text
272
+ tipTitle.firstChild.nodeValue = tooltip1;
273
+ tipTitle.setAttributeNS(null, 'display', 'inline' );
274
+ tipDesc.firstChild.nodeValue = tooltip2;
275
+ tipDesc.setAttributeNS(null, 'display', 'inline' );
255
276
 
256
277
 
257
- // Box size
278
+ // Box size
258
279
  var outline = tipText.getBBox();
259
280
  tipBox.setAttributeNS(null, 'width', Number(outline.width) + 10);
260
- tipBox.setAttributeNS(null, 'height', Number(outline.height));
281
+ tipBox.setAttributeNS(null, 'height', Number(outline.height) + 10);
261
282
 
262
283
 
263
284
  // Update position (keep tooltip inside client area ! )
264
- var yPos = TrueCoords.y + (10 * tipScale);
265
- if (yPos+Number(outline.height)>SVGRoot.height.baseVal.value)
266
- {
267
- yPos = SVGRoot.height.baseVal.value - Number(outline.height)
268
- }
285
+ var yPos = TrueCoords.y + (10 * tipScale);
286
+ if (yPos+Number(outline.height)>SVGRoot.height.baseVal.value)
287
+ {
288
+ yPos = SVGRoot.height.baseVal.value - Number(outline.height)
289
+ }
269
290
  var xPos = TrueCoords.x + (10 * tipScale);
270
- if (xPos+Number(outline.width)>SVGRoot.width.baseVal.value)
271
- {
272
- xPos = SVGRoot.width.baseVal.value - Number(outline.width)
273
- }
291
+ if (xPos+Number(outline.width)>SVGRoot.width.baseVal.value)
292
+ {
293
+ xPos = SVGRoot.width.baseVal.value - Number(outline.width)
294
+ }
274
295
 
275
296
  toolTip.setAttributeNS(null, 'transform', 'translate(' + xPos + ',' + yPos + ')');
276
297
  toolTip.setAttributeNS(null, 'visibility', 'visible');
@@ -310,13 +331,19 @@ function TrackerMouseDown( evt )
310
331
 
311
332
  // compute begin state
312
333
  pTrackerData = SVGDocument.getElementById('gtrackerdata');
313
- nTrackScale = parseInt(pTrackerData.getAttributeNS(null,"gerb_scale"));
334
+ nTrackScale = parseFloat(pTrackerData.getAttributeNS(null,"gerb_scale"));
314
335
  var from_secs = parseInt(pTrackerData.getAttributeNS(null,"gerb_fromts"));
315
-
336
+ var server_tz_offset = parseInt(pTrackerData.getAttributeNS(null,"gerb_tzoffset"));
337
+ var client_tz_offset = new Date().getTimezoneOffset() * 60;
338
+
339
+ // javascript returns utc-local, ruby returns local-utc (so the '+' )
340
+ tz_off = server_tz_offset + client_tz_offset;
341
+ tz_name= pTrackerData.getAttributeNS(null,"gerb_tzname");
342
+
316
343
  // clicked to time delta
317
344
  var xbegin = parseInt(SVGDocument.getElementById('trackerpanel').getAttributeNS(null,"x"));
318
345
  pTrackFromTS = new Date();
319
- pTrackFromTS.setTime(1000* (from_secs + (nTrackBegin-xbegin)*nTrackScale));
346
+ pTrackFromTS.setTime(1000* (tz_off + from_secs + (nTrackBegin-xbegin)*nTrackScale));
320
347
 
321
348
  // text svg elements
322
349
  pTrackTextFromTS=SVGDocument.getElementById('trackertextfromts');
@@ -326,46 +353,59 @@ function TrackerMouseDown( evt )
326
353
  pGTrackingRect.setAttributeNS(null,"visibility","hidden");
327
354
  pTrackingText.setAttributeNS(null,"visibility","hidden");
328
355
 
356
+ evt.preventDefault();
357
+
329
358
  }
330
359
 
331
360
  function TrackerMouseMove(evt)
332
361
  {
362
+
333
363
  if (fTracking==2 && evt.clientX > nTrackBegin)
334
364
  {
365
+
335
366
  var delta = nTrackCurrent-nTrackBegin;
336
367
  var mid = nTrackBegin+(delta)/2;
337
368
  nTrackCurrent=evt.clientX;
369
+
338
370
  pTrackingRect.setAttributeNS(null,"width",delta);
339
371
  pTrackingText.setAttributeNS(null,"transform","translate(" + mid + ')');
340
-
372
+
341
373
  // text box
342
374
  var szwin = FormatSecs(delta*nTrackScale)
343
- var szbegin = "Starting : " + pTrackFromTS.toLocaleString();
375
+ var szbegin = "Starting : " + pTrackFromTS.toLocaleString() + " " + tz_name;
344
376
  pTrackTextInterval.firstChild.nodeValue = szwin;
345
377
  pTrackTextFromTS.firstChild.nodeValue = szbegin;
378
+
346
379
  }
347
- else if (fTracking==1 && (evt.clientX-nTrackBegin) > 5 )
380
+ else if (fTracking==1 && (evt.clientX-nTrackBegin) > 5 )
348
381
  {
349
382
  // we need to move atleast 5 pixels to turn on tracking
350
383
  fTracking=2;
351
-
352
- // visibility on
384
+
385
+ // visibility on
353
386
  pGTrackingRect.setAttributeNS(null,"visibility","visible");
354
387
  pTrackingText.setAttributeNS(null,"visibility","visible");
388
+
389
+ parent.$('drillmod_tools').hide();
355
390
  }
391
+
356
392
  }
393
+
357
394
  function TrackerMouseUp(evt)
358
395
  {
396
+
359
397
  if (fTracking==2)
360
398
  {
361
399
  pTrackingRect=null;
362
400
  nTrackEnd=evt.clientX;
363
401
 
364
402
  pTrackerData.setAttributeNS(null,"gerb_selsecs",(nTrackEnd-nTrackBegin)*nTrackScale);
365
- pTrackerData.setAttributeNS(null,"gerb_selts", pTrackFromTS.getTime()/1000);
403
+ pTrackerData.setAttributeNS(null,"gerb_selts", pTrackFromTS.getTime()/1000-tz_off);
366
404
 
367
405
  }
368
406
  fTracking=0;
407
+ parent.$('drillmod_tools').show();
408
+
369
409
  }
370
410
 
371
411
  function FormatSecs(secs)
@@ -375,7 +415,7 @@ function FormatSecs(secs)
375
415
  } else if (secs>3600) {
376
416
  return "" + Math.floor(secs/3600) + " Hrs " + Math.round((secs%3600)/60) + " Mins";
377
417
  } else if (secs>60) {
378
- return "" + Math.floor(secs/60) + " Mins " + secs%60 + " Secs";
418
+ return "" + Math.floor(secs/60) + " Mins " + Math.round(secs%60) + " Secs";
379
419
  }
380
- return "" + secs + " Secs";
420
+ return "" + Math.round(secs) + " Secs";
381
421
  }
@@ -32,3 +32,6 @@ require 'gerbilcharts/surfaces/stacked_area_surface'
32
32
  require 'gerbilcharts/surfaces/surface_background'
33
33
  require 'gerbilcharts/surfaces/tracker'
34
34
  require 'gerbilcharts/surfaces/square_line_surface'
35
+ require 'gerbilcharts/surfaces/matrix_surface'
36
+ require 'gerbilcharts/surfaces/conversation_ring'
37
+ require 'gerbilcharts/surfaces/bubble_surface'
@@ -0,0 +1,105 @@
1
+ module GerbilCharts::Surfaces
2
+
3
+ #= Bubble Surface
4
+ # Data point represented by bubbles using a log scale count
5
+ # Control the color,thickness of the line via the stylesheet item lineitem1, lineitem2 etc
6
+ # Eg 27,500 = 2x10K bub + 7x1K bub + 5 100 bub (total = 14 bubbles)
7
+ #
8
+ # Supported global options
9
+ #
10
+ # [+scaling+] :auto, :auto_y0
11
+ #
12
+ class BubbleSurface < Surface
13
+
14
+ BUBGRAINS = [1e+9,1e+8,1e+7,1000000,100000,10000,1000,100,10,1]
15
+ SHAPESZ = [40, 36, 35, 34, 31, 30, 20, 16, 12,8]
16
+ RSCALE = 0.50
17
+
18
+ def initialize(opts={})
19
+ super(opts)
20
+ end
21
+
22
+ def int_render(g)
23
+ rx = parent.modelgroup.effective_round_range_x
24
+ ry = parent.modelgroup.cumulative_sweep_round_range_y0
25
+
26
+ # ajax if used
27
+ if parent.usesAjax?
28
+ set_ajaxSurfaceContext(rx.rmax,ry.rmax,"SA")
29
+ end
30
+
31
+ # prepare models for sweeping
32
+ sweep_pos= rx.rmin
33
+ sweep_to = rx.rmax
34
+ modnames = []
35
+ parent.modelgroup.each_model do | mod|
36
+ mod.begin_sweep
37
+ modnames << mod.name
38
+ end
39
+
40
+ # sweep interval
41
+ sweep_interval = parent.modelgroup.sweep_interval
42
+
43
+ rbub=@bounds.clone
44
+ rbub.clip_l(20)
45
+
46
+ # perform the sweep
47
+ while (sweep_pos<=sweep_to)
48
+
49
+ allshapes = []
50
+ xpos = scale_x sweep_pos,rx
51
+ rbub.translate_x xpos
52
+
53
+ parent.modelgroup.each_model_with_index do | mod, i|
54
+ val = mod.sweep(sweep_pos)
55
+ allshapes << valtocircles(val)
56
+ end
57
+
58
+ allshapes.each_with_index do |ai,i|
59
+
60
+ opts = {:id => "item#{i}"}
61
+ opts.store(:fill,color_for_id(i)) if i>10
62
+
63
+ if parent.get_global_option(:auto_tooltips,false)
64
+ opts.store(:gerbiltooltip1, modnames[i])
65
+ end
66
+
67
+
68
+ ai.each do |shp|
69
+ shp.x = rbub.left + rand*(rbub.width)
70
+ shp.y = rbub.bottom - rand*(rbub.height*0.75)
71
+ g.addshape(shp, opts)
72
+ end
73
+ end
74
+
75
+
76
+ sweep_pos += sweep_interval
77
+ end
78
+
79
+ end
80
+
81
+ # vartoradii
82
+ def valtocircles(val)
83
+
84
+ splitup=BUBGRAINS.collect do |grain_size|
85
+ n=(val/grain_size)
86
+ val = val%grain_size
87
+ (n*RSCALE).to_i
88
+ end
89
+
90
+
91
+ ret=[]
92
+ shapes=SHAPESZ.each_with_index do |s,i|
93
+ splitup[i].times do |t|
94
+ ret << GerbilCharts::SVGDC::SVGCircle.new(0, 0, s)
95
+ end
96
+ end
97
+
98
+ ret
99
+
100
+ end
101
+
102
+
103
+ end
104
+
105
+ end
@@ -67,6 +67,8 @@ class Chart < GraphElement
67
67
 
68
68
  def render(ropts={})
69
69
  svgdc = GerbilCharts::SVGDC::SVGDC.new(@bounds.width, @bounds.height)
70
+
71
+ svgdc.enable_tooltips get_global_option(:auto_tooltips,false)
70
72
 
71
73
  dolayout if @needslayout
72
74
 
@@ -79,8 +81,8 @@ class Chart < GraphElement
79
81
  end
80
82
 
81
83
 
82
- @filters.each { |f| svgdc.add_filter(f) }
83
-
84
+ # filters, javascripts, stylesheets
85
+ @filters.each { |f| svgdc.add_filter(f) }
84
86
  @javascripts.each { |scr| svgdc.add_javascriptfile(scr) }
85
87
  @stylesheets.each { |css| svgdc.add_stylesheetfile(css) }
86
88
 
@@ -0,0 +1,64 @@
1
+ module GerbilCharts::Surfaces
2
+
3
+ # Matrix Surface
4
+ # Conversation Chart is drawn
5
+ #
6
+ class ConversationRing < Surface
7
+
8
+ def initialize(opts={})
9
+ super(opts)
10
+ end
11
+
12
+ def int_render(g)
13
+ # any filters ?
14
+ if parent.get_global_option(:filter,false)
15
+ g.curr_win.add_options({:filter => "url(##{parent.get_global_option(:filter,false)})" })
16
+ end
17
+
18
+ # Draw an outer circle
19
+ center_x = (@bounds.width/2)
20
+ center_y = (@bounds.height/2) + @bounds.top + 10
21
+ radius_x = (@bounds.width/2 - 35)
22
+ radius_y = (@bounds.height/2 - 15)
23
+ g.addshape(GerbilCharts::SVGDC::SVGEllipse.new(center_x,center_y,radius_x,radius_y), :fill => '#FFD' )
24
+
25
+
26
+ parent.modelgroup.hash.each_pair do |key,value|
27
+ angle = 360/value.length
28
+ tot_angle = 0
29
+ # Draw the center circle
30
+ radius1 = 15
31
+ opts = {:id => "item0"}
32
+ g.addshape(GerbilCharts::SVGDC::SVGCircle.new(center_x,center_y,radius1),opts)
33
+ g.textout(center_x-30,center_y-20,key,:class => 'elementlabel')
34
+
35
+ # Draw the remaining circles proportion to the largest values
36
+ value.each_with_index do |item,i|
37
+ opts = {:id => "item#{i+1}"}
38
+ label= parent.modelgroup.zenduniq[i]
39
+ string = "(" + key + "-" + label + ")"
40
+
41
+ # Adding tool tips
42
+ if parent.get_global_option(:auto_tooltips,false)
43
+ opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
44
+ opts.store(:gerbiltooltip1, string)
45
+ opts.store(:gerbiltooltip2, "Volume #{GerbilCharts::Models::Presets.new.format_suffix(item)}")
46
+ end
47
+
48
+ # Calculating radius
49
+ radius1 = 20
50
+ effective_radius = (((item.to_f)/parent.modelgroup.sort[0].to_f).to_f * radius1)
51
+ effective_radius = [effective_radius,5.0].max
52
+
53
+ # draw out
54
+ cx = center_x + (Math.cos((Math::PI/180)*(angle+tot_angle))*(radius_x))
55
+ cy = center_y + (Math.sin((Math::PI/180)*(angle+tot_angle))*(radius_y))
56
+ g.addshape(GerbilCharts::SVGDC::SVGCircle.new(cx,cy,effective_radius),opts)
57
+ g.textout(cx-30,cy-15,label,:class => 'elementlabel')
58
+
59
+ tot_angle += angle
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end