Mercurial > public > mercurial-scm > hg-stable
diff mercurial/hgweb/webcommands.py @ 16773:d490edc71146
hgweb: make graph data suitable for template usage
Previously, graph data has been encoded for processing done by
JavaScript code run in the browser, employing simple structures
with implicit member positions. This patch modifies the graph
command to also produce data employing a dictionary-based
structure suitable for use with the templating mechanism, thus
permitting other ways of presenting repository graphs using that
mechanism.
In order to test these changes, the raw theme has been modified
to include templates for graph nodes and edges. In a similar
fashion, themes could employ technologies such as SVG that lend
themselves to templating to produce the graph display. This patch
makes use of a much simpler output representation than SVG in
order to maintain clarity.
author | Paul Boddie <paul@boddie.org.uk> |
---|---|
date | Mon, 21 May 2012 00:20:05 +0200 |
parents | 3e24ce3de5f1 |
children | 6b40cc67ceb4 |
line wrap: on
line diff
--- a/mercurial/hgweb/webcommands.py Mon May 21 14:25:46 2012 -0500 +++ b/mercurial/hgweb/webcommands.py Mon May 21 00:20:05 2012 +0200 @@ -784,28 +784,76 @@ dag = graphmod.dagwalker(web.repo, range(startrev, downrev - 1, -1)) tree = list(graphmod.colored(dag, web.repo)) - canvasheight = (len(tree) + 1) * bg_height - 27 - data = [] - for (id, type, ctx, vtx, edges) in tree: - if type != graphmod.CHANGESET: - continue - node = str(ctx) - age = templatefilters.age(ctx.date()) - desc = templatefilters.firstline(ctx.description()) - desc = cgi.escape(templatefilters.nonempty(desc)) - user = cgi.escape(templatefilters.person(ctx.user())) - branch = ctx.branch() - try: - branchnode = web.repo.branchtip(branch) - except error.RepoLookupError: - branchnode = None - branch = branch, branchnode == ctx.node() - data.append((node, vtx, edges, desc, user, age, branch, ctx.tags(), - ctx.bookmarks())) + + def getcolumns(tree): + cols = 0 + for (id, type, ctx, vtx, edges) in tree: + if type != graphmod.CHANGESET: + continue + cols = max(cols, max([edge[0] for edge in edges] or [0]), + max([edge[1] for edge in edges] or [0])) + return cols + + def graphdata(usetuples, **map): + data = [] + + row = 0 + for (id, type, ctx, vtx, edges) in tree: + if type != graphmod.CHANGESET: + continue + node = str(ctx) + age = templatefilters.age(ctx.date()) + desc = templatefilters.firstline(ctx.description()) + desc = cgi.escape(templatefilters.nonempty(desc)) + user = cgi.escape(templatefilters.person(ctx.user())) + branch = ctx.branch() + try: + branchnode = web.repo.branchtip(branch) + except error.RepoLookupError: + branchnode = None + branch = branch, branchnode == ctx.node() + + if usetuples: + data.append((node, vtx, edges, desc, user, age, branch, + ctx.tags(), ctx.bookmarks())) + else: + edgedata = [dict(col=edge[0], nextcol=edge[1], + color=(edge[2] - 1) % 6 + 1, + width=edge[3], bcolor=edge[4]) + for edge in edges] + + data.append( + dict(node=node, + col=vtx[0], + color=(vtx[1] - 1) % 6 + 1, + edges=edgedata, + row=row, + nextrow=row + 1, + desc=desc, + user=user, + age=age, + bookmarks=webutil.nodebookmarksdict( + web.repo, ctx.node()), + branches=webutil.nodebranchdict(web.repo, ctx), + inbranch=webutil.nodeinbranch(web.repo, ctx), + tags=webutil.nodetagsdict(web.repo, ctx.node()))) + + row += 1 + + return data + + cols = getcolumns(tree) + rows = len(tree) + canvasheight = (rows + 1) * bg_height - 27 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev, lessvars=lessvars, morevars=morevars, downrev=downrev, - canvasheight=canvasheight, jsdata=data, bg_height=bg_height, + cols=cols, rows=rows, + canvaswidth=(cols + 1) * bg_height, + truecanvasheight=rows * bg_height, + canvasheight=canvasheight, bg_height=bg_height, + jsdata=lambda **x: graphdata(True, **x), + nodes=lambda **x: graphdata(False, **x), node=revnode_hex, changenav=changenav) def _getdoc(e):