analytics_charts 1.6.3 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/analytics_charts/custom_module.rb +14 -11
- data/lib/analytics_charts/custom_pie.rb +58 -20
- data/lib/analytics_charts/pie_and_labels.rb +15 -10
- data/lib/analytics_charts/version.rb +1 -1
- metadata +1 -1
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3591ea166bdaed5eb90ee72f9881c17f8b94f86c
         | 
| 4 | 
            +
              data.tar.gz: 387073f74b7a5f8816ffbfa5f38c2cbc1491f5dc
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 828091a522244d336487604fe644b8a429d65d9d16c3060ed962bc2f349ef00a6e41e992c8f8a7fecfbb0efebe65107f73f73150a0967c56f2110c118bfb0123
         | 
| 7 | 
            +
              data.tar.gz: 8c59f8315e3ce67d40a2b0dcc15a22080efa8a60176d03de04fb06765fcfe89ac9d457b19c28cc2641b587d5303551125b68c1676540de2bb81a666980fc6458
         | 
| @@ -14,7 +14,6 @@ class AnalyticsCharts::CustomModule | |
| 14 14 | 
             
                @dummy_image = Image.new(1,1)
         | 
| 15 15 | 
             
                @composite_columns = @composite_image.columns
         | 
| 16 16 | 
             
                @composite_rows = @composite_image.rows
         | 
| 17 | 
            -
                puts "@composite_columns: " + @composite_columns.to_s
         | 
| 18 17 | 
             
                text = text.gsub(/['%]/, '%' => '%%', "'" => "\'")
         | 
| 19 18 | 
             
                begin
         | 
| 20 19 | 
             
                  @rows_of_text = tokenize_text_by_lines(text)
         | 
| @@ -24,9 +23,14 @@ class AnalyticsCharts::CustomModule | |
| 24 23 | 
             
                end
         | 
| 25 24 |  | 
| 26 25 | 
             
                num_separators = @rows_of_text.count {|row| row.empty? }
         | 
| 27 | 
            -
                 | 
| 28 | 
            -
                 | 
| 29 | 
            -
                @ | 
| 26 | 
            +
                num_special_sep = @rows_of_text.count {|row| row.include? "@$$" }
         | 
| 27 | 
            +
                @line_height = @pointsize + 2
         | 
| 28 | 
            +
                @sep_offset = @line_height / 2
         | 
| 29 | 
            +
                starting_offset = @line_height / 2
         | 
| 30 | 
            +
                ending_offset = @line_height / 2
         | 
| 31 | 
            +
                @height = @composite_rows + (@rows_of_text.size - num_separators) *
         | 
| 32 | 
            +
                  @line_height + (num_separators-num_special_sep) * @sep_offset +
         | 
| 33 | 
            +
                  starting_offset + ending_offset
         | 
| 30 34 | 
             
                @base_image = Image.new(@composite_columns, @height) {
         | 
| 31 35 | 
             
                  self.background_color = "black"
         | 
| 32 36 | 
             
                }
         | 
| @@ -35,19 +39,19 @@ class AnalyticsCharts::CustomModule | |
| 35 39 | 
             
                @d.stroke_width(1)
         | 
| 36 40 | 
             
                @d = @d.line(0, @composite_rows, @composite_columns, @composite_rows)
         | 
| 37 41 | 
             
                @d.draw(@base_image)
         | 
| 38 | 
            -
                y_offset =  | 
| 42 | 
            +
                y_offset = @composite_rows + starting_offset
         | 
| 39 43 | 
             
                @rows_of_text.each do |text|
         | 
| 40 44 | 
             
                  if text.include? "@$$" # No paragraph break if we insert this uncommonly used word
         | 
| 41 45 | 
             
                    text.sub!("@$$", "")
         | 
| 42 46 | 
             
                    y_offset -= @sep_offset
         | 
| 47 | 
            +
                    y_offset += @line_height
         | 
| 43 48 | 
             
                    @d.annotate(@base_image, 0 ,0, @pointsize, y_offset, text)
         | 
| 44 | 
            -
                    y_offset += @pointsize
         | 
| 45 49 | 
             
                    next
         | 
| 46 50 | 
             
                  else
         | 
| 47 51 | 
             
                    if text.empty?
         | 
| 48 52 | 
             
                      y_offset += @sep_offset
         | 
| 49 53 | 
             
                    else
         | 
| 50 | 
            -
                      y_offset += @ | 
| 54 | 
            +
                      y_offset += @line_height
         | 
| 51 55 | 
             
                      @d.annotate(@base_image, 0 ,0, @pointsize, y_offset, text)
         | 
| 52 56 | 
             
                    end
         | 
| 53 57 | 
             
                  end
         | 
| @@ -68,12 +72,12 @@ class AnalyticsCharts::CustomModule | |
| 68 72 | 
             
              def line_wrap(text)
         | 
| 69 73 | 
             
                tokens = text.split.reverse # Pop stuff off
         | 
| 70 74 | 
             
                # Safety check, do not allow super long words.
         | 
| 71 | 
            -
                tokens.each {|token| return "" if not fits_in_a_line(token) }
         | 
| 75 | 
            +
                tokens.each {|token| return "" if not fits_in_a_line?(token) }
         | 
| 72 76 | 
             
                line_wrap_tokens = Array.new
         | 
| 73 77 | 
             
                line_builder = ""
         | 
| 74 78 | 
             
                while tokens.size != 0
         | 
| 75 79 | 
             
                  line_builder = tokens.pop # Pop the first word in a line
         | 
| 76 | 
            -
                  while tokens.size != 0 and fits_in_a_line(line_builder + " " + tokens.last)
         | 
| 80 | 
            +
                  while tokens.size != 0 and fits_in_a_line?(line_builder + " " + tokens.last)
         | 
| 77 81 | 
             
                    line_builder += " " + tokens.pop
         | 
| 78 82 | 
             
                  end
         | 
| 79 83 | 
             
                  line_wrap_tokens.push(line_builder) # Add to list of lines
         | 
| @@ -81,8 +85,7 @@ class AnalyticsCharts::CustomModule | |
| 81 85 | 
             
                line_wrap_tokens
         | 
| 82 86 | 
             
              end
         | 
| 83 87 |  | 
| 84 | 
            -
              def fits_in_a_line(text)
         | 
| 85 | 
            -
                puts text + "   SIZE: " + @d.get_type_metrics(@dummy_image,text).width.to_s + "   COLUMNS: " + (@composite_image.columns - 36).to_s
         | 
| 88 | 
            +
              def fits_in_a_line?(text)
         | 
| 86 89 | 
             
                return @d.get_type_metrics(@dummy_image,text).width < @composite_image.columns - 36
         | 
| 87 90 | 
             
              end
         | 
| 88 91 | 
             
            end
         | 
| @@ -10,6 +10,7 @@ class AnalyticsCharts::CustomPie | |
| 10 10 | 
             
              attr_accessor :label_start_x
         | 
| 11 11 | 
             
              attr_accessor :label_start_y
         | 
| 12 12 | 
             
              attr_accessor :label_offset
         | 
| 13 | 
            +
             | 
| 13 14 | 
             
              def initialize(image_path, label_hash, pie_label_hash)
         | 
| 14 15 | 
             
                @base_image = Image.read(image_path)[0]
         | 
| 15 16 | 
             
                @columns = @base_image.columns
         | 
| @@ -44,6 +45,7 @@ class AnalyticsCharts::CustomPie | |
| 44 45 | 
             
              def highest_score(index, score)
         | 
| 45 46 | 
             
                @thresholds[index] = score
         | 
| 46 47 | 
             
              end
         | 
| 48 | 
            +
             | 
| 47 49 | 
             
              def insert_pie_data(name, amount, quality)
         | 
| 48 50 | 
             
                #convert all '' instances to an apostrophe
         | 
| 49 51 | 
             
                name = name.gsub(/'/, "\'")
         | 
| @@ -58,13 +60,24 @@ class AnalyticsCharts::CustomPie | |
| 58 60 | 
             
                end
         | 
| 59 61 | 
             
              end
         | 
| 60 62 |  | 
| 63 | 
            +
              def label_attributes=(label = {})
         | 
| 64 | 
            +
                @label_attributes = label
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              def label_attributes
         | 
| 68 | 
            +
                @label_attributes ||= {}
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              def label_height=(height)
         | 
| 72 | 
            +
                @label_height = height
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              def label_height
         | 
| 76 | 
            +
                @label_height ||= 12
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
             | 
| 61 79 | 
             
              def insert_text_with_circle(x_offset, y_offset, text, features = {})
         | 
| 62 | 
            -
                 | 
| 63 | 
            -
                  set_feature(feature, attribute)
         | 
| 64 | 
            -
                }
         | 
| 65 | 
            -
                # Double quotes automatically escaped in rails db. Refer to Rmagick doc for escaping stuff
         | 
| 66 | 
            -
                text = text.gsub(/['%]/, '%' => '%%', "'" => "\'")
         | 
| 67 | 
            -
                @d.annotate(@base_image, 0 ,0, x_offset, y_offset, text)
         | 
| 80 | 
            +
                insert_text(x_offset, y_offset, text, features)
         | 
| 68 81 | 
             
                height = @d.get_type_metrics(@base_image, text).ascent
         | 
| 69 82 | 
             
                y_offset -= height / 2
         | 
| 70 83 | 
             
                circle_xpos = x_offset - 10
         | 
| @@ -79,6 +92,7 @@ class AnalyticsCharts::CustomPie | |
| 79 92 | 
             
                features.each { |feature, attribute|
         | 
| 80 93 | 
             
                  set_feature(feature, attribute)
         | 
| 81 94 | 
             
                }
         | 
| 95 | 
            +
                # Double quotes automatically escaped in rails db. Refer to Rmagick doc for escaping stuff
         | 
| 82 96 | 
             
                text = text.gsub(/['%]/, '%' => '%%', "'" => "\'")
         | 
| 83 97 | 
             
                @d.annotate(@base_image, 0 ,0, x_offset, y_offset, text)
         | 
| 84 98 | 
             
              end
         | 
| @@ -95,7 +109,7 @@ class AnalyticsCharts::CustomPie | |
| 95 109 | 
             
                  # If we don't refresh draw, future "@d.draw(@base_image)" will redraw the circle,
         | 
| 96 110 | 
             
                  # overlapping on the text written below
         | 
| 97 111 | 
             
                  @d = Draw.new
         | 
| 98 | 
            -
                  insert_text(@pie_center_x - 30, @pie_center_y, "No Data",
         | 
| 112 | 
            +
                  insert_text(@pie_center_x - 30, @pie_center_y, "(No Data)",
         | 
| 99 113 | 
             
                    @label_hash.merge({'fill'=> '#000000', 'font_weight'=> 700 }))
         | 
| 100 114 | 
             
                  return
         | 
| 101 115 | 
             
                end
         | 
| @@ -165,10 +179,10 @@ class AnalyticsCharts::CustomPie | |
| 165 179 | 
             
                    end
         | 
| 166 180 | 
             
                  end
         | 
| 167 181 | 
             
                  prev_degrees = 60.0 # Now focus on labels
         | 
| 168 | 
            -
                  @aggregate.each_with_index do | | 
| 182 | 
            +
                  @aggregate.each_with_index do |cluster_data_value, i|
         | 
| 169 183 | 
             
                    next if degrees[i] == 0
         | 
| 170 184 | 
             
                    half_angle = prev_degrees + degrees[i] / 2
         | 
| 171 | 
            -
                    label_string =  | 
| 185 | 
            +
                    label_string = process_pie_label_data(cluster_data_value)
         | 
| 172 186 | 
             
                    draw_pie_label(@pie_center_x,@pie_center_y, half_angle + label_offset_degrees[i],
         | 
| 173 187 | 
             
                      @pie_radius, label_string, i)
         | 
| 174 188 | 
             
                    prev_degrees += degrees[i]
         | 
| @@ -176,6 +190,26 @@ class AnalyticsCharts::CustomPie | |
| 176 190 | 
             
                end
         | 
| 177 191 | 
             
              end
         | 
| 178 192 |  | 
| 193 | 
            +
              def process_pie_label_data(cluster_data_value)
         | 
| 194 | 
            +
                if cluster_data_value < 10**3
         | 
| 195 | 
            +
                  return '$' + cluster_data_value.round(0).to_s
         | 
| 196 | 
            +
                elsif cluster_data_value < 10**6
         | 
| 197 | 
            +
                  cluster_data_value /= 10**3 # Truncates decimals
         | 
| 198 | 
            +
                  return '$' + cluster_data_value.round(0).to_s + 'K'# Round is unnecessary, but add anyways
         | 
| 199 | 
            +
                elsif cluster_data_value < 10**9
         | 
| 200 | 
            +
                  cluster_data_value /= 10**6
         | 
| 201 | 
            +
                  return '$' + cluster_data_value.round(0).to_s  + 'M'
         | 
| 202 | 
            +
                elsif cluster_data_value < 10**12
         | 
| 203 | 
            +
                  cluster_data_value /= 10**9
         | 
| 204 | 
            +
                  return '$' + cluster_data_value.round(0).to_s + 'B'
         | 
| 205 | 
            +
                elsif cluster_data_value < 10**15
         | 
| 206 | 
            +
                  cluster_data_value /= 10**12
         | 
| 207 | 
            +
                  return '$' + cluster_data_value.round(0).to_s + 'T'
         | 
| 208 | 
            +
                else
         | 
| 209 | 
            +
                  return '>1T'
         | 
| 210 | 
            +
                end
         | 
| 211 | 
            +
              end
         | 
| 212 | 
            +
             | 
| 179 213 | 
             
              def write(filename='graph.png')
         | 
| 180 214 | 
             
                draw
         | 
| 181 215 | 
             
                draw_labels
         | 
| @@ -187,50 +221,49 @@ class AnalyticsCharts::CustomPie | |
| 187 221 | 
             
                sorted_data = @data.sort_by{|key,value| -value[1]} # Sort by descending quality
         | 
| 188 222 | 
             
                x_offset = @label_start_x + 15
         | 
| 189 223 | 
             
                y_offset = @label_start_y
         | 
| 224 | 
            +
                @label_hash = @label_hash.merge(label_attributes)
         | 
| 190 225 | 
             
                for data in sorted_data
         | 
| 191 226 | 
             
                  has_data = false
         | 
| 192 227 | 
             
                  if data[1][0] > 0 # Amount > 0
         | 
| 193 | 
            -
                    font_weight = 900 # Very Bold
         | 
| 194 228 | 
             
                    text = data[0]
         | 
| 195 229 | 
             
                    has_data = true
         | 
| 196 230 | 
             
                  else
         | 
| 197 231 | 
             
                    text = data[0]
         | 
| 198 | 
            -
                    font_weight = 900 # Very Bold
         | 
| 199 232 | 
             
                  end
         | 
| 200 233 | 
             
                  if has_data
         | 
| 201 234 | 
             
                    case data[1][1]
         | 
| 202 235 | 
             
                    when 3
         | 
| 203 236 | 
             
                      # label_hash gets merged and overrided by fill and font_weight.
         | 
| 204 237 | 
             
                      insert_text_with_circle(x_offset, y_offset, text,
         | 
| 205 | 
            -
                        @label_hash.merge({'fill'=> '#1E753B' | 
| 238 | 
            +
                        @label_hash.merge({'fill'=> '#1E753B'}))
         | 
| 206 239 | 
             
                    when 2
         | 
| 207 240 | 
             
                      insert_text_with_circle(x_offset, y_offset, text,
         | 
| 208 | 
            -
                        @label_hash.merge({'fill'=> '#C1B630' | 
| 241 | 
            +
                        @label_hash.merge({'fill'=> '#C1B630'}))
         | 
| 209 242 | 
             
                    when 1
         | 
| 210 243 | 
             
                      insert_text_with_circle(x_offset, y_offset, text,
         | 
| 211 | 
            -
                       @label_hash.merge({'fill'=> '#BE6428' | 
| 244 | 
            +
                       @label_hash.merge({'fill'=> '#BE6428'}))
         | 
| 212 245 | 
             
                    when 0
         | 
| 213 246 | 
             
                      insert_text_with_circle(x_offset, y_offset, text,
         | 
| 214 | 
            -
                        @label_hash.merge({'fill'=> '#AD1F25' | 
| 247 | 
            +
                        @label_hash.merge({'fill'=> '#AD1F25'}))
         | 
| 215 248 | 
             
                    end
         | 
| 216 249 | 
             
                  else
         | 
| 217 250 | 
             
                    case data[1][1]
         | 
| 218 251 | 
             
                    when 3
         | 
| 219 252 | 
             
                      # label_hash gets merged and overrided by fill and font_weight.
         | 
| 220 253 | 
             
                      insert_text(x_offset, y_offset, text,
         | 
| 221 | 
            -
                        @label_hash.merge({'fill'=> '#1E753B' | 
| 254 | 
            +
                        @label_hash.merge({'fill'=> '#1E753B'}))
         | 
| 222 255 | 
             
                    when 2
         | 
| 223 256 | 
             
                      insert_text(x_offset, y_offset, text,
         | 
| 224 | 
            -
                        @label_hash.merge({'fill'=> '#C1B630' | 
| 257 | 
            +
                        @label_hash.merge({'fill'=> '#C1B630'}))
         | 
| 225 258 | 
             
                    when 1
         | 
| 226 259 | 
             
                      insert_text(x_offset, y_offset, text,
         | 
| 227 | 
            -
                       @label_hash.merge({'fill'=> '#BE6428' | 
| 260 | 
            +
                       @label_hash.merge({'fill'=> '#BE6428'}))
         | 
| 228 261 | 
             
                    when 0
         | 
| 229 262 | 
             
                      insert_text(x_offset, y_offset, text,
         | 
| 230 | 
            -
                        @label_hash.merge({'fill'=> '#AD1F25' | 
| 263 | 
            +
                        @label_hash.merge({'fill'=> '#AD1F25'}))
         | 
| 231 264 | 
             
                    end
         | 
| 232 265 | 
             
                  end
         | 
| 233 | 
            -
                  y_offset +=  | 
| 266 | 
            +
                  y_offset += self.label_height
         | 
| 234 267 | 
             
                end
         | 
| 235 268 | 
             
                insert_text_with_circle(x_offset, y_offset, '= purchased by you',
         | 
| 236 269 | 
             
                  @label_hash.merge({'fill'=> '#252525', 'font_weight'=> 900 }))
         | 
| @@ -269,6 +302,11 @@ class AnalyticsCharts::CustomPie | |
| 269 302 | 
             
                insert_text(x, y, percent, {'fill'=> @colors[index]}.merge(@pie_label_hash))# {'fill'=> 'black', 'font_weight'=> 700, 'pointsize'=>48})
         | 
| 270 303 | 
             
              end
         | 
| 271 304 |  | 
| 305 | 
            +
              def recalibrate_metrics_for_labels
         | 
| 306 | 
            +
                label_attributes.each { |feature, attribute|
         | 
| 307 | 
            +
                  set_feature(feature, attribute)
         | 
| 308 | 
            +
                }
         | 
| 309 | 
            +
              end
         | 
| 272 310 | 
             
              def set_feature(feature, attribute)
         | 
| 273 311 | 
             
                begin
         | 
| 274 312 | 
             
                  case feature
         | 
| @@ -12,19 +12,24 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie | |
| 12 12 | 
             
                @d.font_weight = 700
         | 
| 13 13 | 
             
                @dummy_image = Image.new(1,1)
         | 
| 14 14 | 
             
                @composite_columns = @composite_image.columns
         | 
| 15 | 
            -
                puts @composite_columns
         | 
| 16 15 | 
             
                @composite_rows = @composite_image.rows
         | 
| 17 | 
            -
                @org_text_size = 14
         | 
| 18 16 | 
             
                organization = organization.gsub(/['%]/, '%' => '%%', "'" => "\'")
         | 
| 17 | 
            +
                @org_text_size = 14
         | 
| 18 | 
            +
                @org_height = @org_text_size + 1
         | 
| 19 19 | 
             
                @org_texts = tokenize_text_by_lines(organization,
         | 
| 20 20 | 
             
                  {'fill' => '#FFFFFF', 'pointsize'=> @org_text_size, 'font_weight'=> 500  })
         | 
| 21 | 
            +
                org_text_offset = @org_texts.size * @org_height
         | 
| 22 | 
            +
             | 
| 21 23 | 
             
                @label_size = 16
         | 
| 22 | 
            -
                 | 
| 24 | 
            +
                self.label_attributes = {'pointsize' => @label_size, 'font_weight' => 900}
         | 
| 25 | 
            +
                recalibrate_metrics_for_labels
         | 
| 26 | 
            +
                self.label_height = @label_size + 1
         | 
| 27 | 
            +
             | 
| 23 28 | 
             
                # (num_labels + 1) to account for white key on bottom of labels
         | 
| 24 | 
            -
                @height_with_no_disclaimer = [200 + 20, 20 +  | 
| 29 | 
            +
                @height_with_no_disclaimer = [200 + 20, 20 + self.label_height * (num_labels + 1) + 20].max + @composite_rows + org_text_offset
         | 
| 25 30 | 
             
                disclaimer = disclaimer.gsub(/['%]/, '%' => '%%', "'" => "\'")
         | 
| 26 31 | 
             
                @disclaimer_texts = tokenize_text_by_lines(disclaimer)
         | 
| 27 | 
            -
                @height = @height_with_no_disclaimer + @disclaimer_texts.size * 12 | 
| 32 | 
            +
                @height = @height_with_no_disclaimer + @disclaimer_texts.size * 12
         | 
| 28 33 | 
             
                @data = Hash.new # Value is array with two items
         | 
| 29 34 | 
             
                @aggregate = Array([0,0,0,0]) # Cluster brands into categories
         | 
| 30 35 | 
             
                @label_hash = {'pointsize'=> @label_size,'font_weight'=> 700 }
         | 
| @@ -45,11 +50,11 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie | |
| 45 50 | 
             
                  insert_text(22, y_offset ,text,
         | 
| 46 51 | 
             
                        @label_hash.merge({'fill' => '#FFFFFF', 'pointsize'=> @org_text_size, 'font_weight'=> 500  }))
         | 
| 47 52 | 
             
                  @d.annotate(@base_image, 0 ,0, 22, y_offset, text)
         | 
| 48 | 
            -
                  y_offset += @ | 
| 53 | 
            +
                  y_offset += @org_height
         | 
| 49 54 | 
             
                end
         | 
| 50 55 | 
             
              end
         | 
| 51 56 | 
             
              def annotate_disclaimer
         | 
| 52 | 
            -
                y_offset = @height_with_no_disclaimer + @d.get_type_metrics(@dummy_image,"a").height | 
| 57 | 
            +
                y_offset = @height_with_no_disclaimer + @d.get_type_metrics(@dummy_image,"a").height
         | 
| 53 58 | 
             
                @disclaimer_texts.each do |text|
         | 
| 54 59 | 
             
                  if text.include? "@$$" # No paragraph break if we insert this uncommonly used word
         | 
| 55 60 | 
             
                    text.sub!("@$$", "")
         | 
| @@ -153,12 +158,12 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie | |
| 153 158 | 
             
              def line_wrap(text)
         | 
| 154 159 | 
             
                tokens = text.split.reverse # Pop stuff off
         | 
| 155 160 | 
             
                # Safety check, do not allow super long words.
         | 
| 156 | 
            -
                tokens.each {|token| return "" if not fits_in_a_line(token) }
         | 
| 161 | 
            +
                tokens.each {|token| return "" if not fits_in_a_line?(token) }
         | 
| 157 162 | 
             
                line_wrap_tokens = Array.new
         | 
| 158 163 | 
             
                line_builder = ""
         | 
| 159 164 | 
             
                while tokens.size != 0
         | 
| 160 165 | 
             
                  line_builder = tokens.pop # Pop the first word in a line
         | 
| 161 | 
            -
                  while tokens.size != 0 and fits_in_a_line(line_builder + " " + tokens.last)
         | 
| 166 | 
            +
                  while tokens.size != 0 and fits_in_a_line?(line_builder + " " + tokens.last)
         | 
| 162 167 | 
             
                    line_builder += " " + tokens.pop
         | 
| 163 168 | 
             
                  end
         | 
| 164 169 | 
             
                  line_wrap_tokens.push(line_builder) # Add to list of lines
         | 
| @@ -166,7 +171,7 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie | |
| 166 171 | 
             
                line_wrap_tokens
         | 
| 167 172 | 
             
              end
         | 
| 168 173 |  | 
| 169 | 
            -
              def fits_in_a_line(text)
         | 
| 174 | 
            +
              def fits_in_a_line?(text)
         | 
| 170 175 | 
             
                return @d.get_type_metrics(@dummy_image,text).width < @composite_columns - 44
         | 
| 171 176 | 
             
              end
         | 
| 172 177 |  |