class CTioga2::Graphics::Styles::AxisStyle
The style of an axis or an egde of the plot. Unlike tioga, ctioga2 does not make any difference.
Public Class Methods
Returns the AxisStyle
object corresponding to the named axis in the current plot.
# File lib/ctioga2/graphics/styles/axes.rb, line 276 def self.current_axis_style(plotmaker, spec) return PlotStyle.current_plot_style(plotmaker). get_axis_style(spec) end
Creates a new AxisStyle
object at the given location with the given style.
# File lib/ctioga2/graphics/styles/axes.rb, line 94 def initialize(location = nil, decoration = nil, label = nil) @location = Types::PlotLocation.new(location) @decoration = decoration @tick_label_style = FullTextStyle.new @tick_label_style.scale = Types::Dimension.new(:dy, 0.8) @axis_label = TextLabel.new(label) @log = false @ticks_side = {} @ticks = AxisTicks.new @index = @@text_size_index @@text_size_index += 1 end
Public Instance Methods
Draws the axis within the current plot. Boundaries are the current plot boundaries. Also draw the axis_label, if there is one.
todo
-
the offset mechanism, to place the axis away from the place where it should be…
-
non-linear axes (or linear, for that matter, but with a transformation)
watcher is a TextSizeWatcher
object.
# File lib/ctioga2/graphics/styles/axes.rb, line 121 def draw_axis(t, watcher = nil) spec = get_axis_specification(t) info = t.axis_information(spec) # Merge in the specs spec.merge!(@ticks.ticks_specs(t, info, @transform)) # Add tick label style: spec.merge!(@tick_label_style.hash_for_tioga(t)) # Direct copy of attributes for key in %w(stroke_color major_tick_length major_tick_width minor_tick_length minor_tick_width) val = self.send(key.to_sym) if val spec[key] = val end end spec.update(@ticks_side) # We don't allow Tioga to draw tick labels by itself type = spec['type'] spec['type'] = case spec['type'] when Tioga::FigureConstants::AXIS_WITH_MAJOR_TICKS_AND_NUMERIC_LABELS Tioga::FigureConstants::AXIS_WITH_MAJOR_TICKS_ONLY when Tioga::FigureConstants::AXIS_WITH_TICKS_AND_NUMERIC_LABELS Tioga::FigureConstants::AXIS_WITH_TICKS_ONLY else spec['type'] end t.context do if @line_width # Holy gods, there is no way in Tioga to choose the line # width. # # Here is essentially the proof that I must reimplement # the axes. t.xaxis_line_width = @line_width t.yaxis_line_width = @line_width end t.show_axis(spec) end # Now, we draw axis ticks if (type == Tioga::FigureConstants::AXIS_WITH_MAJOR_TICKS_AND_NUMERIC_LABELS) || (type == Tioga::FigureConstants::AXIS_WITH_TICKS_AND_NUMERIC_LABELS) fnc = info['vertical'] ? :convert_figure_to_frame_y : :convert_figure_to_frame_x stl = @tick_label_style.dup stl.shift ||= Types::Dimension.new(:dy, info['shift']) # @todo integrate to the shift_def = ( @location.base_location == :bottom || @location.base_location == :at_y_origin || @location.base_location == :right ) ? 0.3 : 0.4 stl.shift = Types::Dimension.new(:dy, stl.shift.to_dy(t) + shift_def) stl.valign ||= ( @location.base_location == :bottom || @location.base_location == :at_y_origin || @location.base_location == :right ) ? Tioga::FigureConstants::ALIGNED_AT_TOP : Tioga::FigureConstants::ALIGNED_AT_BOTTOM spec['labels'].size.times do |i| pos = spec['major_ticks'][i] label = spec['labels'][i] pos = t.send(fnc, pos) next unless label nm = "axis-tick#{@index}-#{i}" stl.draw_text(t, label, spec['location'], [:pos, pos], nm) if watcher watcher.watch(nm) end end end @axis_label.loc = @location default = vertical? ? 'ylabel' : 'xlabel' nm = "axis-label#{@index}" # stl = @axis_label.dup # # Default to aligning the label where it counts. # stl.valign ||= ( # @location.base_location == :bottom || # @location.base_location == :at_y_origin || # @location.base_location == :right # ) ? Tioga::FigureConstants::ALIGNED_AT_MIDHEIGHT : Tioga::FigureConstants::ALIGNED_AT_BOTTOM @axis_label.draw(t, default, nm) if watcher watcher.watch(nm) end end
Draw the axis background lines:
# File lib/ctioga2/graphics/styles/axes.rb, line 246 def draw_background_lines(t) if @background_lines # First, getting major ticks location from tioga info = t.axis_information(get_axis_specification(t)) tick_info = @ticks.ticks_specs(t, info, @transform) if info['vertical'] x0 = t.bounds_left x1 = t.bounds_right else y0 = t.bounds_bottom y1 = t.bounds_top end t.context do @background_lines.set_stroke_style(t) values = tick_info['major_ticks'] for val in values if info['vertical'] t.stroke_line(x0, val, x1, val) else t.stroke_line(val, y0, val, y1) end end end end end
Returns the extension of the axis (including tick labels and labels if applicable) perpendicular to itself, in units of text height (at scale = current text scale when drawing axes).
style is a PlotStyle
object containing the style information for the target plot.
todo handle offset axes when that is implemented.
# File lib/ctioga2/graphics/styles/axes.rb, line 311 def extension(t, style = nil) return labels_only_extension(t, style) end
Returns the part of the extension
only due to the labels (ticks and standard label).
For now, it returns the same value as extension
, but that might change
# File lib/ctioga2/graphics/styles/axes.rb, line 286 def labels_only_extension(t, style = nil) ticks_shift, ticks_scale = *get_ticks_parameters(t) default = vertical? ? 'ylabel' : 'xlabel' le = @axis_label.label_extension(t, default, @location) case @decoration when AXIS_WITH_MAJOR_TICKS_AND_NUMERIC_LABELS, AXIS_WITH_TICKS_AND_NUMERIC_LABELS te = ticks_shift * ticks_scale else te = 0 end return Dobjects::Dvector[le,te].max * (style ? style.text_scale || 1 : 1) end
Sets
the current boundaries of the t object to the range SimpleRange object for the direction handled by the AxisStyle
, without touching the rest.
# File lib/ctioga2/graphics/styles/axes.rb, line 228 def set_bounds_for_axis(t, range = nil) if ! range return end l,r,top,b = t.bounds_left, t.bounds_right, t.bounds_top, t.bounds_bottom if self.vertical? b = range.first top = range.last else l = range.first r = range.last end t.set_bounds([l,r,top,b]) end
Protected Instance Methods
Setup coordinate transformations
# File lib/ctioga2/graphics/styles/axes.rb, line 357 def compute_coordinate_transforms(t) return unless @transform # We'll proceed by steps... i = t.axis_information({'location' => @location.tioga_location}) t.context do if i['vertical'] top,b = @transform.convert_to([t.bounds_top, t.bounds_bottom]) l,r = t.bounds_left, t.bounds_right else top,b = t.bounds_top, t.bounds_bottom l,r = @transform.convert_to([t.bounds_left, t.bounds_right]) end t.set_bounds([l,r,top,b]) i = t.axis_information({'location' => @location.tioga_location}) # Now, we have the location of everything we need. end # In the following, the || are because of a fix in Tioga # r545 return { 'labels' => i['labels'], 'major_ticks' => @transform. convert_from(i['major_ticks'] || i['major']), 'minor_ticks' => @transform. convert_from(i['minor_ticks'] || i['minor'] ) } end
Returns an argument suitable for use for FigureMaker#show_axis or FigureMaker#axis_information.
For the log axis scale to work, tioga revision 543 is absolutely necessary. It won't fail, though, without it.
# File lib/ctioga2/graphics/styles/axes.rb, line 340 def get_axis_specification(t) if @transform retval = compute_coordinate_transforms(t) else retval = {} end if @offset raise YetUnimplemented, "This has not been implemented yet" else retval. update({'location' => @location.tioga_location, 'type' => @decoration, 'log' => @log}) return retval end end
Returns: ticks_shift, ticks_scale for the axis.
todo try something clever with the angles ?
# File lib/ctioga2/graphics/styles/axes.rb, line 325 def get_ticks_parameters(t) i = t.axis_information({'location' => @location.tioga_location}) retval = [] retval << (@tick_label_style.shift_dy(t) || i['shift']) retval << (@tick_label_style.scale_dy(t) || i['scale']) retval[0] += 1 return retval end
Whether the axis is vertical or not
# File lib/ctioga2/graphics/styles/axes.rb, line 318 def vertical? return @location.vertical? end