Class: Comparison::Presenter

Inherits:
Comparator show all
Includes:
ActionView::Helpers::TranslationHelper
Defined in:
lib/comparison/presenter.rb

Overview

The Presenter object wraps a Comparator with methods that return view-friendly output.

Constant Summary collapse

ARROWS =
{ positive: '↑', negative: '↓', nochange: '' }.freeze

Instance Attribute Summary

Attributes inherited from Comparator

#other, #value

Instance Method Summary collapse

Methods inherited from Comparator

#absolute, #change, #initialize, #m, #n, #relative

Constructor Details

This class inherits a constructor from Comparison::Comparator

Instance Method Details

#arrowObject

Returns the I18n translation for ‘comparison.icons`. (See also #icon.)

This method is intended to display a graphical representation of the comparison. Typically this would be an arrow pointing up or down.

The default implementation is as follows:

en:
  comparison:
    arrows:
      positive_html: '↑'
      negative_html: '↓'
      nochange_html: ''

For example, to generate up and down arrows using Glyphicons included with Bootstrap, you could add the following translations to your application:

#arrows and its sister method #icon perform roughly identical tasks with roughly identical intentions. The difference between the two methods is in the context in which they are intended to be used.

#arrows is meant to be used from view contexts with limited functionality such as an HTML email. As such, the translations you specify should be simple enough, like HTML character entities, to work within said view context.

#icons is meant to be used from full-featured view contexts. As such, #icons is the one to use to generate HTML tags.



123
124
125
126
# File 'lib/comparison/presenter.rb', line 123

def arrow
  key, = expand_i18n_keys 'arrows', suffix: '_html'
  t key, default: ARROWS[description.to_sym]
end

#classesObject



163
164
165
166
# File 'lib/comparison/presenter.rb', line 163

def classes
  Kernel.warn "DEPRECATION WARNING: use #dom_classes instead of #classes (called from #{caller(3..3).first})"
  dom_classes
end

#cssObject



195
196
197
198
# File 'lib/comparison/presenter.rb', line 195

def css
  Kernel.warn "DEPRECATION WARNING: use #inline_style instead of #css (called from #{caller(3..3).first})"
  inline_style
end

#descriptionObject

Returns a string description of the direction of change. Possible descriptions are “positive”, “negative”, and “nochange”.



203
204
205
206
207
208
209
210
211
# File 'lib/comparison/presenter.rb', line 203

def description
  if positive?
    'positive'
  elsif negative?
    'negative'
  else
    'nochange'
  end
end

#differenceObject

Deprecated alias for ‘#difference_as_currency`.

In a future release, this method will be changed to delegate directly ‘Comparator#difference`.



29
30
31
32
33
# File 'lib/comparison/presenter.rb', line 29

def difference(...)
  Kernel.warn 'DEPRECATION WARNING: use #difference_as_currency instead of #difference' \
              " (called from #{caller(3..3).first})"
  difference_as_currency(...)
end

#difference_as_currency(**options) ⇒ Object

Returns Comparator#difference formatted as currency.



16
17
18
19
20
21
22
# File 'lib/comparison/presenter.rb', line 16

def difference_as_currency(**options)
  if positive?
    number_to_currency __getobj__.difference, format: '+%u%n', **options
  else
    number_to_currency __getobj__.difference, **options
  end
end

#dom_classesObject

Returns the I18n translation for ‘comparison.dom_classes`.

Use these translations to specify CSS classes for tags that contain comparison data. For example:

en:
  comparison:
    dom_classes:
      positive: 'comparison positive'
      negative: 'comparison negative'
      nochange: 'comparison nochange'

.comparison.positive {
  color: #3c763d;
  background-color: #dff0d8;
}
.comparison.negative {
  color: #a94442;
  background-color: #f2dede;
}
.comparison.nochange {
  color: #777777;
}

content_tag :span, cmp.difference, class: cmp.dom_classes
# => "<span class=\"comparison positive\">+10%</span>"

If you need to work with inline styles instead of CSS classes, see the ‘#inline_style` method.



158
159
160
161
# File 'lib/comparison/presenter.rb', line 158

def dom_classes
  key, *deprecated_keys = expand_i18n_keys(%w[dom_classes classes])
  t key, default: deprecated_keys
end

#iconObject

Returns the I18n translation for ‘comparison.icons`. (See also #arrow.)

This method is intended to display a graphical representation of the comparison. Typically this would be an arrow pointing up or down.

No default implementation is included. You must provide the translations yourself or you will get missing translations.

For example, to generate up and down arrows using Glyphicons included with Bootstrap, you could add the following translations to your application:

en:
  comparison:
    icons:
      positive_html: '<span class="glyphicon glyphicon-arrow-up"></span>'
      negative_html: '<span class="glyphicon glyphicon-arrow-down"></span>'
      nochange_html: '<span class="glyphicon glyphicon-minus"></span>'


88
89
90
91
# File 'lib/comparison/presenter.rb', line 88

def icon
  key, = expand_i18n_keys 'icons', suffix: '_html'
  t key
end

#inline_styleObject Also known as: style

Returns the I18n translation for ‘comparison.style`.

Use these translations to specify inline CSS style rules to be used when formatting comparison data. For example:

en:
  comparison:
    inline_style:
      positive: 'color: #3c763d; background-color: #dff0d8;'
      negative: 'color: #a94442; background-color: #f2dede;'
      nochange: 'color: #777777;'

content_tag :span, cmp.difference, style: cmp.inline_style
# => "<span style=\"color: #3c763d; background-color: #dff0d8;\">+10%</span>"

In general, it’s probably preferable to use ‘#dom_classes` in conjunction with CSS style rules defined separate CSS files, but this isn’t always possible.



188
189
190
191
# File 'lib/comparison/presenter.rb', line 188

def inline_style
  key, *deprecated_keys = expand_i18n_keys(%w[inline_style style css])
  t key, default: [*deprecated_keys, '']
end

#percentage(**options) ⇒ Object

Returns Comparator#change formatted as a percentage.

If the change evaluates to Infinity or -Infinity, the I18n translaation for infinity is returned. If no translation is defined, ‘nil` is returned.

If the change evaluates to NaN, it is returned as 0.



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/comparison/presenter.rb', line 43

def percentage(**options)
  if nan? || zero?
    number_to_percentage 0, **options
  elsif infinite?
    t 'comparison.infinity_html', default: nil
  elsif positive?
    number_to_percentage __getobj__.percentage, format: '+%n%', **options
  else
    number_to_percentage __getobj__.percentage, **options
  end
end

#unsigned_percentage(**options) ⇒ Object

Returns the absolute value of Comparator#change formatted as a percentage.

See ‘#percentage` for additional information on special return scenarios.

Use this if you are relying on other cues (colors and/or icons) to indicate positive or negative values.



62
63
64
65
66
# File 'lib/comparison/presenter.rb', line 62

def unsigned_percentage(**options)
  return percentage(**options) if nan? || infinite?

  number_to_percentage __getobj__.percentage.abs, **options
end