gerbilcharts 0.0.3
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 +11 -0
- data/License.txt +21 -0
- data/Manifest.txt +75 -0
- data/PostInstall.txt +7 -0
- data/README.txt +174 -0
- data/Rakefile +4 -0
- data/lib/gerbilcharts.rb +18 -0
- data/lib/gerbilcharts/charts.rb +16 -0
- data/lib/gerbilcharts/charts/area_chart.rb +36 -0
- data/lib/gerbilcharts/charts/bar_chart.rb +33 -0
- data/lib/gerbilcharts/charts/bar_chart_compact.rb +26 -0
- data/lib/gerbilcharts/charts/chart_base.rb +123 -0
- data/lib/gerbilcharts/charts/impulse_chart.rb +30 -0
- data/lib/gerbilcharts/charts/line_chart.rb +35 -0
- data/lib/gerbilcharts/charts/stacked_area_chart.rb +31 -0
- data/lib/gerbilcharts/models.rb +19 -0
- data/lib/gerbilcharts/models/bucketized_timeseries_graph_model.rb +138 -0
- data/lib/gerbilcharts/models/discrete_time_range.rb +63 -0
- data/lib/gerbilcharts/models/graph_model.rb +89 -0
- data/lib/gerbilcharts/models/graph_model_group.rb +240 -0
- data/lib/gerbilcharts/models/monotonous_graph_model.rb +192 -0
- data/lib/gerbilcharts/models/presets.rb +94 -0
- data/lib/gerbilcharts/models/raw_range.rb +68 -0
- data/lib/gerbilcharts/models/round_range.rb +104 -0
- data/lib/gerbilcharts/models/round_time_range.rb +105 -0
- data/lib/gerbilcharts/models/sampled_timeseries_graph_model.rb +80 -0
- data/lib/gerbilcharts/models/simple_timeseries_model_group.rb +68 -0
- data/lib/gerbilcharts/models/time_series_graph_model.rb +34 -0
- data/lib/gerbilcharts/public/brushmetal.css +197 -0
- data/lib/gerbilcharts/public/gerbil.js +327 -0
- data/lib/gerbilcharts/surfaces.rb +32 -0
- data/lib/gerbilcharts/surfaces/area_surface.rb +46 -0
- data/lib/gerbilcharts/surfaces/axis.rb +31 -0
- data/lib/gerbilcharts/surfaces/bar_surface.rb +62 -0
- data/lib/gerbilcharts/surfaces/basic_grid.rb +17 -0
- data/lib/gerbilcharts/surfaces/chart.rb +132 -0
- data/lib/gerbilcharts/surfaces/graph_element.rb +170 -0
- data/lib/gerbilcharts/surfaces/grid.rb +38 -0
- data/lib/gerbilcharts/surfaces/horizontal_axis.rb +32 -0
- data/lib/gerbilcharts/surfaces/horizontal_name_axis.rb +28 -0
- data/lib/gerbilcharts/surfaces/horizontal_time_axis.rb +25 -0
- data/lib/gerbilcharts/surfaces/impulse_surface.rb +47 -0
- data/lib/gerbilcharts/surfaces/legend.rb +59 -0
- data/lib/gerbilcharts/surfaces/line_surface.rb +53 -0
- data/lib/gerbilcharts/surfaces/mark_band.rb +17 -0
- data/lib/gerbilcharts/surfaces/panel.rb +17 -0
- data/lib/gerbilcharts/surfaces/pie_surface.rb +16 -0
- data/lib/gerbilcharts/surfaces/rect.rb +86 -0
- data/lib/gerbilcharts/surfaces/stacked_area_surface.rb +66 -0
- data/lib/gerbilcharts/surfaces/stacked_grid.rb +15 -0
- data/lib/gerbilcharts/surfaces/surface.rb +20 -0
- data/lib/gerbilcharts/surfaces/surface_background.rb +13 -0
- data/lib/gerbilcharts/surfaces/title_panel.rb +44 -0
- data/lib/gerbilcharts/surfaces/tracker.rb +62 -0
- data/lib/gerbilcharts/surfaces/vertical_axis.rb +46 -0
- data/lib/gerbilcharts/svgdc.rb +22 -0
- data/lib/gerbilcharts/svgdc/filters.rb +40 -0
- data/lib/gerbilcharts/svgdc/presentation_attributes.rb +50 -0
- data/lib/gerbilcharts/svgdc/svg_circle.rb +22 -0
- data/lib/gerbilcharts/svgdc/svg_custom_win.rb +36 -0
- data/lib/gerbilcharts/svgdc/svg_element.rb +87 -0
- data/lib/gerbilcharts/svgdc/svg_line.rb +26 -0
- data/lib/gerbilcharts/svgdc/svg_polygon.rb +34 -0
- data/lib/gerbilcharts/svgdc/svg_polyline.rb +27 -0
- data/lib/gerbilcharts/svgdc/svg_rect.rb +29 -0
- data/lib/gerbilcharts/svgdc/svg_shape.rb +10 -0
- data/lib/gerbilcharts/svgdc/svg_text.rb +21 -0
- data/lib/gerbilcharts/svgdc/svg_win.rb +52 -0
- data/lib/gerbilcharts/svgdc/svgdc.rb +335 -0
- data/lib/gerbilcharts/svgdc/transformations.rb +66 -0
- data/lib/gerbilcharts/version.rb +9 -0
- data/setup.rb +1585 -0
- data/test/test_Scratch.rb +21 -0
- data/test/test_charts.rb +119 -0
- data/test/test_gerbilcharts.rb +11 -0
- data/test/test_helper.rb +2 -0
- data/test/test_models.rb +118 -0
- data/test/test_noob.rb +81 -0
- data/test/test_ranges.rb +135 -0
- data/test/test_svgdc.rb +221 -0
- data/test/trafgen.rb +25 -0
- metadata +156 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
module GerbilCharts::Surfaces
|
2
|
+
|
3
|
+
|
4
|
+
# = Tracker (allows mouse selection of timearea)
|
5
|
+
# This sets up the hooks to interact with the gerbil.js Javascript file
|
6
|
+
#
|
7
|
+
class Tracker < GraphElement
|
8
|
+
|
9
|
+
|
10
|
+
def initialize(opts={})
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def int_render(dc)
|
15
|
+
|
16
|
+
dc.addshape(SVGCustomWin.new("GerbilTracker",self))
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
# render the elements directly
|
21
|
+
def render_direct(xfrag)
|
22
|
+
|
23
|
+
# calculate scaling factors
|
24
|
+
rx = parent.modelgroup.effective_round_range_x
|
25
|
+
|
26
|
+
# output the SVG fragment directly
|
27
|
+
xfrag.g(:id => 'gtrackerpanel') {
|
28
|
+
xfrag.rect(:id=>"trackerpanel", :class=>"trackerpanel",
|
29
|
+
:height=>@bounds.height, :width=>@bounds.width, :x=>@bounds.left, :y=>@bounds.top,
|
30
|
+
:onmousedown=>"TrackerMouseDown(evt)",
|
31
|
+
:onmousemove=>"TrackerMouseMove(evt)",
|
32
|
+
:onmouseup=>"TrackerMouseUp(evt)")
|
33
|
+
}
|
34
|
+
|
35
|
+
xfrag.g(:id=> 'gtrackerrect', :visibility=>'hidden') {
|
36
|
+
xfrag.rect(:id=>"trackerrect", :class=>"trackerrect",
|
37
|
+
:height=>parent.anchor.bounds.height, :width=>30, :x=>100, :y=>parent.anchor.bounds.top)
|
38
|
+
}
|
39
|
+
|
40
|
+
ty = parent.anchor.bounds.height/2
|
41
|
+
xfrag.g(:id=> 'gtrackertext', :visibility=>'hidden', :transform => "translate(200 50)") {
|
42
|
+
xfrag.text( :class => 'trackertextinterval', :id=>'trackertextbox', "text-anchor" => 'middle' ) {
|
43
|
+
xfrag.tspan( :id => 'trackertextinterval', :x=>0, :y=>ty) {
|
44
|
+
"15 Minutes"
|
45
|
+
}
|
46
|
+
xfrag.tspan( :class => 'trackertextfromts', :id => 'trackertextfromts', :x=>0, :dy=>15) {
|
47
|
+
"Starting: Apr 2 1973, 05:00:00 PM"
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
xfrag.g(:id=>"gtrackerdata",
|
53
|
+
:gerb_fromts=>rx.rmin,
|
54
|
+
:gerb_scale =>(rx.delta)/parent.anchor.bounds.width,
|
55
|
+
:gerb_selts=>"1",
|
56
|
+
:gerb_selsecs=>"1")
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module GerbilCharts::Surfaces
|
2
|
+
|
3
|
+
# =VerticalAxis
|
4
|
+
# Mostly contains rounded Y-values
|
5
|
+
#
|
6
|
+
class VerticalAxis < Axis
|
7
|
+
|
8
|
+
attr_reader :use_cumulative_y # use the cumulative (sum of all models) range
|
9
|
+
|
10
|
+
def initialize(opts={})
|
11
|
+
@class = "vaxis"
|
12
|
+
super(opts)
|
13
|
+
|
14
|
+
@use_cumulative_y = false
|
15
|
+
@use_cumulative_y = opts[:cumulative] if opts[:cumulative]
|
16
|
+
end
|
17
|
+
|
18
|
+
def int_render(g)
|
19
|
+
|
20
|
+
g.rectangle_r(@bounds, {:class => @class})
|
21
|
+
|
22
|
+
return if parent.modelgroup.empty?
|
23
|
+
|
24
|
+
if @use_cumulative_y
|
25
|
+
ry = parent.modelgroup.cumulative_sweep_round_range_y0
|
26
|
+
else
|
27
|
+
ry = parent.modelgroup.effective_round_range_y0
|
28
|
+
end
|
29
|
+
|
30
|
+
ry.each_label do |val,label|
|
31
|
+
yp = scale_y val,ry
|
32
|
+
yp_label=yp
|
33
|
+
|
34
|
+
# make sure the edge ones are visible
|
35
|
+
yp_label = max(yp_label,@bounds.top+10)
|
36
|
+
|
37
|
+
g.textout(@bounds.right-4, yp_label, label, {:class => "axislabel", "text-anchor" => "end"})
|
38
|
+
g.line(@bounds.right-3,yp,@bounds.right+2,yp, {:class => "axistickmajor"})
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# == GerbilCharts svg helper library
|
2
|
+
#
|
3
|
+
# Various helpers that make it easy to work with SVG
|
4
|
+
#
|
5
|
+
|
6
|
+
|
7
|
+
module GerbilCharts::SVGDC;end;
|
8
|
+
|
9
|
+
require 'gerbilcharts/svgdc/svgdc'
|
10
|
+
require 'gerbilcharts/svgdc/svg_element'
|
11
|
+
require 'gerbilcharts/svgdc/filters'
|
12
|
+
require 'gerbilcharts/svgdc/transformations'
|
13
|
+
require 'gerbilcharts/svgdc/presentation_attributes'
|
14
|
+
require 'gerbilcharts/svgdc/svg_win'
|
15
|
+
require 'gerbilcharts/svgdc/svg_custom_win'
|
16
|
+
require 'gerbilcharts/svgdc/svg_shape'
|
17
|
+
require 'gerbilcharts/svgdc/svg_circle'
|
18
|
+
require 'gerbilcharts/svgdc/svg_line'
|
19
|
+
require 'gerbilcharts/svgdc/svg_polygon'
|
20
|
+
require 'gerbilcharts/svgdc/svg_polyline'
|
21
|
+
require 'gerbilcharts/svgdc/svg_rect'
|
22
|
+
require 'gerbilcharts/svgdc/svg_text'
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module GerbilCharts::SVGDC
|
2
|
+
|
3
|
+
|
4
|
+
# =Filters
|
5
|
+
# Various SVG filters (eg, gradients, light). You can attach
|
6
|
+
# this to any SVG element
|
7
|
+
#
|
8
|
+
class Filter
|
9
|
+
|
10
|
+
attr_reader :filterid
|
11
|
+
|
12
|
+
def initialize(id,opts={})
|
13
|
+
@filterid=id
|
14
|
+
end
|
15
|
+
|
16
|
+
def render(xfrag)
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
# == LinearGraidentVertical
|
23
|
+
# A preset filter
|
24
|
+
class LinearGradientVertical < Filter
|
25
|
+
def initialize(id,fromclr, toclr, opts={})
|
26
|
+
super(id,opts)
|
27
|
+
@from_color=fromclr
|
28
|
+
@to_color=toclr
|
29
|
+
end
|
30
|
+
|
31
|
+
def render(xfrag)
|
32
|
+
xfrag.linearGradient(:id => @filterid, :x1=>"0%", :y1=>"0%",:x2=>"0%",:y2=>"100%") {
|
33
|
+
xfrag.stop(:offset=>"0%", :style=>"stop-color:#{@from_color}")
|
34
|
+
xfrag.stop(:offset=>"100%", :style=>"stop-color:#{@to_color}")
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module GerbilCharts::SVGDC
|
2
|
+
|
3
|
+
# = PresentationAttribute
|
4
|
+
# Wrappers around some simple attributes like Pen and Brush
|
5
|
+
# For more complex ones, you can just attach the SVG definition to the object you are drawing
|
6
|
+
#
|
7
|
+
class PresentationAttribute
|
8
|
+
|
9
|
+
attr_reader :color
|
10
|
+
|
11
|
+
def initialize(opt)
|
12
|
+
@color=opt[:color] if defined? opt[:color]
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
class PPen < PresentationAttribute
|
19
|
+
|
20
|
+
attr_reader :width
|
21
|
+
|
22
|
+
def initialize(opt={})
|
23
|
+
super opt
|
24
|
+
@width=opt[:width] if defined? opt[:width]
|
25
|
+
end
|
26
|
+
|
27
|
+
def render
|
28
|
+
h={}
|
29
|
+
h.store("stroke", @color) if @color
|
30
|
+
h.store("stroke-width", @width) if @width
|
31
|
+
h
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
class PBrush < PresentationAttribute
|
37
|
+
|
38
|
+
def initialize(opt={})
|
39
|
+
super opt
|
40
|
+
end
|
41
|
+
|
42
|
+
def render
|
43
|
+
h={}
|
44
|
+
h.store("fill", @color) if @color
|
45
|
+
h
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module GerbilCharts::SVGDC
|
2
|
+
|
3
|
+
# = SVGCircle
|
4
|
+
# Draws a circle at x, y, and radius r
|
5
|
+
#
|
6
|
+
class SVGCircle < SVGShape
|
7
|
+
|
8
|
+
attr_accessor :x,:y,:r
|
9
|
+
|
10
|
+
def initialize(x,y,r)
|
11
|
+
@x,@y,@r=x,y,r
|
12
|
+
super()
|
13
|
+
end
|
14
|
+
|
15
|
+
def render(xfrag)
|
16
|
+
h = { :cx => @x, :cy => @y, :r => @r }
|
17
|
+
xfrag.circle(h.merge(render_attributes))
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module GerbilCharts::SVGDC
|
2
|
+
|
3
|
+
# =SVGCustomWin
|
4
|
+
# custom window, the supplier delegate will render the SVG directly using the Builder facilities
|
5
|
+
# use this for complex SVG elements that cant be handled via the current simplistic GDI like operations
|
6
|
+
#
|
7
|
+
class SVGCustomWin < SVGWin
|
8
|
+
|
9
|
+
attr_reader :render_delegate
|
10
|
+
|
11
|
+
def initialize(name,delegate,opts={})
|
12
|
+
@render_delegate=delegate
|
13
|
+
super(name,opts)
|
14
|
+
end
|
15
|
+
|
16
|
+
def <<(p)
|
17
|
+
raise "Cannot add children to a custom SVG Window"
|
18
|
+
end
|
19
|
+
|
20
|
+
def render(xfrag)
|
21
|
+
h= {}
|
22
|
+
if @transforms
|
23
|
+
strt=""
|
24
|
+
@transforms.each do |t|
|
25
|
+
strt << t.render
|
26
|
+
end
|
27
|
+
h.store(:transform, strt)
|
28
|
+
end
|
29
|
+
|
30
|
+
xfrag.g(h.merge(render_attributes)) {
|
31
|
+
@render_delegate.render_direct(xfrag)
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module GerbilCharts::SVGDC
|
2
|
+
|
3
|
+
# = SVGElement
|
4
|
+
# Base class for all SVG shapes.
|
5
|
+
# Contains rendering, and svg presentation handling code
|
6
|
+
# Note : the presentation as passed on as is to the SVG
|
7
|
+
class SVGElement
|
8
|
+
attr_accessor :custom_style
|
9
|
+
attr_reader :presentations
|
10
|
+
attr_reader :href
|
11
|
+
|
12
|
+
|
13
|
+
def initialize()
|
14
|
+
@presentations=Array.new
|
15
|
+
|
16
|
+
# default fill and stroke (you can override it)
|
17
|
+
@custom_attributes||={}
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def has_presentations?
|
22
|
+
defined? @presentations
|
23
|
+
end
|
24
|
+
|
25
|
+
def render_attributes
|
26
|
+
h={}
|
27
|
+
|
28
|
+
if has_presentations?
|
29
|
+
@presentations.each do |p|
|
30
|
+
h.merge!(p.render)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
if @custom_attributes
|
35
|
+
@custom_attributes.each_pair do |k,v|
|
36
|
+
h.store( k, v)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
return h
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_presentation(p)
|
44
|
+
@presentations << p
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_options(opt)
|
48
|
+
@custom_attributes = {} if not defined? @custom_attributes
|
49
|
+
|
50
|
+
opt.each_pair do |k,v|
|
51
|
+
@custom_attributes.store(k,v)
|
52
|
+
end
|
53
|
+
|
54
|
+
# treat the href custom attribute separately
|
55
|
+
if @custom_attributes[:href]
|
56
|
+
@href=@custom_attributes[:href]
|
57
|
+
@custom_attributes.delete(:href)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def set_id(css_id)
|
62
|
+
add_options(:id=> css_id)
|
63
|
+
end
|
64
|
+
|
65
|
+
def set_class(css_class)
|
66
|
+
add_options(:class=> css_class)
|
67
|
+
end
|
68
|
+
|
69
|
+
def set_href(url)
|
70
|
+
@href=url
|
71
|
+
end
|
72
|
+
|
73
|
+
# base render allows for wrapping with a Anchor tag
|
74
|
+
def render_base(xfrag)
|
75
|
+
if @href
|
76
|
+
xfrag.a("xlink:href" => @href, :target => "_top") {
|
77
|
+
yield
|
78
|
+
}
|
79
|
+
else
|
80
|
+
yield
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module GerbilCharts::SVGDC
|
2
|
+
|
3
|
+
# = SVGLine
|
4
|
+
# A simple svg line that honors the rendering attributes
|
5
|
+
#
|
6
|
+
# See tests for examples
|
7
|
+
#
|
8
|
+
class SVGLine < SVGShape
|
9
|
+
|
10
|
+
attr_reader :x1, :y1, :x2, :y2
|
11
|
+
|
12
|
+
def initialize(x1,y1,x2,y2)
|
13
|
+
super()
|
14
|
+
@x1,@y1,@x2,@y2=x1,y1,x2,y2
|
15
|
+
end
|
16
|
+
|
17
|
+
def render(xfrag)
|
18
|
+
fmt="%.2f"
|
19
|
+
h= { :x1 => fmt%@x1, :y1 => fmt%@y1, :x2 => fmt%@x2, :y2 => fmt%@y2 }
|
20
|
+
xfrag.line( h.merge(render_attributes))
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module GerbilCharts::SVGDC
|
2
|
+
|
3
|
+
# = SVGPolygon
|
4
|
+
#
|
5
|
+
# A polygon identified by the operstring. Sorry this is not the best way to do it
|
6
|
+
# The oper string consists of M x y L x y style commands. See SVG spec.
|
7
|
+
# todo : accept an array of coords and automatically construct the oper string
|
8
|
+
#
|
9
|
+
class SVGPolygon < SVGShape
|
10
|
+
|
11
|
+
attr_reader :operstring
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@operstring = ""
|
15
|
+
end
|
16
|
+
|
17
|
+
def addpoint(x,y)
|
18
|
+
# truncate to 2 significant places (cuts down SVG size)
|
19
|
+
xf,yf = "%.2f"%x, "%.2f"%y
|
20
|
+
@operstring << "#{xf},#{yf} "
|
21
|
+
end
|
22
|
+
|
23
|
+
def render(xfrag)
|
24
|
+
h= {:points => @operstring }
|
25
|
+
xfrag.polygon( h.merge(render_attributes))
|
26
|
+
end
|
27
|
+
|
28
|
+
def isempty?
|
29
|
+
return @operstring.length==0
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module GerbilCharts::SVGDC
|
2
|
+
|
3
|
+
# = SVGPolyLine
|
4
|
+
# A polyline, like the polygon class
|
5
|
+
#
|
6
|
+
# Send this a series of lineto messages
|
7
|
+
#
|
8
|
+
class SVGPolyline < SVGShape
|
9
|
+
|
10
|
+
attr_reader :operstring
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@operstring = ""
|
14
|
+
end
|
15
|
+
|
16
|
+
def lineto(x,y)
|
17
|
+
@operstring << "#{x},#{y} "
|
18
|
+
end
|
19
|
+
|
20
|
+
def render(xfrag)
|
21
|
+
h= {:points => @operstring }
|
22
|
+
xfrag.polyline( h.merge(render_attributes))
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|