Class: BaseChart

Inherits:
Object
  • Object
show all
Defined in:
lib/libisi/chart/base.rb

Overview

Copyright © 2007-2010 Logintas AG Switzerland

This file is part of Libisi.

Libisi is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Libisi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Libisi. If not, see <www.gnu.org/licenses/>.

Direct Known Subclasses

JfreechartChart

Constant Summary collapse

BAR_TYPES =
[:bar, :pie, :gantt, :xy]
DEFAULT_HEIGHT =
480
DEFAULT_WIDTH =
640
DEFAULT_STACKED =
false
DEFAULT_CHART_TYPE =
:bar
DEFAULT_LEGEND_ROTATION =

Math::PI / 6.0

0.0
DEFAULT_LEGEND_CHART_RATIO =
0.4

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ BaseChart

Returns a new instance of BaseChart.



31
32
33
34
35
36
37
38
39
# File 'lib/libisi/chart/base.rb', line 31

def initialize(options = {})
  @height =  DEFAULT_HEIGHT
  @width  =  DEFAULT_WIDTH
  @stacked = DEFAULT_STACKED
  @legend_chart_ratio = DEFAULT_LEGEND_CHART_RATIO
  @options = options
  @options ||= {}
  @axes = []
end

Instance Attribute Details

#heightObject

Returns the value of attribute height.



22
23
24
# File 'lib/libisi/chart/base.rb', line 22

def height
  @height
end

#legend_chart_ratioObject

Returns the value of attribute legend_chart_ratio.



22
23
24
# File 'lib/libisi/chart/base.rb', line 22

def legend_chart_ratio
  @legend_chart_ratio
end

#legend_rotationObject

Returns the value of attribute legend_rotation.



22
23
24
# File 'lib/libisi/chart/base.rb', line 22

def legend_rotation
  @legend_rotation
end

#stackedObject

Returns the value of attribute stacked.



22
23
24
# File 'lib/libisi/chart/base.rb', line 22

def stacked
  @stacked
end

#titleObject

Returns the value of attribute title.



22
23
24
# File 'lib/libisi/chart/base.rb', line 22

def title
  @title
end

#typeObject

Returns the value of attribute type.



22
23
24
# File 'lib/libisi/chart/base.rb', line 22

def type
  @type
end

#widthObject

Returns the value of attribute width.



22
23
24
# File 'lib/libisi/chart/base.rb', line 22

def width
  @width
end

Instance Method Details

#create_chart(type = nil, options = {}) ⇒ Object



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/libisi/chart/base.rb', line 279

def create_chart(type = nil, options = {})
  t = (type or @type or DEFAULT_CHART_TYPE)
  
  case options[:combined_axis]
  when nil, :x, "x",:xaxis, "xaxis", :domain, "domain"
    options[:combined_axis] = :domain
  when nil, :y, "y",:yaxis, "yaxis", :range, "range"
    options[:combined_axis] = :range
  else
    raise "Unexpected combined axis option: #{options[:combined_axis].inspect}"
  end
  
  case t
  when :bar, :line, :gantt, :pie
    plot = nil
    case data_dimension
    when 4
	plot = create_combined_plot(@ranges, options[:combined_axis])
    when 3
	plot = create_plot(nil,@ranges.values[0])
    else
	raise "Unexpected data dimension #{data_dimension}"
    end
    
    create_chart_implementation(plot)
    return @chart
  when :xy
    raise "Not implemented yet chart type #{t}"
  else
    raise "Unknown chart type #{t}"
  end    
end

#create_combined_plot(data, combination_axis = :category) ⇒ Object



312
313
314
# File 'lib/libisi/chart/base.rb', line 312

def create_combined_plot(data, combination_axis = :category)
  create_combined_plot_implementation(data,combination_axis)
end

#create_plot(name, data) ⇒ Object



316
317
318
# File 'lib/libisi/chart/base.rb', line 316

def create_plot(name, data)
  create_plot_implementation(name,data)
end

#data_dimensionObject



208
209
210
211
212
213
214
215
# File 'lib/libisi/chart/base.rb', line 208

def data_dimension
  # RANGE x SERIE x CATEGORY x ARRAY
  return 0 unless @ranges
  return 4 if @ranges.keys.length > 1
  return 3 if @ranges[0].nil? or @ranges[0].keys > 1
  return 2 if @ranges[0][0].nil? or @ranges[0][0].keys > 1
  return 1
end

#display_legendObject



41
# File 'lib/libisi/chart/base.rb', line 41

def display_legend; data_dimension > 1; end

#enable_tooltipsObject



43
# File 'lib/libisi/chart/base.rb', line 43

def enable_tooltips; true; end

#enable_urlsObject



42
# File 'lib/libisi/chart/base.rb', line 42

def enable_urls; false; end

#load(input) ⇒ Object

old fashioned loading from alois



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/libisi/chart/base.rb', line 218

def load(input)
  input = input.split("\n").reverse
  #	System.out.println("Chart title?");
  @title = input.pop
  
  #	System.out.println("Width?");
  @options[:width] = input.pop.to_i

  #	System.out.println("Height?");
  @options[:height] = input.pop.to_i

  #	System.out.println("X-Axis?");
  @axes = []
  @axes[0] = input.pop
  
  #	System.out.println("Y-Axis?");
  @axes[1] = input.pop
  
  #	System.out.println("Series count?");
  serie_count = input.pop.to_i

  #	System.out.println("Range count?");
  range_count = input.pop.to_i
  	  
  @ranges = OrderedHash.new
  range_count.times {|range|
    range_name = input.pop
    range_name = nil if range_name == "<<NULL>>"
    
    current_range = OrderedHash.new
    @ranges[range_name] = current_range
    
    serie_count.times {|serie|
	serie_name =  input.pop
	serie_name = nil if serie_name == "<<NULL>>"
	$log.debug("Serie name: #{category_name}")
	
	current_serie = OrderedHash.new(serie_name)
	current_range[serie_name] = current_serie
	
	rowCount = input.pop.to_i
	columnCount = input.pop.to_i
	
	rowCount.times {|row|
 category_name = input.pop
 category_name = nil if category_name == "<<NULL>>"
 $log.debug("Category name: #{category_name}")
 
 current_category = []
 current_serie[category_name] = current_category
 
 columnCount.times {|col|
   current_category << input.pop
 }
	}
    }
  }


end

#mark(name, from = nil, to = nil, options = {}) ⇒ Object Also known as: marker

markers



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/libisi/chart/base.rb', line 82

def mark(name, from = nil, to = nil, options = {})
  raise "Marker value may not be nil" if 
    from.nil? and !block_given?
  if to.class == Hash
    options = to 
    to = nil
  end
    
  if name.class == Hash
    options = name
    name = nil
  end

  options ||= {}
  options = options.dup
 
  if from.nil?
    options[:type] = :category
    options[:key] = name
  else 
    if to.nil?
	options[:type] = :value
	options[:value] = from
    else
	options[:type] = :interval
	options[:start] = from
	options[:end] = to
    end
  end
  options[:name] = name

  if block_given?      
    # this is a domain marker
    # add all values that has been added
    # yield
    options[:axis] = :domain
    previous_keys = @current_serie.keys.dup
    yield
    current_keys = @current_serie.keys.dup
    new_keys = current_keys.reject {|k| previous_keys.include?(k)}
    
    @current_range_options[:markers] ||= []
    new_keys.each {|k|
	o = options.dup
	o[:key] = k
	@current_range_options[:markers] << o
    }
  else
    options[:axis] = :range
    add_to = @options
    add_to = @current_range_options if @current_range_options
    
    add_to[:markers] ||= []
    add_to[:markers] << options   
  end
end

#orientationObject



44
45
46
47
48
49
50
51
# File 'lib/libisi/chart/base.rb', line 44

def orientation
  return @orientation if @orientation
  if @type == :gantt
    :horizontal
  else
    :vertical
  end
end

#range(name = nil, options = {}) ⇒ Object

Adding values



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/libisi/chart/base.rb', line 141

def range(name = nil, options = {})
  @range_options ||= {}
  @ranges ||= OrderedHash.new        

  raise "Range #{name.inspect} already exist" unless 
    @ranges[name].nil?

  @range_options[name] = options
  @current_range_options = @range_options[name]

  @current_range = OrderedHash.new
  @ranges[name] = @current_range
  yield
  @current_range = nil
end

#rangesObject



69
70
71
# File 'lib/libisi/chart/base.rb', line 69

def ranges
  @ranges
end

#save(filename, options = {}) ⇒ Object

data



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/libisi/chart/base.rb', line 55

def save(filename, options = {})
  create_chart unless @chart
  case filename
  when /.html$/
    Pathname.new(filename).open("w") {|f|
	f.write(data("text/html",options))
    }
  when /.png$/
    Pathname.new(filename).open("w") {|f| f.write(data("image/png",options))}
  else
    raise "Dont know how to save to file #{filename}"
  end
end

#serie(name = nil, options = {}) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/libisi/chart/base.rb', line 157

def serie(name = nil, options = {})
  unless @current_range
    range {
	return serie(name) {
 yield
	}
    }
  end

  @series_options ||= {}
  @series_options[name] = {}

  @current_serie = OrderedHash.new
  @current_range[name] = @current_serie
  yield
  @current_serie = nil
end

#time_span(name, start_time, end_time, options = {}) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/libisi/chart/base.rb', line 179

def time_span(name, start_time, end_time, options = {})   
  raise "No current serie." unless @current_serie
  @type ||= :gantt
  raise "No time_spans allowed for chart type #{@type}" unless
    @type == :gantt

  new_span = {:start => start_time, :end => end_time}
  new_span[:percentage] = options[:percentage] if options[:percentage]

  old_span = @current_timespan
  if @current_timespan
    # ok, we are already in a timespan block
    # add children
    @current_timespan[:children] ||= OrderedHash.new
    raise "There is already a timespan called #{name.inspect}" if
	@current_timespan[:children][name]
    @current_timespan[:children][name] = new_span 
  else
    @current_timespan = new_span
    raise "There is already a timespan called #{name.inspect}" if
	@current_serie[name]
    @current_serie[name] = @current_timespan
  end
  
  yield if block_given?
  @current_timespan = old_span
  new_span
end

#value(name, value) ⇒ Object



175
176
177
# File 'lib/libisi/chart/base.rb', line 175

def value(name, value)
  @current_serie[name] = value
end

#xaxisObject

axes



74
# File 'lib/libisi/chart/base.rb', line 74

def xaxis; @axes[0]; end

#xaxis=(val) ⇒ Object



75
# File 'lib/libisi/chart/base.rb', line 75

def xaxis=(val); @axes[0] = val; end

#yaxisObject



76
# File 'lib/libisi/chart/base.rb', line 76

def yaxis; @axes[1]; end

#yaxis=(val) ⇒ Object



77
# File 'lib/libisi/chart/base.rb', line 77

def yaxis=(val); @axes[1] = val; end

#zaxisObject



78
# File 'lib/libisi/chart/base.rb', line 78

def zaxis; @axes[2]; end

#zaxis=(val) ⇒ Object



79
# File 'lib/libisi/chart/base.rb', line 79

def zaxis=(val); @axes[2] = val; end