Class: Gruffy::Base

Inherits:
Object
  • Object
show all
Includes:
Deprecated, Magick
Defined in:
lib/gruffy/base.rb

Defined Under Namespace

Modules: StackedMixin

Constant Summary collapse

DEBUG =

Draw extra lines showing where the margins and text centers are

false
DATA_LABEL_INDEX =

Used for navigating the array of data to plot

0
DATA_VALUES_INDEX =
1
DATA_COLOR_INDEX =
2
DATA_VALUES_X_INDEX =
3
LEGEND_MARGIN =

Space around text elements. Mostly used for vertical spacing

TITLE_MARGIN = 20.0
LABEL_MARGIN =
10.0
DEFAULT_MARGIN =
20.0
DEFAULT_TARGET_WIDTH =
800
THOUSAND_SEPARATOR =
','

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Deprecated

#graph_height, #graph_left, #graph_top, #graph_width, #scale_measurements, #total_height

Constructor Details

#initialize(target_width = DEFAULT_TARGET_WIDTH) ⇒ Base

If one numerical argument is given, the graph is drawn at 4/3 ratio according to the given width (800 results in 800x600, 400 gives 400x300, etc.).

Or, send a geometry string for other ratios (‘800x400’, ‘400x225’).

Looks for Bitstream Vera as the default font. Expects an environment var of MAGICK_FONT_PATH to be set. (Uses RMagick’s default font otherwise.)



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/gruffy/base.rb', line 231

def initialize(target_width=DEFAULT_TARGET_WIDTH)
  if Numeric === target_width
    @columns = target_width.to_f
    @rows = target_width.to_f * 0.75
  else
    geometric_width, geometric_height = target_width.split('x')
    @columns = geometric_width.to_f
    @rows = geometric_height.to_f
  end

  initialize_ivars

  reset_themes
  self.theme = Themes::KEYNOTE
end

Instance Attribute Details

#additional_line_valuesObject

Experimental



190
191
192
# File 'lib/gruffy/base.rb', line 190

def additional_line_values
  @additional_line_values
end

#background_label_heightObject

Background height of picture and ignoring content



218
219
220
# File 'lib/gruffy/base.rb', line 218

def background_label_height
  @background_label_height
end

#bold_titleObject

Specifies whether to draw the title bolded or not.



126
127
128
# File 'lib/gruffy/base.rb', line 126

def bold_title
  @bold_title
end

#bottom_marginObject

Blank space below the graph



50
51
52
# File 'lib/gruffy/base.rb', line 50

def bottom_margin
  @bottom_margin
end

#center_labels_over_pointObject

Used internally for spacing.

By default, labels are centered over the point they represent.



75
76
77
# File 'lib/gruffy/base.rb', line 75

def center_labels_over_point
  @center_labels_over_point
end

#colorsObject

Get or set the list of colors that will be used to draw the bars or lines.



106
107
108
# File 'lib/gruffy/base.rb', line 106

def colors
  @colors
end

#fontObject

Font used for titles, labels, etc. Works best if you provide the full path to the TTF font file. RMagick must be built with the Freetype libraries for this to work properly.

Tries to find Bitstream Vera (Vera.ttf) in the location specified by ENV. Uses default RMagick font otherwise.

The font= method below fulfills the role of the writer, so we only need a reader here.



120
121
122
# File 'lib/gruffy/base.rb', line 120

def font
  @font
end

#font_colorObject

Returns the value of attribute font_color.



128
129
130
# File 'lib/gruffy/base.rb', line 128

def font_color
  @font_color
end

#has_left_labelsObject

Used internally for horizontal graph types.



78
79
80
# File 'lib/gruffy/base.rb', line 78

def has_left_labels
  @has_left_labels
end

#hide_legendObject

Prevent drawing of the legend



134
135
136
# File 'lib/gruffy/base.rb', line 134

def hide_legend
  @hide_legend
end

#hide_line_markersObject

Prevent drawing of line markers



131
132
133
# File 'lib/gruffy/base.rb', line 131

def hide_line_markers
  @hide_line_markers
end

#hide_line_numbersObject

Prevent drawing of line numbers



140
141
142
# File 'lib/gruffy/base.rb', line 140

def hide_line_numbers
  @hide_line_numbers
end

#hide_titleObject

Prevent drawing of the title



137
138
139
# File 'lib/gruffy/base.rb', line 137

def hide_title
  @hide_title
end

#label_formattingObject

Set the number output format for labels using sprintf Default is “%.2f”



207
208
209
# File 'lib/gruffy/base.rb', line 207

def label_formatting
  @label_formatting
end

#label_max_sizeObject

Truncates labels if longer than max specified



96
97
98
# File 'lib/gruffy/base.rb', line 96

def label_max_size
  @label_max_size
end

#label_rotationObject

Set label rotation Default 0



211
212
213
# File 'lib/gruffy/base.rb', line 211

def label_rotation
  @label_rotation
end

#label_stagger_heightObject

Height of staggering between labels (Bar graph only)



93
94
95
# File 'lib/gruffy/base.rb', line 93

def label_stagger_height
  @label_stagger_height
end

#label_truncation_styleObject

How truncated labels visually appear if they exceed label_max_size :absolute - does not show trailing dots to indicate truncation. This is

the default.

:trailing_dots - shows trailing dots to indicate truncation (note

that label_max_size must be greater than 3).


103
104
105
# File 'lib/gruffy/base.rb', line 103

def label_truncation_style
  @label_truncation_style
end

#label_y_axisObject

Position of label Y axis Default 0



215
216
217
# File 'lib/gruffy/base.rb', line 215

def label_y_axis
  @label_y_axis
end

#labelsObject

A hash of names for the individual columns, where the key is the array index for the column this label represents.

Not all columns need to be named.

Example: 0 => 2005, 3 => 2006, 5 => 2007, 7 => 2008



70
71
72
# File 'lib/gruffy/base.rb', line 70

def labels
  @labels
end

#left_marginObject

Blank space to the left of the graph



56
57
58
# File 'lib/gruffy/base.rb', line 56

def left_margin
  @left_margin
end

#legend_at_bottomObject

Display the legend under the graph



156
157
158
# File 'lib/gruffy/base.rb', line 156

def legend_at_bottom
  @legend_at_bottom
end

#legend_box_sizeObject

Optionally set the size of the colored box by each item in the legend. Default is 20.0

Will be scaled down if graph is smaller than 800px wide.



199
200
201
# File 'lib/gruffy/base.rb', line 199

def legend_box_size
  @legend_box_size
end

#legend_font_sizeObject

Optionally set the size of the font. Based on an 800x600px graph. Default is 20.

Will be scaled down if the graph is smaller than 800px wide.



153
154
155
# File 'lib/gruffy/base.rb', line 153

def legend_font_size
  @legend_font_size
end

#legend_marginObject

Blank space below the legend



62
63
64
# File 'lib/gruffy/base.rb', line 62

def legend_margin
  @legend_margin
end

#marker_colorObject

The color of the auxiliary lines



162
163
164
# File 'lib/gruffy/base.rb', line 162

def marker_color
  @marker_color
end

#marker_countObject

The number of horizontal lines shown for reference



166
167
168
# File 'lib/gruffy/base.rb', line 166

def marker_count
  @marker_count
end

#marker_font_sizeObject

The font size of the labels around the graph



159
160
161
# File 'lib/gruffy/base.rb', line 159

def marker_font_size
  @marker_font_size
end

#marker_shadow_colorObject

Returns the value of attribute marker_shadow_color.



163
164
165
# File 'lib/gruffy/base.rb', line 163

def marker_shadow_color
  @marker_shadow_color
end

#maximum_valueObject

You can manually set a maximum value, such as a percentage-based graph that always goes to 100.

If you use this, you must set it after you have given all your data to the graph object.



179
180
181
# File 'lib/gruffy/base.rb', line 179

def maximum_value
  @maximum_value
end

#minimum_valueObject

You can manually set a minimum value instead of having the values guessed for you.

Set it after you have given all your data to the graph object.



172
173
174
# File 'lib/gruffy/base.rb', line 172

def minimum_value
  @minimum_value
end

#no_data_messageObject

Message shown when there is no data. Fits up to 20 characters. Defaults to “No Data.”



144
145
146
# File 'lib/gruffy/base.rb', line 144

def no_data_message
  @no_data_message
end

#right_marginObject

Blank space to the right of the graph



53
54
55
# File 'lib/gruffy/base.rb', line 53

def right_margin
  @right_margin
end

#show_labels_for_bar_valuesObject

Output the values for the bars on a bar graph Default is false



203
204
205
# File 'lib/gruffy/base.rb', line 203

def show_labels_for_bar_values
  @show_labels_for_bar_values
end

#sortObject

Set to true if you want the data sets sorted with largest avg values drawn first.



183
184
185
# File 'lib/gruffy/base.rb', line 183

def sort
  @sort
end

#sorted_drawingObject

Set to true if you want the data sets drawn with largest avg values drawn first. This does not affect the legend.



187
188
189
# File 'lib/gruffy/base.rb', line 187

def sorted_drawing
  @sorted_drawing
end

#stackedObject

Experimental



193
194
195
# File 'lib/gruffy/base.rb', line 193

def stacked
  @stacked
end

#titleObject

The large title of the graph displayed at the top



109
110
111
# File 'lib/gruffy/base.rb', line 109

def title
  @title
end

#title_fontObject

Same as font but for the title.



123
124
125
# File 'lib/gruffy/base.rb', line 123

def title_font
  @title_font
end

#title_font_sizeObject

The font size of the large title at the top of the graph



147
148
149
# File 'lib/gruffy/base.rb', line 147

def title_font_size
  @title_font_size
end

#title_marginObject

Blank space below the title



59
60
61
# File 'lib/gruffy/base.rb', line 59

def title_margin
  @title_margin
end

#top_marginObject

Blank space above the graph



47
48
49
# File 'lib/gruffy/base.rb', line 47

def top_margin
  @top_margin
end

#use_data_labelObject

With Side Bars use the data label for the marker value to the left of the bar Default is false



222
223
224
# File 'lib/gruffy/base.rb', line 222

def use_data_label
  @use_data_label
end

#x_axis_incrementObject

Manually set increment of the vertical marking lines



87
88
89
# File 'lib/gruffy/base.rb', line 87

def x_axis_increment
  @x_axis_increment
end

#x_axis_labelObject

A label for the bottom of the graph



81
82
83
# File 'lib/gruffy/base.rb', line 81

def x_axis_label
  @x_axis_label
end

#y_axis_incrementObject

Manually set increment of the horizontal marking lines



90
91
92
# File 'lib/gruffy/base.rb', line 90

def y_axis_increment
  @y_axis_increment
end

#y_axis_labelObject

A label for the left side of the graph



84
85
86
# File 'lib/gruffy/base.rb', line 84

def y_axis_label
  @y_axis_label
end

Instance Method Details

#add_color(colorname) ⇒ Object

Add a color to the list of available colors for lines.

Example:

add_color('#c0e9d3')


325
326
327
# File 'lib/gruffy/base.rb', line 325

def add_color(colorname)
  @colors << colorname
end

#data(name, data_points = [], color = nil) ⇒ Object

Parameters are an array where the first element is the name of the dataset and the value is an array of values to plot.

Can be called multiple times with different datasets for a multi-valued graph.

If the color argument is nil, the next color from the default theme will be used.

NOTE: If you want to use a preset theme, you must set it before calling data().

Example:

data("Bart S.", [95, 45, 78, 89, 88, 76], '#ffcc00')


423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/gruffy/base.rb', line 423

def data(name, data_points=[], color=nil)
  data_points = Array(data_points) # make sure it's an array
  @data << [name, data_points, color]
                                   # Set column count if this is larger than previous counts
  @column_count = (data_points.length > @column_count) ? data_points.length : @column_count

  # Pre-normalize
  data_points.each do |data_point|
    next if data_point.nil?

    # Setup max/min so spread starts at the low end of the data points
    if @maximum_value.nil? && @minimum_value.nil?
      @maximum_value = @minimum_value = data_point
    end

    # TODO Doesn't work with stacked bar graphs
    # Original: @maximum_value = larger_than_max?(data_point, index) ? max(data_point, index) : @maximum_value
    @maximum_value = larger_than_max?(data_point) ? data_point : @maximum_value
    @has_data = true if @maximum_value >= 0

    @minimum_value = less_than_min?(data_point) ? data_point : @minimum_value
    @has_data = true if @minimum_value < 0
  end
end

#initialize_ivarsObject

Set instance variables for this object.

Subclasses can override this, call super, then set values separately.

This makes it possible to set defaults in a subclass but still allow developers to change this values in their program.



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
278
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
# File 'lib/gruffy/base.rb', line 253

def initialize_ivars
  # Internal for calculations
  @raw_columns = 800.0
  @raw_rows = 800.0 * (@rows/@columns)
  @background_label_height = 0
  @label_y_axis = 0
  @column_count = 0
  @data = Array.new
  @marker_count = nil
  @maximum_value = @minimum_value = nil
  @has_data = false
  @increment = nil
  @labels = Hash.new
  @label_formatting = nil
  @labels_seen = Hash.new
  @sort = false
  @sorted_drawing = false
  @title = nil
  @title_font = nil

  @scale = @columns / @raw_columns

  vera_font_path = File.expand_path('Vera.ttf', ENV['MAGICK_FONT_PATH'])
  @font = File.exist?(vera_font_path) ? vera_font_path : nil
  @bold_title = true

  @marker_font_size = 21.0
  @legend_font_size = 20.0
  @title_font_size = 36.0

  @top_margin = @bottom_margin = @left_margin = @right_margin = DEFAULT_MARGIN
  @legend_margin = LEGEND_MARGIN
  @title_margin = TITLE_MARGIN

  @legend_box_size = 20.0

  @no_data_message = 'No Data'

  @hide_line_markers = @hide_legend = @hide_title = @hide_line_numbers = @legend_at_bottom = @show_labels_for_bar_values = false
  @center_labels_over_point = true
  @has_left_labels = false
  @label_stagger_height = 0
  @label_max_size = 0
  @label_truncation_style = :absolute

  @additional_line_values = []
  @additional_line_colors = []
  @theme_options = {}

  @use_data_label = false
  @x_axis_increment = nil
  @x_axis_label = @y_axis_label = nil
  @y_axis_increment = nil
  @stacked = nil
  @norm_data = nil
end

#margins=(margin) ⇒ Object

Sets the top, bottom, left and right margins to margin.



311
312
313
# File 'lib/gruffy/base.rb', line 311

def margins=(margin)
  @top_margin = @left_margin = @right_margin = @bottom_margin = margin
end

#replace_colors(color_list = []) ⇒ Object

Replace the entire color list with a new array of colors. Also aliased as the colors= setter method.

If you specify fewer colors than the number of datasets you intend to draw, ‘increment_color’ will cycle through the array, reusing colors as needed.

Note that (as with the ‘theme’ method), you should set up your color list before you send your data (via the ‘data’ method). Calls to the ‘data’ method made prior to this call will use whatever color scheme was in place at the time data was called.

Example:

replace_colors ['#cc99cc', '#d9e043', '#34d8a2']


343
344
345
346
# File 'lib/gruffy/base.rb', line 343

def replace_colors(color_list=[])
  @colors = color_list
  @color_index = 0
end

#theme=(options) ⇒ Object

You can set a theme manually. Assign a hash to this method before you send your data.

graph.theme = {
  :colors => %w(orange purple green white red),
  :marker_color => 'blue',
  :background_colors => ['black', 'grey', :top_bottom]
}

:background_image => ‘squirrel.png’ is also possible.

(Or hopefully something better looking than that.)



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/gruffy/base.rb', line 361

def theme=(options)
  reset_themes

  defaults = {
      :colors => %w(black white),
      :additional_line_colors => [],
      :marker_color => 'white',
      :marker_shadow_color => nil,
      :font_color => 'black',
      :background_colors => nil,
      :background_image => nil
  }
  @theme_options = defaults.merge options

  @colors = @theme_options[:colors]
  @marker_color = @theme_options[:marker_color]
  @marker_shadow_color = @theme_options[:marker_shadow_color]
  @font_color = @theme_options[:font_color] || @marker_color
  @additional_line_colors = @theme_options[:additional_line_colors]
  @background_label_height = @labels.values.sort_by {|v| v.size }.last.size rescue @background_label_height

  render_background
end

#theme_37signalsObject



389
390
391
# File 'lib/gruffy/base.rb', line 389

def theme_37signals
  self.theme = Themes::THIRTYSEVEN_SIGNALS
end

#theme_greyscaleObject



405
406
407
# File 'lib/gruffy/base.rb', line 405

def theme_greyscale
  self.theme = Themes::GREYSCALE
end

#theme_keynoteObject



385
386
387
# File 'lib/gruffy/base.rb', line 385

def theme_keynote
  self.theme = Themes::KEYNOTE
end

#theme_odeoObject



397
398
399
# File 'lib/gruffy/base.rb', line 397

def theme_odeo
  self.theme = Themes::ODEO
end

#theme_pastelObject



401
402
403
# File 'lib/gruffy/base.rb', line 401

def theme_pastel
  self.theme = Themes::PASTEL
end

#theme_rails_keynoteObject



393
394
395
# File 'lib/gruffy/base.rb', line 393

def theme_rails_keynote
  self.theme = Themes::RAILS_KEYNOTE
end

#to_blob(fileformat = 'PNG') ⇒ Object

Return the graph as a rendered binary blob.



458
459
460
461
462
463
# File 'lib/gruffy/base.rb', line 458

def to_blob(fileformat='PNG')
  draw
  @base_image.to_blob do
    self.format = fileformat
  end
end

#write(filename = 'graph.png') ⇒ Object

Writes the graph to a file. Defaults to ‘graph.png’

Example:

write('graphs/my_pretty_graph.png')


452
453
454
455
# File 'lib/gruffy/base.rb', line 452

def write(filename='graph.png')
  draw
  @base_image.write(filename)
end