finished graphs
[phpgitweb.git] / htdocs / lib / graph.class.php
index 5cf843eafce637a484dc1d41398722ff3180e504..53f1aaee6fa5ca5120a6f492037d28ceca9cf3d5 100644 (file)
@@ -26,7 +26,7 @@ class graph_data_generator {
        private $max_branches, $brach_id = 1, $branch_id = 1;
        
        public function __construct() {
-               $this->max_branches = 10;
+               $this->max_branches = GitConfig::GITGRAPH_MAX_BRANCHES;
                $this->data['branches'] = array();
                $this->data['ubranches'] = array();
        }
@@ -55,6 +55,8 @@ class graph_data_generator {
        }
        
        public function parse($commits) {
+               if(!GitConfig::GITGRAPH_ENABLE)
+                       return;
                $brach_id = $this->brach_id;
                $branch_uid = $this->branch_id;
                $first_commit = (count($this->data['branches']) == 0 ? true : false);
@@ -113,7 +115,7 @@ class graph_data_generator {
                                for($j = 1; $j < count($commit['parent']); $j++) {
                                        $add = true;
                                        foreach($this->data['branches'] as $cbranch) {
-                                               if($cbranch['next'] == $commit['parent'][$j]) {
+                                               if(array_key_exists('next', $cbranch) && $cbranch['next'] == $commit['parent'][$j]) {
                                                        $add = false;
                                                        break;
                                                }
@@ -218,6 +220,8 @@ class graph_data_generator {
        }
        
        public function get_graph($id) {
+               if(!GitConfig::GITGRAPH_ENABLE)
+                       return;
                $graph = $this->graph[$id];
                $data = $graph['d']['p'].$graph['d']['type'].count($this->data['branches']).'('.implode(',', $graph['l']).')';
                $first_merge = true;
@@ -231,29 +235,49 @@ class graph_data_generator {
                }
                $graph['cs'] = array();
                foreach($graph['br'] as $buid) {
+                       if(!$buid) continue;
                        $branch = $this->data['ubranches'][$buid];
-                       if($branch['pre_merge'] && $branch['pre_merge_start'])
+                       if($branch['pre_merge'] && array_key_exists('pre_merge_start', $branch) && $branch['pre_merge_start'])
                                $graph['cs'][] = $branch['id']."=".$branch['pre_merge_id'];
                }
                if(count($graph['cs'])) {
                        $data .= '('.implode(',', $graph['cs']).')';
                }
+               if(GitConfig::GITGRAPH_BASE64)
+                       $data = base64_encode($data);
                return $data;
        }
        
+       public function get_header_graph() {
+               $data = "head:";
+               $branchcount = 0;
+               $dataadd = "";
+               foreach($this->data['branches'] as $branch) {
+                       if(array_key_exists('sticky', $branch) && $branch['sticky']) {
+                               $name = explode('/', $branch['name'][0], 3);
+                               $dataadd .= "\n".$branch['id'].":".$name[2];
+                               $branchcount++;
+                       }
+               }
+               $data.=$branchcount.$dataadd;
+               if(GitConfig::GITGRAPH_BASE64)
+                       $data = base64_encode($data);
+               return $data;
+       }
 }
 
 class graph_image_generator {
-       private $max_branches = 10;
+       private $max_branches;
        private $image;
-       private $size = 20;
-       private $tile_size = 20;
+       private $size;
+       private $tile_size;
+       private $header_height = false;
        private $colors, $color_swap = array();
        
-       public function generate($data) {
-               $data = $this->parse_data($data);
-               if(!$data)
-                       return;
+       public function __construct() {
+               $this->max_branches = GitConfig::GITGRAPH_MAX_BRANCHES;
+               $this->size = GitConfig::GITGRAPH_END_SIZE;
+               $this->tile_size = GitConfig::GITGRAPH_TILE_SIZE;
                
                $this->colors = array(
                        NULL,
@@ -265,6 +289,14 @@ class graph_image_generator {
                        array(0, 128, 128),
                        array(128, 0, 128)
                );
+       }
+       
+       public function generate($data) {
+               if(!GitConfig::GITGRAPH_ENABLE)
+                       return;
+               $data = $this->parse_data($data);
+               if(!$data)
+                       return;
                
                $count = $data['count'];
                if($count > $this->max_branches)
@@ -282,10 +314,50 @@ class graph_image_generator {
                imagedestroy($this->image);
        }
        
+       private function display_header($header) {
+               $header = explode("\n",$header);
+               $count = $header[0];
+               $header = array_slice($header, 1);
+               if($count > $this->max_branches)
+                       $count = $this->max_branches;
+               if(!$this->header_height) {
+                       $maxlen = 0;
+                       foreach($header as $head) {
+                               $head = explode(":", $head, 2);
+                               $name = $head[1];
+                               if(strlen($name) > $maxlen)
+                                       $maxlen = strlen($name);
+                       }
+                       $this->header_height = $maxlen * 2 + 15;
+               }
+               $image = imagecreatetruecolor($count * $this->size + 60, $this->header_height);
+               $transparentIndex = imagecolorallocate($image, 217, 216, 209);
+               imagefill($image, 0, 0, $transparentIndex);
+               $branches = 0;
+               foreach($header as $head) {
+                       $head = explode(":", $head, 2);
+                       $color = $this->get_color($head[0], true);
+                       $name = $head[1];
+                       $branches++;
+                       $color = imagecolorallocatealpha($image, $color[0], $color[1], $color[2], 0);
+                       imagettftext($image, 8, 28, ($head[0]-1) * $this->size + 10, $this->header_height-2, $color, realpath(dirname(__FILE__)."/../")."/res/arial.ttf", $name);
+               }
+               if(!$branches) die();
+               imagecolortransparent($image, $transparentIndex);
+               header('Content-Type: image/png');
+               imagepng($image);
+               imagedestroy($image);
+       }
+       
        private function parse_data($data) {
-               //$data = array();
-               if(!preg_match("/^([0-9]+)([abc]{1})([0-9]+)\(([^\)]*)\)([a-z0-9,\|]*)(\(([^\)]*)\)|)/i", $data, $matches))
+               if(GitConfig::GITGRAPH_BASE64)
+                       $data = base64_decode($data);
+               if(!preg_match("/^([0-9]+)([abc]{1})([0-9]+)\(([^\)]*)\)([a-z0-9,\|]*)(\(([^\)]*)\)|)/i", $data, $matches)) {
+                       if(preg_match("/head:(.*)/i", $data, $matches)) {
+                               $this->display_header(substr($data, strlen("head:")));
+                       }
                        return null;
+               }
                
                $data = array();
                $data['dot'] = array();
@@ -359,28 +431,28 @@ class graph_image_generator {
        
        private function apply_data($data) {
                foreach($data['l'] as $l)
-                       $this->overlay_image("img/line.png", ($l-1) * $this->size, $this->get_color($l));
+                       $this->overlay_image("res/line.png", ($l-1) * $this->size, $this->get_color($l));
                foreach($data['m'] as $m) {
                        if($m['dd'] == 'r')
-                               $this->overlay_image("img/dot_merge_right.png", ($data['dot']['pos'] - 1) * $this->size, $this->get_color($m['pos']));
+                               $this->overlay_image("res/dot_merge_right.png", ($data['dot']['pos'] - 1) * $this->size, $this->get_color($m['pos']));
                        else if($m['dd'] == 'l')
-                               $this->overlay_image("img/dot_merge_left.png", ($data['dot']['pos'] - 1) * $this->size, $this->get_color($m['pos']));
+                               $this->overlay_image("res/dot_merge_left.png", ($data['dot']['pos'] - 1) * $this->size, $this->get_color($m['pos']));
                        if($m['md'] == 'r')
-                               $this->overlay_image("img/".(($m['ml'] & 1) ? "branch" : "merge")."_right.png", ($m['pos'] - 1) * $this->size, $this->get_color($m['pos']));
+                               $this->overlay_image("res/".(($m['ml'] & 1) ? "branch" : "merge")."_right.png", ($m['pos'] - 1) * $this->size, $this->get_color($m['pos']));
                        else if($m['md'] == 'l')
-                               $this->overlay_image("img/".(($m['ml'] & 1) ? "branch" : "merge")."_left.png", ($m['pos'] - 1) * $this->size, $this->get_color($m['pos']));
+                               $this->overlay_image("res/".(($m['ml'] & 1) ? "branch" : "merge")."_left.png", ($m['pos'] - 1) * $this->size, $this->get_color($m['pos']));
                        if($m['ml'] == 0)
-                               $this->overlay_image("img/line.png", ($m['pos'] - 1) * $this->size, $this->get_color($m['pos']));
+                               $this->overlay_image("res/line.png", ($m['pos'] - 1) * $this->size, $this->get_color($m['pos']));
                        foreach($m['hl'] as $hl) {
-                               $this->overlay_image("img/line_h.png", ($hl - 1) * $this->size, $this->get_color($m['pos']));
+                               $this->overlay_image("res/line_h.png", ($hl - 1) * $this->size, $this->get_color($m['pos']));
                        }
                }
                if($data['dot']['type'] == 'a')
-                       $this->overlay_image("img/dot.png", ($data['dot']['pos'] - 1) * $this->size, $this->get_color($data['dot']['pos']));
+                       $this->overlay_image("res/dot.png", ($data['dot']['pos'] - 1) * $this->size, $this->get_color($data['dot']['pos']));
                else if($data['dot']['type'] == 'b')
-                       $this->overlay_image("img/dot_merge.png", ($data['dot']['pos'] - 1) * $this->size, $this->get_color($data['dot']['pos']));
+                       $this->overlay_image("res/dot_merge.png", ($data['dot']['pos'] - 1) * $this->size, $this->get_color($data['dot']['pos']));
                else if($data['dot']['type'] == 'c')
-                       $this->overlay_image("img/dot_init.png", ($data['dot']['pos'] - 1) * $this->size, $this->get_color($data['dot']['pos']));
+                       $this->overlay_image("res/dot_init.png", ($data['dot']['pos'] - 1) * $this->size, $this->get_color($data['dot']['pos']));
                
        }