gerbilcharts 0.2.8 → 0.2.10
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/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
|