gerbilcharts 0.10.14 → 0.10.26
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.
- checksums.yaml +5 -5
- data/lib/gerbilcharts/charts/area_chart.rb +8 -5
- data/lib/gerbilcharts/charts/chart_base.rb +6 -1
- data/lib/gerbilcharts/charts/line_chart.rb +4 -2
- data/lib/gerbilcharts/charts/line_chart_table.rb +1 -1
- data/lib/gerbilcharts/charts/mrtg_chart_table.rb +38 -0
- data/lib/gerbilcharts/charts/square_line_chart.rb +2 -2
- data/lib/gerbilcharts/charts/stacked_area_chart.rb +15 -11
- data/lib/gerbilcharts/charts.rb +1 -0
- data/lib/gerbilcharts/models/bucketized_timeseries_graph_model.rb +0 -4
- data/lib/gerbilcharts/models/graph_model_group.rb +9 -0
- data/lib/gerbilcharts/models/monotonous_graph_model.rb +7 -2
- data/lib/gerbilcharts/models/presets.rb +16 -9
- data/lib/gerbilcharts/surfaces/area_surface.rb +30 -20
- data/lib/gerbilcharts/surfaces/detailed_legend.rb +15 -2
- data/lib/gerbilcharts/surfaces/legend.rb +4 -0
- data/lib/gerbilcharts/surfaces/line_surface.rb +20 -11
- data/lib/gerbilcharts/surfaces/mrtg_surface.rb +96 -0
- data/lib/gerbilcharts/surfaces/pie_surface.rb +3 -3
- data/lib/gerbilcharts/surfaces/square_line_surface.rb +26 -14
- data/lib/gerbilcharts/surfaces/stacked_area_surface.rb +84 -85
- data/lib/gerbilcharts/surfaces.rb +1 -0
- data/lib/gerbilcharts/svgdc/svg_win.rb +1 -1
- data/lib/gerbilcharts/svgdc/svgdc.rb +0 -13
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e35059b431a7a0934ef66efdc89c4a5234e381999e0dab77379bacdbcff3e057
|
4
|
+
data.tar.gz: bfb665487745bd666c4ceca6638974c4d2933eb3b24146c9ff4783d47f9bf4a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8933769a6e14c2ef8a774cebbc9930746069b3d85901b9de6b7845b6d0dc65bbb2e08ccb4ba304a08eccb787b64084fc9189384964d34683f4a5f7cab0684800
|
7
|
+
data.tar.gz: 3659f8547bec07faabfab8ead3636d0eceb70c934867908503af9ee8d0411a75d4925d6062636d86315102f7a1ce23a5decb9c865b75cf31b8ef7764f2a71288
|
@@ -23,12 +23,15 @@ class AreaChart < ChartBase
|
|
23
23
|
@thechart.add_child(GerbilCharts::Surfaces::SurfaceBackground.new(:orient => ORIENT_OVERLAY))
|
24
24
|
@thechart.add_child(GerbilCharts::Surfaces::MarkBand.new(:orient => ORIENT_OVERLAY))
|
25
25
|
@thechart.add_child(GerbilCharts::Surfaces::BasicGrid.new(:orient => ORIENT_OVERLAY))
|
26
|
-
@thechart.add_child(GerbilCharts::Surfaces::AreaSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
# timetracker will consume events to circle datapoints tooltips
|
28
|
+
if @feature_circledatapoints
|
29
|
+
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY )) if @feature_timetracker
|
30
|
+
@thechart.add_child(GerbilCharts::Surfaces::AreaSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
31
|
+
else
|
32
|
+
@thechart.add_child(GerbilCharts::Surfaces::AreaSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
33
|
+
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY )) if @feature_timetracker
|
34
|
+
end
|
32
35
|
|
33
36
|
# link pivots
|
34
37
|
if @feature_linkpivots
|
@@ -63,12 +63,17 @@ class ChartBase
|
|
63
63
|
opt.delete :enabletimetracker
|
64
64
|
end
|
65
65
|
|
66
|
-
@
|
66
|
+
@enablelinkpivots=false
|
67
67
|
if opt[:enablelinkpivots]
|
68
68
|
@feature_linkpivots=opt[:enablelinkpivots]
|
69
69
|
opt.delete :enablelinkpivots
|
70
70
|
end
|
71
71
|
|
72
|
+
@feature_circledatapoints=false
|
73
|
+
if opt[:circle_data_points]
|
74
|
+
@feature_circledatapoints=opt[:circle_data_points]
|
75
|
+
end
|
76
|
+
|
72
77
|
|
73
78
|
# pass on options to chart object
|
74
79
|
@thechart = GerbilCharts::Surfaces::Chart.new(opt)
|
@@ -10,7 +10,8 @@ module GerbilCharts::Charts
|
|
10
10
|
# [+style+] Stylesheet file to be applied
|
11
11
|
#
|
12
12
|
# global visual options
|
13
|
-
# [+circle_data_points]
|
13
|
+
# [+circle_data_points] draw a solid circle around each data point
|
14
|
+
# [+show_95th_percentile] show a line of 95th pct
|
14
15
|
#
|
15
16
|
class LineChart < ChartBase
|
16
17
|
|
@@ -25,13 +26,14 @@ class LineChart < ChartBase
|
|
25
26
|
|
26
27
|
# other elements
|
27
28
|
@thechart.add_child(GerbilCharts::Surfaces::SurfaceBackground.new(:orient => ORIENT_OVERLAY))
|
29
|
+
@thechart.add_child(GerbilCharts::Surfaces::MarkBand.new(:orient => ORIENT_OVERLAY))
|
28
30
|
@thechart.add_child(GerbilCharts::Surfaces::BasicGrid.new(:orient => ORIENT_OVERLAY))
|
29
|
-
@thechart.add_child(GerbilCharts::Surfaces::LineSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
30
31
|
|
31
32
|
# optional features
|
32
33
|
if @feature_timetracker
|
33
34
|
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY ))
|
34
35
|
end
|
36
|
+
@thechart.add_child(GerbilCharts::Surfaces::LineSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
35
37
|
|
36
38
|
# link pivots
|
37
39
|
if @feature_linkpivots
|
@@ -28,7 +28,7 @@ class LineChartTable < ChartBase
|
|
28
28
|
@thechart.add_child(GerbilCharts::Surfaces::BasicGrid.new(:orient => ORIENT_OVERLAY))
|
29
29
|
@thechart.add_child(GerbilCharts::Surfaces::TitlePanel.new(:orient => ORIENT_OVERLAY, :dim => 30))
|
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 =>
|
31
|
+
@thechart.add_child(GerbilCharts::Surfaces::DetailedLegend.new(:orient=> ORIENT_SOUTH, :dim => 100 , :always_visible => true ))
|
32
32
|
@thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 ))
|
33
33
|
@thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
|
34
34
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module GerbilCharts::Charts
|
2
|
+
|
3
|
+
# =MRTG 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 MrtgChartTable < 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::MrtgSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
31
|
+
@thechart.add_child(GerbilCharts::Surfaces::DetailedLegend.new(:orient=> ORIENT_SOUTH, :dim => 100 , :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
|
@@ -28,13 +28,13 @@ class SquareLineChart < ChartBase
|
|
28
28
|
@thechart.add_child(GerbilCharts::Surfaces::SurfaceBackground.new(:orient => ORIENT_OVERLAY))
|
29
29
|
@thechart.add_child(GerbilCharts::Surfaces::MarkBand.new(:orient => ORIENT_OVERLAY))
|
30
30
|
@thechart.add_child(GerbilCharts::Surfaces::BasicGrid.new(:orient => ORIENT_OVERLAY))
|
31
|
-
@thechart.add_child(GerbilCharts::Surfaces::SquareLineSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
32
31
|
|
33
32
|
# optional features
|
34
33
|
if @feature_timetracker
|
35
34
|
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY ))
|
36
35
|
end
|
37
|
-
|
36
|
+
|
37
|
+
@thechart.add_child(GerbilCharts::Surfaces::SquareLineSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
38
38
|
# link pivots
|
39
39
|
if @feature_linkpivots
|
40
40
|
@thechart.add_child(GerbilCharts::Surfaces::LinkPivots.new(:orient => ORIENT_OVERLAY ))
|
@@ -15,19 +15,23 @@ class StackedAreaChart < ChartBase
|
|
15
15
|
@thechart.add_child(GerbilCharts::Surfaces::SurfaceBackground.new(:orient => ORIENT_OVERLAY))
|
16
16
|
@thechart.add_child(GerbilCharts::Surfaces::StackedGrid.new(:orient => ORIENT_OVERLAY))
|
17
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
18
|
|
20
|
-
#
|
21
|
-
if @
|
22
|
-
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY ))
|
19
|
+
# timetracker will consume events to circle datapoints tooltips
|
20
|
+
if @feature_circledatapoints
|
21
|
+
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY )) if @feature_timetracker
|
22
|
+
@thechart.add_child(GerbilCharts::Surfaces::StackedAreaSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
23
|
+
else
|
24
|
+
@thechart.add_child(GerbilCharts::Surfaces::StackedAreaSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
25
|
+
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY )) if @feature_timetracker
|
23
26
|
end
|
24
27
|
|
25
|
-
|
26
|
-
|
28
|
+
# link pivots
|
29
|
+
if @feature_linkpivots
|
27
30
|
@thechart.add_child(GerbilCharts::Surfaces::LinkPivots.new(:orient => ORIENT_OVERLAY ))
|
28
|
-
|
29
|
-
|
30
|
-
@thechart.add_child(GerbilCharts::Surfaces::
|
31
|
+
end
|
32
|
+
|
33
|
+
@thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => @legend_width, :align => :left ))
|
34
|
+
@thechart.add_child(GerbilCharts::Surfaces::DetailedLegend.new(:orient=> ORIENT_OVERLAY, :dim => 3*@legend_width, :align => :left))
|
31
35
|
@thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 , :cumulative => true ))
|
32
36
|
@thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
|
33
37
|
|
@@ -36,7 +40,7 @@ class StackedAreaChart < ChartBase
|
|
36
40
|
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_SOUTH, :dim => 10 ))
|
37
41
|
end
|
38
42
|
end
|
39
|
-
end
|
40
43
|
|
41
|
-
end
|
44
|
+
end # class
|
45
|
+
end # module
|
42
46
|
|
data/lib/gerbilcharts/charts.rb
CHANGED
@@ -79,11 +79,7 @@ class BucketizedTimeSeriesGraphModel < TimeSeriesGraphModel
|
|
79
79
|
tv= normalize_time_input(tv_in)
|
80
80
|
exp=tv.tv_sec.divmod(@bucket_size_secs)
|
81
81
|
|
82
|
-
if exp[1] >= @bucket_size_secs/2
|
83
|
-
return Time.at(exp[0]*@bucket_size_secs + @bucket_size_secs)
|
84
|
-
else
|
85
82
|
return Time.at(exp[0]*@bucket_size_secs)
|
86
|
-
end
|
87
83
|
end
|
88
84
|
|
89
85
|
# how many buckets separate the two buckettimes
|
@@ -163,12 +163,12 @@ class MonotonousGraphModel < GraphModel
|
|
163
163
|
#
|
164
164
|
# mode => :normal or :ninety_fifth
|
165
165
|
#
|
166
|
-
# returns array 0 = min, 1 = max, 2 = avg, 3 = total, 4 = latest
|
166
|
+
# returns array 0 = min, 1 = max, 2 = avg, 3 = total, 4 = latest, 5=95th
|
167
167
|
# todo : 5 = stddev
|
168
168
|
# todo : support :ninety_fifth
|
169
169
|
#
|
170
170
|
def get_statistical_analysis()
|
171
|
-
return [0,0,0,0,0] if @yarr.size==0
|
171
|
+
return [0,0,0,0,0,0] if @yarr.size==0
|
172
172
|
|
173
173
|
a = []
|
174
174
|
a[0]= @yrange.rmin
|
@@ -181,6 +181,11 @@ class MonotonousGraphModel < GraphModel
|
|
181
181
|
a[2] = a[3]/@yarr.size
|
182
182
|
a[3] = a[3] * @aggregation_factor
|
183
183
|
a[4] = latest_val
|
184
|
+
|
185
|
+
# 95th statistical
|
186
|
+
rank=(@yarr.size * 0.95).round
|
187
|
+
a[5] = @yarr.sort()[rank-1]
|
188
|
+
|
184
189
|
return a
|
185
190
|
end
|
186
191
|
|
@@ -11,18 +11,25 @@ public
|
|
11
11
|
PRESETS = [
|
12
12
|
[0,0], [1,0.2], [5,1], [10,1],[20,5],
|
13
13
|
[50,10],[100,25],[200,50], [500,100], [1000,200],
|
14
|
-
[2000,500],
|
15
|
-
[20000,5000],
|
16
|
-
[500000,100000],
|
17
|
-
[1000000,200000],
|
18
|
-
[5000000,1000000],
|
19
|
-
[8000000,2000000],
|
20
|
-
[100_000_000,25_000_000],
|
21
|
-
[
|
14
|
+
[2000,500], [5000,1000], [8000,2000], [10000,2000],
|
15
|
+
[20000,5000], [50000,10000], [100000,25000], [200000,50000],
|
16
|
+
[500000,100000], [800000,200000],
|
17
|
+
[1000000,200000], [2000000,500000], [3000000,500000], [4000000,1000000],
|
18
|
+
[5000000,1000000], [6000000, 1000000],
|
19
|
+
[8000000,2000000], [10000000,2000000], [20000000,5000000], [50_000_000, 10_000_000],
|
20
|
+
[100_000_000, 25_000_000],
|
21
|
+
[200_000_000, 50_000_000],
|
22
|
+
[300_000_000, 100_000_000],
|
23
|
+
[500_000_000, 100_000_000],
|
24
|
+
[1_000_000_000, 250_000_000] ,
|
25
|
+
[3_000_000_000, 1_000_000_000] ,
|
26
|
+
[5_000_000_000, 1_000_000_000] ,
|
22
27
|
[10_000_000_000, 2_000_000_000] ,
|
23
28
|
[20_000_000_000, 5_000_000_000] ,
|
24
|
-
|
29
|
+
[50_000_000_000, 10_000_000_000] ,
|
25
30
|
[100_000_000_000, 20_000_000_000] ,
|
31
|
+
[200_000_000_000, 50_000_000_000] ,
|
32
|
+
[500_000_000_000, 100_000_000_000] ,
|
26
33
|
[1_000_000_000_000, 200_000_000_000] ,
|
27
34
|
[10_000_000_000_000,2_000_000_000_000] ,
|
28
35
|
]
|
@@ -4,10 +4,10 @@ module GerbilCharts::Surfaces
|
|
4
4
|
# The transparency kind of allows hidden items to be shown
|
5
5
|
#
|
6
6
|
# ===Options
|
7
|
-
#
|
8
|
-
# :scaling_y
|
9
|
-
#
|
10
|
-
#
|
7
|
+
# :scaling_x :auto, :auto_0, or array [minval,maxval]
|
8
|
+
# :scaling_y
|
9
|
+
# :butterfly true/false for butterfly chart (alternate models on +/- y)
|
10
|
+
# :zbucketsize if no data for this many 'x', then insert a zero
|
11
11
|
#
|
12
12
|
class AreaSurface < Surface
|
13
13
|
|
@@ -17,9 +17,9 @@ class AreaSurface < Surface
|
|
17
17
|
|
18
18
|
def int_render(g)
|
19
19
|
range_options_x = parent.get_global_option(:scaling_x,:auto)
|
20
|
-
|
21
|
-
|
22
|
-
zbucketsize
|
20
|
+
range_options_y = parent.get_global_option(:scaling_y,:auto)
|
21
|
+
butterfly = parent.get_global_option(:butterfly,false)
|
22
|
+
zbucketsize = parent.get_global_option(:zero_bucketsize,nil)
|
23
23
|
|
24
24
|
rx = parent.modelgroup.effective_range_x(range_options_x)
|
25
25
|
ry = parent.modelgroup.effective_range_y(range_options_y)
|
@@ -27,15 +27,15 @@ class AreaSurface < Surface
|
|
27
27
|
|
28
28
|
# any filters ?
|
29
29
|
if parent.get_global_option(:filter,false)
|
30
|
-
|
30
|
+
g.curr_win.add_options({:filter => "url(##{parent.get_global_option(:filter,false)})" })
|
31
31
|
end
|
32
32
|
|
33
33
|
set_ajaxSurfaceContext(rx.rmax,ry.rmax,"AREA") if parent.usesAjax?
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
# butterfly chart
|
36
|
+
ry.update(-ry.rmax) if butterfly
|
37
37
|
|
38
|
-
|
38
|
+
y_zero = scale_y 0,ry
|
39
39
|
|
40
40
|
f_squarize = parent.get_global_option(:squarize,false)
|
41
41
|
|
@@ -49,10 +49,10 @@ class AreaSurface < Surface
|
|
49
49
|
|
50
50
|
firstpoint=true
|
51
51
|
xpos,ypos=0,0
|
52
|
-
|
52
|
+
last_x=nil
|
53
53
|
mod.each_tuple do |x,y|
|
54
54
|
|
55
|
-
|
55
|
+
y =-y if butterfly and i.odd?
|
56
56
|
|
57
57
|
xpos = scale_x x,rx
|
58
58
|
ypos = scale_y y,ry
|
@@ -62,15 +62,25 @@ class AreaSurface < Surface
|
|
62
62
|
firstpoint=false
|
63
63
|
end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
65
|
+
unless zbucketsize.nil?
|
66
|
+
if last_x && (x-last_x) > zbucketsize
|
67
|
+
g.polygon_point scale_x(last_x,rx) ,y_zero
|
68
|
+
g.polygon_point scale_x(x,rx) ,y_zero
|
69
|
+
end
|
70
|
+
last_x=x
|
71
|
+
end
|
72
|
+
|
73
|
+
# tooltip
|
74
|
+
if parent.get_global_option(:circle_data_points,false)
|
75
|
+
opts = {:id => "item#{i}"}
|
76
|
+
opts.store(:gerbiltooltip1, x)
|
77
|
+
opts.store(:gerbiltooltip2, "Val = #{GerbilCharts::Models::Presets.new.format_suffix(y)}")
|
78
|
+
g.circle(xpos,ypos,2,opts)
|
79
|
+
end
|
72
80
|
|
73
81
|
g.polygon_point xpos,ypos
|
82
|
+
|
83
|
+
|
74
84
|
end
|
75
85
|
|
76
86
|
g.polygon_point xpos,y_zero
|
@@ -63,9 +63,17 @@ class DetailedLegend < GraphElement
|
|
63
63
|
|
64
64
|
|
65
65
|
stat_label_pos = @bounds.right - STAT_TABLE_SIZE
|
66
|
-
|
66
|
+
headers = %w(Max Min Avg Latest Total)
|
67
|
+
if parent.get_global_option(:show_95th_percentile,false)
|
68
|
+
headers << " 95th"
|
69
|
+
stat_label_pos = stat_label_pos - 25
|
70
|
+
end
|
71
|
+
|
72
|
+
lab = headers.inject("") { |m,ai| m += ai.rjust(9)}
|
67
73
|
if @show_stats
|
68
|
-
g.textout(stat_label_pos,
|
74
|
+
g.textout(stat_label_pos,
|
75
|
+
rbox.bottom-2, lab,
|
76
|
+
{'xml:space' => 'preserve', :class => "legendstats"} )
|
69
77
|
end
|
70
78
|
|
71
79
|
rbox.top += 16
|
@@ -94,6 +102,11 @@ class DetailedLegend < GraphElement
|
|
94
102
|
mod.formatted_val(stat_ana[2]).to_s.rjust(9) +
|
95
103
|
mod.formatted_val(stat_ana[4]).to_s.rjust(9) +
|
96
104
|
fmt_prefix_2(stat_ana[3]).to_s.rjust(9)
|
105
|
+
|
106
|
+
if parent.get_global_option(:show_95th_percentile,false)
|
107
|
+
outs += mod.formatted_val(stat_ana[5]).to_s.rjust(9)
|
108
|
+
end
|
109
|
+
|
97
110
|
if @show_stats
|
98
111
|
g.textout(stat_label_pos, rbox.bottom-2, outs, {'xml:space' => 'preserve', :class => 'legendstats'} )
|
99
112
|
end
|
@@ -17,6 +17,10 @@ class Legend < GraphElement
|
|
17
17
|
return if not parent.get_global_option(:enable_legend,true)
|
18
18
|
|
19
19
|
w=g.newwin("legendpanel_mini")
|
20
|
+
|
21
|
+
if parent.get_global_option(:align, :right) == :left
|
22
|
+
g.add_option("transform", "translate(#{-@bounds.left+50})")
|
23
|
+
end
|
20
24
|
g.setactivewindow(w)
|
21
25
|
|
22
26
|
# count determines the bounds
|
@@ -35,7 +35,7 @@ class LineSurface < Surface
|
|
35
35
|
mod.each_tuple do |x,y|
|
36
36
|
y = -y if butterfly and i.odd?
|
37
37
|
|
38
|
-
|
38
|
+
# the basic line
|
39
39
|
xpos = scale_x x,rx
|
40
40
|
ypos = scale_y y,ry
|
41
41
|
|
@@ -46,18 +46,27 @@ class LineSurface < Surface
|
|
46
46
|
g.lineto xpos,ypos
|
47
47
|
|
48
48
|
# tooltip
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
# cirle dp
|
57
|
-
g.circle(xpos,ypos,4,opts) if parent.get_global_option(:circle_data_points,false)
|
58
|
-
|
49
|
+
if parent.get_global_option(:auto_tooltips,false) and parent.get_global_option(:circle_data_points,false)
|
50
|
+
opts = {:id => "item#{i}"}
|
51
|
+
opts.store(:gerbiltooltip1, x)
|
52
|
+
opts.store(:gerbiltooltip2, "Val = #{GerbilCharts::Models::Presets.new.format_suffix(y)}")
|
53
|
+
g.circle(xpos,ypos,2,opts)
|
54
|
+
end
|
59
55
|
end
|
60
56
|
g.endline(:id => "lineitem#{i}")
|
57
|
+
|
58
|
+
# 95th percentile line and label
|
59
|
+
if parent.get_global_option(:show_95th_percentile,false)
|
60
|
+
metrics=mod.get_statistical_analysis
|
61
|
+
y95 = scale_y metrics[5],ry
|
62
|
+
g.line( @bounds.left, y95, @bounds.right, y95, {:id=>"lineitem#{i}"} )
|
63
|
+
y95label = mod.formatted_val(metrics[5])
|
64
|
+
g.textout(@bounds.right-10, y95-5, y95label,
|
65
|
+
{:class => "reflinelabel", "text-anchor" => "end"})
|
66
|
+
g.textout(@bounds.right-10, y95+15, "95th pct",
|
67
|
+
{:class => "reflinelabel", "text-anchor" => "end"})
|
68
|
+
end
|
69
|
+
|
61
70
|
end
|
62
71
|
|
63
72
|
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module GerbilCharts::Surfaces
|
2
|
+
|
3
|
+
# = Mrtg Line Surface
|
4
|
+
# MRTG like surface
|
5
|
+
# First data-point = SquareArea Green
|
6
|
+
# Second data-point = SquareLine Blue
|
7
|
+
# Third onwards = SquareLines with usual color base as if starting from zero
|
8
|
+
#
|
9
|
+
# Supported global options
|
10
|
+
#
|
11
|
+
# [+circle_data_points+] Draw a solid circle around datapoints
|
12
|
+
# [+scaling+] :auto, :auto_y0
|
13
|
+
#
|
14
|
+
class MrtgSurface < Surface
|
15
|
+
def initialize(opts={})
|
16
|
+
super(opts)
|
17
|
+
end
|
18
|
+
|
19
|
+
def int_render(g)
|
20
|
+
|
21
|
+
range_options_x = parent.get_global_option(:scaling_x,:auto)
|
22
|
+
range_options_y = parent.get_global_option(:scaling_y,:auto)
|
23
|
+
zbucketsize = parent.get_global_option(:zero_bucketsize,nil)
|
24
|
+
rx = parent.modelgroup.effective_range_x(range_options_x)
|
25
|
+
ry = parent.modelgroup.effective_range_y(range_options_y)
|
26
|
+
|
27
|
+
set_ajaxSurfaceContext(rx.rmax,ry.rmax,"LINE") if parent.usesAjax?
|
28
|
+
|
29
|
+
parent.modelgroup.each_model_with_index do | mod, i|
|
30
|
+
|
31
|
+
if i==0
|
32
|
+
style= "mrtg0"
|
33
|
+
surface= :area
|
34
|
+
elsif i==1
|
35
|
+
style= "mrtg1"
|
36
|
+
else
|
37
|
+
style= "lineitem#{i-2}"
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
if surface==:area
|
42
|
+
|
43
|
+
g.begin_squarized_polygon
|
44
|
+
firstpoint=true
|
45
|
+
xpos,ypos=0,0
|
46
|
+
last_x=nil
|
47
|
+
y_zero = scale_y 0,ry
|
48
|
+
mod.each_tuple do |x,y|
|
49
|
+
|
50
|
+
xpos = scale_x x,rx
|
51
|
+
ypos = scale_y y,ry
|
52
|
+
|
53
|
+
if firstpoint
|
54
|
+
g.polygon_point xpos,y_zero
|
55
|
+
firstpoint=false
|
56
|
+
end
|
57
|
+
|
58
|
+
unless zbucketsize.nil?
|
59
|
+
if last_x && (x-last_x) > zbucketsize
|
60
|
+
g.polygon_point scale_x(last_x,rx) ,y_zero
|
61
|
+
g.polygon_point scale_x(x,rx) ,y_zero
|
62
|
+
end
|
63
|
+
last_x=x
|
64
|
+
end
|
65
|
+
|
66
|
+
g.polygon_point xpos,ypos
|
67
|
+
end
|
68
|
+
|
69
|
+
g.polygon_point xpos,y_zero
|
70
|
+
g.end_polygon(:id => "mrtg0", "opacity"=>"0.8")
|
71
|
+
else
|
72
|
+
|
73
|
+
prev_ypos=nil
|
74
|
+
mod.each_tuple do |x,y|
|
75
|
+
|
76
|
+
xpos = scale_x x,rx
|
77
|
+
ypos = scale_y y,ry
|
78
|
+
|
79
|
+
prev_ypos ||= ypos
|
80
|
+
g.lineto xpos,prev_ypos
|
81
|
+
g.lineto xpos,ypos
|
82
|
+
prev_ypos=ypos
|
83
|
+
|
84
|
+
end
|
85
|
+
g.endline(:id => style)
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -8,7 +8,7 @@ class PieSurface < Surface
|
|
8
8
|
OUTER_OFFSET_X = 10 # x - distance offset from pie boundary
|
9
9
|
OUTER_OFFSET_Y = 10 # y - y offset from pie boundary
|
10
10
|
LEFT_LABEL_OFFSET = 30 # labels on the left of the PIE offset by this (90-270 deg)
|
11
|
-
PERCENT_OFFSET_X = -
|
11
|
+
PERCENT_OFFSET_X = -10 # pull slice label this much (tweak)
|
12
12
|
|
13
13
|
def initialize(opts={})
|
14
14
|
super(opts)
|
@@ -115,10 +115,10 @@ class PieSurface < Surface
|
|
115
115
|
end
|
116
116
|
if(tot_angle > 270)
|
117
117
|
g.textout(percent_pos_x,percent_pos_y+5, "#{percent}%", :class => elementvalue_clsn)
|
118
|
-
g.textout(percent_pos_x,percent_pos_y+
|
118
|
+
g.textout(percent_pos_x,percent_pos_y+25, "#{mod.latest_formatted_val}", :class => 'elementlabel' )
|
119
119
|
else
|
120
120
|
g.textout(percent_pos_x,percent_pos_y, "#{percent}%", :class => elementvalue_clsn)
|
121
|
-
g.textout(percent_pos_x,percent_pos_y+
|
121
|
+
g.textout(percent_pos_x,percent_pos_y+20, "#{mod.latest_formatted_val}", :class => 'elementlabel' )
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
@@ -25,28 +25,40 @@ class SquareLineSurface < Surface
|
|
25
25
|
|
26
26
|
parent.modelgroup.each_model_with_index do | mod, i|
|
27
27
|
|
28
|
-
|
28
|
+
prev_ypos=nil
|
29
29
|
mod.each_tuple do |x,y|
|
30
30
|
|
31
|
-
|
31
|
+
# the basic line
|
32
32
|
xpos = scale_x x,rx
|
33
33
|
ypos = scale_y y,ry
|
34
34
|
|
35
|
-
|
35
|
+
prev_ypos ||= ypos
|
36
36
|
g.lineto xpos,prev_ypos
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
g.circle(xpos,ypos,4,opts) if parent.get_global_option(:circle_data_points,false)
|
37
|
+
g.lineto xpos,ypos
|
38
|
+
prev_ypos=ypos
|
39
|
+
|
40
|
+
# datapoint and a tooltip
|
41
|
+
opts = {:id => "item#{i}"}
|
42
|
+
if parent.get_global_option(:auto_tooltips,false)
|
43
|
+
opts.store(:gerbiltooltip1, x)
|
44
|
+
opts.store(:gerbiltooltip2, "Val = #{GerbilCharts::Models::Presets.new.format_suffix(y)}")
|
45
|
+
end
|
46
|
+
g.circle(xpos,ypos,2,opts) if parent.get_global_option(:circle_data_points,false)
|
48
47
|
end
|
49
48
|
g.endline(:id => "lineitem#{i}")
|
49
|
+
|
50
|
+
# 95th percentile line and label
|
51
|
+
if parent.get_global_option(:show_95th_percentile,false)
|
52
|
+
metrics=mod.get_statistical_analysis
|
53
|
+
y95 = scale_y metrics[5],ry
|
54
|
+
g.line( @bounds.left, y95, @bounds.right, y95, {:id=>"lineitem#{i}"} )
|
55
|
+
y95label = mod.formatted_val(metrics[5])
|
56
|
+
g.textout(@bounds.right-30, y95-5, y95label,
|
57
|
+
{:class => "reflinelabel", "text-anchor" => "end"})
|
58
|
+
g.textout(@bounds.right-30, y95+15, "95th pct",
|
59
|
+
{:class => "reflinelabel", "text-anchor" => "end"})
|
60
|
+
end
|
61
|
+
|
50
62
|
end
|
51
63
|
|
52
64
|
draw_ref_model_lines(g,rx,ry)
|
@@ -9,72 +9,73 @@ class StackedAreaSurface < Surface
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def int_render(g)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
12
|
+
range_options_x = parent.get_global_option(:scaling_x,:auto)
|
13
|
+
|
14
|
+
rx = parent.modelgroup.effective_range_x(range_options_x)
|
15
|
+
ry = parent.modelgroup.cumulative_sweep_round_range_y0
|
16
|
+
|
17
|
+
# ajax if used
|
18
|
+
if parent.usesAjax?
|
19
|
+
set_ajaxSurfaceContext(rx.rmax,ry.rmax,"SA")
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
# draw reference if any
|
24
|
+
if parent.modelgroup.ref_models.size > 0
|
25
|
+
ref_model = parent.modelgroup.ref_models[0]
|
26
|
+
|
27
|
+
y_zero = scale_y 0,ry
|
28
|
+
g.begin_polygon
|
29
|
+
firstpoint=true
|
30
|
+
xpos,ypos=0,0
|
31
|
+
last_x=nil
|
32
|
+
ref_model.each_tuple do |x,y|
|
33
|
+
|
34
|
+
xpos = scale_x x,rx
|
35
|
+
ypos = scale_y y,ry
|
36
|
+
|
37
|
+
if firstpoint
|
38
|
+
g.polygon_point xpos,y_zero
|
39
|
+
firstpoint=false
|
40
|
+
end
|
41
|
+
|
42
|
+
if last_x && (x-last_x) > parent.modelgroup.sweep_interval
|
43
|
+
g.polygon_point scale_x(last_x,rx) ,y_zero
|
44
|
+
g.polygon_point scale_x(x,rx) ,y_zero
|
45
|
+
end
|
46
|
+
last_x=x
|
47
|
+
|
48
|
+
g.polygon_point xpos,ypos
|
49
|
+
end
|
50
|
+
g.polygon_point xpos,y_zero
|
51
|
+
g.end_polygon(:id => "ref_mod")
|
52
|
+
end
|
53
|
+
|
54
|
+
# prepare models for sweeping
|
55
|
+
sweep_pos= rx.rmin
|
56
|
+
sweep_to = rx.rmax
|
57
|
+
polygons = []
|
58
|
+
modnames = []
|
59
|
+
|
60
|
+
klass_poly = parent.get_global_option(:squarize,false) ?
|
61
|
+
GerbilCharts::SVGDC::SVGSquarizedPolygon :
|
62
|
+
GerbilCharts::SVGDC::SVGPolygon
|
63
|
+
|
64
|
+
parent.modelgroup.each_model do | mod|
|
65
|
+
mod.begin_sweep
|
66
|
+
polygons << klass_poly.new
|
67
|
+
modnames << mod.name
|
68
|
+
end
|
53
69
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
klass_poly = parent.get_global_option(:squarize,false) ?
|
61
|
-
GerbilCharts::SVGDC::SVGSquarizedPolygon :
|
62
|
-
GerbilCharts::SVGDC::SVGPolygon
|
63
|
-
|
64
|
-
parent.modelgroup.each_model do | mod|
|
65
|
-
mod.begin_sweep
|
66
|
-
polygons << klass_poly.new
|
67
|
-
modnames << mod.name
|
68
|
-
end
|
69
|
-
|
70
|
-
# sweep interval
|
71
|
-
sweep_interval = parent.modelgroup.sweep_interval
|
72
|
-
|
73
|
-
# perform the sweep
|
74
|
-
while (sweep_pos<=sweep_to)
|
70
|
+
# sweep interval
|
71
|
+
sweep_interval = parent.modelgroup.sweep_interval
|
72
|
+
|
73
|
+
# perform the sweep
|
74
|
+
while (sweep_pos<=sweep_to)
|
75
75
|
acc_y = 0
|
76
76
|
parent.modelgroup.each_model_with_index do | mod, i|
|
77
|
-
|
77
|
+
t_sweep_pos = mod.sweep(sweep_pos)
|
78
|
+
acc_y += t_sweep_pos
|
78
79
|
|
79
80
|
xpos = scale_x sweep_pos,rx
|
80
81
|
ypos = scale_y acc_y,ry
|
@@ -82,31 +83,29 @@ class StackedAreaSurface < Surface
|
|
82
83
|
if polygons[i].isempty?
|
83
84
|
polygons[i].addpoint(xpos,@bounds.bottom)
|
84
85
|
end
|
85
|
-
|
86
86
|
polygons[i].addpoint(xpos,ypos)
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
sweep_pos += sweep_interval
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
90
|
+
end
|
91
|
+
|
92
|
+
# layout all polygons in reverse
|
93
|
+
i=polygons.length-1
|
94
|
+
last_x = scale_x sweep_to,rx
|
95
|
+
polygons.reverse_each do |p|
|
96
|
+
p.addpoint(last_x,@bounds.bottom)
|
97
|
+
|
98
|
+
opts = {:id => "item#{i}" }
|
99
|
+
if parent.get_global_option(:auto_tooltips,false)
|
100
|
+
opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
|
101
|
+
opts.store(:gerbiltooltip1, modnames[i])
|
102
|
+
end
|
103
|
+
|
104
|
+
g.addshape(p,opts)
|
105
|
+
i -= 1
|
106
|
+
end
|
107
107
|
|
108
108
|
end
|
109
109
|
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
110
|
+
end # class
|
111
|
+
end # module
|
@@ -13,7 +13,7 @@ class SVGWin < SVGElement
|
|
13
13
|
# add default options first
|
14
14
|
# by default windows will define fill = none and stroke = black
|
15
15
|
|
16
|
-
add_options("id"=> name, "fill" => "none"
|
16
|
+
add_options("id"=> name, "fill" => "none" )
|
17
17
|
|
18
18
|
add_options opts
|
19
19
|
|
@@ -202,19 +202,6 @@ class SVGDC
|
|
202
202
|
}
|
203
203
|
|
204
204
|
# render tooltips optional
|
205
|
-
if @use_tooltips
|
206
|
-
doc.g(:id=>'ToolTip', :opacity=>'0.8', :visibility=>'hidden', "pointer-events"=>'none') {
|
207
|
-
doc.rect(:id=>'tipbox', :x=>'0', :y=>'5', :width=>'88', :height=> '40', :rx=> '2', :ry=> '2', :fill=>'white', :stroke=>'black')
|
208
|
-
doc.text(:id=>'tipText', :x=>'5', :y=>'20', "font-family"=> 'Arial', "font-size"=>'12') {
|
209
|
-
doc.tspan(:id=>'tipTitle', :x=>'5', "font-weight"=>'bold') {
|
210
|
-
doc.cdata!("")
|
211
|
-
}
|
212
|
-
doc.tspan(:id=>'tipDesc', :x=>'5', :dy=> 15, "fill"=>'blue') {
|
213
|
-
doc.cdata!("")
|
214
|
-
}
|
215
|
-
}
|
216
|
-
}
|
217
|
-
end
|
218
205
|
}
|
219
206
|
|
220
207
|
# convert external stylesheet css to inline styles
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gerbilcharts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.26
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- vivek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: shoulda
|
@@ -89,6 +89,7 @@ files:
|
|
89
89
|
- lib/gerbilcharts/charts/line_chart.rb
|
90
90
|
- lib/gerbilcharts/charts/line_chart_table.rb
|
91
91
|
- lib/gerbilcharts/charts/matrix_chart.rb
|
92
|
+
- lib/gerbilcharts/charts/mrtg_chart_table.rb
|
92
93
|
- lib/gerbilcharts/charts/pie_chart.rb
|
93
94
|
- lib/gerbilcharts/charts/square_line_chart.rb
|
94
95
|
- lib/gerbilcharts/charts/stacked_area_chart.rb
|
@@ -127,6 +128,7 @@ files:
|
|
127
128
|
- lib/gerbilcharts/surfaces/link_pivots.rb
|
128
129
|
- lib/gerbilcharts/surfaces/mark_band.rb
|
129
130
|
- lib/gerbilcharts/surfaces/matrix_surface.rb
|
131
|
+
- lib/gerbilcharts/surfaces/mrtg_surface.rb
|
130
132
|
- lib/gerbilcharts/surfaces/panel.rb
|
131
133
|
- lib/gerbilcharts/surfaces/pie_surface.rb
|
132
134
|
- lib/gerbilcharts/surfaces/rect.rb
|
@@ -176,8 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
178
|
- !ruby/object:Gem::Version
|
177
179
|
version: '0'
|
178
180
|
requirements: []
|
179
|
-
|
180
|
-
rubygems_version: 2.5.1
|
181
|
+
rubygems_version: 3.2.32
|
181
182
|
signing_key:
|
182
183
|
specification_version: 4
|
183
184
|
summary: SVG timeseries charting
|