ziya 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/Manifest.txt +74 -28
  2. data/README.txt +91 -14
  3. data/Rakefile +1 -1
  4. data/bin/ziyafy +2 -0
  5. data/charts/AC_RunActiveContent.js +292 -0
  6. data/charts/charts.swf +0 -0
  7. data/charts/charts_library/ar3d.swf +0 -0
  8. data/charts/charts_library/arno.swf +0 -0
  9. data/charts/charts_library/ars3.swf +0 -0
  10. data/charts/charts_library/arst.swf +0 -0
  11. data/charts/charts_library/brfl.swf +0 -0
  12. data/charts/charts_library/brno.swf +0 -0
  13. data/charts/charts_library/brst.swf +0 -0
  14. data/charts/charts_library/buno.swf +0 -0
  15. data/charts/charts_library/cl3d.swf +0 -0
  16. data/charts/charts_library/clfl.swf +0 -0
  17. data/charts/charts_library/clno.swf +0 -0
  18. data/charts/charts_library/clp3.swf +0 -0
  19. data/charts/charts_library/cls3.swf +0 -0
  20. data/charts/charts_library/clst.swf +0 -0
  21. data/charts/charts_library/cnno.swf +0 -0
  22. data/charts/charts_library/lnno.swf +0 -0
  23. data/charts/charts_library/mxno.swf +0 -0
  24. data/charts/charts_library/pi3d.swf +0 -0
  25. data/charts/charts_library/pino.swf +0 -0
  26. data/charts/charts_library/pono.swf +0 -0
  27. data/charts/charts_library/scno.swf +0 -0
  28. data/charts/full_screen.swf +0 -0
  29. data/charts/sliders/black.swf +0 -0
  30. data/charts/sliders/preview_handle_1.swf +0 -0
  31. data/charts/sliders/preview_handle_2.swf +0 -0
  32. data/fred.rb +36 -0
  33. data/gauges/designs/circle.yml +18 -0
  34. data/gauges/designs/signal.yml +14 -0
  35. data/gauges/designs/thermo.yml +119 -0
  36. data/gauges/designs/title.yml +11 -0
  37. data/gauges/gauge.swf +0 -0
  38. data/lib/ziya.rb +17 -5
  39. data/lib/ziya/charts/area.rb +6 -1
  40. data/lib/ziya/charts/area_threed.rb +16 -0
  41. data/lib/ziya/charts/bar.rb +8 -3
  42. data/lib/ziya/charts/base.rb +210 -153
  43. data/lib/ziya/charts/bubble.rb +18 -0
  44. data/lib/ziya/charts/candle_stick.rb +6 -1
  45. data/lib/ziya/charts/column.rb +7 -2
  46. data/lib/ziya/charts/column_threed.rb +6 -1
  47. data/lib/ziya/charts/floating_bar.rb +6 -1
  48. data/lib/ziya/charts/floating_column.rb +7 -2
  49. data/lib/ziya/charts/line.rb +7 -2
  50. data/lib/ziya/charts/mixed.rb +5 -0
  51. data/lib/ziya/charts/parallel_threed_column.rb +6 -1
  52. data/lib/ziya/charts/pie.rb +7 -2
  53. data/lib/ziya/charts/pie_threed.rb +7 -2
  54. data/lib/ziya/charts/polar.rb +6 -1
  55. data/lib/ziya/charts/scatter.rb +6 -1
  56. data/lib/ziya/charts/stacked_area.rb +5 -0
  57. data/lib/ziya/charts/stacked_bar.rb +5 -0
  58. data/lib/ziya/charts/stacked_column.rb +7 -2
  59. data/lib/ziya/charts/stacked_threed_area.rb +16 -0
  60. data/lib/ziya/charts/stacked_threed_column.rb +6 -1
  61. data/lib/ziya/components/area.rb +5 -2
  62. data/lib/ziya/components/axis_category.rb +8 -60
  63. data/lib/ziya/components/axis_ticks.rb +25 -27
  64. data/lib/ziya/components/axis_value.rb +5 -48
  65. data/lib/ziya/components/base.rb +59 -17
  66. data/lib/ziya/components/bevel.rb +15 -0
  67. data/lib/ziya/components/blur.rb +13 -0
  68. data/lib/ziya/components/chart_border.rb +4 -23
  69. data/lib/ziya/components/chart_grid_h.rb +17 -19
  70. data/lib/ziya/components/chart_grid_v.rb +18 -19
  71. data/lib/ziya/components/chart_guide.rb +16 -0
  72. data/lib/ziya/components/chart_label.rb +16 -0
  73. data/lib/ziya/components/chart_pref.rb +12 -12
  74. data/lib/ziya/components/chart_rect.rb +27 -26
  75. data/lib/ziya/components/chart_transition.rb +15 -16
  76. data/lib/ziya/components/circle.rb +5 -2
  77. data/lib/ziya/components/draw.rb +12 -11
  78. data/lib/ziya/components/draw_base.rb +10 -0
  79. data/lib/ziya/components/filter.rb +26 -0
  80. data/lib/ziya/components/glow.rb +14 -0
  81. data/lib/ziya/components/image.rb +5 -1
  82. data/lib/ziya/components/legend.rb +18 -0
  83. data/lib/ziya/components/line.rb +6 -2
  84. data/lib/ziya/components/link.rb +9 -9
  85. data/lib/ziya/components/link_data.rb +9 -10
  86. data/lib/ziya/components/rect.rb +7 -2
  87. data/lib/ziya/components/scroll.rb +26 -0
  88. data/lib/ziya/components/shadow.rb +14 -0
  89. data/lib/ziya/components/text.rb +5 -1
  90. data/lib/ziya/components/update.rb +19 -0
  91. data/lib/ziya/gauges/base.rb +172 -0
  92. data/lib/ziya/gauges/radial.rb +18 -0
  93. data/lib/ziya/gauges/signal.rb +138 -0
  94. data/lib/ziya/gauges/support/area.rb +13 -0
  95. data/lib/ziya/gauges/support/base.rb +33 -0
  96. data/lib/ziya/gauges/support/circle.rb +14 -0
  97. data/lib/ziya/gauges/support/design.rb +5 -0
  98. data/lib/ziya/gauges/support/image.rb +12 -0
  99. data/lib/ziya/gauges/support/line.rb +12 -0
  100. data/lib/ziya/gauges/support/link.rb +24 -0
  101. data/lib/ziya/gauges/support/move.rb +15 -0
  102. data/lib/ziya/gauges/support/point.rb +12 -0
  103. data/lib/ziya/gauges/support/polygon.rb +13 -0
  104. data/lib/ziya/gauges/support/radial_base.rb +21 -0
  105. data/lib/ziya/gauges/support/radial_numbers.rb +41 -0
  106. data/lib/ziya/gauges/support/radial_ticks.rb +29 -0
  107. data/lib/ziya/gauges/support/rect.rb +14 -0
  108. data/lib/ziya/gauges/support/rotate.rb +15 -0
  109. data/lib/ziya/gauges/support/scale.rb +15 -0
  110. data/lib/ziya/gauges/support/text.rb +21 -0
  111. data/lib/ziya/gauges/support/update.rb +12 -0
  112. data/lib/ziya/gauges/thermo.rb +121 -0
  113. data/lib/ziya/helpers/base_helper.rb +39 -6
  114. data/lib/ziya/utils/text.rb +6 -0
  115. data/lib/ziya/version.rb +1 -1
  116. data/lib/ziya/ziya_helper.rb +289 -62
  117. data/spec/charts/base_spec.rb +35 -21
  118. data/spec/charts/chart_type_spec.rb +24 -3
  119. data/spec/components/area_spec.rb +9 -2
  120. data/spec/components/draw_spec.rb +1 -2
  121. data/spec/components/filter_spec.rb +27 -0
  122. data/spec/components/link_spec.rb +1 -2
  123. data/spec/components/series_color_spec.rb +1 -2
  124. data/spec/components/series_explode_spec.rb +1 -2
  125. data/spec/components/series_switch_spec.rb +1 -2
  126. data/spec/designs/circle.yml +7 -0
  127. data/spec/designs/crapping_out.yml +8 -0
  128. data/spec/designs/gauge_1.yml +43 -0
  129. data/spec/designs/gauge_2.yml +11 -0
  130. data/spec/designs/gauge_no_name.yml +43 -0
  131. data/spec/designs/gauge_raw.yml +5 -0
  132. data/spec/designs/thermo.yml +13 -0
  133. data/spec/gauges/base_spec.rb +90 -0
  134. data/spec/gauges/signal_spec.rb +36 -0
  135. data/spec/gauges/support/area_spec.rb +40 -0
  136. data/spec/gauges/support/circle_spec.rb +78 -0
  137. data/spec/gauges/support/image_spec.rb +35 -0
  138. data/spec/gauges/support/line_spec.rb +34 -0
  139. data/spec/gauges/support/link_spec.rb +35 -0
  140. data/spec/gauges/support/move_spec.rb +45 -0
  141. data/spec/gauges/support/polygon_spec.rb +36 -0
  142. data/spec/gauges/support/radial_numbers_spec.rb +35 -0
  143. data/spec/gauges/support/radial_ticks_spec.rb +30 -0
  144. data/spec/gauges/support/rotate_spec.rb +45 -0
  145. data/spec/gauges/support/scale_spec.rb +46 -0
  146. data/spec/gauges/support/text_spec.rb +40 -0
  147. data/spec/gauges/thermo_spec.rb +49 -0
  148. data/spec/helpers/base_helper_spec.rb +20 -6
  149. data/spec/spec_helper.rb +4 -1
  150. data/spec/test_helpers/gauge_2_helper.rb +17 -0
  151. data/spec/utils/logger_spec.rb +1 -3
  152. data/spec/utils/text_spec.rb +1 -2
  153. data/spec/ziya_helper_spec.rb +88 -11
  154. data/spec/ziya_spec.rb +1 -1
  155. data/tasks/gem.rake +1 -1
  156. metadata +79 -32
  157. data/charts/themes/commando/bar_chart.yml +0 -9
  158. data/charts/themes/commando/base_chart.yml +0 -65
  159. data/charts/themes/commando/column_chart.yml +0 -13
  160. data/charts/themes/commando/column_threed_chart.yml +0 -25
  161. data/charts/themes/commando/parallel_threed_column_chart.yml +0 -17
  162. data/charts/themes/commando/pie_chart.yml +0 -22
  163. data/charts/themes/commando/pie_threed_chart.yml +0 -28
  164. data/charts/themes/commando/polar_chart.yml +0 -11
  165. data/charts/themes/commando/stacked_bar_chart.yml +0 -9
  166. data/charts/themes/commando/stacked_column_chart.yml +0 -14
  167. data/charts/themes/commando/stacked_threed_column_chart.yml +0 -17
  168. data/charts/themes/default/bar_chart.yml +0 -3
  169. data/charts/themes/default/base_chart.yml +0 -67
  170. data/charts/themes/default/column_chart.yml +0 -13
  171. data/charts/themes/default/column_threed_chart.yml +0 -25
  172. data/charts/themes/default/parallel_threed_column_chart.yml +0 -17
  173. data/charts/themes/default/pie_chart.yml +0 -29
  174. data/charts/themes/default/pie_threed_chart.yml +0 -28
  175. data/charts/themes/default/polar_chart.yml +0 -12
  176. data/charts/themes/default/stacked_bar_chart.yml +0 -3
  177. data/charts/themes/default/stacked_column_chart.yml +0 -14
  178. data/charts/themes/default/stacked_threed_column_chart.yml +0 -17
  179. data/charts/themes/default/test.yml +0 -4
  180. data/lib/ziya/components/chart_value.rb +0 -71
  181. data/lib/ziya/components/legend_label.rb +0 -18
  182. data/lib/ziya/components/legend_rect.rb +0 -19
  183. data/lib/ziya/components/legend_transition.rb +0 -18
  184. data/lib/ziya/components/live_update.rb +0 -21
Binary file
Binary file
Binary file
data/fred.rb ADDED
@@ -0,0 +1,36 @@
1
+ # GAUGE IDEAS ??
2
+
3
+ css_parser for ruby
4
+
5
+ gauge = Ziya::Gauges::Base.new( :id => 'volume' )
6
+ gauge.add( Ziya::Gauges::Support::RadialTicks.new( :id => 'ticks' ) )
7
+
8
+ gauge 'volume'
9
+ radial_ticks 'volume_ticks'
10
+ rotate( circle( :circle_1), circle( :circle_2 ) )
11
+
12
+
13
+ gauge#volume {
14
+ x: 100;
15
+ y: 100;
16
+ radius: 35;
17
+ }
18
+
19
+ gauge#volume rotate {
20
+ x: 100;
21
+ y: 75;
22
+ }
23
+
24
+ gauge = Ziya::Gauges::Base.new( :id => "fred" )
25
+ gauge.add( :ticks, :volume_ticks )
26
+ gauge.add( :circle, :circle_1 )
27
+ gauge.add( :circle, :circle_2 )
28
+ gauge.add( :rotate, :circle_1, :circle_2 )
29
+ gauge.to_xml
30
+
31
+ gauge#fred {
32
+ }
33
+
34
+ gauge#fred circle#volume_ticks {
35
+
36
+ }
@@ -0,0 +1,18 @@
1
+ <%= gauge :base %>
2
+ <%= dial :circle, :circle_1 %>
3
+ x: 10
4
+ y: 20
5
+ radius: 30
6
+ fill_alpha: 0
7
+ line_thickness: 5
8
+
9
+ <%= dial :text, :title %>
10
+ rotation: -90
11
+ size: 78
12
+ alpha: 10
13
+ x: -15
14
+ y: 300
15
+ color: ffffff
16
+ width: 300
17
+ text: Hello World
18
+
@@ -0,0 +1,14 @@
1
+ <%= gauge :signal %>
2
+ <%= dial :text, :signal %>
3
+ x: 20
4
+ y: 30
5
+ width: 40
6
+ size: 16
7
+ align: center
8
+ color: <%= colorizer( options[:signal] ) %>
9
+ text: <%= options[:signal] %>
10
+
11
+ # show current signal
12
+ <%= signal_indicator( options[:x], options[:y], 20, 30, 10, 0, 360, 10, 20, "88ff00" ) %>
13
+ # shows delta from previous signal
14
+ <%= delta_indicator( options[:x]+35, options[:y]-22 ) %>
@@ -0,0 +1,119 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Thermometer design
3
+ # -----------------------------------------------------------------------------
4
+ <%= gauge :thermo %>
5
+ # -----------------------------------------------------------------------------
6
+ # Gauge Title
7
+ <%= dial :text, :gauge_title %>
8
+ rotation: -90
9
+ size: 75
10
+ alpha: 10
11
+ x: <%= options[:x] - 150 %>
12
+ y: <%= options[:y] + 270 %>
13
+ color: ffffff
14
+ width: 300
15
+ text: <%= options[:title] %>
16
+
17
+ # -----------------------------------------------------------------------------
18
+ # Thermo tube
19
+ <%= dial :rect, :neck %>
20
+ x: <%= options[:x] + 20 %>
21
+ y: <%= options[:y] + 20 %>
22
+ height: 150
23
+ width: 40
24
+ fill_alpha: 20
25
+ fill_color: <%= options[:gauge_color] %>
26
+ line_thickness: 8
27
+
28
+ # -----------------------------------------------------------------------------
29
+ # Thermo bottom
30
+ <%= dial :circle, :vase %>
31
+ x: <%= options[:x] + 40 %>
32
+ y: <%= options[:y] + 190 %>
33
+ radius: 48
34
+ line_thickness: 8
35
+ fill_color: <%= options[:gauge_color] %>
36
+ fill_alpha: 100
37
+
38
+ # main
39
+ <%= dial :circle, :vase_main %>
40
+ radius: 40
41
+ x: <%= options[:x] + 40 %>
42
+ y: <%= options[:y] + 190 %>
43
+ fill_color: <%= options[:gauge_color] %>
44
+
45
+ # reflection
46
+ <%= dial :circle, :vase_reflection_1 %>
47
+ x: <%= options[:x] + 40 %>
48
+ y: <%= options[:y] + 190 %>
49
+ radius: 27
50
+ fill_alpha: 50
51
+ fill_color: ffff00
52
+
53
+ # inside
54
+ <%= dial :circle, :vase_reflection_2 %>
55
+ x: <%= options[:x] + 35 %>
56
+ y: <%= options[:y] + 190 %>
57
+ radius: 28
58
+ fill_color: <%= options[:gauge_color] %>
59
+
60
+ # -----------------------------------------------------------------------------
61
+ # Scale Legends
62
+ <%= dial :text, :legend %>
63
+ x: <%= options[:x] %>
64
+ y: <%= options[:y] %>
65
+ size: 14
66
+ color: cccccc
67
+ width: 200
68
+ text: C F
69
+
70
+ # degree
71
+ <%= dial :circle, :degrees %>
72
+ x: <%= options[:x] %>
73
+ y: <%= options[:y] + 5 %>
74
+ radius: 2
75
+ fill_alpha: 0
76
+ line_color: cccccc
77
+ line_thickness: 1
78
+
79
+ # farenheit
80
+ <%= dial :circle, :farenheit %>
81
+ x: <%= options[:x] + 65 %>
82
+ y: <%= options[:y] + 5 %>
83
+ radius: 2
84
+ fill_alpha: 0
85
+ line_color: cccccc
86
+ line_thickness: 1
87
+
88
+ # -----------------------------------------------------------------------------
89
+ # Current Temperature
90
+ <%= dial :scale, :animation %>
91
+ x: <%= options[:x] + 40 %>
92
+ y: <%= options[:y] + 133 %>
93
+ direction: vertical
94
+ step: 5
95
+ start_scale: 100
96
+ end_scale: <%= options[:end_scale] %>
97
+ shake_span: 1
98
+ shake_frequency: 10
99
+ shadow_alpha: 0
100
+ <%= dials %>
101
+ <%= dial :rect, :due_point %>
102
+ x: <%= options[:x] + 24 %>
103
+ y: <%= options[:y] + 32 %>
104
+ height: 100
105
+ width: 32
106
+ fill_color: <%= options[:gauge_color] %>
107
+
108
+ # hides to of thermo base circle
109
+ <%= dial :rect, :z_patch %>
110
+ x: <%= options[:x] + 24 %>
111
+ y: <%= options[:y] + 132 %>
112
+ height: 30
113
+ width: 32
114
+ fill_alpha: 100
115
+ # fill_color: ff0000
116
+ fill_color: <%= options[:gauge_color] %>
117
+
118
+ <%= draw_celsius_scale( -10, 50 ) %>
119
+ <%= draw_farenheit_scale( 20, 120 ) %>
@@ -0,0 +1,11 @@
1
+ <%= gauge :base %>
2
+ <%= dial :text, :title %>
3
+ rotation: -90
4
+ size: 78
5
+ alpha: 10
6
+ x: -15
7
+ y: 300
8
+ color: ffffff
9
+ width: 300
10
+ text: Hello World
11
+
Binary file
@@ -11,7 +11,7 @@ unless defined? Ziya
11
11
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
12
12
 
13
13
  def self.default_configuration
14
- { :themes_dir => File.join( File.dirname(__FILE__), %w[.. themes] ),
14
+ { :themes_dir => File.join( File.dirname(__FILE__), %w[.. charts themes] ),
15
15
  :log_file => $stdout,
16
16
  :log_level => :info }
17
17
  end
@@ -22,8 +22,14 @@ unless defined? Ziya
22
22
  @config = default_configuration.merge( opts )
23
23
  @logger = opts[:logger] if opts[:logger]
24
24
 
25
- # Verify existance of themes and helper dirs if any
26
- raise "Unable to find themes directory `#{themes_dir}" unless File.exists?( themes_dir )
25
+ # Verify existance of themes, designs and helper dirs if any
26
+ if themes_dir
27
+ raise "Unable to find themes directory `#{themes_dir}" unless File.exists?( themes_dir )
28
+ end
29
+
30
+ if designs_dir
31
+ raise "Unable to find designs directory `#{designs_dir}" unless File.exists?( designs_dir )
32
+ end
27
33
 
28
34
  if helpers_dir
29
35
  raise "Unable to find helper directory `#{helpers_dir}" unless File.exists?( helpers_dir )
@@ -31,8 +37,9 @@ unless defined? Ziya
31
37
 
32
38
  # Add the ziya/lib to the ruby path...
33
39
  $: << libpath
34
- Ziya.require_all_libs_relative_to __FILE__
35
- dump
40
+ Ziya.require_all_libs_relative_to __FILE__
41
+
42
+ dump if config[:log_level] == :debug
36
43
  end
37
44
 
38
45
  # ZiYa configuration
@@ -49,6 +56,11 @@ unless defined? Ziya
49
56
  def self.themes_dir
50
57
  config[:themes_dir]
51
58
  end
59
+
60
+ # the gauges designs root directory location
61
+ def self.designs_dir
62
+ config[:designs_dir]
63
+ end
52
64
 
53
65
  # Debug
54
66
  def self.dump #:nodoc:
@@ -1,11 +1,16 @@
1
1
  # -----------------------------------------------------------------------------
2
2
  # Generates necessary xml for area chart
3
+ #
4
+ # Author: Fernand
3
5
  # -----------------------------------------------------------------------------
4
6
  require 'ziya/charts/base'
5
7
 
6
8
  module Ziya::Charts
7
9
  class Area < Base
8
- def initialize( license=nil, chart_id=nil)
10
+ # Creates an area chart
11
+ # <tt>:license</tt>:: the XML/SWF charts license
12
+ # <tt>:chart_id</tt>:: the name of the chart style sheet.
13
+ def initialize( license=nil, chart_id=nil )
9
14
  super( license, chart_id )
10
15
  @type = "area"
11
16
  end
@@ -0,0 +1,16 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Generates necessary xml for a 3d area chart
3
+ #
4
+ # Author: Fernand
5
+ # -----------------------------------------------------------------------------
6
+ module Ziya::Charts
7
+ class AreaThreed < Base
8
+ # Creates a 3d area chart
9
+ # <tt>:license</tt>:: the XML/SWF charts license
10
+ # <tt>:chart_id</tt>:: the name of the chart style sheet.
11
+ def initialize( license=nil, chart_id=nil )
12
+ super( license, chart_id )
13
+ @type = "3d area"
14
+ end
15
+ end
16
+ end
@@ -1,11 +1,16 @@
1
1
  # -----------------------------------------------------------------------------
2
- # Generates necessary xml for a StackColumn chart
2
+ # Generates necessary xml for a Bar chart
3
+ #
4
+ # Author: Fernand
3
5
  # -----------------------------------------------------------------------------
4
6
  module Ziya::Charts
5
7
  class Bar < Base
6
- def initialize( license=nil, chart_id=nil)
8
+ # Creates a bar chart
9
+ # <tt>:license</tt>:: the XML/SWF charts license
10
+ # <tt>:chart_id</tt>:: the name of the chart style sheet.
11
+ def initialize( license=nil, chart_id=nil )
7
12
  super( license, chart_id )
8
- @type = "bar"
13
+ @type = "bar"
9
14
  end
10
15
  end
11
16
  end
@@ -12,20 +12,29 @@
12
12
  require 'ziya/helpers/base_helper'
13
13
  require 'yaml'
14
14
 
15
+ # TODO Figure out the equiv require_dep for merb if any ??
16
+ # TODO Refact and clean up.
15
17
  module Ziya::Charts
18
+ # The mother ship of all charts. This class figures out how to generate the
19
+ # correct xml to render the chart on the client side. This class handles loading
20
+ # style sheets and chart helper for the helper directory specified during
21
+ # initialization.
16
22
  class Base
23
+ # blee blee
17
24
  include Ziya::Helpers::BaseHelper
18
25
 
19
26
  # =========================================================================
20
27
  protected
21
28
  # defines the various chart components
22
- def self.declare_components
23
- @components = [:axis_category, :axis_ticks, :axis_value, :chart_rect,
24
- :chart_border, :chart_grid_h, :chart_grid_v,
25
- :chart_transition, :chart_value, :legend_rect,
26
- :legend_transition, :legend_label, :draw, :series_color,
27
- :series_gap, :series_switch, :series_explode, :chart_pref,
28
- :live_update, :link_data, :link]
29
+ def self.declare_components # :nodoc:
30
+ @components = [
31
+ :axis_category, :axis_ticks, :axis_value,
32
+ :chart_rect, :chart_border, :chart_grid_h, :chart_grid_v,
33
+ :chart_transition, :chart_label, :chart_guide, :legend,
34
+ :filter, :draw,
35
+ :series_color, :series_gap, :series_switch, :series_explode,
36
+ :chart_pref, :scroll,
37
+ :update, :link_data, :link]
29
38
  @components.each { |a| attr_accessor a }
30
39
  end
31
40
  declare_components
@@ -33,44 +42,44 @@ module Ziya::Charts
33
42
  # =========================================================================
34
43
  public
35
44
 
36
- attr_accessor :license, :id, :theme, :options, :size
37
- attr_reader :type
45
+ attr_accessor :license, :id, :theme, :options, :size # :nodoc:
46
+ attr_reader :type # :nodoc:
38
47
 
39
- # -------------------------------------------------------------------------
40
- # Create a new chart.
41
- # license - the XML/SWF charts license
42
- # title - the chart title
43
- # chart_id - the id of the chart used to associate a style with the chart.
44
- # If chart_id is specified the framework will attempt to load the chart styles
48
+ # create a new chart.
49
+ # <tt>:license</tt>:: the XML/SWF charts license
50
+ # <tt>:chart_id</tt>:: the name of the chart style sheet.
51
+ # NOTE: If chart_id is specified the framework will attempt to load the chart styles
45
52
  # from public/themes/theme_name/chart_id.yml
46
53
  def initialize( license=nil, chart_id=nil )
47
54
  @id = chart_id
48
55
  @license = license
49
56
  @options = {}
57
+ @series = []
50
58
  @theme = default_theme
51
59
  initialize_components
52
60
  load_helpers( Ziya.helpers_dir ) if Ziya.helpers_dir
53
61
  end
54
62
 
55
63
  # class component accessor...
56
- def self.components
64
+ def self.components # :nodoc:
57
65
  @components
58
66
  end
59
67
 
60
68
  # -------------------------------------------------------------------------
61
69
  # Default ZiYa theme
62
- def default_theme
70
+ def default_theme # :nodoc:
63
71
  File.join( Ziya.themes_dir, %w[default] )
64
72
  end
65
73
 
66
74
  # -------------------------------------------------------------------------
67
75
  # Load up ERB style helpers
68
- def load_helpers( helper_dir )
76
+ def load_helpers( helper_dir ) # :nodoc:
69
77
  Dir.foreach(helper_dir) do |helper_file|
70
78
  next unless helper_file =~ /^([a-z][a-z_]*_helper).rb$/
71
79
  Ziya.logger.debug( ">>> ZiYa loading custom helper `#{$1}" )
72
- require_dependency File.join(helper_dir, $1)
73
- helper_module_name = $1.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
80
+ require_dependency File.join(helper_dir, $1)
81
+ helper_module_name = "Ziya::" + $1.gsub(/(^|_)(.)/) { $2.upcase }
82
+ # helper_module_name = $1.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
74
83
  # if Ziya::Helpers.const_defined?(helper_module_name)
75
84
  Ziya.logger.debug( "Include module #{helper_module_name}")
76
85
  Ziya::Charts::Base.class_eval("include #{helper_module_name}")
@@ -78,14 +87,14 @@ module Ziya::Charts
78
87
  end
79
88
  end
80
89
 
81
- # -------------------------------------------------------------------------
82
90
  # Add chart components such as x and y axis labels, data points and chart
83
91
  # labels.
84
92
  #
85
93
  # Example:
94
+ # my_chart = Ziya::Charts::Bar.new
86
95
  # my_chart.add( :axis_category_text, ['2004', '2005', '2006'] )
87
96
  # my_chart.add( :series, 'series A', [ 10, 20, 30], [ '10 dogs', '20 cats', '30 rats'] )
88
- # my_chart.add( :axis_value_text, [ 'my dogs', 'my cats', 'my rats'] )
97
+ # my_chart.add( :axis_value_label, [ 'my dogs', 'my cats', 'my rats'] )
89
98
  # my_chart.add( :user_data, :mykey, "Fred" )
90
99
  #
91
100
  # This will display a bar chart with x axis ticks my dogs, my cats, my fox and
@@ -97,28 +106,30 @@ module Ziya::Charts
97
106
  # <tt>:axis_category_text</tt>:: Array of strings representing the x/y axis
98
107
  # ticks dependending on the chart type. This
99
108
  # value is required.
109
+ # <tt>:axis_category_label</tt>:: Array of strings representing the x axis
110
+ # labels. This is supported only for Scatter and Bubble charts.
111
+ # This value is optional. Specify nil for no label change.
100
112
  # <tt>:series</tt>:: Specifies the series name and chart data points.
101
113
  # The series name will be used to display chart legends.
102
114
  # You must have at least one of these tag defined.
103
115
  # You may also specify an array of strings to identifies the
104
116
  # custom labels that will be used on top of the chart
105
- # elements.
106
- # <tt>:axis_value_text</tt>:: Array of strings representing the ticks on the x/y
117
+ # elements
118
+ # <tt>:axis_value_label</tt>:: Array of strings representing the ticks on the x/y
107
119
  # axis depending on the chart type. This is symmetrical
108
- # to the <tt>axis_category_text</tt> tag for the opposite
109
- # chart axis.
120
+ # to the <tt>axis_category_label</tt> tag for the opposite
121
+ # chart axis. Specify nil for no label change.
110
122
  # <tt>:user_data</tt>:: Used to make user data available to the ERB templates in
111
123
  # the chart stylesheet yaml file. You must specify a key symbol
112
124
  # and an ad-hoc value. The key will be used with the @options
113
125
  # hash to access the user data.
114
- # <tt>:composites</tt>:: Embeds multiple charts within the given chart.
126
+ # <tt>:composites</tt>:: Embeds multiple charts within the given chart via the draw image component.
115
127
  # <tt>:chart_types</tt>:: Specify the chart types per series. This option should
116
128
  # only be used with Mixed Charts !!
117
129
  # <tt>:theme</tt>:: Specify the use of a given theme
118
130
  #
119
- # TODO Validation categories = series, series = labels, etc...
120
- # BOZO !! If you have a series you'll need to define an axis_category for it
121
131
  def add( *args )
132
+ # TODO Validation categories = series, series = labels, etc...
122
133
  directive = args.shift
123
134
  case directive
124
135
  when :axis_category_text
@@ -126,26 +137,29 @@ module Ziya::Charts
126
137
  raise ArgumentError, "Must specify an array of categories" if categories.empty?
127
138
  categories.insert( 0, nil )
128
139
  @options[directive] = categories
140
+ when :axis_category_label
141
+ labels = args.first.is_a?(Array) ? args.shift : []
142
+ raise ArgumentError, "Must specify an array of category labels" if labels.empty?
143
+ @options[directive] = labels
129
144
  when :composites
130
145
  composites = args.first.is_a?(Array) ? args.shift: []
131
146
  raise ArgumentError, "Must specify an array of urls for the composite chart(s)" if composites.empty?
132
147
  @options[directive] = composites
133
- when :axis_value_text
148
+ when :axis_value_label
134
149
  values = args.first.is_a?(Array) ? args.shift : []
135
150
  raise ArgumentError, "Must specify an array of values" if values.empty?
136
151
  @options[directive] = values
137
152
  when :series
138
153
  legend = args.first.is_a?(String) ? args.shift : ""
139
154
  raise ArgumentError, "Must specify a series name" if legend.empty?
140
- points = args.first.is_a?(Array) ? args.shift : []
141
- raise ArgumentError, "Must specify data points" if points.empty?
142
- points.insert( 0, legend )
143
- labels = args.first.is_a?(Array) ? args.shift : []
144
- count = "_#{sprintf( '%04d', next_series_count )}_#{legend}"
145
- series_name = "series#{count}"
146
- labels_name = "labels#{count}" unless labels.empty?
147
- @options[series_name.to_sym] = points
148
- @options[labels_name.to_sym] = labels unless labels.empty?
155
+ if args.first.is_a?( Array )
156
+ points = args.shift || []
157
+ raise ArgumentError, "Must specify an array of data points" if points.empty?
158
+ points.insert( 0, legend )
159
+ @series << points
160
+ else
161
+ raise ArgumentError, "Must specify an array of data points"
162
+ end
149
163
  when :user_data
150
164
  key = args.first.is_a?(Symbol) ? args.shift : ""
151
165
  raise ArgumentError, "Must specify a key" if key.to_s.empty?
@@ -155,41 +169,29 @@ module Ziya::Charts
155
169
  when :styles
156
170
  styles = args.first.is_a?(String) ? args.shift : ""
157
171
  raise ArgumentError, "Must specify a set of styles" if styles.to_s.empty?
158
- @options[:styles] = styles
172
+ @options[directive] = styles
159
173
  when :chart_types
160
174
  types = args.first.is_a?(Array) ? args.shift : []
161
175
  raise ArgumentError, "Must specify a set of chart types" if types.to_s.empty?
162
- @options[:chart_types] = types
176
+ @options[directive] = types
163
177
  when :theme
164
178
  theme = args.first.is_a?(String) ? args.shift : ""
165
179
  raise ArgumentError, "Must specify a theme name" if theme.to_s.empty?
166
180
  @theme = "#{Ziya.themes_dir}/#{theme}"
167
181
  else raise ArgumentError, "Invalid directive must be one of " +
168
- ":axis_category, :axis_value, :series, :user_data"
182
+ ":axis_category_text, :axis_value, :series, :user_data"
169
183
  end
170
184
  end
171
-
172
- # -------------------------------------------------------------------------
173
- # Set up theme for overall look and feel
174
- # <tt>theme_name</tt> the name of the directory that contains the chart styles
175
- def self.theme( theme_name )
176
- @theme = "#{Ziya.themes_dir}/#{theme_name}"
177
- end
178
-
179
- # -------------------------------------------------------------------------
180
- # Return the local theme if set or the global theme otherwise
181
- def theme
182
- @theme || @@theme
183
- end
184
-
185
- # ---------------------------------------------------------------------------
186
- # Spews the graph specification to xml
185
+
186
+ # spews the graph specification to a string
187
187
  # <tt>:partial</tt>:: You can specify this option to only update parts of the charts
188
188
  # that have actually changed. This is useful for live update and
189
189
  # link update where you may not need to redraw the whole chart.
190
190
  def to_s( options={} )
191
191
  @partial = options[:partial] || false
192
192
  @xml = Builder::XmlMarkup.new
193
+ # Forces utf8 encoding on xml stream
194
+ @xml.instruct! :xml, :version => "1.0", :encoding => "UTF-8"
193
195
  @xml.chart do
194
196
  @xml.license( @license ) unless @license.nil?
195
197
  if !@type.nil?
@@ -203,23 +205,13 @@ module Ziya::Charts
203
205
  setup_series
204
206
  end
205
207
  @xml.to_s.gsub( /<to_s\/>/, '' )
206
- end
207
-
208
- # -------------------------------------------------------------------------
209
- # Synonym for to_s
208
+ end
209
+ # dumps the chart design to xml for client side consumption
210
210
  alias to_xml to_s
211
211
 
212
212
  # =========================================================================
213
213
  private
214
214
 
215
- # -------------------------------------------------------------------------
216
- # Make sure series appear in the right order
217
- def next_series_count
218
- count = 1
219
- @options.keys.each{ |k| count+=1 unless k.to_s.index( "series_").nil? }
220
- count
221
- end
222
-
223
215
  # -------------------------------------------------------------------------
224
216
  # Inflate object state based on object hierarchy
225
217
  def setup_state( state )
@@ -239,6 +231,7 @@ module Ziya::Charts
239
231
  file_name = "#{theme}/#{instance}" unless instance.nil?
240
232
  Ziya.logger.debug ">>> Ziya attempt to load style sheet file '#{file_name}"
241
233
  yml = IO.read( "#{file_name}.yml" )
234
+ # Ziya.logger.debug( yml )
242
235
  load = YAML::load( erb_render( yml ) )
243
236
  Ziya.logger.info ">>> ZiYa [loading styles] -- #{file_name}.yml"
244
237
  return load
@@ -260,120 +253,188 @@ module Ziya::Charts
260
253
 
261
254
  # -------------------------------------------------------------------------
262
255
  # Generates xml element for given data set
263
- def gen_data_points( series_name )
264
- value = @options[series_name]
256
+ # TODO Lame ! Refact...
257
+ def gen_data_points( series_name, labels=nil )
258
+ values = @options[series_name]
259
+ labels.insert( 0, nil ) if labels
265
260
  @xml.row do
266
- if value.respond_to? :each
267
- value.each do |c|
268
- @xml.null if c.nil?
269
- @xml.string( c ) if c.instance_of? String
270
- @xml.number( c ) if c.respond_to? :zero?
261
+ if values.respond_to? :each
262
+ values.each do |c|
263
+ if c.nil?
264
+ @xml.null
265
+ elsif c.instance_of? String
266
+ if labels and !labels.empty?
267
+ label = labels.shift
268
+ if label
269
+ @xml.string( :label => label ) { |x| x.text!( c ) }
270
+ else
271
+ @xml.string( c )
272
+ end
273
+ else
274
+ @xml.string( c )
275
+ end
276
+ elsif c.respond_to? :zero?
277
+ if labels and !labels.empty?
278
+ label = labels.shift
279
+ if label
280
+ @xml.number( :label => label ) { |x| x.text!( c.to_s ) }
281
+ else
282
+ @xml.number( c )
283
+ end
284
+ else
285
+ @xml.number( c )
286
+ end
287
+ end
271
288
  end
272
289
  else
273
- @xml.string( value )
290
+ @xml.string( values )
274
291
  end
275
292
  end
276
293
  end
277
294
 
278
- # -------------------------------------------------------------------------
279
- # Generates custom axis values
280
- def gen_axis_value_text( values )
281
- return if values.nil? or values.empty?
282
- @xml.axis_value_text do
283
- values.each { |v| @xml.string( v ) }
284
- end
285
- end
295
+ # # -------------------------------------------------------------------------
296
+ # # Generates custom axis values
297
+ # def gen_axis_value_text( values )
298
+ # return if values.nil? or values.empty?
299
+ # @xml.axis_value_text do
300
+ # values.each { |v| @xml.string( v ) }
301
+ # end
302
+ # end
286
303
 
304
+ # # -------------------------------------------------------------------------
305
+ # # Check if the series are named
306
+ # def named_series?( names )
307
+ # names.each do |name|
308
+ # next unless name.to_s.index( 'series_' )
309
+ # return @options[name][0].instance_of?(String) if @options[name] and !@options[name].empty?
310
+ # end
311
+ # false
312
+ # end
313
+
314
+ # # -------------------------------------------------------------------------
315
+ # # Check if the options have custom labels ie :label_xxx tag
316
+ # def has_labels( names )
317
+ # names.each do |name|
318
+ # next unless name.to_s.index( 'labels_' )
319
+ # return @options[name].size if @options[name] and !@options[name].empty?
320
+ # end
321
+ # 0
322
+ # end
323
+
324
+ # # -------------------------------------------------------------------------
325
+ # # Generates custom labels
326
+ # def gen_labels( series_name, is_default=false )
327
+ # cltn = @options[series_name]
328
+ # cltn.insert( 0, nil ) unless is_default
329
+ # @xml.row do
330
+ # cltn.each { |c| ((c.nil? or c.to_s.empty?) ? @xml.null : @xml.string( c )) }
331
+ # end
332
+ # end
333
+
334
+ # # ------------------------------------------------------------------------
335
+ # # Generates default series labels
336
+ # def gen_default_labels( size )
337
+ # labels = []
338
+ # size.times { |i| labels << nil }
339
+ # @xml.row do
340
+ # labels.each { |c| @xml.null }
341
+ # end
342
+ # end
343
+
344
+ # ------------------------------------------------------------------------
345
+ # generates chart data row
346
+ # TODO Validate options !!
347
+ def gen_row_data( value, opts=nil )
348
+ if value.instance_of? String
349
+ gen_string_data( value, opts )
350
+ elsif value.respond_to? :zero?
351
+ gen_number_data( value, opts )
352
+ end
353
+ end
354
+
287
355
  # -------------------------------------------------------------------------
288
- # Check if the series are named
289
- def named_series?( names )
290
- names.each do |name|
291
- next unless name.to_s.index( 'series_' )
292
- return @options[name][0].instance_of?(String) if @options[name] and !@options[name].empty?
356
+ # generates string chart_value
357
+ def gen_string_data( value, opts )
358
+ if opts
359
+ @xml.string( opts ) { |x| x.text!( value ) }
360
+ else
361
+ @xml.string( value )
293
362
  end
294
- false
295
363
  end
296
364
 
297
365
  # -------------------------------------------------------------------------
298
- # Check if the options have custom labels ie :label_xxx tag
299
- def has_labels( names )
300
- names.each do |name|
301
- next unless name.to_s.index( 'labels_' )
302
- return @options[name].size if @options[name] and !@options[name].empty?
366
+ # generates number chart_value
367
+ def gen_number_data( value, opts )
368
+ if opts
369
+ @xml.number( opts ) { |x| x.text!( value.to_s ) }
370
+ else
371
+ @xml.number( value )
303
372
  end
304
- 0
305
- end
373
+ end
306
374
 
307
375
  # -------------------------------------------------------------------------
308
- # Generates custom labels
309
- def gen_labels( series_name, is_default=false )
310
- cltn = @options[series_name]
311
- cltn.insert( 0, nil ) unless is_default
312
- @xml.row do
313
- cltn.each { |c| ((c.nil? or c.to_s.empty?) ? @xml.null : @xml.string( c )) }
314
- end
315
- end
316
-
317
- # ------------------------------------------------------------------------
318
- # Generates default series labels
319
- def gen_default_labels( size )
320
- labels = []
321
- size.times { |i| labels << nil }
322
- @xml.row do
323
- labels.each { |c| @xml.null }
324
- end
325
- end
376
+ # generates chart data points
377
+ # BOZO !! Check args on hash
378
+ def gen_chart_data( series )
379
+ @xml.row do
380
+ series.each do |row|
381
+ if row.nil?
382
+ @xml.null
383
+ elsif row.instance_of? Hash
384
+ value = row.delete( :value )
385
+ gen_row_data( value, row )
386
+ else
387
+ gen_row_data( row )
388
+ end
389
+ end
390
+ end
391
+ end
326
392
 
327
393
  # -------------------------------------------------------------------------
328
394
  # Lay down graph data points and labels if any
329
395
  # TODO Validate series sizes/label sizes
330
396
  def setup_series
331
- keys = @options.keys.sort { |a,b| a.to_s <=> b.to_s }
332
- named_series = named_series?( keys )
397
+ raise "You must specify an axis_category_text with your series." if !@series.empty? and ! @options[:axis_category_text]
333
398
 
334
- raise "You must specify an axis_category_text with your series." if named_series and ! @options[:axis_category_text]
335
-
336
- unless @options[:axis_category_text].nil?
399
+ if @options[:axis_category_text]
337
400
  @xml.chart_data do
338
- # Setup axis categories
339
- # @options[:axis_category_text].insert( 0, nil ) if named_series
340
401
  gen_data_points( :axis_category_text )
341
- keys.each do |k|
342
- gen_data_points( k ) unless k.to_s.index( 'series_' ).nil?
402
+ # render xml for each series
403
+ @series.each do |series|
404
+ gen_chart_data( series )
343
405
  end
344
406
  end
345
407
  end
346
-
347
- size = has_labels( keys )
348
- if size > 0
349
- @xml.chart_value_text do
350
- labels = []
351
- (1..(size-1)).each { |i| labels << '' }
352
- @options[:labels] = labels
353
- gen_labels( :labels, true )
354
-
355
- # Generates series labels if specified
356
- keys.each do |k|
357
- next unless k.to_s.index( /^series/ )
358
- label = k.to_s.gsub( /series/, 'labels' ).to_sym
359
- unless @options[label].nil?
360
- gen_labels( label )
361
- else
362
- gen_default_labels( size )
363
- end
408
+
409
+ # display category labels if any
410
+ if @options[:axis_category_label]
411
+ @xml.axis_category_label do
412
+ @options[:axis_category_label].each do |label|
413
+ label ? @xml.string( label ) : @xml.null
364
414
  end
365
- end
415
+ end
366
416
  end
417
+
418
+ # display axis value labels if any
419
+ if @options[:axis_value_label]
420
+ @xml.axis_value_label do
421
+ @options[:axis_value_label].each do |label|
422
+ label ? @xml.string( label ) : @xml.null
423
+ end
424
+ end
425
+ end
426
+
367
427
  end
368
428
 
369
429
  # -------------------------------------------------------------------------
370
430
  # Walk up class hierarchy to find chart inheritance classes
371
431
  def ancestors
372
- excludes = [ "Kernel", "Object", "CommonUtils" ]
373
432
  ancestors = self.class.ancestors.reverse
374
- list = []
375
- ancestors.each { |a| list << a unless excludes.include? a.to_s }
376
- list
433
+ allow = false
434
+ ancestors.map do |k|
435
+ allow = true if k == Ziya::Charts::Base
436
+ k if allow
437
+ end.compact!
377
438
  end
378
439
 
379
440
  # -------------------------------------------------------------------------
@@ -407,10 +468,6 @@ module Ziya::Charts
407
468
  # Generates xml for look and feel data
408
469
  def setup_lnf
409
470
  load_lnf
410
- if @options[:axis_value_text] and ! @options[:axis_value_text].empty?
411
- gen_axis_value_text( @options[:axis_value_text] )
412
- end
413
-
414
471
  unless @partial
415
472
  Base.components.each do |comp|
416
473
  next unless self.send( comp ).configured? # => Don't include non configured components