class CTioga2::Graphics::Legends::LegendArea
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.
Attributes
The position of the LegendArea
. Only significant when the type is :inside. A Types::AlignedPoint
instance.
The style of the LegendStorage
, a Styles::LegendStorageStyle
object (of course)
The type of the legend. Can be :left, :right, :top, :bottom or :inside
@todo Should this move inside the style ?
Public Class Methods
# 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
Public Instance Methods
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 ?
# 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
Returns an enlarged page size that can accomodate for both the text and the legend.
# 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
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.
# 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
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.
# 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
Protected Instance Methods
Returns the X and Y values for the top left of the legend inside the legend frame. Depends on a lot of things, including the type of the legend.
# File lib/ctioga2/graphics/legends/area.rb, line 201 def initial_xy(t, container) case @legend_type when :right l,r,top,b = container.actual_subframe(t).to_frame_margins(t) # Here, we take profit from the fact that frame # coordinates are also figure coordinates within the # legend. ## \todo that won't work in the case of labels on the # right-hand-side. return [0, 1.0 - top] when :inside return [0.0, 1.0] else raise "Unimplemented yet..." end end