Class: CTioga2::Graphics::Styles::PlotStyle

Inherits:
Object
  • Object
show all
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 .?)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Log

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

Constructor Details

#initializePlotStyle

Returns a new instance of PlotStyle.



77
78
79
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
# File 'lib/ctioga2/graphics/styles/plot.rb', line 77

def initialize
  # Default style for the plots.
  @axes = {}
  @axes[:left] = AxisStyle.new(:left, 
                               AXIS_WITH_TICKS_AND_NUMERIC_LABELS,
                               '$y$')
  @axes[:bottom] = AxisStyle.new(:bottom, 
                                 AXIS_WITH_TICKS_AND_NUMERIC_LABELS,
                                 '$x$')

  @axes[:right] = AxisStyle.new(:right, AXIS_WITH_TICKS_ONLY)
  @axes[:top] = AxisStyle.new(:top, AXIS_WITH_TICKS_ONLY)

  @xaxis_location = :bottom
  @yaxis_location = :left

  @title = TextLabel.new
  @title.loc = Types::PlotLocation.new(:top)

  @plot_margin = nil

  @transforms = CoordinateTransforms.new

  @background = BackgroundStyle.new

  # A padding of 4bp ? Why ?? Why not ?
  @padding = Types::Dimension.new(:bp, 4)
end

Instance Attribute Details

#axesObject

The various sides of the plot. A hash location -> AxisStyle.



43
44
45
# File 'lib/ctioga2/graphics/styles/plot.rb', line 43

def axes
  @axes
end

#backgroundObject

Style of the background of the plot



63
64
65
# File 'lib/ctioga2/graphics/styles/plot.rb', line 63

def background
  @background
end

#lines_scaleObject

Scale of the lines of the plot. The plot is wrapped in a t.rescale_lines call.



67
68
69
# File 'lib/ctioga2/graphics/styles/plot.rb', line 67

def lines_scale
  @lines_scale
end

#paddingObject

A padding around the box when automatic spacing is in auto mode. A Dimension.



75
76
77
# File 'lib/ctioga2/graphics/styles/plot.rb', line 75

def padding
  @padding
end

#plot_marginObject

A margin to be left around the data points



55
56
57
# File 'lib/ctioga2/graphics/styles/plot.rb', line 55

def plot_margin
  @plot_margin
end

#text_scaleObject

Scale of the text of the plot. The plot is wrapped in a t.rescale_text call.



71
72
73
# File 'lib/ctioga2/graphics/styles/plot.rb', line 71

def text_scale
  @text_scale
end

#titleObject

The title of the plot



52
53
54
# File 'lib/ctioga2/graphics/styles/plot.rb', line 52

def title
  @title
end

#transformsObject

TODO:

they should be axis-specific.

Coordinate tranforms



60
61
62
# File 'lib/ctioga2/graphics/styles/plot.rb', line 60

def transforms
  @transforms
end

#xaxis_locationObject

The default location of the X axis (well, mainly, the X label)



46
47
48
# File 'lib/ctioga2/graphics/styles/plot.rb', line 46

def xaxis_location
  @xaxis_location
end

#yaxis_locationObject

The default location of the Y axis (well, mainly, the Y label)



49
50
51
# File 'lib/ctioga2/graphics/styles/plot.rb', line 49

def yaxis_location
  @yaxis_location
end

Class Method Details

.current_plot_style(plotmaker) ⇒ Object

Returns the PlotStyle object of the current plot



264
265
266
# File 'lib/ctioga2/graphics/styles/plot.rb', line 264

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



108
109
110
# File 'lib/ctioga2/graphics/styles/plot.rb', line 108

def apply_transforms!(dataset)
  @transforms.transform_2d!(dataset)
end

#deep_copyObject

Returns a deep copy of self, with all references stripped.



259
260
261
# File 'lib/ctioga2/graphics/styles/plot.rb', line 259

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.



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/ctioga2/graphics/styles/plot.rb', line 222

def draw_all_axes(t, bounds)
  for which, axis in @axes
    t.context do
      begin
        axis.set_bounds_for_axis(t, bounds[which])
        axis.draw_axis(t)
      rescue Exception => e
        error { "Impossible to draw axis #{which}: #{e.message}" }
        debug { "Full message: #{e.inspect}" }
      end
    end
  end
  # We draw the title last
  title.draw(t, 'title')
end

#draw_all_background_lines(t) ⇒ Object

Draws all axes background lines for the plot.



239
240
241
242
243
# File 'lib/ctioga2/graphics/styles/plot.rb', line 239

def draw_all_background_lines(t)
  for which, axis in @axes
    axis.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



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/ctioga2/graphics/styles/plot.rb', line 273

def estimate_margins(t)
  margins = [:left, :right, :top, :bottom].map do |side|
    exts = axes_for_side(side).map do |ax|
      ax.extension(t,self)
    end
    if @title.loc.is_side?(side)
      exts << @title.label_extension(t, 'title', @title.loc) * 
        (@text_scale || 1)
    end
    Types::Dimension.new(:dy, exts.max)
  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.



169
170
171
172
173
174
175
# File 'lib/ctioga2/graphics/styles/plot.rb', line 169

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” ?



156
157
158
159
160
161
162
163
164
# File 'lib/ctioga2/graphics/styles/plot.rb', line 156

def get_axis_style(name)
  style = @axes[get_axis_key(name)]
  if ! style
    ## @todo Type-safe exception here
    raise "Unkown named axis: '#{name}'"
  else
    return 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.



192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/ctioga2/graphics/styles/plot.rb', line 192

def get_label_style(location)
  if location =~ /^\s*title\s*$/
    return @title
  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_style(name, style) ⇒ Object



177
178
179
180
# File 'lib/ctioga2/graphics/styles/plot.rb', line 177

def set_axis_style(name, style)
  key = get_axis_key(name)
  @axes[key] = style
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



137
138
139
140
# File 'lib/ctioga2/graphics/styles/plot.rb', line 137

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



208
209
210
211
212
213
214
215
# File 'lib/ctioga2/graphics/styles/plot.rb', line 208

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.



120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/ctioga2/graphics/styles/plot.rb', line 120

def set_log_scale(which, val)
  case which
  when :x
    @axes[:top].log = val
    @axes[:bottom].log = val
    @transforms.x_log = val
  when :y
    @axes[:left].log = val
    @axes[:right].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.



248
249
250
251
252
253
254
255
# File 'lib/ctioga2/graphics/styles/plot.rb', line 248

def setup_figure_maker(t)
  if @lines_scale
    t.rescale_lines(@lines_scale)
  end
  if @text_scale
    t.rescale_text(@text_scale)
  end
end