gerbilcharts 0.5.9 → 0.6.8
Sign up to get free protection for your applications and to get access to all the features.
- data/{License.txt → LICENSE.txt} +0 -0
- data/{README.txt → README.rdoc} +0 -0
- data/lib/gerbilcharts/charts.rb +2 -0
- data/lib/gerbilcharts/charts/chart_base.rb +1 -1
- data/lib/gerbilcharts/charts/line_chart_table.rb +38 -0
- data/lib/gerbilcharts/charts/stacked_area_chart_table.rb +31 -0
- data/lib/gerbilcharts/models/bucketized_timeseries_graph_model.rb +10 -7
- data/lib/gerbilcharts/models/graph_model_group.rb +1 -1
- data/lib/gerbilcharts/models/presets.rb +2 -2
- data/lib/gerbilcharts/models/raw_range.rb +1 -0
- data/lib/gerbilcharts/surfaces/area_surface.rb +46 -39
- data/lib/gerbilcharts/surfaces/conversation_ring.rb +7 -3
- data/lib/gerbilcharts/surfaces/detailed_legend.rb +15 -4
- data/lib/gerbilcharts/surfaces/impulse_surface.rb +10 -4
- data/lib/gerbilcharts/surfaces/line_surface.rb +31 -34
- data/lib/gerbilcharts/surfaces/square_line_surface.rb +27 -30
- data/lib/gerbilcharts/surfaces/surface.rb +27 -1
- data/lib/gerbilcharts/svgdc/svg_polygon.rb +14 -7
- data/lib/gerbilcharts/svgdc/svg_polyline.rb +8 -2
- data/lib/gerbilcharts/svgdc/svgdc.rb +8 -0
- data/lib/gerbilcharts/version.rb +2 -2
- metadata +118 -97
- data/History.txt +0 -105
- data/Manifest.txt +0 -92
- data/PostInstall.txt +0 -2
- data/Rakefile +0 -4
- data/lib/gerbilcharts/public/brushmetal.css +0 -284
- data/lib/gerbilcharts/public/gerbil.js +0 -421
- data/setup.rb +0 -1585
- data/test/test_Scratch.rb +0 -21
- data/test/test_bar.rb +0 -39
- data/test/test_bubble.rb +0 -52
- data/test/test_charts.rb +0 -122
- data/test/test_conversation.rb +0 -34
- data/test/test_embed_styles.rb +0 -35
- data/test/test_gerbilcharts.rb +0 -11
- data/test/test_helper.rb +0 -2
- data/test/test_lines.rb +0 -46
- data/test/test_matrix.rb +0 -34
- data/test/test_models.rb +0 -118
- data/test/test_negatives.rb +0 -39
- data/test/test_noob.rb +0 -86
- data/test/test_pie.rb +0 -43
- data/test/test_ranges.rb +0 -169
- data/test/test_render_string.rb +0 -38
- data/test/test_sa.rb +0 -88
- data/test/test_scaling.rb +0 -57
- data/test/test_svgdc.rb +0 -221
- data/test/trafgen.rb +0 -25
data/{License.txt → LICENSE.txt}
RENAMED
File without changes
|
data/{README.txt → README.rdoc}
RENAMED
File without changes
|
data/lib/gerbilcharts/charts.rb
CHANGED
@@ -19,3 +19,5 @@ require 'gerbilcharts/charts/square_line_chart'
|
|
19
19
|
require 'gerbilcharts/charts/matrix_chart'
|
20
20
|
require 'gerbilcharts/charts/conversation_ring'
|
21
21
|
require 'gerbilcharts/charts/bubble_chart'
|
22
|
+
require 'gerbilcharts/charts/line_chart_table'
|
23
|
+
require 'gerbilcharts/charts/stacked_area_chart_table'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module GerbilCharts::Charts
|
2
|
+
|
3
|
+
# =Line Chart Table
|
4
|
+
# Each model is a separate line & table legend is shown below chart
|
5
|
+
#
|
6
|
+
# options
|
7
|
+
#
|
8
|
+
# [+width+] Width of the chart (pixels)
|
9
|
+
# [+height+] Width of the chart (pixels)
|
10
|
+
# [+style+] Stylesheet file to be applied
|
11
|
+
#
|
12
|
+
# global visual options
|
13
|
+
# [+circle_data_points] draw a solid circle around each data point
|
14
|
+
#
|
15
|
+
class LineChartTable < ChartBase
|
16
|
+
|
17
|
+
def initialize(opt={})
|
18
|
+
super(opt)
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_chart_elements
|
22
|
+
|
23
|
+
# anchor (line surface)
|
24
|
+
@thechart.create_filter(GerbilCharts::SVGDC::LinearGradientVertical.new("vertgrad","rgb(255,255,255)","rgb(192,192,192)"))
|
25
|
+
|
26
|
+
# other elements
|
27
|
+
@thechart.add_child(GerbilCharts::Surfaces::SurfaceBackground.new(:orient => ORIENT_OVERLAY))
|
28
|
+
@thechart.add_child(GerbilCharts::Surfaces::BasicGrid.new(:orient => ORIENT_OVERLAY))
|
29
|
+
@thechart.add_child(GerbilCharts::Surfaces::TitlePanel.new(:orient => ORIENT_OVERLAY, :dim => 30))
|
30
|
+
@thechart.add_child(GerbilCharts::Surfaces::LineSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
31
|
+
@thechart.add_child(GerbilCharts::Surfaces::DetailedLegend.new(:orient=> ORIENT_SOUTH, :dim => 80 , :always_visible => true ))
|
32
|
+
@thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 ))
|
33
|
+
@thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module GerbilCharts::Charts
|
2
|
+
|
3
|
+
# = StackedAreaChart
|
4
|
+
# The models are stacked on top of each other !
|
5
|
+
#
|
6
|
+
class StackedAreaChartTable < ChartBase
|
7
|
+
|
8
|
+
def initialize(opt={})
|
9
|
+
super(opt)
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_chart_elements
|
13
|
+
|
14
|
+
# other elements
|
15
|
+
@thechart.add_child(GerbilCharts::Surfaces::SurfaceBackground.new(:orient => ORIENT_OVERLAY))
|
16
|
+
@thechart.add_child(GerbilCharts::Surfaces::StackedGrid.new(:orient => ORIENT_OVERLAY))
|
17
|
+
@thechart.add_child(GerbilCharts::Surfaces::TitlePanel.new(:orient => ORIENT_OVERLAY, :dim => 30))
|
18
|
+
@thechart.add_child(GerbilCharts::Surfaces::StackedAreaSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
19
|
+
@thechart.add_child(GerbilCharts::Surfaces::DetailedLegend.new(:orient=> ORIENT_SOUTH, :dim => 200 , :always_visible => true, :show_stats => false ))
|
20
|
+
@thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 , :cumulative => true ))
|
21
|
+
@thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
|
22
|
+
|
23
|
+
# optional features
|
24
|
+
if @feature_timetracker
|
25
|
+
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_SOUTH, :dim => 10 ))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
@@ -11,14 +11,14 @@ module GerbilCharts::Models
|
|
11
11
|
class BucketizedTimeSeriesGraphModel < TimeSeriesGraphModel
|
12
12
|
|
13
13
|
attr_reader :bucket_size_secs # current bucket size
|
14
|
-
attr_reader :behavior
|
14
|
+
attr_reader :behavior # :average or :max or :sum
|
15
15
|
attr_reader :last_sweep_pos # :nodoc:
|
16
16
|
|
17
|
-
def initialize(name,bucketsec, opt={})
|
17
|
+
def initialize(name,bucketsec, opt={:behavior => :average})
|
18
18
|
super(name,opt)
|
19
19
|
@bucket_size_secs=bucketsec
|
20
20
|
@samp_count =0
|
21
|
-
@behavior = :
|
21
|
+
@behavior = opt[:behavior]
|
22
22
|
@last_sweep_pos=0
|
23
23
|
end
|
24
24
|
|
@@ -63,7 +63,8 @@ class BucketizedTimeSeriesGraphModel < TimeSeriesGraphModel
|
|
63
63
|
# returns the time floor of the bucket this belongs to
|
64
64
|
# example 8:06 AM will belong to the 8:05AM bucket if bucketsize = 5 min
|
65
65
|
#
|
66
|
-
def to_buckettime(
|
66
|
+
def to_buckettime(tv_in)
|
67
|
+
tv= normalize_time_input(tv_in)
|
67
68
|
exp=tv.tv_sec.divmod(@bucket_size_secs)
|
68
69
|
|
69
70
|
if exp[1] >= @bucket_size_secs/2
|
@@ -98,6 +99,8 @@ class BucketizedTimeSeriesGraphModel < TimeSeriesGraphModel
|
|
98
99
|
elsif @behavior == :maxima
|
99
100
|
cval = @yarr.last
|
100
101
|
@yarr[@yarr.length-1]=max(cval,val)
|
102
|
+
elsif @behavior == :sum
|
103
|
+
@yarr[@yarr.length-1]+=val
|
101
104
|
end
|
102
105
|
return @yarr.last
|
103
106
|
|
@@ -114,15 +117,15 @@ class BucketizedTimeSeriesGraphModel < TimeSeriesGraphModel
|
|
114
117
|
return 0 if @xarr.length == 0
|
115
118
|
return 0 if @last_sweep_pos >= @xarr.length
|
116
119
|
|
117
|
-
|
118
120
|
xv=@xarr[@last_sweep_pos]
|
121
|
+
nBucks=bucket_diff(xv,tval)
|
122
|
+
|
119
123
|
if tval < xv
|
120
124
|
return 0
|
121
|
-
elsif tval == xv
|
125
|
+
elsif tval == xv || nBucks < 1
|
122
126
|
@last_sweep_pos+=1
|
123
127
|
rval = @yarr[@last_sweep_pos-1]
|
124
128
|
else
|
125
|
-
nBucks=bucket_diff(xv,tval)
|
126
129
|
@last_sweep_pos+= nBucks
|
127
130
|
end
|
128
131
|
return rval.nil? ? 0:rval
|
@@ -156,7 +156,7 @@ class GraphModelGroup
|
|
156
156
|
|
157
157
|
if rangeopts == :auto
|
158
158
|
return effective_round_range_y
|
159
|
-
elsif rangeopts == :auto_0
|
159
|
+
elsif rangeopts == :auto_0 or rangeopts == :auto_y0
|
160
160
|
return effective_round_range_y0
|
161
161
|
elsif rangeopts.respond_to?('size') and rangeopts.size == 2
|
162
162
|
reffy = RawRange.new
|
@@ -26,8 +26,8 @@ public
|
|
26
26
|
[0,0], [1,0.2], [5,1], [10,1],[20,5],
|
27
27
|
[30,10],[60,10],[120,15], [300,60], [600,120],
|
28
28
|
[900,300], [1800,300],
|
29
|
-
[3600,900], [7200,1800],[10800,3600], [14400,3600], [21600,
|
30
|
-
[43200,
|
29
|
+
[3600,900], [7200,1800],[10800,3600], [14400,3600], [21600,3600],
|
30
|
+
[43200, 7200], [86400,7200],
|
31
31
|
[172800, 43200], [259200,86400],
|
32
32
|
[604800, 86400], [1209600,172800],
|
33
33
|
[2419200, 604800],
|
@@ -10,70 +10,77 @@ module GerbilCharts::Surfaces
|
|
10
10
|
# :zbucketsize if no data for this many 'x', then insert a zero
|
11
11
|
#
|
12
12
|
class AreaSurface < Surface
|
13
|
-
def initialize(opts={})
|
14
|
-
super(opts)
|
15
|
-
end
|
16
|
-
|
17
|
-
def int_render(g)
|
18
13
|
|
19
|
-
|
20
|
-
|
14
|
+
def initialize(opts={})
|
15
|
+
super(opts)
|
16
|
+
end
|
17
|
+
|
18
|
+
def int_render(g)
|
19
|
+
range_options_x = parent.get_global_option(:scaling_x,:auto)
|
21
20
|
range_options_y = parent.get_global_option(:scaling_y,:auto)
|
22
21
|
butterfly = parent.get_global_option(:butterfly,false)
|
23
|
-
|
22
|
+
zbucketsize = parent.get_global_option(:zero_bucketsize,nil)
|
24
23
|
|
25
|
-
|
26
|
-
|
24
|
+
rx = parent.modelgroup.effective_range_x(range_options_x)
|
25
|
+
ry = parent.modelgroup.effective_range_y(range_options_y)
|
27
26
|
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
# any filters ?
|
29
|
+
if parent.get_global_option(:filter,false)
|
30
|
+
g.curr_win.add_options({:filter => "url(##{parent.get_global_option(:filter,false)})" })
|
31
|
+
end
|
33
32
|
|
34
|
-
|
35
|
-
if parent.usesAjax?
|
36
|
-
set_ajaxSurfaceContext(rx.rmax,ry.rmax,"AREA")
|
37
|
-
end
|
33
|
+
set_ajaxSurfaceContext(rx.rmax,ry.rmax,"AREA") if parent.usesAjax?
|
38
34
|
|
39
35
|
# butterfly chart
|
40
36
|
ry.update(-ry.rmax) if butterfly
|
41
37
|
|
42
38
|
y_zero = scale_y 0,ry
|
39
|
+
|
40
|
+
f_squarize = parent.get_global_option(:squarize,false)
|
43
41
|
|
44
|
-
|
42
|
+
parent.modelgroup.each_model_with_index do | mod, i|
|
43
|
+
|
44
|
+
if f_squarize
|
45
|
+
g.begin_squarized_polygon
|
46
|
+
else
|
45
47
|
g.begin_polygon
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
48
|
+
end
|
49
|
+
|
50
|
+
firstpoint=true
|
51
|
+
xpos,ypos=0,0
|
52
|
+
last_x=nil
|
53
|
+
mod.each_tuple do |x,y|
|
50
54
|
|
51
|
-
|
55
|
+
y =-y if butterfly and i.odd?
|
52
56
|
|
53
|
-
|
54
|
-
|
57
|
+
xpos = scale_x x,rx
|
58
|
+
ypos = scale_y y,ry
|
55
59
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
+
if firstpoint
|
61
|
+
g.polygon_point xpos,y_zero
|
62
|
+
firstpoint=false
|
63
|
+
end
|
60
64
|
|
61
|
-
|
62
|
-
|
65
|
+
unless zbucketsize.nil?
|
66
|
+
if last_x && (x-last_x) > zbucketsize
|
63
67
|
g.polygon_point scale_x(last_x,rx) ,y_zero
|
64
68
|
g.polygon_point scale_x(x,rx) ,y_zero
|
65
|
-
|
66
|
-
|
69
|
+
end
|
70
|
+
last_x=x
|
67
71
|
end
|
68
72
|
|
69
|
-
|
70
|
-
end
|
71
|
-
g.polygon_point xpos,y_zero
|
72
|
-
g.end_polygon(:id => "item#{i}", "opacity"=>"0.3")
|
73
|
+
g.polygon_point xpos,ypos
|
73
74
|
end
|
75
|
+
|
76
|
+
g.polygon_point xpos,y_zero
|
77
|
+
g.end_polygon(:id => "item#{i}", "opacity"=>"0.8")
|
74
78
|
end
|
75
79
|
|
76
|
-
|
80
|
+
draw_ref_model_line(g,rx,ry) if parent.modelgroup.has_ref_model?
|
81
|
+
|
82
|
+
end
|
77
83
|
|
78
84
|
|
79
85
|
end
|
86
|
+
end
|
@@ -46,9 +46,13 @@ class ConversationRing < Surface
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# Calculating radius
|
49
|
-
radius1 = 20
|
50
|
-
|
51
|
-
|
49
|
+
radius1 = 20
|
50
|
+
if parent.modelgroup.sort[0] > 0
|
51
|
+
effective_radius = (((item.to_f)/parent.modelgroup.sort[0].to_f).to_f * radius1)
|
52
|
+
effective_radius = [effective_radius,5.0].max
|
53
|
+
else
|
54
|
+
effective_radius=0
|
55
|
+
end
|
52
56
|
|
53
57
|
# draw out
|
54
58
|
cx = center_x + (Math.cos((Math::PI/180)*(angle+tot_angle))*(radius_x))
|
@@ -9,18 +9,25 @@ class DetailedLegend < GraphElement
|
|
9
9
|
|
10
10
|
attr_reader :width
|
11
11
|
attr_reader :showvalues
|
12
|
+
attr_reader :always_visible
|
12
13
|
|
13
14
|
def initialize(opts={})
|
14
15
|
@class = "legendpanel"
|
15
16
|
super(opts)
|
16
17
|
@width = opts[:dim] if defined? opts[:dim]
|
18
|
+
@always_visible = opts[:always_visible] || false
|
19
|
+
@show_stats = opts[:show_stats].nil? ? true:opts[:show_stats]
|
17
20
|
end
|
18
21
|
|
19
22
|
def int_render(g)
|
20
23
|
|
21
24
|
return unless parent.get_global_option(:enable_detailed_legend,true)
|
22
25
|
|
23
|
-
|
26
|
+
if @always_visible
|
27
|
+
w=g.newwin("legendpanel_detail")
|
28
|
+
else
|
29
|
+
w=g.newwin("legendpanel_detail", {:visibility => 'hidden'} )
|
30
|
+
end
|
24
31
|
g.setactivewindow(w)
|
25
32
|
|
26
33
|
|
@@ -58,7 +65,9 @@ class DetailedLegend < GraphElement
|
|
58
65
|
|
59
66
|
stat_label_pos = rbox.right + STAT_TABLE_OFFSET
|
60
67
|
lab = %w(Max Min Avg Latest).inject("") { |m,ai| m += ai.rjust(9)}
|
61
|
-
|
68
|
+
if @show_stats
|
69
|
+
g.textout(stat_label_pos, rbox.bottom-2, lab, {'xml:space' => 'preserve', :class => "legendstats"} )
|
70
|
+
end
|
62
71
|
|
63
72
|
rbox.top += 16
|
64
73
|
rbox.bottom = rbox.top+10
|
@@ -83,7 +92,9 @@ class DetailedLegend < GraphElement
|
|
83
92
|
mod.formatted_val(stat_ana[0]).to_s.rjust(9) +
|
84
93
|
mod.formatted_val(stat_ana[2]).to_s.rjust(9) +
|
85
94
|
mod.formatted_val(stat_ana[4]).to_s.rjust(9)
|
86
|
-
|
95
|
+
if @show_stats
|
96
|
+
g.textout(stat_label_pos, rbox.bottom-2, outs, {'xml:space' => 'preserve', :class => 'legendstats'} )
|
97
|
+
end
|
87
98
|
|
88
99
|
|
89
100
|
rbox.top += 10 + 5
|
@@ -99,7 +110,7 @@ class DetailedLegend < GraphElement
|
|
99
110
|
super
|
100
111
|
@bounds.deflate_v(10,10)
|
101
112
|
@bounds.deflate_h(2,4)
|
102
|
-
if @width
|
113
|
+
if isoverlay? and @width
|
103
114
|
@bounds.left = @bounds.right - @width
|
104
115
|
end
|
105
116
|
end
|
@@ -13,7 +13,8 @@ class ImpulseSurface < Surface
|
|
13
13
|
range_options_y = parent.get_global_option(:scaling_y,:auto)
|
14
14
|
rx = parent.modelgroup.effective_range_x(range_options_x)
|
15
15
|
ry = parent.modelgroup.effective_range_y(range_options_y)
|
16
|
-
|
16
|
+
|
17
|
+
|
17
18
|
impulse_width = 2
|
18
19
|
x2 = scale_x Time.at(0),rx
|
19
20
|
x1 = scale_x Time.at(parent.modelgroup.models[0].bucket_size_secs),rx
|
@@ -26,19 +27,24 @@ class ImpulseSurface < Surface
|
|
26
27
|
|
27
28
|
|
28
29
|
|
29
|
-
w=g.newwin("impulse"
|
30
|
+
w=g.newwin("impulse")
|
30
31
|
g.setactivewindow(w)
|
31
32
|
|
33
|
+
xadj=0
|
32
34
|
parent.modelgroup.each_model_with_index do | mod, i|
|
33
35
|
opts = {:id => "lineitem#{i}"}
|
34
|
-
firstpoint=true
|
35
36
|
xpos=0
|
36
37
|
ypos=0
|
37
38
|
mod.each_tuple do |x,y|
|
38
39
|
xpos = scale_x x,rx
|
39
40
|
ypos = scale_y y,ry
|
40
|
-
g.line(xpos,@bounds.bottom,xpos,ypos,opts)
|
41
|
+
g.line(xpos + xadj,@bounds.bottom,xpos + xadj,ypos,opts)
|
42
|
+
|
43
|
+
g.ellipse(xpos + xadj, ypos, 18, 8, { "stroke-width" => 0, :fill => "orange"} )
|
44
|
+
g.textout(xpos + xadj-11, ypos+3, ry.format_value(y) , { :class => "elementvalue" } )
|
45
|
+
|
41
46
|
end
|
47
|
+
xadj=xadj+2
|
42
48
|
end
|
43
49
|
|
44
50
|
g.setactivewindow
|
@@ -10,52 +10,49 @@ module GerbilCharts::Surfaces
|
|
10
10
|
# [+scaling+] :auto, :auto_y0
|
11
11
|
#
|
12
12
|
class LineSurface < Surface
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
def initialize(opts={})
|
14
|
+
super(opts)
|
15
|
+
end
|
16
16
|
|
17
|
-
|
17
|
+
def int_render(g)
|
18
18
|
|
19
19
|
range_options_x = parent.get_global_option(:scaling_x,:auto)
|
20
20
|
range_options_y = parent.get_global_option(:scaling_y,:auto)
|
21
21
|
butterfly = parent.get_global_option(:butterfly,false)
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
rx = parent.modelgroup.effective_range_x(range_options_x)
|
24
|
+
ry = parent.modelgroup.effective_range_y(range_options_y)
|
25
25
|
|
26
26
|
ry.update(-ry.rmax) if butterfly
|
27
|
+
set_ajaxSurfaceContext(rx.rmax,ry.rmax,"LINE") if parent.usesAjax?
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
parent.modelgroup.each_model_with_index do |mod,i|
|
30
|
+
mod.each_tuple do |x,y|
|
31
|
+
y = -y if butterfly and i.odd?
|
32
|
+
|
33
|
+
# the basic line
|
34
|
+
xpos = scale_x x,rx
|
35
|
+
ypos = scale_y y,ry
|
36
|
+
g.lineto xpos,ypos
|
37
|
+
|
38
|
+
# tooltip
|
39
|
+
opts = {:id => "item#{i}"}
|
40
|
+
if parent.get_global_option(:auto_tooltips,false)
|
41
|
+
opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
|
42
|
+
opts.store(:gerbiltooltip1, mod.name)
|
43
|
+
opts.store(:gerbiltooltip2, "Val = #{y}")
|
44
|
+
end
|
45
|
+
|
46
|
+
# cirle dp
|
47
|
+
g.circle(xpos,ypos,4,opts) if parent.get_global_option(:circle_data_points,false)
|
32
48
|
|
33
|
-
parent.modelgroup.each_model_with_index do | mod, i|
|
34
|
-
|
35
|
-
mod.each_tuple do |x,y|
|
36
|
-
|
37
|
-
y = -y if butterfly and i.odd?
|
38
|
-
|
39
|
-
# the basic line
|
40
|
-
xpos = scale_x x,rx
|
41
|
-
ypos = scale_y y,ry
|
42
|
-
g.lineto xpos,ypos
|
43
|
-
|
44
|
-
# datapoint and a tooltip
|
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 = #{y}")
|
50
|
-
end
|
51
|
-
g.circle(xpos,ypos,4,opts) if parent.get_global_option(:circle_data_points,false)
|
52
|
-
end
|
53
|
-
g.endline(:id => "lineitem#{i}")
|
54
49
|
end
|
55
|
-
|
56
|
-
#draw each model in the group
|
50
|
+
g.endline(:id => "lineitem#{i}")
|
57
51
|
end
|
58
52
|
|
59
|
-
|
53
|
+
draw_ref_model_line(g,rx,ry) if parent.modelgroup.has_ref_model?
|
60
54
|
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
61
58
|
end
|