SVG-TT-Graph

 view release on metacpan or  search on metacpan

lib/SVG/TT/Graph/TimeSeries.pm  view on Meta::CPAN

    croak sprintf("Series %d can not be stacked on previous series. Mismatched length.",
      scalar(@{$self->{'data'}}))
      unless (scalar(@sorted) == scalar(@$prev));

    for (my $i = 0; $i < @sorted; $i++) {
      # check the time value matches
      croak sprintf("Series %d can not be stacked on previous series. Mismatched timestamp at sample %d (time %s).",
        scalar(@{$self->{'data'}}),
        $i,
        HTTP::Date::time2iso($sorted[$i][0]))
      unless ($sorted[$i][0] == $prev->[$i][0]);

      $sorted[$i][1] += $prev->[$i][1];
    }
  }

  my %store = (
    'pairs' => \@sorted,
  );

  $store{'title'} = $conf->{'title'} if defined $conf->{'title'};
  push (@{$self->{'data'}},\%store);

  return 1;
}

#This is for internal use only, so we don't have to pass the time zone around.
#It gets local()ed below before it's used.
our $_TIME_ZONE;

sub burn {
  my ($self, @args) = @_;

  local $_TIME_ZONE = $self->{'config'}{'timescale_time_zone'};

  return $self->SUPER::burn(@args);
}

# Helper function for doing date/time calculations
# Current implementations of DateTime can be slow :-(
sub dateadd {
  my ($epoch,$value,$unit) = @_;
  my $dt = DateTime->from_epoch(epoch => $epoch);

  #This should have been local()ed prior to getting here.
  if ( $_TIME_ZONE ) {
    $dt->set_time_zone( $_TIME_ZONE );
  }

  $dt->add( $unit => $value );
  return $dt->epoch();
}

# override calculations to set a few calculated values, mainly for scaling
sub calculations {
  my $self = shift;

  # Need to set the timezone in order for x-axis labels to be 
  # formatted correctly by strftime:
  $ENV{'TZ'} = $self->{config}->{timescale_time_zone};
  POSIX::tzset() if ($] lt '5.008009');

  # run through the data and calculate maximum and minimum values
  my ($max_key_size,$max_time,$min_time,$max_value,$min_value,$max_x_label_length,$x_label);

  foreach my $dataset (@{$self->{data}}) {
    $max_key_size = length($dataset->{title}) if ((!defined $max_key_size) || ($max_key_size < length($dataset->{title})));

    foreach my $pair (@{$dataset->{pairs}}) {
      $max_time = $pair->[0] if ((!defined $max_time) || ($max_time < $pair->[0]));
      $min_time = $pair->[0] if ((!defined $min_time) || ($min_time > $pair->[0]));
      $max_value = $pair->[1] if (($pair->[1] ne '') && ((!defined $max_value) || ($max_value < $pair->[1])));
      $min_value = $pair->[1] if (($pair->[1] ne '') && ((!defined $min_value) || ($min_value > $pair->[1])));

      $x_label = strftime($self->{config}->{x_label_format},localtime($pair->[0]));
      $max_x_label_length = length($x_label) if ((!defined $max_x_label_length) || ($max_x_label_length < length($x_label)));
    }
  }
  $self->{calc}->{max_key_size} = $max_key_size;
  $self->{calc}->{max_time} = $max_time;
  $self->{calc}->{min_time} = $min_time;
  $self->{calc}->{max_value} = $max_value;
  $self->{calc}->{min_value} = $min_value;
  $self->{calc}->{max_x_label_length} = $max_x_label_length;

  # Calc the x axis scale values
  $self->{calc}->{min_timescale_value} = ($self->_is_valid_config('min_timescale_value')) ? str2time($self->{config}->{min_timescale_value}) : $min_time;
  $self->{calc}->{max_timescale_value} = ($self->_is_valid_config('max_timescale_value')) ? str2time($self->{config}->{max_timescale_value}) : $max_time;
  $self->{calc}->{timescale_range} = $self->{calc}->{max_timescale_value} - $self->{calc}->{min_timescale_value};

  # Calc the y axis scale values
  $self->{calc}->{min_scale_value} = ($self->_is_valid_config('min_scale_value')) ? $self->{config}->{min_scale_value} : $min_value;
  $self->{calc}->{max_scale_value} = ($self->_is_valid_config('max_scale_value')) ? $self->{config}->{max_scale_value} : $max_value;
  $self->{calc}->{scale_range} = $self->{calc}->{max_scale_value} - $self->{calc}->{min_scale_value};

  my ($range,$division,$precision);

  if ($self->_is_valid_config('scale_divisions')) {
    $division = $self->{config}->{scale_divisions};

    if ($division >= 1) {
      $precision = 0;
    }
    else {
      $precision = length($division) - 2;
    }
  }
  else {
    # Find divisions, format and range
    ($range,$division,$precision) = $self->_range_calc($self->{calc}->{scale_range});

    # If a max value hasn't been set we can set a revised range and max value
    if (! $self->_is_valid_config('max_scale_value')) {
      $self->{calc}->{max_scale_value} = $self->{calc}->{min_scale_value} + $range;
      $self->{calc}->{scale_range} = $self->{calc}->{max_scale_value} - $self->{calc}->{min_scale_value};
    }
  }
  $self->{calc}->{scale_division} = $division;

  $self->{calc}->{y_label_format} = ($self->_is_valid_config('y_label_format')) ? $self->{config}->{y_label_format} : "%.${precision}f";
  $self->{calc}->{data_value_format} = ($self->_is_valid_config('data_value_format')) ? $self->{config}->{data_value_format} : "%.${precision}f";



( run in 3.101 seconds using v1.01-cache-2.11-cpan-a49fcb8fa48 )