##// END OF EJS Templates
graph: optimize rendering by appending all nodes at once
Augie Fackler -
r6728:84294e37 default
parent child Browse files
Show More
@@ -1,114 +1,110 b''
1 1 {header}
2 2 <title>{repo|escape}: revision graph</title>
3 3 <link rel="alternate" type="application/atom+xml"
4 4 href="{url}atom-log" title="Atom feed for {repo|escape}: log">
5 5 <link rel="alternate" type="application/rss+xml"
6 6 href="{url}rss-log" title="RSS feed for {repo|escape}: log">
7 7 <!--[if IE]><script type="text/javascript" src="{staticurl}excanvas.js"></script><![endif]-->
8 8 </head>
9 9 <body>
10 10
11 11 <div class="container">
12 12 <div class="menu">
13 13 <div class="logo">
14 14 <a href="http://www.selenic.com/mercurial/">
15 15 <img src="{staticurl}hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
16 16 </div>
17 17 <ul>
18 18 <li><a href="{url}shortlog{sessionvars%urlparameter}">log</a></li>
19 19 <li class="active">graph</li>
20 20 <li><a href="{url}tags{sessionvars%urlparameter}">tags</a></li>
21 21 </ul>
22 22 <ul>
23 23 <li><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a></li>
24 24 <li><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}">browse</a></li>
25 25 </ul>
26 26 </div>
27 27
28 28 <div class="main">
29 29 <h2>{repo|escape}</h2>
30 30 <h3>graph</h3>
31 31
32 32 <form class="search" action="{url}log">
33 33 {sessionvars%hiddenformentry}
34 34 <p><input name="rev" id="search1" type="text" size="30"></p>
35 35 </form>
36 36
37 37 <div class="navigate">
38 38 <a href="{url}graph/{uprev}{sessionvars%urlparameter}?revcount={revcountless}">less</a>
39 39 <a href="{url}graph/{uprev}{sessionvars%urlparameter}?revcount={revcountmore}">more</a>
40 40 | {changenav%navgraphentry}
41 41 </div>
42 42
43 43 <div id="noscript">The revision graph only works with JavaScript-enabled browsers.</div>
44 44
45 45 <div id="wrapper">
46 46 <ul id="nodebgs"></ul>
47 47 <canvas id="graph" width="224" height="{canvasheight}"></canvas>
48 48 <ul id="graphnodes"></ul>
49 49 </div>
50 50
51 51 <script type="text/javascript" src="{staticurl}graph.js"></script>
52 52 <script>
53 53
54 54 document.getElementById('noscript').style.visibility = 'hidden';
55 55
56 56 data = {jsdata|json};
57 57 graph = new Graph();
58 58 graph.scale({bg_height});
59 59
60 60 graph.edge = function(x0, y0, x1, y1, color) {
61 61
62 62 this.setColor(color, 0.0, 0.65);
63 63 this.ctx.beginPath();
64 64 this.ctx.moveTo(x0, y0);
65 65 this.ctx.lineTo(x1, y1);
66 66 this.ctx.stroke();
67 67
68 68 }
69 69
70 var nodes = document.getElementById('graphnodes');
71 var nodebgs = document.getElementById('nodebgs');
72
73 70 var revlink = '<li style="_STYLE"><span class="desc">';
74 71 revlink += '<a href="{url}rev/_NODEID{sessionvars%urlparameter}" title="_NODEID">_DESC</a>';
75 72 revlink += '</span><span class="tag">_TAGS</span>';
76 73 revlink += '<span class="info">_DATE ago, by _USER</span></li>';
77 74
78 75 graph.vertex = function(x, y, color, parity, cur) {
79 76
80 77 this.ctx.beginPath();
81 78 color = this.setColor(color, 0.25, 0.75);
82 79 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
83 80 this.ctx.fill();
84 81
85 82 var bg = '<li class="bg parity' + parity + '"></li>';
86 nodebgs.innerHTML += bg;
87
88 83 var left = (this.columns + 1) * this.bg_height;
89 84 var nstyle = 'padding-left: ' + left + 'px;';
90 85 var item = revlink.replace(/_STYLE/, nstyle);
91 86 item = item.replace(/_PARITY/, 'parity' + parity);
92 87 item = item.replace(/_NODEID/, cur[0]);
93 88 item = item.replace(/_NODEID/, cur[0]);
94 89 item = item.replace(/_DESC/, cur[3]);
95 90 item = item.replace(/_USER/, cur[4]);
96 91 item = item.replace(/_DATE/, cur[5]);
97 92 item = item.replace(/_TAGS/, cur[7].join('&nbsp; '));
98 nodes.innerHTML += item;
93
94 return [bg, item];
99 95
100 96 }
101 97
102 98 graph.render(data);
103 99 </script>
104 100
105 101 <div class="navigate">
106 102 <a href="{url}graph/{uprev}{sessionvars%urlparameter}?revcount={revcountless}">less</a>
107 103 <a href="{url}graph/{uprev}{sessionvars%urlparameter}?revcount={revcountmore}">more</a>
108 104 | {changenav%navgraphentry}
109 105 </div>
110 106
111 107 </div>
112 108 </div>
113 109
114 110 {footer}
@@ -1,123 +1,118 b''
1 1 #header#
2 2 <title>#repo|escape#: Graph</title>
3 3 <link rel="alternate" type="application/atom+xml"
4 4 href="{url}atom-log" title="Atom feed for #repo|escape#"/>
5 5 <link rel="alternate" type="application/rss+xml"
6 6 href="{url}rss-log" title="RSS feed for #repo|escape#"/>
7 7 </head>
8 8 <body>
9 9
10 10 <div class="page_header">
11 11 <a href="http://www.selenic.com/mercurial/" title="Mercurial" style="float: right;">Mercurial</a><a href="{url}summary{sessionvars%urlparameter}">#repo|escape#</a> / graph
12 12 </div>
13 13
14 14 <form action="{url}log">
15 15 {sessionvars%hiddenformentry}
16 16 <div class="search">
17 17 <input type="text" name="rev" />
18 18 </div>
19 19 </form>
20 20 <div class="page_nav">
21 21 <a href="{url}summary{sessionvars%urlparameter}">summary</a> |
22 22 <a href="{url}shortlog{sessionvars%urlparameter}">shortlog</a> |
23 23 <a href="{url}log/#rev#{sessionvars%urlparameter}">changelog</a> |
24 24 graph |
25 25 <a href="{url}tags{sessionvars%urlparameter}">tags</a> |
26 26 <a href="{url}file/#node|short#{sessionvars%urlparameter}">files</a>
27 27 <br/>
28 28 <a href="{url}graph/{uprev}{sessionvars%urlparameter}?revcount={revcountless}">less</a>
29 29 <a href="{url}graph/{uprev}{sessionvars%urlparameter}?revcount={revcountmore}">more</a>
30 30 | #changenav%navgraphentry#<br/>
31 31 </div>
32 32
33 33 <div class="title">&nbsp;</div>
34 34
35 35 <div id="noscript">The revision graph only works with JavaScript-enabled browsers.</div>
36 36
37 37 <div id="wrapper">
38 38 <ul id="nodebgs"></ul>
39 39 <canvas id="graph" width="224" height="#canvasheight#"></canvas>
40 40 <ul id="graphnodes"></ul>
41 41 </div>
42 42
43 43 <script type="text/javascript" src="#staticurl#graph.js"></script>
44 44 <script>
45 45
46 46 document.getElementById('noscript').style.visibility = 'hidden';
47 47
48 48 data = {jsdata|json};
49 49 graph = new Graph();
50 50 graph.scale({bg_height});
51 51
52 52 graph.edge = function(x0, y0, x1, y1, color) {
53 53
54 54 this.setColor(color, 0.0, 0.65);
55 55 this.ctx.beginPath();
56 56 this.ctx.moveTo(x0, y0);
57 57 this.ctx.lineTo(x1, y1);
58 58 this.ctx.stroke();
59 59
60 60 }
61 61
62 var nodes = document.getElementById('graphnodes');
63 var nodebgs = document.getElementById('nodebgs');
64
65 62 var revlink = '<li style="_STYLE"><span class="desc">';
66 63 revlink += '<a class="list" href="{url}rev/_NODEID{sessionvars%urlparameter}" title="_NODEID"><b>_DESC</b></a>';
67 64 revlink += '</span> _TAGS';
68 65 revlink += '<span class="info">_DATE ago, by _USER</span></li>';
69 66
70 67 graph.vertex = function(x, y, color, parity, cur) {
71 68
72 69 this.ctx.beginPath();
73 70 color = this.setColor(color, 0.25, 0.75);
74 71 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
75 72 this.ctx.fill();
76 73
77 74 var bg = '<li class="bg parity' + parity + '"></li>';
78 nodebgs.innerHTML += bg;
79
80 75 var left = (this.columns + 1) * this.bg_height;
81 76 var nstyle = 'padding-left: ' + left + 'px;';
82 77 var item = revlink.replace(/_STYLE/, nstyle);
83 78 item = item.replace(/_PARITY/, 'parity' + parity);
84 79 item = item.replace(/_NODEID/, cur[0]);
85 80 item = item.replace(/_NODEID/, cur[0]);
86 81 item = item.replace(/_DESC/, cur[3]);
87 82 item = item.replace(/_USER/, cur[4]);
88 83 item = item.replace(/_DATE/, cur[5]);
89 84
90 85 var tagspan = '';
91 86 if (cur[7].length || (cur[6][0] != 'default' || cur[6][1])) {
92 87 tagspan = '<span class="logtags">';
93 88 if (cur[6][1]) {
94 89 tagspan += '<span class="branchtag" title="' + cur[6][0] + '">';
95 90 tagspan += cur[6][0] + '</span> ';
96 91 } else if (!cur[6][1] && cur[6][0] != 'default') {
97 92 tagspan += '<span class="inbranchtag" title="' + cur[6][0] + '">';
98 93 tagspan += cur[6][0] + '</span> ';
99 94 }
100 95 if (cur[7].length) {
101 96 for (var t in cur[7]) {
102 97 var tag = cur[7][t];
103 98 tagspan += '<span class="tagtag">' + tag + '</span> ';
104 99 }
105 100 }
106 101 tagspan += '</span>';
107 102 }
108 103
109 104 item = item.replace(/_TAGS/, tagspan);
110 nodes.innerHTML += item;
105 return [bg, item];
111 106
112 107 }
113 108
114 109 graph.render(data);
115 110 </script>
116 111
117 112 <div class="page_nav">
118 113 <a href="{url}graph/{uprev}{sessionvars%urlparameter}?revcount={revcountless}">less</a>
119 114 <a href="{url}graph/{uprev}{sessionvars%urlparameter}?revcount={revcountmore}">more</a>
120 115 | {changenav%navgraphentry}
121 116 </div>
122 117
123 118 #footer#
@@ -1,97 +1,93 b''
1 1 #header#
2 2 <title>#repo|escape#: graph</title>
3 3 <link rel="alternate" type="application/atom+xml"
4 4 href="#url#atom-tags" title="Atom feed for #repo|escape#: tags">
5 5 <link rel="alternate" type="application/rss+xml"
6 6 href="#url#rss-tags" title="RSS feed for #repo|escape#: tags">
7 7 </head>
8 8 <body>
9 9
10 10 <div class="buttons">
11 11 <a href="#url#log{sessionvars%urlparameter}">changelog</a>
12 12 <a href="#url#shortlog{sessionvars%urlparameter}">shortlog</a>
13 13 <a href="#url#tags{sessionvars%urlparameter}">tags</a>
14 14 <a href="#url#file/#node|short#/{sessionvars%urlparameter}">files</a>
15 15 </div>
16 16
17 17 <h2>graph</h2>
18 18
19 19 <form action="#url#log">
20 20 {sessionvars%hiddenformentry}
21 21 <p>
22 22 <label for="search1">search:</label>
23 23 <input name="rev" id="search1" type="text" size="30">
24 24 navigate: <small class="navigate">#changenav%navgraphentry#</small>
25 25 </p>
26 26 </form>
27 27
28 28 <div id="noscript">The revision graph only works with JavaScript-enabled browsers.</div>
29 29
30 30 <div id="wrapper">
31 31 <ul id="nodebgs"></ul>
32 32 <canvas id="graph" width="224" height="#canvasheight#"></canvas>
33 33 <ul id="graphnodes"></ul>
34 34 </div>
35 35
36 36 <script type="text/javascript" src="#staticurl#graph.js"></script>
37 37 <script>
38 38
39 39 document.getElementById('noscript').style.visibility = 'hidden';
40 40
41 41 data = {jsdata|json};
42 42 graph = new Graph();
43 43 graph.scale({bg_height});
44 44
45 45 graph.edge = function(x0, y0, x1, y1, color) {
46 46
47 47 this.setColor(color, 0.0, 0.65);
48 48 this.ctx.beginPath();
49 49 this.ctx.moveTo(x0, y0);
50 50 this.ctx.lineTo(x1, y1);
51 51 this.ctx.stroke();
52 52
53 53 }
54 54
55 var nodes = document.getElementById('graphnodes');
56 var nodebgs = document.getElementById('nodebgs');
57
58 55 var revlink = '<li style="_STYLE"><span class="desc">';
59 56 revlink += '<a href="{url}rev/_NODEID{sessionvars%urlparameter}" title="_NODEID">_DESC</a>';
60 57 revlink += '</span><span class="info">_DATE ago, by _USER</span></li>';
61 58
62 59 graph.vertex = function(x, y, color, parity, cur) {
63 60
64 61 this.ctx.beginPath();
65 62 color = this.setColor(color, 0.25, 0.75);
66 63 this.ctx.arc(x, y, radius, 0, Math.PI * 2, true);
67 64 this.ctx.fill();
68 65
69 66 var bg = '<li class="bg parity' + parity + '"></li>';
70 nodebgs.innerHTML += bg;
71
72 67 var left = (this.columns + 1) * this.bg_height;
73 68 var nstyle = 'padding-left: ' + left + 'px;';
74 69 var item = revlink.replace(/_STYLE/, nstyle);
75 70 item = item.replace(/_PARITY/, 'parity' + parity);
76 71 item = item.replace(/_NODEID/, cur[0]);
77 72 item = item.replace(/_NODEID/, cur[0]);
78 73 item = item.replace(/_DESC/, cur[3]);
79 74 item = item.replace(/_USER/, cur[4]);
80 75 item = item.replace(/_DATE/, cur[5]);
81 nodes.innerHTML += item;
76
77 return [bg, item];
82 78
83 79 }
84 80
85 81 graph.render(data);
86 82 </script>
87 83
88 84 <form action="#url#log">
89 85 {sessionvars%hiddenformentry}
90 86 <p>
91 87 <label for="search1">search:</label>
92 88 <input name="rev" id="search1" type="text" size="30">
93 89 navigate: <small class="navigate">#changenav%navgraphentry#</small>
94 90 </p>
95 91 </form>
96 92
97 93 #footer#
@@ -1,129 +1,137 b''
1 1 // branch_renderer.js - Rendering of branch DAGs on the client side
2 2 //
3 3 // Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
4 4 // Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
5 5 //
6 6 // derived from code written by Scott James Remnant <scott@ubuntu.com>
7 7 // Copyright 2005 Canonical Ltd.
8 8 //
9 9 // This software may be used and distributed according to the terms
10 10 // of the GNU General Public License, incorporated herein by reference.
11 11
12 12 var colors = [
13 13 [ 1.0, 0.0, 0.0 ],
14 14 [ 1.0, 1.0, 0.0 ],
15 15 [ 0.0, 1.0, 0.0 ],
16 16 [ 0.0, 1.0, 1.0 ],
17 17 [ 0.0, 0.0, 1.0 ],
18 18 [ 1.0, 0.0, 1.0 ]
19 19 ];
20 20
21 21 function Graph() {
22 22
23 23 this.canvas = document.getElementById('graph');
24 24 if (navigator.userAgent.indexOf('MSIE') >= 0) this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
25 25 this.ctx = this.canvas.getContext('2d');
26 26 this.ctx.strokeStyle = 'rgb(0, 0, 0)';
27 27 this.ctx.fillStyle = 'rgb(0, 0, 0)';
28 28 this.cur = [0, 0];
29 29 this.line_width = 3;
30 30 this.bg = [0, 4];
31 31 this.cell = [2, 0];
32 32 this.columns = 0;
33 33 this.revlink = '';
34 34
35 35 this.scale = function(height) {
36 36 this.bg_height = height;
37 37 this.box_size = Math.floor(this.bg_height / 1.2);
38 38 this.cell_height = this.box_size;
39 39 }
40 40
41 41 function colorPart(num) {
42 42 num *= 255
43 43 num = num < 0 ? 0 : num;
44 44 num = num > 255 ? 255 : num;
45 45 var digits = Math.round(num).toString(16);
46 46 if (num < 16) {
47 47 return '0' + digits;
48 48 } else {
49 49 return digits;
50 50 }
51 51 }
52 52
53 53 this.setColor = function(color, bg, fg) {
54 54
55 55 // Set the colour.
56 56 //
57 57 // Picks a distinct colour based on an internal wheel; the bg
58 58 // parameter provides the value that should be assigned to the 'zero'
59 59 // colours and the fg parameter provides the multiplier that should be
60 60 // applied to the foreground colours.
61 61
62 62 color %= colors.length;
63 63 var red = (colors[color][0] * fg) || bg;
64 64 var green = (colors[color][1] * fg) || bg;
65 65 var blue = (colors[color][2] * fg) || bg;
66 66 red = Math.round(red * 255);
67 67 green = Math.round(green * 255);
68 68 blue = Math.round(blue * 255);
69 69 var s = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
70 70 this.ctx.strokeStyle = s;
71 71 this.ctx.fillStyle = s;
72 72 return s;
73 73
74 74 }
75 75
76 76 this.render = function(data) {
77 77
78 var backgrounds = '';
79 var nodedata = '';
80
78 81 for (var i in data) {
79 82
80 83 var parity = i % 2;
81 84 this.cell[1] += this.bg_height;
82 85 this.bg[1] += this.bg_height;
83 86
84 87 var cur = data[i];
85 88 var node = cur[1];
86 89 var edges = cur[2];
87 90 var fold = false;
88 91
89 92 for (var j in edges) {
90 93
91 94 line = edges[j];
92 95 start = line[0];
93 96 end = line[1];
94 97 color = line[2];
95 98
96 99 if (end > this.columns || start > this.columns) {
97 100 this.columns += 1;
98 101 }
99 102
100 103 if (start == this.columns && start > end) {
101 104 var fold = true;
102 105 }
103 106
104 107 x0 = this.cell[0] + this.box_size * start + this.box_size / 2;
105 108 y0 = this.bg[1] - this.bg_height / 2;
106 109 x1 = this.cell[0] + this.box_size * end + this.box_size / 2;
107 110 y1 = this.bg[1] + this.bg_height / 2;
108 111
109 112 this.edge(x0, y0, x1, y1, color);
110 113
111 114 }
112 115
113 116 // Draw the revision node in the right column
114 117
115 118 column = node[0]
116 119 color = node[1]
117 120
118 121 radius = this.box_size / 8;
119 122 x = this.cell[0] + this.box_size * column + this.box_size / 2;
120 123 y = this.bg[1] - this.bg_height / 2;
121 this.vertex(x, y, color, parity, cur);
124 var add = this.vertex(x, y, color, parity, cur);
125 backgrounds += add[0];
126 nodedata += add[1];
122 127
123 128 if (fold) this.columns -= 1;
124 129
125 130 }
126 131
132 document.getElementById('nodebgs').innerHTML += backgrounds;
133 document.getElementById('graphnodes').innerHTML += nodedata;
134
127 135 }
128 136
129 137 }
General Comments 0
You need to be logged in to leave comments. Login now