Gadabout
view release on metacpan or search on metacpan
Gadabout.pm view on Meta::CPAN
sub GetTextSize{
die "Virtual function";
}
#
# End Virtual Classes
sub InitGraph{
my $self = shift;
my $width = shift;
my $height = shift;
$self->{num_data_sets} = 0;
$self->{perLegendHeight} = 30;
$self->{xpad} = 70;
$self->{ypad} = 50;
$self->{image_height} = $height;
$self->{image_width} = $width;
$self->SetGraphSize();
$self->InitImage();
$self->{xAxisSpacing} = 50;
$self->{yAxisSpacing} = 50;
$self->{vBarWidth} = 7; #for bar charts
$self->{xTickPadding} = 8;
$self->{yTickPadding} = 8;
$self->{yTitlePadding} = 5;
$self->{polygon_max_verts} = 2;
$self->CreateColor("white" , 255, 255, 255, 255);
$self->CreateColor("black" , 0 , 0 , 0 , 255);
$self->CreateColor("red" , 220, 0 , 0 , 200);
$self->CreateColor("lightred" , 255, 150, 150, 200);
$self->CreateColor("blue" , 0 , 0 , 220, 200);
$self->CreateColor("lightblue" , 0 , 0 , 220, 125);
$self->CreateColor("darkgray" , 120, 120, 120, 200);
$self->CreateColor("gray" , 180, 180, 180, 200);
$self->CreateColor("magenta" , 240, 0 , 240, 200);
$self->CreateColor("yellow" , 240, 240, 0 , 200);
$self->CreateColor("green" , 0 , 140, 0 , 200);
$self->CreateColor("lightgreen", 0 , 140, 0 , 125);
} # sub InitGraph
sub SetGraphSize{
my $self = shift;
my $noLegend = shift;
$noLegend = 0 if (!defined($noLegend));
if (!$self->{noLegend}) {
$self->{legendHeight} = $self->{perLegendHeight} * ($self->{num_data_sets} + 1);
} else {
$self->{legendHeight} = 0;
}
$self->{graph_height} = $self->{image_height} - (2 * $self->{ypad}) - $self->{legendHeight};
$self->{graph_width} = $self->{image_width} - (2 * $self->{xpad});
} # sub SetGraphSize
sub CreateColor{
my $self = shift;
my $name = shift;
my $red = shift;
my $green = shift;
my $blue = shift;
my $alpha = shift;
$alpha = 125 if (!defined($alpha));
if (($red >= 0) && ($red <= 255) && ($blue >= 0) && ($blue <= 255) &&($green >= 0) && ($green <= 255)) {
$self->{color}{$name} = {"red" => $red, "blue" => $blue, "green" => $green, "alpha" => $alpha};
$self->{color}{"translucent-" . $name} = {"red" => $red, "blue" => $blue, "green" => $green, "alpha" => $self->min(30,floor($alpha / 2))};
return $name;
}
else {
return 0;
}
} # sub CreateColor
sub SetTitle{
my $self = shift;
my $title = shift;
my $titleSize = $self->GetTextSize($title,0);
my $text_left = ($self->{image_width} / 2) - ($titleSize->{"width"} / 2);
$self->DrawText($self->{font},$text_left,5,$title,"black",0);
} # sub SetTitle
sub SetSubTitle{
my $self = shift;
my $subtitle = shift;
my $titleSize = $self->GetTextSize($subtitle,0);
my $text_left = ($self->{image_width} / 2) - ($titleSize->{"width"} / 2);
$self->DrawText($self->{font},$text_left,25,$subtitle,"black",0);
} # sub SetTitle
sub SetxTitle{
my $self = shift;
my $xtitle = shift;
$self->{xTitle} = $xtitle;
} # sub SetxTitle
sub SetyTitle{
my $self = shift;
my $ytitle = shift;
$self->{yTitle} = $ytitle;
} # sub SetyTitle
sub SetAxis2Title{
my $self = shift;
my $title = shift;
$self->{axis2Title} = $title;
} # sub SetAxis2Title
sub AddData{
my ($self, $xdata, $ydata, $name) = @_;
$name = "" if (!defined($name));
$self->SetGraphSize($self->{image_height},$self->{image_width});
$self->{legendText}[$self->{num_data_sets}] = $name;
#sort(@xdata);
my $dataSetIndex = $self->{num_data_sets};
for (my $i=0; $i < @$xdata; $i++){
$self->{data_set}[$dataSetIndex]{"x"}[$i] = $xdata->[$i];
$self->{data_set}[$dataSetIndex]{"y"}[$i] = $ydata->[$i];
}
my $XSize = @$xdata;
my $YSize = @$ydata;
$self->{num_points}[$self->{num_data_sets}] = $self->min($XSize, $YSize);
if ($self->{num_data_sets} == 0) {
$self->{xmax} = $self->ArrayMax($xdata);
$self->{xmin} = $self->ArrayMin($xdata);
}
else {
my $tmp_xmax = $self->ArrayMax($xdata);
my $tmp_xmin = $self->ArrayMin($xdata);
$self->{xmax} = $self->max($self->{xmax},$tmp_xmax);
$self->{xmin} = $self->min($self->{xmin},$tmp_xmin);
}
$self->{xdata_diff} = $self->{xmax} - $self->{xmin};
if (!$self->{xdata_diff}) {
$self->{xdata_diff} = 5;
}
if (!$self->{use_axis2}) {
if ($self->{num_data_sets} == 0) {
$self->SetYMax($self->ArrayMax($ydata));
$self->SetYMin($self->ArrayMin($ydata));
} else {
my $tmp_ymax = $self->ArrayMax($ydata);
my $tmp_ymin = $self->ArrayMin($ydata);
$self->SetYMax($self->max($self->{ymax},$tmp_ymax));
$self->SetYMin($self->min($self->{ymin},$tmp_ymin));
}
if ($self->{ymax} == $self->{ymin}) {
$self->{ydata_diff} = 10;
$self->SetYMax($self->{ymin} + $self->{ydata_diff});
} else {
$self->{ydata_diff} = $self->{ymax} - $self->{ymin};
}
}
else {
$self->{axis2_data}[$self->{num_data_sets}] = 1;
if (!defined(%{$self->{axis2}})) {
$self->{axis2}{"ymax"} = $self->ArrayMax($ydata);
$self->{axis2}{"ymin"} = $self->ArrayMin($ydata);
}
else {
my $tmp_ymax = $self->ArrayMax($ydata);
my $tmp_ymin = $self->ArrayMin($ydata);
Gadabout.pm view on Meta::CPAN
for (my $gridCount = $xStart; $gridCount <= $xEnd; ++$gridCount) {
my $gridx = $gridCount * $xTick;
$xLabelYMod = $xLabelYMod * -1;
my ($x0, $y0) = $self->translate($gridx,$self->{ymin});
$self->GraphDashedLine($gridx, $self->{ymin}, $gridx, $self->{ymax}, 2, 3, $color);
$self->DrawLine($x0, $y0 + 9 + $xLabelYMod, $x0, $y0 - 3, "black");
my $gridLabel;
if ($self->{xLabel}) {
$gridLabel = $self->{xLabel}[$gridx];
}
else {
$gridLabel = $gridx;
}
my $gridLabelSize = $self->GetTextSize($gridLabel,0);
$self->DrawText($self->{font},$x0 - ($gridLabelSize->{"width"} / 2),$y0 + 10 + $xLabelYMod,$gridLabel,"black",0);
my $lastdrawn = $xLabelYMod;
}
for (my $gridCount = $yStart; $gridCount <= $yEnd; $gridCount++) {
my $gridy = $gridCount * $yTick;
my ($x0, $y0) = $self->translate($self->{xmin},$gridy);
$self->GraphDashedLine($self->{xmin}, $gridy, $self->{xmax}, $gridy, 2, 3, $color);
$self->DrawLine($x0 - 3, $y0, $x0 + 3, $y0, "black");
if (defined($axis2_ytick)) {
$self->DrawLine($im_xmax - 3, $y0, $im_xmax + 3, $y0, "black");
}
my $strSize = $self->GetTextSize($gridy,0);
$self->{axis1Padding} = $self->max($self->{axis1Padding},$strSize->{width});
$self->DrawText($self->{font},$x0 - $strSize->{"width"} - $self->{xTickPadding},$y0 - ($strSize->{"height"} / 2),$gridy,"black",0);
if (defined($axis2_ytick) && ($axis2_ytick != 0)) {
my $axis2_gridy = ($gridCount - $yStart) * $axis2_ytick + $self->{axis2}{"ymin"};
my $strSize = $self->GetTextSize($axis2_gridy,0);
$self->{axis2Padding} = $self->max($self->{axis2Padding},$strSize->{"width"});
$self->DrawText($self->{font},$im_xmax + $self->{xTickPadding},$y0 - ($strSize->{"height"} / 2),$axis2_gridy,"black",0);
$self->{axis2LegendPad} = $self->max($self->{axis2LegendPad},length($axis2_gridy));
}
}
$self->DrawLine($im_xmax-1, $im_ymax, $im_xmax, $im_ymax, $color);
$self->DrawLine($im_xmax, $im_ymax+1, $im_xmax, $im_ymax, $color);
} # sub DrawGrid
sub LineGraph{
my ($self, $dataset, $color) = @_;
$self->{current_dataset} = $dataset;
$self->{legend}{$dataset}{'LineGraph'} = {"color" => $color};
my $lastx = $self->{data_set}[$dataset]{"x"}[0];
my $lasty = $self->{data_set}[$dataset]{"y"}[0];
for (my $i = 1; $i < $self->{num_points}[$dataset]; $i++) {
$self->GraphLine($lastx, $lasty, $self->{data_set}[$dataset]{"x"}[$i], $self->{data_set}[$dataset]{"y"}[$i], $color);
$lastx = $self->{data_set}[$dataset]{"x"}[$i];
$lasty = $self->{data_set}[$dataset]{"y"}[$i];
}
} #sub LineGraph
sub FilledLineGraph{
my $self = shift;
my $dataset = shift;
my $color = shift;
$self->{current_dataset} = -1;
my $min = $self->min($self->{ymin}, $self->{axis2}{ymin});
my ($graph_left, $graph_bottom) = $self->translate($self->{xmin},$min);
$self->{current_dataset} = $dataset;
$self->{legend}{$dataset}{'FilledLineGraph'} = {'color' => $color};
my ($last_x, $last_y) = $self->translate($self->{data_set}[$dataset]{"x"}[0],$self->{data_set}[$dataset]{"y"}[0]);
$graph_bottom = int($graph_bottom+.5);
my $first_x = int($last_x+.5);
my $first_y = int($last_y+.5);
my %graphed;
my @verts;
$verts[0] = {"x" => $first_x, "y" => $first_y};
$graphed{$first_x . "," . $first_y} = 1;
my $this_x;
my $this_y;
for (my $i=0; $i < $self->{num_points}[$dataset]; $i++) {
($this_x, $this_y) = $self->translate($self->{data_set}[$dataset]{"x"}[$i],$self->{data_set}[$dataset]{"y"}[$i]);
$this_x = int($this_x+.5);
$this_y = int($this_y+.5);
if (!scalar(@verts)) {
my $slope = ($this_y - $last_y) / ($this_x - $last_x);
$first_x = $last_x + 1;
$first_y = $last_y + int($slope+.5);
$verts[0] = {"x" => $first_x, "y" => $first_y};
$graphed{$first_x . "," . $first_y} = 1;
}
if (!defined($graphed{$this_x . "," . $this_y})) {
push(@verts, {"x" => $this_x, "y" => $this_y});
$graphed{$this_x . "," . $this_y} = 1;
}
if ($i % $self->{polygon_max_verts} == 0) {
if (!defined($graphed{$this_x . "," . $graph_bottom})) {
push(@verts,{"x" => $this_x, "y" => $graph_bottom});
$graphed{$this_x . "," . $graph_bottom} = 1;
}
if (!defined($graphed{$first_x . "," . $graph_bottom})) {
push(@verts,{"x" => $first_x , "y" => $graph_bottom});
$graphed{$first_x . "," . $graph_bottom} = 1;
}
$self->DrawFilledPolygon(\@verts,$color);
$last_x = $this_x;
$last_y = $this_y;
%graphed = ();
@verts = ();
}
}
if (!defined($graphed{$this_x . "," . $graph_bottom})) {
push(@verts, {"x" => $this_x, "y" => $graph_bottom});
$graphed{$this_x . "," . $graph_bottom} = 1;
}
if (!defined($graphed{$first_x . "," . $graph_bottom})) {
push(@verts,{"x" => $verts[0]{"x"} , "y" => $graph_bottom});
$graphed{$first_x . "," . $graph_bottom} = 1;
}
if (scalar(@verts) > 3) {
$self->DrawFilledPolygon(\@verts,$color);
}
} # sub FilledLineGraph
sub DrawLegend{
my $self = shift;
if (defined($self->{legend})) {
my $legend_top = $self->{graph_height} + 2 * $self->{ypad};
my $current_top = $legend_top;
$self->DrawText($self->{font},10,$legend_top - 18,"Legend:","black",0);
$self->DrawLine(10,$legend_top - 4,47,$legend_top - 4,"black");
my $dataset;
my $type;
my $datasetInfo;
my $legendInfo;
my $tmpHash = $self->{legend};
while (($dataset, $legendInfo) = each %$tmpHash) {
my $legend_left = 10;
while(($type, $datasetInfo) = each %$legendInfo) {
my $legendMod;
if (exists($legendInfo->{'FilledLineGraph'}) || exists($legendInfo->{'VBarGraph'})) {
$legendMod = 0;
} else {
$legendMod = 8;
}
if ($type eq "FilledLineGraph"){
$self->DrawFilledRectangle($legend_left,$current_top,15,15,$datasetInfo->{"color"});
}
else{
if ($type eq "DashedLineGraph"){
$self->DrawDashedLine($legend_left,$current_top + $legendMod, $legend_left + 15, $current_top + $legendMod, 3, 4, $datasetInfo->{"color"});
}
else{
if ($type eq "ScatterGraph"){
$self->DrawBrush($legend_left + 8,$current_top + $legendMod,$datasetInfo->{'shape'},$datasetInfo->{"color"});
}
else{
if ($type eq "LineGraph"){
$self->DrawLine($legend_left,$current_top + $legendMod, $legend_left + 15, $current_top + $legendMod, $datasetInfo->{"color"});
}
else{
if ($type eq "VBarGraph"){
$self->DrawGradientRectangle($legend_left + (15 - $self->{vBarWidth}) / 2, $current_top , $self->{vBarWidth}, 15, $datasetInfo->{"color"});
}
}
}
}
}
}
my $mesg;
if (defined($self->{axis2_data}[$dataset])) {
$mesg = " (Right Hand Scale)";
} else {
$mesg = "";
}
$legend_left += 20;
my $label;
if (defined($self->{legendText}[$dataset])){
$label = $self->{legendText}[$dataset];
}
else{
$label = "Dataset: " . $dataset;
}
$label = $label . $mesg;
$self->DrawText($self->{font}, $legend_left, $current_top, $label, "black", 0);
$current_top += 20;
#$dataset++;
}
}
} #sub DrawLegend
sub DrawAxis{
my $self = shift;
$self->{current_dataset} = 0;
$self->GraphLine($self->{xmin},$self->{ymin},$self->{xmax},$self->{ymin},"black");
$self->GraphLine($self->{xmin},$self->{ymin},$self->{xmin},$self->{ymax},"black");
if ($self->{show_axis2}) {
$self->GraphLine($self->{xmax},$self->{ymin},$self->{xmax},$self->{ymax},"black");
}
$self->DrawxTitle();
$self->DrawyTitle();
if ($self->{show_axis2}) {
$self->DrawAxis2Title();
}
$self->DrawLegend();
} # sub DrawAxis
sub showDebug{
my $self = shift;
my $i = 0;
foreach my $k ($self->{strDebug}) {
$self->DrawText($self->{font},5,10 * (++$i) - 5,$k,"black",0);
}
} # sub showDebug
sub ShowGraph{
my $self = shift;
$self->showDebug();
header ("Expires: 0"); # Date in the past
header ("Cache-Control: no-cache, must-revalidate"); # HTTP/1.1
header ("Pragma: no-cache"); # HTTP/1.0
$self->DrawImage();
} # sub ShowGraph
sub translateX{
my $self = shift;
my $xIn = shift;
my $xdata_diff = $self->{xdata_diff};
my $xmin = $self->{xmin};
if ($xdata_diff) {
return ($self->{graph_width} / $xdata_diff) * ($xIn - $xmin) + $self->{xpad};
}
} # sub translateX
Gadabout.pm view on Meta::CPAN
my $y = shift;
my $color = shift;
my $xshift = shift;
if (!defined($xshift)){
$xshift = 0;
}
my ($xpos, $ypos) = $self->translate($x,$y);
my ($xminpos, $yminpos) = $self->translate($self->{xmin},$self->{ymin});
my $width = $self->{vBarWidth};
my $height = abs($ypos - $yminpos);
$xpos = $xpos + $xshift;
$self->DrawGradientRectangle($xpos - floor($width / 2), $ypos, $width, $height, $color);
} #sub GraphVBar
sub SetGridLabel{
my $self = shift;
my $labels = shift;
my $axis = shift;
if ($axis eq "x") {
$self->{xLabel} = $labels;
} else {
$self->{yLabel} = $labels;
}
}
sub SetXGridLabel{
my $self = shift;
my $labels = shift;
$self->SetGridLabel($labels,"x");
}
sub SetYGridLabel{
my $self = shift;
my $labels = shift;
$self->SetGridLabel($labels,"y");
}
sub SetXAxisSpacing{
my $self = shift;
my $spacing = shift;
$self->{xAxisSpacing} = $spacing;
}#sub SetXAxisSpacing
sub SetYAxisSpacing{
my $self = shift;
my $spacing = shift;
$self->{yAxisSpacing} = $spacing;
}#sub SetYAxisSpacing
sub ScatterGraph{
my $self = shift;
my $dataset = shift;
my $shape = shift;
my $color = shift;
$self->{current_dataset} = $dataset;
$self->{legend}{$dataset}{'ScatterGraph'} = {"color" => $color, 'shape' => $shape};
reset($self->{data_set}[$dataset]{"x"});
for (my $i=0; $i < $self->{num_points}[$dataset]; $i++) {
my $x = $self->{data_set}[$dataset]{"x"}[$i];
my $y = $self->{data_set}[$dataset]{"y"}[$i];
$self->GraphBrush($x,$y,$shape,$color);
}
}#sub ScatterGraph
sub VBarGraph{
my $self = shift;
my $dataset = shift;
my $color = shift;
$self->{current_dataset} = $dataset;
$self->{legend}{$dataset}{'VBarGraph'} = {"color" => $color};
for (my $i = 0; $i < $self->{num_points}[$dataset]; $i++) {
$self->GraphVBar($self->{data_set}[$dataset]{"x"}[$i], $self->{data_set}[$dataset]{"y"}[$i], $color);
}
}#sub BarGraph
sub PieChart{
my $self = shift;
my $pieData = shift;
my $name = $pieData->{name};
my $data = $pieData->{data};
my $radMod = $pieData->{radMod};
my $title = $pieData->{title};
if (!defined($title)){
$title ="";
}
#my $maxLength = length($title);
my $maxLength = $self->GetTextSize($title,0);
$maxLength = $maxLength->{width};
foreach my $thisname (@$name) {
my $tempWidth = $self->GetTextSize($thisname,0);
$maxLength = $self->max($maxLength,$tempWidth->{width});
}
reset ($name);
my $pieProps = $self->InitPieChart();
my $xAngle = $pieProps->{"xAngle"};
my $yAngle = $pieProps->{"yAngle"};
my $zAngle = $pieProps->{"zAngle"};
my $dMod = $pieProps->{"dMod"};
my $defaultRadMod = $pieProps->{"radMod"};
my $startHeightMod = $pieProps->{"startHeightMod"};
my $edgeColor = $pieProps->{"edgeColor"};
my $maxDepth = $pieProps->{"maxDepth"};
my $titlePad = 15;
my $legendBoxHeight = 15;
my $legendBoxSpace = 8;
my $legendHeightMod = $legendBoxHeight + $legendBoxSpace + 1;
my $maxMod = $self->max($defaultRadMod,($self->ArrayMax($radMod)));
$self->{image_width} = $self->max($self->{image_width},$maxMod+(0.75 * $self->{image_width})); # + ($maxLength * 1));
my $radius = ($self->{image_width} - 10) * .2;
#my $radius = ($self->{image_width} - 10) * .3;
$self->{image_height} = $self->max(2 * ($radius + $maxMod/2) + $self->{ypad},scalar(@$data) * $legendHeightMod + $titlePad);
$self->InitGraph($self->{image_width},$self->{image_height});
my $color = $self->GeneratePieChartColors(scalar(@$data));
#$radius = ($self->{image_width} - 10) * .3;
$radius = $self->min(($self->{image_width} - 10-(.75*$maxMod)) * .2,($self->{image_height} - 40-(.75*$maxMod)) * .5);
my $absCenterX = int(($radius + ($radius / 10) + (.75*$maxMod)) + 20 +.5);
my $absCenterY = int($radius + 10 + .75*$maxMod +.5);
my $legend_left = 2 * $absCenterX;
my $legend_top = 10;
my $degreeSteps = 6;
if (defined($title)) {
$self->DrawText($self->{font},$legend_left,$legend_top,$title,"black",0);
$self->DrawLine($legend_left - 2,$legend_top + $titlePad,$legend_left + (length($title) * 5.2),$legend_top + $titlePad,"black");
$legend_top = $legend_top + 25;
}
#arsort($data);
my $total = 0;
for (my $i = 0; $i < scalar(@$data); $i++){
$total = $total + @$data->[$i];
}
if (!defined(@$data)) {
$color->[0] = "white";
$data->[0] = 0;
$total = 0;
}
my %piePolys;
my %side1Polys;
my %side2Polys;
my @edgePolys;
my %polyOrder;
my @pieColors;
my $end_angle = 360;
my $colorCount = 0;
reset($data);
for (my $pieceNumber = 0; $pieceNumber < scalar(@$data); $pieceNumber++){
my $value = $data->[$pieceNumber];
my $start_angle = $end_angle;
if ($total) {
$end_angle = $start_angle - (($value / $total) * 360);
} else {
$end_angle = 0;
}
if ($end_angle < 0) {
$end_angle = 0;
}
my $pieceRadMod;
if (defined(@$radMod->[$pieceNumber])){
$pieceRadMod = $radMod->[$pieceNumber];
}
else{
$pieceRadMod = $defaultRadMod;
}
my $bisector = ($start_angle + $end_angle) / 2;
my $centerx = $absCenterX + $pieceRadMod * cos($self->deg2rad($bisector));
my $centery = $absCenterY + $pieceRadMod * sin($self->deg2rad($bisector));
my $startDepth = $pieceNumber * $startHeightMod;
my $xPos;
my $yPos;
my $topPoint;
my $bottomPoint;
@{$piePolys{$pieceNumber}{"top"}} = ();
@{$piePolys{$pieceNumber}{"bottom"}} = ();
for (my $angle = $end_angle; $angle < ($start_angle - $self->min($degreeSteps/2,abs($start_angle - $end_angle) / 2)); $angle = $angle + $degreeSteps){
$xPos = $radius * cos($self->deg2rad($angle)) + $centerx;
$yPos = $centery + $radius * sin($self->deg2rad($angle));
$topPoint = $self->GetPerspectiveXY($absCenterX,$absCenterY,$xPos,$yPos,0,$xAngle,$yAngle,$zAngle);
$bottomPoint = $self->GetPerspectiveXY($absCenterX,$absCenterY,$xPos,$yPos,$dMod * $maxDepth,$xAngle,$yAngle,$zAngle);
push(@{$piePolys{$pieceNumber}{"top"}}, $topPoint);
push(@{$piePolys{$pieceNumber}{"bottom"}}, $bottomPoint);
if ($angle == $end_angle) {
push(@{$side1Polys{$pieceNumber}},$topPoint);
push(@{$side1Polys{$pieceNumber}},$bottomPoint);
}
}
$xPos = $radius * cos($self->deg2rad($start_angle)) + $centerx;
$yPos = $centery + $radius * sin($self->deg2rad($start_angle));
$topPoint = $self->GetPerspectiveXY($absCenterX,$absCenterY,$xPos,$yPos,0,$xAngle,$yAngle,$zAngle);
$bottomPoint = $self->GetPerspectiveXY($absCenterX,$absCenterY,$xPos,$yPos,$dMod * $maxDepth,$xAngle,$yAngle,$zAngle);
push(@{$piePolys{$pieceNumber}{"top"}},$topPoint);
push(@{$piePolys{$pieceNumber}{"bottom"}},$bottomPoint);
@{$edgePolys[$pieceNumber]} = @{$piePolys{$pieceNumber}{"top"}};
push(@{$edgePolys[$pieceNumber]} ,reverse @{$piePolys{$pieceNumber}{"bottom"}});
push(@{$side2Polys{$pieceNumber}},$topPoint);
push(@{$side2Polys{$pieceNumber}},$bottomPoint);
if (((scalar(@$data)) > 1) && ($value != $total)) {
$topPoint = $self->GetPerspectiveXY($absCenterX,$absCenterY,$centerx,$centery,0,$xAngle,$yAngle,$zAngle);
$bottomPoint = $self->GetPerspectiveXY($absCenterX,$absCenterY,$centerx,$centery,$dMod * $maxDepth,$xAngle,$yAngle,$zAngle);
push(@{$piePolys{$pieceNumber}{"top"}},$topPoint);
push(@{$piePolys{$pieceNumber}{"bottom"}},$bottomPoint);
push(@{$side1Polys{$pieceNumber}},$bottomPoint);
push(@{$side1Polys{$pieceNumber}},$topPoint);
push(@{$side2Polys{$pieceNumber}},$bottomPoint);
push(@{$side2Polys{$pieceNumber}},$topPoint);
}
my $orderX = $absCenterX + $radius * cos($self->deg2rad($bisector));
my $orderY = $absCenterY + $radius * sin($self->deg2rad($bisector));
my $depth;
my $order = $self->GetPerspectiveXY($absCenterX,$absCenterY,$orderX,$orderY,$dMod * $depth,$xAngle,$yAngle,$zAngle);
$polyOrder{$pieceNumber} = $order->{"y"};
if (defined($total)) {
$self->DrawFilledRectangle($legend_left,$legend_top,$legendBoxHeight,$legendBoxHeight,$color->[$colorCount]);
$self->DrawRectangle($legend_left,$legend_top,$legendBoxHeight,$legendBoxHeight,"black");
my $totalPercentage = ($total ? (int(($value / $total * 1000)+.5) / 10) : "0");
my $strLegend = " - " . @$name->[$pieceNumber] . ": " . @$data->[$pieceNumber] . " (" . $totalPercentage . "%)";
$self->DrawText($self->{font},$legend_left + 20, $legend_top, $strLegend,"black",0);
$legend_top = $legend_top + $legendBoxHeight + $legendBoxSpace;
$pieColors[$pieceNumber] = $colorCount;
$colorCount++;
}
}
foreach my $pieceNumber (sort keys %polyOrder){
$colorCount = $pieColors[$pieceNumber];
my $startDepth = $pieceNumber * $startHeightMod;
my $lastVert = scalar(@{$piePolys{$pieceNumber}{"bottom"}}) - 1;
$self->DrawPolygon($piePolys{$pieceNumber}{"bottom"}, $edgeColor);
$self->DrawLine($piePolys{$pieceNumber}{top}[$lastVert]{x},$piePolys{$pieceNumber}{top}[$lastVert]{y},$piePolys{$pieceNumber}{bottom}[$lastVert]{x}, $piePolys{$pieceNumber}{bottom}[$lastVert]{y},$edgeColor);
$self->DrawLine($piePolys{$pieceNumber}{"top"}[$lastVert - 1]{"x"},$piePolys{$pieceNumber}{"top"}[$lastVert - 1]{"y"},$piePolys{$pieceNumber}{"bottom"}[$lastVert - 1]{"x"},$piePolys{$pieceNumber}{"bottom"}[$lastVert - 1]{"y"},$edgeColor);
$self->DrawLine($piePolys{$pieceNumber}{"top"}[0]{"x"},$piePolys{$pieceNumber}{"top"}[0]{"y"},$piePolys{$pieceNumber}{"bottom"}[0]{"x"},$piePolys{$pieceNumber}{"bottom"}[0]{"y"},$edgeColor);
$self->DrawFilledPolygon($piePolys{$pieceNumber}{"bottom"}, "translucent-" . $color->[$colorCount]);
$self->DrawFilledPolygon($edgePolys[$pieceNumber], $color->[$colorCount]);
$self->DrawFilledPolygon($side1Polys{$pieceNumber}, "translucent-" . $color->[$colorCount]);
$self->DrawFilledPolygon($side2Polys{$pieceNumber}, "translucent-" . $color->[$colorCount]);
$self->DrawFilledPolygon($piePolys{$pieceNumber}{"top"}, $color->[$colorCount]);
$self->DrawPolygon($piePolys{$pieceNumber}{"top"}, $edgeColor);
}
} #sub PieChart
sub GeneratePieChartColors{
my $self = shift;
my $numData = shift;
my $alternate = shift;
if (!defined($alternate)){
$alternate = 1;
}
my $mult;
if ($alternate) {
$mult = 2;
} else {
$mult = 1;
}
my $interval = floor((768 * $mult) / $self->max($numData,1));
my @colors;
my $colorCount = 0;
for (my $i = 1; $i <= 768; $i = $i+$interval) {
my $colorMod = floor($i / 256);
my ($r, $g, $b);
if ($colorMod == 0){
$r = 256 - $i;
$g = $i - 1;
$b = 0;
}
Gadabout.pm view on Meta::CPAN
sub NoData{
my $self = shift;
$self->InitGraph(80,20);
$self->DrawText($self->{font},20,0, "No Data","black",0);
}
sub AddChart{
my $self = shift;
my $type = shift;
my $data1 = shift;
if (!defined($data1)){
$data1 = "";
}
if (!defined($self->{chartCount})) {
$self->{chartCount} = 0;
} else {
$self->{chartCount}++;
}
my $totalDataSets = scalar(@_) - 1;
if ($data1) {
for (my $i = 1; $i <= $totalDataSets; ++$i) {
push(@{$self->{chartData}[$self->{chartCount}]}, $_[$i]);
}
}
return ($self->{chartCount});
}
sub AddChartData($chartID,$data) {
my $self = shift;
my $chartID = shift;
my $data = shift;
push(@{$self->{chartData}[$chartID]}, $data);
} # sub AddChartData
sub VBarChart{
my $self = shift;
my $chartID = shift;
my $dataset;
$self->{current_dataset} = $dataset;
my $totalDataSets = scalar(@$self->{chartData}[$chartID]);
if ($totalDataSets) {
my $colors = $self->GeneratePieChartColors($totalDataSets,0);
my $offSet = 6;
my $count = ceil(($totalDataSets / 2) - $totalDataSets);
my %tempHash = %$self->{chartData}[$chartID];
while (my ($foo,$dataset) = each %tempHash) {
$self->{legend}{$dataset}{"VBarGraph"} = {"color" => @$colors[$foo]};
my $xOffset = $offSet * $count;
for (my $i = 0; $i < $self->{num_points}[$dataset]; $i++) {
$self->GraphVBar($self->{data_set}[$dataset]{"x"}[$i], $self->{data_set}[$dataset]{"y"}[$i], @$colors[$foo], $xOffset);
}
$count++;
}
return 1;
} else {
return 0;
}
} #sub VBarChart
sub ArrayMin{
my $self = shift;
my $x = shift;
my $i = 0;
my $tmpMin = $x->[$i];
for (my $i=1; $i<scalar(@$x); $i++){
if ($x->[$i] < $tmpMin){
$tmpMin = $x->[$i];
}
}
return $tmpMin;
}
sub ArrayMax{
my $self = shift;
my $x = shift;
my $i = 0;
my $tmpMax = $x->[$i];
for (my $i=1; $i<scalar(@$x); $i++){
if ($x->[$i] > $tmpMax){
$tmpMax = $x->[$i];
}
}
return $tmpMax;
}
sub min{
my $self = shift;
my $x = shift;
my $y = shift;
if ($x>$y){
return $y;
}
else{
return $x;
}
}
sub max{
my $self = shift;
( run in 2.386 seconds using v1.01-cache-2.11-cpan-8f98c5d2c55 )