ziya 1.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.
- data/History.txt +4 -0
- data/Manifest.txt +127 -0
- data/README.txt +137 -0
- data/Rakefile +45 -0
- data/bin/ziyafy +51 -0
- data/charts/charts.swf +0 -0
- data/charts/charts_library/arno.swf +0 -0
- data/charts/charts_library/arst.swf +0 -0
- data/charts/charts_library/brfl.swf +0 -0
- data/charts/charts_library/brno.swf +0 -0
- data/charts/charts_library/brst.swf +0 -0
- data/charts/charts_library/cl3d.swf +0 -0
- data/charts/charts_library/clfl.swf +0 -0
- data/charts/charts_library/clno.swf +0 -0
- data/charts/charts_library/clp3.swf +0 -0
- data/charts/charts_library/cls3.swf +0 -0
- data/charts/charts_library/clst.swf +0 -0
- data/charts/charts_library/cnno.swf +0 -0
- data/charts/charts_library/lnno.swf +0 -0
- data/charts/charts_library/mxno.swf +0 -0
- data/charts/charts_library/pi3d.swf +0 -0
- data/charts/charts_library/pino.swf +0 -0
- data/charts/charts_library/pono.swf +0 -0
- data/charts/charts_library/scno.swf +0 -0
- data/charts/themes/commando/bar_chart.yml +9 -0
- data/charts/themes/commando/base_chart.yml +65 -0
- data/charts/themes/commando/column_chart.yml +13 -0
- data/charts/themes/commando/column_threed_chart.yml +25 -0
- data/charts/themes/commando/parallel_threed_column_chart.yml +17 -0
- data/charts/themes/commando/pie_chart.yml +22 -0
- data/charts/themes/commando/pie_threed_chart.yml +28 -0
- data/charts/themes/commando/polar_chart.yml +11 -0
- data/charts/themes/commando/stacked_bar_chart.yml +9 -0
- data/charts/themes/commando/stacked_column_chart.yml +14 -0
- data/charts/themes/commando/stacked_threed_column_chart.yml +17 -0
- data/charts/themes/default/bar_chart.yml +3 -0
- data/charts/themes/default/base_chart.yml +67 -0
- data/charts/themes/default/column_chart.yml +13 -0
- data/charts/themes/default/column_threed_chart.yml +25 -0
- data/charts/themes/default/parallel_threed_column_chart.yml +17 -0
- data/charts/themes/default/pie_chart.yml +29 -0
- data/charts/themes/default/pie_threed_chart.yml +28 -0
- data/charts/themes/default/polar_chart.yml +12 -0
- data/charts/themes/default/stacked_bar_chart.yml +3 -0
- data/charts/themes/default/stacked_column_chart.yml +14 -0
- data/charts/themes/default/stacked_threed_column_chart.yml +17 -0
- data/charts/themes/default/test.yml +4 -0
- data/lib/ziya.rb +100 -0
- data/lib/ziya/charts/area.rb +13 -0
- data/lib/ziya/charts/bar.rb +11 -0
- data/lib/ziya/charts/base.rb +435 -0
- data/lib/ziya/charts/candle_stick.rb +11 -0
- data/lib/ziya/charts/column.rb +11 -0
- data/lib/ziya/charts/column_threed.rb +11 -0
- data/lib/ziya/charts/floating_bar.rb +11 -0
- data/lib/ziya/charts/floating_column.rb +11 -0
- data/lib/ziya/charts/line.rb +11 -0
- data/lib/ziya/charts/mixed.rb +11 -0
- data/lib/ziya/charts/parallel_threed_column.rb +11 -0
- data/lib/ziya/charts/pie.rb +11 -0
- data/lib/ziya/charts/pie_threed.rb +11 -0
- data/lib/ziya/charts/polar.rb +11 -0
- data/lib/ziya/charts/scatter.rb +11 -0
- data/lib/ziya/charts/stacked_area.rb +11 -0
- data/lib/ziya/charts/stacked_bar.rb +11 -0
- data/lib/ziya/charts/stacked_column.rb +11 -0
- data/lib/ziya/charts/stacked_threed_column.rb +11 -0
- data/lib/ziya/components/area.rb +14 -0
- data/lib/ziya/components/axis_category.rb +69 -0
- data/lib/ziya/components/axis_ticks.rb +37 -0
- data/lib/ziya/components/axis_value.rb +59 -0
- data/lib/ziya/components/base.rb +100 -0
- data/lib/ziya/components/chart_border.rb +33 -0
- data/lib/ziya/components/chart_grid_h.rb +28 -0
- data/lib/ziya/components/chart_grid_v.rb +28 -0
- data/lib/ziya/components/chart_pref.rb +22 -0
- data/lib/ziya/components/chart_rect.rb +36 -0
- data/lib/ziya/components/chart_transition.rb +26 -0
- data/lib/ziya/components/chart_value.rb +71 -0
- data/lib/ziya/components/circle.rb +13 -0
- data/lib/ziya/components/draw.rb +45 -0
- data/lib/ziya/components/image.rb +13 -0
- data/lib/ziya/components/legend_label.rb +18 -0
- data/lib/ziya/components/legend_rect.rb +19 -0
- data/lib/ziya/components/legend_transition.rb +18 -0
- data/lib/ziya/components/line.rb +12 -0
- data/lib/ziya/components/link.rb +29 -0
- data/lib/ziya/components/link_data.rb +19 -0
- data/lib/ziya/components/live_update.rb +21 -0
- data/lib/ziya/components/rect.rb +13 -0
- data/lib/ziya/components/series_color.rb +35 -0
- data/lib/ziya/components/series_explode.rb +38 -0
- data/lib/ziya/components/series_gap.rb +18 -0
- data/lib/ziya/components/series_switch.rb +25 -0
- data/lib/ziya/components/text.rb +13 -0
- data/lib/ziya/helpers/base_helper.rb +37 -0
- data/lib/ziya/utils/logger.rb +125 -0
- data/lib/ziya/utils/text.rb +33 -0
- data/lib/ziya/version.rb +15 -0
- data/lib/ziya/ziya_helper.rb +147 -0
- data/spec/charts/base_spec.rb +120 -0
- data/spec/charts/chart_type_spec.rb +42 -0
- data/spec/components/area_spec.rb +60 -0
- data/spec/components/draw_spec.rb +33 -0
- data/spec/components/link_spec.rb +23 -0
- data/spec/components/series_color_spec.rb +40 -0
- data/spec/components/series_explode_spec.rb +40 -0
- data/spec/components/series_switch_spec.rb +19 -0
- data/spec/helpers/base_helper_spec.rb +22 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/themes/default/fred.yml +6 -0
- data/spec/themes/default/line_chart.yml +6 -0
- data/spec/utils/logger_spec.rb +57 -0
- data/spec/utils/text_spec.rb +34 -0
- data/spec/ziya_helper_spec.rb +40 -0
- data/spec/ziya_spec.rb +19 -0
- data/tasks/ann.rake +76 -0
- data/tasks/annotations.rake +22 -0
- data/tasks/doc.rake +48 -0
- data/tasks/gem.rake +110 -0
- data/tasks/manifest.rake +49 -0
- data/tasks/post_load.rake +26 -0
- data/tasks/rubyforge.rake +57 -0
- data/tasks/setup.rb +227 -0
- data/tasks/spec.rake +61 -0
- data/tasks/svn.rake +44 -0
- data/tasks/test.rake +38 -0
- metadata +190 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Generates necessary xml for area chart
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
require 'ziya/charts/base'
|
|
5
|
+
|
|
6
|
+
module Ziya::Charts
|
|
7
|
+
class Area < Base
|
|
8
|
+
def initialize( license=nil, chart_id=nil)
|
|
9
|
+
super( license, chart_id )
|
|
10
|
+
@type = "area"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Generates necessary xml for a StackColumn chart
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
module Ziya::Charts
|
|
5
|
+
class Bar < Base
|
|
6
|
+
def initialize( license=nil, chart_id=nil)
|
|
7
|
+
super( license, chart_id )
|
|
8
|
+
@type = "bar"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# == Ziya::Charts::Base
|
|
3
|
+
#
|
|
4
|
+
# Charts mother ship
|
|
5
|
+
#
|
|
6
|
+
# TODO !! Match helpers with chart class name
|
|
7
|
+
# TODO !! Add accessor for specifying refresh look and data links on comps
|
|
8
|
+
#
|
|
9
|
+
# Author:: Fernand Galiana
|
|
10
|
+
# Date:: Dec 15th, 2006
|
|
11
|
+
# -----------------------------------------------------------------------------
|
|
12
|
+
require 'ziya/helpers/base_helper'
|
|
13
|
+
require 'yaml'
|
|
14
|
+
|
|
15
|
+
module Ziya::Charts
|
|
16
|
+
class Base
|
|
17
|
+
include Ziya::Helpers::BaseHelper
|
|
18
|
+
|
|
19
|
+
# =========================================================================
|
|
20
|
+
protected
|
|
21
|
+
# 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
|
+
@components.each { |a| attr_accessor a }
|
|
30
|
+
end
|
|
31
|
+
declare_components
|
|
32
|
+
|
|
33
|
+
# =========================================================================
|
|
34
|
+
public
|
|
35
|
+
|
|
36
|
+
attr_accessor :license, :id, :theme, :options, :size
|
|
37
|
+
attr_reader :type
|
|
38
|
+
|
|
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
|
|
45
|
+
# from public/themes/theme_name/chart_id.yml
|
|
46
|
+
def initialize( license=nil, chart_id=nil )
|
|
47
|
+
@id = chart_id
|
|
48
|
+
@license = license
|
|
49
|
+
@options = {}
|
|
50
|
+
@theme = default_theme
|
|
51
|
+
initialize_components
|
|
52
|
+
load_helpers( Ziya.helpers_dir ) if Ziya.helpers_dir
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# class component accessor...
|
|
56
|
+
def self.components
|
|
57
|
+
@components
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# -------------------------------------------------------------------------
|
|
61
|
+
# Default ZiYa theme
|
|
62
|
+
def default_theme
|
|
63
|
+
File.join( Ziya.themes_dir, %w[default] )
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# -------------------------------------------------------------------------
|
|
67
|
+
# Load up ERB style helpers
|
|
68
|
+
def load_helpers( helper_dir )
|
|
69
|
+
Dir.foreach(helper_dir) do |helper_file|
|
|
70
|
+
next unless helper_file =~ /^([a-z][a-z_]*_helper).rb$/
|
|
71
|
+
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 }
|
|
74
|
+
# if Ziya::Helpers.const_defined?(helper_module_name)
|
|
75
|
+
Ziya.logger.debug( "Include module #{helper_module_name}")
|
|
76
|
+
Ziya::Charts::Base.class_eval("include #{helper_module_name}")
|
|
77
|
+
# end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# -------------------------------------------------------------------------
|
|
82
|
+
# Add chart components such as x and y axis labels, data points and chart
|
|
83
|
+
# labels.
|
|
84
|
+
#
|
|
85
|
+
# Example:
|
|
86
|
+
# my_chart.add( :axis_category_text, ['2004', '2005', '2006'] )
|
|
87
|
+
# 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'] )
|
|
89
|
+
# my_chart.add( :user_data, :mykey, "Fred" )
|
|
90
|
+
#
|
|
91
|
+
# This will display a bar chart with x axis ticks my dogs, my cats, my fox and
|
|
92
|
+
# y axis values 2004, 2005, 2006. The labels on the bars will read 10 dogs,
|
|
93
|
+
# 20 cats, 30 rats
|
|
94
|
+
#
|
|
95
|
+
# The <tt>args</tt> must contain certain keys for the chart
|
|
96
|
+
# to be display correctly. The keys are defined as follows:
|
|
97
|
+
# <tt>:axis_category_text</tt>:: Array of strings representing the x/y axis
|
|
98
|
+
# ticks dependending on the chart type. This
|
|
99
|
+
# value is required.
|
|
100
|
+
# <tt>:series</tt>:: Specifies the series name and chart data points.
|
|
101
|
+
# The series name will be used to display chart legends.
|
|
102
|
+
# You must have at least one of these tag defined.
|
|
103
|
+
# You may also specify an array of strings to identifies the
|
|
104
|
+
# 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
|
|
107
|
+
# axis depending on the chart type. This is symmetrical
|
|
108
|
+
# to the <tt>axis_category_text</tt> tag for the opposite
|
|
109
|
+
# chart axis.
|
|
110
|
+
# <tt>:user_data</tt>:: Used to make user data available to the ERB templates in
|
|
111
|
+
# the chart stylesheet yaml file. You must specify a key symbol
|
|
112
|
+
# and an ad-hoc value. The key will be used with the @options
|
|
113
|
+
# hash to access the user data.
|
|
114
|
+
# <tt>:composites</tt>:: Embeds multiple charts within the given chart.
|
|
115
|
+
# <tt>:chart_types</tt>:: Specify the chart types per series. This option should
|
|
116
|
+
# only be used with Mixed Charts !!
|
|
117
|
+
# <tt>:theme</tt>:: Specify the use of a given theme
|
|
118
|
+
#
|
|
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
|
+
def add( *args )
|
|
122
|
+
directive = args.shift
|
|
123
|
+
case directive
|
|
124
|
+
when :axis_category_text
|
|
125
|
+
categories = args.first.is_a?(Array) ? args.shift : []
|
|
126
|
+
raise ArgumentError, "Must specify an array of categories" if categories.empty?
|
|
127
|
+
categories.insert( 0, nil )
|
|
128
|
+
@options[directive] = categories
|
|
129
|
+
when :composites
|
|
130
|
+
composites = args.first.is_a?(Array) ? args.shift: []
|
|
131
|
+
raise ArgumentError, "Must specify an array of urls for the composite chart(s)" if composites.empty?
|
|
132
|
+
@options[directive] = composites
|
|
133
|
+
when :axis_value_text
|
|
134
|
+
values = args.first.is_a?(Array) ? args.shift : []
|
|
135
|
+
raise ArgumentError, "Must specify an array of values" if values.empty?
|
|
136
|
+
@options[directive] = values
|
|
137
|
+
when :series
|
|
138
|
+
legend = args.first.is_a?(String) ? args.shift : ""
|
|
139
|
+
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?
|
|
149
|
+
when :user_data
|
|
150
|
+
key = args.first.is_a?(Symbol) ? args.shift : ""
|
|
151
|
+
raise ArgumentError, "Must specify a key" if key.to_s.empty?
|
|
152
|
+
value = args.shift
|
|
153
|
+
# raise ArgumentError, "Must specify a value" if value.empty?
|
|
154
|
+
@options[key] = value
|
|
155
|
+
when :styles
|
|
156
|
+
styles = args.first.is_a?(String) ? args.shift : ""
|
|
157
|
+
raise ArgumentError, "Must specify a set of styles" if styles.to_s.empty?
|
|
158
|
+
@options[:styles] = styles
|
|
159
|
+
when :chart_types
|
|
160
|
+
types = args.first.is_a?(Array) ? args.shift : []
|
|
161
|
+
raise ArgumentError, "Must specify a set of chart types" if types.to_s.empty?
|
|
162
|
+
@options[:chart_types] = types
|
|
163
|
+
when :theme
|
|
164
|
+
theme = args.first.is_a?(String) ? args.shift : ""
|
|
165
|
+
raise ArgumentError, "Must specify a theme name" if theme.to_s.empty?
|
|
166
|
+
@theme = "#{Ziya.themes_dir}/#{theme}"
|
|
167
|
+
else raise ArgumentError, "Invalid directive must be one of " +
|
|
168
|
+
":axis_category, :axis_value, :series, :user_data"
|
|
169
|
+
end
|
|
170
|
+
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
|
|
187
|
+
# <tt>:partial</tt>:: You can specify this option to only update parts of the charts
|
|
188
|
+
# that have actually changed. This is useful for live update and
|
|
189
|
+
# link update where you may not need to redraw the whole chart.
|
|
190
|
+
def to_s( options={} )
|
|
191
|
+
@partial = options[:partial] || false
|
|
192
|
+
@xml = Builder::XmlMarkup.new
|
|
193
|
+
@xml.chart do
|
|
194
|
+
@xml.license( @license ) unless @license.nil?
|
|
195
|
+
if !@type.nil?
|
|
196
|
+
@xml.chart_type( @type )
|
|
197
|
+
elsif @options[:chart_types].is_a? Array and ! @options[:chart_types].empty?
|
|
198
|
+
@xml.chart_type do
|
|
199
|
+
@options[:chart_types].each { |type| @xml.string( type ) }
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
setup_lnf
|
|
203
|
+
setup_series
|
|
204
|
+
end
|
|
205
|
+
@xml.to_s.gsub( /<to_s\/>/, '' )
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# -------------------------------------------------------------------------
|
|
209
|
+
# Synonym for to_s
|
|
210
|
+
alias to_xml to_s
|
|
211
|
+
|
|
212
|
+
# =========================================================================
|
|
213
|
+
private
|
|
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
|
+
# -------------------------------------------------------------------------
|
|
224
|
+
# Inflate object state based on object hierarchy
|
|
225
|
+
def setup_state( state )
|
|
226
|
+
override = self.class.name == state.class.name
|
|
227
|
+
Base.components.each do |comp|
|
|
228
|
+
instance_eval "#{comp}.merge( state.#{comp}, override ) unless state.#{comp}.nil?"
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# -------------------------------------------------------------------------
|
|
233
|
+
# Load yaml file associated with class if any
|
|
234
|
+
def inflate( clazz, theme, instance=nil )
|
|
235
|
+
class_name = underscore(clazz.to_s.gsub( /Ziya::Charts/, '' )).gsub( /\//, '' )
|
|
236
|
+
class_name += '_chart' unless class_name.match( /.?_chart$/ )
|
|
237
|
+
begin
|
|
238
|
+
file_name = "#{theme}/#{class_name}"
|
|
239
|
+
file_name = "#{theme}/#{instance}" unless instance.nil?
|
|
240
|
+
Ziya.logger.debug ">>> Ziya attempt to load style sheet file '#{file_name}"
|
|
241
|
+
yml = IO.read( "#{file_name}.yml" )
|
|
242
|
+
load = YAML::load( erb_render( yml ) )
|
|
243
|
+
Ziya.logger.info ">>> ZiYa [loading styles] -- #{file_name}.yml"
|
|
244
|
+
return load
|
|
245
|
+
rescue SystemCallError => boom
|
|
246
|
+
; # ignore if no style file...
|
|
247
|
+
rescue => bang
|
|
248
|
+
Ziya.logger.error ">>> ZiYa -- Error encountered loading file `#{file_name} -- #{bang}"
|
|
249
|
+
bang.backtrace.each { |l| Ziya.logger.error( l ) }
|
|
250
|
+
end
|
|
251
|
+
nil
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# -------------------------------------------------------------------------
|
|
255
|
+
# Parse erb template if any
|
|
256
|
+
def erb_render(fixture_content)
|
|
257
|
+
b = binding
|
|
258
|
+
ERB.new(fixture_content).result b
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# -------------------------------------------------------------------------
|
|
262
|
+
# Generates xml element for given data set
|
|
263
|
+
def gen_data_points( series_name )
|
|
264
|
+
value = @options[series_name]
|
|
265
|
+
@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?
|
|
271
|
+
end
|
|
272
|
+
else
|
|
273
|
+
@xml.string( value )
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
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
|
|
286
|
+
|
|
287
|
+
# -------------------------------------------------------------------------
|
|
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?
|
|
293
|
+
end
|
|
294
|
+
false
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# -------------------------------------------------------------------------
|
|
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?
|
|
303
|
+
end
|
|
304
|
+
0
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# -------------------------------------------------------------------------
|
|
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
|
|
326
|
+
|
|
327
|
+
# -------------------------------------------------------------------------
|
|
328
|
+
# Lay down graph data points and labels if any
|
|
329
|
+
# TODO Validate series sizes/label sizes
|
|
330
|
+
def setup_series
|
|
331
|
+
keys = @options.keys.sort { |a,b| a.to_s <=> b.to_s }
|
|
332
|
+
named_series = named_series?( keys )
|
|
333
|
+
|
|
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?
|
|
337
|
+
@xml.chart_data do
|
|
338
|
+
# Setup axis categories
|
|
339
|
+
# @options[:axis_category_text].insert( 0, nil ) if named_series
|
|
340
|
+
gen_data_points( :axis_category_text )
|
|
341
|
+
keys.each do |k|
|
|
342
|
+
gen_data_points( k ) unless k.to_s.index( 'series_' ).nil?
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
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
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
# -------------------------------------------------------------------------
|
|
370
|
+
# Walk up class hierarchy to find chart inheritance classes
|
|
371
|
+
def ancestors
|
|
372
|
+
excludes = [ "Kernel", "Object", "CommonUtils" ]
|
|
373
|
+
ancestors = self.class.ancestors.reverse
|
|
374
|
+
list = []
|
|
375
|
+
ancestors.each { |a| list << a unless excludes.include? a.to_s }
|
|
376
|
+
list
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
# -------------------------------------------------------------------------
|
|
380
|
+
# Load up look and feel data
|
|
381
|
+
def load_lnf
|
|
382
|
+
unless @partial
|
|
383
|
+
ancestors.each do |super_class|
|
|
384
|
+
if ( super_class == self.class )
|
|
385
|
+
# Load class instance prefs
|
|
386
|
+
o = inflate( super_class, theme )
|
|
387
|
+
setup_state( o ) unless o.nil?
|
|
388
|
+
# Now load instance prefs if any
|
|
389
|
+
unless id.nil?
|
|
390
|
+
o = inflate( super_class, theme, id )
|
|
391
|
+
setup_state( o ) unless o.nil?
|
|
392
|
+
end
|
|
393
|
+
else
|
|
394
|
+
o = inflate( super_class, theme, nil )
|
|
395
|
+
setup_state( o ) unless o.nil?
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
# Additional styles specified ? if so load them
|
|
400
|
+
unless @options[:styles].nil?
|
|
401
|
+
o = YAML::load( erb_render( @options[:styles] ) )
|
|
402
|
+
setup_state( o ) unless o.nil?
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# -------------------------------------------------------------------------
|
|
407
|
+
# Generates xml for look and feel data
|
|
408
|
+
def setup_lnf
|
|
409
|
+
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
|
+
unless @partial
|
|
415
|
+
Base.components.each do |comp|
|
|
416
|
+
next unless self.send( comp ).configured? # => Don't include non configured components
|
|
417
|
+
if comp == :draw
|
|
418
|
+
instance_eval "#{comp}.flatten( @xml, @options[:composites] )"
|
|
419
|
+
else
|
|
420
|
+
instance_eval "#{comp}.flatten( @xml )"
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
# -------------------------------------------------------------------------
|
|
427
|
+
def initialize_components
|
|
428
|
+
# Setup instance vars
|
|
429
|
+
Base.components.each do |comp|
|
|
430
|
+
instance_var = lambda { |v| self.instance_eval{ instance_variable_set "@#{comp}", v } }
|
|
431
|
+
instance_var.call(Ziya::Components.const_get(classify(comp)).new)
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
end
|