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 | |
| parent | bac3a136113548551ad7320cc8a8ed7ecbb2e11a (diff) | |
| download | zabbix-4e4aa7eb198963720b377cd568825309616dce8a.tar.gz zabbix-4e4aa7eb198963720b377cd568825309616dce8a.tar.xz zabbix-4e4aa7eb198963720b377cd568825309616dce8a.zip | |
- 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')
| -rw-r--r-- | frontends/php/include/classes/chart.inc.php | 1104 | ||||
| -rw-r--r-- | frontends/php/include/classes/graph.inc.php | 1599 | ||||
| -rw-r--r-- | frontends/php/include/classes/pie.inc.php | 610 |
3 files changed, 1971 insertions, 1342 deletions
diff --git a/frontends/php/include/classes/chart.inc.php b/frontends/php/include/classes/chart.inc.php new file mode 100644 index 00000000..64c30a1d --- /dev/null +++ b/frontends/php/include/classes/chart.inc.php @@ -0,0 +1,1104 @@ +<?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 Chart extends Graph{ + + function Chart($type = GRAPH_TYPE_NORMAL){ + parent::Graph($type); + + $this->yaxismin = null; + $this->yaxismax = null; + + $this->triggers = array(); + + $this->yaxistype=GRAPH_YAXIS_TYPE_CALCULATED; + $this->yaxisright=0; + $this->yaxisleft=0; + + $this->m_showWorkPeriod = 1; + $this->m_showTriggers = 1; + + $this->zero = array(); + $this->graphorientation = ''; + } + + function updateShifts() + { + if( ($this->yaxisleft == 1) && ($this->yaxisright == 1)) + { + $this->shiftXleft = 60; + $this->shiftXright = 60; + } + else if($this->yaxisleft == 1) + { + $this->shiftXleft = 60; + $this->shiftXright = 20; + } + else if($this->yaxisright == 1) + { + $this->shiftXleft = 10; + $this->shiftXright = 60; + } +// $this->sizeX = $this->sizeX - $this->shiftXleft-$this->shiftXright; + } + + function ShowWorkPeriod($value) + { + $this->m_showWorkPeriod = $value == 1 ? 1 : 0; + } + + function ShowTriggers($value) + { + $this->m_showTriggers = $value == 1 ? 1 : 0; + } + + function AddItem($itemid, $axis=GRAPH_YAXIS_SIDE_RIGHT, $calc_fnc=CALC_FNC_AVG, + $color=null, $drawtype=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]["drawtype"] = is_null($drawtype) ? GRAPH_ITEM_DRAWTYPE_LINE : $drawtype; + $this->items[$this->num]["axisside"] = is_null($axis) ? GRAPH_YAXIS_SIDE_RIGHT : $axis; + $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; + + if($this->items[$this->num]["axisside"] == GRAPH_YAXIS_SIDE_LEFT) + $this->yaxisleft=1; + + if($this->items[$this->num]["axisside"] == GRAPH_YAXIS_SIDE_RIGHT) + $this->yaxisright=1; +// SDI($this->items); + + $this->num++; + } + + function CheckGraphOrientation($value){ + + if(!empty($this->graphorientation)){ + if(($this->graphorientation == '+') && ($value<0)){ +// Error(); + } + elseif(($this->graphorientation == '-') && ($value>0)){ +// Error(); + } + } + else { + if($value < 0){ + $this->graphorientation = '-'; + } + elseif($value > 0){ + $this->graphorientation = '+'; + } + } + } + + function setYAxisMin($yaxismin) + { + $this->yaxismin=$yaxismin; + } + + function setYAxisMax($yaxismax) + { + $this->yaxismax=$yaxismax; + } + + function setYAxisType($yaxistype) + { + $this->yaxistype=$yaxistype; + } + + function drawGrid() + { + $this->drawSmallRectangle(); + for($i=1;$i<=5;$i++) + { + DashedLine($this->im,$this->shiftXleft,$i*($this->sizeY/6)+$this->shiftY,$this->sizeX+$this->shiftXleft,$i*($this->sizeY/6)+$this->shiftY,$this->GetColor("Gray")); + } + + for($i=1;$i<=23;$i++) + { + DashedLine($this->im,$i*($this->sizeX/24)+$this->shiftXleft,$this->shiftY,$i*($this->sizeX/24)+$this->shiftXleft,$this->sizeY+$this->shiftY,$this->GetColor("Gray")); + } + + $old_day=-1; + for($i=0;$i<=24;$i++) + { + ImageStringUp($this->im, 1,$i*($this->sizeX/24)+$this->shiftXleft-3, $this->sizeY+$this->shiftY+57, date(" H:i",$this->from_time+$i*($this->period/24)) , $this->GetColor("Black No Alpha")); + + $new_day=date("d",$this->from_time+$i*($this->period/24)); + if( ($old_day != $new_day) ||($i==24)) + { + $old_day=$new_day; + ImageStringUp($this->im, 1,$i*($this->sizeX/24)+$this->shiftXleft-3, $this->sizeY+$this->shiftY+57, date("m.d H:i",$this->from_time+$i*($this->period/24)) , $this->GetColor("Dark Red No Alpha")); + + } + } + } + + function drawWorkPeriod() + { + if($this->m_showWorkPeriod != 1) return; + if($this->period > 2678400) return; // > 31*24*3600 (month) + + $db_work_period = DBselect("select work_period from config"); + $work_period = DBfetch($db_work_period); + if(!$work_period) + return; + + $periods = parse_period($work_period['work_period']); + if(!$periods) + return; + + ImageFilledRectangle($this->im, + $this->shiftXleft+1, + $this->shiftY, + $this->sizeX+$this->shiftXleft, + $this->sizeY+$this->shiftY, + $this->GetColor("Not Work Period")); + + $now = time(); + 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; + } + $from = $this->from_time; + $max_time = $this->to_time; + + $start = find_period_start($periods,$from); + $end = -1; + while($start < $max_time && $start > 0) + { + $end = find_period_end($periods,$start,$max_time); + + $x1 = round((($start-$from)*$this->sizeX)/$this->period) + $this->shiftXleft; + $x2 = round((($end-$from)*$this->sizeX)/$this->period) + $this->shiftXleft; + + //draw rectangle + ImageFilledRectangle( + $this->im, + $x1, + $this->shiftY, + $x2, + $this->sizeY+$this->shiftY, + $this->GetColor("White")); + + $start = find_period_start($periods,$end); + } + } + + function calcTriggers() + { + $this->triggers = array(); + if($this->m_showTriggers != 1) return; + if($this->num != 1) return; // skip multiple graphs + + $max = 3; + $cnt = 0; + + $db_triggers = DBselect("select distinct tr.triggerid,tr.expression,tr.priority from triggers tr,functions f,items i". + " where tr.triggerid=f.triggerid and f.function in ('last','min','max') and". + " tr.status=".TRIGGER_STATUS_ENABLED." and i.itemid=f.itemid and f.itemid=".$this->items[0]["itemid"]." order by tr.priority"); + + while(($trigger = DBfetch($db_triggers)) && ($cnt < $max)) + { + $db_fnc_cnt = DBselect('select count(*) as cnt from functions f where f.triggerid='.$trigger['triggerid']); + $fnc_cnt = DBfetch($db_fnc_cnt); + if($fnc_cnt['cnt'] != 1) continue; + + if(!eregi('\{([0-9]{1,})\}([\<\>\=]{1})([0-9\.]{1,})([K|M|G]{0,1})',$trigger['expression'],$arr)) + continue; + + $val = $arr[3]; + if(strcasecmp($arr[4],'K') == 0) $val *= 1024; + else if(strcasecmp($arr[4],'M') == 0) $val *= 1048576; //1024*1024; + else if(strcasecmp($arr[4],'G') == 0) $val *= 1073741824; //1024*1024*1024; + + $minY = $this->m_minY[$this->items[0]["axisside"]]; + $maxY = $this->m_maxY[$this->items[0]["axisside"]]; + + if($val <= $minY || $val >= $maxY) continue; + + if($trigger['priority'] == 5) $color = "Priority Disaster"; + elseif($trigger['priority'] == 4) $color = "Priority Hight"; + elseif($trigger['priority'] == 3) $color = "Priority Average"; + else $color = "Priority"; + + array_push($this->triggers,array( + 'y' => $this->sizeY - (($val-$minY) / ($maxY-$minY)) * $this->sizeY + $this->shiftY, + 'color' => $color, + 'description' => 'trigger: '.expand_trigger_description($trigger['triggerid']).' ['.$arr[2].' '.$arr[3].$arr[4].']' + )); + ++$cnt; + } + + } + function drawTriggers() + { + if($this->m_showTriggers != 1) return; + if($this->num != 1) return; // skip multiple graphs + + foreach($this->triggers as $trigger) + { + DashedLine( + $this->im, + $this->shiftXleft, + $trigger['y'], + $this->sizeX+$this->shiftXleft, + $trigger['y'], + $this->GetColor($trigger['color'])); + } + + } + + + function drawLegend() + { + $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++) + { + if($this->items[$i]["calc_type"] == GRAPH_ITEM_AGGREGATED) + { + $fnc_name = "agr(".$this->items[$i]["periods_cnt"].")"; + $color = $this->GetColor("HistoryMinMax"); + } + else + { + $color = $this->GetColor($this->items[$i]["color"]); + switch($this->items[$i]["calc_fnc"]) + { + case CALC_FNC_MIN: $fnc_name = "min"; break; + case CALC_FNC_MAX: $fnc_name = "max"; break; + case CALC_FNC_ALL: $fnc_name = "all"; break; + case CALC_FNC_AVG: + default: $fnc_name = "avg"; + } + } + + $data = &$this->data[$this->items[$i]["itemid"]][$this->items[$i]["calc_type"]]; + if(isset($data)&&isset($data->min)) + { + $str=sprintf("%s: %s [%s] [min:%s max:%s last:%s]", + str_pad($this->items[$i]["host"],$max_host_len," "), + str_pad($this->items[$i]["description"],$max_desc_len," "), + $fnc_name, + convert_units(min($data->min),$this->items[$i]["units"]), + convert_units(max($data->max),$this->items[$i]["units"]), + convert_units($this->getLastValue($i),$this->items[$i]["units"])); + } + else + { + $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+$this->shiftY+62+12*$i,$this->shiftXleft+5,$this->sizeY+$this->shiftY+5+62+12*$i,$color); + ImageRectangle($this->im,$this->shiftXleft,$this->sizeY+$this->shiftY+62+12*$i,$this->shiftXleft+5,$this->sizeY+$this->shiftY+5+62+12*$i,$this->GetColor("Black No Alpha")); + + ImageString($this->im, 2, + $this->shiftXleft+9, + $this->sizeY+$this->shiftY+(62-5)+12*$i, + $str, + $this->GetColor("Black No Alpha")); + } + + if($this->sizeY < 120) return; + + foreach($this->triggers as $trigger) + { + ImageFilledEllipse($this->im, + $this->shiftXleft + 2, + $this->sizeY+$this->shiftY+2+62+12*$i, + 6, + 6, + $this->GetColor($trigger["color"])); + + ImageEllipse($this->im, + $this->shiftXleft + 2, + $this->sizeY+$this->shiftY+2+62+12*$i, + 6, + 6, + $this->GetColor("Black No Alpha")); + + ImageString( + $this->im, + 2, + $this->shiftXleft+9, + $this->sizeY+$this->shiftY+(62-5)+12*$i, + $trigger['description'], + $this->GetColor("Black No Alpha")); + ++$i; + } + } + + function drawElement( + &$data, $from, $to, + $minX, $maxX, $minY, $maxY, + $drawtype, $max_color, $avg_color, $min_color, $minmax_color, + $calc_fnc, + $axisside + ) + { + if(!isset($data->max[$from]) || !isset($data->max[$to])) return; + + $oxy = $this->oxy[$axisside]; + $zero = $this->zero[$axisside]; + $unit2px = $this->unit2px[$axisside]; + + $shift_min_from = $shift_min_to = 0; + $shift_max_from = $shift_max_to = 0; + $shift_avg_from = $shift_avg_to = 0; + + if(isset($data->shift_min[$from])) $shift_min_from = $data->shift_min[$from]; + if(isset($data->shift_min[$to])) $shift_min_to = $data->shift_min[$to]; + + if(isset($data->shift_max[$from])) $shift_max_from = $data->shift_max[$from]; + if(isset($data->shift_max[$to])) $shift_max_to = $data->shift_max[$to]; + + if(isset($data->shift_avg[$from])) $shift_avg_from = $data->shift_avg[$from]; + if(isset($data->shift_avg[$to])) $shift_avg_to = $data->shift_avg[$to]; +/**/ + $min_from = $data->min[$from] + $shift_min_from; + $min_to = $data->min[$to] + $shift_min_to; + + $max_from = $data->max[$from] + $shift_max_from; + $max_to = $data->max[$to] + $shift_max_to; + + $avg_from = $data->avg[$from] + $shift_avg_from; + $avg_to = $data->avg[$to] + $shift_avg_to; + + $x1 = $from + $this->shiftXleft - 1; + $x2 = $to + $this->shiftXleft; + + + $y1min = $zero - ($min_from-$oxy)/$unit2px; + $y2min = $zero - ($min_to-$oxy)/$unit2px; + + $y1max = $zero - ($max_from-$oxy)/$unit2px; + $y2max = $zero - ($max_to-$oxy)/$unit2px; + + $y1avg = $zero - ($avg_from-$oxy)/$unit2px; + $y2avg = $zero - ($avg_to-$oxy)/$unit2px; //*/ + + switch($calc_fnc){ + case CALC_FNC_MAX: + $y1 = $y1max; + $y2 = $y2max; + $shift_from = $shift_max_from; + $shift_to = $shift_max_to; + break; + case CALC_FNC_MIN: + $y1 = $y1min; + $y2 = $y2min; + $shift_from = $shift_min_from; + $shift_to = $shift_min_to; + break; + case CALC_FNC_ALL: + $a[0] = $x1; $a[1] = $y1max; + $a[2] = $x1; $a[3] = $y1min; + $a[4] = $x2; $a[5] = $y2min; + $a[6] = $x2; $a[7] = $y2max; + + ImageFilledPolygon($this->im,$a,4,$minmax_color); + ImageLine($this->im,$x1,$y1max,$x2,$y2max,$max_color); + ImageLine($this->im,$x1,$y1min,$x2,$y2min,$min_color); + + /* don't use break, avg must be drawed in this statement */ + // break; + case CALC_FNC_AVG: + /* don't use break, avg must be drawed in this statement */ + // break; + default: + $y1 = $y1avg; + $y2 = $y2avg; + $shift_from = $shift_avg_from ; + $shift_to = $shift_avg_to; + } + + $shift_from -= ($shift_from != 0)?($oxy):(0); + $shift_to -= ($shift_to != 0)?($oxy):(0); + + $y1_shift = $zero - $shift_from/$unit2px; + $y2_shift = $zero - $shift_to/$unit2px;//*/ + + /* draw main line */ + switch($drawtype) + { + case GRAPH_ITEM_DRAWTYPE_BOLD_LINE: + ImageLine($this->im,$x1,$y1+1,$x2,$y2+1,$avg_color); + // break; /* don't use break, must be drawed line also */ + case GRAPH_ITEM_DRAWTYPE_LINE: + ImageLine($this->im,$x1,$y1,$x2,$y2,$avg_color); + break; + case GRAPH_ITEM_DRAWTYPE_FILLED_REGION: + $a[0] = $x1; $a[1] = $y1; + $a[2] = $x1; $a[3] = $y1_shift; + $a[4] = $x2; $a[5] = $y2_shift; + $a[6] = $x2; $a[7] = $y2; + +// SDI($a); + + ImageFilledPolygon($this->im,$a,4,$avg_color); + break; + case GRAPH_ITEM_DRAWTYPE_DOT: + ImageFilledRectangle($this->im,$x1-1,$y1-1,$x1+1,$y1+1,$avg_color); + ImageFilledRectangle($this->im,$x2-1,$y2-1,$x2+1,$y2+1,$avg_color); + break; + case GRAPH_ITEM_DRAWTYPE_DASHED_LINE: + if( function_exists('imagesetstyle') ){ + + /* Use ImageSetStyle+ImageLIne instead of bugged ImageDashedLine */ + $style = array($avg_color, $avg_color, IMG_COLOR_TRANSPARENT, IMG_COLOR_TRANSPARENT); + ImageSetStyle($this->im, $style); + ImageLine($this->im,$x1,$y1,$x2,$y2,IMG_COLOR_STYLED); + } + else{ + ImageDashedLine($this->im,$x1,$y1,$x2,$y2,$avg_color); + } + break; + } + } + +// Calculation of minimum Y axis + function calculateMinY($side){ + if($this->yaxistype==GRAPH_YAXIS_TYPE_FIXED){ + return $this->yaxismin; + } + else{ + unset($minY); + for($i=0;$i<$this->num;$i++){ + + if($this->items[$i]["axisside"] != $side) + continue; + + foreach(array(GRAPH_ITEM_SIMPLE, GRAPH_ITEM_AGGREGATED) as $type){ + + if(!isset($this->data[$this->items[$i]["itemid"]][$type])) + continue; + + $data = &$this->data[$this->items[$i]["itemid"]][$type]; + + if(!isset($data)) continue; + + if($type == GRAPH_ITEM_AGGREGATED) + $calc_fnc = CALC_FNC_ALL; + else + $calc_fnc = $this->items[$i]["calc_fnc"]; + + switch($calc_fnc){ + case CALC_FNC_ALL: /* use min */ + case CALC_FNC_MIN: $val = $data->min; $shift_val = $data->shift_min; break; + case CALC_FNC_MAX: $val = $data->max; $shift_val = $data->shift_max; break; + case CALC_FNC_AVG: + default: $val = $data->avg; $shift_val = $data->shift_avg; + } + + if(!isset($val)) continue; + + if($this->type == GRAPH_TYPE_STACKED){ + $min_val_shift = min(count($val), count($shift_val)); + for($ci=0; $ci < $min_val_shift; $ci++){ + if($shift_val[$ci] < 0){ + $val[$ci] += $shift_val[$ci]; + } + } + + } + + if(!isset($minY)){ + if(isset($val) && count($val) > 0){ + $minY = min($val); + } + } + else{ + $minY = min($minY, min($val)); + } + } + } + + if(isset($minY)&&($minY>0)){ + $minY = $minY - ($minY * 0.2) - 0.05; + } + elseif(isset($minY)&&($minY<0)){ + $minY = $minY + ($minY * 0.2) - 0.05; + } + else { + $minY=0; + } + + $minY = round($minY,1); + return $minY; + } + } + +// Calculation of maximum Y of a side (left/right) + function calculateMaxY($side) + { + if($this->yaxistype==GRAPH_YAXIS_TYPE_FIXED) + { + return $this->yaxismax; + } + else + { + + unset($maxY); + for($i=0;$i<$this->num;$i++) + { + if($this->items[$i]["axisside"] != $side) + continue; + + foreach(array(GRAPH_ITEM_SIMPLE, GRAPH_ITEM_AGGREGATED) as $type) + { + if(!isset($this->data[$this->items[$i]["itemid"]][$type])) + continue; + + $data = &$this->data[$this->items[$i]["itemid"]][$type]; + + if(!isset($data)) continue; + + if($type == GRAPH_ITEM_AGGREGATED) + $calc_fnc = CALC_FNC_ALL; + else + $calc_fnc = $this->items[$i]["calc_fnc"]; + + switch($calc_fnc) + { + case CALC_FNC_ALL: /* use max */ + case CALC_FNC_MAX: $val = $data->max; $shift_val = $data->shift_max; break; + case CALC_FNC_MIN: $val = $data->min; $shift_val = $data->shift_min; break; + case CALC_FNC_AVG: + default: $val = $data->avg; $shift_val = $data->shift_avg; + } + + if(!isset($val)) continue; + + for($ci=0; $ci < min(count($val),count($shift_val)); $ci++) $val[$ci] += $shift_val[$ci]; + + if(!isset($maxY)) + { + if(isset($val) && count($val) > 0) + { + $maxY = max($val); + } + } + else + { + $maxY = max($maxY, max($val)); + } + + } + } + + if(isset($maxY)&&($maxY>0)){ + +/* $exp = round(log10($maxY)); + $mant = $maxY/pow(10,$exp); + + $mant=((round(($mant*11)/6)-1)*6)/10; + $maxY = $mant*pow(10,$exp);//*/ + + $maxY = round($maxY,1) + round($maxY,1)*0.2 + 0.05; + } + elseif(isset($maxY)&&($maxY<0)){ + $maxY = round($maxY,1) - round($maxY,1)*0.2 + 0.05; + } + else { + $maxY=0.3; + } + return $maxY; + } + } + + 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 + + for($i=0; $i < $this->num; $i++){ + + $type = $this->items[$i]["calc_type"]; + + if($type == GRAPH_ITEM_AGGREGATED) { + /* skip current period */ + $from_time = $this->from_time - $this->period * $this->items[$i]["periods_cnt"]; + $to_time = $this->from_time; + } else { + $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 itemid,'.$calc_field.' as i,'. + ' count(*) as count,avg(value) as avg,min(value) as min,'. + ' max(value) as max,max(clock) as clock'. + ' from history where itemid='.$this->items[$i]['itemid'].' and clock>='.$from_time. + ' and clock<='.$to_time.' group by itemid,'.$calc_field + , + + 'select itemid,'.$calc_field.' as i,'. + ' count(*) as count,avg(value) as avg,min(value) as min,'. + ' max(value) as max,max(clock) as clock'. + ' from history_uint where itemid='.$this->items[$i]['itemid'].' and clock>='.$from_time. + ' and clock<='.$to_time.' group by itemid,'.$calc_field + ); + } + else{ + array_push($sql_arr, + 'select itemid,'.$calc_field.' as i,'. + ' sum(num) as count,avg(value_avg) as avg,min(value_min) as min,'. + ' max(value_max) as max,max(clock) as clock'. + ' from trends where itemid='.$this->items[$i]['itemid'].' and clock>='.$from_time. + ' and clock<='.$to_time.' group by itemid,'.$calc_field + ); + } + + $curr_data = &$this->data[$this->items[$i]["itemid"]][$type]; + $curr_data->count = NULL; + $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)){ + $idx=$row["i"]-1; + if($idx<0) continue; + /* -------------------------------------------------- + We are taking graph on 1px more than we need, + and here we are skiping first px, because of MOD (in SELECT), + it combined prelast point (it would be last point if not that 1px in begining) + and first point, but we still losing prelast point :( + but now we've got the first point. + --------------------------------------------------*/ + + $curr_data->count[$idx] = $row["count"]; + $curr_data->min[$idx] = $row["min"]; + $curr_data->max[$idx] = $row["max"]; + $curr_data->avg[$idx] = $row["avg"]; + $curr_data->clock[$idx] = $row["clock"]; + $curr_data->shift_min[$idx] = 0; + $curr_data->shift_max[$idx] = 0; + $curr_data->shift_avg[$idx] = 0; + + if($this->type == GRAPH_TYPE_STACKED){ + $this->CheckGraphOrientation($curr_data->min[$idx]); + } + } + unset($row); + } + /* calculate missed points */ + $first_idx = 0; + /* + first_idx - last existed point + ci - current index + cj - count of missed in onetime + dx - offset to first value (count to last existed point) + //*/ + + for($ci = 0, $cj=0; $ci < $this->sizeX; $ci++) + { + if(!isset($curr_data->count[$ci]) || $curr_data->count[$ci] == 0) + { + $curr_data->count[$ci] = 0; + $curr_data->shift_min[$ci] = 0; + $curr_data->shift_max[$ci] = 0; + $curr_data->shift_avg[$ci] = 0; + $cj++; + } + else if($cj > 0) + { + $dx = $cj + 1; + + $first_idx = $ci - $dx; + + if($first_idx < 0) $first_idx = $ci; // if no data from start of graph get current data as first data + + for(;$cj > 0; $cj--){ + +/* if(($first_idx == $ci) && ($dx < ($this->sizeX)) && ($this->type == GRAPH_TYPE_STACKED)){ + $curr_data->count[$ci - ($dx - $cj)] = 1; + } + else //*/ + if(($dx < ($this->sizeX/20)) && ($this->type == GRAPH_TYPE_STACKED)){ + $curr_data->count[$ci - ($dx - $cj)] = 1; + }//*/ + + foreach(array('clock','min','max','avg') as $var_name){ + $var = &$curr_data->$var_name; + + if($first_idx == $ci && $var_name == 'clock'){ + $var[$ci - ($dx - $cj)] = $var[$first_idx] - (($p / $this->sizeX) * ($dx - $cj)); + continue; + } + + $dy = $var[$ci] - $var[$first_idx]; + $var[$ci - ($dx - $cj)] = $var[$first_idx] + ($cj * $dy) / $dx; + } + } + } + } + + if($cj > 0 && $ci > $cj){ + $dx = $cj + 1; + + $first_idx = $ci - $dx; + + for(;$cj > 0; $cj--){ + +// if($dx < ($this->sizeX/20)) //($this->type == GRAPH_TYPE_STACKED) +// $curr_data->count[$first_idx + ($dx - $cj)] = 1; + + foreach(array('clock','min','max','avg') as $var_name){ + $var = &$curr_data->$var_name; + + if( $var_name == 'clock') + { + $var[$first_idx + ($dx - $cj)] = $var[$first_idx] + (($p / $this->sizeX) * ($dx - $cj)); + continue; + } + $var[$first_idx + ($dx - $cj)] = $var[$first_idx]; + } + } + } + /* end of missed points calculation */ + } + + /* calculte shift for stacked graphs */ + + if($this->type == GRAPH_TYPE_STACKED) + { + for($i=1; $i<$this->num; $i++) + { + $curr_data = &$this->data[$this->items[$i]["itemid"]][$this->items[$i]["calc_type"]]; + + if(!isset($curr_data)) continue; + + for($j = $i-1; $j >= 0; $j--) + { + if($this->items[$j]["axisside"] != $this->items[$i]["axisside"]) continue; + + $prev_data = &$this->data[$this->items[$j]["itemid"]][$this->items[$j]["calc_type"]]; + + if(!isset($prev_data)) continue; + + for($ci = 0; $ci < $this->sizeX; $ci++) + { + foreach(array('min','max','avg') as $var_name) + { + $shift_var_name = 'shift_'.$var_name; + $curr_shift = &$curr_data->$shift_var_name; + $curr_var = &$curr_data->$var_name; + $prev_shift = &$prev_data->$shift_var_name; + $prev_var = &$prev_data->$var_name; + $curr_shift[$ci] = $prev_var[$ci] + $prev_shift[$ci]; + } + } + break; + } + } + } + /* end calculation of stacked graphs */ + } + + function DrawLeftSide() + { + if($this->yaxisleft == 1) + { + $minY = $this->m_minY[GRAPH_YAXIS_SIDE_LEFT]; + $maxY = $this->m_maxY[GRAPH_YAXIS_SIDE_LEFT]; + + for($item=0;$item<$this->num;$item++) + { + if($this->items[$item]["axisside"] == GRAPH_YAXIS_SIDE_LEFT) + { + $units=$this->items[$item]["units"]; + break; + } + } + for($i=0;$i<=6;$i++) + { + $str = str_pad(convert_units($this->sizeY*$i/6*($maxY-$minY)/$this->sizeY+$minY,$units),10," ", STR_PAD_LEFT); + ImageString($this->im, 1, 5, $this->sizeY-$this->sizeY*$i/6-4+$this->shiftY, $str, $this->GetColor("Dark Red No Alpha")); + } + if(($this->zero[GRAPH_YAXIS_SIDE_LEFT] != $this->sizeY+$this->shiftY) && + ($this->zero[GRAPH_YAXIS_SIDE_LEFT] != $this->shiftY)){ + imageline($this->im, + $this->shiftXleft, + $this->zero[GRAPH_YAXIS_SIDE_LEFT], + $this->shiftXleft+$this->sizeX, + $this->zero[GRAPH_YAXIS_SIDE_LEFT], + $this->GetColor(GRAPH_ZERO_LINE_COLOR_LEFT) + ); //*/ + } + } + } + + function DrawRightSide() + { + if($this->yaxisright == 1) + { + $minY = $this->m_minY[GRAPH_YAXIS_SIDE_RIGHT]; + $maxY = $this->m_maxY[GRAPH_YAXIS_SIDE_RIGHT]; + + for($item=0;$item<$this->num;$item++){ + if($this->items[$item]["axisside"] == GRAPH_YAXIS_SIDE_RIGHT){ + $units=$this->items[$item]["units"]; + break; + } + } + for($i=0;$i<=6;$i++){ + $str = str_pad(convert_units($this->sizeY*$i/6*($maxY-$minY)/$this->sizeY+$minY,$units),10," "); + ImageString($this->im, 1, $this->sizeX+$this->shiftXleft+2, $this->sizeY-$this->sizeY*$i/6-4+$this->shiftY, $str, $this->GetColor("Dark Red No Alpha")); + } + + if(($this->zero[GRAPH_YAXIS_SIDE_RIGHT] != $this->sizeY+$this->shiftY) && + ($this->zero[GRAPH_YAXIS_SIDE_RIGHT] != $this->shiftY)){ + imageline($this->im, + $this->shiftXleft, + $this->zero[GRAPH_YAXIS_SIDE_RIGHT], + $this->shiftXleft+$this->sizeX, + $this->zero[GRAPH_YAXIS_SIDE_RIGHT], + $this->GetColor(GRAPH_ZERO_LINE_COLOR_RIGHT) + ); //*/ + } + } + } + + function CalcZero(){ + $left = GRAPH_YAXIS_SIDE_LEFT; + $right = GRAPH_YAXIS_SIDE_RIGHT; + + $this->unit2px[$right] = ($this->m_maxY[$right] - $this->m_minY[$right])/$this->sizeY; + $this->unit2px[$left] = ($this->m_maxY[$left] - $this->m_minY[$left])/$this->sizeY; + + if($this->m_minY[$right]>0){ + $this->zero[$right] = $this->sizeY+$this->shiftY; + $this->oxy[$right] = min(abs($this->m_minY[$right]),abs($this->m_maxY[$right])); + } + elseif($this->m_maxY[$right]<0) { + $this->zero[$right] = $this->shiftY; + $this->oxy[$right] = min(abs($this->m_minY[$right]),abs($this->m_maxY[$right])); + } + else{ + $this->zero[$right] = $this->sizeY+$this->shiftY - (int)abs($this->m_minY[$right]/$this->unit2px[$right]); + $this->oxy[$right] = 0; + } + + if($this->m_minY[$left]>0){ + $this->zero[$left] = $this->sizeY+$this->shiftY; + $this->oxy[$left] = min(abs($this->m_minY[$left]),abs($this->m_maxY[$left])); + } + elseif($this->m_maxY[$left]<0){ + $this->zero[$left] = $this->shiftY; + $this->oxy[$left] = min(abs($this->m_minY[$left]),abs($this->m_maxY[$left])); + } + else{ + $this->zero[$left] = $this->sizeY+$this->shiftY - (int)abs($this->m_minY[$left]/$this->unit2px[$left]); + $this->oxy[$left] = 0; + } + } + + function Draw() + { + $start_time=getmicrotime(); + + set_image_header(); + + check_authorisation(); + + $this->selectData(); + + $this->m_minY[GRAPH_YAXIS_SIDE_LEFT] = $this->calculateMinY(GRAPH_YAXIS_SIDE_LEFT); + $this->m_minY[GRAPH_YAXIS_SIDE_RIGHT] = $this->calculateMinY(GRAPH_YAXIS_SIDE_RIGHT); + $this->m_maxY[GRAPH_YAXIS_SIDE_LEFT] = $this->calculateMaxY(GRAPH_YAXIS_SIDE_LEFT); + $this->m_maxY[GRAPH_YAXIS_SIDE_RIGHT] = $this->calculateMaxY(GRAPH_YAXIS_SIDE_RIGHT); + + $this->updateShifts(); + $this->calcTriggers(); + $this->CalcZero(); + + $this->fullSizeX = $this->sizeX+$this->shiftXleft+$this->shiftXright+1; + $this->fullSizeY = $this->sizeY+$this->shiftY+62+12*($this->num+ (($this->sizeY < 120) ? 0 : count($this->triggers)))+8; + + 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(); + + if($this->num==0) + { +// $this->noDataFound(); + } + + $this->drawWorkPeriod(); + $this->drawGrid(); + + $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; + + if($this->items[$item]["calc_type"] == GRAPH_ITEM_AGGREGATED){ + $drawtype = GRAPH_ITEM_DRAWTYPE_LINE; + + $max_color = $this->GetColor("HistoryMax"); + $avg_color = $this->GetColor("HistoryAvg"); + $min_color = $this->GetColor("HistoryMin"); + $minmax_color = $this->GetColor("HistoryMinMax"); + + $calc_fnc = CALC_FNC_ALL; + } + elseif($this->type == GRAPH_TYPE_STACKED){ + $drawtype = $this->items[$item]["drawtype"]; + + $max_color = $this->GetColor("ValueMax",GRAPH_STACKED_ALFA); + $avg_color = $this->GetColor($this->items[$item]["color"],GRAPH_STACKED_ALFA); + $min_color = $this->GetColor("ValueMin",GRAPH_STACKED_ALFA); + $minmax_color = $this->GetColor("ValueMinMax",GRAPH_STACKED_ALFA); + + $calc_fnc = $this->items[$item]["calc_fnc"]; + } + else{ + $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"]; + } + // For each X + for($i = 1, $j = 0; $i < $maxX; $i++) // new point + { + if(($data->count[$i] == 0) && ($i != ($maxX-1))) continue; + + $diff = abs($data->clock[$i] - $data->clock[$j]); + $cell = ($this->to_time - $this->from_time)/$this->sizeX; + $delay = $this->items[$item]["delay"]; + + if($cell > $delay) + $draw = (boolean) ($diff < ZBX_GRAPH_MAX_SKIP_CELL * $cell); + else + $draw = (boolean) ($diff < ZBX_GRAPH_MAX_SKIP_DELAY * $delay); + + if($draw == false && $this->items[$item]["calc_type"] == GRAPH_ITEM_AGGREGATED) + $draw = $i - $j < 5; + + if($this->items[$item]["type"] == ITEM_TYPE_TRAPPER) + $draw = true; +// SDI($draw); + if($draw){ + + $this->drawElement( + $data, + $i, $j, + 0, $this->sizeX, + $minY, $maxY, + $drawtype, + $max_color, + $avg_color, + $min_color, + $minmax_color, + $calc_fnc, + $this->items[$item]['axisside'] + ); + } +// echo "\nDraw II \n"; printf("%0.4f",(getmicrotime()-$start_time)); + + $j = $i; + } + } + + $this->DrawLeftSide(); + $this->DrawRightSide(); + $this->drawTriggers(); + + $this->drawLogo(); + + $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 diff --git a/frontends/php/include/classes/graph.inc.php b/frontends/php/include/classes/graph.inc.php index fd97fd7c..c6b6f2d0 100644 --- a/frontends/php/include/classes/graph.inc.php +++ b/frontends/php/include/classes/graph.inc.php @@ -19,1431 +19,346 @@ **/ ?> <?php - require_once "include/items.inc.php"; - require_once "include/hosts.inc.php"; +require_once "include/items.inc.php"; +require_once "include/hosts.inc.php"; - define("GRAPH_YAXIS_TYPE_CALCULATED",0); - define("GRAPH_YAXIS_TYPE_FIXED",1); +define("GRAPH_YAXIS_TYPE_CALCULATED",0); +define("GRAPH_YAXIS_TYPE_FIXED",1); - define("GRAPH_YAXIS_SIDE_LEFT",0); - define("GRAPH_YAXIS_SIDE_RIGHT",1); +define("GRAPH_YAXIS_SIDE_LEFT",0); +define("GRAPH_YAXIS_SIDE_RIGHT",1); - define("GRAPH_ITEM_SIMPLE" , 0); - define("GRAPH_ITEM_AGGREGATED", 1); +define("GRAPH_ITEM_SIMPLE" , 0); +define("GRAPH_ITEM_AGGREGATED", 1); +define("GRAPH_ITEM_SUM", 2); - define("GRAPH_TYPE_NORMAL", 0); - define("GRAPH_TYPE_STACKED", 1); - define("GRAPH_STACKED_ALFA", 15); //0..100 - - define("GRAPH_ZERO_LINE_COLOR_LEFT", 'AAAAAA'); - define("GRAPH_ZERO_LINE_COLOR_RIGHT", '888888'); - - define('ZBX_MAX_TREND_DIFF', 3600); - - define('ZBX_GRAPH_MAX_SKIP_CELL', 16); - define('ZBX_GRAPH_MAX_SKIP_DELAY', 4); - - class Graph - { - /* - //var $period; - //var $from; - var $stime; - //var $sizeX; - //var $sizeY; - //var $shiftXleft; - //var $shiftXright; - //var $shiftY; - //var $border; - - var $fullSizeX; - var $fullSizeY; - - //var $m_showWorkPeriod; - //var $m_showTriggers; +define("GRAPH_TYPE_NORMAL", 0); +define("GRAPH_TYPE_STACKED", 1); - //var $type; // 0 - simple graph; 1 - stacked graph; +define("GRAPH_TYPE_PIE", 2); +define("GRAPH_TYPE_EXPLODED", 3); +define("GRAPH_TYPE_3D", 4); +define("GRAPH_TYPE_3D_EXPLODED", 5); - //var $yaxistype; - var $yaxismin; - var $yaxismax; - //var $yaxisleft; - //var $yaxisright; - var $m_minY; - var $m_maxY; +define("GRAPH_3D_ANGLE", 70); - var $data = array(); +define("GRAPH_STACKED_ALFA", 15); //0..100 transperancy - // items[num].data.min[max|avg] - var $items; - // $idnum[$num] is itemid - var $min; - var $max; - var $avg; - var $clock; - var $count; - // Number of items - //var $num; - - var $header; - - var $from_time; - var $to_time; - - var $colors; - var $im; - - var $triggers = array();*/ - - function Graph($type = GRAPH_TYPE_NORMAL) - { - $this->stime = null; - $this->fullSizeX = null; - $this->fullSizeY = null; +define("GRAPH_ZERO_LINE_COLOR_LEFT", 'AAAAAA'); +define("GRAPH_ZERO_LINE_COLOR_RIGHT", '888888'); - $this->yaxismin = null; - $this->yaxismax = null; +define('ZBX_MAX_TREND_DIFF', 3600); - $this->m_minY = null; - $this->m_maxY = null; +define('ZBX_GRAPH_MAX_SKIP_CELL', 16); +define('ZBX_GRAPH_MAX_SKIP_DELAY', 4); - $this->data = array(); +class Graph{ - $this->items = null; - - $this->min = null; - $this->max = null; - $this->avg = null; - $this->clock = null; - $this->count = null; - - $this->header = null; - - $this->from_time = null; - $this->to_time = null; + function Graph($type = GRAPH_TYPE_NORMAL){ + + $this->stime = null; + $this->fullSizeX = null; + $this->fullSizeY = null; - $this->colors = null; - $this->im = null; + $this->m_minY = null; + $this->m_maxY = null; - $this->triggers = array(); - - $this->period=3600; - $this->from=0; - $this->sizeX=900; - $this->sizeY=200; - $this->shiftXleft=10; - $this->shiftXright=60; - $this->shiftY=17; - $this->border=1; - $this->num=0; - $this->type = $type; - $this->yaxistype=GRAPH_YAXIS_TYPE_CALCULATED; - $this->yaxisright=0; - $this->yaxisleft=0; - - $this->m_showWorkPeriod = 1; - $this->m_showTriggers = 1; - - $this->zero = array(); - $this->graphorientation = ''; -/* if($this->period<=3600) - { - $this->date_format="H:i"; - } - else - { - $this->date_format="m.d H:i"; - }*/ + $this->data = array(); - } + $this->items = null; - function updateShifts() - { - if( ($this->yaxisleft == 1) && ($this->yaxisright == 1)) - { - $this->shiftXleft = 60; - $this->shiftXright = 60; - } - else if($this->yaxisleft == 1) - { - $this->shiftXleft = 60; - $this->shiftXright = 20; - } - else if($this->yaxisright == 1) - { - $this->shiftXleft = 10; - $this->shiftXright = 60; - } -# $this->sizeX = $this->sizeX - $this->shiftXleft-$this->shiftXright; - } + $this->min = null; + $this->max = null; + $this->avg = null; + $this->clock = null; + $this->count = null; - function initColors() - { + $this->header = null; - $colors = array( /* Red, Green, Blue, Alpha */ - "Red" => array(255,0,0,50), - "Dark Red" => array(150,0,0,50), - "Green" => array(0,255,0,50), - "Dark Green" => array(0,150,0,50), - "Blue" => array(0,0,255,50), - "Dark Blue" => array(0,0,150,50), - "Yellow" => array(255,255,0,50), - "Dark Yellow" => array(150,150,0,50), - "Cyan" => array(0,255,255,50), - "Black" => array(0,0,0,50), - "Gray" => array(150,150,150,50), - "White" => array(255,255,255), - "Dark Red No Alpha" => array(150,0,0), - "Black No Alpha" => array(0,0,0), + $this->from_time = null; + $this->to_time = null; - "HistoryMinMax" => array(90,150,185,50), - "HistoryMax" => array(255,100,100,50), - "HistoryMin" => array(50,255,50,50), - "HistoryAvg" => array(50,50,50,50), + $this->colors = null; + $this->colorsrgb = null; + $this->im = null; + + $this->period=3600; + $this->from=0; + $this->sizeX=900; + $this->sizeY=200; + $this->shiftXleft=10; + $this->shiftXright=60; + $this->shiftY=17; + $this->border=1; + $this->num=0; + $this->type = $type; - "ValueMinMax" => array(255,255,150,50), - "ValueMax" => array(255,180,180,50), - "ValueMin" => array(100,255,100,50), + } - "Priority Disaster" => array(255,0,0), - "Priority Hight" => array(255,100,100), - "Priority Average" => array(221,120,120), - "Priority" => array(100,100,100), - "Not Work Period" => array(230,230,230), - "UnknownData" => array(130,130,130, 50) - ); + function initColors() + { + $colors = array( /* Red, Green, Blue, Alpha */ + "Red" => array(255,0,0,50), + "Dark Red" => array(150,0,0,50), + "Green" => array(0,255,0,50), + "Dark Green" => array(0,150,0,50), + "Blue" => array(0,0,255,50), + "Dark Blue" => array(0,0,150,50), + "Yellow" => array(255,255,0,50), + "Dark Yellow" => array(150,150,0,50), + "Cyan" => array(0,255,255,50), + "Dark Cyan" => array(0,150,150,50), + "Black" => array(0,0,0,50), + "Gray" => array(150,150,150,50), + "White" => array(255,255,255), + "Dark Red No Alpha" => array(150,0,0), + "Black No Alpha" => array(0,0,0), + + "HistoryMinMax" => array(90,150,185,50), + "HistoryMax" => array(255,100,100,50), + "HistoryMin" => array(50,255,50,50), + "HistoryAvg" => array(50,50,50,50), + + "ValueMinMax" => array(255,255,150,50), + "ValueMax" => array(255,180,180,50), + "ValueMin" => array(100,255,100,50), + + "Priority Disaster" => array(255,0,0), + "Priority Hight" => array(255,100,100), + "Priority Average" => array(221,120,120), + "Priority" => array(100,100,100), + "Not Work Period" => array(230,230,230), + + "UnknownData" => array(130,130,130, 50) + ); + + $this->colorsrgb = $colors; + // I should rename No Alpha to Alpha at some point to get rid of some confusion - foreach($colors as $name => $RGBA) + foreach($colors as $name => $RGBA) + { + if(isset($RGBA[3]) && + function_exists("ImageColorExactAlpha") && + function_exists("ImageCreateTrueColor") && + @ImageCreateTrueColor(1,1) + ) { - if(isset($RGBA[3]) && - function_exists("ImageColorExactAlpha") && - function_exists("ImageCreateTrueColor") && - @ImageCreateTrueColor(1,1) - ) - { - $this->colors[$name] = ImageColorExactAlpha($this->im,$RGBA[0],$RGBA[1],$RGBA[2],$RGBA[3]); - } - else - { - $this->colors[$name] = ImageColorAllocate($this->im,$RGBA[0],$RGBA[1],$RGBA[2]); - } + $this->colors[$name] = ImageColorExactAlpha($this->im,$RGBA[0],$RGBA[1],$RGBA[2],$RGBA[3]); } - } - - function ShowWorkPeriod($value) - { - $this->m_showWorkPeriod = $value == 1 ? 1 : 0; - } - - function ShowTriggers($value) - { - $this->m_showTriggers = $value == 1 ? 1 : 0; - } - - function AddItem($itemid, $axis=GRAPH_YAXIS_SIDE_RIGHT, $calc_fnc=CALC_FNC_AVG, - $color=null, $drawtype=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]["drawtype"] = is_null($drawtype) ? GRAPH_ITEM_DRAWTYPE_LINE : $drawtype; - $this->items[$this->num]["axisside"] = is_null($axis) ? GRAPH_YAXIS_SIDE_RIGHT : $axis; - $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; - - if($this->items[$this->num]["axisside"] == GRAPH_YAXIS_SIDE_LEFT) - $this->yaxisleft=1; - - if($this->items[$this->num]["axisside"] == GRAPH_YAXIS_SIDE_RIGHT) - $this->yaxisright=1; -// SDI($this->items); - - $this->num++; - } - - function CheckGraphOrientation($value){ - - if(!empty($this->graphorientation)){ - if(($this->graphorientation == '+') && ($value<0)){ -// Error(); - } - elseif(($this->graphorientation == '-') && ($value>0)){ -// Error(); - } - } - else { - if($value < 0){ - $this->graphorientation = '-'; - } - elseif($value > 0){ - $this->graphorientation = '+'; - } + else{ + $this->colors[$name] = ImageColorAllocate($this->im,$RGBA[0],$RGBA[1],$RGBA[2]); } } + } - function setPeriod($period) - { - $this->period=$period; - } - function setYAxisMin($yaxismin) - { - $this->yaxismin=$yaxismin; - } - function setYAxisMax($yaxismax) - { - $this->yaxismax=$yaxismax; - } + function setPeriod($period) + { + $this->period=$period; + } - function setYAxisType($yaxistype) - { - $this->yaxistype=$yaxistype; - } - function SetSTime($stime) + function SetSTime($stime) + { + if($stime>200000000000 && $stime<220000000000) { - if($stime>200000000000 && $stime<220000000000) - { - $this->stime=mktime(substr($stime,8,2),substr($stime,10,2),0,substr($stime,4,2),substr($stime,6,2),substr($stime,0,4)); - } + $this->stime=mktime(substr($stime,8,2),substr($stime,10,2),0,substr($stime,4,2),substr($stime,6,2),substr($stime,0,4)); } + } - function setFrom($from) - { - $this->from=$from; - } + function setFrom($from) + { + $this->from=$from; + } - function setWidth($value = NULL) - { + function setWidth($value = NULL) + { // Avoid sizeX==0, to prevent division by zero later - if($value == 0) $value = NULL; - if($value > 1300) $value = 1300; - if(is_null($value)) $value = 900; + if($value == 0) $value = NULL; + if($value > 1300) $value = 1300; + if(is_null($value)) $value = 900; - $this->sizeX = $value; - } + $this->sizeX = $value; + } - function setHeight($value = NULL) - { - if($value == 0) $value = NULL; - if(is_null($value)) $value = 900; + function setHeight($value = NULL) + { + if($value == 0) $value = NULL; + if(is_null($value)) $value = 900; - $this->sizeY = $value; - } + $this->sizeY = $value; + } - function setBorder($border) - { - $this->border=$border; - } + function setBorder($border) + { + $this->border=$border; + } - function getLastValue($num) + function getLastValue($num) + { + $data = &$this->data[$this->items[$num]["itemid"]][$this->items[$num]["calc_type"]]; + if(isset($data)) for($i=$this->sizeX-1;$i>=0;$i--) { - $data = &$this->data[$this->items[$num]["itemid"]][$this->items[$num]["calc_type"]]; - if(isset($data)) for($i=$this->sizeX-1;$i>=0;$i--) + if(isset($data->count[$i]) && ($data->count[$i] > 0)) { - if(isset($data->count[$i]) && ($data->count[$i] > 0)) + switch($this->items[$num]["calc_fnc"]) { - switch($this->items[$num]["calc_fnc"]) - { - case CALC_FNC_MIN: return $data->min[$i]; - case CALC_FNC_MAX: return $data->max[$i]; - case CALC_FNC_ALL: /* use avg */ - case CALC_FNC_AVG: - default: return $data->avg[$i]; - } + case CALC_FNC_MIN: return $data->min[$i]; + case CALC_FNC_MAX: return $data->max[$i]; + case CALC_FNC_ALL: /* use avg */ + case CALC_FNC_AVG: + default: return $data->avg[$i]; } } - return 0; - } - - function drawSmallRectangle() - { - DashedRectangle($this->im, - $this->shiftXleft-1, - $this->shiftY-1, - $this->sizeX+$this->shiftXleft-1, - $this->sizeY+$this->shiftY+1, - $this->GetColor("Black No Alpha") - ); } + return 0; + } - function drawRectangle() - { - ImageFilledRectangle($this->im,0,0, - $this->fullSizeX,$this->fullSizeY, - $this->GetColor("White")); - - - if($this->border==1) - { - ImageRectangle($this->im,0,0,$this->fullSizeX-1,$this->fullSizeY-1,$this->GetColor("Black No Alpha")); - } - } - - function period2str($period) - { - $second = 1; $minute=$second * 60; $hour=$minute*60; $day=$hour*24; - $str = " ( "; - - $days=floor($this->period/$day); - $hours=floor(($this->period%$day)/$hour); - $minutes=floor((($this->period%$day)%$hour)/$minute); - $seconds=floor(((($this->period%$day)%$hour)%$minute)/$second); - - $str.=($days>0 ? $days."d" : "").($hours>0 ? $hours."h" : "").($minutes>0 ? $minutes."m" : "").($seconds>0 ? $seconds."s" : ""); - $str.=" history "; - - $hour=1; $day=$hour*24; - $days=floor($this->from/$day); - $hours=floor(($this->from%$day)/$hour); - $minutes=floor((($this->from%$day)%$hour)/$minute); - $seconds=floor(((($this->from%$day)%$hour)%$minute)/$second); - - $str.=($days>0 ? $days."d" : "").($hours>0 ? $hours."h" : "").($minutes>0 ? $minutes."m" : "").($seconds>0 ? $seconds."s" : ""); - $str.=($days+$hours+$minutes+$seconds>0 ? " in past " : ""); + function drawSmallRectangle() + { + DashedRectangle($this->im, + $this->shiftXleft-1, + $this->shiftY-1, + $this->sizeX+$this->shiftXleft-1, + $this->sizeY+$this->shiftY+1, + $this->GetColor("Black No Alpha") + ); + } - $str.=")"; + function drawRectangle() + { + ImageFilledRectangle($this->im,0,0, + $this->fullSizeX,$this->fullSizeY, + $this->GetColor("White")); - return $str; - } - function drawHeader() + if($this->border==1) { - if(!isset($this->header)) - { - $str=$this->items[0]["host"].":".$this->items[0]["description"]; - } - else - { - $str=$this->header; - } - - $str=$str.$this->period2str($this->period); - - if($this->sizeX < 500) - { - $fontnum = 2; - } - else - { - $fontnum = 4; - } - $x=$this->fullSizeX/2-ImageFontWidth($fontnum)*strlen($str)/2; - ImageString($this->im, $fontnum,$x,1, $str , $this->GetColor("Dark Red No Alpha")); + ImageRectangle($this->im,0,0,$this->fullSizeX-1,$this->fullSizeY-1,$this->GetColor("Black No Alpha")); } + } - function setHeader($header) - { - $this->header=$header; - } + function period2str($period) + { + $second = 1; $minute=$second * 60; $hour=$minute*60; $day=$hour*24; + $str = " ( "; - function drawGrid() - { - $this->drawSmallRectangle(); - for($i=1;$i<=5;$i++) - { - DashedLine($this->im,$this->shiftXleft,$i*($this->sizeY/6)+$this->shiftY,$this->sizeX+$this->shiftXleft,$i*($this->sizeY/6)+$this->shiftY,$this->GetColor("Gray")); - } + $days=floor($this->period/$day); + $hours=floor(($this->period%$day)/$hour); + $minutes=floor((($this->period%$day)%$hour)/$minute); + $seconds=floor(((($this->period%$day)%$hour)%$minute)/$second); - for($i=1;$i<=23;$i++) - { - DashedLine($this->im,$i*($this->sizeX/24)+$this->shiftXleft,$this->shiftY,$i*($this->sizeX/24)+$this->shiftXleft,$this->sizeY+$this->shiftY,$this->GetColor("Gray")); - } - - $old_day=-1; - for($i=0;$i<=24;$i++) - { - ImageStringUp($this->im, 1,$i*($this->sizeX/24)+$this->shiftXleft-3, $this->sizeY+$this->shiftY+57, date(" H:i",$this->from_time+$i*($this->period/24)) , $this->GetColor("Black No Alpha")); - - $new_day=date("d",$this->from_time+$i*($this->period/24)); - if( ($old_day != $new_day) ||($i==24)) - { - $old_day=$new_day; - ImageStringUp($this->im, 1,$i*($this->sizeX/24)+$this->shiftXleft-3, $this->sizeY+$this->shiftY+57, date("m.d H:i",$this->from_time+$i*($this->period/24)) , $this->GetColor("Dark Red No Alpha")); - - } - } - } - - function drawWorkPeriod() - { - if($this->m_showWorkPeriod != 1) return; - if($this->period > 2678400) return; // > 31*24*3600 (month) - - $db_work_period = DBselect("select work_period from config"); - $work_period = DBfetch($db_work_period); - if(!$work_period) - return; - - $periods = parse_period($work_period['work_period']); - if(!$periods) - return; - - ImageFilledRectangle($this->im, - $this->shiftXleft+1, - $this->shiftY, - $this->sizeX+$this->shiftXleft, - $this->sizeY+$this->shiftY, - $this->GetColor("Not Work Period")); - - $now = time(); - 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; - } - $from = $this->from_time; - $max_time = $this->to_time; - - $start = find_period_start($periods,$from); - $end = -1; - while($start < $max_time && $start > 0) - { - $end = find_period_end($periods,$start,$max_time); - - $x1 = round((($start-$from)*$this->sizeX)/$this->period) + $this->shiftXleft; - $x2 = round((($end-$from)*$this->sizeX)/$this->period) + $this->shiftXleft; - - //draw rectangle - ImageFilledRectangle( - $this->im, - $x1, - $this->shiftY, - $x2, - $this->sizeY+$this->shiftY, - $this->GetColor("White")); - - $start = find_period_start($periods,$end); - } - } + $str.=($days>0 ? $days."d" : "").($hours>0 ? $hours."h" : "").($minutes>0 ? $minutes."m" : "").($seconds>0 ? $seconds."s" : ""); + $str.=" history "; + + $hour=1; $day=$hour*24; + $days=floor($this->from/$day); + $hours=floor(($this->from%$day)/$hour); + $minutes=floor((($this->from%$day)%$hour)/$minute); + $seconds=floor(((($this->from%$day)%$hour)%$minute)/$second); - function calcTriggers() - { - $this->triggers = array(); - if($this->m_showTriggers != 1) return; - if($this->num != 1) return; // skip multiple graphs - - $max = 3; - $cnt = 0; - - $db_triggers = DBselect("select distinct tr.triggerid,tr.expression,tr.priority from triggers tr,functions f,items i". - " where tr.triggerid=f.triggerid and f.function in ('last','min','max') and". - " tr.status=".TRIGGER_STATUS_ENABLED." and i.itemid=f.itemid and f.itemid=".$this->items[0]["itemid"]." order by tr.priority"); - - while(($trigger = DBfetch($db_triggers)) && ($cnt < $max)) - { - $db_fnc_cnt = DBselect('select count(*) as cnt from functions f where f.triggerid='.$trigger['triggerid']); - $fnc_cnt = DBfetch($db_fnc_cnt); - if($fnc_cnt['cnt'] != 1) continue; - - if(!eregi('\{([0-9]{1,})\}([\<\>\=]{1})([0-9\.]{1,})([K|M|G]{0,1})',$trigger['expression'],$arr)) - continue; - - $val = $arr[3]; - if(strcasecmp($arr[4],'K') == 0) $val *= 1024; - else if(strcasecmp($arr[4],'M') == 0) $val *= 1048576; //1024*1024; - else if(strcasecmp($arr[4],'G') == 0) $val *= 1073741824; //1024*1024*1024; + $str.=($days>0 ? $days."d" : "").($hours>0 ? $hours."h" : "").($minutes>0 ? $minutes."m" : "").($seconds>0 ? $seconds."s" : ""); + $str.=($days+$hours+$minutes+$seconds>0 ? " in past " : ""); - $minY = $this->m_minY[$this->items[0]["axisside"]]; - $maxY = $this->m_maxY[$this->items[0]["axisside"]]; + $str.=")"; - if($val <= $minY || $val >= $maxY) continue; - - if($trigger['priority'] == 5) $color = "Priority Disaster"; - elseif($trigger['priority'] == 4) $color = "Priority Hight"; - elseif($trigger['priority'] == 3) $color = "Priority Average"; - else $color = "Priority"; + return $str; + } - array_push($this->triggers,array( - 'y' => $this->sizeY - (($val-$minY) / ($maxY-$minY)) * $this->sizeY + $this->shiftY, - 'color' => $color, - 'description' => 'trigger: '.expand_trigger_description($trigger['triggerid']).' ['.$arr[2].' '.$arr[3].$arr[4].']' - )); - ++$cnt; - } - - } - function drawTriggers() + function drawHeader() + { + if(!isset($this->header)) { - if($this->m_showTriggers != 1) return; - if($this->num != 1) return; // skip multiple graphs - - foreach($this->triggers as $trigger) - { - DashedLine( - $this->im, - $this->shiftXleft, - $trigger['y'], - $this->sizeX+$this->shiftXleft, - $trigger['y'], - $this->GetColor($trigger['color'])); - } - + $str=$this->items[0]["host"].":".$this->items[0]["description"]; } - - function drawLogo() + else { - ImageStringUp($this->im,0,$this->fullSizeX-10,$this->fullSizeY-50, "http://www.zabbix.com", $this->GetColor("Gray")); + $str=$this->header; } - function GetColor($color,$alfa=50) + $str=$str.$this->period2str($this->period); + + if($this->sizeX < 500) { - if(isset($this->colors[$color])) - return $this->colors[$color]; - - $RGB = array( - hexdec('0x'.substr($color, 0,2)), - hexdec('0x'.substr($color, 2,2)), - hexdec('0x'.substr($color, 4,2)) - ); - - if(isset($alfa) && - function_exists("ImageColorExactAlpha") && - function_exists("ImageCreateTrueColor") && - @ImageCreateTrueColor(1,1) - ) - { - return ImageColorExactAlpha($this->im,$RGB[0],$RGB[1],$RGB[2],$alfa); - } - - return ImageColorAllocate($this->im,$RGB[0],$RGB[1],$RGB[2]); + $fontnum = 2; } - - function drawLegend() + else { - $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++) - { - if($this->items[$i]["calc_type"] == GRAPH_ITEM_AGGREGATED) - { - $fnc_name = "agr(".$this->items[$i]["periods_cnt"].")"; - $color = $this->GetColor("HistoryMinMax"); - } - else - { - $color = $this->GetColor($this->items[$i]["color"]); - switch($this->items[$i]["calc_fnc"]) - { - case CALC_FNC_MIN: $fnc_name = "min"; break; - case CALC_FNC_MAX: $fnc_name = "max"; break; - case CALC_FNC_ALL: $fnc_name = "all"; break; - case CALC_FNC_AVG: - default: $fnc_name = "avg"; - } - } - - $data = &$this->data[$this->items[$i]["itemid"]][$this->items[$i]["calc_type"]]; - if(isset($data)&&isset($data->min)) - { - $str=sprintf("%s: %s [%s] [min:%s max:%s last:%s]", - str_pad($this->items[$i]["host"],$max_host_len," "), - str_pad($this->items[$i]["description"],$max_desc_len," "), - $fnc_name, - convert_units(min($data->min),$this->items[$i]["units"]), - convert_units(max($data->max),$this->items[$i]["units"]), - convert_units($this->getLastValue($i),$this->items[$i]["units"])); - } - else - { - $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+$this->shiftY+62+12*$i,$this->shiftXleft+5,$this->sizeY+$this->shiftY+5+62+12*$i,$color); - ImageRectangle($this->im,$this->shiftXleft,$this->sizeY+$this->shiftY+62+12*$i,$this->shiftXleft+5,$this->sizeY+$this->shiftY+5+62+12*$i,$this->GetColor("Black No Alpha")); - - ImageString($this->im, 2, - $this->shiftXleft+9, - $this->sizeY+$this->shiftY+(62-5)+12*$i, - $str, - $this->GetColor("Black No Alpha")); - } - - if($this->sizeY < 120) return; - - foreach($this->triggers as $trigger) - { - ImageFilledEllipse($this->im, - $this->shiftXleft + 2, - $this->sizeY+$this->shiftY+2+62+12*$i, - 6, - 6, - $this->GetColor($trigger["color"])); - - ImageEllipse($this->im, - $this->shiftXleft + 2, - $this->sizeY+$this->shiftY+2+62+12*$i, - 6, - 6, - $this->GetColor("Black No Alpha")); - - ImageString( - $this->im, - 2, - $this->shiftXleft+9, - $this->sizeY+$this->shiftY+(62-5)+12*$i, - $trigger['description'], - $this->GetColor("Black No Alpha")); - ++$i; - } - } - - function drawElement( - &$data, $from, $to, - $minX, $maxX, $minY, $maxY, - $drawtype, $max_color, $avg_color, $min_color, $minmax_color, - $calc_fnc, - $axisside - ) - { - if(!isset($data->max[$from]) || !isset($data->max[$to])) return; - - $oxy = $this->oxy[$axisside]; - $zero = $this->zero[$axisside]; - $unit2px = $this->unit2px[$axisside]; - - $shift_min_from = $shift_min_to = 0; - $shift_max_from = $shift_max_to = 0; - $shift_avg_from = $shift_avg_to = 0; - - if(isset($data->shift_min[$from])) $shift_min_from = $data->shift_min[$from]; - if(isset($data->shift_min[$to])) $shift_min_to = $data->shift_min[$to]; - - if(isset($data->shift_max[$from])) $shift_max_from = $data->shift_max[$from]; - if(isset($data->shift_max[$to])) $shift_max_to = $data->shift_max[$to]; - - if(isset($data->shift_avg[$from])) $shift_avg_from = $data->shift_avg[$from]; - if(isset($data->shift_avg[$to])) $shift_avg_to = $data->shift_avg[$to]; -/**/ - $min_from = $data->min[$from] + $shift_min_from; - $min_to = $data->min[$to] + $shift_min_to; - - $max_from = $data->max[$from] + $shift_max_from; - $max_to = $data->max[$to] + $shift_max_to; - - $avg_from = $data->avg[$from] + $shift_avg_from; - $avg_to = $data->avg[$to] + $shift_avg_to; - - $x1 = $from + $this->shiftXleft - 1; - $x2 = $to + $this->shiftXleft; - -// SDI($max_from." : ".$max_to." : ".$oxy); - - $y1min = $zero - ($min_from-$oxy)/$unit2px; - $y2min = $zero - ($min_to-$oxy)/$unit2px; - - $y1max = $zero - ($max_from-$oxy)/$unit2px; - $y2max = $zero - ($max_to-$oxy)/$unit2px; - - $y1avg = $zero - ($avg_from-$oxy)/$unit2px; - $y2avg = $zero - ($avg_to-$oxy)/$unit2px; //*/ - - switch($calc_fnc){ - case CALC_FNC_MAX: - $y1 = $y1max; - $y2 = $y2max; - $shift_from = $shift_max_from; - $shift_to = $shift_max_to; - break; - case CALC_FNC_MIN: - $y1 = $y1min; - $y2 = $y2min; - $shift_from = $shift_min_from; - $shift_to = $shift_min_to; - break; - case CALC_FNC_ALL: - $a[0] = $x1; $a[1] = $y1max; - $a[2] = $x1; $a[3] = $y1min; - $a[4] = $x2; $a[5] = $y2min; - $a[6] = $x2; $a[7] = $y2max; - - ImageFilledPolygon($this->im,$a,4,$minmax_color); - ImageLine($this->im,$x1,$y1max,$x2,$y2max,$max_color); - ImageLine($this->im,$x1,$y1min,$x2,$y2min,$min_color); - - /* don't use break, avg must be drawed in this statement */ - // break; - case CALC_FNC_AVG: - /* don't use break, avg must be drawed in this statement */ - // break; - default: - $y1 = $y1avg; - $y2 = $y2avg; - $shift_from = $shift_avg_from ; - $shift_to = $shift_avg_to; - } - - $shift_from -= ($shift_from != 0)?($oxy):(0); - $shift_to -= ($shift_to != 0)?($oxy):(0); - - $y1_shift = $zero - $shift_from/$unit2px; - $y2_shift = $zero - $shift_to/$unit2px;//*/ - - /* draw main line */ - switch($drawtype) - { - case GRAPH_ITEM_DRAWTYPE_BOLD_LINE: - ImageLine($this->im,$x1,$y1+1,$x2,$y2+1,$avg_color); - // break; /* don't use break, must be drawed line also */ - case GRAPH_ITEM_DRAWTYPE_LINE: - ImageLine($this->im,$x1,$y1,$x2,$y2,$avg_color); - break; - case GRAPH_ITEM_DRAWTYPE_FILLED_REGION: - $a[0] = $x1; $a[1] = $y1; - $a[2] = $x1; $a[3] = $y1_shift; - $a[4] = $x2; $a[5] = $y2_shift; - $a[6] = $x2; $a[7] = $y2; - -// SDI($a); - - ImageFilledPolygon($this->im,$a,4,$avg_color); - break; - case GRAPH_ITEM_DRAWTYPE_DOT: - ImageFilledRectangle($this->im,$x1-1,$y1-1,$x1+1,$y1+1,$avg_color); - ImageFilledRectangle($this->im,$x2-1,$y2-1,$x2+1,$y2+1,$avg_color); - break; - case GRAPH_ITEM_DRAWTYPE_DASHED_LINE: - if( function_exists('imagesetstyle') ){ - - /* Use ImageSetStyle+ImageLIne instead of bugged ImageDashedLine */ - $style = array($avg_color, $avg_color, IMG_COLOR_TRANSPARENT, IMG_COLOR_TRANSPARENT); - ImageSetStyle($this->im, $style); - ImageLine($this->im,$x1,$y1,$x2,$y2,IMG_COLOR_STYLED); - } - else{ - ImageDashedLine($this->im,$x1,$y1,$x2,$y2,$avg_color); - } - break; - } - } - -// Calculation of minimum Y axis - function calculateMinY($side){ - if($this->yaxistype==GRAPH_YAXIS_TYPE_FIXED){ - return $this->yaxismin; - } - else{ - unset($minY); - for($i=0;$i<$this->num;$i++){ - - if($this->items[$i]["axisside"] != $side) - continue; - - foreach(array(GRAPH_ITEM_SIMPLE, GRAPH_ITEM_AGGREGATED) as $type){ - - if(!isset($this->data[$this->items[$i]["itemid"]][$type])) - continue; - - $data = &$this->data[$this->items[$i]["itemid"]][$type]; - - if(!isset($data)) continue; - - if($type == GRAPH_ITEM_AGGREGATED) - $calc_fnc = CALC_FNC_ALL; - else - $calc_fnc = $this->items[$i]["calc_fnc"]; - - switch($calc_fnc){ - case CALC_FNC_ALL: /* use min */ - case CALC_FNC_MIN: $val = $data->min; $shift_val = $data->shift_min; break; - case CALC_FNC_MAX: $val = $data->max; $shift_val = $data->shift_max; break; - case CALC_FNC_AVG: - default: $val = $data->avg; $shift_val = $data->shift_avg; - } - - if(!isset($val)) continue; - - if($this->type == GRAPH_TYPE_STACKED){ - $min_val_shift = min(count($val), count($shift_val)); - for($ci=0; $ci < $min_val_shift; $ci++){ - if($shift_val[$ci] < 0){ - $val[$ci] += $shift_val[$ci]; - } - } - - } - - if(!isset($minY)){ - if(isset($val) && count($val) > 0){ - $minY = min($val); - } - } - else{ - $minY = min($minY, min($val)); - } - } - } - - if(isset($minY)&&($minY>0)){ - $minY = $minY - ($minY * 0.2) - 0.05; - } - elseif(isset($minY)&&($minY<0)){ - $minY = $minY + ($minY * 0.2) - 0.05; - } - else { - $minY=0; - } - - $minY = round($minY,1); - return $minY; - } + $fontnum = 4; } + $x=$this->fullSizeX/2-ImageFontWidth($fontnum)*strlen($str)/2; + ImageString($this->im, $fontnum,$x,1, $str , $this->GetColor("Dark Red No Alpha")); + } -// Calculation of maximum Y of a side (left/right) - function calculateMaxY($side) - { - if($this->yaxistype==GRAPH_YAXIS_TYPE_FIXED) - { - return $this->yaxismax; - } - else - { - - unset($maxY); - for($i=0;$i<$this->num;$i++) - { - if($this->items[$i]["axisside"] != $side) - continue; - - foreach(array(GRAPH_ITEM_SIMPLE, GRAPH_ITEM_AGGREGATED) as $type) - { - if(!isset($this->data[$this->items[$i]["itemid"]][$type])) - continue; - - $data = &$this->data[$this->items[$i]["itemid"]][$type]; - - if(!isset($data)) continue; - - if($type == GRAPH_ITEM_AGGREGATED) - $calc_fnc = CALC_FNC_ALL; - else - $calc_fnc = $this->items[$i]["calc_fnc"]; + function setHeader($header) + { + $this->header=$header; + } - switch($calc_fnc) - { - case CALC_FNC_ALL: /* use max */ - case CALC_FNC_MAX: $val = $data->max; $shift_val = $data->shift_max; break; - case CALC_FNC_MIN: $val = $data->min; $shift_val = $data->shift_min; break; - case CALC_FNC_AVG: - default: $val = $data->avg; $shift_val = $data->shift_avg; - } - - if(!isset($val)) continue; - for($ci=0; $ci < min(count($val),count($shift_val)); $ci++) $val[$ci] += $shift_val[$ci]; + function drawLogo() + { + ImageStringUp($this->im,0,$this->fullSizeX-10,$this->fullSizeY-50, "http://www.zabbix.com", $this->GetColor("Gray")); + } - if(!isset($maxY)) - { - if(isset($val) && count($val) > 0) - { - $maxY = max($val); - } - } - else - { - $maxY = max($maxY, max($val)); - } - - } - } + function GetColor($color,$alfa=50){ - if(isset($maxY)&&($maxY>0)){ - -/* $exp = round(log10($maxY)); - $mant = $maxY/pow(10,$exp); - - $mant=((round(($mant*11)/6)-1)*6)/10; - $maxY = $mant*pow(10,$exp);//*/ - - $maxY = round($maxY,1) + round($maxY,1)*0.2 + 0.05; - } - elseif(isset($maxY)&&($maxY<0)){ - $maxY = round($maxY,1) - round($maxY,1)*0.2 + 0.05; - } - else { - $maxY=0.3; - } - return $maxY; - } - } - - 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 - - for($i=0; $i < $this->num; $i++) - { - $type = $this->items[$i]["calc_type"]; - - if($type == GRAPH_ITEM_AGGREGATED) { - /* skip current period */ - $from_time = $this->from_time - $this->period * $this->items[$i]["periods_cnt"]; - $to_time = $this->from_time; - } else { - $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 itemid,'.$calc_field.' as i,'. - ' count(*) as count,avg(value) as avg,min(value) as min,'. - ' max(value) as max,max(clock) as clock'. - ' from history where itemid='.$this->items[$i]['itemid'].' and clock>='.$from_time. - ' and clock<='.$to_time.' group by itemid,'.$calc_field - , - - 'select itemid,'.$calc_field.' as i,'. - ' count(*) as count,avg(value) as avg,min(value) as min,'. - ' max(value) as max,max(clock) as clock'. - ' from history_uint where itemid='.$this->items[$i]['itemid'].' and clock>='.$from_time. - ' and clock<='.$to_time.' group by itemid,'.$calc_field - ); - } - else - { - array_push($sql_arr, - 'select itemid,'.$calc_field.' as i,'. - ' sum(num) as count,avg(value_avg) as avg,min(value_min) as min,'. - ' max(value_max) as max,max(clock) as clock'. - ' from trends where itemid='.$this->items[$i]['itemid'].' and clock>='.$from_time. - ' and clock<='.$to_time.' group by itemid,'.$calc_field - ); - } - - $curr_data = &$this->data[$this->items[$i]["itemid"]][$type]; - $curr_data->count = NULL; - $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)) - { - $idx=$row["i"]-1; - if($idx<0) continue; - /* -------------------------------------------------- - We are taking graph on 1px more than we need, - and here we are skiping first px, because of MOD (in SELECT), - it combines prelast point (it would be last point if not that 1px in begining) - and first point, but we still losing prelast point :( - --------------------------------------------------*/ - - $curr_data->count[$idx] = $row["count"]; - $curr_data->min[$idx] = $row["min"]; - $curr_data->max[$idx] = $row["max"]; - $curr_data->avg[$idx] = $row["avg"]; - $curr_data->clock[$idx] = $row["clock"]; - $curr_data->shift_min[$idx] = 0; - $curr_data->shift_max[$idx] = 0; - $curr_data->shift_avg[$idx] = 0; -// SDI($idx.' : '.$row['clock'].' : '.$row['count'].' : '.round($x * (($row['clock']+$z) % $p) / $p, 0)); - - if($this->type == GRAPH_TYPE_STACKED){ - $this->CheckGraphOrientation($curr_data->min[$idx]); - } - } - unset($row); - } - /* calculate missed points */ - $first_idx = 0; - /* - first_idx - last existed point - ci - current index - cj - count of missed in onetime - dx - offset to first value (count to last existed point) - //*/ - - for($ci = 0, $cj=0; $ci < $this->sizeX; $ci++) - { - if(!isset($curr_data->count[$ci]) || $curr_data->count[$ci] == 0) - { - $curr_data->count[$ci] = 0; - $curr_data->shift_min[$ci] = 0; - $curr_data->shift_max[$ci] = 0; - $curr_data->shift_avg[$ci] = 0; - $cj++; - } - else if($cj > 0) - { - $dx = $cj + 1; - - $first_idx = $ci - $dx; - - if($first_idx < 0) $first_idx = $ci; // if no data from start of graph get current data as first data - - for(;$cj > 0; $cj--){ - -/* if(($first_idx == $ci) && ($dx < ($this->sizeX)) && ($this->type == GRAPH_TYPE_STACKED)){ - $curr_data->count[$ci - ($dx - $cj)] = 1; - } - else //*/ - if(($dx < ($this->sizeX/20)) && ($this->type == GRAPH_TYPE_STACKED)){ - $curr_data->count[$ci - ($dx - $cj)] = 1; - }//*/ - - foreach(array('clock','min','max','avg') as $var_name){ - $var = &$curr_data->$var_name; - - if($first_idx == $ci && $var_name == 'clock'){ - $var[$ci - ($dx - $cj)] = $var[$first_idx] - (($p / $this->sizeX) * ($dx - $cj)); - continue; - } - - $dy = $var[$ci] - $var[$first_idx]; - $var[$ci - ($dx - $cj)] = $var[$first_idx] + ($cj * $dy) / $dx; - } - } - } - } - - if($cj > 0 && $ci > $cj){ - $dx = $cj + 1; - - $first_idx = $ci - $dx; - - for(;$cj > 0; $cj--){ - -// if($dx < ($this->sizeX/20)) //($this->type == GRAPH_TYPE_STACKED) -// $curr_data->count[$first_idx + ($dx - $cj)] = 1; - - foreach(array('clock','min','max','avg') as $var_name){ - $var = &$curr_data->$var_name; - - if( $var_name == 'clock') - { - $var[$first_idx + ($dx - $cj)] = $var[$first_idx] + (($p / $this->sizeX) * ($dx - $cj)); - continue; - } - $var[$first_idx + ($dx - $cj)] = $var[$first_idx]; - } - } - } - /* end of missed points calculation */ - } - - /* calculte shift for stacked graphs */ + if(isset($this->colors[$color])) + return $this->colors[$color]; - if($this->type == GRAPH_TYPE_STACKED) - { - for($i=1; $i<$this->num; $i++) - { - $curr_data = &$this->data[$this->items[$i]["itemid"]][$this->items[$i]["calc_type"]]; - - if(!isset($curr_data)) continue; - - for($j = $i-1; $j >= 0; $j--) - { - if($this->items[$j]["axisside"] != $this->items[$i]["axisside"]) continue; - - $prev_data = &$this->data[$this->items[$j]["itemid"]][$this->items[$j]["calc_type"]]; - - if(!isset($prev_data)) continue; - - for($ci = 0; $ci < $this->sizeX; $ci++) - { - foreach(array('min','max','avg') as $var_name) - { - $shift_var_name = 'shift_'.$var_name; - $curr_shift = &$curr_data->$shift_var_name; - $curr_var = &$curr_data->$var_name; - $prev_shift = &$prev_data->$shift_var_name; - $prev_var = &$prev_data->$var_name; - $curr_shift[$ci] = $prev_var[$ci] + $prev_shift[$ci]; - } - } - break; - } - } - } - /* end calculation of stacked graphs */ - } - - function DrawLeftSide() + $RGB = array( + hexdec('0x'.substr($color, 0,2)), + hexdec('0x'.substr($color, 2,2)), + hexdec('0x'.substr($color, 4,2)) + ); + + if(isset($alfa) && + function_exists("ImageColorExactAlpha") && + function_exists("ImageCreateTrueColor") && + @ImageCreateTrueColor(1,1) + ) { - if($this->yaxisleft == 1) - { - $minY = $this->m_minY[GRAPH_YAXIS_SIDE_LEFT]; - $maxY = $this->m_maxY[GRAPH_YAXIS_SIDE_LEFT]; - - for($item=0;$item<$this->num;$item++) - { - if($this->items[$item]["axisside"] == GRAPH_YAXIS_SIDE_LEFT) - { - $units=$this->items[$item]["units"]; - break; - } - } - for($i=0;$i<=6;$i++) - { - $str = str_pad(convert_units($this->sizeY*$i/6*($maxY-$minY)/$this->sizeY+$minY,$units),10," ", STR_PAD_LEFT); - ImageString($this->im, 1, 5, $this->sizeY-$this->sizeY*$i/6-4+$this->shiftY, $str, $this->GetColor("Dark Red No Alpha")); - } - if(($this->zero[GRAPH_YAXIS_SIDE_LEFT] != $this->sizeY+$this->shiftY) && - ($this->zero[GRAPH_YAXIS_SIDE_LEFT] != $this->shiftY)){ - imageline($this->im, - $this->shiftXleft, - $this->zero[GRAPH_YAXIS_SIDE_LEFT], - $this->shiftXleft+$this->sizeX, - $this->zero[GRAPH_YAXIS_SIDE_LEFT], - $this->GetColor(GRAPH_ZERO_LINE_COLOR_LEFT) - ); //*/ - } - } + return ImageColorExactAlpha($this->im,$RGB[0],$RGB[1],$RGB[2],$alfa); } - - function DrawRightSide() - { - if($this->yaxisright == 1) - { - $minY = $this->m_minY[GRAPH_YAXIS_SIDE_RIGHT]; - $maxY = $this->m_maxY[GRAPH_YAXIS_SIDE_RIGHT]; - - for($item=0;$item<$this->num;$item++){ - if($this->items[$item]["axisside"] == GRAPH_YAXIS_SIDE_RIGHT){ - $units=$this->items[$item]["units"]; - break; - } - } - for($i=0;$i<=6;$i++){ - $str = str_pad(convert_units($this->sizeY*$i/6*($maxY-$minY)/$this->sizeY+$minY,$units),10," "); - ImageString($this->im, 1, $this->sizeX+$this->shiftXleft+2, $this->sizeY-$this->sizeY*$i/6-4+$this->shiftY, $str, $this->GetColor("Dark Red No Alpha")); - } - - if(($this->zero[GRAPH_YAXIS_SIDE_RIGHT] != $this->sizeY+$this->shiftY) && - ($this->zero[GRAPH_YAXIS_SIDE_RIGHT] != $this->shiftY)){ - imageline($this->im, - $this->shiftXleft, - $this->zero[GRAPH_YAXIS_SIDE_RIGHT], - $this->shiftXleft+$this->sizeX, - $this->zero[GRAPH_YAXIS_SIDE_RIGHT], - $this->GetColor(GRAPH_ZERO_LINE_COLOR_RIGHT) - ); //*/ - } - } + + return ImageColorAllocate($this->im,$RGB[0],$RGB[1],$RGB[2]); + } + + function GetShadow($color,$alfa=0){ + + if(isset($this->colorsrgb[$color])){ + $red = $this->colorsrgb[$color][0]; + $green = $this->colorsrgb[$color][1]; + $blue = $this->colorsrgb[$color][2]; + } + else{ + $red = hexdec(substr($color, 0,2)); + $green = hexdec(substr($color, 2,2)); + $blue = hexdec(substr($color, 4,2)); } - function CalcZero(){ - $left = GRAPH_YAXIS_SIDE_LEFT; - $right = GRAPH_YAXIS_SIDE_RIGHT; - - $this->unit2px[$right] = ($this->m_maxY[$right] - $this->m_minY[$right])/$this->sizeY; - $this->unit2px[$left] = ($this->m_maxY[$left] - $this->m_minY[$left])/$this->sizeY; - - if($this->m_minY[$right]>0){ - $this->zero[$right] = $this->sizeY+$this->shiftY; - $this->oxy[$right] = min(abs($this->m_minY[$right]),abs($this->m_maxY[$right])); - } - elseif($this->m_maxY[$right]<0) { - $this->zero[$right] = $this->shiftY; - $this->oxy[$right] = min(abs($this->m_minY[$right]),abs($this->m_maxY[$right])); - } - else{ - $this->zero[$right] = $this->sizeY+$this->shiftY - (int)abs($this->m_minY[$right]/$this->unit2px[$right]); - $this->oxy[$right] = 0; - } - - if($this->m_minY[$left]>0){ - $this->zero[$left] = $this->sizeY+$this->shiftY; - $this->oxy[$left] = min(abs($this->m_minY[$left]),abs($this->m_maxY[$left])); - } - elseif($this->m_maxY[$left]<0){ - $this->zero[$left] = $this->shiftY; - $this->oxy[$left] = min(abs($this->m_minY[$left]),abs($this->m_maxY[$left])); - } - else{ - $this->zero[$left] = $this->sizeY+$this->shiftY - (int)abs($this->m_minY[$left]/$this->unit2px[$left]); - $this->oxy[$left] = 0; - } + if($this->sum > 0){ + $red = (int)($red * 0.6); + $green = (int)($green * 0.6); + $blue = (int)($blue * 0.6); } - - function Draw() + + $RGB = array($red,$green,$blue); + + if(isset($alfa) && + function_exists("ImageColorExactAlpha") && + function_exists("ImageCreateTrueColor") && + @ImageCreateTrueColor(1,1) + ) { - $start_time=getmicrotime(); - - set_image_header(); - - check_authorisation(); - - $this->selectData(); - - $this->m_minY[GRAPH_YAXIS_SIDE_LEFT] = $this->calculateMinY(GRAPH_YAXIS_SIDE_LEFT); - $this->m_minY[GRAPH_YAXIS_SIDE_RIGHT] = $this->calculateMinY(GRAPH_YAXIS_SIDE_RIGHT); - $this->m_maxY[GRAPH_YAXIS_SIDE_LEFT] = $this->calculateMaxY(GRAPH_YAXIS_SIDE_LEFT); - $this->m_maxY[GRAPH_YAXIS_SIDE_RIGHT] = $this->calculateMaxY(GRAPH_YAXIS_SIDE_RIGHT); - - $this->updateShifts(); - $this->calcTriggers(); - $this->CalcZero(); - - $this->fullSizeX = $this->sizeX+$this->shiftXleft+$this->shiftXright+1; - $this->fullSizeY = $this->sizeY+$this->shiftY+62+12*($this->num+ (($this->sizeY < 120) ? 0 : count($this->triggers)))+8; - - 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(); - - if($this->num==0) - { -// $this->noDataFound(); - } - - $this->drawWorkPeriod(); - $this->drawGrid(); - - $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; - - if($this->items[$item]["calc_type"] == GRAPH_ITEM_AGGREGATED){ - $drawtype = GRAPH_ITEM_DRAWTYPE_LINE; - - $max_color = $this->GetColor("HistoryMax"); - $avg_color = $this->GetColor("HistoryAvg"); - $min_color = $this->GetColor("HistoryMin"); - $minmax_color = $this->GetColor("HistoryMinMax"); - - $calc_fnc = CALC_FNC_ALL; - } - elseif($this->type == GRAPH_TYPE_STACKED){ - $drawtype = $this->items[$item]["drawtype"]; - - $max_color = $this->GetColor("ValueMax",GRAPH_STACKED_ALFA); - $avg_color = $this->GetColor($this->items[$item]["color"],GRAPH_STACKED_ALFA); - $min_color = $this->GetColor("ValueMin",GRAPH_STACKED_ALFA); - $minmax_color = $this->GetColor("ValueMinMax",GRAPH_STACKED_ALFA); - - $calc_fnc = $this->items[$item]["calc_fnc"]; - } - else{ - $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"]; - } - // For each X - for($i = 1, $j = 0; $i < $maxX; $i++) // new point - { - if(($data->count[$i] == 0) && ($i != ($maxX-1))) continue; - - $diff = abs($data->clock[$i] - $data->clock[$j]); - $cell = ($this->to_time - $this->from_time)/$this->sizeX; - $delay = $this->items[$item]["delay"]; - - if($cell > $delay) - $draw = (boolean) ($diff < ZBX_GRAPH_MAX_SKIP_CELL * $cell); - else - $draw = (boolean) ($diff < ZBX_GRAPH_MAX_SKIP_DELAY * $delay); - - if($draw == false && $this->items[$item]["calc_type"] == GRAPH_ITEM_AGGREGATED) - $draw = $i - $j < 5; - - if($this->items[$item]["type"] == ITEM_TYPE_TRAPPER) - $draw = true; -// SDI($draw); - if($draw){ - - $this->drawElement( - $data, - $i, $j, - 0, $this->sizeX, - $minY, $maxY, - $drawtype, - $max_color, - $avg_color, - $min_color, - $minmax_color, - $calc_fnc, - $this->items[$item]['axisside'] - ); - } -// echo "\nDraw II \n"; printf("%0.4f",(getmicrotime()-$start_time)); - - $j = $i; - } - } - - $this->DrawLeftSide(); - $this->DrawRightSide(); - $this->drawTriggers(); - - $this->drawLogo(); - - $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); + return ImageColorExactAlpha($this->im,$RGB[0],$RGB[1],$RGB[2],$alfa); } + + return ImageColorAllocate($this->im,$RGB[0],$RGB[1],$RGB[2]); } + +} ?> 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 |
