gerbilcharts 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/History.txt +8 -0
  2. data/Manifest.txt +2 -0
  3. data/lib/gerbilcharts/charts/area_chart.rb +1 -1
  4. data/lib/gerbilcharts/charts/bar_chart.rb +18 -1
  5. data/lib/gerbilcharts/charts/chart_base.rb +4 -0
  6. data/lib/gerbilcharts/charts/impulse_chart.rb +1 -1
  7. data/lib/gerbilcharts/charts/line_chart.rb +1 -2
  8. data/lib/gerbilcharts/charts/square_line_chart.rb +38 -0
  9. data/lib/gerbilcharts/charts/stacked_area_chart.rb +1 -1
  10. data/lib/gerbilcharts/charts.rb +1 -0
  11. data/lib/gerbilcharts/models/graph_model.rb +1 -1
  12. data/lib/gerbilcharts/models/monotonous_graph_model.rb +5 -10
  13. data/lib/gerbilcharts/models/round_time_range.rb +40 -7
  14. data/lib/gerbilcharts/public/brushmetal.css +75 -67
  15. data/lib/gerbilcharts/surfaces/axis.rb +0 -2
  16. data/lib/gerbilcharts/surfaces/bar_surface.rb +28 -24
  17. data/lib/gerbilcharts/surfaces/grid.rb +21 -3
  18. data/lib/gerbilcharts/surfaces/horizontal_axis.rb +1 -1
  19. data/lib/gerbilcharts/surfaces/horizontal_name_axis.rb +17 -17
  20. data/lib/gerbilcharts/surfaces/horizontal_time_axis.rb +1 -1
  21. data/lib/gerbilcharts/surfaces/legend.rb +9 -4
  22. data/lib/gerbilcharts/surfaces/pie_surface.rb +2 -2
  23. data/lib/gerbilcharts/surfaces/square_line_surface.rb +60 -0
  24. data/lib/gerbilcharts/surfaces/stacked_area_surface.rb +7 -8
  25. data/lib/gerbilcharts/surfaces.rb +1 -0
  26. data/lib/gerbilcharts/svgdc/svg_polyline.rb +2 -1
  27. data/lib/gerbilcharts/version.rb +1 -1
  28. data/test/test_bar.rb +6 -4
  29. data/test/test_charts.rb +4 -1
  30. data/test/test_lines.rb +100 -0
  31. data/test/test_pie.rb +2 -2
  32. metadata +5 -2
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.2.3 2009-10-19
2
+ * Changes
3
+ * New Squarized Line Surface
4
+ * Sophisticated grid works well with time axis
5
+ * Legend panel autosizing
6
+ * Bar chart labels now stagger automatically depending on chart size
7
+ * Fixed line chart problem due to a bad CSS
8
+
1
9
  == 0.2.2 2009-09-21
2
10
  * Changes
3
11
  * SVG filters specular lighting effect
data/Manifest.txt CHANGED
@@ -55,6 +55,7 @@ lib/gerbilcharts/surfaces/title_panel.rb
55
55
  lib/gerbilcharts/surfaces/tracker.rb
56
56
  lib/gerbilcharts/surfaces/vertical_axis.rb
57
57
  lib/gerbilcharts/surfaces/pie_surface.rb
58
+ lib/gerbilcharts/surfaces/square_line_surface.rb
58
59
  lib/gerbilcharts/charts/area_chart.rb
59
60
  lib/gerbilcharts/charts/bar_chart_compact.rb
60
61
  lib/gerbilcharts/charts/bar_chart.rb
@@ -63,6 +64,7 @@ lib/gerbilcharts/charts/impulse_chart.rb
63
64
  lib/gerbilcharts/charts/line_chart.rb
64
65
  lib/gerbilcharts/charts/stacked_area_chart.rb
65
66
  lib/gerbilcharts/charts/pie_chart.rb
67
+ lib/gerbilcharts/charts/square_line_chart.rb
66
68
  lib/gerbilcharts/svgdc/svgdc.rb
67
69
  lib/gerbilcharts/svgdc/svg_element.rb
68
70
  lib/gerbilcharts/svgdc/filters.rb
@@ -21,7 +21,7 @@ class AreaChart < ChartBase
21
21
  @thechart.add_child(GerbilCharts::Surfaces::BasicGrid.new(:orient => ORIENT_OVERLAY))
22
22
  @thechart.add_child(GerbilCharts::Surfaces::TitlePanel.new(:orient => ORIENT_OVERLAY, :dim => 30))
23
23
  @thechart.add_child(GerbilCharts::Surfaces::AreaSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
24
- @thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => 100))
24
+ @thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => @legend_width))
25
25
  @thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 ))
26
26
  @thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
27
27
 
@@ -11,9 +11,10 @@ class BarChart < ChartBase
11
11
  def initialize(opt={})
12
12
  super(opt)
13
13
 
14
- @staggerlabels = 2
14
+ @staggerlabels = optimum_stagger(opt[:width])
15
15
  @staggerlabels = opt[:stagger] if opt[:stagger]
16
16
  end
17
+
17
18
 
18
19
  def create_chart_elements
19
20
 
@@ -27,7 +28,23 @@ class BarChart < ChartBase
27
28
  @thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 ))
28
29
  @thechart.add_child(GerbilCharts::Surfaces::HorizontalNameAxis.new(:orient => ORIENT_SOUTH, :dim => (15 * @staggerlabels.to_i), :stagger => @staggerlabels))
29
30
  end
31
+
32
+
33
+ protected
34
+
35
+ # compute the optimum stagger level based on the width of the bar chart so we
36
+ # do not have nasty overlaps atleast when labels are 15 chars wide (eg, big ip address)
37
+ def optimum_stagger(width)
38
+ case width
39
+ when (0..250); return 4
40
+ when (250..350); return 3
41
+ when (350..600); return 2
42
+ else; return 1
43
+ end
44
+ end
45
+
30
46
  end
31
47
 
32
48
 
49
+
33
50
  end
@@ -46,6 +46,7 @@ class ChartBase
46
46
  attr_reader :thechart
47
47
  attr_reader :renderopts
48
48
  attr_reader :feature_timetracker
49
+ attr_reader :legend_width
49
50
 
50
51
  def initialize(opt={})
51
52
 
@@ -59,6 +60,9 @@ class ChartBase
59
60
  # pass on options to chart object
60
61
  @thechart = GerbilCharts::Surfaces::Chart.new(opt)
61
62
  @renderopts = {}
63
+
64
+ # common relative widths
65
+ @legend_width = [opt[:width]/4,100].max
62
66
  end
63
67
 
64
68
  def set_renderoptions=(opts)
@@ -16,7 +16,7 @@ class ImpulseChart < ChartBase
16
16
  @thechart.add_child(GerbilCharts::Surfaces::BasicGrid.new(:orient => ORIENT_OVERLAY))
17
17
  @thechart.add_child(GerbilCharts::Surfaces::TitlePanel.new(:orient => ORIENT_OVERLAY, :dim => 30))
18
18
  @thechart.add_child(GerbilCharts::Surfaces::ImpulseSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
19
- @thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => 100))
19
+ @thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => @legend_width))
20
20
  @thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 ))
21
21
  @thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
22
22
 
@@ -14,7 +14,6 @@ module GerbilCharts::Charts
14
14
  #
15
15
  class LineChart < ChartBase
16
16
 
17
-
18
17
  def initialize(opt={})
19
18
  super(opt)
20
19
  end
@@ -29,7 +28,7 @@ class LineChart < ChartBase
29
28
  @thechart.add_child(GerbilCharts::Surfaces::BasicGrid.new(:orient => ORIENT_OVERLAY))
30
29
  @thechart.add_child(GerbilCharts::Surfaces::TitlePanel.new(:orient => ORIENT_OVERLAY, :dim => 30))
31
30
  @thechart.add_child(GerbilCharts::Surfaces::LineSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
32
- @thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => 100))
31
+ @thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => @legend_width))
33
32
  @thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 ))
34
33
  @thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
35
34
  end
@@ -0,0 +1,38 @@
1
+ module GerbilCharts::Charts
2
+
3
+ # =Square Line Chart
4
+ # Each model is a squarized line.
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 SquareLineChart < ChartBase
16
+
17
+
18
+ def initialize(opt={})
19
+ super(opt)
20
+ end
21
+
22
+ def create_chart_elements
23
+
24
+ # anchor (line surface)
25
+ @thechart.create_filter(GerbilCharts::SVGDC::LinearGradientVertical.new("vertgrad","rgb(255,255,255)","rgb(192,192,192)"))
26
+
27
+ # other elements
28
+ @thechart.add_child(GerbilCharts::Surfaces::SurfaceBackground.new(:orient => ORIENT_OVERLAY))
29
+ @thechart.add_child(GerbilCharts::Surfaces::BasicGrid.new(:orient => ORIENT_OVERLAY))
30
+ @thechart.add_child(GerbilCharts::Surfaces::TitlePanel.new(:orient => ORIENT_OVERLAY, :dim => 30))
31
+ @thechart.add_child(GerbilCharts::Surfaces::SquareLineSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
32
+ @thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => @legend_width))
33
+ @thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 ))
34
+ @thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
35
+ end
36
+ end
37
+
38
+ end
@@ -16,7 +16,7 @@ class StackedAreaChart < ChartBase
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
18
  @thechart.add_child(GerbilCharts::Surfaces::StackedAreaSurface.new(:orient => ORIENT_OVERLAY),:anchor => true)
19
- @thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => 100))
19
+ @thechart.add_child(GerbilCharts::Surfaces::Legend.new(:orient=> ORIENT_OVERLAY, :dim => @legend_width))
20
20
  @thechart.add_child(GerbilCharts::Surfaces::VerticalAxis.new(:orient => ORIENT_WEST, :dim => 40 , :cumulative => true ))
21
21
  @thechart.add_child(GerbilCharts::Surfaces::HorizontalTimeAxis.new(:orient => ORIENT_SOUTH, :dim => 25 ))
22
22
 
@@ -15,3 +15,4 @@ require 'gerbilcharts/charts/impulse_chart'
15
15
  require 'gerbilcharts/charts/line_chart'
16
16
  require 'gerbilcharts/charts/stacked_area_chart'
17
17
  require 'gerbilcharts/charts/pie_chart'
18
+ require 'gerbilcharts/charts/square_line_chart'
@@ -1,6 +1,6 @@
1
1
  module GerbilCharts::Models
2
2
 
3
- # GraphModel - Basic interface to a model in GerbilCharts
3
+ # = GraphModel - Basic interface to a model in GerbilCharts
4
4
  #
5
5
  # You can create your own model as long as all the methods here are implemented
6
6
  # or you can use one of the predefined graph models.
@@ -26,23 +26,18 @@ class MonotonousGraphModel < GraphModel
26
26
  # A new datapoint must have a x_val greater than the previous one
27
27
  def add(x_val,y_val)
28
28
 
29
-
30
29
  if @xarr.length > 0 and @xarr.last > x_val
31
30
  raise "Expecting monotonous series data"
32
31
  end
33
32
 
33
+ # x updates
34
34
  @xrange.update x_val
35
-
36
35
  @xarr << x_val
37
36
 
38
- if @transformer
39
- trval = @transformer.xform(y_val)
40
- @yarr << trval
41
- @yrange.update trval
42
- else
43
- @yarr << y_val
44
- @yrange.update y_val
45
- end
37
+ # y updates
38
+ y_val = @transformer.xform(y_val) if @transformer
39
+ @yarr << y_val
40
+ @yrange.update y_val
46
41
 
47
42
  end
48
43
 
@@ -1,5 +1,9 @@
1
1
  module GerbilCharts::Models
2
2
 
3
+ MINUTE=60
4
+ HOUR=3600
5
+ DAY=86400
6
+
3
7
  #
4
8
  # rounded time range - Rounds the max to a nice preset
5
9
  # This class allows for labels at clean intervals instead of
@@ -47,19 +51,32 @@ class RoundTimeRange < RawRange
47
51
  end
48
52
 
49
53
  # provide ticks (per label interval)
54
+ # note the tpl is not used !
50
55
  def each_tick(tpl)
51
56
  raise "Range not aligned with presets (call round range first)" if not @ldelta
52
-
53
- lint = @lmax/tpl
54
- if @rmin % lint != 0
55
- v = (@rmin+lint) - (@rmin%lint)
57
+
58
+ return if @ldelta == 0
59
+
60
+ subtick_delta = ideal_subtick_interval(@ldelta)
61
+
62
+ if (@rmin.tv_sec % @ldelta) != @gmhalfhour
63
+ ni_sec = (@rmin.tv_sec+@ldelta)/@ldelta
64
+
65
+ # if labeling hours, make sure you account tz weirdness like india GMT +5:30
66
+ if @ldelta >= 3600
67
+ v = Time.at(@ldelta* ni_sec.to_i - @gmhalfhour)
68
+ else
69
+ v = Time.at(@ldelta * ni_sec.to_i)
70
+ end
56
71
  else
57
72
  v = @rmin
58
73
  end
59
- while (v<@rmax) do
60
- yield v
61
- v = v+lint
74
+
75
+ while (v<=@rmax) do
76
+ yield v
77
+ v = v+subtick_delta
62
78
  end
79
+
63
80
  end
64
81
 
65
82
  # format min value completely
@@ -99,6 +116,22 @@ private
99
116
  return last_pre,last_lab
100
117
  end
101
118
 
119
+ # ideal subticks
120
+ # You dont want to do a fixed subdivision of a time interval will be ugly
121
+ # Eg. 10x of 2 hours will be 12 min ticks = FAIL
122
+ def ideal_subtick_interval(label_interval)
123
+
124
+ case ldelta
125
+ when (0..1*MINUTE); return 10
126
+ when (1*MINUTE..2*HOUR); return 15*MINUTE
127
+ when (2*HOUR..6*HOUR); return 30*MINUTE
128
+ when (6*HOUR..12*HOUR); return 1*HOUR
129
+ when (12*HOUR..1*DAY); return 3*HOUR
130
+ else; return 1*DAY
131
+ end
132
+ end
133
+
134
+
102
135
 
103
136
  end
104
137
 
@@ -1,84 +1,90 @@
1
1
  .surfacepanel
2
2
  {
3
3
  fill: none;
4
- stroke-width: 1;
5
- stroke: black;
4
+ stroke-width: 1;
5
+ stroke: black;
6
6
  }
7
7
  .gridlineh
8
- {
9
- stroke-width: 1;
10
- stroke: lightgray;
8
+ {
9
+ stroke-width: 1;
10
+ stroke: lightgray;
11
11
  }
12
12
  .gridlinev
13
13
  {
14
- stroke-width: 1;
15
- stroke: lightgray;
14
+ stroke-width: 1;
15
+ stroke: lightgray;
16
+ }
17
+ .gridlinesub
18
+ {
19
+ stroke-width: 0.4;
20
+ stroke: lightgray;
16
21
  }
17
22
  .surfaceback
18
23
  {
19
- fill: url(#vertgrad);
24
+ fill: url(#vertgrad);
20
25
  }
21
26
  .axispanel
22
27
  {
23
- fill: lightgray;
28
+ fill: lightgray;
24
29
  }
25
30
  .axistickmajor
26
31
  {
27
- stroke-width: 2;
28
- stroke: black;
32
+ stroke-width: 2;
33
+ stroke: black;
29
34
  }
30
35
  .axistickminor
31
36
  {
32
- stroke-width: 1;
33
- stroke: black;
37
+ stroke-width: 1;
38
+ stroke: black;
34
39
  }
35
40
  .panel
36
41
  {
37
- fill: white;
42
+ fill: white;
38
43
  }
44
+
39
45
  .legend
40
46
  {
41
- fill: red;
47
+ fill: red;
42
48
  }
43
49
  #item0
44
50
  {
45
- stroke: none;
46
- fill: #00FF00;
51
+ stroke: none;
52
+ fill: #1F75FE;
47
53
  }
48
54
  #item1
49
55
  {
50
- stroke: none;
51
- fill: red;
56
+ stroke: none;
57
+ fill: #B87333;
52
58
  }
53
59
  #item2
54
60
  {
55
- stroke: none;
56
- fill: gold;
61
+ stroke: none;
62
+ fill: gold;
57
63
  }
58
64
  #item3
59
65
  {
60
- stroke: none;
61
- fill: magenta;
66
+ stroke: none;
67
+ fill: magenta;
62
68
  }
63
69
  #item4
64
70
  {
65
- stroke: none;
66
- fill: olive;
71
+ stroke: none;
72
+ fill: olive;
67
73
  }
68
74
  #item5
69
75
  {
70
- stroke: none;
71
- fill: #F88017;
76
+ stroke: none;
77
+ fill: green;
72
78
  }
73
79
  #item6
74
80
  {
75
- stroke: none;
76
- fill: #1F75FE;
81
+ stroke: none;
82
+ fill: red;
77
83
  }
78
84
  #item7
79
85
  {
80
- stroke: none;
81
- fill: #B87333;
86
+ stroke: none;
87
+ fill: #F88017;
82
88
  }
83
89
  #item8
84
90
  {
@@ -97,37 +103,37 @@
97
103
  }
98
104
  #lineitem0
99
105
  {
100
- stroke: none;
106
+ stroke: #1F75FE;
101
107
  stroke-width: 2;
102
108
  }
103
109
  #lineitem1
104
110
  {
105
- stroke: none;
111
+ stroke: #B87333;
106
112
  stroke-width: 2;
107
113
  }
108
114
  #lineitem2
109
115
  {
110
- stroke: none;
116
+ stroke: gold;
111
117
  stroke-width: 2;
112
118
  }
113
119
  #lineitem3
114
120
  {
115
- stroke: none;
121
+ stroke: magenta;
116
122
  stroke-width: 2;
117
123
  }
118
124
  #lineitem4
119
125
  {
120
- stroke: none;
126
+ stroke: olive;
121
127
  stroke-width: 2;
122
128
  }
123
129
  #lineitem5
124
130
  {
125
- stroke: none;
131
+ stroke: green;
126
132
  stroke-width: 2;
127
133
  }
128
134
  #lineitem6
129
135
  {
130
- stroke: none;
136
+ stroke: red;
131
137
  stroke-width: 2;
132
138
  }
133
139
  #lineitem7
@@ -142,57 +148,58 @@
142
148
  }
143
149
  .axislabel
144
150
  {
145
- font-family: sans;
146
- font-size: 10px;
147
- fill: black;
148
- stroke: none;
151
+ font-family: sans;
152
+ font-size: 10px;
153
+ fill: black;
154
+ stroke: none;
149
155
  }
150
156
 
151
157
  .axislabelt0
152
158
  {
153
- font-family: sans;
154
- font-size: 8px;
155
- fill: black;
156
- stroke: none;
159
+ font-family: sans;
160
+ font-size: 8px;
161
+ fill: black;
162
+ stroke: none;
157
163
  }
158
164
  .titletext
159
165
  {
160
- fill: gray;
161
- stroke: none;
162
- font-family: Arial, Helvetica, sans-serif;;
163
- font-size: 24px;
164
- font-weight: bold;
166
+ fill: gray;
167
+ stroke: none;
168
+ font-family: Arial, Helvetica, sans-serif;;
169
+ font-size: 24px;
170
+ font-weight: bold;
165
171
  }
166
172
  .titlepanel
167
173
  {
168
- fill: white;
169
- fill-opacity: 0.5;
174
+ fill: white;
175
+ fill-opacity: 0.5;
170
176
  }
171
177
  .legendpanel
172
178
  {
173
- fill: white;
174
- fill-opacity: 0.5;
179
+ fill: white;
180
+ fill-opacity: 0.5;
175
181
  }
182
+
176
183
  .legendtext
177
184
  {
178
- font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
179
- font-size: 10px;
180
- fill: black;
181
- stroke: none;
185
+ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
186
+ font-size: 10px;
187
+ fill: black;
188
+ stroke: none;
182
189
  }
183
190
  .elementlabel
184
191
  {
185
- font-family: sans;
186
- font-size: 10px;
187
- fill: black;
188
- stroke: none;
192
+ font-family: sans;
193
+ font-size: 10px;
194
+ fill: black;
195
+ stroke: none;
189
196
  }
190
197
  .elementvalue
191
198
  {
192
- font-family: sans;
193
- font-size: 8px;
194
- fill: black;
195
- stroke: none;
199
+ font-family: sans;
200
+ font-size: 8px;
201
+ fill: black;
202
+ stroke: none;
196
203
  }
197
204
  .trackerpanel
198
205
  {
@@ -209,6 +216,7 @@
209
216
  font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
210
217
  font-size: 14px;
211
218
  }
219
+ 209,1 97%
212
220
  .trackertextfromts
213
221
  {
214
222
  font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
@@ -16,13 +16,11 @@ class Axis < GraphElement
16
16
  @stagger_levels=1
17
17
  end
18
18
 
19
-
20
19
  def int_render(g)
21
20
  g.rectangle_r(@bounds, {:class => @class})
22
21
  end
23
22
 
24
23
  def get_stagger_off(level, offset)
25
- #p "stager levles = #{@stagger_levels}"
26
24
  return (level % @stagger_levels) * offset
27
25
  end
28
26
 
@@ -3,15 +3,18 @@ module GerbilCharts::Surfaces
3
3
  # = Bar Surface
4
4
  # Draws latest values from models in a bar chart
5
5
  #
6
+ # Options
7
+ # element_width : optimum width of bars
8
+ # element_spacing : optimum spacing of bars
6
9
  class BarSurface < Surface
7
10
 
8
11
  attr_reader :element_width # optimum width of bar
9
- attr_reader :element_spacing # optimum spacing between bars
12
+ attr_reader :element_spacing # optimum spacing between bars
10
13
 
11
14
  def initialize(opts={})
12
15
  super(opts)
13
- @element_width = 20
14
- @element_spacing = 25
16
+ @element_width = opts[:element_width]||20
17
+ @element_spacing = opts[:element_spacing]|| 25
15
18
  end
16
19
 
17
20
  def int_render(g)
@@ -24,11 +27,13 @@ class BarSurface < Surface
24
27
 
25
28
  # see if the element spacing or width need to be adjusted to fit
26
29
  nmodels = parent.modelgroup.count
27
- delta = @bounds.width - (nmodels * (@element_width + @element_spacing) + @element_spacing)
28
- if delta < 0
29
- delta_per_item = delta/(nmodels+2)
30
- @element_width += delta_per_item
31
- @element_spacing = 2 * @element_width
30
+ extra_space = @bounds.width - (nmodels * (@element_width + @element_spacing) + @element_spacing)
31
+ if extra_space < 0
32
+ delta_per_item = extra_space/(2*nmodels)
33
+ @element_width += delta_per_item
34
+ @element_spacing += delta_per_item
35
+ else
36
+ @element_spacing += extra_space /(nmodels)
32
37
  end
33
38
 
34
39
  # atleast one model is present, chhug along
@@ -38,24 +43,23 @@ class BarSurface < Surface
38
43
 
39
44
  xpos = @bounds.left + @element_spacing
40
45
  parent.modelgroup.each_model_with_index do | mod, i|
41
- y=mod.latest_val
42
- ypos = scale_y y,ry
46
+ y=mod.latest_val
47
+ ypos = scale_y y,ry
43
48
 
44
- # Adding tool tips to the rectangle
45
- opts = {:id => "item#{i}"}
46
- if parent.get_global_option(:auto_tooltips,false)
47
- opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
48
- opts.store(:gerbiltooltip1, mod.name)
49
- opts.store(:gerbiltooltip2, "Val = #{mod.latest_val}")
50
- end
49
+ # Adding tool tips to the rectangle
50
+ opts = {:id => "item#{i}"}
51
+ if parent.get_global_option(:auto_tooltips,false)
52
+ opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
53
+ opts.store(:gerbiltooltip1, mod.name)
54
+ opts.store(:gerbiltooltip2, "Val = #{mod.latest_val}")
55
+ end
51
56
 
52
- # draw the abr
53
- g.rectangle(xpos, ypos, @element_width, @bounds.bottom - ypos, opts)
54
- g.textout( xpos+@element_width/2, ypos-5,
55
- mod.latest_formatted_val,
56
- {:class => "elementlabel", "text-anchor" => "middle"}
57
- )
58
- xpos += @element_spacing + @element_width
57
+ # draw the bar
58
+ g.rectangle(xpos, ypos, @element_width, @bounds.bottom - ypos, opts)
59
+ g.textout( xpos+@element_width/2, ypos-5,
60
+ mod.latest_formatted_val,
61
+ {:class => "elementlabel", "text-anchor" => "middle"})
62
+ xpos += @element_spacing + @element_width
59
63
  end
60
64
  end
61
65
  end
@@ -4,24 +4,43 @@ module GerbilCharts::Surfaces
4
4
  # Draws both x and y grids
5
5
  class Grid < GraphElement
6
6
 
7
+ attr_reader :tick_count
8
+
7
9
  def initialize(opts={})
8
10
  super(opts)
11
+ @tick_count = 5
9
12
  end
10
13
 
11
14
  def int_render(g)
12
- return
13
15
 
16
+ # horizontal grid lines
14
17
  ry = grid_range_y
15
18
  ry.each_label do |val,label|
16
19
  yp = scale_y val,ry
17
20
  g.line(@bounds.left,yp,@bounds.right,yp, {:class => "gridlineh"})
18
- end
21
+ end
22
+
23
+ # horiz subticks
24
+ ry = grid_range_y
25
+ ry.each_tick(@tick_count) do |val|
26
+ yp = scale_y val,ry
27
+ g.line(@bounds.left,yp,@bounds.right,yp, {:class => "gridlinesub"})
28
+ end
29
+
30
+
19
31
 
32
+ # vertical subticks
20
33
  rx = grid_range_x
21
34
  rx.each_label do |val,label|
22
35
  xp = scale_x val,rx
23
36
  g.line(xp,@bounds.top,xp,@bounds.bottom, {:class => "gridlinev"})
24
37
  end
38
+
39
+ rx.each_tick(0) do |val|
40
+ xp = scale_x val,rx
41
+ g.line(xp,@bounds.top,xp,@bounds.bottom, {:class => "gridlinesub"})
42
+ end
43
+
25
44
  end
26
45
 
27
46
  protected
@@ -33,7 +52,6 @@ class Grid < GraphElement
33
52
  def grid_range_y
34
53
  return parent.modelgroup.effective_round_range_y0
35
54
  end
36
-
37
55
 
38
56
  end
39
57
 
@@ -21,7 +21,7 @@ class HorizontalAxis < Axis
21
21
  xp = @bounds.right-10
22
22
  end
23
23
 
24
- g.textout(xp, @bounds.top+10, label, {:class => "axislabel"})
24
+ g.textout(xp, @bounds.top+10, label, {:class => "axislabel", "text-anchor" => "middle"})
25
25
  g.line(xp,@bounds.top-2,xp,@bounds.top+3, {:class => "axistickmajor"})
26
26
  end
27
27
 
@@ -11,22 +11,22 @@ class HorizontalNameAxis < Axis
11
11
  end
12
12
 
13
13
  def int_render(g)
14
- super
15
- xp = @bounds.left + parent.anchor.element_spacing + parent.anchor.element_width/2
16
- parent.modelgroup.each_model_with_index do |m,i|
17
- yoff=get_stagger_off(i,10)
18
- #Adding tool tips to the text
19
- opts = { :class => "axislabel"}
20
- if parent.get_global_option(:auto_tooltips,false)
21
- opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
22
- opts.store(:gerbiltooltip1, m.name)
23
- opts.store(:gerbiltooltip2, "Val = #{m.latest_val}")
24
- end
25
- g.textout(xp, @bounds.top+15+yoff, m.name[0..4], opts)
26
- xp += parent.anchor.element_width + parent.anchor.element_spacing
27
- end
28
- end
29
-
30
- end
14
+ super
15
+ xp = @bounds.left + parent.anchor.element_spacing + parent.anchor.element_width/2
16
+ parent.modelgroup.each_model_with_index do |m,i|
17
+ yoff=get_stagger_off(i,10)
18
+
19
+ #Adding tool tips to the text
20
+ opts = { :class => "axislabel","text-anchor"=> "middle" }
21
+ parent.get_global_option(:auto_tooltips,false)
31
22
 
23
+ opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
24
+ opts.store(:gerbiltooltip1, m.name)
25
+ opts.store(:gerbiltooltip2, "Val = #{m.latest_val}")
26
+
27
+ g.textout(xp, @bounds.top+15+yoff, m.name[0..14], opts)
28
+ xp += parent.anchor.element_width + parent.anchor.element_spacing
29
+ end
30
+ end
31
+ end
32
32
  end
@@ -15,7 +15,7 @@ class HorizontalTimeAxis < HorizontalAxis
15
15
 
16
16
  rx = parent.modelgroup.effective_round_range_x
17
17
  sfmt = rx.format_min_value
18
- g.textout(@bounds.left-20, @bounds.top+20, sfmt, {:class => "axislabelt0"})
18
+ g.textout(@bounds.left-20, @bounds.top+20, sfmt, {:class => "axislabelt0" })
19
19
  g.line(@bounds.left,@bounds.top,@bounds.left,@bounds.top+10,{:class => "axistickmajor"})
20
20
 
21
21
  end
@@ -14,7 +14,6 @@ class Legend < GraphElement
14
14
  end
15
15
 
16
16
  def int_render(g)
17
-
18
17
  # count determines the bounds
19
18
  @bounds.bottom = @bounds.top + 15 * parent.modelgroup.count
20
19
  g.rectangle_r(@bounds, {:class => @class})
@@ -27,10 +26,16 @@ class Legend < GraphElement
27
26
  rbox.bottom = rbox.top+10
28
27
 
29
28
  parent.modelgroup.each_model_with_index do | mod, i|
30
-
31
-
29
+
30
+ # Adding tool tips
31
+ opts = { :class => "legendtext" }
32
+ parent.get_global_option(:auto_tooltips,false)
33
+ opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
34
+ opts.store(:gerbiltooltip1, mod.name)
35
+ opts.store(:gerbiltooltip2, "Val = #{mod.latest_val}")
36
+
32
37
  g.rectangle_r(rbox, :id => "item#{i}")
33
- g.textout(rbox.right+5, rbox.bottom-2, mod.name, {:class => "legendtext"})
38
+ g.textout(rbox.right+5, rbox.bottom-2, mod.name,opts)
34
39
 
35
40
  rbox.top += 10 + 5
36
41
  rbox.bottom = rbox.top+10
@@ -59,8 +59,8 @@ class PieSurface < Surface
59
59
  new_pos_y = cy + (Math.sin((Math::PI/180)*tot_angle)*radius)
60
60
  label_pos_x = cx + (Math.cos((Math::PI/180)*half_angle)*radius_label)
61
61
  label_pos_y = cy + (Math.sin((Math::PI/180)*half_angle)*radius_label)
62
-
63
- percent_mod = (mod.latest_val*360/y_total)
62
+
63
+ percent_mod = ((mod.latest_val*360).to_i/y_total.to_i)
64
64
  percent = (percent_mod*100/360)
65
65
  percent_pos_x = cx + ((Math.cos((Math::PI/180)*half_angle)*radius_label)*0.6)
66
66
  percent_pos_y = cy + ((Math.sin((Math::PI/180)*half_angle)*radius_label)*0.6)
@@ -0,0 +1,60 @@
1
+ module GerbilCharts::Surfaces
2
+
3
+ # = Square Line Surface
4
+ # Squarized line surface
5
+ # Control the color,thickness of the line via the stylesheet item lineitem1, lineitem2 etc
6
+ #
7
+ # Supported global options
8
+ #
9
+ # [+circle_data_points+] Draw a solid circle around datapoints
10
+ # [+scaling+] :auto, :auto_y0
11
+ #
12
+ class SquareLineSurface < Surface
13
+ def initialize(opts={})
14
+ super(opts)
15
+ end
16
+
17
+ def int_render(g)
18
+
19
+ range_options_x = parent.get_global_option(:scaling_x,:auto)
20
+ range_options_y = parent.get_global_option(:scaling_y,:auto)
21
+ rx = parent.modelgroup.effective_range_x(range_options_x)
22
+ ry = parent.modelgroup.effective_range_y(range_options_y)
23
+
24
+ # ajax if used
25
+ if parent.usesAjax?
26
+ set_ajaxSurfaceContext(rx.rmax,ry.rmax,"LINE")
27
+ end
28
+
29
+ parent.modelgroup.each_model_with_index do | mod, i|
30
+
31
+ prev_ypos=nil
32
+ mod.each_tuple do |x,y|
33
+
34
+ # the basic line
35
+ xpos = scale_x x,rx
36
+ ypos = scale_y y,ry
37
+
38
+ prev_ypos ||= ypos
39
+ g.lineto xpos,prev_ypos
40
+ g.lineto xpos,ypos
41
+ prev_ypos=ypos
42
+
43
+ # datapoint and a tooltip
44
+ opts = {:id => "item#{i}"}
45
+ if parent.get_global_option(:auto_tooltips,false)
46
+ opts.merge!(:onmouseover => "OpacityDown(evt)", :onmouseout => "OpacityUp(evt)")
47
+ opts.store(:gerbiltooltip1, mod.name)
48
+ opts.store(:gerbiltooltip2, "Val = #{y}")
49
+ end
50
+ g.circle(xpos,ypos,4,opts) if parent.get_global_option(:circle_data_points,false)
51
+ end
52
+ g.endline(:id => "lineitem#{i}")
53
+ end
54
+
55
+ #draw each model in the group
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -9,8 +9,7 @@ class StackedAreaSurface < Surface
9
9
  end
10
10
 
11
11
  def int_render(g)
12
-
13
-
12
+ # debugger
14
13
  rx = parent.modelgroup.effective_round_range_x
15
14
  ry = parent.modelgroup.cumulative_sweep_round_range_y0
16
15
 
@@ -24,6 +23,7 @@ class StackedAreaSurface < Surface
24
23
  sweep_to = rx.rmax
25
24
  polygons = []
26
25
  parent.modelgroup.each_model do | mod|
26
+ # debugger
27
27
  mod.begin_sweep
28
28
  polygons << GerbilCharts::SVGDC::SVGPolygon.new
29
29
  end
@@ -33,11 +33,10 @@ class StackedAreaSurface < Surface
33
33
 
34
34
  # perform the sweep
35
35
  while (sweep_pos<=sweep_to)
36
-
36
+ # debugger
37
37
  acc_y = 0
38
-
39
38
  parent.modelgroup.each_model_with_index do | mod, i|
40
-
39
+ # debugger
41
40
  acc_y += mod.sweep(sweep_pos)
42
41
  xpos = scale_x sweep_pos,rx
43
42
  ypos = scale_y acc_y,ry
@@ -50,12 +49,12 @@ class StackedAreaSurface < Surface
50
49
  end
51
50
 
52
51
  sweep_pos += sweep_interval
53
- end
54
-
52
+ end
53
+ # debugger
55
54
  # layout all polygons in reverse
56
55
  i=polygons.length-1
57
56
  polygons.reverse_each do |p|
58
- g.addshape(p, {:id => "item#{i}"})
57
+ g.addshape(p,{:id => "item#{i}"})
59
58
  i -= 1
60
59
  end
61
60
 
@@ -30,3 +30,4 @@ require 'gerbilcharts/surfaces/pie_surface'
30
30
  require 'gerbilcharts/surfaces/stacked_area_surface'
31
31
  require 'gerbilcharts/surfaces/surface_background'
32
32
  require 'gerbilcharts/surfaces/tracker'
33
+ require 'gerbilcharts/surfaces/square_line_surface'
@@ -14,7 +14,8 @@ class SVGPolyline < SVGShape
14
14
  end
15
15
 
16
16
  def lineto(x,y)
17
- @operstring << "#{x},#{y} "
17
+ fmt="%.2f"
18
+ @operstring << "#{fmt%x},#{fmt%y} "
18
19
  end
19
20
 
20
21
  def render(xfrag)
@@ -2,7 +2,7 @@ module GerbilCharts
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 2
5
+ TINY = 3
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/test/test_bar.rb CHANGED
@@ -18,16 +18,18 @@ class TestBar < Test::Unit::TestCase
18
18
  ["Wasim", 112,22, 45, 70, 218, 145],
19
19
  ["Buzo" , 0, 23, 25, 40, 18, 59],
20
20
  ["Vipin", 145,112, 22, 45, 18, 70],
21
- ["label", 145,112, 22, 45, 18, 240],
21
+ ["covad11.covad.nc.us", 145,112, 22, 45, 18, 240],
22
22
  ["very very very long name 9th item ", 145,112, 22, 45, 18, 45],
23
+ ["192.168.201.200 ", 145,112, 22, 45, 18, 15],
24
+ ["192.168.201.200 ", 145,112, 22, 45, 18, 15],
23
25
  ["Others ", 145,112, 22, 45, 18, 15],
24
26
  ["VIVEK", 145,112, 22, 45, 18, 170]
25
27
  ]
26
28
  )
27
- mychart = GerbilCharts::Charts::BarChart.new( :width => 350, :height => 200,
29
+ mychart = GerbilCharts::Charts::BarChart.new( :width => 550, :height => 200,
28
30
  :style => 'brushmetal.css', :auto_tooltips => true ,
29
- :javascripts => {'javascripts/gerbil.js' => false, 'javascripts/prototype.js' => false}
30
- )
31
+ :javascripts => {'/tmp/gerbil.js' => false, '/tmp/prototype.js' => false}
32
+ )
31
33
  mychart.modelgroup=modelgroup
32
34
  mychart.render('/tmp/bar_monthly_sales.svg')
33
35
  end
data/test/test_charts.rb CHANGED
@@ -109,7 +109,10 @@ class TestCharts < Test::Unit::TestCase
109
109
  # test a area chart
110
110
  def test_stacked_area_1
111
111
 
112
- mychart = GerbilCharts::Charts::StackedAreaChart.new( :width => 350, :height => 200, :style => 'brushmetal.css')
112
+ mychart = GerbilCharts::Charts::StackedAreaChart.new( :width => 350, :height => 200,
113
+ :style => 'brushmetal.css', :auto_tooltips=> true,
114
+ :javascripts => {'/tmp/gerbil.js' => false, '/tmp/prototype.js' => false , '/tmp/scriptaculous.js' => false}
115
+ )
113
116
  mychart.setmodelgroup(@modgroupbucketized)
114
117
  mychart.render('/tmp/c_sachart1.svg')
115
118
 
@@ -0,0 +1,100 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestLines < Test::Unit::TestCase
4
+
5
+ attr_reader :test_vector_tm1
6
+ attr_reader :test_vector_tm2
7
+ attr_reader :mod1, :mod2, :modbucket1
8
+
9
+ def setup
10
+ @test_vector_tm1 = []
11
+ @test_vector_tm2 = []
12
+ @test_vector_tm3 = []
13
+ tbeg = Time.local( 1978, "jun", 5, 9, 10, 0, 0)
14
+ sbeg = tbeg
15
+ sec_inc = 1000
16
+
17
+ for i in (0..20)
18
+ @test_vector_tm1 << [sbeg + i*sec_inc, i*sec_inc*1000 ]
19
+ @test_vector_tm2 << [sbeg + i*sec_inc, i*sec_inc*1200 ]
20
+ @test_vector_tm3 << [sbeg + i*sec_inc, i*sec_inc*1000*rand() ]
21
+ end
22
+
23
+ @mod1 = GerbilCharts::Models::TimeSeriesGraphModel.new("External Gateway")
24
+ @mod1.add_tuples @test_vector_tm1
25
+
26
+ @mod2 = GerbilCharts::Models::TimeSeriesGraphModel.new("209.216.22.220")
27
+ @mod2.add_tuples @test_vector_tm2
28
+
29
+ @mod3 = GerbilCharts::Models::TimeSeriesGraphModel.new("udldev Print Server")
30
+ @mod3.add_tuples @test_vector_tm3
31
+
32
+ @modgroup = GerbilCharts::Models::GraphModelGroup.new("Hosts")
33
+ @modgroup.add(@mod1)
34
+ @modgroup.add(@mod2)
35
+ @modgroup.add(@mod3)
36
+
37
+ setup_bucketized_models()
38
+
39
+ end
40
+
41
+ def setup_bucketized_models
42
+ # bucketized models
43
+ modbucket1 = GerbilCharts::Models::BucketizedTimeSeriesGraphModel.new("Out Bw",60)
44
+ tbeg = Time.local( 1978, "jun", 5, 9, 10, 0, 0)
45
+ sbeg = tbeg
46
+
47
+ #second with some gaps
48
+ sbeg = tbeg
49
+ test_vector_bucket_1 = []
50
+ test_vector_bucket_1 << [sbeg + 60, 1000 ]
51
+ test_vector_bucket_1 << [sbeg + 120, 1000 ]
52
+ test_vector_bucket_1 << [sbeg + 180, 1000 ]
53
+ test_vector_bucket_1 << [sbeg + 239, 1000 ]
54
+ test_vector_bucket_1 << [sbeg + 295, 1000 ]
55
+ test_vector_bucket_1 << [sbeg + 296, 1000 ]
56
+ test_vector_bucket_1 << [sbeg + 297, 5000 ]
57
+ test_vector_bucket_1 << [sbeg + 298, 1000 ]
58
+ test_vector_bucket_1 << [sbeg + 360, 1000 ]
59
+ test_vector_bucket_1 << [sbeg + 420, 1000 ]
60
+ test_vector_bucket_1 << [sbeg + 480, 1000 ]
61
+ test_vector_bucket_1 << [sbeg + 530, 1000 ]
62
+ test_vector_bucket_1 << [sbeg + 604, 1000 ]
63
+ test_vector_bucket_1 << [sbeg + 800, 1000 ]
64
+ modbucket1.add_tuples(test_vector_bucket_1)
65
+
66
+ #second with some gaps
67
+ modbucket2 = GerbilCharts::Models::BucketizedTimeSeriesGraphModel.new("In Bw",60)
68
+ sbeg = tbeg
69
+ test_vector_bucket_2 = []
70
+ test_vector_bucket_2 << [sbeg + 10, 1800 ]
71
+ test_vector_bucket_2 << [sbeg + 20, 2600 ]
72
+ test_vector_bucket_2 << [sbeg + 22, 1000 ]
73
+ test_vector_bucket_2 << [sbeg + 60, 1000 ]
74
+ test_vector_bucket_2 << [sbeg + 120, 1900 ]
75
+ test_vector_bucket_2 << [sbeg + 180, 700 ]
76
+ test_vector_bucket_2 << [sbeg + 240, 5000 ]
77
+ test_vector_bucket_2 << [sbeg + 301, 1000 ]
78
+ test_vector_bucket_2 << [sbeg + 350, 1000 ]
79
+ test_vector_bucket_2 << [sbeg + 420, 100 ]
80
+ test_vector_bucket_2 << [sbeg + 470, 500 ]
81
+ test_vector_bucket_2 << [sbeg + 540, 1000 ]
82
+ modbucket2.add_tuples(test_vector_bucket_2)
83
+
84
+ @modgroupbucketized = GerbilCharts::Models::GraphModelGroup.new("Bandwidth")
85
+ @modgroupbucketized .add(modbucket1)
86
+ @modgroupbucketized .add(modbucket2)
87
+
88
+ end
89
+
90
+
91
+ # test a line chart
92
+ def test_line_1
93
+
94
+ mychart = GerbilCharts::Charts::AreaChart.new( :width => 450, :height => 400, :style => 'brushmetal.css')
95
+ mychart.setmodelgroup(@modgroup)
96
+ mychart.render('/tmp/sq_linechart1.svg')
97
+
98
+ end
99
+
100
+ end
data/test/test_pie.rb CHANGED
@@ -15,7 +15,7 @@ class TestPie < Test::Unit::TestCase
15
15
  :title => "Sales figures",
16
16
  :timeseries => (1..6).collect { |month| Time.local(2008,month) },
17
17
  :models => [ ["Bruce", 1, 10, 18, 28, 80, 134],
18
- ["Rex" , 112,22, 45, 70, 218, 309],
18
+ ["Rex" , 112,22, 45, 70, 218, 309.98],
19
19
  ["Sharmila", 112,22, 45, 70, 218, 245],
20
20
  ["Wasim", 112,22, 45, 70, 218, 145],
21
21
  ["Buzo" , 0, 23, 25, 40, 18, 59],
@@ -33,7 +33,7 @@ class TestPie < Test::Unit::TestCase
33
33
  :filter => 'LikeButton'
34
34
  )
35
35
  mychart.modelgroup=modelgroup
36
- mychart.render('/tmp/pie_monthly_sales_lit.svg')
36
+ mychart.render('/tmp/pie_monthly_sales.svg')
37
37
  end
38
38
 
39
39
 
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.2
4
+ version: 0.2.3
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-09-21 00:00:00 +05:30
12
+ date: 2009-10-19 00:00:00 +05:30
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -92,6 +92,7 @@ files:
92
92
  - lib/gerbilcharts/surfaces/title_panel.rb
93
93
  - lib/gerbilcharts/surfaces/tracker.rb
94
94
  - lib/gerbilcharts/surfaces/vertical_axis.rb
95
+ - lib/gerbilcharts/surfaces/square_line_surface.rb
95
96
  - lib/gerbilcharts/charts/area_chart.rb
96
97
  - lib/gerbilcharts/charts/bar_chart_compact.rb
97
98
  - lib/gerbilcharts/charts/bar_chart.rb
@@ -100,6 +101,7 @@ files:
100
101
  - lib/gerbilcharts/charts/line_chart.rb
101
102
  - lib/gerbilcharts/charts/stacked_area_chart.rb
102
103
  - lib/gerbilcharts/charts/pie_chart.rb
104
+ - lib/gerbilcharts/charts/square_line_chart.rb
103
105
  - lib/gerbilcharts/svgdc/svgdc.rb
104
106
  - lib/gerbilcharts/svgdc/svg_element.rb
105
107
  - lib/gerbilcharts/svgdc/filters.rb
@@ -152,6 +154,7 @@ test_files:
152
154
  - test/test_helper.rb
153
155
  - test/test_svgdc.rb
154
156
  - test/test_noob.rb
157
+ - test/test_lines.rb
155
158
  - test/test_pie.rb
156
159
  - test/test_render_string.rb
157
160
  - test/test_bar.rb