]> de.git.xonotic.org Git - xonotic/xonstat.git/blob - xonstat/templates/player_info.mako
Merge branch 'zykure-approved'
[xonotic/xonstat.git] / xonstat / templates / player_info.mako
1 <%inherit file="base.mako"/>
2 <%namespace name="nav" file="nav.mako" />
3 <%namespace file="accuracy.mako" import="accuracy" />
4 <%namespace file="accuracy_graph.mako" import="accuracy_graph" />
5
6 <%block name="navigation">
7 ${nav.nav('players')}
8 </%block>
9
10 <%block name="css">
11 ${parent.css()}
12 <link href="/static/css/sprites.css" rel="stylesheet">
13 </%block>
14
15 <%block name="js">
16 ${parent.js()}
17 % if player is not None:
18 <script src="/static/js/jquery.flot.min.js"></script>
19 <script type="text/javascript">
20 $(function () {
21   $('#gbtab li').click(function(e) {
22     e.preventDefault();
23     $(this).tab('show');
24   })
25
26   $('#gbtab a:first').tab('show');
27 })
28 </script>
29
30 <script type="text/javascript">
31 $(function () {
32     // plot the accuracy graph
33     function plot_acc_graph(data) {
34     var games = new Array();
35     var avgs = new Array();
36     var accs = new Array();
37
38   var i=0;
39   for(i=0; i < data.games; i++) {
40     avgs[i] = [i, data.avg];
41     accs[i] = [i, data.accs[i][1]];
42     game_link = '/game/' + data.accs[i][0];
43     j = data.games - i;
44     games[i] = [i, '<a href="' + game_link + '">' + j + '</a>'];
45   }
46
47   $.plot(
48     $("#acc-graph"), 
49     [ { label: 'average', data: avgs, hoverable: true, clickable: false }, 
50       { label: 'accuracy', data: accs, lines: {show:true}, points: {show:false}, hoverable: true, clickable: true }, ],
51       { yaxis: {ticks: 10, min: 0, max: 100 },
52         xaxis: {ticks: games},
53         grid: { hoverable: true, clickable: true },
54       });
55 }
56
57 // plot the damage graph
58 function plot_dmg_graph(data) {
59   var games = new Array();
60   var avgs = new Array();
61   var dmgs = new Array();
62
63 var i=0;
64 for(i=0; i < data.games; i++) {
65   avgs[i] = [i, data.avg];
66   dmgs[i] = [i, data.dmgs[i][1]];
67   game_link = '/game/' + data.dmgs[i][0];
68   j = data.games - i;
69   games[i] = [i, '<a href="' + game_link + '">' + j + '</a>'];
70 }
71
72 $.plot(
73   $("#dmg-graph"), 
74   [ { label: 'average', data: avgs, hoverable: true, clickable: false }, 
75     { label: 'efficiency', data: dmgs, lines: {show:true}, points: {show:false}, hoverable: true, clickable: true }, ],
76     { yaxis: {ticks: 10, min: 0 },
77       xaxis: {ticks: games},
78       grid: { hoverable: true, clickable: true },
79     });
80           }
81
82           function showTooltip(x, y, contents) {
83             $('<div id="tooltip">' + contents + '</div>').css( {
84               position: 'absolute',
85               display: 'none',
86               top: y - 35,
87               left: x + 10,
88               border: '1px solid #fdd',
89               padding: '2px',
90               'background-color': '#333333',
91               opacity: 0.80
92             }).appendTo("body").fadeIn(200);
93           }
94
95           var previousPoint = null;
96           var previousLabel = null;
97           $('#acc-graph').bind("plothover", function (event, pos, item) {
98             if (item) {
99               if ((previousLabel != item.series.label) || (previousPoint != item.dataIndex)) {
100                 previousLabel = item.series.label;
101                 previousPoint = item.dataIndex;
102
103                 $("#tooltip").remove();
104                 var x = item.datapoint[0].toFixed(2),
105                 y = item.datapoint[1].toFixed(2);
106
107                 showTooltip(item.pageX, item.pageY, y + "%");
108               }
109             }
110             else {
111               $("#tooltip").remove();
112               previousPoint = null;
113               previousLabel = null;
114             }
115           });
116
117           $('#dmg-graph').bind("plothover", function (event, pos, item) {
118             if (item) {
119               if ((previousLabel != item.series.label) || (previousPoint != item.dataIndex)) {
120                 previousPoint = item.dataIndex;
121                 previousLabel = item.series.label;
122
123                 $("#tooltip").remove();
124                 var x = item.datapoint[0].toFixed(2),
125                 y = item.datapoint[1].toFixed(2);
126
127                 showTooltip(item.pageX, item.pageY, y);
128               }
129             }
130             else {
131               $("#tooltip").remove();
132               previousPoint = null;
133               previousLabel = null;
134             }
135           });
136
137 // bind click events to the weapon images
138 $(".acc-weap").click(function () {
139     var dataurl = $(this).find('a').attr('href');
140
141           $('.accuracy-nav').find('.weapon-active').removeClass('weapon-active');
142           $(this).addClass('weapon-active');
143
144           $.ajax({
145             url: dataurl,
146             method: 'GET',
147             dataType: 'json',
148             success: plot_acc_graph
149           });
150 });
151
152 $(".dmg-weap").click(function () {
153   var dataurl = $(this).find('a').attr('href');
154
155   $('.damage-nav').find('.weapon-active').removeClass('weapon-active');
156   $(this).addClass('weapon-active');
157
158   $.ajax({
159     url: dataurl,
160     method: 'GET',
161     dataType: 'json',
162     success: plot_dmg_graph
163   });
164 });
165
166 // populate the graphs with the default weapons
167 $.ajax({
168 url: '${request.route_url("player_accuracy", id=player.player_id)}',
169 method: 'GET',
170 dataType: 'json',
171 success: plot_acc_graph
172 });
173
174 $.ajax({
175   url: '${request.route_url("player_damage", id=player.player_id)}',
176   method: 'GET',
177   dataType: 'json',
178   success: plot_dmg_graph
179 });
180 })
181 </script>
182 % endif
183 </%block>
184
185 <%block name="title">
186 Player Information
187 </%block>
188
189
190 % if player is None:
191 <h2>This player is so good we couldn't find him!</h2>
192 <p>Seriously though, he probably doesn't exist...just a figment of your imagination. Carry on then!</p>
193
194 % else:
195 <div class="row">
196   <div class="span12">
197     <h2>
198       ${player.nick_html_colors()|n}
199     </h2>
200     <h4>
201       <i><span class="abstime" data-epoch="${player.epoch()}" title="${player.create_dt.strftime('%a, %d %b %Y %H:%M:%S UTC')}">Joined ${player.joined_pretty_date()}</span> (player #${player.player_id})</i>
202       % if cake_day:
203       <img src="/static/images/icons/24x24/cake.png" title="Happy cake day!" />
204       % endif
205     </h4>
206   </div>
207 </div>
208
209 <div class="row">
210   <div id="gbtabcontainer" class="tabbable tabs-below">
211     <div class="tab-content">
212       % for g in games_played:
213       % if not g.game_type_cd in ['cq']:
214       <div class="tab-pane fade in 
215         % if g.game_type_cd == 'overall':
216         active
217         % endif
218         " id="tab-${g.game_type_cd}">
219         <div class="span5">
220           <p>
221           % if g.game_type_cd in overall_stats:
222           Last Played: <small><span class="abstime" data-epoch="${overall_stats[g.game_type_cd].last_played_epoch}" title="${overall_stats[g.game_type_cd].last_played.strftime('%a, %d %b %Y %H:%M:%S UTC')}"> ${overall_stats[g.game_type_cd].last_played_fuzzy} </span> <br /></small>
223           % else:
224           <small><br /></small>
225           % endif
226
227           Games Played: 
228           % if g.game_type_cd == 'overall':
229           <small><a href="${request.route_url("player_game_index", player_id=player.player_id)}" title="View recent games">
230           % else:
231           <small><a href="${request.route_url("player_game_index", player_id=player.player_id, _query={'type':g.game_type_cd})}" title="View recent ${overall_stats[g.game_type_cd].game_type_descr} games">
232           % endif
233           ${g.games}</a> <br /></small>
234
235           Playing Time: <small>${overall_stats[g.game_type_cd].total_playing_time} <br /></small>
236
237           % if g.game_type_cd in fav_maps:
238           Favorite Map: <small><a href="${request.route_url("map_info", id=fav_maps[g.game_type_cd].map_id)}" title="Go to the detail page for this map">${fav_maps[g.game_type_cd].map_name}</a> <br /></small>
239           % else:
240           <small><br /></small>
241           % endif
242           
243           % if g.game_type_cd == 'ctf':
244           % if overall_stats[g.game_type_cd].total_captures is not None:
245           <small><a href="${request.route_url("player_captimes", id=player.player_id)}">Fastest flag captures...</a> <br /></small>
246           % else:
247           <small><br /></small>
248           % endif
249           % else:
250           <small><br /></small>
251           % endif
252           
253           </p>
254         </div>
255         <div class="span5">
256           <p>
257           Win Percentage: <small>${round(g.win_pct,2)}% (${g.wins} wins, ${g.losses} losses) <br /></small>
258
259           % if g.game_type_cd in overall_stats:
260           % if overall_stats[g.game_type_cd].k_d_ratio is not None:
261           Kill Ratio: <small>${round(overall_stats[g.game_type_cd].k_d_ratio,2)} (${overall_stats[g.game_type_cd].total_kills} kills, ${overall_stats[g.game_type_cd].total_deaths} deaths) <br /></small>
262           % endif
263           % else:
264           <small><br /></small>
265           % endif
266
267           % if g.game_type_cd in elos:
268           % if g.game_type_cd == 'overall':
269           Best Elo: <small>${round(elos[g.game_type_cd].elo,2)} (${elos[g.game_type_cd].game_type_cd}, ${elos[g.game_type_cd].games} games) <br /></small>
270           % else:
271           Elo: <small>${round(elos[g.game_type_cd].elo,2)} (${elos[g.game_type_cd].games} games) <br /></small>
272           % endif
273           % else:
274           <small><br /></small>
275           % endif
276
277           % if g.game_type_cd in ranks:
278           % if g.game_type_cd == 'overall':
279           Best Rank: <small>${ranks[g.game_type_cd].rank} of ${ranks[g.game_type_cd].max_rank} (${ranks[g.game_type_cd].game_type_cd}, percentile: ${round(ranks[g.game_type_cd].percentile,2)}) <br /></small>
280           % else:
281           Rank: 
282           <small>
283             <a href="
284               % if ranks[g.game_type_cd].rank % 20 == 0:
285                 ${request.route_url('rank_index', game_type_cd=g.game_type_cd, _query={'page':ranks[g.game_type_cd].rank/20})}
286
287               % else:
288                 ${request.route_url('rank_index', game_type_cd=g.game_type_cd, _query={'page':ranks[g.game_type_cd].rank/20+1})}
289
290               % endif
291             " title="Player rank page for this player">
292             ${ranks[g.game_type_cd].rank} of ${ranks[g.game_type_cd].max_rank}</a>
293             (percentile: ${round(ranks[g.game_type_cd].percentile,2)})
294             <br />
295           </small>
296           % endif
297           % else:
298           <small><br /></small>
299           % endif
300
301           % if g.game_type_cd == 'ctf':
302           % if overall_stats[g.game_type_cd].cap_ratio is not None:
303           Cap Ratio: <small>${round(overall_stats[g.game_type_cd].cap_ratio,2)} (${overall_stats[g.game_type_cd].total_captures} captures, ${overall_stats[g.game_type_cd].total_pickups} pickups) <br /></small>
304           % else:
305           <small><br /></small>
306           % endif
307           % else:
308           <small><br /></small>
309           % endif
310           </p>
311         </div>
312       </div>
313       % endif
314       % endfor
315     </div>
316   </div>
317 </div>
318 <div class="row">
319   <div class="span12">
320     <ul id="gbtab" class="nav nav-tabs">
321       % for g in games_played:
322       <li>
323       <a href="#tab-${g.game_type_cd}" data-toggle="tab" alt="${g.game_type_cd}" title="${overall_stats[g.game_type_cd].game_type_descr}">
324         <span class="sprite sprite-${g.game_type_cd}"> </span><br />
325         ${g.game_type_cd} <br />
326         <small>(${g.games})</small>
327       </a>
328       </li>
329       % endfor
330     </ul>
331   </div>
332 </div>
333
334
335 ### ACCURACY GRAPH
336 ${accuracy_graph(recent_weapons)}
337
338 % if 'rocketlauncher' in recent_weapons or 'grenadelauncher' in recent_weapons or 'electro' in recent_weapons or 'crylink' in recent_weapons or 'laser' in recent_weapons:
339 <div class="row">
340   <div class="span12">
341     <h3>Damage Efficiency</h3>
342     <div id="dmg-graph" class="flot" style="width:95%; height:200px;">
343     </div>
344
345     <div class="weapon-nav damage-nav">
346       <ul>
347         % if 'rocketlauncher' in recent_weapons:
348         <li>
349         <div class="dmg-weap weapon-active">
350           <span class="sprite sprite-rocketlauncher"></span>
351           <p><small>Rocket</small></p>
352           <a href="${request.route_url('player_damage', id=player.player_id, _query={'weapon':'rocketlauncher'})}" title="Show rocket launcher efficiency"></a>
353         </div>
354         </li>
355         % endif
356
357         % if 'grenadelauncher' in recent_weapons:
358         <li>
359         <div class="dmg-weap">
360           <span class="sprite sprite-grenadelauncher"></span>
361           <p><small>Mortar</small></p>
362           <a href="${request.route_url('player_damage', id=player.player_id, _query={'weapon':'grenadelauncher'})}" title="Show mortar damage efficiency"></a>
363         </div>
364         </li>
365         % endif
366
367         % if 'electro' in recent_weapons:
368         <li>
369         <div class="dmg-weap">
370           <span class="sprite sprite-electro"></span>
371           <p><small>Electro</small></p>
372           <a href="${request.route_url('player_damage', id=player.player_id, _query={'weapon':'electro'})}" title="Show electro damage efficiency"></a>
373         </div>
374         </li>
375         % endif
376
377         % if 'crylink' in recent_weapons:
378         <li>
379         <div class="dmg-weap">
380           <span class="sprite sprite-crylink"></span>
381           <p><small>Crylink</small></p>
382           <a href="${request.route_url('player_damage', id=player.player_id, _query={'weapon':'crylink'})}" title="Show crylink damage efficiency"></a>
383         </div>
384         </li>
385         % endif
386
387         % if 'hagar' in recent_weapons:
388         <li>
389         <div class="dmg-weap">
390           <span class="sprite sprite-hagar"></span>
391           <p><small>Hagar</small></p>
392           <a href="${request.route_url('player_damage', id=player.player_id, _query={'weapon':'hagar'})}" title="Show hagar damage efficiency"></a>
393         </div>
394         </li>
395         % endif
396
397         % if 'laser' in recent_weapons:
398         <li>
399         <div class="dmg-weap">
400           <span class="sprite sprite-laser"></span>
401           <p><small>Laser</small></p>
402           <a href="${request.route_url('player_damage', id=player.player_id, _query={'weapon':'laser'})}" title="Show laser damage efficiency"></a>
403         </div>
404         </li>
405         % endif
406
407       </ul>
408     </div>
409
410   </div>
411 </div>
412 % endif
413
414
415 ##### RECENT GAMES (v2) ####
416 % if recent_games:
417 <div class="row">
418   <div class="span12">
419     <h3>Recent Games</h3>
420     <table class="table table-hover table-condensed">
421       <thead>
422         <tr>
423           <th></th>
424           <th>Type</th>
425           <th>Server</th>
426           <th>Map</th>
427           <th>Result</th>
428           <th>Played</th>
429           <th>Elo</th>
430         </tr>
431       </thead>
432       <tbody>
433       % for rg in recent_games:
434       <tr>
435         <td class="tdcenter"><a class="btn btn-primary btn-small" href="${request.route_url('game_info', id=rg.game_id)}" title="View detailed information about this game">view</a></td>
436         <td class="tdcenter"><span class="sprite sprite-${rg.game_type_cd}" alt="${rg.game_type_cd}" title="${rg.game_type_descr}"></span></td>
437         <td><a href="${request.route_url('server_info', id=rg.server_id)}" title="Go to the detail page for this server">${rg.server_name}</a></td>
438         <td><a href="${request.route_url('map_info', id=rg.map_id)}" title="Go to the detail page for this map">${rg.map_name}</a></td>
439         <td>
440           % if rg.team != None:
441           % if rg.team == rg.winner:
442           Win
443           % else:
444           Loss
445           % endif
446           % else:
447           % if rg.rank == 1:
448           Win
449           % else:
450           Loss (#${rg.rank})
451           % endif
452           % endif
453         </td>
454         <td><span class="abstime" data-epoch="${rg.epoch}" title="${rg.start_dt.strftime('%a, %d %b %Y %H:%M:%S UTC')}">${rg.fuzzy_date}</span></td>
455         <td class="tdcenter">
456           <a href="${request.route_url('game_info', id=rg.game_id, _query={'show_elo':1})}" title="View detailed information about this game">
457             % if rg.elo_delta is not None:
458             % if round(rg.elo_delta,2) > 0:
459             <span class="eloup" title="Elo went up by ${round(rg.elo_delta,2)}"><i class="glyphicon glyphicon-arrow-up"></i></span>
460             % elif round(rg.elo_delta,2) < 0:
461             <span class="elodown" title="Elo went down by ${round(-rg.elo_delta,2)}"><i class="glyphicon glyphicon-arrow-down"></i></span>
462             % else:
463             <span class="eloneutral" title="Elo did not change"><i class="glyphicon glyphicon-minus"></i></span>
464             % endif
465             % else:
466             <span class="eloneutral" title="Elo did not change"><i class="glyphicon glyphicon-minus"></i></span>
467             % endif
468           </a>
469         </td>
470       </tr>
471       % endfor
472       </tbody>
473     </table>
474     % if total_games > 10:
475     <p><a href="${request.route_url("player_game_index", player_id=player.player_id, page=1)}" title="Game index for ${player.stripped_nick}">More...</a></p>
476     % endif
477   </div>
478 </div>
479 % endif
480 % endif