class MagicCloud::Cloud
Main word-cloud class. Takes words with sizes, returns image
Constants
- DEFAULT_FAMILY
- FONT_MAX
- FONT_MIN
FIXME: should be options too
Attributes
palette[R]
rotator[R]
scaler[R]
Public Class Methods
new(words, options = {})
click to toggle source
# File lib/magic_cloud/cloud.rb, line 16 def initialize(words, options = {}) @words = words.sort_by(&:last).reverse @options = options @scaler = make_scaler(words, options[:scale] || :log) @rotator = make_rotator(options[:rotate] || :square) @palette = make_palette(options[:palette] || :default) end
Public Instance Methods
draw(width, height)
click to toggle source
# File lib/magic_cloud/cloud.rb, line 26 def draw(width, height) # FIXME: do it in init, for specs would be happy shapes = @words.each_with_index.map{|(word, size), i| Word.new( word, font_family: @options[:font_family] || DEFAULT_FAMILY, font_size: scaler.call(word, size, i), color: palette.call(word, i), rotate: rotator.call(word, i) ) } Debug.reset! spriter = Spriter.new spriter.make_sprites!(shapes) layouter = Layouter.new(width, height) visible = layouter.layout!(shapes) canvas = Canvas.new(width, height, 'white') visible.each{|sh| sh.draw(canvas)} canvas.render end
Private Instance Methods
make_const_palette(sym)
click to toggle source
# File lib/magic_cloud/cloud.rb, line 74 def make_const_palette(sym) palette = PALETTES[sym] or fail(ArgumentError, "Unknown palette: #{sym.inspect}") ->(_, index){palette[index % palette.size]} end
make_palette(source)
click to toggle source
rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity,Metrics/AbcSize
# File lib/magic_cloud/cloud.rb, line 57 def make_palette(source) case source when :default make_const_palette(:category20) when Symbol make_const_palette(source) when Array ->(_, index){source[index % source.size]} when Proc source when ->(s){s.respond_to?(:color)} ->(word, index){source.color(word, index)} else fail ArgumentError, "Unknown palette: #{source.inspect}" end end
make_rotator(source)
click to toggle source
# File lib/magic_cloud/cloud.rb, line 81 def make_rotator(source) case source when :none ->(*){0} when :square ->(*){ (rand * 2).to_i * 90 } when :free ->(*){ (((rand * 6) - 3) * 30).round } when Array ->(*){ source.sample } when Proc source when ->(s){s.respond_to?(:rotate)} ->(word, index){source.rotate(word, index)} else fail ArgumentError, "Unknown rotation algo: #{source.inspect}" end end
make_scaler(words, algo)
click to toggle source
# File lib/magic_cloud/cloud.rb, line 110 def make_scaler(words, algo) norm = case algo when :no # no normalization, treat tag weights as font size return ->(_word, size, _index){size} when :linear ->(x){x} when :log ->(x){Math.log(x) / Math.log(10)} when :sqrt ->(x){Math.sqrt(x)} else fail ArgumentError, "Unknown scaling algo: #{algo.inspect}" end smin = norm.call(words.map(&:last).min) smax = norm.call(words.map(&:last).max) koeff = (FONT_MAX - FONT_MIN).to_f / (smax - smin) ->(_word, size, _index){ ssize = norm.call(size) ((ssize - smin).to_f * koeff + FONT_MIN).to_i } end