Class: Hirb::Helpers::Table::Resizer

Inherits:
Object
  • Object
show all
Defined in:
lib/hirb/helpers/table/resizer.rb

Overview

Resizes a table’s fields to the table’s max width.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(table) ⇒ Resizer

Returns a new instance of Resizer.



13
14
15
16
17
# File 'lib/hirb/helpers/table/resizer.rb', line 13

def initialize(table)
  @table, @width, @field_size = table, table.actual_width, table.fields.size
  @field_lengths = table.field_lengths
  @original_field_lengths = @field_lengths.dup
end

Instance Attribute Details

#field_lengthsObject (readonly)

:stopdoc:



12
13
14
# File 'lib/hirb/helpers/table/resizer.rb', line 12

def field_lengths
  @field_lengths
end

Class Method Details

.resize!(table) ⇒ Object

Modifies field_lengths to fit within width. Also enforces a table’s max_fields.



5
6
7
8
9
# File 'lib/hirb/helpers/table/resizer.rb', line 5

def self.resize!(table)
  obj = new(table)
  obj.resize
  obj.field_lengths
end

Instance Method Details

#add_extra_widthObject



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/hirb/helpers/table/resizer.rb', line 56

def add_extra_width
  added_width = 0
  extra_width = @width - sum(@field_lengths.values)
  unmaxed_fields = @field_lengths.keys.select {|f| !remaining_width(f).zero? }
  # order can affect which one gets the remainder so let's keep it consistent
  unmaxed_fields = unmaxed_fields.sort_by {|e| e.to_s}

  unmaxed_fields.each_with_index do |f, i|
    extra_per_field = (extra_width - added_width) / (unmaxed_fields.size - i)
    add_to_field = remaining_width(f) < extra_per_field ? remaining_width(f) : extra_per_field
    added_width += add_to_field
    @field_lengths[f] += add_to_field
  end
end

#adjust_long_fieldsObject

Simple algorithm which allows smaller fields to be displayed while restricting longer fields to an average_long_field



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/hirb/helpers/table/resizer.rb', line 27

def adjust_long_fields
  while (total_length = sum(@field_lengths.values)) > @width
    average_field = total_length / @field_size.to_f
    long_lengths = @field_lengths.values.select {|e| e > average_field }
    return false if long_lengths.empty?

    # adjusts average long field by ratio with @width
    average_long_field = sum(long_lengths)/long_lengths.size * @width/total_length
    @field_lengths.each {|f,length|
      @field_lengths[f] = average_long_field if length > average_long_field
    }
  end
  true
end

#default_restrict_field_lengthsObject

Produces a field_lengths which meets the @width requirement



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/hirb/helpers/table/resizer.rb', line 43

def default_restrict_field_lengths
  original_total_length = sum @original_field_lengths.values
  # set fields by their relative weight to original length
  new_lengths = @original_field_lengths.inject({}) {|t,(k,v)|
    t[k] = (v / original_total_length.to_f * @width).to_i; t  }

  # set all fields the same if relative doesn't work
  unless new_lengths.values.all? {|e| e > MIN_FIELD_LENGTH} && (sum(new_lengths.values) <= @width)
    new_lengths = @field_lengths.inject({}) {|t,(k,v)| t[k] = @width / @field_size; t }
  end
  @field_lengths.each {|k,v| @field_lengths[k] = new_lengths[k] }
end

#remaining_width(field) ⇒ Object



71
72
73
74
75
# File 'lib/hirb/helpers/table/resizer.rb', line 71

def remaining_width(field)
  (@remaining_width ||= {})[field] ||= begin
    (@table.max_fields[field] || @original_field_lengths[field]) - @field_lengths[field]
  end
end

#resizeObject



19
20
21
22
23
# File 'lib/hirb/helpers/table/resizer.rb', line 19

def resize
  adjust_long_fields || default_restrict_field_lengths
  @table.enforce_field_constraints
  add_extra_width
end

#sum(arr) ⇒ Object



77
78
79
# File 'lib/hirb/helpers/table/resizer.rb', line 77

def sum(arr)
  arr.inject {|t,e| t += e } || 0
end