Class: CTioga::EdgesAndAxes::Axis

Inherits:
Object
  • Object
show all
Includes:
Log, Utils, Tioga::FigureConstants
Defined in:
lib/CTioga/axes.rb

Overview

A class that represents an axis.

Constant Summary collapse

Attributes =

The various attributes

[:line_width, :loc, :log_values, :type,
:ticks_inside, :ticks_outside, :visible]

Constants included from Utils

Utils::FrameNames, Utils::Locations, Utils::NaturalDistances, Utils::NaturalDistancesNonLinear

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

apply_margin_to_frame, compose_margins, frame_to_array, frames_str, framespec_str, inset_margins, interpret_arg, location_index, margin_hash, partition_nonlinear, partition_segment, #safe_float, side, side?

Methods included from Log

#identify, #init_logger, #logger, #logger_options, #spawn

Constructor Details

#initialize(which, ticks = nil) ⇒ Axis

which can be :x or :y



535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
# File 'lib/CTioga/axes.rb', line 535

def initialize(which, ticks = nil)
  @which = which
  case which
  when :x
    @loc = BOTTOM
  when :y
    @loc = LEFT
  when String
    # We have a named position, in which case a little
    # more tweaking needs to be done.
    if which =~ /(\w+)([+-].*)?/
      # OK, $1 is the position, and $2 is a position shift
      loc = EdgesAndAxes::parse_axis_position($1)
      if $2
        dim = Dimension.new($2)
      else
        dim = false
      end
      if dim
        @loc = [loc, dim]
      else
        @loc = loc
      end
    end
  end
  @ticks = ticks || TickLabels.new(:none)

  # Background lines.
  @lines_color = false
  @lines_style = Styles::Dashes
  @lines_width = false
end

Instance Attribute Details

#axis_to_realObject

The coordinate conversions blocks



532
533
534
# File 'lib/CTioga/axes.rb', line 532

def axis_to_real
  @axis_to_real
end

#lines_colorObject

The color of perpendicular lines, or false if no lines are to be drawn



523
524
525
# File 'lib/CTioga/axes.rb', line 523

def lines_color
  @lines_color
end

#lines_styleObject

The line style of perpendicular lines



526
527
528
# File 'lib/CTioga/axes.rb', line 526

def lines_style
  @lines_style
end

#lines_widthObject

The line width of perpendicular lines



529
530
531
# File 'lib/CTioga/axes.rb', line 529

def lines_width
  @lines_width
end

#real_to_axisObject

The coordinate conversions blocks



532
533
534
# File 'lib/CTioga/axes.rb', line 532

def real_to_axis
  @real_to_axis
end

#ticksObject

The corresponding TickLabels



519
520
521
# File 'lib/CTioga/axes.rb', line 519

def ticks
  @ticks
end

#whichObject

Which axis ?



516
517
518
# File 'lib/CTioga/axes.rb', line 516

def which
  @which
end

Instance Method Details

#axis_argument(t, container) ⇒ Object

Gets the argument to give to FigureMaker#show_axis and FigureMaker#axis_information.



656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
# File 'lib/CTioga/axes.rb', line 656

def axis_argument(t, container)
  if @which == :x or @which == :y
    return @loc
  end
  spec = {}
  if @loc.is_a? Array
    spec['location'] = @loc.first
  else
    spec['location'] = @loc
  end
  
  spec['type'] = @type if @type
  if val = prepare_major_ticks(t, container)
    spec['major_ticks'] = val[0]
    spec['labels'] = val[1].map { |v| v.to_s }
  end
  return spec
end

#axis_coordinate_boundaries(t, container) ⇒ Object

Returns the boundaries of the axis corresponding to the location of the axis



602
603
604
605
606
607
608
609
610
# File 'lib/CTioga/axes.rb', line 602

def axis_coordinate_boundaries(t, container)
  loc = (@loc.is_a?(Array) ? @loc.first : @loc)
  case loc
  when TOP, BOTTOM, AT_Y_ORIGIN
    return [t.bounds_left, t.bounds_right]
  when LEFT, RIGHT, AT_X_ORIGIN
    return [t.bounds_bottom, t.bounds_top]
  end
end

#draw_lines(t, container) ⇒ Object

Draws the background lines associated with this axis, if applicable.

This function requires Tioga SVN -r 482



679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
# File 'lib/CTioga/axes.rb', line 679

def draw_lines(t, container)

  return unless @lines_color
  # First, getting major ticks location from tioga
  info = t.axis_information(axis_argument(t, container))

  if info['vertical']
    x0 = t.bounds_left
    x1 = t.bounds_right
  else
    y0 = t.bounds_bottom
    y1 = t.bounds_top
  end

  t.context do
    t.stroke_color = @lines_color
    t.line_width = @lines_width || info['major_tick_width']
    t.line_type = @lines_style
    for val in info['major']
      if info['vertical']
        t.stroke_line(x0, val, x1, val)
      else
        t.stroke_line(val, y0, val, y1)
      end
    end
  end
end

#extension(t, scale = 1) ⇒ Object



725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
# File 'lib/CTioga/axes.rb', line 725

def extension(t, scale = 1)
  ext = 0
  f = [0,0,0,0]
  # First, we estimate the size:
  case @type
  when AXIS_WITH_MAJOR_TICKS_AND_NUMERIC_LABELS, 
    AXIS_WITH_TICKS_AND_NUMERIC_LABELS
    ext = (1 + (label_shift(t))) * label_scale(t) *
      t.default_text_scale * t.default_font_size
  else
    ext = 0
  end
  loc_idx = Utils::location_index(@loc)
  if loc_idx  # That is, left,right, top, bottom
    f[loc_idx] = ext
  end
  return f
end

#label_scale(t) ⇒ Object



716
717
718
719
720
721
722
723
# File 'lib/CTioga/axes.rb', line 716

def label_scale(t)
  scale = nil
  if @ticks
    scale = @ticks.scale
  end
  scale = t.send("#{@which}axis_numeric_label_scale") unless scale
  return scale
end

#label_shift(t) ⇒ Object



707
708
709
710
711
712
713
714
# File 'lib/CTioga/axes.rb', line 707

def label_shift(t)
  shift = nil
  if @ticks
    shift = @ticks.shift
  end
  shift = t.send("#{@which}axis_numeric_label_shift") unless shift
  return shift
end

#prepare_major_ticks(t, container) ⇒ Object

Prepares the major ticks/tick labels, in the case of a non-linear axis. These are returned as a

[tick position], [tick values]

Returns nil if no tick changes are applicable



617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
# File 'lib/CTioga/axes.rb', line 617

def prepare_major_ticks(t, container)
  if @real_to_axis
    # First, the naive version:
    
    x1, x2 = axis_coordinate_boundaries(t, container)

    y1 = @real_to_axis.call(x1)
    y2 = @real_to_axis.call(x2)

    # Now the y1, y2 segment is our mapping.
    # We make sure y1 < y2:
    if y1 > y2 
      y1, y2 = y2, y1
    end

    # We get information about what the axis would have been
    loc = (@loc.is_a?(Array) ? @loc.first : @loc)
    info = t.axis_information(loc)

    # First: we divide relatively naively
    number = info['major'].size

    values = Utils::partition_nonlinear(@real_to_axis, @axis_to_real,
                                        x1, x2, number + 1)

    # Now, we have the positions (or nearly so), we need to
    # convert that back to original
    
    positions = values.map(&@axis_to_real)

    return [positions, values]
    
  else
    return nil
  end
end

#setup(t, container) ⇒ Object

Setup attributes for the axis.



569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
# File 'lib/CTioga/axes.rb', line 569

def setup(t, container)
  # We readjust the position of the axis if the X or Y origin is
  # out of bounds
  case @loc
  when AT_X_ORIGIN
    bounds = Boundaries.new(container.internal_get_boundaries)
    case bounds.where_x?(0)
    when :left
      @loc = LEFT
    when :right
      @loc = RIGHT
    end
  when AT_Y_ORIGIN
    bounds = Boundaries.new(container.internal_get_boundaries)
    case bounds.where_y?(0)
    when :top
      @loc = TOP
    when :bottom
      @loc = BOTTOM
    end
  end
  for attr in Attributes
    if instance_variables.include?("@#{attr}")
      # The visible attribute cannot be explicitly set to true.
      next if attr == :visible && @visible
      val = instance_variable_get("@#{attr}")
      t.send("#{which}axis_#{attr}=", val)
    end
  end
end

#show(t, container) ⇒ Object

Manually shows the given element.



745
746
747
# File 'lib/CTioga/axes.rb', line 745

def show(t, container)
  t.show_axis(axis_argument(t, container))
end