Class: Squid::Plotter

Inherits:
Object
  • Object
show all
Defined in:
lib/squid/plotter.rb

Overview

A Plotter wraps a Prawn::Document object in order to provide new methods like `gridline` or `ticks` used by Squid::Graph to plot graph elements.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pdf, bottom:) ⇒ Plotter

Returns a new instance of Plotter

Parameters:

  • a (Prawn::Document)

    PDF document to wrap in a Plotter instance.


10
11
12
13
# File 'lib/squid/plotter.rb', line 10

def initialize(pdf, bottom:)
  @pdf = pdf
  @bottom = bottom
end

Instance Attribute Details

#paddingsObject

Returns the value of attribute paddings


8
9
10
# File 'lib/squid/plotter.rb', line 8

def paddings
  @paddings
end

Instance Method Details

#axis_labels(labels) ⇒ Object


49
50
51
52
53
54
55
56
# File 'lib/squid/plotter.rb', line 49

def axis_labels(labels)
  labels.each do |label|
    x = (label.align == :right) ? 0 : @pdf.bounds.right - label.width
    y = label.y + @bottom + text_options[:height] / 2
    options = text_options.merge width: label.width, at: [x, y]
    @pdf.text_box label.label, options.merge(align: label.align)
  end
end

#box(x: 0, y: @pdf.cursor, w: @pdf.bounds.width, h:, border: false) ⇒ Object

Draws a bounding box of the given height, rendering the block inside it.


16
17
18
19
20
21
# File 'lib/squid/plotter.rb', line 16

def box(x: 0, y: @pdf.cursor, w: @pdf.bounds.width, h:, border: false)
  @pdf.bounding_box [x, y], width: w, height: h do
    @pdf.stroke_bounds if border
    yield
  end
end

#categories(labels, every:, ticks:) ⇒ Object


58
59
60
61
62
63
64
65
66
67
# File 'lib/squid/plotter.rb', line 58

def categories(labels, every:, ticks:)
  labels.each.with_index do |label, index|
    w = width / labels.count.to_f
    x = left + w * (index)
    padding = 2
    options = category_options.merge(width: every*w-2*padding, at: [x+padding-w*(every/2.0-0.5), @bottom])
    @pdf.text_box label, options if (index % every).zero?
    @pdf.stroke_vertical_line @bottom, @bottom - 2, at: x + w/2 if ticks
  end
end

#columns(series, colors: []) ⇒ Object


95
96
97
98
99
100
101
# File 'lib/squid/plotter.rb', line 95

def columns(series, colors: [])
  items(series, colors: colors, fill: true, count: series.size) do |point, w, i, padding|
    item_w = (w - 2 * padding)/ series.size
    x, y = point.index*w + padding + left + i*item_w, point.y + @bottom
    @pdf.fill_rectangle [x, y], item_w, point.height
  end
end

#horizontal_line(y, options = {}) ⇒ Object

Draws a horizontal line.


38
39
40
41
42
43
# File 'lib/squid/plotter.rb', line 38

def horizontal_line(y, options = {})
  with options do
    at = y + @bottom
    @pdf.stroke_horizontal_line left, @pdf.bounds.right - right, at: at
  end
end

#legend(labels, height:, offset: 0, colors: []) ⇒ Object

Draws the graph legend with the given labels.

Parameters:

  • The (Array<LegendItem>)

    labels to write as part of the legend.


25
26
27
28
29
30
31
32
33
34
35
# File 'lib/squid/plotter.rb', line 25

def legend(labels, height:, offset: 0, colors: [])
  left = @pdf.bounds.width/2
  box(x: left, y: @pdf.bounds.top, w: left, h: height) do
    x = @pdf.bounds.right - offset
    options = {size: 7, height: @pdf.bounds.height, valign: :center}
    labels.each.with_index do |label, i|
      color = Array.wrap(colors[labels.size - 1 - i]).first
      x = legend_item label, x, color, options
    end
  end
end

#lines(series, colors: [], line_widths: []) ⇒ Object


76
77
78
79
80
81
82
83
84
85
86
# File 'lib/squid/plotter.rb', line 76

def lines(series, colors: [], line_widths: [])
  x, y = nil, nil
  items(series, colors: colors) do |point, w, i, padding|
    prev_x, prev_y = x, y
    x, y = (point.index + 0.5)*w + left, point.y + @bottom
    line_width = Array.wrap(line_widths).fetch(i, 1)
    with line_width: line_width, cap_style: :round do
      @pdf.line [prev_x, prev_y], [x,y] unless point.index.zero? || prev_y.nil? || prev_x > x
    end
  end
end

#points(series, colors: []) ⇒ Object


69
70
71
72
73
74
# File 'lib/squid/plotter.rb', line 69

def points(series, colors: [])
  items(series, colors: colors) do |point, w, i, padding|
    x, y = (point.index + 0.5)*w + left, point.y + @bottom
    @pdf.fill_circle [x, y], 5
  end
end

#stacks(series, colors: []) ⇒ Object


88
89
90
91
92
93
# File 'lib/squid/plotter.rb', line 88

def stacks(series, colors: [])
  items(series, colors: colors, fill: true) do |point, w, i, padding|
    x, y = point.index*w + padding + left, point.y + @bottom
    @pdf.fill_rectangle [x, y], w - 2*padding, point.height
  end
end

#width_of(label) ⇒ Object


45
46
47
# File 'lib/squid/plotter.rb', line 45

def width_of(label)
  @pdf.width_of(label, size: 8).ceil
end