Changeset - ab1afe7444f3
[Not reviewed]
default
1 4 0
Marcin Kuzminski - 15 years ago 2010-06-23 00:18:10
marcin@python-works.com
Initial graph release.
5 files changed with 120 insertions and 137 deletions:
0 comments (0 inline, 0 general)
pylons_app/controllers/changelog.py
Show inline comments
 
#!/usr/bin/env python
 
# encoding: utf-8
 
# changelog controller for pylons
 
# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
 
from json import dumps
 
from mercurial.graphmod import colored, CHANGESET
 
from mercurial.node import short
 
from mercurial.templatefilters import person
 
from pylons import request, session, tmpl_context as c
 
from pylons_app.lib.auth import LoginRequired
 
from pylons_app.lib.base import BaseController, render
 
from pylons_app.model.hg_model import HgModel
 
from webhelpers.paginate import Page
 
import logging
 
from mercurial.graphmod import revisions as graph_rev
 
 
 
# 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; version 2
 
# of the License or (at your opinion) any later version of the license.
 
# 
 
@@ -19,18 +30,12 @@
 
# MA  02110-1301, USA.
 
"""
 
Created on April 21, 2010
 
changelog controller for pylons
 
@author: marcink
 
"""
 
from pylons import request, session, tmpl_context as c
 
from pylons_app.lib.auth import LoginRequired
 
from pylons_app.lib.base import BaseController, render
 
from pylons_app.model.hg_model import HgModel
 
from webhelpers.paginate import Page
 
import logging
 
log = logging.getLogger(__name__)     
 

	
 
class ChangelogController(BaseController):
 
    
 
    @LoginRequired()
 
    def __before__(self):
 
@@ -55,42 +60,38 @@ class ChangelogController(BaseController
 
            
 
        p = int(request.params.get('page', 1))
 
        c.total_cs = len(changesets)
 
        c.pagination = Page(changesets, page=p, item_count=c.total_cs,
 
                            items_per_page=c.size)
 
            
 
        #self._graph(c.repo, c.size,p)
 
        self._graph(changesets, c.size, p)
 
        
 
        return render('changelog/changelog.html')
 

	
 

	
 
    def _graph(self, repo, size, p):
 
        pass
 
#        revcount = size
 
#        if not repo.revisions:return dumps([]), 0
 
#        
 
#        max_rev = repo.revisions[-1]
 
#        offset = 1 if p == 1 else  ((p - 1) * revcount)
 
#        rev_start = repo.revisions[(-1 * offset)]
 
#        c.bg_height = 120
 
#        
 
#        revcount = min(max_rev, revcount)
 
#        rev_end = max(0, rev_start - revcount)
 
#        dag = graph_rev(repo.repo, rev_start, rev_end)
 
#        
 
#        c.dag = tree = list(colored(dag))
 
#        canvasheight = (len(tree) + 1) * c.bg_height - 27
 
#        data = []
 
#        for (id, type, ctx, vtx, edges) in tree:
 
#            if type != CHANGESET:
 
#                continue
 
#            node = short(ctx.node())
 
#            age = _age(ctx.date())
 
#            desc = ctx.description()
 
#            user = person(ctx.user())
 
#            branch = ctx.branch()
 
#            branch = branch, repo.repo.branchtags().get(branch) == ctx.node()
 
#            data.append((node, vtx, edges, desc, user, age, branch, ctx.tags()))
 
#    
 
#        c.jsdata = dumps(data) 
 
#        c.canvasheight = canvasheight 
 
        revcount = size
 
        if not repo.revisions:return dumps([]), 0
 
        
 
        max_rev = repo.revisions[-1]
 
        offset = 1 if p == 1 else  ((p - 1) * revcount)
 
        rev_start = repo.revisions[(-1 * offset)]
 
        
 
        revcount = min(max_rev, revcount)
 
        rev_end = max(0, rev_start - revcount)
 
        dag = graph_rev(repo.repo, rev_start, rev_end)
 
        
 
        c.dag = tree = list(colored(dag))
 
        data = []
 
        for (id, type, ctx, vtx, edges) in tree:
 
            if type != CHANGESET:
 
                continue
 
            node = short(ctx.node())
 
            age = ctx.date()
 
            desc = ctx.description()
 
            user = person(ctx.user())
 
            branch = ctx.branch()
 
            branch = branch, repo.repo.branchtags().get(branch) == ctx.node()
 
            data.append((node, vtx, edges, desc, user, age, branch, ctx.tags()))
 
    
 
        c.jsdata = dumps(data) 
 

	
pylons_app/public/css/monoblue_custom.css
Show inline comments
 
@@ -642,16 +642,14 @@ p.files {
 
	text-align: left;	
 
}
 

	
 
/** end of changeset **/ 
 

	
 
/** canvas **/
 
canvas {
 
	position: absolute;
 
	z-index: 5;
 
	top: -0.7em;
 
#graph_nodes{
 
	margin-top:8px;
 
}
 
#graph{
 
	overflow: hidden;
 

	
 
}
 
#graph_nodes{
pylons_app/public/js/excanvas.js
Show inline comments
 
deleted file
pylons_app/public/js/graph.js
Show inline comments
 
// branch_renderer.js - Rendering of branch DAGs on the client side
 
//
 
// Copyright 2008 Jesper Noehr <jesper AT noehr DOT org>
 
// Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
 
// Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
 
//
 
// derived from code written by Scott James Remnant <scott@ubuntu.com>
 
// Copyright 2005 Canonical Ltd.
 
//
 
@@ -12,126 +13,119 @@
 
var colors = [
 
	[ 1.0, 0.0, 0.0 ],
 
	[ 1.0, 1.0, 0.0 ],
 
	[ 0.0, 1.0, 0.0 ],
 
	[ 0.0, 1.0, 1.0 ],
 
	[ 0.0, 0.0, 1.0 ],
 
	[ 1.0, 0.0, 1.0 ]
 
	[ 1.0, 0.0, 1.0 ],
 
	[ 1.0, 1.0, 0.0 ],
 
	[ 0.0, 0.0, 0.0 ]
 
];
 

	
 
function Graph() {
 
function BranchRenderer() {
 
	
 
	this.canvas = document.getElementById('graph');
 
	if (navigator.userAgent.indexOf('MSIE') >= 0) this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
 
	this.canvas = document.getElementById("graph_canvas");
 
	
 
	//if ($.browser.msie)
 
	//	this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
 
	this.ctx = this.canvas.getContext('2d');
 
	this.ctx.strokeStyle = 'rgb(0, 0, 0)';
 
	this.ctx.fillStyle = 'rgb(0, 0, 0)';
 
	this.cur = [0, 0];
 
	this.max_column = 1;
 
	this.line_width = 3;
 
	this.bg = [0, 4];
 
	this.cell = [2, 0];
 
	this.columns = 0;
 
	this.revlink = '';
 
	
 
	this.scale = function(height) {
 
		this.box_size = Math.floor(height/1.2);
 
		this.cell_height = this.box_size;
 
		this.bg_height = height;
 
		this.box_size = Math.floor(this.bg_height / 1.2);
 
		this.cell_height = this.box_size;
 
	}
 
	
 
	function colorPart(num) {
 
		num *= 255
 
		num = num < 0 ? 0 : num;
 
		num = num > 255 ? 255 : num;
 
		var digits = Math.round(num).toString(16);
 
		if (num < 16) {
 
			return '0' + digits;
 
		} else {
 
			return digits;
 
		}
 
	}
 

	
 
	this.setColor = function(color, bg, fg) {
 
		
 
		// Set the colour.
 
		//
 
		// Picks a distinct colour based on an internal wheel; the bg
 
		// parameter provides the value that should be assigned to the 'zero'
 
		// colours and the fg parameter provides the multiplier that should be
 
		// applied to the foreground colours.
 
		
 
		color %= colors.length;
 
		var red = (colors[color][0] * fg) || bg;
 
		var green = (colors[color][1] * fg) || bg;
 
		var blue = (colors[color][2] * fg) || bg;
 
		red = Math.round(red * 255);
 
		green = Math.round(green * 255);
 
		blue = Math.round(blue * 255);
 
		var s = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
 
		this.ctx.strokeStyle = s;
 
		this.ctx.fillStyle = s;
 
		return s;
 
		
 
	}
 

	
 
	this.render = function(data) {
 
		
 
		var backgrounds = '';
 
		var nodedata = '';
 
		var idx = 1;
 
		var rela = document.getElementById('graph');
 
		var pad = 160;
 
		var scale = 20;
 
		
 
		for (var i in data) {
 
			this.scale(scale);
 
			var row = document.getElementById("chg_"+idx);
 
			var	next = document.getElementById("chg_"+idx+1);
 
			var extra = 0;
 
			
 
			var parity = i % 2;
 
			this.cell[1] += this.bg_height;
 
			//skip this since i don't have DATE in my app
 
			//if (next.is('.changesets-date')) {
 
			//	extra = next.outerHeight();
 
			//}
 
						
 
			
 
			this.cell[1] += row.clientWidth;
 
			this.bg[1] += this.bg_height;
 
			
 
			var cur = data[i];
 
			var node = cur[1];
 
			var edges = cur[2];
 
			var fold = false;
 
			cur = data[i];
 
			nodeid = cur[0];
 
			node = cur[1];
 
			in_l = cur[2];
 
			
 
			for (var j in edges) {
 
			for (var j in in_l) {
 
				
 
				line = edges[j];
 
				line = in_l[j];
 
				start = line[0];
 
				end = line[1];
 
				color = line[2];
 

	
 
				if (end > this.columns || start > this.columns) {
 
					this.columns += 1;
 
				if (start > this.max_column) {
 
					this.max_column = start;
 
				}
 
				
 
				if (start == this.columns && start > end) {
 
					var fold = true;
 
				if (end > this.max_column) {
 
					this.max_column = end;
 
				}
 
				
 
				x0 = this.cell[0] + this.box_size * start + this.box_size / 2;
 
				y0 = this.bg[1] - this.bg_height / 2;
 
				x1 = this.cell[0] + this.box_size * end + this.box_size / 2;
 
				y1 = this.bg[1] + this.bg_height / 2;
 
				this.setColor(color, 0.0, 0.65);
 
				
 
				
 
				this.edge(x0, y0, x1, y1, color);
 
				y = row.offsetTop-rela.offsetTop+4;
 
				x = pad-((this.cell[0] + this.box_size * start - 1) + this.bg_height-2);
 
				this.ctx.beginPath();
 
				this.ctx.moveTo(x, y);
 
				
 
				y += row.clientHeight;
 
				x = pad-((1 + this.box_size * end) + this.bg_height-2);
 
				this.ctx.lineTo(x,y+extra);
 
				this.ctx.stroke();
 
			}
 
			
 
			// Draw the revision node in the right column
 
			
 
			column = node[0]
 
			color = node[1]
 
			
 
			radius = this.box_size / 8;
 
			x = this.cell[0] + this.box_size * column + this.box_size / 2;
 
			y = this.bg[1] - this.bg_height / 2;
 
			var add = this.vertex(x, y, color, parity, cur);
 
			backgrounds += add[0];
 
			nodedata += add[1];
 
			radius = 4;
 
			y = row.offsetTop-rela.offsetTop+4;
 
			x = pad-(Math.round(this.cell[0] * scale/2 * column + radius) + 15 - (column*4));
 
		
 
			this.ctx.beginPath();
 
			this.setColor(color, 0.25, 0.75);
 
			this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
 
			this.ctx.fill();
 
			
 
			if (fold) this.columns -= 1;
 
			
 
			idx++;
 
		}
 
		
 
		document.getElementById('nodebgs').innerHTML += backgrounds;
 
		document.getElementById('graphnodes').innerHTML += nodedata;
 
		
 
				
 
	}
 

	
 
}
pylons_app/templates/changelog/changelog.html
Show inline comments
 
@@ -21,24 +21,24 @@
 
    	${_('out of')} ${c.total_cs} ${_('revisions')}
 
    </h2>
 
	<noscript>${_('The revision graph only works with JavaScript-enabled browsers.')}</noscript>
 
% if c.pagination:
 

	
 
<div id="graph">
 
	##<div id="graph_nodes" style="height:1000px">
 
	##	<canvas id="graph" width="160"></canvas>
 
	##</div>
 
	<div id="graph_nodes">
 
		<canvas id="graph_canvas"></canvas>
 
	</div>
 
	<div id="graph_content">
 
		<div class="container_header">
 
			${h.form(h.url.current(),method='get')}
 
				${_('Show')}: ${h.text('size',size=2,value=c.size)} ${_('revisions')}
 
				${h.submit('','set')}
 
			${h.end_form()}
 
		</div>
 
	%for cnt,cs in enumerate(c.pagination):
 
		<div class="container">
 
		<div id="chg_${cnt+1}" class="container">
 
			<div class="left">
 
				<div class="date">${_('commit')} ${cs.revision}: ${cs.raw_id}@${cs.date}</div>
 
				<div class="author">${cs.author}</div>
 
				<div id="chg_${cnt}" class="message">
 
					${h.link_to(h.wrap_paragraphs(cs.message),
 
					h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}
 
@@ -69,25 +69,34 @@
 
			</div>				
 
		</div>
 
		
 
	%endfor
 
	</div>
 
</div>
 
<script type="text/javascript" src="/js/graph.js"></script>
 

	
 
##<script type="text/javascript" src="/js/graph2.js"></script>
 
##<script type="text/javascript" src="http://bitbucket-assets.s3.amazonaws.com/js/lib/bundle.160310Mar.js"></script>
 
##
 
##<script>
 
##<!-- hide script content
 
##
 
##var jsdata = ${c.jsdata|n};
 
##var r = new BranchRenderer();
 
##r.render(jsdata); 
 
<script type="text/javascript">
 
YAHOO.util.Event.onDOMReady(function(){
 
	function set_canvas() {
 
		var c = document.getElementById('graph_nodes');
 
		var t = document.getElementById('graph_content');
 
		canvas = document.getElementById('graph_canvas');
 
		var div_h = t.clientHeight;
 
		c.style.height=div_h+'px';
 
		canvas.setAttribute('height',div_h);
 
		canvas.setAttribute('width',160);
 
	};
 

	
 
##// stop hiding script -->
 
##</script>
 
	set_canvas();
 
	
 
	var jsdata = ${c.jsdata|n};
 
	var r = new BranchRenderer();
 
	r.render(jsdata); 
 

	
 
});
 
</script>
 

	
 
<div>
 
	<h2>${c.pagination.pager('$link_previous ~2~ $link_next')}</h2>
 
</div>	
 
%else:
 
	${_('There are no changes yet')}
0 comments (0 inline, 0 general)