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

Inherits:
Elements::TiogaElement 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 ????

This class is a subclass of Elements::TiogaElement so that it can be styled just like the rest.

Constant Summary

Constants inherited from Elements::TiogaElement

Elements::TiogaElement::StyleBaseOptions

Instance Attribute Summary collapse

Attributes inherited from Elements::TiogaElement

#clipped, #depth, #hidden, #location, #object_classes, #object_id, #object_parent, #parent

Instance Method Summary collapse

Methods inherited from Elements::TiogaElement

all_styles, base_style, #check_styled, define_style, #do, find_object, find_objects, #get_style, #has_style?, inherited, #inspect, register_object, register_style, #setup_style, #style_class, style_class, style_name, #style_name, styled_classes, #update_style

Methods included from Log

context, counts, debug, error, fatal, #format_exception, #identify, info, init_logger, log_to, logger, set_level, #spawn, warn

Constructor Details

#initialize(type = :right, parent = nil, opts = {}) ⇒ LegendArea

Returns a new instance of LegendArea.



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

def initialize(type = :right, parent = nil, opts = {})
  setup_style(parent, opts)
  @legend_style = get_style()
  @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.



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

def legend_position
  @legend_position
end

#legend_styleObject

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



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

def legend_style
  @legend_style
end

#legend_typeObject

TODO:

Should this move inside the style ?

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



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

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 ?



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/ctioga2/graphics/legends/area.rb', line 80

def display_legend(t, container)
  items = container.legend_storage.harvest_contents
  if self.hidden
    return              # Not doing anything
  end
  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.



150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/ctioga2/graphics/legends/area.rb', line 150

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)/t.scaling_factor, 
            height]
  when :top, :bottom
    return [width, height + t.convert_figure_to_output_dy(h)/t.scaling_factor]
  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.



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/ctioga2/graphics/legends/area.rb', line 176

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.



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/ctioga2/graphics/legends/area.rb', line 119

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