gerbilcharts 0.1.9 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -0
- data/lib/gerbilcharts/models/round_time_range.rb +2 -2
- data/lib/gerbilcharts/public/brushmetal.css +2 -0
- data/lib/gerbilcharts/surfaces/bar_surface.rb +35 -35
- data/lib/gerbilcharts/surfaces/horizontal_axis.rb +1 -1
- data/lib/gerbilcharts/surfaces/horizontal_name_axis.rb +14 -10
- data/lib/gerbilcharts/surfaces/pie_surface.rb +61 -41
- data/lib/gerbilcharts/version.rb +2 -2
- data/test/test_bar.rb +36 -0
- data/test/test_pie.rb +5 -2
- metadata +3 -2
data/History.txt
CHANGED
@@ -16,7 +16,7 @@ class RoundTimeRange < RawRange
|
|
16
16
|
@rdelta,@ldelta=round_delta(raw_range.delta)
|
17
17
|
@rmin=raw_range.rmin
|
18
18
|
@rmax=round_max(raw_range.rmax,@rdelta)
|
19
|
-
|
19
|
+
@gmhalfhour = Time.now.gmt_offset%3600
|
20
20
|
end
|
21
21
|
|
22
22
|
# provide labels
|
@@ -71,7 +71,7 @@ class RoundTimeRange < RawRange
|
|
71
71
|
private
|
72
72
|
# round_max (ceiling)
|
73
73
|
def round_max(raw, interval)
|
74
|
-
return
|
74
|
+
return raw if interval == 0
|
75
75
|
ni_secs = (raw.tv_sec+interval)/interval
|
76
76
|
return Time.at(interval * ni_secs.to_i)
|
77
77
|
end
|
@@ -14,50 +14,50 @@ class BarSurface < Surface
|
|
14
14
|
@element_spacing = 25
|
15
15
|
end
|
16
16
|
|
17
|
-
def int_render(g)
|
17
|
+
def int_render(g)
|
18
|
+
# bail out of empty models quickly
|
19
|
+
if parent.modelgroup.empty?
|
20
|
+
g.textout(@bounds.left + @bounds.width/2, @bounds.height/2,
|
21
|
+
parent.modelgroup.empty_caption,{"text-anchor" => "middle"})
|
22
|
+
return
|
23
|
+
end
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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"
|
25
|
+
# see if the element spacing or width need to be adjusted to fit
|
26
|
+
nmodels = parent.modelgroup.count
|
27
|
+
delta = @bounds.width - (nmodels * (@element_width + @element_spacing) + @element_spacing)
|
28
|
+
if delta < 0
|
29
|
+
delta_per_item = delta/(nmodels+2)
|
30
|
+
@element_width += delta_per_item
|
31
|
+
@element_spacing = 2 * @element_width
|
32
|
+
end
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
# atleast one model is present, chhug along
|
35
|
+
range_options_y = parent.get_global_option(:scaling_y,:auto)
|
36
|
+
ry = parent.modelgroup.effective_range_y(range_options_y)
|
37
|
+
set_ajaxSurfaceContext(0,ry.rmax,"BAR") if parent.usesAjax?
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
xpos = @bounds.left + @element_spacing
|
40
|
+
parent.modelgroup.each_model_with_index do | mod, i|
|
45
41
|
y=mod.latest_val
|
46
42
|
ypos = scale_y y,ry
|
47
43
|
|
48
|
-
|
49
|
-
opts
|
50
|
-
|
51
|
-
|
44
|
+
# Adding tool tips to the rectangle
|
45
|
+
opts = {:id => "item#{i}"}
|
46
|
+
if parent.get_global_option(:auto_tooltips,false)
|
47
|
+
opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
|
48
|
+
opts.store(:gerbiltooltip1, mod.name)
|
49
|
+
opts.store(:gerbiltooltip2, "Val = #{mod.latest_val}")
|
50
|
+
end
|
52
51
|
|
52
|
+
# draw the abr
|
53
53
|
g.rectangle(xpos, ypos, @element_width, @bounds.bottom - ypos, opts)
|
54
|
-
g.textout(xpos+@element_width/2,ypos-5,
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
g.textout( xpos+@element_width/2, ypos-5,
|
55
|
+
mod.latest_formatted_val,
|
56
|
+
{:class => "elementlabel", "text-anchor" => "middle"}
|
57
|
+
)
|
58
|
+
xpos += @element_spacing + @element_width
|
59
|
+
end
|
59
60
|
end
|
60
|
-
|
61
61
|
end
|
62
62
|
|
63
63
|
end
|
@@ -11,16 +11,20 @@ class HorizontalNameAxis < Axis
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def int_render(g)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
14
|
+
super
|
15
|
+
xp = @bounds.left + parent.anchor.element_spacing + parent.anchor.element_width/2
|
16
|
+
parent.modelgroup.each_model_with_index do |m,i|
|
17
|
+
yoff=get_stagger_off(i,10)
|
18
|
+
#Adding tool tips to the text
|
19
|
+
opts = { :class => "axislabel"}
|
20
|
+
if parent.get_global_option(:auto_tooltips,false)
|
21
|
+
opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
|
22
|
+
opts.store(:gerbiltooltip1, m.name)
|
23
|
+
opts.store(:gerbiltooltip2, "Val = #{m.latest_val}")
|
24
|
+
end
|
25
|
+
g.textout(xp, @bounds.top+15+yoff, m.name[0..4], opts)
|
26
|
+
xp += parent.anchor.element_width + parent.anchor.element_spacing
|
27
|
+
end
|
24
28
|
end
|
25
29
|
|
26
30
|
end
|
@@ -2,6 +2,13 @@ module GerbilCharts::Surfaces
|
|
2
2
|
|
3
3
|
# = Pie Surface
|
4
4
|
class PieSurface < Surface
|
5
|
+
|
6
|
+
MIN_INSIDE_LABEL_ANGLE = 8 # do not draw outer label for small angles
|
7
|
+
MIN_OUTSIDE_LABEL_ANGLE = 3 # do not draw inner percentages (pie slice) for small angles
|
8
|
+
OUTER_OFFSET_X = 10 # x - distance offset from pie boundary
|
9
|
+
OUTER_OFFSET_Y = 10 # y - y offset from pie boundary
|
10
|
+
LEFT_LABEL_OFFSET = 30 # labels on the left of the PIE offset by this (90-270 deg)
|
11
|
+
|
5
12
|
def initialize(opts={})
|
6
13
|
super(opts)
|
7
14
|
end
|
@@ -33,54 +40,67 @@ class PieSurface < Surface
|
|
33
40
|
cy = @bounds.height/2
|
34
41
|
current_pos_x = cx + radius
|
35
42
|
current_pos_y = cy
|
36
|
-
|
37
|
-
|
43
|
+
|
38
44
|
# draw each slice
|
39
45
|
tot_angle =0
|
40
46
|
parent.modelgroup.each_model_with_index do | mod, i|
|
41
|
-
mod_angle = ((mod.latest_val*360).to_f)/(y_total.to_f)
|
42
|
-
half_angle = tot_angle + mod_angle/2
|
43
|
-
tot_angle = tot_angle + mod_angle
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
percent_pos_y = cy + ((Math.sin((Math::PI/180)*half_angle)*radius_label)*0.6)
|
54
|
-
|
55
|
-
opts = {:id => "item#{i}" }
|
56
|
-
g.addshape(GerbilCharts::SVGDC::SVGArc.new(cx,cy,radius,radius,
|
57
|
-
current_pos_x,current_pos_y,
|
58
|
-
new_pos_x,new_pos_y,mod_angle),
|
59
|
-
opts)
|
48
|
+
mod_angle = ((mod.latest_val*360).to_f)/(y_total.to_f)
|
49
|
+
half_angle = tot_angle + mod_angle/2
|
50
|
+
tot_angle = tot_angle + mod_angle
|
51
|
+
|
52
|
+
new_pos_x = cx + (Math.cos((Math::PI/180)*tot_angle)*radius)
|
53
|
+
new_pos_y = cy + (Math.sin((Math::PI/180)*tot_angle)*radius)
|
54
|
+
label_pos_x = cx + (Math.cos((Math::PI/180)*half_angle)*radius_label)
|
55
|
+
label_pos_y = cy + (Math.sin((Math::PI/180)*half_angle)*radius_label)
|
60
56
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
57
|
+
percent_mod = (mod.latest_val*360/y_total)
|
58
|
+
percent = (percent_mod*100/360)
|
59
|
+
percent_pos_x = cx + ((Math.cos((Math::PI/180)*half_angle)*radius_label)*0.6)
|
60
|
+
percent_pos_y = cy + ((Math.sin((Math::PI/180)*half_angle)*radius_label)*0.6)
|
61
|
+
|
62
|
+
|
63
|
+
# if tooltips enabled, user can position on pie slice
|
64
|
+
opts = {:id => "item#{i}"}
|
65
|
+
if parent.get_global_option(:auto_tooltips,false)
|
66
|
+
opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
|
67
|
+
opts.store(:gerbiltooltip1, mod.name)
|
68
|
+
opts.store(:gerbiltooltip2, "Val = #{mod.latest_val}")
|
68
69
|
end
|
69
|
-
|
70
|
-
|
71
|
-
g.
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
70
|
+
|
71
|
+
# draw the slice
|
72
|
+
g.addshape(GerbilCharts::SVGDC::SVGArc.new(cx,cy,radius,radius,
|
73
|
+
current_pos_x,current_pos_y,
|
74
|
+
new_pos_x,new_pos_y,mod_angle),
|
75
|
+
opts)
|
76
|
+
|
77
|
+
if(percent >= MIN_OUTSIDE_LABEL_ANGLE)
|
78
|
+
if(tot_angle > 270)
|
79
|
+
if(label_pos_x > cx ) && (label_pos_y > cy )
|
80
|
+
g.textout( label_pos_x, label_pos_y, "#{mod.latest_val}", :class => 'elementlabel')
|
81
|
+
g.textout(label_pos_x,label_pos_y+OUTER_OFFSET_Y, "#{mod.name}", :class => 'elementlabel' )
|
82
|
+
else
|
83
|
+
g.textout( label_pos_x+OUTER_OFFSET_X, label_pos_y, "#{mod.latest_val}", :class => 'elementlabel' )
|
84
|
+
g.textout( label_pos_x+OUTER_OFFSET_X, label_pos_y+OUTER_OFFSET_Y, "#{mod.name}", :class => 'elementlabel' )
|
85
|
+
end
|
86
|
+
elsif(label_pos_x > cx ) && (label_pos_y > cy )
|
87
|
+
g.textout( label_pos_x, label_pos_y, "#{mod.latest_val}", :class => 'elementlabel' )
|
88
|
+
g.textout( label_pos_x, label_pos_y+OUTER_OFFSET_Y, "#{mod.name}", :class => 'elementlabel' )
|
89
|
+
else
|
90
|
+
g.textout( label_pos_x-LEFT_LABEL_OFFSET, label_pos_y, "#{mod.latest_val}", :class => 'elementlabel' )
|
91
|
+
g.textout( label_pos_x-LEFT_LABEL_OFFSET, label_pos_y+OUTER_OFFSET_Y, "#{mod.name}", :class => 'elementlabel' )
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
77
95
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
96
|
+
if(percent > MIN_INSIDE_LABEL_ANGLE)
|
97
|
+
g.textout(percent_pos_x,percent_pos_y, "#{percent}%", :class => 'elementvalue')
|
98
|
+
end
|
99
|
+
|
100
|
+
current_pos_x = new_pos_x
|
101
|
+
current_pos_y = new_pos_y
|
102
|
+
|
103
|
+
end
|
84
104
|
end
|
85
105
|
end
|
86
106
|
end
|
data/lib/gerbilcharts/version.rb
CHANGED
data/test/test_bar.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
require 'trafgen'
|
4
|
+
|
5
|
+
# test pie chart
|
6
|
+
class TestBar < Test::Unit::TestCase
|
7
|
+
|
8
|
+
|
9
|
+
# test sales figures of 3 sales people
|
10
|
+
# show in a pie chart
|
11
|
+
def test_monthly_sales
|
12
|
+
modelgroup = GerbilCharts::Models::SimpleTimeSeriesModelGroup.new(
|
13
|
+
:title => "Sales figures",
|
14
|
+
:timeseries => (1..6).collect { |month| Time.local(2008,month) },
|
15
|
+
:models => [ ["Bruce", 1, 10, 18, 28, 80, 134],
|
16
|
+
["Rex" , 112,22, 45, 70, 218, 309],
|
17
|
+
["Sharmila", 112,22, 45, 70, 218, 245],
|
18
|
+
["Wasim", 112,22, 45, 70, 218, 145],
|
19
|
+
["Buzo" , 0, 23, 25, 40, 18, 59],
|
20
|
+
["Vipin", 145,112, 22, 45, 18, 70],
|
21
|
+
["label", 145,112, 22, 45, 18, 240],
|
22
|
+
["very very very long name 9th item ", 145,112, 22, 45, 18, 45],
|
23
|
+
["Others ", 145,112, 22, 45, 18, 15],
|
24
|
+
["VIVEK", 145,112, 22, 45, 18, 170]
|
25
|
+
]
|
26
|
+
)
|
27
|
+
mychart = GerbilCharts::Charts::BarChart.new( :width => 350, :height => 200,
|
28
|
+
:style => 'brushmetal.css', :auto_tooltips => true ,
|
29
|
+
:javascripts => {'javascripts/gerbil.js' => false, 'javascripts/prototype.js' => false}
|
30
|
+
)
|
31
|
+
mychart.modelgroup=modelgroup
|
32
|
+
mychart.render('/tmp/bar_monthly_sales.svg')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
data/test/test_pie.rb
CHANGED
@@ -20,14 +20,17 @@ class TestPie < Test::Unit::TestCase
|
|
20
20
|
["Wasim", 112,22, 45, 70, 218, 145],
|
21
21
|
["Buzo" , 0, 23, 25, 40, 18, 59],
|
22
22
|
["Vipin", 145,112, 22, 45, 18, 70],
|
23
|
-
["
|
23
|
+
["label", 145,112, 22, 45, 18, 240],
|
24
24
|
["9th item ", 145,112, 22, 45, 18, 45],
|
25
25
|
["Others ", 145,112, 22, 45, 18, 15],
|
26
26
|
["VIVEK", 145,112, 22, 45, 18, 170]
|
27
27
|
]
|
28
28
|
)
|
29
29
|
|
30
|
-
mychart = GerbilCharts::Charts::PieChart.new( :width => 350, :height => 200,
|
30
|
+
mychart = GerbilCharts::Charts::PieChart.new( :width => 350, :height => 200,
|
31
|
+
:style => 'brushmetal.css', :auto_tooltips => true ,
|
32
|
+
:javascripts => {'/tmp/gerbil.js' => false, '/tmp/prototype.js' => false}
|
33
|
+
)
|
31
34
|
mychart.modelgroup=modelgroup
|
32
35
|
mychart.render('/tmp/pie_monthly_sales.svg')
|
33
36
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gerbilcharts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vivek Rajagopalan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-09-
|
12
|
+
date: 2009-09-17 00:00:00 +05:30
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -154,6 +154,7 @@ test_files:
|
|
154
154
|
- test/test_noob.rb
|
155
155
|
- test/test_pie.rb
|
156
156
|
- test/test_render_string.rb
|
157
|
+
- test/test_bar.rb
|
157
158
|
- test/test_models.rb
|
158
159
|
- test/test_charts.rb
|
159
160
|
- test/test_scaling.rb
|