Class: Dumbstats::Histogram

Inherits:
Object
  • Object
show all
Includes:
Initialization
Defined in:
lib/dumbstats/histogram.rb

Overview

Renders a Histogram of values.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Initialization

#update_from_hash!

Constructor Details

#initialize(*args) ⇒ Histogram

Returns a new instance of Histogram.



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

def initialize *args
  @min = @max = nil
  @show_sum = true
  super
  @width ||= 15
  @height ||= 20
end

Instance Attribute Details

#heightObject

Returns the value of attribute height.



14
15
16
# File 'lib/dumbstats/histogram.rb', line 14

def height
  @height
end

#maxObject

Returns the value of attribute max.



13
14
15
# File 'lib/dumbstats/histogram.rb', line 13

def max
  @max
end

#minObject

Returns the value of attribute min.



13
14
15
# File 'lib/dumbstats/histogram.rb', line 13

def min
  @min
end

#nameObject

Returns the value of attribute name.



12
13
14
# File 'lib/dumbstats/histogram.rb', line 12

def name
  @name
end

#show_sumObject

Returns the value of attribute show_sum.



14
15
16
# File 'lib/dumbstats/histogram.rb', line 14

def show_sum
  @show_sum
end

#valuesObject

Returns the value of attribute values.



12
13
14
# File 'lib/dumbstats/histogram.rb', line 12

def values
  @values
end

#widthObject

Returns the value of attribute width.



14
15
16
# File 'lib/dumbstats/histogram.rb', line 14

def width
  @width
end

Instance Method Details

#generateObject

Raises:

  • (TypeError)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/dumbstats/histogram.rb', line 24

def generate
  raise TypeError, "@values not set" unless @values
  return [ ] if @values.size < 2
  @x_graph = Graph.new(:min => @min, :max => @max, :values => @values, :width => @width)
  return [ ] if @x_graph.empty?
  # @x_graph.fix_width!

  @buckets = Hash.new { |h, k| b = Bucket.new; b.name = k; h[k] = b }
  @values.each do | v |
    next if @min and v < @min
    next if @max and v > @max
    i = @x_graph.v_to_x(v).to_i
    if i >= 0 and i < @x_graph.width
      @buckets[i].add! v
    end
  end

  cnt = @buckets.values.map { |b| b.count }
  cnt << 0
  @cnt_graph = Graph.new(:values => cnt, :width => @height)
  return [ ] if @cnt_graph.empty?
  # @cnt_graph.fix_width!

  if @show_sum
  sum = @buckets.values.map { |b| b.sum }
  sum << 0
  @sum_graph = Graph.new(:values => sum, :width => @height)
  # @sum_graph.fix_width!
  end

  # binding.pry

  rows = [ ]
  table =
    Terminal::Table.new() do | t |
    t.title = @name
    s = t.style
    s.border_x =
      s.border_y =
      s.border_i = ''
    s.padding_left = 0
    s.padding_right = 1

    # Header:
    h = [ '>=', '<', 'cnt', '%', "cnt h", "min", "avg", "max" ]
    align_right = [ 0, 1, 2, 3, 5, 6, 7 ]
    if @show_sum
      h.push('sum', '%', 'sum h')
      align_right.push(8, 9)
    end
    rows << h

    cnt_sum = sum_sum = 0
    @width.times do | i |
      x0 = @x_graph.x_to_v(i)
      x1 = @x_graph.x_to_v(i + 1)
      $stderr.puts "  i=#{i} x0=#{x0.inspect} x1=#{x1.inspect} #{@x_graph.min.inspect} #{@x_graph.max.inspect}" if @debug
      x0 = x0.to_i
      x1 = x1.to_i

      b = @buckets[i]
      b.finish!

      cnt_sum += b.count
      r = [ ]
      r << x0
      r << x1
      r << b.count
      r << @cnt_graph.percent(b.count)
      r << @cnt_graph.bar(b.count)
      r << b.min
      r << (b.avg && (@cnt_graph.values_are_integers ? b.avg.to_i : b.avg))
      r << b.max
      if @show_sum
        sum_sum += b.sum || 0
        r << b.sum
        r << @sum_graph.percent(b.sum || 0)
        r << @sum_graph.bar(b.sum || 0)
      end
      rows << r
    end

    f = [ '', '=', cnt_sum, '', '', '', '', '' ]
    if @show_sum
      f.push(sum_sum, '', '')
    end
    rows << f

    rows.each do | r |
      r.map! do | c |
        case c
        when nil
          ''
        when Integer
          thousands(c)
        else
          c
        end
      end
      t << r
    end

    raise unless h.size == f.size

    align_right.each { | c | t.align_column(c, :right) }
  end

  formatted = table.to_s.split("\n")

  formatted
end

#thousands(x, sep = '_') ⇒ Object



136
137
138
# File 'lib/dumbstats/histogram.rb', line 136

def thousands x, sep = '_'
  x && x.to_s.reverse!.gsub(/(\d{3})/, "\\1#{sep}").reverse!.sub(/^(\D|\A)#{sep}/, '')
end