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

  • 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.



53
54
55
56
57
# File 'lib/ctioga2/graphics/legends/area.rb', line 53

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.



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

def legend_position
  @legend_position
end

#legend_styleObject

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



43
44
45
# File 'lib/ctioga2/graphics/legends/area.rb', line 43

def legend_style
  @legend_style
end

#legend_typeObject

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



47
48
49
# File 'lib/ctioga2/graphics/legends/area.rb', line 47

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 ?



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
# File 'lib/ctioga2/graphics/legends/area.rb', line 72

def display_legend(t, container)
  items = container.legend_storage.harvest_contents
  t.context do 

    ## @todo These two commands should join LegendStyle
    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)

    w,h = *size(t, container, false)


    @legend_style.frame.
      draw_box_around(t, x, y,
                      x + w, y - h, @legend_style.frame_padding)
    
    for item in items
      ## \todo transform the 0.0 for x into a negative
      # user-specifiable stuff.
      iw, ih = *item.size(t, @legend_style)
      item.draw(t, @legend_style, x , y)
      y -= ih
    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.



139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/ctioga2/graphics/legends/area.rb', line 139

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.



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/ctioga2/graphics/legends/area.rb', line 165

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, resize = true) ⇒ Object

Returns the total size of the legend as a

[ width, height ]

array in figure coordinates.

It assumes that the scales are not setup yet, unless resize is set to false.



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/ctioga2/graphics/legends/area.rb', line 108

def size(t, container, resize = true)
  items = container.legend_storage.harvest_contents
  width, height = 0,0

  # We apparently can't use context here, for a reason that fails me...
  if resize
    t.rescale(@legend_style.scale)
    t.rescale_text(@legend_style.text_scale)
  end
  
  for item in items
    w,h = item.size(t, @legend_style)
    
    if w > width
      width = w
    end
    
    height += h
  end
  
  if resize
    t.rescale(1/@legend_style.scale)
    t.rescale_text(1/@legend_style.text_scale)
  end

  return [ width, height ]
end