Class: CTioga2::Graphics::Styles::PlotStyle
- Inherits:
-
Object
- Object
- CTioga2::Graphics::Styles::PlotStyle
- Includes:
- Log, Tioga::FigureConstants
- Defined in:
- lib/ctioga2/graphics/styles/plot.rb
Overview
The style of a Elements::Subplot object.
todo it should hold
-
labels
-
axes and edges (in a clean way !)
-
ticks
-
background (uniform fill + watermark if applicable + possibly a picture .?)
This class is way too complex and needs too much flexibility to be handled by a subclass of BasicStyle. However, all substyles should be.
Constant Summary collapse
- @@current_index =
0
Instance Attribute Summary collapse
-
#axes ⇒ Object
The various sides of the plot.
-
#background ⇒ Object
Style of the background of the plot.
-
#frame_real_size ⇒ Object
If not nil, then the boundaries are computed from the real dimensions of the plot frame, using the given number as a conversion factor from postscript points.
-
#lines_scale ⇒ Object
Scale of the lines of the plot.
-
#padding ⇒ Object
A padding around the box when automatic spacing is in auto mode.
-
#plot_margin ⇒ Object
A margin to be left around the data points.
-
#target_plot ⇒ Object
The target plot (ie the parent of all the small elements).
-
#text_auto_adjust ⇒ Object
Mode for auto-adjust.
-
#text_scale ⇒ Object
Scale of the text of the plot.
-
#title ⇒ Object
The title of the plot.
-
#transforms ⇒ Object
Coordinate tranforms.
-
#xaxis_location ⇒ Object
The default location of the X axis (well, mainly, the X label).
-
#yaxis_location ⇒ Object
The default location of the Y axis (well, mainly, the Y label).
Class Method Summary collapse
-
.current_plot_style(plotmaker) ⇒ Object
Returns the PlotStyle object of the current plot.
Instance Method Summary collapse
-
#apply_transforms!(dataset) ⇒ Object
Apply (destructively) the current transformations to the given dataset.
-
#clear_axes ⇒ Object
Clear all axes.
-
#compute_margins(t, prev_margins) ⇒ Object
Computes the margins based on the text information.
-
#deep_copy ⇒ Object
Returns a deep copy of self, with all references stripped.
-
#draw_all_axes(t, bounds) ⇒ Object
Draws all axes for the plot.
-
#draw_all_background_lines(t) ⇒ Object
Draws all axes background lines for the plot.
-
#estimate_margins(t) ⇒ Object
Estimate the margins of the plot whose style this object controls.
-
#get_axis_key(name) ⇒ Object
Returns the key corresponding to the named axis.
-
#get_axis_style(name) ⇒ Object
Returns the AxisStyle corresponding to the named axis.
-
#get_label_style(location) ⇒ Object
Returns a BaseTextStyle or similar for the given location.
-
#initialize(plt) ⇒ PlotStyle
constructor
A new instance of PlotStyle.
- #set_axis(name, axis) ⇒ Object
-
#set_default_axis(which, name) ⇒ Object
Sets the axis which should be used for subsequent objects (for which no axis is specified) for the given plot.
-
#set_label_style(which, hash, text = nil) ⇒ Object
Sets the style of the given label.
-
#set_log_scale(which, val) ⇒ Object
Whether to use log scale for the given axis.
-
#setup_figure_maker(t) ⇒ Object
Sets up the FigureMaker object for the plot.
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(plt) ⇒ PlotStyle
Returns a new instance of PlotStyle.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 94 def initialize(plt) # Default style for the plots. @target_plot = plt @axes = {} for ax in [:left, :right, :top, :bottom] cls = [ax.to_s] cls << if (ax == :bottom or ax == :top) 'x' else 'y' end dec = if (ax == :bottom or ax == :left) AXIS_WITH_TICKS_AND_NUMERIC_LABELS else AXIS_WITH_TICKS_ONLY end label = nil if ax == :bottom label = '$x$' elsif ax == :left label = '$y$' end axis = Elements::AxisElement.new axis.setup_style(@target_plot, {'class' => cls}) axis.initialize_style(ax, dec, label) @axes[ax] = axis end @xaxis_location = :bottom @yaxis_location = :left @title = Elements::TitleElement.new(@target_plot, {}) @plot_margin = nil @transforms = CoordinateTransforms.new @background = Elements::BackgroundElement.new(@target_plot, {}) # A padding of 6bp ? Why ?? Why not ? @padding = Types::Dimension.new(:bp, 6) @text_size_index = @@current_index @@current_index += 1 # Automatic adjustment of text sizes... @text_sizes = TextSizeWatcher.new @text_sizes.watch("title-#{@text_size_index}") @text_auto_adjust = :both end |
Instance Attribute Details
#axes ⇒ Object
The various sides of the plot. A hash location -> AxisStyle.
46 47 48 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 46 def axes @axes end |
#background ⇒ Object
Style of the background of the plot
66 67 68 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 66 def background @background end |
#frame_real_size ⇒ Object
If not nil, then the boundaries are computed from the real dimensions of the plot frame, using the given number as a conversion factor from postscript points.
86 87 88 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 86 def frame_real_size @frame_real_size end |
#lines_scale ⇒ Object
Scale of the lines of the plot. The plot is wrapped in a t.rescale_lines call.
70 71 72 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 70 def lines_scale @lines_scale end |
#padding ⇒ Object
A padding around the box when automatic spacing is in auto mode. A Dimension.
78 79 80 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 78 def padding @padding end |
#plot_margin ⇒ Object
A margin to be left around the data points
58 59 60 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 58 def plot_margin @plot_margin end |
#target_plot ⇒ Object
The target plot (ie the parent of all the small elements)
90 91 92 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 90 def target_plot @target_plot end |
#text_auto_adjust ⇒ Object
Mode for auto-adjust
81 82 83 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 81 def text_auto_adjust @text_auto_adjust end |
#text_scale ⇒ Object
Scale of the text of the plot. The plot is wrapped in a t.rescale_text call.
74 75 76 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 74 def text_scale @text_scale end |
#title ⇒ Object
The title of the plot
55 56 57 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 55 def title @title end |
#transforms ⇒ Object
they should be axis-specific.
Coordinate tranforms
63 64 65 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 63 def transforms @transforms end |
#xaxis_location ⇒ Object
The default location of the X axis (well, mainly, the X label)
49 50 51 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 49 def xaxis_location @xaxis_location end |
#yaxis_location ⇒ Object
The default location of the Y axis (well, mainly, the Y label)
52 53 54 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 52 def yaxis_location @yaxis_location end |
Class Method Details
.current_plot_style(plotmaker) ⇒ Object
Returns the PlotStyle object of the current plot
309 310 311 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 309 def self.current_plot_style(plotmaker) return plotmaker.root_object.current_plot.style end |
Instance Method Details
#apply_transforms!(dataset) ⇒ Object
Apply (destructively) the current transformations to the given dataset
154 155 156 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 154 def apply_transforms!(dataset) @transforms.transform_2d!(dataset) end |
#clear_axes ⇒ Object
Clear all axes
340 341 342 343 344 345 346 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 340 def clear_axes() [:left, :right, :top, :bottom].each do |loc| style = get_axis_style(loc) style.decoration = Tioga::FigureConstants::AXIS_HIDDEN style.axis_label.text = false end end |
#compute_margins(t, prev_margins) ⇒ Object
Computes the margins based on the text information.
This is very different from the one above, since this one relies on measured texts to get it right !
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 352 def compute_margins(t, prev_margins) margins = estimate_margins(t) if @text_auto_adjust == :old return margins else pad = if @padding @padding.to_bp(t) else 4 end nm = @text_sizes.update_margins(t, prev_margins, pad) # We include the old margins, unless we have the :measure # text adjust mode if @text_auto_adjust != :measure nm.(t, margins) end return nm end end |
#deep_copy ⇒ Object
Returns a deep copy of self, with all references stripped.
304 305 306 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 304 def deep_copy return Marshal.load(Marshal.dump(self)) end |
#draw_all_axes(t, bounds) ⇒ Object
Draws all axes for the plot. The bounds argument is that computed by Subplot#compute_boundaries; it is there to ensure that the axes know whether they have their own coordinate system or if they just follow what’s around.
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 267 def draw_all_axes(t, bounds) for which, axis in @axes t.context do begin axis.style.set_bounds_for_axis(t, bounds[which]) axis.style.draw_axis(t, @text_sizes) rescue Exception => e error { "Impossible to draw axis #{which}: #{e.}" } info { "Full message: #{e.inspect}\n#{e.backtrace.join("\n")}" } end end end # We draw the title last title.style.draw(t, 'title', "title-#{@text_size_index}") end |
#draw_all_background_lines(t) ⇒ Object
Draws all axes background lines for the plot.
284 285 286 287 288 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 284 def draw_all_background_lines(t) for which, axis in @axes axis.style.draw_background_lines(t) end end |
#estimate_margins(t) ⇒ Object
Estimate the margins of the plot whose style this object controls. These margins are used when the plot margins are in automatic mode.
Returns a Types::MarginsBox
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 318 def estimate_margins(t) margins = [:left, :right, :top, :bottom].map do |side| exts = axes_for_side(side).map do |ax| ax.style.extension(t, self) end if @title.style.loc.is_side?(side) exts << @title.style.label_extension(t, 'title', @title.style.loc) * (@text_scale || 1) end Types::Dimension.new(:dy, exts.max || 0) end box = Types::MarginsBox.new(*margins) if @padding for dim in box.margins dim.replace_if_bigger(t, @padding) end end return box end |
#get_axis_key(name) ⇒ Object
Returns the key corresponding to the named axis. See #get_axis_style for more information; though ultimately the latter is using this function.
214 215 216 217 218 219 220 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 214 def get_axis_key(name) if name =~ /^\s*([xy])(?:axis)?\s*$/i return self.send("#{$1.downcase}axis_location") else return clean_axis_name(name) end end |
#get_axis_style(name) ⇒ Object
Returns the AxisStyle corresponding to the named axis. name can be:
-
one of the named axes (ie, by default: top, left, right, bottom). All names are stripped from spaces around, and downcased (see #clean_axis_name). Can be also user-defined axes.
-
x(axis)?/y(axis)?, which returns the default object for the given location
todo Maybe x2 and y2 could be provided to signify “the side which isn’t the default” ?
201 202 203 204 205 206 207 208 209 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 201 def get_axis_style(name) axis = @axes[get_axis_key(name)] if ! axis ## @todo Type-safe exception here raise "Unkown named axis: '#{name}'" else return axis.style end end |
#get_label_style(location) ⇒ Object
Returns a BaseTextStyle or similar for the given location. The location is of the form:
axis_name(_(ticks?|label))
or
title
If neither label nor ticks is specified in the first form, ticks are implied.
237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 237 def get_label_style(location) if location =~ /^\s*title\s*$/ return @title.style end location =~ /^\s*(.*?)(?:_(ticks?|label))?\s*$/i which = $2 axis = get_axis_style($1) if which =~ /label/ return axis.axis_label else return axis.tick_label_style end end |
#set_axis(name, axis) ⇒ Object
222 223 224 225 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 222 def set_axis(name, axis) key = get_axis_key(name) @axes[key] = axis end |
#set_default_axis(which, name) ⇒ Object
Sets the axis which should be used for subsequent objects (for which no axis is specified) for the given plot
182 183 184 185 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 182 def set_default_axis(which, name) axis = get_axis_key(name) self.send("#{which}axis_location=", axis) end |
#set_label_style(which, hash, text = nil) ⇒ Object
Sets the style of the given label. Sets the text as well, if text is not nil
253 254 255 256 257 258 259 260 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 253 def set_label_style(which, hash, text = nil) style = get_label_style(which) hash = hash.merge({'text' => text}) unless text.nil? if hash.key?('text') and ! style.is_a?(TextLabel) CTioga2::Log::warn {"Text property of label #{which} was set, but this has no meaning: tick labels can't be set this way. Did you mean to use \"#{which}_label\"" + " instead ?" } end style.set_from_hash(hash) end |
#set_log_scale(which, val) ⇒ Object
Whether to use log scale for the given axis.
Now the question is: how should that affect user-defined axes ? It should not.
todo This really should move to Axis when transformations are handled correctly.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 165 def set_log_scale(which, val) case which when :x @axes[:top].style.log = val @axes[:bottom].style.log = val @transforms.x_log = val when :y @axes[:left].style.log = val @axes[:right].style.log = val @transforms.y_log = val else raise "Unknown axis: #{which.inspect}" end end |
#setup_figure_maker(t) ⇒ Object
Sets up the FigureMaker object for the plot. To be called just after the outermost context call for the concerned plot.
293 294 295 296 297 298 299 300 |
# File 'lib/ctioga2/graphics/styles/plot.rb', line 293 def setup_figure_maker(t) if @lines_scale t.rescale_lines(@lines_scale) end if @text_scale t.rescale_text(@text_scale) end end |