App-Widget-ChartDirector

 view release on metacpan or  search on metacpan

lib/App/Widget/ChartDirector.pm  view on Meta::CPAN


        if ($#{$spec->{y_labels}} <= 0) {
            $height = $spec->{height};  
        }
    }

   
    my $graph_height_increment = 0; 
    my $fontsize = 10;
    if ($spec->{x_label_pos}) {
        if ($#$x > 30 && $total_x_length > $width/8 && $x->[0] !~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/) {
            for (my $i = 30; $i <= $#$x; $i++ ) {
                $fontsize = $fontsize - 0.1;
                $fontsize = 1 if ($fontsize < 1);
            }  
            $fontsize += ceil(($width - $spec->{width})/$#$x) - 1 if ($#$x > 50);
        }
        $self->{fontsize} = $fontsize;
        if ($total_x_length > $width/8  && $x->[0] !~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/) {
            $graph_height_increment = 1/2 * $x_values[-1] * floor ($fontsize); 
            $height += $graph_height_increment;   
        }
    }
   
    my $c = new XYChart($width, $height);

    my $graph_adjusted_height = $height - $spec->{height}-$graph_height_increment;
    my ($top_margin_adjusted,$bottom_margin_adjusted);

    if ($legend_pos eq "top" ) {
        $top_margin_adjusted    = $top_margin+$graph_adjusted_height;
        $bottom_margin_adjusted = $height-$top_margin-$bottom_margin-$graph_adjusted_height-$graph_height_increment;
    }
    elsif ($legend_pos eq "bottom") {
        $top_margin_adjusted    = $top_margin;
        $bottom_margin_adjusted = $height-$top_margin-$bottom_margin-$graph_adjusted_height-$graph_height_increment;
    }
    else {
        $top_margin_adjusted    = $top_margin;
        $bottom_margin_adjusted = $height-$top_margin-$bottom_margin-$graph_height_increment;
    }
    my $plot_area = $c->setPlotArea($left_margin , $top_margin_adjusted,
        $width-$left_margin-$right_margin,
        $bottom_margin_adjusted);

    $spec->{plot_area_x}      = $left_margin;
    $spec->{plot_area_y}      = $top_margin_adjusted;
    $spec->{plot_area_width}  = $width - $left_margin - $right_margin;
    $spec->{plot_area_height} = $bottom_margin_adjusted;
    $spec->{plot_bgcolor}     = $plot_bgcolor;

    $plot_area->setBackground(hex($plot_bgcolor), hex($plot_bgcolor));

    $c->addTitle($spec->{title}, "arialbd.ttf", 12, hex($titlecolor)) if ($spec->{title});

    if ($y_max_zero == 0) {
        $c->yAxis()->setMargin($top_margin_adjusted + 15);
    }

    #Add a legend box at (55, 22) using horizontal layout, with transparent
    #background
    my $legend;
    if ($spec->{y_labels}) {
        my $x_adj = 0;
        my $y_adj = -2;
        if ($spec->{"3D"}) {
            $x_adj += 5;
            $y_adj += -5;
        }
        
        if (($#{$spec->{y_labels}} > 0) && ($legend_pos eq "top" || $legend_pos eq "bottom")) { 
            if ($legend_pos eq "top" ) {
                $legend = $c->addLegend($right_margin, $top_margin + $y_adj, 0,"arial.ttf",10);
            }
            elsif ($legend_pos eq "bottom" ) {
                $legend = $c->addLegend($right_margin, $height - $graph_adjusted_height - $top_margin/4 , 0,"arial.ttf",10);
            }
            $legend->setBackground(hex($plot_bgcolor)); 
            $legend->setMargin(5);
            $legend->setWidth($legend_width);
            $legend->setCols($num_legend_columns);
            $legend->setTruncate($legend_width,1); 
        }
        else {
            $legend = $c->addLegend($left_margin+$x_adj, $top_margin+$y_adj, 0);
            $legend->setBackground($perlchartdir::Transparent);
            $legend->setMargin(5);
        }
    }
        
    # To handle the situation when the graph wrapping happens.
    if ($legend_pos eq "top" || $legend_pos eq "bottom") {
        my $graph_count = $spec->{graph_count} || 1; 
        $spec->{height} = $height if ($graph_count == 1);
    }

    if ($spec->{x_label_pos} && $total_x_length > $width/8  && $x->[0] !~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/) {
        $spec->{height} = $height;
        $spec->{width} = $width;
    }
        
    $c->yAxis()->setTitle($spec->{y_title}, "arial.ttf", 10, hex($y_titlecolor)) if ($spec->{y_title});
    $c->setBackground(hex($bgcolor));
    $c->yAxis()->setLabelStyle("arial.ttf", 10, hex($y_labelcolor));
    $c->xAxis()->setLabelStyle("arial.ttf", 10, hex($x_labelcolor));

    if ($spec->{add_mark} ne "" || $spec->{add_mark2} ne "") {
        my $value  = $spec->{add_mark};
        my $value2 = $spec->{add_mark2};
        my $color  = $spec->{add_mark_color};
        my $color2 = $spec->{add_mark_color2};

        $color  =~ s/^#//;
        $color  = "000000" if (!$color  || $color  eq "none");
        $color2 =~ s/^#//;
        $color2 = "000000" if (!$color2 || $color2 eq "none");

        my ($add_mark_vals);
        foreach my $data ([$value, $color], [$value2, $color2]) {
           my $hash = {};
           if (defined $data->[0]) {

lib/App/Widget/ChartDirector.pm  view on Meta::CPAN

        if ($y_mantissa > 0.5) {
            $y_max = $y_scale;
            $minor_tick = $y_max/10;
            $micro_tick = $y_max/20;
        }
        elsif ($y_mantissa > 0.2) {
            $y_max = 0.5 * $y_scale;
            $minor_tick = $y_max/25;
            $micro_tick = undef;
        }
        else {
            $y_max = 0.2 * $y_scale;
            $minor_tick = $y_max/10;
            $micro_tick = $y_max/20;
        }
        $major_tick = $y_max/5;
    }

    my $y_red    = $spec->{y_red} || ($y_max * 0.80);
    my $y_yellow = $spec->{y_yellow} || ($y_max * 0.60);

    #Meter scale is 0 - 100, with major tick every 20 units, minor tick every 10
    #units, and micro tick every 5 units
    $c->setScale(0, $y_max, $major_tick, $minor_tick, $micro_tick);

    #Set 0 - 60 as green (66FF66) zone
    $c->addZone(0, $y_yellow, 0, $radius, 0x66ff66);

    #Set 60 - 80 as yellow (FFFF33) zone
    $c->addZone($y_yellow, $y_red, 0, $radius, 0xffff33);

    #Set 80 - 100 as red (FF6666) zone
    $c->addZone($y_red, $y_max, 0, $radius, 0xff6666);

    #Add a text label centered at (100, 60) with 12 pts Arial Bold font
    if ($spec->{y_title}) {
        $c->addText($center_x, $center_y-int($radius * 0.35), $spec->{y_title},
            "arialbd.ttf", 11, $perlchartdir::TextColor, $perlchartdir::Center);
    }

    my $x_title = "";
    $x_title = $spec->{x_title} if ($spec->{x_title});
    if ($x) {
        $x_title .= ": " if ($x_title);
        $x_title .= $x->[0];
    }
    if ($spec->{y_labels}) {
        if ($x_title) {
            $x_title .= " ($spec->{y_labels}[0])";
        }
        else {
            $x_title = $spec->{y_labels}[0];
        }
    }
    if ($x_title) {
        $c->addText($center_x, $center_y+18, $x_title,
            "arialbd.ttf", 10, $perlchartdir::TextColor, $perlchartdir::Center);
    }

    #Add a text box at the top right corner of the meter showing the value formatted
    #to 2 decimal places, using white text on a black background, and with 1 pixel
    #3D depressed border
    $c->addText($center_x + int($radius * 0.7), $center_y - int($radius * 1.0),
        $c->formatValue($value, "2"),
        "arial.ttf", 8, 0xffffff)->setBackground(0x0, 0, -1);

    #Add a semi-transparent blue (40666699) pointer with black border at the
    #specified value
    $value = $y_max if ($value > $y_max);
    $value = 0 if ($value < 0);
    $c->addPointer($value, 0x40666699, 0x0);
    $c->makeChart($spec->{image_path});
    &App::sub_exit() if ($App::trace);
}

sub write_pie_graph_image {
    &App::sub_entry if ($App::trace);
    my ($self, $spec) = @_;

    my $c  = $self->new_pie_chart($spec);
    my $x  = $self->get_x($spec);
    my $yn = $self->get_y($spec);

    my $data;
    foreach my $y (@$yn) {  push (@$data, @{$y});  }

    if ($#$x > 0) {
        $c->setData($data, $x);
    }
    else {
        $c->setData($data, $spec->{y_labels});
    }

    # The depths for the sectors
    #my $depths = [30, 20, 10, 10];
    #$c->set3D2($depths);
    #$c->setStartAngle(225);

    $c->set3D() if ($spec->{"3D"});
    $c->makeChart($spec->{image_path});
    &App::sub_exit() if ($App::trace);
}

#my $data = [25, 18, 15, 12, 8, 30, 35];
##The labels for the pie chart
#my $labels = ["Labor", "Licenses", "Taxes", "Legal", "Insurance", "Facilities",
#    "Production"];
##Create a PieChart object of size 360 x 300 pixels
#my $c = new PieChart(360, 300);
##Set the center of the pie at (180, 140) and the radius to 100 pixels
#$c->setPieSize(180, 140, 100);
##Add a title to the pie chart
#$c->addTitle("Project Cost Breakdown");
##Draw the pie in 3D
#$c->set3D();
##Set the pie data and the pie labels
#$c->setData($data, $labels);

# TODO: This one doesn't work yet
sub write_step_graph_image_step {
    &App::sub_entry if ($App::trace);
    my ($self, $spec) = @_;
    require "perlchartdir.pm";
    #Create a XYChart object of size 500 x 270 pixels, with a pale blue (0xe0e0ff)
    #background, a light blue (0xccccff) border, and 1 pixel 3D border effect.
    my $c = new XYChart(600, 350, 0xe0e0ff, 0xccccff, 1);  #800
    #Set the plotarea at (50, 50) and of size 420 x 180 pixels, using white
    #(0xffffff) as the plot area background color. Turn on both horizontal and
    #vertical grid lines with light grey color (0xc0c0c0)

    $c->setPlotArea(50, 50, 320, 260, 0xffffff)->setGridColor(0xc0c0c0, 0xc0c0c0); #720

    #Add a legend box at (55, 25) (top of the chart) with horizontal layout. Use 10
    #pts Arial Bold Italic font. Set the background and border color to Transparent.
    $c->addLegend(55, 20, 0, "arialbi.ttf", 10)->setBackground($perlchartdir::Transparent);

    #Add a title to the chart using 14 points Times Bold Itatic font, using blue
    #(0x9999ff) as the background color
    $c->addTitle("Rate History", "arialbi.ttf", 12)->setBackground(0x9999ff);

    #Set the y axis label format to display a percentage sign
    #$c->yAxis()->setLabelFormat("{value}%");

    my $labels = $spec->{labels} || [ "Unknown" ];
    my $default_colors =
        [ 0x0000ff, 0x00ff00, 0xff0000, 0x00ffff, 0xff00ff, 0xffff00,
          0x111199, 0x119911, 0x991111, 0x119999, 0x991199, 0x999911,
          0x3333dd, 0x33dd33, 0xdd3333, 0x33dddd, 0xdd33dd, 0xdddd33,
          0x2222bb, 0x22bb22, 0xbb2222, 0x22bbbb, 0xbb22bb, 0xbbbb22 ];
    my $colors = $spec->{colors} || $default_colors;

    my ($label, $color, $step_xaxis, $xaxis, $yaxis, $layer);
    for (my $i = 0; $i <= $#$labels; $i++) {
        $label = $labels->[$i];
        $color = $colors->[$i] || 0;
        if ($color =~ /^0[xX][0-9A-Fa-f]+$/) {
            $color = eval $color;
        }
        $xaxis = $spec->{"x$i"} || [ $i, $i+1, $i+2, $i+3 ];
        $yaxis = $spec->{"y$i"} || [ $i, $i+1, $i+2, $i+3 ];

        # set the xAxis scale
        #$c->xAxis()->setLinearScale($xaxis->[0] - 1, $xaxis->[$#$xaxis], 1, 0);
        $c->xAxis()->setAutoScale(0,0,1);
        $c->yAxis()->setAutoScale(0,0,1);
        $c->xAxis()->setIndent(1);

        # we decrement the $step_xaxis values by a day to account for the fact that
        # the step function runs from left to right but that the spec-> occurred
        # from right to left.
        $step_xaxis = [ @$xaxis ];   # make a copy
        for (my $x = 0; $x <= $#$step_xaxis; $x++) {
            $step_xaxis->[$x]--;
        }

        #Add a step line layer to the chart and set the line width to 2 pixels
        $layer = $c->addStepLineLayer($yaxis, $color, $label);
        #$layer->setXData($step_xaxis);
        $layer->setLineWidth(2);

        # Add a line layer to the chart
        # $layer = $c->addLineLayer();
        # Add the line. Plot the points with a 9 pixel diamond symbol
        # $layer->addDataSet($yaxis, $color)->setDataSymbol( $perlchartdir::DiamondSymbol, 9);
        # Enable data label on the data points. Set the label format to nn%.
        # $layer->setDataLabelFormat("{value}");
    }

    print $c->makeChart($spec->{image_path});
    &App::sub_exit() if ($App::trace);
}

sub write_step_graph_image {
    &App::sub_entry if ($App::trace);
    my ($self, $spec) = @_;
    my $c = $self->new_xy_chart($spec);
    my $x = $self->get_x($spec);
    my $yn = $self->get_y($spec);



( run in 1.393 second using v1.01-cache-2.11-cpan-d8267643d1d )