gerbilcharts 0.5.9 → 0.6.8
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.
- 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
|