ziya 1.0.0 → 2.0.0

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.
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