Class: Gruff::Base

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

Direct Known Subclasses

Area, Bar, Bullet, Dot, Line, Net, PhotoBar, Pie, Scene, SideBar, Spider, StackedArea, StackedBar

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



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/gruff/base.rb', line 182

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

  initialize_ivars

  reset_themes
  theme_keynote
end

Instance Attribute Details

#additional_line_valuesObject

Experimental



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

def additional_line_values
  @additional_line_values
end

#bottom_marginObject

Blank space below the graph



51
52
53
# File 'lib/gruff/base.rb', line 51

def bottom_margin
  @bottom_margin
end

#center_labels_over_pointObject

Used internally for spacing.

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



76
77
78
# File 'lib/gruff/base.rb', line 76

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.



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

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.



107
108
109
# File 'lib/gruff/base.rb', line 107

def font
  @font
end

#font_colorObject

Returns the value of attribute font_color.



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

def font_color
  @font_color
end

#has_left_labelsObject

Used internally for horizontal graph types.



79
80
81
# File 'lib/gruff/base.rb', line 79

def has_left_labels
  @has_left_labels
end

#hide_legendObject

Prevent drawing of the legend



115
116
117
# File 'lib/gruff/base.rb', line 115

def hide_legend
  @hide_legend
end

#hide_line_markersObject

Prevent drawing of line markers



112
113
114
# File 'lib/gruff/base.rb', line 112

def hide_line_markers
  @hide_line_markers
end

#hide_line_numbersObject

Prevent drawing of line numbers



121
122
123
# File 'lib/gruff/base.rb', line 121

def hide_line_numbers
  @hide_line_numbers
end

#hide_titleObject

Prevent drawing of the title



118
119
120
# File 'lib/gruff/base.rb', line 118

def hide_title
  @hide_title
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



71
72
73
# File 'lib/gruff/base.rb', line 71

def labels
  @labels
end

#left_marginObject

Blank space to the left of the graph



57
58
59
# File 'lib/gruff/base.rb', line 57

def left_margin
  @left_margin
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.



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

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 graph is smaller than 800px wide.



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

def legend_font_size
  @legend_font_size
end

#legend_marginObject

Blank space below the legend



63
64
65
# File 'lib/gruff/base.rb', line 63

def legend_margin
  @legend_margin
end

#marker_colorObject

The color of the auxiliary lines



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

def marker_color
  @marker_color
end

#marker_countObject

The number of horizontal lines shown for reference



143
144
145
# File 'lib/gruff/base.rb', line 143

def marker_count
  @marker_count
end

#marker_font_sizeObject

The font size of the labels around the graph



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

def marker_font_size
  @marker_font_size
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.



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

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.



149
150
151
# File 'lib/gruff/base.rb', line 149

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



125
126
127
# File 'lib/gruff/base.rb', line 125

def no_data_message
  @no_data_message
end

#right_marginObject

Blank space to the right of the graph



54
55
56
# File 'lib/gruff/base.rb', line 54

def right_margin
  @right_margin
end

#sortObject

Set to false if you don’t want the data to be sorted with largest avg values at the back.



160
161
162
# File 'lib/gruff/base.rb', line 160

def sort
  @sort
end

#stackedObject

Experimental



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

def stacked
  @stacked
end

#titleObject

The large title of the graph displayed at the top



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

def title
  @title
end

#title_font_sizeObject

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



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

def title_font_size
  @title_font_size
end

#title_marginObject

Blank space below the title



60
61
62
# File 'lib/gruff/base.rb', line 60

def title_margin
  @title_margin
end

#top_marginObject

Blank space above the graph



48
49
50
# File 'lib/gruff/base.rb', line 48

def top_margin
  @top_margin
end

#x_axis_labelObject

A label for the bottom of the graph



82
83
84
# File 'lib/gruff/base.rb', line 82

def x_axis_label
  @x_axis_label
end

#y_axis_incrementObject

Manually set increment of the horizontal marking lines



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

def y_axis_increment
  @y_axis_increment
end

#y_axis_labelObject

A label for the left side of the graph



85
86
87
# File 'lib/gruff/base.rb', line 85

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')


264
265
266
# File 'lib/gruff/base.rb', line 264

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')


457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/gruff/base.rb', line 457

def data(name, data_points=[], color=nil)
  data_points = Array(data_points) # make sure it's an array
  @data << [name, data_points, (color || increment_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_with_index do |data_point, index|
    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.



204
205
206
207
208
209
210
211
212
213
214
215
216
217
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
# File 'lib/gruff/base.rb', line 204

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

  @scale = @columns / @raw_columns

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

  @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 = false
  @center_labels_over_point = true
  @has_left_labels = false

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

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



250
251
252
# File 'lib/gruff/base.rb', line 250

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']


282
283
284
285
# File 'lib/gruff/base.rb', line 282

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 => %w(black grey)
}

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

(Or hopefully something better looking than that.)



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/gruff/base.rb', line 300

def theme=(options)
  reset_themes()

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

  @colors = @theme_options[:colors]
  @marker_color = @theme_options[:marker_color]
  @font_color = @theme_options[:font_color] || @marker_color
  @additional_line_colors = @theme_options[:additional_line_colors]

  render_background
end

#theme_37signalsObject

A color scheme plucked from the colors on the popular usability blog.



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/gruff/base.rb', line 342

def theme_37signals
  # Colors
  @green = '#339933'
  @purple = '#cc99cc'
  @blue = '#336699'
  @yellow = '#FFF804'
  @red = '#ff0000'
  @orange = '#cf5910'
  @black = 'black'
  @colors = [@yellow, @blue, @green, @red, @purple, @orange, @black]

  self.theme = {
    :colors => @colors,
    :marker_color => 'black',
    :font_color => 'black',
    :background_colors => ['#d1edf5', 'white']
  }
end

#theme_greyscaleObject

A greyscale theme



424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# File 'lib/gruff/base.rb', line 424

def theme_greyscale
  # Colors
  @colors = [
             '#282828', #
             '#383838', #
             '#686868', #
             '#989898', #
             '#c8c8c8', #
             '#e8e8e8', #
            ]

  self.theme = {
    :colors => @colors,
    :marker_color => '#aea9a9', # Grey
    :font_color => 'black',
    :background_colors => 'white'
  }
end

#theme_keynoteObject

A color scheme similar to the popular presentation software.



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/gruff/base.rb', line 322

def theme_keynote
  # Colors
  @blue = '#6886B4'
  @yellow = '#FDD84E'
  @green = '#72AE6E'
  @red = '#D1695E'
  @purple = '#8A6EAF'
  @orange = '#EFAA43'
  @white = 'white'
  @colors = [@yellow, @blue, @green, @red, @purple, @orange, @white]

  self.theme = {
    :colors => @colors,
    :marker_color => 'white',
    :font_color => 'white',
    :background_colors => ['black', '#4a465a']
  }
end

#theme_odeoObject

A color scheme similar to that used on the popular podcast site.



383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/gruff/base.rb', line 383

def theme_odeo
  # Colors
  @grey = '#202020'
  @white = 'white'
  @dark_pink = '#a21764'
  @green = '#8ab438'
  @light_grey = '#999999'
  @dark_blue = '#3a5b87'
  @black = 'black'
  @colors = [@grey, @white, @dark_blue, @dark_pink, @green, @light_grey, @black]

  self.theme = {
    :colors => @colors,
    :marker_color => 'white',
    :font_color => 'white',
    :background_colors => ['#ff47a4', '#ff1f81']
  }
end

#theme_pastelObject

A pastel theme



403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'lib/gruff/base.rb', line 403

def theme_pastel
  # Colors
  @colors = [
             '#a9dada', # blue
             '#aedaa9', # green
             '#daaea9', # peach
             '#dadaa9', # yellow
             '#a9a9da', # dk purple
             '#daaeda', # purple
             '#dadada' # grey
            ]

  self.theme = {
    :colors => @colors,
    :marker_color => '#aea9a9', # Grey
    :font_color => 'black',
    :background_colors => 'white'
  }
end

#theme_rails_keynoteObject

A color scheme from the colors used on the 2005 Rails keynote presentation at RubyConf.



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

def theme_rails_keynote
  # Colors
  @green = '#00ff00'
  @grey = '#333333'
  @orange = '#ff5d00'
  @red = '#f61100'
  @white = 'white'
  @light_grey = '#999999'
  @black = 'black'
  @colors = [@green, @grey, @orange, @red, @white, @light_grey, @black]

  self.theme = {
    :colors => @colors,
    :marker_color => 'white',
    :font_color => 'white',
    :background_colors => ['#0083a3', '#0083a3']
  }
end

#to_blob(fileformat = 'PNG') ⇒ Object

Return the graph as a rendered binary blob.



492
493
494
495
496
497
# File 'lib/gruff/base.rb', line 492

def to_blob(fileformat='PNG')
  draw()
  return @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')


486
487
488
489
# File 'lib/gruff/base.rb', line 486

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