caption = $caption; $this->background_colour = 0xffffcc; $this->border_colour = 0x000000; $this->text_colour = 0x000000; $this->filled = false; $this->font_file = 'times.ttf'; $this->font_size = 12; if($data == '') $data = $caption; $this->data = $data; } function render() { // calculate dimensions $z = imagettfbbox($this->font_size, 0, $this->font_file, $this->caption); $width = $z[4] - $z[0]; $height = $z[5] - $z[1]; $diameter = ceil(sqrt(2) * (8 + max($width, $height))); // create image $img = imagecreate($diameter + 4, $diameter + 2); // allocate colours imagecolorallocateint($img, $this->background_colour); $fg = imagecolorallocateint($img, $this->border_colour); if($this->text_colour != $this->border_colour) $tc = imagecolorallocateint($img, $this->text_colour); else $tc = $fg; // render circle if($this->filled) imagefilledarc($img, $diameter / 2 + 2, $diameter / 2 + 1, $diameter, $diameter, 0, 360, $fg, IMG_ARC_PIE); else imagearc($img, $diameter / 2 + 2, $diameter / 2 + 1, $diameter, $diameter, 0, 360, $fg); // render text imagettftext($img, $this->font_size, 0, $diameter / 2 + 2 - $width / 2, $diameter / 2 + 1 - $height / 2, $tc, $this->font_file, $this->caption); return $img; } } class tree { var $parent; var $children; var $background_colour; var $line_colour; var $map; function tree($parent, $children=array()) { $this->parent = $parent; $this->children = $children; $this->background_colour = $parent->background_colour; $this->line_colour = $parent->text_colour; $this->map = array(); } function from_array($a) { foreach($a as $key=>$val) { $n = new node($key); if(is_array($val)) { $t = new tree($n); $t->from_array($val); $this->children[] = $t; } else { $n->data = $val; $this->children[] = $n; } } } function render() { // render parent $p = $this->parent->render(); // render children for($i = 0; $i < sizeof($this->children); $i++) $n[] = $this->children[$i]->render(); // calculate size $width = imagesx($n[0]); $height = imagesy($n[0]); for($i = 1; $i < sizeof($n); $i++) { $width += imagesx($n[$i]); $height = max($height, imagesy($n[$i])); } $height += imagesy($p) + $width / 6 + 4; $width = max($width, imagesx($p)); $img = imagecreate($width, $height); imagecolorallocateint($img, $this->background_colour); $fg = imagecolorallocateint($img, $this->line_colour); // place parent on image map $m = array('x'=>round($width/2), 'y'=>round(imagesy($p)/2), 'r'=>round(imagesy($p)/2), 'data'=>$this->parent->data); $this->map = array($m); // place parent on image imagecopy($img, $p, $m['x'] - imagesx($p) / 2, 0, 0, 0, imagesx($p), imagesy($p)); $x = 0; $y = imagesy($p) + $width / 6; $px = $width / 2; $py = imagesy($p); for($i = 0; $i < sizeof($n); $i++) { $sx = imagesx($n[$i]); $sy = imagesy($n[$i]); if($x > 0) { // edge back until we hit something $w = $x - $sx / 2; $z = imagecolorat($img, 0, 0); $found = 0; for($u = $x; $u > $w; $u--) { for($v = $y; $v < $sy + $y; $v++) { $a = imagecolorat($img, $u, $v); //imagesetpixel($img, $u, $v, 1); if($a != $z) { $found = 1; break; } } if($found == 0) $x = $u; else break; } } $x++; $sx = imagesx($n[$i]); if(isset($this->children[$i]->map)) { // translate image map from child tree for($j = 0; $j < sizeof($this->children[$i]->map); $j++) $this->map[] = array('x'=>round($this->children[$i]->map[$j]['x']+$x), 'y'=>round($this->children[$i]->map[$j]['y']+$y), 'r'=>$this->children[$i]->map[$j]['r'], 'data'=>$this->children[$i]->map[$j]['data']); } else // place child on image map $this->map[] = array('x'=>round($x+$sx / 2), 'y'=>round($y + $sy / 2), 'r'=>round($sy / 2), 'data'=>$this->children[$i]->data); // place child on image imagecopy($img, $n[$i], $x, $y, 0, 0, $sx, $sy); imageline($img, $x + $sx / 2, $y, $px, $py, $fg); $x += $sx; } // $i = imagecreate($x, imagesy($img)); // imagecopy($i, $img, 0, 0, 0, 0, $x, imagesy($img)); return $img; } function test_map() { $img = $this->render(); $red = imagecolorallocate($img, 255, 0, 0); for($i = 0; $i < sizeof($this->map); $i++) imagearc($img, $this->map[$i]['x'], $this->map[$i]['y'], 2 * $this->map[$i]['r'], 2 * $this->map[$i]['r'], 0, 360, $red); return $img; } function image_map($name) { $ret = "\n"; for($i = 0; $i < sizeof($this->map); $i++) { $data = $this->map[$i]['data']; if(is_array($data)) { if(isset($data['url'])) { $url = $data['url']; unset($data['url']); } else $url = '#'; if(isset($data['caption'])) $alt = $data['caption']; else { $alt = ''; foreach($data as $key=>$val) $alt .= "$key=$val\n"; $alt = trim($alt); } } else { $alt = $this->map[$i]['data']; $url = '#'; } $ret .= " map[$i]['x']},{$this->map[$i]['y']},{$this->map[$i]['r']}\""; $ret .= " href=\"$url\" alt=\"$alt\" />\n"; } $ret .= "\n"; return $ret; } } ?>