Class: CTioga2::Graphics::Legends::LegendArea

Inherits:
Object
  • Object
show all
Defined in:
lib/ctioga2/graphics/legends/area.rb

Overview

This class holds a series of legends for curves.

TODO:

  • a legend can be plotted either inside a plot or outside the root object

  • in case it is plotted outside the root object, the user should be able to choose whether it should be counted in the real-size or not.

  • legends should provide all the kind of things that were in the first ctioga, such as background, frames, and so on…

  • legends could be organized as columns (especially at the bottom of the graph).

  • whenever a –legend-inside is specified, we create a private @legend_area for the current Elements::Container, with the given position.

TODO: make a subclass for a top-level area ????

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type = :right) ⇒ LegendArea

Returns a new instance of LegendArea.



62
63
64
65
66
# File 'lib/ctioga2/graphics/legends/area.rb', line 62

def initialize(type = :right)
  @legend_style = Styles::LegendStorageStyle.new
  @legend_type = type
  @legend_position = Types::AlignedPoint.new(0.5,0.5,:frame)
end

Instance Attribute Details

#legend_positionObject

The position of the LegendArea. Only significant when the type is :inside. A Types::AlignedPoint instance.



60
61
62
# File 'lib/ctioga2/graphics/legends/area.rb', line 60

def legend_position
  @legend_position
end

#legend_styleObject

The style of the LegendStorage, a Styles::LegendStorageStyle object (of course)



52
53
54
# File 'lib/ctioga2/graphics/legends/area.rb', line 52

def legend_style
  @legend_style
end

#legend_typeObject

The type of the legend. Can be :left, :right, :top, :bottom or :inside



56
57
58
# File 'lib/ctioga2/graphics/legends/area.rb', line 56

def legend_type
  @legend_type
end

Instance Method Details

#display_legend(t, container) ⇒ Object

Draws the legend of the given container and all its subobjects. It assumes that the frames have been set according to the return value of #partition_frame

TODO:

  • customization of the x and y of origin (y should match the top of the corresponding graph, if applicable)

  • add padding on the external side of the legend, if applicable ?



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ctioga2/graphics/legends/area.rb', line 81

def display_legend(t, container)
  items = container.legend_storage.harvest_contents
  t.context do 
    t.rescale(@legend_style.scale)
    t.rescale_text(@legend_style.text_scale)

    # We make figure coordinates frame coordinates
    t.set_bounds([0, 1, 1, 0])
    # TODO: customize this !
    x, y = initial_xy(t, container)
    for item in items
      # TODO: transform the 0.0 for x into a negative
      # user-specifiable stuff.
      item.draw(t, @legend_style, x , y)
      y -= @legend_style.dy.to_figure(t,:y)
    end
  end
end

#enlarged_page_size(t, container, width, height) ⇒ Object

Returns an enlarged page size that can accomodate for both the text and the legend.



122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/ctioga2/graphics/legends/area.rb', line 122

def enlarged_page_size(t, container, width, height)
  w, h = size(t, container)
  case @legend_type
  when :left, :right
    return [width + t.convert_figure_to_output_dx(w)/10, 
            height]
  when :top, :bottom
    return [width, height + t.convert_figure_to_output_dy(h)/10]
  when :inside
    return [width, height]
  end
  raise "Unknown type: #{@legend_type}"
end

#partition_frame(t, container) ⇒ Object

Partitions the frame in two: the plot frame and the legend frame, according to various parameters:

  • the #type of the LegendArea

  • the #size of the legend.

It returns two arrays:

[ plot_margins, legend_margins]

These arrays can be used as arguments for subframe_margins or respectively the graph and the legends part of the plot.

This function will eventually also work in the case of a #legend_type :inside?



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/ctioga2/graphics/legends/area.rb', line 151

def partition_frame(t, container)
  w,h = size(t, container)
  case @legend_type
  when :right
    w = t.convert_figure_to_frame_dx(w)
    return [ [0, w, 0, 0], [1 - w, 0, 0, 0]]
  when :left
    w = t.convert_figure_to_frame_dx(w)
    return [ [w, 0, 0, 0], [0, 1 - w, 0, 0]]
  when :inside
    return [ 
            [0, 0, 0, 0], 
            @legend_position.to_frame_margins(t, w, h)
           ]
  else 
    raise "Unimplemented yet..."
  end
  
end

#size(t, container) ⇒ Object

Returns the total size of the legend as a

[ width, height ]

array in figure coordinates.



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/ctioga2/graphics/legends/area.rb', line 103

def size(t, container)
  items = container.legend_storage.harvest_contents
  width, height = 0,0
  for item in items
    w,h = item.size(t, @legend_style)
    if w > width
      width = w
    end
    # Hmmm... this is plain wrong... 
    # height += h
    height += @legend_style.dy.to_figure(t,:y) * 
      @legend_style.scale * @legend_style.text_scale
  end
  return [ width, height ]
end