18c04-1.php

来自「介绍PHP5的给类型函数应用」· PHP 代码 · 共 332 行

PHP
332
字号
<?php// A class for drawing charts that allows its configuration to be pushed//  into it via public propertiesclass MultiGraph {    // Public class members, all of these need filled in before drawing.    public $border_color; // Color of the border/text    public $grid_color;   // Color of the grid lines    public $data_color;   // Color of any data blocks    public $g;            // Graphics object    public $data;         // Data to turn into a graph    public $draw_border = true;           // Should the border be drawn?    public $horizontal_grid_segments = 5; // How many horizontal grid lines?    public $vertical_grid_segments = 0;   // How about vertical ones?    public $x = 0;    // X value of the upper left corner of CHART area    public $y = 0;    // Y value    public $w = 200;  // Width of actual chart area    public $h = 100;  // Height of actual chart area    public $point_size = 5;  // Size of data points when doing a Point Chart    public $y_axis_autolabel = true;  // Generate labels for Y axis?    public $x_axis_autolabel = true;  // Generate labels for X axis?    public $font = 'arial';  // Font to use    public $fontsize = 8;    // Size of font.    // Constructor method.  Requires the graphics object    public function __construct($graphics) {        // Store the graphics object        $this->g = $graphics;                // Go ahead and turn on antialiasing        imageantialias($this->g, true);    }        // Method to make it easy to set dimensions    public function setDimensions($x, $y, $w, $h) {        // Just do it        $this->x = $x;        $this->y = $y;        $this->h = $h;        $this->w = $w;    }    // The method that will draw a line graph to the screen!    public function drawLineGraph() {        // We are asked to draw a line graph.  First of all draw the borders        $this->_drawBorder();                // Calculate the conversion factors to scale data to space given        $yscale = $this->_calcYScale();        $xscale = $this->_calcXScale();                // Draw a grid if asked        $this->_drawHorizontal();                    $this->_drawVertical();                            // Now we are ready for the data (finally)        // We are doing a line graph, assume the key is the X value & sort.        // Since we are sorting, make a copy to not mess up the real data        $tmpdata = $this->data;        ksort($tmpdata);                        // Now step through it, drawing the lines as appropriate:        list($ldx, $ldy) = each($tmpdata);        while (list($dx, $dy) = each($tmpdata)) {            // Draw the line from the last x,y pair, to the current one            imageline($this->g,                 $this->x + $ldx * $xscale,                 $this->y + $this->h - $ldy * $yscale,                 $this->x + $dx * $xscale,                 $this->y + $this->h - $dy * $yscale,                 $this->data_color);                        // Reset data for next loop            $ldx = $dx;            $ldy = $dy;        }    }    // The method that will draw a point plot to the screen.    public function drawPointGraph() {        // We are asked to draw a point graph.  First draw the borders        $this->_drawBorder();                // Calculate the conversion factors to scale data to space given        $yscale = $this->_calcYScale();        $xscale = $this->_calcXScale();                // Draw a grid if asked        $this->_drawHorizontal();                    $this->_drawVertical();                            // Now we are ready for the data - Now step through it        foreach ($this->data as $dx => $dy) {            // Draw the point for this data:            imagefilledellipse($this->g, $this->x + $dx * $xscale,                 $this->y + $this->h - $dy * $yscale,                 $this->point_size, $this->point_size, $this->data_color);        }    }    // The method that will draw a bar graph    // NOTE:  Bar graphs assume that the keys of the array are     //        labels, not 'x' values.    public function drawBarGraph() {        // We've been asked to draw a Bar graph.  First draw the borders        $this->_drawBorder();                // Calculate the conversion factors to scale data to space given        $yscale = $this->_calcYScale();                // Draw a grid if asked        $this->_drawHorizontal();                    // Precalculate a few items to be efficient:        //  The width of each 'section':        $section = (float) $this->w / count($this->data);        //  The width of a bar, we want it 70% of section:        $bar = (int) ($section * 0.7);                 // Loop once per data item that we have - assume they are in order        $count = 0;        foreach ($this->data as $label => $val) {            $count++;                        // Draw the bar to the appropriate height & width:            // First as a colored filled rectangle:            imagefilledrectangle($this->g,                 $this->x + ($section * $count) - $bar,                 $this->y + $this->h,                 $this->x + ($section * $count),                 $this->y + $this->h - $val * $yscale,                 $this->data_color);            // Then as an outline:            imagerectangle($this->g, $this->x + ($section * $count) - $bar,                 $this->y + $this->h, $this->x + ($section * $count),                 $this->y + $this->h - $val * $yscale, $this->border_color);                            // Now, since vertical grids don't really exist for bar graphs            // We need to create the labels ourselves            if ($this->x_axis_autolabel) {                // Calculate the width of the box needed by the bounding box                $box = imagettfbbox($this->fontsize, 270,                    $this->font, $label);                $texwidth = abs($box[4] - $box[0]);                // Draw it going vertical                imagettftext($this->g,                     $this->fontsize, 270,                     ($this->x + ($section * $count)) -                             ($bar / 2) - ($texwidth / 2),                     $this->y + $this->h + 4,                     $this->border_color,                     $this->font,                     $label);            }        }    }    // Support function to draw the border:    private function _drawBorder() {        if ($this->draw_border) {            // Vertical one            imageline($this->g, $this->x, $this->y, $this->x,                 $this->h + $this->y, $this->border_color);            // Horizontal one            imageline($this->g, $this->x, $this->h+$this->y,                 $this->w + $this->x, $this->h + $this->y,                $this->border_color);        }    }        // Support function for calculating the Y scale    private function _calcYScale() {        // Add a fudge for visual purposes so it doesn't ever hit the top.        return (float) $this->h / $this->_calcYMax();    }    // Support function for calculating the X scale    private function _calcXScale() {        return (float) $this->w / $this->_calcXMax();    }        // Support function for calculating the maximum Y value, for scaling/etc    private function _calcYMax() {        // Add a fudge for visual purposes so it doesn't ever hit the top.        // Also force round it to only 2 significant digits        //  as this will make it look 'clean'        $max = (float) max($this->data) * 1.05;        // Get the 'length' of this:        $len = strlen((int)$max);        // Find a 2 digit ceiling, if less than 2 digits, just return it:        if ($len < 2) {            return $max;        } else {            // Keep the first two digits and pad with zeros:            return intval(substr($max, 0, 2) . str_repeat('0', $len - 2));        }    }        // Support function for calculating the maximum X value, for scaling/etc    private function _calcXMax() {        return max(array_keys($this->data));    }    // Support function for drawing the Horizontal Grid    private function _drawHorizontal() {        if ($this->horizontal_grid_segments) {            // Figure out their placement            foreach(range(1, $this->horizontal_grid_segments) as $hg) {                // Y height for this is:                $yheight = (int) $this->y + $this->h -                     ($hg * ($this->h / $this->horizontal_grid_segments));                imageline($this->g, $this->x + 1, $yheight,                     $this->w + $this->x, $yheight, $this->grid_color);                                    // Now, IF they wanted automatic labels, give 'em                if ($this->y_axis_autolabel) {                    // Calculate the value for here, and display it                    $ax_step = (int)(($this->_calcYMax() /                         $this->horizontal_grid_segments) * $hg);                                        // Calculate the width of the box needed to display                     //  this: Use the lower left X (0) and the upper right                    //  X (4) to calculate width:                    $box = imagettfbbox($this->fontsize, 0,                         $this->font, $ax_step);                    $texwidth = abs($box[4] - $box[0]);                    $texheight = abs($box[5] - $box[1]);                    // Draw it right justified:                    imagettftext($this->g, $this->fontsize, 0,                         $this->x - 3 - $texwidth, $yheight + $texheight / 2,                         $this->border_color, $this->font, $ax_step);                }            }        }    }        // Support function for drawing the Vertical Grid    private function _drawVertical() {        if ($this->vertical_grid_segments) {            // Figure out their placement            foreach(range(1, $this->vertical_grid_segments) as $vg) {                // X location for this is:                $xloc = (int) ($this->x +                      ($vg * ($this->w / $this->vertical_grid_segments)));                imageline($this->g, $xloc, $this->y,                     $xloc, $this->y + $this->h - 1, $this->grid_color);                // Now, IF they wanted automatic labels, give 'em                if ($this->x_axis_autolabel) {                    // Calculate the value for here, and display it                    $ax_step = (int)(($this->_calcXMax() /                         $this->vertical_grid_segments) * $vg);                                        // Calculate the width of the box needed to display                    //  this:  Use the lower left X (0) and the upper                     //  right X (4) to calculate width:                    $box = imagettfbbox($this->fontsize, 270,                         $this->font, $ax_step);                    $texwidth = abs($box[4] - $box[0]);                    // Draw it going vertical                    imagettftext($this->g, $this->fontsize, 270,                         $xloc - $texwidth / 2, $this->y + $this->h + 3,                         $this->border_color, $this->font, $ax_step);                }            }        }    }    }// Pre/setup for the date functions:date_default_timezone_set('America/New_York');// Create a blank image to test with.$gfx = imagecreatetruecolor(950, 650);// Declare a few colors$red = imagecolorallocate($gfx, 255, 0, 0);$manilla = imagecolorallocate($gfx, 255, 255, 245);$black = imagecolorallocate($gfx, 0, 0, 0);$lgray = imagecolorallocate($gfx, 200, 200, 200);// Color our backgroundimagefill($gfx, 0, 0, $manilla);// Initialize a new Multigraph$graph = new MultiGraph($gfx);$graph->border_color = $black;$graph->grid_color = $lgray;$graph->data_color = $red;$graph->vertical_grid_segments = 10;// Create some fake data//  Generate up to 50 random points of data, with random values:$chartdata = array();for ($i = 0; $i < 50; $i++) {    $chartdata[rand(1,200)] = rand(1,1000);}$graph->data = $chartdata;// Ok, output a line graph$graph->setDimensions(50, 50, 300, 200);$graph->drawLineGraph();// Now do it as a point graph with some changed grid parameters$graph->horizontal_grid_segments = 9;$graph->vertical_grid_segments = 15;$graph->setDimensions(50, 350, 300, 200);$graph->drawPointGraph();// Finally lets create a bar graph, we need new data for that, with labels.// Automatically generate some that is based on Month names.$bardata = array();foreach(range(1,12) as $mon) {    $bardata[date('F', mktime(0, 0, 0, $mon))] = rand(1,5000);}// Change some options, and display the BIG bar graph:$cyan = imagecolorallocate($gfx, 0, 255, 255);$graph->data_color = $cyan;$graph->fontsize = 11;$graph->horizontal_grid_segments = 12;$graph->setDimensions(450, 40, 400, 500);$graph->data = $bardata;$graph->drawBarGraph();// Output our sample as a PNGheader('Content-type: image/png');imagepng($gfx);?>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?