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):