CGI-Application-Plugin-DBIProfile-0.07/ 0000755 0000764 0000764 00000000000 11276104343 020241 5 ustar tanderson tanderson CGI-Application-Plugin-DBIProfile-0.07/lib/ 0000755 0000764 0000764 00000000000 11276104343 021007 5 ustar tanderson tanderson CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/ 0000755 0000764 0000764 00000000000 11276104343 021411 5 ustar tanderson tanderson CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/ 0000755 0000764 0000764 00000000000 11276104343 023654 5 ustar tanderson tanderson CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/Plugin/ 0000755 0000764 0000764 00000000000 11276104343 025112 5 ustar tanderson tanderson CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/Plugin/DBIProfile/ 0000755 0000764 0000764 00000000000 11276104343 027031 5 ustar tanderson tanderson CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/Plugin/DBIProfile/Graph/ 0000755 0000764 0000764 00000000000 11276104343 030072 5 ustar tanderson tanderson CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/Plugin/DBIProfile/Graph/HTML/ 0000755 0000764 0000764 00000000000 11276104343 030636 5 ustar tanderson tanderson ././@LongLink 0000000 0000000 0000000 00000000146 00000000000 011566 L ustar root root CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/Plugin/DBIProfile/Graph/HTML/Horizontal.pm CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/Plugin/DBIProfile/Graph/HTML/Horizontal.p0000644 0000764 0000764 00000006753 11276104123 033157 0 ustar tanderson tanderson package CGI::Application::Plugin::DBIProfile::Graph::HTML::Horizontal;
###############################################################################
# Required inclusions.
###############################################################################
use strict;
use warnings;
use HTML::Template;
use List::Util qw(max);
###############################################################################
# Set up the colours we use for the bar graphs and the row backgrounds.
###############################################################################
my @COLOURS = qw(
2856E0 8DA6F0 C5D1F7 445896 222C4B 687AB0 9FA9C8
FFAB2E FFD596 FFEACB AA854D 554227 BFA071 DFCDB1
);
my @ROW_BGS = qw(
FFFFFF EEEEFF
);
###############################################################################
# Subroutine: build_graph($self, %opts)
# Parameters: $self - CAP::DBIProfile object
# %opts - Graphing options
###############################################################################
# Builds a horizontal bar graph based on the provided '%opts', and returns the
# HTML for that graph back to the caller.
###############################################################################
sub build_graph {
my ($self, %opts) = @_;
my $data = $opts{'data'};
my $tags = $opts{'tags'};
# calculate widths for the bar graphs
my $max = max( @{$data} ) || 1;
my @widths = map { ($_ / $max) * 300 } @{$data};
# assemble data set for HTML::Template
my $cols = [
map { { 'width' => $widths[$_],
'value' => $data->[$_],
'tag' => $tags->[$_],
'colour' => $COLOURS[ $_ % scalar @COLOURS ],
'row_bg' => $ROW_BGS[ $_ % scalar @ROW_BGS ],
} }
(0 .. $#widths)
];
# template body
my $body = q{
">
; width: px;">
};
# generate report using HTML::Template
my $tmpl = HTML::Template->new(
die_on_bad_params => 1,
loop_context_vars => 1,
scalarref => \$body,
);
$tmpl->param('cols', $cols);
return $tmpl->output();
}
1;
=head1 NAME
CGI::Application::Plugin::DBIProfile::Graph::HTML::Horizontal - Horizontal bar graph for CAP::DBIProfile
=head1 SYNOPSIS
# In startup.pl, or your CGI::Application class
BEGIN {
$ENV{'CAP_DBIPROFILE_GRAPHMODULE'} = 'CGI::Application::Plugin::DBIProfile::Graph::HTML::Horizontal';
};
=head1 DESCRIPTION
C implements a
basic/simple horizontal bar graph for C.
=head1 AUTHOR
Graham TerMarsch (cpan@howlingfrog.com)
=head1 COPYRIGHT
Copyright (C) 2007, Graham TerMarsch. All Rights Reserved.
This is free software; you can redistribute it and/or modify it under the same
license as Perl itself.
=head1 SEE ALSO
L,
L.
=cut
CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/Plugin/DBIProfile/Graph/HTMLBarGraph.pm 0000644 0000764 0000764 00000006306 11276104123 032604 0 ustar tanderson tanderson package CGI::Application::Plugin::DBIProfile::Graph::HTMLBarGraph;
use strict;
use HTML::Template;
use HTML::BarGraph;
# NOTE: HTML::BarGraph is a little broken on its pure HTML output.
# if you have issues, try changing the "bartype" to "pixel", and
# setup the pixel directory ("/dbiprofile_images") in your webroot.
# NOTE: HTML::BarGraph is also pure broken.. can't call graph more
# than once, cause your maxval scaling will stick!
sub build_graph
{
my $proto = shift;
my $class = ref($proto) || $proto;
my %opts = @_;
#my $self = { };
#bless $self, $class;
$opts{data} ||= [];
my $stmt_count = @{$opts{data}};
my $title = "Top $stmt_count statements"; # by total runtime
my $tag = 1;
my $tags = [ map { $tag++ } @{$opts{data}} ];
my %defs = (
direction => 'v',
graphminsize => 50,
bartype => 'html', # pixel or html
pixeldir => '/dbiprofile_images',
pixelfmt => 'PNG',
barlength => 150,
barwidth => 10,
#baraspect => 0.5,
colors => ["#7187C7"], # this is color per-dataset.
data => [ ],
tags => $tags,
setspacer => 0,
#highlighttag => undef,
#highlightpos => [],
addalt => 1,
showaxistags => 1,
showvalues => 1,
valuesuffix => '', # s
valueprefix => '',
bordertype => 'flat', # reised or flat
bordercolor => 'black',
borderwidth => '3',
bgcolor => 'white',
textcolor => 'black',
title => $title,
titlecolor => 'black',
titlealign => 'center',
fontface => 'Verdana,Arial,San-Serif',
xlabel => '',
ylabel => 'Seconds',
xlabelalign => 'center',
ylabelalign => 'middle',
labeltextcolor => 'black',
labelbgcolor => '#aaaaaa',
);
%defs = (%defs, %opts);
return HTML::BarGraph::graph(%defs);
}
1;
__END__
=head1 NAME
CGI::Application::Plugin::DBIProfile::Graph::HTMLBarGraph - If it weren't for HTML::BarGraph bugs, this would work.
=head1 DO NOT USE THIS
This is provided because I had it done, and it provides another example, but there are bugs in HTML::BarGraph.
If HTML::BarGraph ever gets fixed, this will start to work correctly. The problem is its use of globals to track things like $maxval, which throws off scaling of the graph for subsequent calls to graph().
=head1 BUGS
HTML::BarGraph is not mod_perl safe. It has globals that track, for instance, $maxval. That doesn't get reset accross calls to graph(), so whatever your largest value graphed is, that will set the scale of all graphs to come.
Actually, it's not even single process safe... you can't make more than one call to graph().
=head1 SEE ALSO
L
=head1 AUTHOR
Joshua I Miller, L
=head1 COPYRIGHT & LICENSE
Copyright 2007 Joshua Miller, all rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
=cut
CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/Plugin/DBIProfile/Graph/GDGraphInline.pm 0000644 0000764 0000764 00000010704 11276104123 033041 0 ustar tanderson tanderson package CGI::Application::Plugin::DBIProfile::Graph::GDGraphInline;
use strict;
use Carp qw(carp);
use GD::Graph::bars;
use MIME::Base64 qw(encode_base64);
our $SIZE_WARNING = 1;
our $FORMAT = 'png';
our $WIDTH = 600;
our $HEIGHT = 300;
# setup colors, generated by
# http://wellstyled.com/tools/colorscheme/index-en.html
our @BARS = qw( 2856E0 8DA6F0 C5D1F7 445896 222C4B 687AB0 9FA9C8
FFAB2E FFD596 FFEACB AA854D 554227 BFA071 DFCDB1 );
sub build_graph
{
my $proto = shift;
my $class = ref($proto) || $proto;
my %opts = @_;
#my $self = { };
#bless $self, $class;
$opts{data} ||= [];
our @BARS;
my @bars = map { "#$_" } @BARS;
my $stmt_count = @{$opts{data}};
my $title = "Top $stmt_count statements"; # by total runtime
my $tag = 1;
my $tags = [ map { $tag++ } @{$opts{data}} ];
my %defs = (
tags => $tags,
data => [],
title => $title,
ylabel => '',
);
# merge options with defaults.
%opts = (%defs, map { $_ => $opts{$_} }
grep { defined $opts{$_} }
keys %opts );
# build the graph image
my $graph_data;
{
our @BARS;
my $graph = GD::Graph::bars->new($WIDTH, $HEIGHT);
$graph->set(transparent => 0,
bgclr => '#FFFFFF',
legend_placement => 'BC',
x_ticks => 0,
cycle_clrs => 1,
bar_spacing => 5,
shadow_depth => 2,
dclrs => [ map { "#$_" } @BARS ],
);
$graph->set(title => $opts{title});
$graph->set(y_label => $opts{ylabel});
my $gd = $graph->plot([ $opts{tags}, $opts{data} ]);
$graph_data = $gd->png if $FORMAT eq 'png';
$graph_data = $gd->gif if $FORMAT eq 'gif';
$graph_data = $gd->jpeg if $FORMAT eq 'jpeg';
}
# return an inline image tag.
my $base64 = encode_base64($graph_data);
my $string = 'data:image/'.$FORMAT.';base64,'.$base64;
my $l = length($string);
if ($l > 4096 && $SIZE_WARNING) {
carp "Image is too big (encoded length $l > 4096)";
}
my $content = qq(
=item L
=back
=head1 SEE ALSO
=over
=item L
=item L
=back
=head1 AUTHOR
Joshua I Miller, L
=head1 COPYRIGHT & LICENSE
Copyright 2007 Joshua Miller, all rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
=cut
CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/Plugin/DBIProfile/Graph/SVGTT.pm 0000644 0000764 0000764 00000011230 11276104123 031330 0 ustar tanderson tanderson package CGI::Application::Plugin::DBIProfile::Graph::SVGTT;
use strict;
use CGI();
use SVG::TT::Graph::Bar;
our $WIDTH = 600;
our $HEIGHT = 300;
sub import
{
my $c = scalar caller;
$c->add_callback('init', \&_add_runmode);
}
sub _add_runmode
{
my $self = shift;
$self->run_modes( dbiprof_graph_svgtt => \&graph );
}
sub graph
{
my $self = shift;
my $q = $self->query();
my %opts = (
title => $q->param('title'),
ylabel => $q->param('ylabel'),
data => [ $q->param('data') ],
tags => [ $q->param('tags') ],
);
$opts{data} ||= [];
my $stmt_count = @{$opts{data}};
my $title = "Top $stmt_count statements"; # by total runtime
my $tag = 1;
my $tags = [ map { $tag++ } @{$opts{data}} ];
my %defs = (
tags => $tags,
data => [],
title => $title,
ylabel => '',
);
# merge options with defaults.
%opts = (%defs, map { $_ => $opts{$_} }
grep { defined $opts{$_} }
keys %opts );
# build the graph image
my $graph_data;
{
# BUG in SVG::TT::Graph... if all values are less than 0.5,
# the code to determine the scale ticks does an illegal division by zero
# So, we turn on 'scale_integers' if that's the case.
my $maxval = 0;
foreach (@{$opts{data}}) {
$maxval = $_ if $_ > $maxval;
}
my %extra_opt = ($maxval < 0.5) ? (scale_integers => 1) : ();
my $graph = SVG::TT::Graph::Bar->new({
width => $WIDTH,
height => $HEIGHT,
fields => $opts{tags},
graph_title => $opts{title},
y_title => $opts{ylabel},
show_y_title => 1,
show_y_labels => 1,
show_graph_title => 1,
%extra_opt,
});
$graph->add_data({
data => $opts{data},
title => $opts{title},
});
$graph_data = $graph->burn();
}
$self->header_add(-type => 'image/svg+xml');
return $graph_data;
}
sub build_graph
{
my $proto = shift;
my $class = ref($proto) || $proto;
my %opts = @_;
my $mode_param = $opts{mode_param} || 'rm';
my @url;
push(@url, $mode_param.'=dbiprof_graph_svgtt');
push(@url, 'ylabel=' .CGI::escape($opts{ylabel}) );
push(@url, 'title=' .CGI::escape($opts{title}) );
my @data = map { 'data=' .CGI::escape($_) }
ref($opts{data}) ? @{$opts{data}} : ();
push(@url, @data);
my @tags = map { 'tags=' .CGI::escape($_) }
ref($opts{tags}) ? @{$opts{tags}} : ();
push(@url, @tags);
my $url = $opts{self}->query->url();
$url .= '?'.join('&', @url);
my $h_title = CGI::escapeHTML($opts{title});
#return qq(\n);
# embed/object/iframe... dunno which is best
# http://www.spartanicus.utvinternet.ie/embed.htm#svg
# return qq();
return qq();
}
1;
__END__
=head1 NAME
CGI::Application::Plugin::DBIProfile::Graph::SVGTT - SVT::TT::Graph::Bar Graph output for CAP:DBIProfile.
=head1 SYNOPSIS
# in httpd.conf
SetVar CAP_DBIPROFILE_GRAPHMODULE CGI::Application::Plugin::DBIProfile::Graph::SVGTT
PerlSetVar CAP_DBIPROFILE_GRAPHMODULE CGI::Application::Plugin::DBIProfile::Graph::SVGTT
# in your CGI::Application subclass (needed to install callback)
use CGI::Application;
use CGI::Application::Plugin::DBIProfile::Graph::SVGTT;
=head1 DESCRIPTION
This module provides a SVG::TT::Graph::Bars graphing option for CAP:DBIProfile.
This also provides an example of non-inline graphs for DBIProfile.
The following settings control the output:
=over
=item $CGI::Application::Plugin::DBIProfile::Graph::SVGTT::WIDTH
Width of output image.
=item $CGI::Application::Plugin::DBIProfile::Graph::SVGTT::HEIGHT
Height of output image.
=back
=head1 REQUIREMENTS
=over
=item L
=back
=head1 SEE ALSO
=over
=item L
=item L
=item L
=back
=head1 AUTHOR
Joshua I Miller, L
=head1 COPYRIGHT & LICENSE
Copyright 2007 Joshua Miller, all rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
=cut
CGI-Application-Plugin-DBIProfile-0.07/lib/CGI/Application/Plugin/DBIProfile/Graph/HTML.pm 0000644 0000764 0000764 00000014327 11276104123 031177 0 ustar tanderson tanderson package CGI::Application::Plugin::DBIProfile::Graph::HTML;
use strict;
use HTML::Template;
use List::Util qw(max);
# setup colors, generated by
# http://wellstyled.com/tools/colorscheme/index-en.html
our @BARS = qw( 2856E0 8DA6F0 C5D1F7 445896 222C4B 687AB0 9FA9C8
FFAB2E FFD596 FFEACB AA854D 554227 BFA071 DFCDB1 );
sub build_graph
{
my $proto = shift;
my $class = ref($proto) || $proto;
my %opts = @_;
#my $self = { };
#bless $self, $class;
$opts{data} ||= [];
our @BARS;
my @bars = map { "#$_" } @BARS;
my $stmt_count = @{$opts{data}};
my $title = "Top $stmt_count statements"; # by total runtime
my $tag = 1;
my $tags = [ map { $tag++ } @{$opts{data}} ];
my %defs = (
tags => $tags,
data => [],
title => $title,
ylabel => '',
barlength => 150,
barwidth => 10,
barcolors => \@bars,
);
# merge options with defaults.
%opts = (%defs, map { $_ => $opts{$_} }
grep { defined $opts{$_} }
keys %opts );
# rotate ylabel
$opts{ylabel} = join ' ', split(//, $opts{ylabel});
# get max value from dataset (XXX doesn't support negative values)
my $maxval = max(@{$opts{data}}) || 1;
# ratio of barlenth to values
my $ratio = $opts{barlength} / $maxval;
# all bar lengths
my @barlength = map { $_ || 1 }
map { sprintf('%0.0f', ($_ * $ratio)) }
@{$opts{data}};
# build data for HTML::Template
my $cols = [];
for (my $i=0; $i<@barlength; $i++) {
push(@$cols, {
tag => $opts{tags}->[$i],
value => $opts{data}->[$i],
barlength => $barlength[$i],
barwidth => $opts{barwidth},
barcolor => $opts{barcolors}[ $i % scalar @{$opts{barcolors}} ],
});
}
my $TEMPLATE = <
TMPL
my $t = HTML::Template->new(scalarref => \$TEMPLATE,
loop_context_vars => 1,
die_on_bad_params => 0, );
$t->param('title' => $opts{title});
$t->param('ylabel' => $opts{ylabel});
$t->param('cols' => $cols);
return $t->output;
}
1;
__END__
=head1 NAME
CGI::Application::Plugin::DBIProfile::Graph::HTML - VERY basic pure html vertical bar graphing for CAP:DBIProfile.
=head1 SYNOPSIS
# in httpd.conf
SetVar CAP_DBIPROFILE_GRAPHMODULE CGI::Application::Plugin::DBIProfile::Graph::HTML
PerlSetVar CAP_DBIPROFILE_GRAPHMODULE CGI::Application::Plugin::DBIProfile::Graph::HTML
=head1 DESCRIPTION
This module is provided as a basic implementation of graphing for CAP:DBIProfile. It can be used as an example to develop other, more sophisticated, graphing solutions.
=head1 GRAPH PLUGIN DEVELOPMENT
The graphing plugin must have a method called "build_graph", which must accept options as a hash.
It should return a scalar or scalar ref holding the HTML output needed to generate your graph.
The following options will be passed to the "build_graph" method:
=over
=item self
The cgiapp object.
=item mode_param
$self->mode_param - the runmode variable used to determine runmode (usefull for creating links back to ourselves).
=item title
A textual title for your graph. You don't have to use this, but is there if you want it.
=item ylabel
Label for values we're graphing. Either "Count" or "Seconds".
=item data
An array of the datapoints to graph.
=item tags
Labels for each datapoint which match the labels that will be used on the sql statement list (1 to however many items there are).
=back
The easiest graphs to implement are fully inline - ie. it doesn't need to make any external calls (no or