lib/tty/pie.rb in tty-pie-0.1.0 vs lib/tty/pie.rb in tty-pie-0.2.0

- old
+ new

@@ -26,10 +26,12 @@ attr_reader :cursor attr_reader :fill + attr_reader :colors + attr_reader :legend # Create pie chart # # @example @@ -39,27 +41,30 @@ # @param [Array[Hash]] data # the data to display in each slice # @param [Integer] top # @param [Integer] left # @param [Integer] radius - # @param [Boolean] legend + # @param [Hash,Boolean] legend # @param [String] fill # @param [Float] aspect_ratio # # @api public - def initialize(data: [], top: nil, left: nil, radius: 10, legend: {}, fill: POINT_SYMBOL, aspect_ratio: 2) + def initialize(data: [], top: nil, left: nil, radius: 10, + legend: {}, fill: POINT_SYMBOL, aspect_ratio: 2, + colors: []) @data = data.dup @top = top @left = left @radius = radius @legend = legend - @fill = fill + @fill = Array(fill) + @colors = Array(colors) @aspect_ratio = aspect_ratio @center_x = (left || 0) + radius * aspect_ratio @center_y = (top || 0) + radius - @pastel = Pastel.new + @pastel = Pastel.new(enabled: !!colors) @cursor = TTY::Cursor end # Total for the data items # @@ -75,15 +80,15 @@ # @return [Array[DataItem]] # # @api private def data_items total_value = total - @data.map do |item| + @data.each_with_index.map do |item, i| percent = (item[:value] * 100) / total_value.to_f - color_fill = item[:fill] || fill - DataItem.new(item[:name], item[:value], percent, - item.fetch(:color, false), color_fill) + color_fill = item[:fill] || fill[i % fill.size] + color = colors && !colors.empty? ? colors[i % colors.size] : item.fetch(:color, false) + DataItem.new(item[:name], item[:value], percent, color, color_fill) end end # Add a data item # @@ -103,23 +108,25 @@ # @param [Array[Hash]] # # @api public def update(data) @data = data + self end # Draw a pie based on the provided data # # @return [String] # # @api public - def draw + def render items = data_items + return '' if items.empty? angles = data_angles(items) output = [] - labels = items.map(&:to_label) + labels = items.map { |item| item.to_label(legend) } label_vert_space = legend_line label_horiz_space = legend_left label_offset = labels.size / 2 label_boundry = label_vert_space * label_offset labels_range = (-label_boundry..label_boundry).step(label_vert_space) @@ -145,20 +152,31 @@ if legend if !top.nil? output << cursor.move_to(center_x + aspect_ratio * radius + label_horiz_space, center_y + y) end if labels_range.include?(y) - output << ' ' * ((center_x - width) + label_horiz_space) if top.nil? + if top.nil? + output << ' ' * ((center_x - (left.to_i + width)) + label_horiz_space) + end output << labels[label_offset + y / label_vert_space] end end output << "\n" end output.join end - alias to_s draw + alias to_s render + + # Reset data + # + # @api public + def clear + @data = [] + self + end + alias reset clear private # All angles from the data to slice the pie #