gerbilcharts 0.2.8 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- ypos=0
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
- rx = parent.modelgroup.effective_round_range_x
16
- rx.each_label do |val,label|
17
- xp = scale_x val,rx
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
- # make sure edge ones are visible
20
- if (xp>=@bounds.right-10)
25
+ # make sure edge ones are visible
26
+ if (xp>=@bounds.right-10)
21
27
  xp = @bounds.right-10
22
- end
28
+ end
23
29
 
24
- g.textout(xp, @bounds.top+10, label, {:class => "axislabel", "text-anchor" => "middle"})
25
- g.line(xp,@bounds.top-2,xp,@bounds.top+3, {:class => "axistickmajor"})
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
- rx = parent.modelgroup.effective_round_range_x
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
- raise "Time Tracker expects X-Axis to be a time interval " unless rx.rmin.is_a? Time
54
-
55
+ raise "Time Tracker expects X-Axis to be a time interval " unless rx.rmin.is_a? Time
55
56
 
56
- xfrag.g(:id=>"gtrackerdata", :visibility=>'hidden',
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=>"1",
60
- :gerb_selsecs=>"1")
61
+ :gerb_selts=>1,
62
+ :gerb_selsecs=>1)
61
63
 
62
64
  end
63
65
 
@@ -21,3 +21,4 @@ require 'gerbilcharts/svgdc/svg_polyline'
21
21
  require 'gerbilcharts/svgdc/svg_rect'
22
22
  require 'gerbilcharts/svgdc/svg_text'
23
23
  require 'gerbilcharts/svgdc/svg_arc'
24
+ require 'gerbilcharts/svgdc/css_inliner'
@@ -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
- @ref_styles ||= []
58
- @ref_styles << cssfile
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
@@ -2,7 +2,7 @@ module GerbilCharts
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 8
5
+ TINY = 10
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -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.8
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-10-30 00:00:00 +05:30
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