App-Chart

 view release on metacpan or  search on metacpan

lib/App/Chart/Gtk2/HAxis.pm  view on Meta::CPAN

  $self->{'sizes'} = undef; # if no adj etc
  my $adj       = $self->{'adjustment'} || return;
  my $timebase  = $self->{'timebase'}   || return;
  # my $page_size = $adj->page_size       || return;
  # my $win       = $self->window         || return;

  my $sizes = $self->{'sizes'} = {};
  my $layout = $self->{'layout'};
  my $em     = Gtk2::Ex::Units::em($layout);
  my $line_height = Gtk2::Ex::Units::line_height ($layout);
  # my ($win_width, $win_height) = $win->get_size;
  my $x_step = $adj->get_pixel_per_value;

  $sizes->{'small_y'}  = POSIX::ceil (SMALL_TICK_LINE_FRAC * $line_height);
  $sizes->{'medium_y'} = POSIX::ceil (MEDIUM_TICK_LINE_FRAC * $line_height);
  $sizes->{'text_y'}
    = $sizes->{'medium_y'} + POSIX::ceil (MEDIUM_GAP_LINE_FRAC * $line_height);

  # establish $medium_timebase as the entry in @marks_timebase_list which
  # is one above $timebase
  {
    my @a = List::MoreUtils::after {$timebase->isa($_)}
      @marks_timebase_list;
    if (@a) {
      my $medium_timebase_class = $a[0];
      require Module::Load;
      Module::Load::load ($medium_timebase_class);

      # medium_timebase from the class name, with an arbitrary start base
      $sizes->{'medium_timebase'}
        = $medium_timebase_class->new_from_ymd (1970,1,5);
    }
  }

  my $label_x_offset = $sizes->{'label_x_offset'}
    = POSIX::ceil ($em * LABEL_LEFT_SPACE_EMS);
  foreach my $elem (@format_list) {
    my ($format_func, $timebase_class) = @$elem;

    require Module::Load;
    Module::Load::load ($timebase_class);

    # label_timebase from the class name, with an arbitrary start base
    my $label_timebase = $timebase_class->new_from_ymd (1970,1,5);
    my $t_width = $x_step
      * ($timebase->convert_from_floor ($label_timebase, 1)
         - $timebase->convert_from_floor ($label_timebase, 0));
    my $label_width = $label_x_offset
      + format_func_width ($layout, $format_func)
        + POSIX::ceil ($em * LABEL_RIGHT_SPACE_EMS);
    if (DEBUG) {
      print "$label_timebase label $label_width versus $t_width\n"; }

    if ($label_width < $t_width || $elem == $format_list[-1]) {
      $sizes->{'label_timebase'} = $label_timebase;
      $sizes->{'format_func'} = $format_func;
      last;
    }
  }

  if (DEBUG) { require Data::Dumper;
               print "HAxis sizes ", Data::Dumper::Dumper($sizes);
               print "  em=$em\n";
               print "  x_step=$x_step\n";
             }
  return $sizes;
}

# 'expose-event' class closure
sub _do_expose_event {
  my ($self, $event) = @_;
  if (DEBUG >= 2) { print "HAxis expose\n"; }
  my $sizes = ($self->{'sizes'} || _establish_bases($self));

  # must have an adjustment and timebase set and a non-empty page to draw
  # anything
  my $adj = $self->{'adjustment'}    || return Gtk2::EVENT_PROPAGATE;
  my $timebase = $self->{'timebase'} || return Gtk2::EVENT_PROPAGATE;
  # my $page_size = $adj->page_size    || return Gtk2::EVENT_PROPAGATE;

  my $layout = $self->{'layout'};
  my $style  = $self->style;
  my $state  = $self->state;
  my $gc     = $style->fg_gc($state);
  my $win    = $self->window;
  my $value_to_pixel_proc = $adj->value_to_pixel_proc;

  my $t_lo = POSIX::floor ($adj->value);
  my $t_hi = POSIX::ceil ($adj->value + $adj->page_size);
  if (DEBUG >= 2) { print "  values $t_lo to $t_hi  ",
                      $timebase->to_iso($t_lo), " to ",
                        $timebase->to_iso($t_hi), "\n"; }

  # small tick marks at every $timebase increment, unless that's every pixel
  #
  my $x_step = $adj->get_pixel_per_value;
  if ($x_step > 1) {
    my $small_y = $sizes->{'small_y'};
    $win->draw_segments ($gc, map { my $x = $value_to_pixel_proc->($_);
                                    ($x,0, $x,$small_y) }
                         ($t_lo .. $t_hi));
  }

  # medium tick marks at every $medium_timebase increment, if such a timebase
  #
  if (my $medium_timebase = $sizes->{'medium_timebase'}) {
    my $medium_y = $sizes->{'medium_y'};
    my $medium_t_lo
      = $medium_timebase->convert_from_floor ($timebase, $t_lo) - 1;
    my $medium_t_hi
      = $medium_timebase->convert_from_floor ($timebase, $t_hi) + 1;
    if (DEBUG >= 2) { print "  medium $medium_t_lo to $medium_t_hi  ",
                        $medium_timebase->to_iso($medium_t_lo), " to ",
                          $medium_timebase->to_iso($medium_t_hi), "\n"; }

    $win->draw_segments ($gc, map {
      my $t = $timebase->convert_from_floor ($medium_timebase, $_);
      my $x = $value_to_pixel_proc->($t);
      ($x,0, $x,$medium_y) }
                         ($medium_t_lo .. $medium_t_hi));
  }



( run in 1.006 second using v1.01-cache-2.11-cpan-39bf76dae61 )