diff options
| author | artem <artem@97f52cf1-0a1b-0410-bd0e-c28be96e8082> | 2007-07-16 10:01:08 +0000 |
|---|---|---|
| committer | artem <artem@97f52cf1-0a1b-0410-bd0e-c28be96e8082> | 2007-07-16 10:01:08 +0000 |
| commit | 4e4aa7eb198963720b377cd568825309616dce8a (patch) | |
| tree | e1c0bb863be19aeb630bf5ef77fb8c3c8e27731f /frontends/php/include/classes/pie.inc.php | |
| parent | bac3a136113548551ad7320cc8a8ed7ecbb2e11a (diff) | |
- added pie graphs (Artem)
- added subclasses chart.inc.php and pie.inc.php, extending graph.inc.php (Artem)
git-svn-id: svn://svn.zabbix.com/trunk@4458 97f52cf1-0a1b-0410-bd0e-c28be96e8082
Diffstat (limited to 'frontends/php/include/classes/pie.inc.php')
| -rw-r--r-- | frontends/php/include/classes/pie.inc.php | 610 |
1 files changed, 610 insertions, 0 deletions
diff --git a/frontends/php/include/classes/pie.inc.php b/frontends/php/include/classes/pie.inc.php new file mode 100644 index 00000000..dd14bb41 --- /dev/null +++ b/frontends/php/include/classes/pie.inc.php @@ -0,0 +1,610 @@ +<?php +/* +** ZABBIX +** Copyright (C) 2000-2007 SIA Zabbix +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +**/ +?> +<?php +require_once "include/classes/graph.inc.php"; + +class Pie extends Graph{ + +function Pie($type = GRAPH_TYPE_PIE){ + parent::Graph($type); + + $this->background = false; + $this->sum = false; + $this->exploderad = 1; + $this->exploderad3d = 3; + $this->graphheight3d = 12; + $this->shiftlegendright = 17*7 + 7 + 10; // count of static chars * px/char + for color rectangle + space + $this->drawlegendallow = 1; +} + +function switchlegend($type=false){ + if($type && is_numeric($type)){ + $this->drawlegendallow = $type; + return $this->drawlegendallow; + } elseif($this->drawlegendallow == 0){ + $this->drawlegendallow = 1; + } else { + $this->drawlegendallow = 0; + } +return $this->drawlegendallow; +} + +function AddItem($itemid, $calc_fnc=CALC_FNC_AVG,$color=null, $type=null, $periods_cnt=null) +{ + if($this->type == GRAPH_TYPE_STACKED /* stacked graph */) + $drawtype = GRAPH_ITEM_DRAWTYPE_FILLED_REGION; + + $this->items[$this->num] = get_item_by_itemid($itemid); + $this->items[$this->num]['description']=item_description($this->items[$this->num]['description'],$this->items[$this->num]['key_']); + $host=get_host_by_hostid($this->items[$this->num]['hostid']); + + $this->items[$this->num]['host'] = $host['host']; + $this->items[$this->num]['color'] = is_null($color) ? 'Dark Green' : $color; + $this->items[$this->num]['calc_fnc'] = is_null($calc_fnc) ? CALC_FNC_AVG : $calc_fnc; + $this->items[$this->num]['calc_type'] = is_null($type) ? GRAPH_ITEM_SIMPLE : $type; + $this->items[$this->num]['periods_cnt'] = is_null($periods_cnt) ? 0 : $periods_cnt; + + $this->num++; +} + + +function selectData(){ + global $DB_TYPE; + + $this->data = array(); + + $now = time(NULL); + + if(isset($this->stime)){ + $this->from_time = $this->stime; + $this->to_time = $this->stime + $this->period; + } + else{ + $this->to_time = $now - 3600 * $this->from; + $this->from_time = $this->to_time - $this->period; + } + + $p = $this->to_time - $this->from_time; // graph size in time + $z = $p - $this->from_time % $p; //<strong></strong> + $x = $this->sizeX; // graph size in px + $strvaluelength = 0; // we need to know how long in px will be our legend + + for($i=0; $i < $this->num; $i++){ + + $type = $this->items[$i]['calc_type']; + + $from_time = $this->from_time; + $to_time = $this->to_time; + +// $calc_field = 'round('.$x.'*(mod(clock+'.$z.','.$p.'))/('.$p.'),0)'; /* required for 'group by' support of Oracle */ + $sql_arr = array(); + + if(($this->period / $this->sizeX) <= (ZBX_MAX_TREND_DIFF / ZBX_GRAPH_MAX_SKIP_CELL)){ + array_push($sql_arr, + 'SELECT h.itemid, i.lastvalue as lst, '. + ' avg(h.value) AS avg,min(h.value) AS min, '. + ' max(h.value) AS max,max(h.clock) AS clock '. + ' FROM history AS h LEFT JOIN items AS i ON h.itemid = i.itemid'. + ' WHERE h.itemid='.$this->items[$i]['itemid']. + ' AND h.clock>='.$from_time. + ' AND h.clock<='.$to_time. + ' GROUP BY h.itemid' + , + + 'SELECT hu.itemid, i.lastvalue as lst, '. + ' avg(hu.value) AS avg,min(hu.value) AS min,'. + ' max(hu.value) AS max,max(hu.clock) AS clock'. + ' FROM history_uint AS hu LEFT JOIN items AS i ON hu.itemid = i.itemid'. + ' WHERE hu.itemid='.$this->items[$i]['itemid']. + ' AND hu.clock>='.$from_time. + ' AND hu.clock<='.$to_time. + ' GROUP BY hu.itemid' + ); + } + else{ + array_push($sql_arr, + 'SELECT t.itemid, i.lastvalue as lst, '. + ' avg(t.value_avg) AS avg,min(t.value_min) AS min,'. + ' max(t.value_max) AS max,max(t.clock) AS clock'. + ' FROM trends AS t LEFT JOIN items AS i ON t.itemid = i.itemid'. + ' WHERE t.itemid='.$this->items[$i]['itemid']. + ' AND t.clock>='.$from_time. + ' AND t.clock<='.$to_time. + ' GROUP BY t.itemid' + ); + } + + $curr_data = &$this->data[$this->items[$i]['itemid']][$type]; + $curr_data->min = NULL; + $curr_data->max = NULL; + $curr_data->avg = NULL; + $curr_data->clock = NULL; + + foreach($sql_arr as $sql){ + $result=DBselect($sql); + + while($row=DBfetch($result)){ + $curr_data->min = $row['min']; + $curr_data->max = $row['max']; + $curr_data->avg = $row['avg']; + $curr_data->lst = $row['lst']; + $curr_data->clock = $row['clock']; + $curr_data->shift_min = 0; + $curr_data->shift_max = 0; + $curr_data->shift_avg = 0; + } + unset($row); + } + + switch($this->items[$i]['calc_fnc']){ + case CALC_FNC_MIN: + $item_value = abs($curr_data->min); + + break; + case CALC_FNC_MAX: + $item_value = abs($curr_data->max); + break; + case CALC_FNC_LST: + $item_value = abs($curr_data->lst); + break; + case CALC_FNC_AVG: + default: + $item_value = abs($curr_data->avg); + } + + if($type == GRAPH_ITEM_SUM){ + $this->background = $i; + $graph_sum = $item_value; + } + + $this->sum += $item_value; + $strvaluelenght = max($strvaluelenght,strlen($item_value)); + } + + if(isset($graph_sum)) $this->sum = $graph_sum; + $this->shiftlegendright += $strvaluelenght * 6; +} + + +/*function set3DAngle($angle = 70){ + if(is_numeric($angle) && ($angle < 85) && ($angle > 10)){ + $this->angle3d = (int) $angle; + } + else { + $this->angle3d = 70; + } +}//*/ + +function SwitchPie3D($type = false){ + if($type){ + $this->type = $type; + } + else{ + switch($this->type){ + case GRAPH_TYPE_EXPLODED: + $this->type = GRAPH_TYPE_3D_EXPLODED; + break; + case GRAPH_TYPE_3D_EXPLODED: + $this->type = GRAPH_TYPE_EXPLODED; + break; + case GRAPH_TYPE_3D: + $this->type = GRAPH_TYPE_PIE; + break; + case GRAPH_TYPE_PIE: + $this->type = GRAPH_TYPE_3D; + break; + default: + $this->type = GRAPH_TYPE_PIE; + } + } +return $this->type; +} + +function SwitchPieExploded($type){ + if($type){ + $this->type = $type; + } + else{ + switch($this->type){ + case GRAPH_TYPE_EXPLODED: + $this->type = GRAPH_TYPE_PIE; + break; + case GRAPH_TYPE_3D_EXPLODED: + $this->type = GRAPH_TYPE_3D; + break; + case GRAPH_TYPE_3D: + $this->type = GRAPH_TYPE_3D_EXPLODED; + break; + case GRAPH_TYPE_PIE: + $this->type = GRAPH_TYPE_EXPLODED; + break; + default: + $this->type = GRAPH_TYPE_PIE; + } + } +return $this->type; +} + +function calc3dhight($height){ + $this->graphheight3d = (int) ($height/20); +} + +function calcExplodedCenter($anglestart,$angleend,$x,$y,$count){ + $count *= $this->exploderad; + $anglemid = (int) (($anglestart + $angleend) / 2 ); + + $y+= round($count * sin(deg2rad($anglemid))); + $x+= round($count * cos(deg2rad($anglemid))); +// SDI($x.' xy '.$y); + +return array($x,$y); +} + +function calcExplodedRadius($sizeX,$sizeY,$count){ + $count *= $this->exploderad*2; + $sizeX -= $count; + $sizeY -= $count; +return array($sizeX,$sizeY); +} + +function calc3DAngle($sizeX,$sizeY){ + $sizeY *= (GRAPH_3D_ANGLE / 90); +return array($sizeX,round($sizeY)); +} + +function drawLegend(){ + + $shiftY = $this->shiftY + $this->shiftYLegend; + + $max_host_len=0; + $max_desc_len=0; + + for($i=0;$i<$this->num;$i++){ + if(strlen($this->items[$i]['host'])>$max_host_len) $max_host_len=strlen($this->items[$i]['host']); + if(strlen($this->items[$i]['description'])>$max_desc_len) $max_desc_len=strlen($this->items[$i]['description']); + } + + for($i=0;$i<$this->num;$i++){ + + $color = $this->GetColor($this->items[$i]['color']); + $data = &$this->data[$this->items[$i]['itemid']][$this->items[$i]['calc_type']]; + + switch($this->items[$i]['calc_fnc']){ + case CALC_FNC_MIN: + $fnc_name = 'min'; + $datavalue = $data->min; + break; + case CALC_FNC_MAX: + $fnc_name = 'max'; + $datavalue = $data->max; + break; + case CALC_FNC_LST: + $fnc_name = 'last'; + $datavalue = $data->lst; + break; + case CALC_FNC_AVG: + default: + $fnc_name = 'avg'; + $datavalue = $data->avg; + } + + $proc = ($datavalue * 100)/ $this->sum; + + if(isset($data) && isset($datavalue)){ + $strvalue = sprintf("Value: %0.4f (%0.2f%s)",$datavalue,$proc,'%'); + $str = sprintf("%s: %s [%s] ", + str_pad($this->items[$i]['host'],$max_host_len,' '), + str_pad($this->items[$i]['description'],$max_desc_len,' '), + $fnc_name); + } + else{ + $strvalue = sprintf("Value: no data"); + $str=sprintf("%s: %s [ no data ]", + str_pad($this->items[$i]['host'],$max_host_len,' '), + str_pad($this->items[$i]['description'],$max_desc_len,' ')); + } + + ImageFilledRectangle($this->im,$this->shiftXleft,$this->sizeY+$shiftY+12*$i,$this->shiftXleft+5,$this->sizeY+$shiftY+5+12*$i,$color); + ImageRectangle($this->im,$this->shiftXleft,$this->sizeY+$shiftY+12*$i,$this->shiftXleft+5,$this->sizeY+$shiftY+5+12*$i,$this->GetColor('Black No Alpha')); + + ImageString($this->im, 2, + $this->shiftXleft+9, + $this->sizeY+$shiftY-5+12*$i, + $str, + $this->GetColor('Black No Alpha')); + + $shiftX = $this->fullSizeX - $this->shiftlegendright - $this->shiftXright + 10; +// SDI($shiftX.','.$this->sizeX); + + ImageFilledRectangle($this->im,$shiftX,$this->shiftY+10+5+12*$i,$shiftX+5,$this->shiftY+10+10+12*$i,$color); + ImageRectangle($this->im,$shiftX,$this->shiftY+10+5+12*$i,$shiftX+5,$this->shiftY+10+10+12*$i,$this->GetColor('Black No Alpha')); + + ImageString($this->im, 2, + $shiftX+9, + $this->shiftY+10+12*$i, + $strvalue, + $this->GetColor('Black No Alpha')); + } + + if($this->sizeY < 120) return; +} + + +function drawElementPie($values){ + + $sum = $this->sum; + + if($this->background !== false){ + $least = 0; + foreach($values as $item => $value){ +// SDI($item.' : '.$value.' , '.$this->background); + if($item != $this->background){ + $least += $value; + } + } + $values[$this->background] -= $least; + } + + if($sum <= 0){ + $this->items[0]['color'] = 'FFFFFF'; + $values = array(0 => 1); + $sum = 1; + } +// asort($values); + + $sizeX = $this->sizeX; + $sizeY = $this->sizeY; + + if($this->type == GRAPH_TYPE_EXPLODED){ + list($sizeX,$sizeY) = $this->calcExplodedRadius($sizeX,$sizeY,count($values)); + } else { + $sizeX =(int) $sizeX * 0.95; + $sizeY =(int) $sizeY * 0.95; + } + + $xc = $x = (int) $this->sizeX/2 + ($this->shiftXleft); + $yc = $y = (int) $this->sizeY/2 + $this->shiftY; + + $anglestart = 0; + $angleend = 0; + foreach($values as $item => $value){ + $angleend += (int)(360 * $value/$sum)+1; + $angleend = ($angleend > 360)?(360):($angleend); + if(($angleend - $anglestart) < 1) continue; + + if($this->type == GRAPH_TYPE_EXPLODED){ + list($x,$y) = $this->calcExplodedCenter($anglestart,$angleend,$xc,$yc,count($values)); + } + + imagefilledarc($this->im, $x, $y, $sizeX, $sizeY, $anglestart, $angleend, $this->GetColor($this->items[$item]['color'],0), IMG_ARC_PIE); + imagefilledarc($this->im, $x, $y, $sizeX, $sizeY, $anglestart, $angleend, $this->GetColor('Black'), IMG_ARC_PIE|IMG_ARC_EDGED|IMG_ARC_NOFILL); + $anglestart = $angleend; + } +// imageline($this->im, $xc, $yc, $xc, $yc, $this->GetColor('Black')); +} + +function drawElementPie3D($values){ + + $sum = $this->sum; + + if($this->background !== false){ + $least = 0; + foreach($values as $item => $value){ + if($item != $this->background){ + $least += $value; + } + } + $values[$this->background] -= $least; + } + + if($sum <= 0){ + $this->items[0]['color'] = 'FFFFFF'; + $values = array(0 => 1); + $sum = 1; + } +// asort($values); + + $sizeX = $this->sizeX; + $sizeY = $this->sizeY; + + $this->exploderad = $this->exploderad3d; + + if($this->type == GRAPH_TYPE_3D_EXPLODED){ + list($sizeX,$sizeY) = $this->calcExplodedRadius($sizeX,$sizeY,count($values)); + } + + list($sizeX,$sizeY) = $this->calc3DAngle($sizeX,$sizeY); + + $xc = $x = (int) $this->sizeX/2 + ($this->shiftXleft); + $yc = $y = (int) $this->sizeY/2 + $this->shiftY; + +// ----- bottom angle line ---- + $anglestart = 0; + $angleend = 0; + foreach($values as $item => $value){ + + $angleend += (int)(360 * $value/$sum) +1; + $angleend = ($angleend > 360)?(360):($angleend); + if(($angleend - $anglestart) < 1) continue; + + if($this->type == GRAPH_TYPE_3D_EXPLODED){ + list($x,$y) = $this->calcExplodedCenter($anglestart,$angleend,$xc,$yc,count($values)); + } + imagefilledarc($this->im, $x, $y+$this->graphheight3d+1, $sizeX, $sizeY, $anglestart, $angleend, $this->GetShadow($this->items[$item]['color'],0), IMG_ARC_PIE); + imagefilledarc($this->im, $x, $y+$this->graphheight3d+1, $sizeX, $sizeY, $anglestart, $angleend, $this->GetColor('Black'), IMG_ARC_PIE|IMG_ARC_EDGED|IMG_ARC_NOFILL); + $anglestart = $angleend; + }//*/ + +// ------ 3d effect ------ + for ($i = $this->graphheight3d; $i > 0; $i--) { + $anglestart = 0; + $angleend = 0; + foreach($values as $item => $value){ + $angleend += (int)(360 * $value/$sum) +1; + $angleend = ($angleend > 360)?(360):($angleend); + + if(($angleend - $anglestart) < 1) continue; + elseif($this->sum == 0) continue; + + if($this->type == GRAPH_TYPE_3D_EXPLODED){ + list($x,$y) = $this->calcExplodedCenter($anglestart,$angleend,$xc,$yc,count($values)); + } + + imagefilledarc($this->im, $x, $y+$i, $sizeX, $sizeY, $anglestart, $angleend, $this->GetShadow($this->items[$item]['color'],0), IMG_ARC_PIE); + $anglestart = $angleend; + } + } + + $anglestart = 0; + $angleend = 0; + foreach($values as $item => $value){ + + $angleend += (int)(360 * $value/$sum) +1; + $angleend = ($angleend > 360)?(360):($angleend); + if(($angleend - $anglestart) < 1) continue; + + if($this->type == GRAPH_TYPE_3D_EXPLODED){ + list($x,$y) = $this->calcExplodedCenter($anglestart,$angleend,$xc,$yc,count($values)); + } + + imagefilledarc($this->im, $x, $y, $sizeX, $sizeY, $anglestart, $angleend, $this->GetColor($this->items[$item]['color'],0), IMG_ARC_PIE); + imagefilledarc($this->im, $x, $y, $sizeX, $sizeY, $anglestart, $angleend, $this->GetColor('Black'), IMG_ARC_PIE|IMG_ARC_EDGED|IMG_ARC_NOFILL); + $anglestart = $angleend; + }//*/ +} + +function Draw(){ + $start_time=getmicrotime(); + set_image_header(); + check_authorisation(); + + $this->selectData(); + + $this->shiftY = 20; + $this->shiftYLegend = 20; + $this->shiftXleft = 10; + $this->shiftXright = 0; + + $this->fullSizeX = $this->sizeX; + $this->fullSizeY = $this->sizeY; + + if(($this->sizeX < 300) || ($this->sizeY < 200)) $this->switchlegend(0); + + if($this->drawlegendallow == 1){ + $this->sizeX -= ($this->shiftXleft+$this->shiftXright+$this->shiftlegendright); + $this->sizeY -= ($this->shiftY+$this->shiftYLegend+12*$this->num+8); + } + else { + $this->sizeX -= ($this->shiftXleft*2); + $this->sizeY -= ($this->shiftY*2); + } + +// SDI($this->sizeX.','.$this->sizeY); + + $this->sizeX = min($this->sizeX,$this->sizeY); + $this->sizeY = min($this->sizeX,$this->sizeY); + +// SDI($this->graphheight3d); + $this->calc3dhight($this->sizeY); +// SDI($this->graphheight3d); + + $this->exploderad = (int) $this->sizeX / 100; + $this->exploderad3d = (int) $this->sizeX / 60; + + if(function_exists('ImageColorExactAlpha')&&function_exists('ImageCreateTrueColor')&&@imagecreatetruecolor(1,1)) + $this->im = imagecreatetruecolor($this->fullSizeX,$this->fullSizeY); + else + $this->im = imagecreate($this->fullSizeX,$this->fullSizeY); + + + $this->initColors(); + $this->drawRectangle(); + $this->drawHeader(); + + $maxX = $this->sizeX; + + // For each metric + for($item = 0; $item < $this->num; $item++){ + $minY = $this->m_minY[$this->items[$item]['axisside']]; + $maxY = $this->m_maxY[$this->items[$item]['axisside']]; + + $data = &$this->data[$this->items[$item]['itemid']][$this->items[$item]['calc_type']]; + + if(!isset($data)) continue; + + $drawtype = $this->items[$item]['drawtype']; + + $max_color = $this->GetColor('ValueMax'); + $avg_color = $this->GetColor($this->items[$item]['color']); + $min_color = $this->GetColor('ValueMin'); + $minmax_color = $this->GetColor('ValueMinMax'); + + $calc_fnc = $this->items[$item]['calc_fnc']; + + switch($calc_fnc){ + case CALC_FNC_MAX: + $values[$item] = abs($data->max); + break; + case CALC_FNC_MIN: + $values[$item] = abs($data->min); + break; + case CALC_FNC_AVG: + $values[$item] = abs($data->avg); + break; + case CALC_FNC_LST: + $values[$item] = abs($data->lst); + break; + } +// $this->sum += $values[$item]; + } +// $this->SwitchPie3D(); +// $this->SwitchPieExploded(); + + switch($this->type){ + case GRAPH_TYPE_EXPLODED: + $this->drawElementPie($values); + break; + case GRAPH_TYPE_3D: + $this->drawElementPie3D($values); + break; + case GRAPH_TYPE_3D_EXPLODED: + $this->drawElementPie3D($values); + break; + default: + $this->drawElementPie($values); + break; + } + + $this->drawLogo(); + + if($this->drawlegendallow == 1) $this->drawLegend(); + + $end_time=getmicrotime(); + $str=sprintf("%0.2f",(getmicrotime()-$start_time)); + ImageString($this->im, 0,$this->fullSizeX-120,$this->fullSizeY-12,"Generated in $str sec", $this->GetColor('Gray')); + + unset($this->items, $this->data); + + ImageOut($this->im); +} + +} +?>
\ No newline at end of file |
