gerbilcharts 0.10.3 → 0.10.25
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.rb +1 -0
- data/lib/gerbilcharts/charts/area_chart.rb +15 -5
- data/lib/gerbilcharts/charts/chart_base.rb +14 -0
- data/lib/gerbilcharts/charts/line_chart.rb +14 -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 +13 -5
- data/lib/gerbilcharts/charts/stacked_area_chart.rb +19 -5
- data/lib/gerbilcharts/models/bucketized_timeseries_graph_model.rb +2 -4
- data/lib/gerbilcharts/models/graph_model.rb +12 -0
- data/lib/gerbilcharts/models/graph_model_group.rb +9 -0
- data/lib/gerbilcharts/models/monotonous_graph_model.rb +19 -14
- data/lib/gerbilcharts/models/presets.rb +22 -12
- data/lib/gerbilcharts/models/time_series_graph_model.rb +2 -7
- data/lib/gerbilcharts/surfaces.rb +2 -0
- data/lib/gerbilcharts/surfaces/area_surface.rb +30 -20
- data/lib/gerbilcharts/surfaces/detailed_legend.rb +18 -5
- data/lib/gerbilcharts/surfaces/graph_element.rb +1 -1
- data/lib/gerbilcharts/surfaces/grid.rb +12 -12
- data/lib/gerbilcharts/surfaces/legend.rb +11 -7
- data/lib/gerbilcharts/surfaces/line_surface.rb +20 -11
- data/lib/gerbilcharts/surfaces/link_pivots.rb +57 -0
- 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/surface.rb +1 -2
- data/lib/gerbilcharts/surfaces/tracker.rb +3 -3
- metadata +10 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ab4d1e7b91e428def41543bb977bff3461c2ef72d5213ff578b6fba14dc61ea2
|
|
4
|
+
data.tar.gz: bd656b9672a061fe3b52ca7eef0d4920cf65f9e2cf72802f11de39cc0fde44db
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 29094bdd20e10c4c29d4120839fb55e8883424b6300a58296eab7ece85cd952aaa3febd407d6ba2709fd8b807bea89f64afba955878e03ab8d8563b3854ce0ac
|
|
7
|
+
data.tar.gz: 25b5413cf6830914f0f8e1a90e06c0d1da8cdc984e54bad63f4e871a59a90473ed8aa119e50b5ea6ba63c828363ec270496e0b5b8e90f0682e0ca015f6553630
|
data/lib/gerbilcharts/charts.rb
CHANGED
|
@@ -23,17 +23,27 @@ 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
|
+
|
|
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
|
|
35
|
+
|
|
36
|
+
# link pivots
|
|
37
|
+
if @feature_linkpivots
|
|
38
|
+
@thechart.add_child(GerbilCharts::Surfaces::LinkPivots.new(:orient => ORIENT_OVERLAY ))
|
|
39
|
+
end
|
|
40
|
+
|
|
26
41
|
@thechart.add_child(GerbilCharts::Surfaces::TitlePanel.new(:orient => ORIENT_OVERLAY, :dim => 30))
|
|
27
|
-
@thechart.add_child(GerbilCharts::Surfaces::AreaSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
|
28
42
|
@thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => @legend_width))
|
|
29
43
|
@thechart.add_child(GerbilCharts::Surfaces::DetailedLegend.new(:orient=> ORIENT_OVERLAY, :dim => 3*@legend_width))
|
|
30
44
|
@thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 ))
|
|
31
45
|
@thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
|
|
32
46
|
|
|
33
|
-
# optional features
|
|
34
|
-
if @feature_timetracker
|
|
35
|
-
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY ))
|
|
36
|
-
end
|
|
37
47
|
end
|
|
38
48
|
|
|
39
49
|
end
|
|
@@ -29,6 +29,7 @@ module GerbilCharts::Charts
|
|
|
29
29
|
# [+:scaling_y+] Allowed values are :auto, :auto_0, and an array [min,max] (default = :auto)
|
|
30
30
|
# [+:circle_data_points+] Draws a tiny circle around datapoints for tooltips
|
|
31
31
|
# [+:enabletimetracker+] Time tracker javascript selector (default = false)
|
|
32
|
+
# [+:enablelinkpivots+] Link Pivot box javascript selector (default = false)
|
|
32
33
|
#
|
|
33
34
|
class ChartBase
|
|
34
35
|
|
|
@@ -50,6 +51,7 @@ class ChartBase
|
|
|
50
51
|
attr_reader :thechart
|
|
51
52
|
attr_reader :renderopts
|
|
52
53
|
attr_reader :feature_timetracker
|
|
54
|
+
attr_reader :feature_linkpivots
|
|
53
55
|
attr_reader :legend_width
|
|
54
56
|
|
|
55
57
|
def initialize(opt={})
|
|
@@ -60,6 +62,18 @@ class ChartBase
|
|
|
60
62
|
@feature_timetracker=opt[:enabletimetracker]
|
|
61
63
|
opt.delete :enabletimetracker
|
|
62
64
|
end
|
|
65
|
+
|
|
66
|
+
@enablelinkpivots=false
|
|
67
|
+
if opt[:enablelinkpivots]
|
|
68
|
+
@feature_linkpivots=opt[:enablelinkpivots]
|
|
69
|
+
opt.delete :enablelinkpivots
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
@feature_circledatapoints=false
|
|
73
|
+
if opt[:circle_data_points]
|
|
74
|
+
@feature_circledatapoints=opt[:circle_data_points]
|
|
75
|
+
end
|
|
76
|
+
|
|
63
77
|
|
|
64
78
|
# pass on options to chart object
|
|
65
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,9 +26,20 @@ 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
|
-
|
|
31
|
+
|
|
32
|
+
# optional features
|
|
33
|
+
if @feature_timetracker
|
|
34
|
+
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY ))
|
|
35
|
+
end
|
|
30
36
|
@thechart.add_child(GerbilCharts::Surfaces::LineSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
|
37
|
+
|
|
38
|
+
# link pivots
|
|
39
|
+
if @feature_linkpivots
|
|
40
|
+
@thechart.add_child(GerbilCharts::Surfaces::LinkPivots.new(:orient => ORIENT_OVERLAY ))
|
|
41
|
+
end
|
|
42
|
+
@thechart.add_child(GerbilCharts::Surfaces::TitlePanel.new(:orient => ORIENT_OVERLAY, :dim => 30))
|
|
31
43
|
@thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => @legend_width))
|
|
32
44
|
@thechart.add_child(GerbilCharts::Surfaces::DetailedLegend.new(:orient=> ORIENT_OVERLAY, :dim => 3*@legend_width))
|
|
33
45
|
@thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 ))
|
|
@@ -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,17 +28,25 @@ 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
|
-
|
|
31
|
+
|
|
32
|
+
# optional features
|
|
33
|
+
if @feature_timetracker
|
|
34
|
+
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY ))
|
|
35
|
+
end
|
|
36
|
+
|
|
32
37
|
@thechart.add_child(GerbilCharts::Surfaces::SquareLineSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
|
|
38
|
+
# link pivots
|
|
39
|
+
if @feature_linkpivots
|
|
40
|
+
@thechart.add_child(GerbilCharts::Surfaces::LinkPivots.new(:orient => ORIENT_OVERLAY ))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
@thechart.add_child(GerbilCharts::Surfaces::TitlePanel.new(:orient => ORIENT_OVERLAY, :dim => 30))
|
|
33
44
|
@thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => @legend_width))
|
|
34
45
|
@thechart.add_child(GerbilCharts::Surfaces::DetailedLegend.new(:orient=> ORIENT_OVERLAY, :dim => 3*@legend_width))
|
|
35
46
|
@thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 ))
|
|
36
47
|
@thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
|
|
37
48
|
|
|
38
|
-
|
|
39
|
-
if @feature_timetracker
|
|
40
|
-
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_OVERLAY ))
|
|
41
|
-
end
|
|
49
|
+
|
|
42
50
|
end
|
|
43
51
|
end
|
|
44
52
|
|
|
@@ -15,9 +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
|
-
|
|
19
|
-
|
|
20
|
-
@
|
|
18
|
+
|
|
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
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# link pivots
|
|
29
|
+
if @feature_linkpivots
|
|
30
|
+
@thechart.add_child(GerbilCharts::Surfaces::LinkPivots.new(:orient => ORIENT_OVERLAY ))
|
|
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))
|
|
21
35
|
@thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 , :cumulative => true ))
|
|
22
36
|
@thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
|
|
23
37
|
|
|
@@ -26,7 +40,7 @@ class StackedAreaChart < ChartBase
|
|
|
26
40
|
@thechart.add_child(GerbilCharts::Surfaces::Tracker.new(:orient => ORIENT_SOUTH, :dim => 10 ))
|
|
27
41
|
end
|
|
28
42
|
end
|
|
29
|
-
end
|
|
30
43
|
|
|
31
|
-
end
|
|
44
|
+
end # class
|
|
45
|
+
end # module
|
|
32
46
|
|
|
@@ -13,6 +13,7 @@ class BucketizedTimeSeriesGraphModel < TimeSeriesGraphModel
|
|
|
13
13
|
attr_reader :bucket_size_secs # current bucket size
|
|
14
14
|
attr_reader :behavior # :average or :max or :sum
|
|
15
15
|
attr_reader :last_sweep_pos # :nodoc:
|
|
16
|
+
attr_reader :vartype
|
|
16
17
|
|
|
17
18
|
def initialize(name,bucketsec, opt={:behavior => :average, :vartype => :bits_per_sec })
|
|
18
19
|
super(name,opt)
|
|
@@ -20,6 +21,7 @@ class BucketizedTimeSeriesGraphModel < TimeSeriesGraphModel
|
|
|
20
21
|
@samp_count =0
|
|
21
22
|
@behavior = opt[:behavior]
|
|
22
23
|
@last_sweep_pos=0
|
|
24
|
+
@vartype = opt[:vartype]
|
|
23
25
|
@aggregation_factor = case opt[:vartype]
|
|
24
26
|
when :bits_per_sec ; @bucket_size_secs / 8.0
|
|
25
27
|
when :per_sec ; @bucket_size_secs
|
|
@@ -77,11 +79,7 @@ class BucketizedTimeSeriesGraphModel < TimeSeriesGraphModel
|
|
|
77
79
|
tv= normalize_time_input(tv_in)
|
|
78
80
|
exp=tv.tv_sec.divmod(@bucket_size_secs)
|
|
79
81
|
|
|
80
|
-
if exp[1] >= @bucket_size_secs/2
|
|
81
|
-
return Time.at(exp[0]*@bucket_size_secs + @bucket_size_secs)
|
|
82
|
-
else
|
|
83
82
|
return Time.at(exp[0]*@bucket_size_secs)
|
|
84
|
-
end
|
|
85
83
|
end
|
|
86
84
|
|
|
87
85
|
# how many buckets separate the two buckettimes
|
|
@@ -15,6 +15,7 @@ class GraphModel
|
|
|
15
15
|
attr_reader :userlabel1 # map to tooltip 1
|
|
16
16
|
attr_reader :userlabel2 # map to tooltip 2
|
|
17
17
|
attr_reader :transformer # value transformer (a lambda function)
|
|
18
|
+
attr_accessor :href_pivot # href for pivot box (used w/ time selector)
|
|
18
19
|
|
|
19
20
|
def initialize(n="Untitled")
|
|
20
21
|
@name=n
|
|
@@ -42,11 +43,22 @@ class GraphModel
|
|
|
42
43
|
h1=h.gsub("{","%7B")
|
|
43
44
|
@href=h1.gsub("}","%7D")
|
|
44
45
|
end
|
|
46
|
+
|
|
47
|
+
# clean up the href (todo: improve this)
|
|
48
|
+
def setHrefPivot(h)
|
|
49
|
+
h1=h.gsub("{","%7B")
|
|
50
|
+
@href_pivot=h1.gsub("}","%7D")
|
|
51
|
+
end
|
|
52
|
+
|
|
45
53
|
|
|
46
54
|
def hasHref?
|
|
47
55
|
return @href != nil
|
|
48
56
|
end
|
|
49
57
|
|
|
58
|
+
def hasHrefPivot?
|
|
59
|
+
return @href_pivot != nil
|
|
60
|
+
end
|
|
61
|
+
|
|
50
62
|
def setUserData(d)
|
|
51
63
|
@userdata=d
|
|
52
64
|
end
|
|
@@ -163,27 +163,32 @@ 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
|
-
|
|
171
|
+
return [0,0,0,0,0,0] if @yarr.size==0
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
a = []
|
|
174
|
+
a[0]= @yrange.rmin
|
|
175
|
+
a[1]= @yrange.rmax
|
|
176
|
+
a[3]=0
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
178
|
+
@yarr.each do |v|
|
|
179
|
+
a[3] = a[3] + v
|
|
180
|
+
end
|
|
181
|
+
a[2] = a[3]/@yarr.size
|
|
182
|
+
a[3] = a[3] * @aggregation_factor
|
|
183
|
+
a[4] = latest_val
|
|
184
|
+
|
|
185
|
+
# 95th statistical
|
|
186
|
+
rank=(@yarr.size * 0.95).round
|
|
187
|
+
a[5] = @yarr.sort()[rank-1]
|
|
188
|
+
|
|
189
|
+
return a
|
|
185
190
|
end
|
|
186
|
-
|
|
191
|
+
|
|
187
192
|
private
|
|
188
193
|
# recompute ranges
|
|
189
194
|
def recompute_ranges
|
|
@@ -11,24 +11,34 @@ 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
|
-
[
|
|
21
|
-
[
|
|
22
|
-
[
|
|
23
|
-
[
|
|
24
|
-
[
|
|
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] ,
|
|
27
|
+
[10_000_000_000, 2_000_000_000] ,
|
|
28
|
+
[20_000_000_000, 5_000_000_000] ,
|
|
29
|
+
[50_000_000_000, 10_000_000_000] ,
|
|
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] ,
|
|
33
|
+
[1_000_000_000_000, 200_000_000_000] ,
|
|
34
|
+
[10_000_000_000_000,2_000_000_000_000] ,
|
|
25
35
|
]
|
|
26
36
|
|
|
27
37
|
TIMEPRESETS = [
|
|
28
38
|
[0,0], [1,0.2], [5,1], [10,1],[20,5],
|
|
29
39
|
[30,10],[60,10],[120,15], [300,60], [600,120],
|
|
30
40
|
[900,300], [1800,300],
|
|
31
|
-
[3600,
|
|
41
|
+
[3600,300], [7200,900],[10800,1800], [14400,3600], [21600,3600],
|
|
32
42
|
[43200, 7200], [86400,7200],
|
|
33
43
|
[172800, 43200], [259200,86400],
|
|
34
44
|
[604800, 86400], [1209600,172800],
|
|
@@ -34,9 +34,7 @@ class TimeSeriesGraphModel < MonotonousGraphModel
|
|
|
34
34
|
def normalize_time_input(tin)
|
|
35
35
|
if tin.is_a? Time
|
|
36
36
|
return tin
|
|
37
|
-
elsif tin.is_a?
|
|
38
|
-
return Time.at(tin)
|
|
39
|
-
elsif tin.is_a? Bignum
|
|
37
|
+
elsif tin.is_a? Integer
|
|
40
38
|
if tin > 0xffffffff
|
|
41
39
|
return Time.at(tin>>32)
|
|
42
40
|
else
|
|
@@ -44,10 +42,7 @@ class TimeSeriesGraphModel < MonotonousGraphModel
|
|
|
44
42
|
end
|
|
45
43
|
end
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
return Time.at(tin) if tin.is_a? Fixnum
|
|
49
|
-
return Time.at(tin>>32) if tin.is_a? Bignum
|
|
50
|
-
raise "Timeseries graph model expects Time,Bignum,Fixnum to represent time"
|
|
45
|
+
raise "Timeseries graph model expects Time, or Integer represent time"
|
|
51
46
|
end
|
|
52
47
|
|
|
53
48
|
|
|
@@ -35,3 +35,5 @@ require 'gerbilcharts/surfaces/square_line_surface'
|
|
|
35
35
|
require 'gerbilcharts/surfaces/matrix_surface'
|
|
36
36
|
require 'gerbilcharts/surfaces/conversation_ring'
|
|
37
37
|
require 'gerbilcharts/surfaces/bubble_surface'
|
|
38
|
+
require 'gerbilcharts/surfaces/link_pivots'
|
|
39
|
+
require 'gerbilcharts/surfaces/mrtg_surface'
|
|
@@ -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
|
|
@@ -45,12 +45,12 @@ class DetailedLegend < GraphElement
|
|
|
45
45
|
|
|
46
46
|
# toggle detail/mini legend
|
|
47
47
|
g.rectangle(@bounds.left-5,@bounds.top,5,5, {:href => "javascript:void(0);",
|
|
48
|
-
:onclick => "showMiniLegend();",
|
|
48
|
+
:onclick => "showMiniLegend(event);",
|
|
49
49
|
:fill => "white",
|
|
50
50
|
:stroke => "none",
|
|
51
51
|
:gerbiltooltip1 => "Click to show compact legend" })
|
|
52
|
-
g.textout(@bounds.left-4,@bounds.top+5,'>', {'
|
|
53
|
-
:onclick => "showMiniLegend();",
|
|
52
|
+
g.textout(@bounds.left-4,@bounds.top+5,'>', {:class=>'legend-tool',
|
|
53
|
+
:onclick => "showMiniLegend(event);",
|
|
54
54
|
:gerbiltooltip1 => "Click to show compact legend" })
|
|
55
55
|
|
|
56
56
|
|
|
@@ -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
|
|
@@ -24,12 +24,12 @@ class Grid < GraphElement
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
# horiz subticks
|
|
27
|
-
g.newwin('hgridsub', {:class => "gridlinesub"} ) do |g|
|
|
28
|
-
ry.each_tick(@tick_count) do |val|
|
|
29
|
-
yp = scale_y val,ry
|
|
30
|
-
g.line(@bounds.left,yp,@bounds.right,yp)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
27
|
+
# g.newwin('hgridsub', {:class => "gridlinesub"} ) do |g|
|
|
28
|
+
# ry.each_tick(@tick_count) do |val|
|
|
29
|
+
# yp = scale_y val,ry
|
|
30
|
+
# g.line(@bounds.left,yp,@bounds.right,yp)
|
|
31
|
+
# end
|
|
32
|
+
# end
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
scaling_x = parent.get_global_option(:scaling_x,:auto)
|
|
@@ -47,12 +47,12 @@ class Grid < GraphElement
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
g.newwin('vgridsub', {:class => "gridlinesub"} ) do |g|
|
|
51
|
-
rx.each_tick(0) do |val|
|
|
52
|
-
xp = scale_x val,rwx
|
|
53
|
-
g.line(xp,@bounds.top,xp,@bounds.bottom)
|
|
54
|
-
end
|
|
55
|
-
end
|
|
50
|
+
# g.newwin('vgridsub', {:class => "gridlinesub"} ) do |g|
|
|
51
|
+
# rx.each_tick(0) do |val|
|
|
52
|
+
# xp = scale_x val,rwx
|
|
53
|
+
# g.line(xp,@bounds.top,xp,@bounds.bottom)
|
|
54
|
+
# end
|
|
55
|
+
# end
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
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
|
|
@@ -25,13 +29,13 @@ class Legend < GraphElement
|
|
|
25
29
|
|
|
26
30
|
# toggle detail/mini legend
|
|
27
31
|
g.rectangle(@bounds.left-5,@bounds.top,5,5, {:href => "javascript:void(0);",
|
|
28
|
-
:onclick => "showDetailedLegend();",
|
|
32
|
+
:onclick => "showDetailedLegend(event);",
|
|
29
33
|
:fill => "white",
|
|
30
34
|
:stroke => "none",
|
|
31
35
|
:gerbiltooltip1 => "Click to show a detailed legend" })
|
|
32
36
|
|
|
33
|
-
g.textout(@bounds.left-7,@bounds.top+5,'+', {
|
|
34
|
-
:onclick => "showDetailedLegend();",
|
|
37
|
+
g.textout(@bounds.left-7,@bounds.top+5,'+', {:class=> 'legend-tool',
|
|
38
|
+
:onclick => "showDetailedLegend(event);",
|
|
35
39
|
:gerbiltooltip1 => "Click to show a detailed legend" })
|
|
36
40
|
|
|
37
41
|
# shift
|
|
@@ -40,8 +44,8 @@ class Legend < GraphElement
|
|
|
40
44
|
:fill => "white",
|
|
41
45
|
:stroke => "none",
|
|
42
46
|
:gerbiltooltip1 => "Click to move legend to left side" })
|
|
43
|
-
g.textout(@bounds.left-7,@bounds.top+15,'<', {'
|
|
44
|
-
:onclick => "shiftLegend(#{-@bounds.left+50});",
|
|
47
|
+
g.textout(@bounds.left-7,@bounds.top+15,'<', {:class=>'legend-tool',
|
|
48
|
+
:onclick => "shiftLegend(#{-@bounds.left+50});",
|
|
45
49
|
:gerbiltooltip1 => "Click to move legend to left side" })
|
|
46
50
|
|
|
47
51
|
|
|
@@ -51,8 +55,8 @@ class Legend < GraphElement
|
|
|
51
55
|
:fill => "white",
|
|
52
56
|
:stroke => "none" ,
|
|
53
57
|
:gerbiltooltip1 => "Click to move legend to right side"})
|
|
54
|
-
g.textout(@bounds.left-7,@bounds.top+25,'>', {
|
|
55
|
-
:onclick => "shiftLegend(0);",
|
|
58
|
+
g.textout(@bounds.left-7,@bounds.top+25,'>', {:class => 'legend-tool',
|
|
59
|
+
:onclick => "shiftLegend(0);",
|
|
56
60
|
:gerbiltooltip1 => "Click to move legend to right side"})
|
|
57
61
|
rbox = Rect.new
|
|
58
62
|
rbox.initfrom(@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,57 @@
|
|
|
1
|
+
module GerbilCharts::Surfaces
|
|
2
|
+
|
|
3
|
+
# == Link Pivots
|
|
4
|
+
# When time is selected, we show custom links to Jump to other places
|
|
5
|
+
#
|
|
6
|
+
class LinkPivots < GraphElement
|
|
7
|
+
|
|
8
|
+
attr_accessor :just
|
|
9
|
+
|
|
10
|
+
def initialize(opts={})
|
|
11
|
+
@class = "linkpivots"
|
|
12
|
+
super(opts)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def int_render(g)
|
|
16
|
+
opts = {:class => "linkpivots", 'text-anchor' => 'middle' }
|
|
17
|
+
|
|
18
|
+
win = g.newwin( "linkpivots", {:class => 'linkpivots' , :visibility => 'hidden' })
|
|
19
|
+
g.setactivewindow(win)
|
|
20
|
+
|
|
21
|
+
# count determines the bounds
|
|
22
|
+
@bounds.top = @bounds.bottom - 20 * parent.modelgroup.count - 10
|
|
23
|
+
if @bounds.top < 0
|
|
24
|
+
@bounds.top =0
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
g.rectangle_r(@bounds)
|
|
29
|
+
|
|
30
|
+
# start
|
|
31
|
+
x = @bounds.left + @bounds.width/2
|
|
32
|
+
y = @bounds.top + 15
|
|
33
|
+
|
|
34
|
+
parent.modelgroup.each_model_with_index do | mod, i|
|
|
35
|
+
|
|
36
|
+
if mod.hasHrefPivot?
|
|
37
|
+
opts.store(:href, mod.href_pivot)
|
|
38
|
+
opts.store(:base_href, mod.href_pivot)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
opts.merge!( :class => "legendtext")
|
|
42
|
+
g.textout(x,y, "Drill down into #{mod.name}",opts)
|
|
43
|
+
|
|
44
|
+
y += 20;
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def align_to_anchor(anc)
|
|
50
|
+
super
|
|
51
|
+
@bounds.deflate_h(40,40)
|
|
52
|
+
@bounds.top = @bounds.bottom - 40
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -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
|
|
@@ -48,7 +48,7 @@ class Tracker < GraphElement
|
|
|
48
48
|
xfrag.tspan( :id => 'trackertextinterval', :x=>0, :y=>ty) {
|
|
49
49
|
"15 Minutes"
|
|
50
50
|
}
|
|
51
|
-
xfrag.tspan( :class => 'trackertextfromts', :id => 'trackertextfromts', :x=>0, :dy=>
|
|
51
|
+
xfrag.tspan( :class => 'trackertextfromts', :id => 'trackertextfromts', :x=>0, :dy=>25) {
|
|
52
52
|
"Starting: Apr 2 1973, 05:00:00 PM"
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -59,8 +59,8 @@ class Tracker < GraphElement
|
|
|
59
59
|
:gerb_fromts=>rx.rmin.tv_sec,
|
|
60
60
|
:gerb_seconds=>rx.rmax.tv_sec-rx.rmin.tv_sec,
|
|
61
61
|
:gerb_scale =>(rx.delta)/parent.anchor.bounds.width,
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
:gerb_tzoffset => Time.new.utc_offset,
|
|
63
|
+
:gerb_tzname => Time.new.zone,
|
|
64
64
|
:gerb_selts=>1,
|
|
65
65
|
:gerb_selsecs=>1)
|
|
66
66
|
|
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.25
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- vivek
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-04-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: shoulda
|
|
@@ -39,7 +39,7 @@ dependencies:
|
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
42
|
+
name: juwelier
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - ">="
|
|
@@ -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
|
|
@@ -124,8 +125,10 @@ files:
|
|
|
124
125
|
- lib/gerbilcharts/surfaces/impulse_surface.rb
|
|
125
126
|
- lib/gerbilcharts/surfaces/legend.rb
|
|
126
127
|
- lib/gerbilcharts/surfaces/line_surface.rb
|
|
128
|
+
- lib/gerbilcharts/surfaces/link_pivots.rb
|
|
127
129
|
- lib/gerbilcharts/surfaces/mark_band.rb
|
|
128
130
|
- lib/gerbilcharts/surfaces/matrix_surface.rb
|
|
131
|
+
- lib/gerbilcharts/surfaces/mrtg_surface.rb
|
|
129
132
|
- lib/gerbilcharts/surfaces/panel.rb
|
|
130
133
|
- lib/gerbilcharts/surfaces/pie_surface.rb
|
|
131
134
|
- lib/gerbilcharts/surfaces/rect.rb
|
|
@@ -160,7 +163,7 @@ homepage: http://github.com/vivekrajan/gerbilcharts
|
|
|
160
163
|
licenses:
|
|
161
164
|
- MIT
|
|
162
165
|
metadata: {}
|
|
163
|
-
post_install_message:
|
|
166
|
+
post_install_message:
|
|
164
167
|
rdoc_options: []
|
|
165
168
|
require_paths:
|
|
166
169
|
- lib
|
|
@@ -175,9 +178,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
175
178
|
- !ruby/object:Gem::Version
|
|
176
179
|
version: '0'
|
|
177
180
|
requirements: []
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
signing_key:
|
|
181
|
+
rubygems_version: 3.1.4
|
|
182
|
+
signing_key:
|
|
181
183
|
specification_version: 4
|
|
182
184
|
summary: SVG timeseries charting
|
|
183
185
|
test_files: []
|