gerbilcharts 0.2.8 → 0.2.10
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -6
- data/Manifest.txt +1 -0
- data/README.txt +2 -0
- data/lib/gerbilcharts/models/graph_model_group.rb +10 -9
- data/lib/gerbilcharts/public/brushmetal.css +227 -227
- data/lib/gerbilcharts/public/gerbil.js +351 -356
- data/lib/gerbilcharts/surfaces/area_surface.rb +22 -2
- data/lib/gerbilcharts/surfaces/horizontal_axis.rb +14 -8
- data/lib/gerbilcharts/surfaces/horizontal_time_axis.rb +3 -1
- data/lib/gerbilcharts/surfaces/tracker.rb +8 -6
- data/lib/gerbilcharts/svgdc.rb +1 -0
- data/lib/gerbilcharts/svgdc/css_inliner.rb +59 -0
- data/lib/gerbilcharts/svgdc/svgdc.rb +36 -6
- data/lib/gerbilcharts/version.rb +1 -1
- data/test/test_embed_styles.rb +35 -0
- metadata +4 -2
@@ -2,6 +2,12 @@ module GerbilCharts::Surfaces
|
|
2
2
|
|
3
3
|
# == Area Surface w/ transparency
|
4
4
|
# The transparency kind of allows hidden items to be shown
|
5
|
+
#
|
6
|
+
# ===Options
|
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
|
5
11
|
#
|
6
12
|
class AreaSurface < Surface
|
7
13
|
def initialize(opts={})
|
@@ -9,13 +15,17 @@ class AreaSurface < Surface
|
|
9
15
|
end
|
10
16
|
|
11
17
|
def int_render(g)
|
18
|
+
|
19
|
+
|
12
20
|
range_options_x = parent.get_global_option(:scaling_x,:auto)
|
13
21
|
range_options_y = parent.get_global_option(:scaling_y,:auto)
|
14
22
|
butterfly = parent.get_global_option(:butterfly,false)
|
23
|
+
zbucketsize = parent.get_global_option(:zero_bucketsize,nil)
|
15
24
|
|
16
25
|
rx = parent.modelgroup.effective_range_x(range_options_x)
|
17
26
|
ry = parent.modelgroup.effective_range_y(range_options_y)
|
18
27
|
|
28
|
+
|
19
29
|
# ajax if used
|
20
30
|
if parent.usesAjax?
|
21
31
|
set_ajaxSurfaceContext(rx.rmax,ry.rmax,"AREA")
|
@@ -29,18 +39,28 @@ class AreaSurface < Surface
|
|
29
39
|
parent.modelgroup.each_model_with_index do | mod, i|
|
30
40
|
g.begin_polygon
|
31
41
|
firstpoint=true
|
32
|
-
xpos=0
|
33
|
-
|
42
|
+
xpos,ypos=0,0
|
43
|
+
last_x=nil
|
34
44
|
mod.each_tuple do |x,y|
|
35
45
|
|
36
46
|
y =-y if butterfly and i.odd?
|
37
47
|
|
38
48
|
xpos = scale_x x,rx
|
39
49
|
ypos = scale_y y,ry
|
50
|
+
|
40
51
|
if firstpoint
|
41
52
|
g.polygon_point xpos,y_zero
|
42
53
|
firstpoint=false
|
43
54
|
end
|
55
|
+
|
56
|
+
unless zbucketsize.nil?
|
57
|
+
if last_x && (x-last_x) > zbucketsize
|
58
|
+
g.polygon_point scale_x(last_x,rx) ,y_zero
|
59
|
+
g.polygon_point scale_x(x,rx) ,y_zero
|
60
|
+
end
|
61
|
+
last_x=x
|
62
|
+
end
|
63
|
+
|
44
64
|
g.polygon_point xpos,ypos
|
45
65
|
end
|
46
66
|
g.polygon_point xpos,y_zero
|
@@ -12,17 +12,23 @@ class HorizontalAxis < Axis
|
|
12
12
|
|
13
13
|
return if parent.modelgroup.empty?
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
range_options_x = parent.get_global_option(:scaling_x,:auto)
|
16
|
+
rawx = parent.modelgroup.effective_range_x(range_options_x)
|
17
|
+
|
18
|
+
# need roundx for labels
|
19
|
+
roundx = parent.modelgroup.effective_round_range_x
|
20
|
+
roundx.each_label do |val,label|
|
21
|
+
xp = scale_x val,rawx
|
22
|
+
|
23
|
+
break if val>rawx.rmax
|
18
24
|
|
19
|
-
|
20
|
-
|
25
|
+
# make sure edge ones are visible
|
26
|
+
if (xp>=@bounds.right-10)
|
21
27
|
xp = @bounds.right-10
|
22
|
-
|
28
|
+
end
|
23
29
|
|
24
|
-
|
25
|
-
|
30
|
+
g.textout(xp, @bounds.top+10, label, {:class => "axislabel", "text-anchor" => "middle"})
|
31
|
+
g.line(xp,@bounds.top-2,xp,@bounds.top+3, {:class => "axistickmajor"})
|
26
32
|
end
|
27
33
|
|
28
34
|
end
|
@@ -12,9 +12,11 @@ class HorizontalTimeAxis < HorizontalAxis
|
|
12
12
|
|
13
13
|
def int_render(g)
|
14
14
|
super
|
15
|
-
|
15
|
+
|
16
16
|
rx = parent.modelgroup.effective_round_range_x
|
17
17
|
sfmt = rx.format_min_value
|
18
|
+
|
19
|
+
|
18
20
|
g.textout(@bounds.left-20, @bounds.top+20, sfmt, {:class => "axislabelt0" })
|
19
21
|
g.line(@bounds.left,@bounds.top,@bounds.left,@bounds.top+10,{:class => "axistickmajor"})
|
20
22
|
|
@@ -21,7 +21,9 @@ class Tracker < GraphElement
|
|
21
21
|
def render_direct(xfrag)
|
22
22
|
|
23
23
|
# calculate scaling factors
|
24
|
-
|
24
|
+
range_options_x = parent.get_global_option(:scaling_x,:auto)
|
25
|
+
rx = parent.modelgroup.effective_range_x(range_options_x)
|
26
|
+
|
25
27
|
|
26
28
|
xfrag.g(:id=> 'gtrackerrect', :visibility=>'hidden') {
|
27
29
|
xfrag.rect(:id=>"trackerrect", :class=>"trackerrect",
|
@@ -50,14 +52,14 @@ class Tracker < GraphElement
|
|
50
52
|
}
|
51
53
|
}
|
52
54
|
|
53
|
-
|
54
|
-
|
55
|
+
raise "Time Tracker expects X-Axis to be a time interval " unless rx.rmin.is_a? Time
|
55
56
|
|
56
|
-
|
57
|
+
xfrag.g(:id=>"gtrackerdata", :visibility=>'hidden',
|
57
58
|
:gerb_fromts=>rx.rmin.tv_sec,
|
59
|
+
:gerb_seconds=>rx.rmax.tv_sec-rx.rmin.tv_sec,
|
58
60
|
:gerb_scale =>(rx.delta)/parent.anchor.bounds.width,
|
59
|
-
:gerb_selts=>
|
60
|
-
:gerb_selsecs=>
|
61
|
+
:gerb_selts=>1,
|
62
|
+
:gerb_selsecs=>1)
|
61
63
|
|
62
64
|
end
|
63
65
|
|
data/lib/gerbilcharts/svgdc.rb
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module GerbilCharts::SVGDC
|
4
|
+
|
5
|
+
# = CssInliner - dead simple css inliner
|
6
|
+
#
|
7
|
+
class CssInliner
|
8
|
+
|
9
|
+
attr_reader :class_table
|
10
|
+
attr_reader :selector_table
|
11
|
+
|
12
|
+
# need a css string
|
13
|
+
def initialize(css_string)
|
14
|
+
|
15
|
+
css_string.tr!("\r\n\t","")
|
16
|
+
@class_table = {}
|
17
|
+
@selector_table = {}
|
18
|
+
|
19
|
+
css_string.split('}').each do |rec|
|
20
|
+
|
21
|
+
parts = rec.split('{')
|
22
|
+
parts.each { |p| p.strip!; p.squeeze!(' ');}
|
23
|
+
|
24
|
+
case parts[0][0]
|
25
|
+
when 35; @selector_table.store(parts[0][1..-1],parts[1])
|
26
|
+
when 46; @class_table.store(parts[0][1..-1],parts[1])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# inline_doc
|
33
|
+
# inline the incoming svg string using the css
|
34
|
+
# return
|
35
|
+
# the transformed svg string with inlined styles
|
36
|
+
def inline_doc(doc_string)
|
37
|
+
rxdoc = REXML::Document.new doc_string
|
38
|
+
proc_ele(rxdoc.root)
|
39
|
+
return rxdoc.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
|
46
|
+
def proc_ele(ele)
|
47
|
+
ele.each_element_with_attribute('id') { |e| inline_style(e,e.attributes['id'],@selector_table) }
|
48
|
+
ele.each_element_with_attribute('class') { |e| inline_style(e,e.attributes['class'],@class_table) }
|
49
|
+
ele.each_element { |e| proc_ele(e)}
|
50
|
+
end
|
51
|
+
|
52
|
+
def inline_style(ele, key, tbl)
|
53
|
+
stylestr = tbl[key]
|
54
|
+
ele.add_attribute('style',stylestr) if stylestr
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -32,6 +32,7 @@ class SVGDC
|
|
32
32
|
attr_reader :ajaxOptions
|
33
33
|
attr_reader :ajaxContext
|
34
34
|
attr_reader :use_tooltips
|
35
|
+
attr_reader :embed_style
|
35
36
|
|
36
37
|
def initialize(w,h)
|
37
38
|
@width,@height=w,h
|
@@ -41,6 +42,7 @@ class SVGDC
|
|
41
42
|
setactivewindow(@base_win)
|
42
43
|
@svg_predefs = []
|
43
44
|
@use_tooltips=true
|
45
|
+
@embed_style=false
|
44
46
|
end
|
45
47
|
|
46
48
|
# ==Note on Stylesheet
|
@@ -48,21 +50,29 @@ class SVGDC
|
|
48
50
|
# If you want to use your own stylesheets put them in the working directory, or in the
|
49
51
|
# public directory of gerbilcharts.
|
50
52
|
# To inline stylesheet use "inline:<stylesheetname>" , eg "inline:brushmetal.css"
|
53
|
+
# To embed stylesheet use "embed:<stylesheetname>" , eg "embed:brushmetal.css"
|
51
54
|
# Default is to xref a stylesheet
|
52
55
|
def add_stylesheetfile(cssfile_in)
|
56
|
+
return unless cssfile_in
|
53
57
|
cssfile=cssfile_in.gsub(/^inline:/,'')
|
54
58
|
if cssfile.length < cssfile_in.length
|
55
59
|
@svg_styles = get_file_content(cssfile)
|
56
60
|
else
|
57
|
-
|
58
|
-
|
61
|
+
cssfile=cssfile_in.gsub(/^embed:/,'')
|
62
|
+
if cssfile.length < cssfile_in.length
|
63
|
+
@svg_styles = get_file_content(cssfile)
|
64
|
+
@embed_style = true
|
65
|
+
else
|
66
|
+
@ref_styles ||= []
|
67
|
+
@ref_styles << cssfile
|
68
|
+
end
|
59
69
|
end
|
60
|
-
|
61
70
|
end
|
62
71
|
|
63
72
|
# To inline javascript use "inline:<javascript-file-name>"
|
64
73
|
#
|
65
74
|
def add_javascriptfile(jsfile_in)
|
75
|
+
return unless jsfile_in
|
66
76
|
jsfile=jsfile_in.gsub(/^inline:/,'')
|
67
77
|
if jsfile.length < jsfile.length
|
68
78
|
@svg_javascript ||= ""
|
@@ -147,7 +157,7 @@ class SVGDC
|
|
147
157
|
doc.svg(svg_attributes) {
|
148
158
|
|
149
159
|
# stylesheet (inlined into SVG)
|
150
|
-
doc.style(@svg_styles, :type => "text/css") if @svg_styles
|
160
|
+
doc.style(@svg_styles, :type => "text/css") if @svg_styles and not @embed_style
|
151
161
|
|
152
162
|
# javascripts (ajax, etc) hrefed
|
153
163
|
@ref_javascripts && @ref_javascripts.each do |scr|
|
@@ -206,6 +216,9 @@ class SVGDC
|
|
206
216
|
}
|
207
217
|
end
|
208
218
|
}
|
219
|
+
|
220
|
+
# convert external stylesheet css to inline styles
|
221
|
+
|
209
222
|
end
|
210
223
|
|
211
224
|
# render the SVG fragments to a string
|
@@ -227,8 +240,9 @@ class SVGDC
|
|
227
240
|
|
228
241
|
render_to_frag(doc,opts)
|
229
242
|
|
230
|
-
# return the svg_string
|
231
|
-
return svg_string
|
243
|
+
# return the svg_string (inline if embedding desired)
|
244
|
+
return @embed_style ? do_embed_styles(svg_string) : svg_string
|
245
|
+
|
232
246
|
end
|
233
247
|
|
234
248
|
# render the SVG to a file
|
@@ -359,6 +373,22 @@ private
|
|
359
373
|
raise "Resource #{fname} not found in current directory or in the gerbilcharts/public folder"
|
360
374
|
end
|
361
375
|
|
376
|
+
# external styles to inline (for svg_web)
|
377
|
+
def do_embed_styles(svgdoc_string)
|
378
|
+
|
379
|
+
if @ref_styles
|
380
|
+
css_string = File.read('@ref_styles')
|
381
|
+
else
|
382
|
+
css_string = @svg_styles
|
383
|
+
end
|
384
|
+
|
385
|
+
css_inliner = GerbilCharts::SVGDC::CssInliner.new(css_string)
|
386
|
+
return css_inliner.inline_doc(svgdoc_string)
|
387
|
+
|
388
|
+
end
|
389
|
+
|
390
|
+
|
391
|
+
|
362
392
|
end
|
363
393
|
|
364
394
|
end
|
data/lib/gerbilcharts/version.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestLines < Test::Unit::TestCase
|
4
|
+
|
5
|
+
attr_reader :mod1, :mod2, :modbucket1
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@test_vector_tm1 = []
|
9
|
+
tbeg = Time.local( 1978, "jun", 5, 9, 10, 0, 0)
|
10
|
+
sbeg = tbeg
|
11
|
+
sec_inc = 50
|
12
|
+
|
13
|
+
for i in (0..20)
|
14
|
+
@test_vector_tm1 << [sbeg + i*sec_inc, i*sec_inc*250*rand() ]
|
15
|
+
end
|
16
|
+
|
17
|
+
@mod1 = GerbilCharts::Models::TimeSeriesGraphModel.new("External Gateway")
|
18
|
+
@mod1.add_tuples @test_vector_tm1
|
19
|
+
|
20
|
+
@modgroup = GerbilCharts::Models::GraphModelGroup.new("Hosts")
|
21
|
+
@modgroup.add(@mod1)
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# test a line chart
|
27
|
+
def test_line_1
|
28
|
+
|
29
|
+
mychart = GerbilCharts::Charts::AreaChart.new( :width => 450, :height => 250, :style => 'embed:brushmetal.css')
|
30
|
+
mychart.setmodelgroup(@modgroup)
|
31
|
+
mychart.render('/tmp/embed_style.svg')
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gerbilcharts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vivek Rajagopalan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-03 00:00:00 +05:30
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -117,6 +117,7 @@ files:
|
|
117
117
|
- lib/gerbilcharts/svgdc/svg_rect.rb
|
118
118
|
- lib/gerbilcharts/svgdc/svg_text.rb
|
119
119
|
- lib/gerbilcharts/svgdc/svg_arc.rb
|
120
|
+
- lib/gerbilcharts/svgdc/css_inliner.rb
|
120
121
|
has_rdoc: true
|
121
122
|
homepage: http://gerbilcharts.rubyforge.org
|
122
123
|
licenses: []
|
@@ -149,6 +150,7 @@ signing_key:
|
|
149
150
|
specification_version: 3
|
150
151
|
summary: SVG based charting library for timeseries data
|
151
152
|
test_files:
|
153
|
+
- test/test_embed_styles.rb
|
152
154
|
- test/test_gerbilcharts.rb
|
153
155
|
- test/test_ranges.rb
|
154
156
|
- test/test_helper.rb
|