Mercurial > public > mercurial-scm > hg-stable
comparison 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 |
comparison
equal
deleted
inserted
replaced
16770:b3435385f99f | 16773:d490edc71146 |
---|---|
782 if rev < web.maxshortchanges: | 782 if rev < web.maxshortchanges: |
783 startrev = uprev | 783 startrev = uprev |
784 | 784 |
785 dag = graphmod.dagwalker(web.repo, range(startrev, downrev - 1, -1)) | 785 dag = graphmod.dagwalker(web.repo, range(startrev, downrev - 1, -1)) |
786 tree = list(graphmod.colored(dag, web.repo)) | 786 tree = list(graphmod.colored(dag, web.repo)) |
787 canvasheight = (len(tree) + 1) * bg_height - 27 | 787 |
788 data = [] | 788 def getcolumns(tree): |
789 for (id, type, ctx, vtx, edges) in tree: | 789 cols = 0 |
790 if type != graphmod.CHANGESET: | 790 for (id, type, ctx, vtx, edges) in tree: |
791 continue | 791 if type != graphmod.CHANGESET: |
792 node = str(ctx) | 792 continue |
793 age = templatefilters.age(ctx.date()) | 793 cols = max(cols, max([edge[0] for edge in edges] or [0]), |
794 desc = templatefilters.firstline(ctx.description()) | 794 max([edge[1] for edge in edges] or [0])) |
795 desc = cgi.escape(templatefilters.nonempty(desc)) | 795 return cols |
796 user = cgi.escape(templatefilters.person(ctx.user())) | 796 |
797 branch = ctx.branch() | 797 def graphdata(usetuples, **map): |
798 try: | 798 data = [] |
799 branchnode = web.repo.branchtip(branch) | 799 |
800 except error.RepoLookupError: | 800 row = 0 |
801 branchnode = None | 801 for (id, type, ctx, vtx, edges) in tree: |
802 branch = branch, branchnode == ctx.node() | 802 if type != graphmod.CHANGESET: |
803 data.append((node, vtx, edges, desc, user, age, branch, ctx.tags(), | 803 continue |
804 ctx.bookmarks())) | 804 node = str(ctx) |
805 age = templatefilters.age(ctx.date()) | |
806 desc = templatefilters.firstline(ctx.description()) | |
807 desc = cgi.escape(templatefilters.nonempty(desc)) | |
808 user = cgi.escape(templatefilters.person(ctx.user())) | |
809 branch = ctx.branch() | |
810 try: | |
811 branchnode = web.repo.branchtip(branch) | |
812 except error.RepoLookupError: | |
813 branchnode = None | |
814 branch = branch, branchnode == ctx.node() | |
815 | |
816 if usetuples: | |
817 data.append((node, vtx, edges, desc, user, age, branch, | |
818 ctx.tags(), ctx.bookmarks())) | |
819 else: | |
820 edgedata = [dict(col=edge[0], nextcol=edge[1], | |
821 color=(edge[2] - 1) % 6 + 1, | |
822 width=edge[3], bcolor=edge[4]) | |
823 for edge in edges] | |
824 | |
825 data.append( | |
826 dict(node=node, | |
827 col=vtx[0], | |
828 color=(vtx[1] - 1) % 6 + 1, | |
829 edges=edgedata, | |
830 row=row, | |
831 nextrow=row + 1, | |
832 desc=desc, | |
833 user=user, | |
834 age=age, | |
835 bookmarks=webutil.nodebookmarksdict( | |
836 web.repo, ctx.node()), | |
837 branches=webutil.nodebranchdict(web.repo, ctx), | |
838 inbranch=webutil.nodeinbranch(web.repo, ctx), | |
839 tags=webutil.nodetagsdict(web.repo, ctx.node()))) | |
840 | |
841 row += 1 | |
842 | |
843 return data | |
844 | |
845 cols = getcolumns(tree) | |
846 rows = len(tree) | |
847 canvasheight = (rows + 1) * bg_height - 27 | |
805 | 848 |
806 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev, | 849 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev, |
807 lessvars=lessvars, morevars=morevars, downrev=downrev, | 850 lessvars=lessvars, morevars=morevars, downrev=downrev, |
808 canvasheight=canvasheight, jsdata=data, bg_height=bg_height, | 851 cols=cols, rows=rows, |
852 canvaswidth=(cols + 1) * bg_height, | |
853 truecanvasheight=rows * bg_height, | |
854 canvasheight=canvasheight, bg_height=bg_height, | |
855 jsdata=lambda **x: graphdata(True, **x), | |
856 nodes=lambda **x: graphdata(False, **x), | |
809 node=revnode_hex, changenav=changenav) | 857 node=revnode_hex, changenav=changenav) |
810 | 858 |
811 def _getdoc(e): | 859 def _getdoc(e): |
812 doc = e[0].__doc__ | 860 doc = e[0].__doc__ |
813 if doc: | 861 if doc: |