class AltmetricBadger

Wrap an Altmetric data hash and provide translation to badge URIs

Constants

BADGE_TYPES
BASE_HOST
DEFAULT_TYPE_STRING
SEGMENT_COUNT

Attributes

data[R]
score[R]

Public Class Methods

new(score: nil, data:) click to toggle source
# File lib/altmetric_badger.rb, line 12
def initialize(score: nil, data:)
  fail InvalidDataError unless data && data.respond_to?(:sort_by)
  @data = data
  @score = score
end

Private Class Methods

code_for_key(type) click to toggle source
# File lib/altmetric_badger.rb, line 56
def code_for_key(type)
  sources_key_map.fetch(type, sources_key_map[nil])['code']
end
color_for_code(code) click to toggle source
# File lib/altmetric_badger.rb, line 60
def color_for_code(code)
  sources_code_map.fetch(code, sources_key_map[nil])['color']
end
key_for_code(code) click to toggle source
# File lib/altmetric_badger.rb, line 52
def key_for_code(code)
  sources_code_map.fetch(code, {})['key']
end
sources() click to toggle source
# File lib/altmetric_badger.rb, line 36
def sources
  @sources ||= JSON.parse(
    File.read(
      File.join(__dir__, '..', 'data', 'sources.json')
    )
  )
end
sources_code_map() click to toggle source
# File lib/altmetric_badger.rb, line 48
def sources_code_map
  @sources_code_map ||= sources.map { |e| [e['code'], e] }.to_h
end
sources_key_map() click to toggle source
# File lib/altmetric_badger.rb, line 44
def sources_key_map
  @sources_key_map ||= sources.map { |e| [e['key'], e] }.to_h
end

Private Instance Methods

apportion_segments(segments) click to toggle source

Divide segments among all post types, reflecting their proportion, and ensuring that the most popular SEGMENT_COUNT post types receive at least one segment each

# File lib/altmetric_badger.rb, line 86
def apportion_segments(segments)
  (SEGMENT_COUNT - segments.length).times do
    segments << post_percentages.max_by { |_, v| v }.first
    post_percentages[segments.last] -= (1 / SEGMENT_COUNT.to_f)
  end
  segments
end
color_difference_value(segment1, segment2) click to toggle source

Calculate an absolute difference value between two colors This is pretty stupid and broken, but we need to keep the same behaviour as the Altmetric API so that the donuts don’t look different.

# File lib/altmetric_badger.rb, line 109
def color_difference_value(segment1, segment2)
  color1, color2 = [segment1, segment2].map do |color|
    Color::RGB.from_html(self.class.color_for_code(color))
  end.map(&:to_hsl)

  %i(hue saturation brightness).map do |n|
    color1.send(n) - color2.send(n)
  end.reduce(:+)
end
post_percentages() click to toggle source

Return a hash of each post type to the percentage of posts of that type

# File lib/altmetric_badger.rb, line 77
def post_percentages
  @post_percentages ||= data.sort_by { |_, v| v }.map do |type, count|
    [self.class.code_for_key(type), (count / total_posts.to_f)]
  end.to_h
end
segments_to_string(segments) click to toggle source

Sort list of segments by apparent brightness and return combined string

# File lib/altmetric_badger.rb, line 100
def segments_to_string(segments)
  segments.sort do |segment1, segment2|
    color_difference_value(segment1, segment2)
  end.join
end
total_posts() click to toggle source

Return the total number of posts in the data hash

# File lib/altmetric_badger.rb, line 95
def total_posts
  @total_posts ||= data.values.reduce(:+) || 0
end
type_string() click to toggle source

Return string of type codes that Altmetric badge URI uses

# File lib/altmetric_badger.rb, line 66
def type_string
  return DEFAULT_TYPE_STRING unless total_posts > 0

  @type_string ||= segments_to_string(
    apportion_segments(
      post_percentages.keys.last(SEGMENT_COUNT)
    )
  )
end