| 1 | <?php
|
|---|
| 2 | // Skript pro generování grafu stromové struktury sítě do PNG obrázku
|
|---|
| 3 | include('../global.php');
|
|---|
| 4 |
|
|---|
| 5 | if (array_key_exists('debug', $_GET)) $debug = $_GET['debug'];
|
|---|
| 6 | else $debug = 0;
|
|---|
| 7 | $TopHostName = 'nix-router';
|
|---|
| 8 | // $debug = 0;
|
|---|
| 9 |
|
|---|
| 10 | // === Zpětné vyvážení stromu do hloubky =======================================
|
|---|
| 11 | function balance($id, $level, &$vlast, &$vleft, &$vpred, &$vfirst, &$vnext, &$tbound, &$width, $limit)
|
|---|
| 12 | {
|
|---|
| 13 | global $debug, $bbound;
|
|---|
| 14 |
|
|---|
| 15 | if (!array_key_exists($id, $vfirst)) $vfirst[$id] = 0;
|
|---|
| 16 | if ($i = $vfirst[$id])
|
|---|
| 17 | {
|
|---|
| 18 | //if ($debug==2) echo $id.':'.@$i.','.@$vpred[$i].'-'.@$vleft[@$vpred[$i]]."\n";
|
|---|
| 19 | if (($vlast[$id] > 0) && ($vleft[$id] > $vleft[$vlast[$id]]))
|
|---|
| 20 | {
|
|---|
| 21 | $diff=$vleft[$id]-$vleft[$vlast[$id]];
|
|---|
| 22 | $i=$vfirst[$id];
|
|---|
| 23 | if ($vleft[$id] >= $tbound[$level])
|
|---|
| 24 | {
|
|---|
| 25 | $tbound[$level] = $vleft[$id] + 2;
|
|---|
| 26 | if ($vleft[$id] > $width) $width = $vleft[$id];
|
|---|
| 27 | }
|
|---|
| 28 | } else {
|
|---|
| 29 | $diff=0;
|
|---|
| 30 | if ($vpred[$i]&&($vleft[$i]<=$vleft[$vpred[$i]]))
|
|---|
| 31 | {
|
|---|
| 32 | $diff=$vleft[$i]-$vleft[$vpred[$i]]+2;
|
|---|
| 33 | } else $i = 0;
|
|---|
| 34 | }
|
|---|
| 35 | while ($i>0)
|
|---|
| 36 | {
|
|---|
| 37 | $vleft[$i]+=$diff;
|
|---|
| 38 | $limit = balance($i,$level+1, $vlast,$vleft,$vpred, $vfirst,$vnext,$tbound, $width, $limit) + 2;
|
|---|
| 39 | if (!array_key_exists($i, $vnext)) $vnext[$i] = 0;
|
|---|
| 40 | $i = $vnext[$i];
|
|---|
| 41 | }
|
|---|
| 42 | }
|
|---|
| 43 | }
|
|---|
| 44 |
|
|---|
| 45 | // === Generování rovinné stromové struktury ===================================
|
|---|
| 46 | function gentree($mode) // depth-first algorithm
|
|---|
| 47 | {
|
|---|
| 48 | global $debug, $TopHostName, $Database;
|
|---|
| 49 |
|
|---|
| 50 | // --- Inicializace ----------------------------------------------------------
|
|---|
| 51 | $tbound = array(); // Hranice pozic jednotlivých úrovní
|
|---|
| 52 | $tranger = array(); // Hranicni prvek
|
|---|
| 53 | $position = array(); // Pozice aktuálního prvku na dané úrovni
|
|---|
| 54 | $vfirst = array(); // První potomek prvku
|
|---|
| 55 | $vlast = array(); // Poslední potomek prvku
|
|---|
| 56 | $vnext = array(); // Následující sourozenec
|
|---|
| 57 | $vleft = array(); // Pozice prvku zleva
|
|---|
| 58 | $vtop = array(); // Pozice prvku shora
|
|---|
| 59 | $vpred = array(); // Vedlejsi prvek na řádku
|
|---|
| 60 |
|
|---|
| 61 | $index = 0; // Index aktuálního prvku
|
|---|
| 62 | $curr = 0; // Aktuální prvek
|
|---|
| 63 | $level = 0; // Aktuální úroveň hloubky ve stromu
|
|---|
| 64 | $width = 0; // Šířka stromu
|
|---|
| 65 | $height = 0; // Hloubka stromu
|
|---|
| 66 |
|
|---|
| 67 | $parent[$level] = 0; // Rodič dané úrovně
|
|---|
| 68 | $position[$level] = 0; // Aktuální pozice prvku na dané úrovni
|
|---|
| 69 | $count[$level] = 0; // Počet prvků na dané úrovni
|
|---|
| 70 |
|
|---|
| 71 | $maxindex = 0;
|
|---|
| 72 | $tbound[$level] = 0;
|
|---|
| 73 | $tranger[$level] = 0;
|
|---|
| 74 |
|
|---|
| 75 | // --- Hlavní cyklus ---------------------------------------------------------
|
|---|
| 76 | do
|
|---|
| 77 | {
|
|---|
| 78 | // --- Proveď databázový dotaz -----------------------------------------------
|
|---|
| 79 | $query = 'SELECT * FROM hosts WHERE used=1 AND ';
|
|---|
| 80 | if ($level == 0)
|
|---|
| 81 | {
|
|---|
| 82 | $query .= 'name = "'.$TopHostName.'" ORDER BY id';
|
|---|
| 83 | } else
|
|---|
| 84 | {
|
|---|
| 85 | $query .= ' parent = '.$parent[$level].' ORDER BY id';
|
|---|
| 86 | }
|
|---|
| 87 | if ($mode) $query.=' DESC';
|
|---|
| 88 | $query .= ' LIMIT '.$position[$level].',1';
|
|---|
| 89 | //echo($query.'<br>');
|
|---|
| 90 | $DbResult = $Database->query($query);
|
|---|
| 91 | $item = $DbResult->fetch_array();
|
|---|
| 92 | if ($item)
|
|---|
| 93 | {
|
|---|
| 94 | // --- Zpracování položky z DB -----------------------------------------------
|
|---|
| 95 | if ($position[$level] > 0)
|
|---|
| 96 | {
|
|---|
| 97 | $vnext[$curr] = $item['id']; // Neprvní položka, nastav předchozí
|
|---|
| 98 | }
|
|---|
| 99 | $curr = $item['id'];
|
|---|
| 100 | if ($curr > $maxindex) $maxindex = $curr;
|
|---|
| 101 | if ($position[$level] == 0) $vfirst[$parent[$level]]=$curr; // První položka, nastav první
|
|---|
| 102 | $vlast[$parent[$level]] = $curr;
|
|---|
| 103 | $vtop[$curr] = $level;
|
|---|
| 104 | if (!array_key_exists($level, $tbound)) $tbound[$level] = 0;
|
|---|
| 105 | $vleft[$curr] = $tbound[$level];
|
|---|
| 106 | if (!array_key_exists($level, $tranger)) $tranger[$level] = 0;
|
|---|
| 107 | $vpred[$curr] = $tranger[$level];
|
|---|
| 108 | $tranger[$level] = $curr;
|
|---|
| 109 | if (($debug == 3) && ($level == 8)) echo $curr.',';
|
|---|
| 110 | $position[$level]++;
|
|---|
| 111 | $count[$level]++;
|
|---|
| 112 | // --- Zjisti existenci potomků ----------------------------------------------
|
|---|
| 113 | $DbResult = $Database->query('SELECT COUNT(*) FROM hosts WHERE used=1 AND parent = '.$curr);
|
|---|
| 114 | $childcnt = $DbResult->fetch_array();
|
|---|
| 115 | if ($childcnt[0] > 0)
|
|---|
| 116 | {
|
|---|
| 117 | // Uzelový vrchol
|
|---|
| 118 | if (array_key_exists($level + 1, $tbound))
|
|---|
| 119 | if ($tbound[$level + 1] > $vleft[$curr]) $vleft[$curr] = $tbound[$level + 1];
|
|---|
| 120 | }
|
|---|
| 121 | $tbound[$level] = $vleft[$curr] + 2;
|
|---|
| 122 | if ($vleft[$curr] > $width) $width = $vleft[$curr];
|
|---|
| 123 | if ($childcnt[0] > 0)
|
|---|
| 124 | {
|
|---|
| 125 | $level++;
|
|---|
| 126 | if ($level > $height) $height = $level;
|
|---|
| 127 | $parent[$level] = $curr;
|
|---|
| 128 | $position[$level] = 0;
|
|---|
| 129 | $count[$level] = 0;
|
|---|
| 130 | } else $index++; // Listový vrchol
|
|---|
| 131 | } else
|
|---|
| 132 | {
|
|---|
| 133 | // --- Zarovnávání prvků kvůli vzhledu
|
|---|
| 134 | if (!array_key_exists($vfirst[$parent[$level]], $vleft)) $vleft[$vfirst[$parent[$level]]] = 0;
|
|---|
| 135 | if (!array_key_exists($parent[$level], $vleft)) $vleft[$parent[$level]] = 0;
|
|---|
| 136 | if ($vleft[$vfirst[$parent[$level]]] > $vleft[$parent[$level]])
|
|---|
| 137 | {
|
|---|
| 138 | $vleft[$parent[$level]] = $vleft[$vfirst[$parent[$level]]];
|
|---|
| 139 | if ($vleft[$parent[$level]]+2>$tbound[$level-1]) $tbound[$level-1] = $vleft[$parent[$level]]+2;
|
|---|
| 140 | }
|
|---|
| 141 | balance($parent[$level],$level, $vlast,$vleft,$vpred,$vfirst,$vnext,$tbound, $width, 0);
|
|---|
| 142 | if ($position[$level]==1)
|
|---|
| 143 | {
|
|---|
| 144 | $vleft[$vfirst[$parent[$level]]] = $vleft[$parent[$level]];
|
|---|
| 145 | }
|
|---|
| 146 | $level--;
|
|---|
| 147 | if (!array_key_exists($level, $parent)) $parent[$level] = 0;
|
|---|
| 148 | if (!array_key_exists($parent[$level], $vlast)) $vlast[$parent[$level]] = 0;
|
|---|
| 149 | $curr = $vlast[$parent[$level]];
|
|---|
| 150 |
|
|---|
| 151 | if (!array_key_exists($level, $tbound)) $tbound[$level] = 0;
|
|---|
| 152 | if (!array_key_exists($level + 1, $tbound)) $tbound[$level + 1] = 0;
|
|---|
| 153 | if ($tbound[$level] > $tbound[$level + 1]) $tbound[$level + 1] = $tbound[$level];
|
|---|
| 154 | }
|
|---|
| 155 | } while ($level >= 0);
|
|---|
| 156 | $data = compact('tbound', 'count', 'tbound', 'vfirst', 'vlast', 'vtop', 'vleft', 'height', 'width', 'index', 'maxindex');
|
|---|
| 157 | return $data;
|
|---|
| 158 | };
|
|---|
| 159 |
|
|---|
| 160 | // === Vytvoř stromy a spoj je =================================================
|
|---|
| 161 | extract(gentree(0));
|
|---|
| 162 | // exit();
|
|---|
| 163 | $data = gentree(1);
|
|---|
| 164 | $datawidth = $data['width'];
|
|---|
| 165 | for ($i = 0; $i <= $maxindex; $i++)
|
|---|
| 166 | {
|
|---|
| 167 | if (!array_key_exists($i, $vleft)) $vleft[$i] = 0;
|
|---|
| 168 | if (!array_key_exists($i, $data['vleft'])) $data['vleft'][$i] = 0;
|
|---|
| 169 | $vleft[$i] = .2 + ($vleft[$i] + ($datawidth - $data['vleft'][$i])) / 2;
|
|---|
| 170 | }
|
|---|
| 171 |
|
|---|
| 172 | $spacex = 32;
|
|---|
| 173 | $spacey = 68;
|
|---|
| 174 | $halfx = $spacex / 2;
|
|---|
| 175 | $halfy = $spacey / 2;
|
|---|
| 176 |
|
|---|
| 177 | // Preload icon images
|
|---|
| 178 | $IconList = array();
|
|---|
| 179 | $DbResult = $Database->query('SELECT * FROM HostType');
|
|---|
| 180 | while ($HostType = $DbResult->fetch_assoc())
|
|---|
| 181 | $IconList[$HostType['Id']] = imagecreatefrompng('images/'.$HostType['IconName'].'.png');
|
|---|
| 182 |
|
|---|
| 183 | // === Generování obrázku ======================================================
|
|---|
| 184 | $im = imagecreate(($datawidth + $width + 3.2) * $halfx, ($height + 1) * $spacey);
|
|---|
| 185 | $background_color = imagecolorallocate($im, 255, 255, 255);
|
|---|
| 186 | $black = imagecolorallocate($im, 0, 0, 0);
|
|---|
| 187 | $red = imagecolorallocate($im, 255, 0, 0);
|
|---|
| 188 | $green = imagecolorallocate($im, 0, 128, 0);
|
|---|
| 189 | $blue = imagecolorallocate($im, 100, 100, 255);
|
|---|
| 190 | $gray = imagecolorallocate($im, 160, 160, 160);
|
|---|
| 191 |
|
|---|
| 192 | function xpos($id)
|
|---|
| 193 | {
|
|---|
| 194 | global $vleft, $spacex;
|
|---|
| 195 | return $vleft[$id] * $spacex;
|
|---|
| 196 | }
|
|---|
| 197 |
|
|---|
| 198 | $DbResult = $Database->query('SELECT * FROM hosts JOIN HostType ON HostType.Id = hosts.type WHERE hosts.used=1');
|
|---|
| 199 | while ($item = $DbResult->fetch_array())
|
|---|
| 200 | {
|
|---|
| 201 | $id = $item['id'];
|
|---|
| 202 | if (!array_key_exists($id, $vtop)) $vtop[$id] = 0;
|
|---|
| 203 | if (($vtop[$id] > 0) || ($item['name'] == $TopHostName))
|
|---|
| 204 | {
|
|---|
| 205 | if ($vtop[$id] > 0) imageline($im, xpos($id) + $halfx, $vtop[$id] * $spacey, xpos($id) + $halfx, $vtop[$id] * $spacey + 8, $black);
|
|---|
| 206 | if (!array_key_exists($id, $vfirst)) $vfirst[$id] = 0;
|
|---|
| 207 | if ($vfirst[$id] > 0)
|
|---|
| 208 | {
|
|---|
| 209 | imageline($im, xpos($vfirst[$id]) + $halfx, $vtop[$id] * $spacey + $spacey, xpos($vlast[$id]) + $halfx, $vtop[$id] * $spacey + $spacey, $black);
|
|---|
| 210 | imageline($im, xpos($id) + $halfx, ($vtop[$id] + 1) * $spacey - 10, xpos($id) + $halfx, ($vtop[$id] + 1) * $spacey, $black);
|
|---|
| 211 | }
|
|---|
| 212 |
|
|---|
| 213 | $image = $IconList[$item['type']];
|
|---|
| 214 | if ($item['IP'] == '')
|
|---|
| 215 | {
|
|---|
| 216 | $color = $gray;
|
|---|
| 217 | } else
|
|---|
| 218 | if ($item['ShowOnline'] == 1)
|
|---|
| 219 | {
|
|---|
| 220 | if ($item['online'] == 1) $color = $green; else $color = $black;
|
|---|
| 221 | } else
|
|---|
| 222 | {
|
|---|
| 223 | if ($item['online'] == 1) $color = $green; else $color = $red;
|
|---|
| 224 | }
|
|---|
| 225 | // $text='IP: '.$ip[0];
|
|---|
| 226 | // imagestring($im,2,xpos($id)+($spacex-strlen($text)*imagefontwidth(2))/2,$vtop[$id]*$spacey+24+imagefontheight(2),$text,$black);
|
|---|
| 227 | imagecopy($im, $image, xpos($id) + $halfx - 15, $vtop[$id] * $spacey + 12, 0, 0, 30, 30);
|
|---|
| 228 | // imagerectangle($im,xpos($id)+$halfx-6,$vtop[$id]*$spacey+16,xpos($id)+$halfx+6,$vtop[$id]*$spacey+28,$color);
|
|---|
| 229 | if ($debug)
|
|---|
| 230 | {
|
|---|
| 231 | imagestring($im, 2, xpos($id) + ($spacex - strlen($item['id']) * imagefontwidth(2)) / 2, $vtop[$id] * $spacey + 31 + imagefontheight(2), $item['id'], $color);
|
|---|
| 232 | } else
|
|---|
| 233 | imagestring($im, 2, xpos($id) + ($spacex - strlen($item['name']) * imagefontwidth(2)) / 2, $vtop[$id] * $spacey + 31 + imagefontheight(2), strtoupper($item['name']), $color);
|
|---|
| 234 | }
|
|---|
| 235 | }
|
|---|
| 236 |
|
|---|
| 237 | // === Sestavení výsledného souboru ============================================
|
|---|
| 238 | if (!($debug > 1))
|
|---|
| 239 | {
|
|---|
| 240 | header('Content-type: image/png');
|
|---|
| 241 | header('Cache-Control: no-cache');
|
|---|
| 242 | imagepng($im);
|
|---|
| 243 | imagedestroy($im);
|
|---|
| 244 | }
|
|---|