##// END OF EJS Templates
statistics: only load the Flot library when we need it
Mads Kiilerich -
r6753:b44cc07c default
parent child Browse files
Show More
@@ -1,140 +1,139 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <!DOCTYPE html>
2 <!DOCTYPE html>
3 <html xmlns="http://www.w3.org/1999/xhtml">
3 <html xmlns="http://www.w3.org/1999/xhtml">
4 <head>
4 <head>
5 <title><%block name="title"/><%block name="branding_title"/></title>
5 <title><%block name="title"/><%block name="branding_title"/></title>
6 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
6 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7 <meta name="robots" content="index, nofollow"/>
7 <meta name="robots" content="index, nofollow"/>
8 <link rel="icon" href="${h.url('/images/favicon.ico')}" type="image/x-icon" />
8 <link rel="icon" href="${h.url('/images/favicon.ico')}" type="image/x-icon" />
9
9
10 ## CSS ###
10 ## CSS ###
11 <link rel="stylesheet" type="text/css" href="${h.url('/css/jquery.dataTables.css', ver=c.kallithea_version)}"/>
11 <link rel="stylesheet" type="text/css" href="${h.url('/css/jquery.dataTables.css', ver=c.kallithea_version)}"/>
12 <link rel="stylesheet" type="text/css" href="${h.url('/js/select2/select2.css', ver=c.kallithea_version)}"/>
12 <link rel="stylesheet" type="text/css" href="${h.url('/js/select2/select2.css', ver=c.kallithea_version)}"/>
13 <link rel="stylesheet" type="text/css" href="${h.url('/css/bootstrap.css', ver=c.kallithea_version)}"/>
13 <link rel="stylesheet" type="text/css" href="${h.url('/css/bootstrap.css', ver=c.kallithea_version)}"/>
14 <link rel="stylesheet" type="text/css" href="${h.url('/js/select2/select2-bootstrap.css', ver=c.kallithea_version)}"/>
14 <link rel="stylesheet" type="text/css" href="${h.url('/js/select2/select2-bootstrap.css', ver=c.kallithea_version)}"/>
15 <link rel="stylesheet" type="text/css" href="${h.url('/css/pygments.css', ver=c.kallithea_version)}"/>
15 <link rel="stylesheet" type="text/css" href="${h.url('/css/pygments.css', ver=c.kallithea_version)}"/>
16 <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css', ver=c.kallithea_version)}" media="screen"/>
16 <link rel="stylesheet" type="text/css" href="${h.url('/css/style.css', ver=c.kallithea_version)}" media="screen"/>
17 <link rel="stylesheet" type="text/css" href="${h.url('/css/contextbar.css', ver=c.kallithea_version)}" media="screen"/>
17 <link rel="stylesheet" type="text/css" href="${h.url('/css/contextbar.css', ver=c.kallithea_version)}" media="screen"/>
18 <link rel="stylesheet" type="text/css" href="${h.url('/fontello/css/kallithea.css', ver=c.kallithea_version)}">
18 <link rel="stylesheet" type="text/css" href="${h.url('/fontello/css/kallithea.css', ver=c.kallithea_version)}">
19 <%block name="css_extra"/>
19 <%block name="css_extra"/>
20
20
21 ## JAVASCRIPT ##
21 ## JAVASCRIPT ##
22 <script type="text/javascript">
22 <script type="text/javascript">
23 ## JS translations map
23 ## JS translations map
24 var TRANSLATION_MAP = {
24 var TRANSLATION_MAP = {
25 'Cancel': ${h.jshtml(_("Cancel"))},
25 'Cancel': ${h.jshtml(_("Cancel"))},
26 'Retry': ${h.jshtml(_("Retry"))},
26 'Retry': ${h.jshtml(_("Retry"))},
27 'Submitting ...': ${h.jshtml(_("Submitting ..."))},
27 'Submitting ...': ${h.jshtml(_("Submitting ..."))},
28 'Unable to post': ${h.jshtml(_("Unable to post"))},
28 'Unable to post': ${h.jshtml(_("Unable to post"))},
29 'Add Another Comment': ${h.jshtml(_("Add Another Comment"))},
29 'Add Another Comment': ${h.jshtml(_("Add Another Comment"))},
30 'Stop following this repository': ${h.jshtml(_('Stop following this repository'))},
30 'Stop following this repository': ${h.jshtml(_('Stop following this repository'))},
31 'Start following this repository': ${h.jshtml(_('Start following this repository'))},
31 'Start following this repository': ${h.jshtml(_('Start following this repository'))},
32 'Group': ${h.jshtml(_('Group'))},
32 'Group': ${h.jshtml(_('Group'))},
33 'members': ${h.jshtml(_('members'))},
33 'members': ${h.jshtml(_('members'))},
34 'Loading ...': ${h.jshtml(_('Loading ...'))},
34 'Loading ...': ${h.jshtml(_('Loading ...'))},
35 'loading ...': ${h.jshtml(_('loading ...'))},
35 'loading ...': ${h.jshtml(_('loading ...'))},
36 'Search truncated': ${h.jshtml(_('Search truncated'))},
36 'Search truncated': ${h.jshtml(_('Search truncated'))},
37 'No matching files': ${h.jshtml(_('No matching files'))},
37 'No matching files': ${h.jshtml(_('No matching files'))},
38 'Open New Pull Request from {0}': ${h.jshtml(_('Open New Pull Request from {0}'))},
38 'Open New Pull Request from {0}': ${h.jshtml(_('Open New Pull Request from {0}'))},
39 'Open New Pull Request for {0} &rarr; {1}': ${h.js(_('Open New Pull Request for {0} &rarr; {1}'))},
39 'Open New Pull Request for {0} &rarr; {1}': ${h.js(_('Open New Pull Request for {0} &rarr; {1}'))},
40 'Show Selected Changesets {0} &rarr; {1}': ${h.js(_('Show Selected Changesets {0} &rarr; {1}'))},
40 'Show Selected Changesets {0} &rarr; {1}': ${h.js(_('Show Selected Changesets {0} &rarr; {1}'))},
41 'Selection Link': ${h.jshtml(_('Selection Link'))},
41 'Selection Link': ${h.jshtml(_('Selection Link'))},
42 'Collapse Diff': ${h.jshtml(_('Collapse Diff'))},
42 'Collapse Diff': ${h.jshtml(_('Collapse Diff'))},
43 'Expand Diff': ${h.jshtml(_('Expand Diff'))},
43 'Expand Diff': ${h.jshtml(_('Expand Diff'))},
44 'Type name of user or member to grant permission': ${h.jshtml(_('Type name of user or member to grant permission'))},
44 'Type name of user or member to grant permission': ${h.jshtml(_('Type name of user or member to grant permission'))},
45 'Failed to revoke permission': ${h.jshtml(_('Failed to revoke permission'))},
45 'Failed to revoke permission': ${h.jshtml(_('Failed to revoke permission'))},
46 'Confirm to revoke permission for {0}: {1} ?': ${h.jshtml(_('Confirm to revoke permission for {0}: {1} ?'))},
46 'Confirm to revoke permission for {0}: {1} ?': ${h.jshtml(_('Confirm to revoke permission for {0}: {1} ?'))},
47 'Enabled': ${h.jshtml(_('Enabled'))},
47 'Enabled': ${h.jshtml(_('Enabled'))},
48 'Disabled': ${h.jshtml(_('Disabled'))},
48 'Disabled': ${h.jshtml(_('Disabled'))},
49 'Select changeset': ${h.jshtml(_('Select changeset'))},
49 'Select changeset': ${h.jshtml(_('Select changeset'))},
50 'Specify changeset': ${h.jshtml(_('Specify changeset'))},
50 'Specify changeset': ${h.jshtml(_('Specify changeset'))},
51 'MSG_SORTASC': ${h.jshtml(_('Click to sort ascending'))},
51 'MSG_SORTASC': ${h.jshtml(_('Click to sort ascending'))},
52 'MSG_SORTDESC': ${h.jshtml(_('Click to sort descending'))},
52 'MSG_SORTDESC': ${h.jshtml(_('Click to sort descending'))},
53 'MSG_EMPTY': ${h.jshtml(_('No records found.'))},
53 'MSG_EMPTY': ${h.jshtml(_('No records found.'))},
54 'MSG_ERROR': ${h.jshtml(_('Data error.'))},
54 'MSG_ERROR': ${h.jshtml(_('Data error.'))},
55 'MSG_LOADING': ${h.jshtml(_('Loading...'))}
55 'MSG_LOADING': ${h.jshtml(_('Loading...'))}
56 };
56 };
57 var _TM = TRANSLATION_MAP;
57 var _TM = TRANSLATION_MAP;
58
58
59 var TOGGLE_FOLLOW_URL = ${h.js(h.url('toggle_following'))};
59 var TOGGLE_FOLLOW_URL = ${h.js(h.url('toggle_following'))};
60
60
61 var REPO_NAME = "";
61 var REPO_NAME = "";
62 %if hasattr(c, 'repo_name'):
62 %if hasattr(c, 'repo_name'):
63 var REPO_NAME = ${h.js(c.repo_name)};
63 var REPO_NAME = ${h.js(c.repo_name)};
64 %endif
64 %endif
65
65
66 var _authentication_token = ${h.js(h.authentication_token())};
66 var _authentication_token = ${h.js(h.authentication_token())};
67 </script>
67 </script>
68 <script type="text/javascript" src="${h.url('/js/yui.2.9.js', ver=c.kallithea_version)}"></script>
68 <script type="text/javascript" src="${h.url('/js/yui.2.9.js', ver=c.kallithea_version)}"></script>
69 <script type="text/javascript" src="${h.url('/js/jquery.min.js', ver=c.kallithea_version)}"></script>
69 <script type="text/javascript" src="${h.url('/js/jquery.min.js', ver=c.kallithea_version)}"></script>
70 <script type="text/javascript" src="${h.url('/js/jquery.dataTables.min.js', ver=c.kallithea_version)}"></script>
70 <script type="text/javascript" src="${h.url('/js/jquery.dataTables.min.js', ver=c.kallithea_version)}"></script>
71 <script type="text/javascript" src="${h.url('/js/bootstrap.js', ver=c.kallithea_version)}"></script>
71 <script type="text/javascript" src="${h.url('/js/bootstrap.js', ver=c.kallithea_version)}"></script>
72 <script type="text/javascript" src="${h.url('/js/select2/select2.js', ver=c.kallithea_version)}"></script>
72 <script type="text/javascript" src="${h.url('/js/select2/select2.js', ver=c.kallithea_version)}"></script>
73 <script type="text/javascript" src="${h.url('/js/yui.flot.js', ver=c.kallithea_version)}"></script>
74 <script type="text/javascript" src="${h.url('/js/native.history.js', ver=c.kallithea_version)}"></script>
73 <script type="text/javascript" src="${h.url('/js/native.history.js', ver=c.kallithea_version)}"></script>
75 <script type="text/javascript" src="${h.url('/js/base.js', ver=c.kallithea_version)}"></script>
74 <script type="text/javascript" src="${h.url('/js/base.js', ver=c.kallithea_version)}"></script>
76 ## EXTRA FOR JS
75 ## EXTRA FOR JS
77 <%block name="js_extra"/>
76 <%block name="js_extra"/>
78 <script type="text/javascript">
77 <script type="text/javascript">
79 (function(window,undefined){
78 (function(window,undefined){
80 var History = window.History; // Note: We are using a capital H instead of a lower h
79 var History = window.History; // Note: We are using a capital H instead of a lower h
81 if ( !History.enabled ) {
80 if ( !History.enabled ) {
82 // History.js is disabled for this browser.
81 // History.js is disabled for this browser.
83 // This is because we can optionally choose to support HTML4 browsers or not.
82 // This is because we can optionally choose to support HTML4 browsers or not.
84 return false;
83 return false;
85 }
84 }
86 })(window);
85 })(window);
87
86
88 $(document).ready(function(){
87 $(document).ready(function(){
89 tooltip_activate();
88 tooltip_activate();
90 show_more_event();
89 show_more_event();
91 // routes registration
90 // routes registration
92 pyroutes.register('home', ${h.js(h.url('home'))}, []);
91 pyroutes.register('home', ${h.js(h.url('home'))}, []);
93 pyroutes.register('new_gist', ${h.js(h.url('new_gist'))}, []);
92 pyroutes.register('new_gist', ${h.js(h.url('new_gist'))}, []);
94 pyroutes.register('gists', ${h.js(h.url('gists'))}, []);
93 pyroutes.register('gists', ${h.js(h.url('gists'))}, []);
95 pyroutes.register('new_repo', ${h.js(h.url('new_repo'))}, []);
94 pyroutes.register('new_repo', ${h.js(h.url('new_repo'))}, []);
96
95
97 pyroutes.register('summary_home', ${h.js(h.url('summary_home', repo_name='%(repo_name)s'))}, ['repo_name']);
96 pyroutes.register('summary_home', ${h.js(h.url('summary_home', repo_name='%(repo_name)s'))}, ['repo_name']);
98 pyroutes.register('changelog_home', ${h.js(h.url('changelog_home', repo_name='%(repo_name)s'))}, ['repo_name']);
97 pyroutes.register('changelog_home', ${h.js(h.url('changelog_home', repo_name='%(repo_name)s'))}, ['repo_name']);
99 pyroutes.register('files_home', ${h.js(h.url('files_home', repo_name='%(repo_name)s',revision='%(revision)s',f_path='%(f_path)s'))}, ['repo_name', 'revision', 'f_path']);
98 pyroutes.register('files_home', ${h.js(h.url('files_home', repo_name='%(repo_name)s',revision='%(revision)s',f_path='%(f_path)s'))}, ['repo_name', 'revision', 'f_path']);
100 pyroutes.register('edit_repo', ${h.js(h.url('edit_repo', repo_name='%(repo_name)s'))}, ['repo_name']);
99 pyroutes.register('edit_repo', ${h.js(h.url('edit_repo', repo_name='%(repo_name)s'))}, ['repo_name']);
101 pyroutes.register('edit_repo_perms', ${h.js(h.url('edit_repo_perms', repo_name='%(repo_name)s'))}, ['repo_name']);
100 pyroutes.register('edit_repo_perms', ${h.js(h.url('edit_repo_perms', repo_name='%(repo_name)s'))}, ['repo_name']);
102 pyroutes.register('pullrequest_home', ${h.js(h.url('pullrequest_home', repo_name='%(repo_name)s'))}, ['repo_name']);
101 pyroutes.register('pullrequest_home', ${h.js(h.url('pullrequest_home', repo_name='%(repo_name)s'))}, ['repo_name']);
103
102
104 pyroutes.register('toggle_following', ${h.js(h.url('toggle_following'))});
103 pyroutes.register('toggle_following', ${h.js(h.url('toggle_following'))});
105 pyroutes.register('changeset_info', ${h.js(h.url('changeset_info', repo_name='%(repo_name)s', revision='%(revision)s'))}, ['repo_name', 'revision']);
104 pyroutes.register('changeset_info', ${h.js(h.url('changeset_info', repo_name='%(repo_name)s', revision='%(revision)s'))}, ['repo_name', 'revision']);
106 pyroutes.register('repo_size', ${h.js(h.url('repo_size', repo_name='%(repo_name)s'))}, ['repo_name']);
105 pyroutes.register('repo_size', ${h.js(h.url('repo_size', repo_name='%(repo_name)s'))}, ['repo_name']);
107 pyroutes.register('repo_refs_data', ${h.js(h.url('repo_refs_data', repo_name='%(repo_name)s'))}, ['repo_name']);
106 pyroutes.register('repo_refs_data', ${h.js(h.url('repo_refs_data', repo_name='%(repo_name)s'))}, ['repo_name']);
108 });
107 });
109 </script>
108 </script>
110
109
111 <%block name="head_extra"/>
110 <%block name="head_extra"/>
112 </head>
111 </head>
113 <body>
112 <body>
114 <nav class="navbar navbar-inverse">
113 <nav class="navbar navbar-inverse">
115 <div class="navbar-header" id="logo">
114 <div class="navbar-header" id="logo">
116 <a class="navbar-brand" href="${h.url('home')}">
115 <a class="navbar-brand" href="${h.url('home')}">
117 <img class="pull-left" src="${h.url('/images/kallithea-logo.svg')}" alt="Kallithea"/>
116 <img class="pull-left" src="${h.url('/images/kallithea-logo.svg')}" alt="Kallithea"/>
118 %if c.site_name:
117 %if c.site_name:
119 <span class="branding">${c.site_name}</span>
118 <span class="branding">${c.site_name}</span>
120 %endif
119 %endif
121 </a>
120 </a>
122 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
121 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
123 <span class="sr-only">Toggle navigation</span>
122 <span class="sr-only">Toggle navigation</span>
124 <span class="icon-bar"></span>
123 <span class="icon-bar"></span>
125 <span class="icon-bar"></span>
124 <span class="icon-bar"></span>
126 <span class="icon-bar"></span>
125 <span class="icon-bar"></span>
127 </button>
126 </button>
128 </div>
127 </div>
129 <div id="navbar" class="navbar-collapse collapse">
128 <div id="navbar" class="navbar-collapse collapse">
130 <%block name="header_menu"/>
129 <%block name="header_menu"/>
131 </div>
130 </div>
132 </nav>
131 </nav>
133
132
134 ${next.body()}
133 ${next.body()}
135
134
136 %if c.ga_code:
135 %if c.ga_code:
137 ${h.literal(c.ga_code)}
136 ${h.literal(c.ga_code)}
138 %endif
137 %endif
139 </body>
138 </body>
140 </html>
139 </html>
@@ -1,447 +1,448 b''
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2
2
3 <%block name="title">
3 <%block name="title">
4 ${_('%s Statistics') % c.repo_name}
4 ${_('%s Statistics') % c.repo_name}
5 </%block>
5 </%block>
6
6
7 <%def name="breadcrumbs_links()">
7 <%def name="breadcrumbs_links()">
8 ${_('Statistics')}
8 ${_('Statistics')}
9 </%def>
9 </%def>
10
10
11 <%block name="header_menu">
11 <%block name="header_menu">
12 ${self.menu('repositories')}
12 ${self.menu('repositories')}
13 </%block>
13 </%block>
14
14
15 <%block name="head_extra">
15 <%block name="head_extra">
16 <link href="${h.url('atom_feed_home',repo_name=c.db_repo.repo_name,api_key=request.authuser.api_key)}" rel="alternate" title="${_('%s ATOM feed') % c.repo_name}" type="application/atom+xml" />
16 <link href="${h.url('atom_feed_home',repo_name=c.db_repo.repo_name,api_key=request.authuser.api_key)}" rel="alternate" title="${_('%s ATOM feed') % c.repo_name}" type="application/atom+xml" />
17 <link href="${h.url('rss_feed_home',repo_name=c.db_repo.repo_name,api_key=request.authuser.api_key)}" rel="alternate" title="${_('%s RSS feed') % c.repo_name}" type="application/rss+xml" />
17 <link href="${h.url('rss_feed_home',repo_name=c.db_repo.repo_name,api_key=request.authuser.api_key)}" rel="alternate" title="${_('%s RSS feed') % c.repo_name}" type="application/rss+xml" />
18 <script type="text/javascript" src="${h.url('/js/yui.flot.js', ver=c.kallithea_version)}"></script>
18 </%block>
19 </%block>
19
20
20 <%def name="main()">
21 <%def name="main()">
21 ${self.repo_context_bar('summary')}
22 ${self.repo_context_bar('summary')}
22 <div class="panel panel-primary">
23 <div class="panel panel-primary">
23 <div class="panel-heading clearfix">
24 <div class="panel-heading clearfix">
24 ${self.breadcrumbs()}
25 ${self.breadcrumbs()}
25 </div>
26 </div>
26
27
27 <div class="graph panel-body">
28 <div class="graph panel-body">
28 <div>
29 <div>
29 %if c.no_data:
30 %if c.no_data:
30 ${c.no_data_msg}
31 ${c.no_data_msg}
31 %if h.HasPermissionAny('hg.admin')('enable stats on from summary'):
32 %if h.HasPermissionAny('hg.admin')('enable stats on from summary'):
32 ${h.link_to(_('Enable'),h.url('edit_repo',repo_name=c.repo_name),class_="btn btn-default btn-xs")}
33 ${h.link_to(_('Enable'),h.url('edit_repo',repo_name=c.repo_name),class_="btn btn-default btn-xs")}
33 %endif
34 %endif
34 %else:
35 %else:
35 ${_('Stats gathered: ')} ${c.stats_percentage}%
36 ${_('Stats gathered: ')} ${c.stats_percentage}%
36 %endif
37 %endif
37 </div>
38 </div>
38 <div id="commit_history" class="pull-left"></div>
39 <div id="commit_history" class="pull-left"></div>
39
40
40 <div id="legend_data" class="pull-left">
41 <div id="legend_data" class="pull-left">
41 <div id="legend_container"></div>
42 <div id="legend_container"></div>
42 <div id="legend_choices">
43 <div id="legend_choices">
43 <table class="table" id="legend_choices_tables"></table>
44 <table class="table" id="legend_choices_tables"></table>
44 </div>
45 </div>
45 </div>
46 </div>
46
47
47 <div id="overview"></div>
48 <div id="overview"></div>
48 </div>
49 </div>
49 </div>
50 </div>
50
51
51 <script type="text/javascript">
52 <script type="text/javascript">
52 var data = ${h.js(c.trending_languages)};
53 var data = ${h.js(c.trending_languages)};
53 var total = 0;
54 var total = 0;
54 var no_data = true;
55 var no_data = true;
55 var tbl = document.createElement('table');
56 var tbl = document.createElement('table');
56 tbl.setAttribute('class','trending_language_tbl');
57 tbl.setAttribute('class','trending_language_tbl');
57 var cnt = 0;
58 var cnt = 0;
58 for (var i=0;i<data.length;i++){
59 for (var i=0;i<data.length;i++){
59 total+= data[i][1].count;
60 total+= data[i][1].count;
60 }
61 }
61 for (var i=0;i<data.length;i++){
62 for (var i=0;i<data.length;i++){
62 cnt += 1;
63 cnt += 1;
63 no_data = false;
64 no_data = false;
64
65
65 var hide = cnt>2;
66 var hide = cnt>2;
66 var tr = document.createElement('tr');
67 var tr = document.createElement('tr');
67 if (hide){
68 if (hide){
68 tr.setAttribute('style','display:none');
69 tr.setAttribute('style','display:none');
69 tr.setAttribute('class','stats_hidden');
70 tr.setAttribute('class','stats_hidden');
70 }
71 }
71 var k = data[i][0];
72 var k = data[i][0];
72 var obj = data[i][1];
73 var obj = data[i][1];
73 var percentage = Math.round((obj.count/total*100),2);
74 var percentage = Math.round((obj.count/total*100),2);
74
75
75 var td1 = document.createElement('td');
76 var td1 = document.createElement('td');
76 td1.width = 150;
77 td1.width = 150;
77 var trending_language_label = document.createElement('div');
78 var trending_language_label = document.createElement('div');
78 trending_language_label.innerHTML = obj.desc+" ("+k+")";
79 trending_language_label.innerHTML = obj.desc+" ("+k+")";
79 td1.appendChild(trending_language_label);
80 td1.appendChild(trending_language_label);
80
81
81 var td2 = document.createElement('td');
82 var td2 = document.createElement('td');
82 td2.setAttribute('style','padding-right:14px !important');
83 td2.setAttribute('style','padding-right:14px !important');
83 var trending_language = document.createElement('div');
84 var trending_language = document.createElement('div');
84 var nr_files = obj.count + ' ' + ${h.jshtml(_('files'))};
85 var nr_files = obj.count + ' ' + ${h.jshtml(_('files'))};
85
86
86 trending_language.title = k+" "+nr_files;
87 trending_language.title = k+" "+nr_files;
87
88
88 if (percentage>22){
89 if (percentage>22){
89 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"% "+nr_files+ "</b>";
90 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"% "+nr_files+ "</b>";
90 }
91 }
91 else{
92 else{
92 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"%</b>";
93 trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"%</b>";
93 }
94 }
94
95
95 trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
96 trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
96 trending_language.style.width=percentage+"%";
97 trending_language.style.width=percentage+"%";
97 td2.appendChild(trending_language);
98 td2.appendChild(trending_language);
98
99
99 tr.appendChild(td1);
100 tr.appendChild(td1);
100 tr.appendChild(td2);
101 tr.appendChild(td2);
101 tbl.appendChild(tr);
102 tbl.appendChild(tr);
102 if(cnt == 3){
103 if(cnt == 3){
103 var show_more = document.createElement('tr');
104 var show_more = document.createElement('tr');
104 var td = document.createElement('td');
105 var td = document.createElement('td');
105 lnk = document.createElement('a');
106 lnk = document.createElement('a');
106
107
107 lnk.href='#';
108 lnk.href='#';
108 lnk.innerHTML = ${h.jshtml(_('Show more'))};
109 lnk.innerHTML = ${h.jshtml(_('Show more'))};
109 lnk.id='code_stats_show_more';
110 lnk.id='code_stats_show_more';
110 td.appendChild(lnk);
111 td.appendChild(lnk);
111
112
112 show_more.appendChild(td);
113 show_more.appendChild(td);
113 show_more.appendChild(document.createElement('td'));
114 show_more.appendChild(document.createElement('td'));
114 tbl.appendChild(show_more);
115 tbl.appendChild(show_more);
115 }
116 }
116
117
117 }
118 }
118
119
119 </script>
120 </script>
120 <script type="text/javascript">
121 <script type="text/javascript">
121 var YUD = YAHOO.util.Dom;
122 var YUD = YAHOO.util.Dom;
122 var YUE = YAHOO.util.Event;
123 var YUE = YAHOO.util.Event;
123
124
124 /**
125 /**
125 * Plots summary graph
126 * Plots summary graph
126 *
127 *
127 * @class SummaryPlot
128 * @class SummaryPlot
128 * @param {from} initial from for detailed graph
129 * @param {from} initial from for detailed graph
129 * @param {to} initial to for detailed graph
130 * @param {to} initial to for detailed graph
130 * @param {dataset}
131 * @param {dataset}
131 * @param {overview_dataset}
132 * @param {overview_dataset}
132 */
133 */
133 function SummaryPlot(from,to,dataset,overview_dataset) {
134 function SummaryPlot(from,to,dataset,overview_dataset) {
134 var initial_ranges = {
135 var initial_ranges = {
135 "xaxis":{
136 "xaxis":{
136 "from":from,
137 "from":from,
137 "to":to
138 "to":to
138 }
139 }
139 };
140 };
140 var dataset = dataset;
141 var dataset = dataset;
141 var overview_dataset = [overview_dataset];
142 var overview_dataset = [overview_dataset];
142 var choiceContainer = YUD.get("legend_choices");
143 var choiceContainer = YUD.get("legend_choices");
143 var choiceContainerTable = YUD.get("legend_choices_tables");
144 var choiceContainerTable = YUD.get("legend_choices_tables");
144 var plotContainer = YUD.get('commit_history');
145 var plotContainer = YUD.get('commit_history');
145 var overviewContainer = YUD.get('overview');
146 var overviewContainer = YUD.get('overview');
146
147
147 var plot_options = {
148 var plot_options = {
148 bars: {show:true, align: 'center', lineWidth: 4},
149 bars: {show:true, align: 'center', lineWidth: 4},
149 legend: {show:true, container: "legend_container"},
150 legend: {show:true, container: "legend_container"},
150 points: {show:true, radius: 0, fill: false},
151 points: {show:true, radius: 0, fill: false},
151 yaxis: {tickDecimals: 0},
152 yaxis: {tickDecimals: 0},
152 xaxis: {
153 xaxis: {
153 mode: "time",
154 mode: "time",
154 timeformat: "%d/%m",
155 timeformat: "%d/%m",
155 min: from,
156 min: from,
156 max: to
157 max: to
157 },
158 },
158 grid: {
159 grid: {
159 hoverable: true,
160 hoverable: true,
160 clickable: true,
161 clickable: true,
161 autoHighlight: true,
162 autoHighlight: true,
162 color: "#999"
163 color: "#999"
163 },
164 },
164 //selection: {mode: "x"}
165 //selection: {mode: "x"}
165 };
166 };
166 var overview_options = {
167 var overview_options = {
167 legend:{show:false},
168 legend:{show:false},
168 bars: {show:true, barWidth: 2},
169 bars: {show:true, barWidth: 2},
169 shadowSize: 0,
170 shadowSize: 0,
170 xaxis: {mode: "time", timeformat: "%d/%m/%y"},
171 xaxis: {mode: "time", timeformat: "%d/%m/%y"},
171 yaxis: {ticks: 3, min: 0, tickDecimals:0},
172 yaxis: {ticks: 3, min: 0, tickDecimals:0},
172 grid: {color: "#999"},
173 grid: {color: "#999"},
173 selection: {mode: "x"}
174 selection: {mode: "x"}
174 };
175 };
175
176
176 /**
177 /**
177 *get dummy data needed in few places
178 *get dummy data needed in few places
178 */
179 */
179 function getDummyData(label){
180 function getDummyData(label){
180 return {"label":label,
181 return {"label":label,
181 "data":[{"time":0,
182 "data":[{"time":0,
182 "commits":0,
183 "commits":0,
183 "added":0,
184 "added":0,
184 "changed":0,
185 "changed":0,
185 "removed":0
186 "removed":0
186 }],
187 }],
187 "schema":["commits"],
188 "schema":["commits"],
188 "color":'#ffffff'
189 "color":'#ffffff'
189 }
190 }
190 }
191 }
191
192
192 /**
193 /**
193 * generate checkboxes accordingly to data
194 * generate checkboxes accordingly to data
194 * @param keys
195 * @param keys
195 * @returns
196 * @returns
196 */
197 */
197 function generateCheckboxes(data) {
198 function generateCheckboxes(data) {
198 //append checkboxes
199 //append checkboxes
199 var i = 0;
200 var i = 0;
200 choiceContainerTable.innerHTML = '';
201 choiceContainerTable.innerHTML = '';
201 for(var pos in data) {
202 for(var pos in data) {
202
203
203 data[pos].color = i;
204 data[pos].color = i;
204 i++;
205 i++;
205 if(data[pos].label != ''){
206 if(data[pos].label != ''){
206 choiceContainerTable.innerHTML +=
207 choiceContainerTable.innerHTML +=
207 '<tr><td><label><input type="checkbox" id="id_user_{0}" name="{0}" checked="checked" /> \
208 '<tr><td><label><input type="checkbox" id="id_user_{0}" name="{0}" checked="checked" /> \
208 {0}</label></td></tr>'.format(data[pos].label);
209 {0}</label></td></tr>'.format(data[pos].label);
209 }
210 }
210 }
211 }
211 }
212 }
212
213
213 /**
214 /**
214 * ToolTip show
215 * ToolTip show
215 */
216 */
216 function showTooltip(x, y, contents) {
217 function showTooltip(x, y, contents) {
217 var div=document.getElementById('tooltip');
218 var div=document.getElementById('tooltip');
218 if(!div) {
219 if(!div) {
219 div = document.createElement('div');
220 div = document.createElement('div');
220 div.id="tooltip";
221 div.id="tooltip";
221 div.style.position="absolute";
222 div.style.position="absolute";
222 div.style.border='1px solid #fdd';
223 div.style.border='1px solid #fdd';
223 div.style.padding='2px';
224 div.style.padding='2px';
224 div.style.backgroundColor='#fee';
225 div.style.backgroundColor='#fee';
225 document.body.appendChild(div);
226 document.body.appendChild(div);
226 }
227 }
227 YUD.setStyle(div, 'opacity', 0);
228 YUD.setStyle(div, 'opacity', 0);
228 div.innerHTML = contents;
229 div.innerHTML = contents;
229 div.style.top=(y + 5) + "px";
230 div.style.top=(y + 5) + "px";
230 div.style.left=(x + 5) + "px";
231 div.style.left=(x + 5) + "px";
231
232
232 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
233 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
233 anim.animate();
234 anim.animate();
234 }
235 }
235
236
236 /**
237 /**
237 * This function will detect if selected period has some changesets
238 * This function will detect if selected period has some changesets
238 for this user if it does this data is then pushed for displaying
239 for this user if it does this data is then pushed for displaying
239 Additionally it will only display users that are selected by the checkbox
240 Additionally it will only display users that are selected by the checkbox
240 */
241 */
241 function getDataAccordingToRanges(ranges) {
242 function getDataAccordingToRanges(ranges) {
242
243
243 var data = [];
244 var data = [];
244 var new_dataset = {};
245 var new_dataset = {};
245 var keys = [];
246 var keys = [];
246 var max_commits = 0;
247 var max_commits = 0;
247 for(var key in dataset){
248 for(var key in dataset){
248
249
249 for(var ds in dataset[key].data){
250 for(var ds in dataset[key].data){
250 commit_data = dataset[key].data[ds];
251 commit_data = dataset[key].data[ds];
251 if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
252 if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
252
253
253 if(new_dataset[key] === undefined){
254 if(new_dataset[key] === undefined){
254 new_dataset[key] = {data:[],schema:["commits"],label:key};
255 new_dataset[key] = {data:[],schema:["commits"],label:key};
255 }
256 }
256 new_dataset[key].data.push(commit_data);
257 new_dataset[key].data.push(commit_data);
257 }
258 }
258 }
259 }
259 if (new_dataset[key] !== undefined){
260 if (new_dataset[key] !== undefined){
260 data.push(new_dataset[key]);
261 data.push(new_dataset[key]);
261 }
262 }
262 }
263 }
263
264
264 if (data.length > 0){
265 if (data.length > 0){
265 return data;
266 return data;
266 }
267 }
267 else{
268 else{
268 //just return dummy data for graph to plot itself
269 //just return dummy data for graph to plot itself
269 return [getDummyData('')];
270 return [getDummyData('')];
270 }
271 }
271 }
272 }
272
273
273 /**
274 /**
274 * redraw using new checkbox data
275 * redraw using new checkbox data
275 */
276 */
276 function plotchoiced(e,args){
277 function plotchoiced(e,args){
277 var cur_data = args[0];
278 var cur_data = args[0];
278 var cur_ranges = args[1];
279 var cur_ranges = args[1];
279
280
280 var new_data = [];
281 var new_data = [];
281 var inputs = choiceContainer.getElementsByTagName("input");
282 var inputs = choiceContainer.getElementsByTagName("input");
282
283
283 //show only checked labels
284 //show only checked labels
284 for(var i=0; i<inputs.length; i++) {
285 for(var i=0; i<inputs.length; i++) {
285 var checkbox_key = inputs[i].name;
286 var checkbox_key = inputs[i].name;
286
287
287 if(inputs[i].checked){
288 if(inputs[i].checked){
288 for(var d in cur_data){
289 for(var d in cur_data){
289 if(cur_data[d].label == checkbox_key){
290 if(cur_data[d].label == checkbox_key){
290 new_data.push(cur_data[d]);
291 new_data.push(cur_data[d]);
291 }
292 }
292 }
293 }
293 }
294 }
294 else{
295 else{
295 //push dummy data to not hide the label
296 //push dummy data to not hide the label
296 new_data.push(getDummyData(checkbox_key));
297 new_data.push(getDummyData(checkbox_key));
297 }
298 }
298 }
299 }
299
300
300 var new_options = YAHOO.lang.merge(plot_options, {
301 var new_options = YAHOO.lang.merge(plot_options, {
301 xaxis: {
302 xaxis: {
302 min: cur_ranges.xaxis.from,
303 min: cur_ranges.xaxis.from,
303 max: cur_ranges.xaxis.to,
304 max: cur_ranges.xaxis.to,
304 mode: "time",
305 mode: "time",
305 timeformat: "%d/%m"
306 timeformat: "%d/%m"
306 }
307 }
307 });
308 });
308 if (!new_data){
309 if (!new_data){
309 new_data = [[0,1]];
310 new_data = [[0,1]];
310 }
311 }
311 // do the zooming
312 // do the zooming
312 plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
313 plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
313
314
314 plot.subscribe("plotselected", plotselected);
315 plot.subscribe("plotselected", plotselected);
315
316
316 //resubscribe plothover
317 //resubscribe plothover
317 plot.subscribe("plothover", plothover);
318 plot.subscribe("plothover", plothover);
318
319
319 // don't fire event on the overview to prevent eternal loop
320 // don't fire event on the overview to prevent eternal loop
320 overview.setSelection(cur_ranges, true);
321 overview.setSelection(cur_ranges, true);
321
322
322 }
323 }
323
324
324 /**
325 /**
325 * plot only selected items from overview
326 * plot only selected items from overview
326 * @param ranges
327 * @param ranges
327 * @returns
328 * @returns
328 */
329 */
329 function plotselected(ranges,cur_data) {
330 function plotselected(ranges,cur_data) {
330 //updates the data for new plot
331 //updates the data for new plot
331 var data = getDataAccordingToRanges(ranges);
332 var data = getDataAccordingToRanges(ranges);
332 generateCheckboxes(data);
333 generateCheckboxes(data);
333
334
334 var new_options = YAHOO.lang.merge(plot_options, {
335 var new_options = YAHOO.lang.merge(plot_options, {
335 xaxis: {
336 xaxis: {
336 min: ranges.xaxis.from,
337 min: ranges.xaxis.from,
337 max: ranges.xaxis.to,
338 max: ranges.xaxis.to,
338 mode:"time",
339 mode:"time",
339 timeformat: "%d/%m"
340 timeformat: "%d/%m"
340 }
341 }
341 });
342 });
342 // do the zooming
343 // do the zooming
343 plot = YAHOO.widget.Flot(plotContainer, data, new_options);
344 plot = YAHOO.widget.Flot(plotContainer, data, new_options);
344
345
345 plot.subscribe("plotselected", plotselected);
346 plot.subscribe("plotselected", plotselected);
346
347
347 //resubscribe plothover
348 //resubscribe plothover
348 plot.subscribe("plothover", plothover);
349 plot.subscribe("plothover", plothover);
349
350
350 // don't fire event on the overview to prevent eternal loop
351 // don't fire event on the overview to prevent eternal loop
351 overview.setSelection(ranges, true);
352 overview.setSelection(ranges, true);
352
353
353 //resubscribe choiced
354 //resubscribe choiced
354 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
355 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
355 }
356 }
356
357
357 var previousPoint = null;
358 var previousPoint = null;
358
359
359 function plothover(o) {
360 function plothover(o) {
360 var pos = o.pos;
361 var pos = o.pos;
361 var item = o.item;
362 var item = o.item;
362
363
363 //YUD.get("x").innerHTML = pos.x.toFixed(2);
364 //YUD.get("x").innerHTML = pos.x.toFixed(2);
364 //YUD.get("y").innerHTML = pos.y.toFixed(2);
365 //YUD.get("y").innerHTML = pos.y.toFixed(2);
365 if (item) {
366 if (item) {
366 if (previousPoint != item.datapoint) {
367 if (previousPoint != item.datapoint) {
367 previousPoint = item.datapoint;
368 previousPoint = item.datapoint;
368
369
369 var tooltip = YUD.get("tooltip");
370 var tooltip = YUD.get("tooltip");
370 if(tooltip) {
371 if(tooltip) {
371 tooltip.parentNode.removeChild(tooltip);
372 tooltip.parentNode.removeChild(tooltip);
372 }
373 }
373 var x = item.datapoint.x.toFixed(2);
374 var x = item.datapoint.x.toFixed(2);
374 var y = item.datapoint.y.toFixed(2);
375 var y = item.datapoint.y.toFixed(2);
375
376
376 if (!item.series.label){
377 if (!item.series.label){
377 item.series.label = 'commits';
378 item.series.label = 'commits';
378 }
379 }
379 var d = new Date(x*1000);
380 var d = new Date(x*1000);
380 var fd = d.toDateString();
381 var fd = d.toDateString();
381 var nr_commits = parseInt(y);
382 var nr_commits = parseInt(y);
382
383
383 var cur_data = dataset[item.series.label].data[item.dataIndex];
384 var cur_data = dataset[item.series.label].data[item.dataIndex];
384 var added = cur_data.added;
385 var added = cur_data.added;
385 var changed = cur_data.changed;
386 var changed = cur_data.changed;
386 var removed = cur_data.removed;
387 var removed = cur_data.removed;
387
388
388 var nr_commits_suffix = ' ' + ${h.jshtml(_('commits'))} + ' ';
389 var nr_commits_suffix = ' ' + ${h.jshtml(_('commits'))} + ' ';
389 var added_suffix = ' ' + ${h.jshtml(_('files added'))} + ' ';
390 var added_suffix = ' ' + ${h.jshtml(_('files added'))} + ' ';
390 var changed_suffix = ' ' + ${h.jshtml(_('files changed'))} + ' ';
391 var changed_suffix = ' ' + ${h.jshtml(_('files changed'))} + ' ';
391 var removed_suffix = ' ' + ${h.jshtml(_('files removed'))} + ' ';
392 var removed_suffix = ' ' + ${h.jshtml(_('files removed'))} + ' ';
392
393
393 if(nr_commits == 1){ nr_commits_suffix = ' ' + ${h.jshtml(_('commit'))} + ' '; }
394 if(nr_commits == 1){ nr_commits_suffix = ' ' + ${h.jshtml(_('commit'))} + ' '; }
394 if(added == 1) { added_suffix=' ' + ${h.jshtml(_('file added'))} + ' '; }
395 if(added == 1) { added_suffix=' ' + ${h.jshtml(_('file added'))} + ' '; }
395 if(changed == 1) { changed_suffix=' ' + ${h.jshtml(_('file changed'))} + ' '; }
396 if(changed == 1) { changed_suffix=' ' + ${h.jshtml(_('file changed'))} + ' '; }
396 if(removed == 1) { removed_suffix=' ' + ${h.jshtml(_('file removed'))} + ' '; }
397 if(removed == 1) { removed_suffix=' ' + ${h.jshtml(_('file removed'))} + ' '; }
397
398
398 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
399 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
399 +'<br/>'+
400 +'<br/>'+
400 nr_commits + nr_commits_suffix+'<br/>'+
401 nr_commits + nr_commits_suffix+'<br/>'+
401 added + added_suffix +'<br/>'+
402 added + added_suffix +'<br/>'+
402 changed + changed_suffix + '<br/>'+
403 changed + changed_suffix + '<br/>'+
403 removed + removed_suffix + '<br/>');
404 removed + removed_suffix + '<br/>');
404 }
405 }
405 }
406 }
406 else {
407 else {
407 var tooltip = YUD.get("tooltip");
408 var tooltip = YUD.get("tooltip");
408
409
409 if(tooltip) {
410 if(tooltip) {
410 tooltip.parentNode.removeChild(tooltip);
411 tooltip.parentNode.removeChild(tooltip);
411 }
412 }
412 previousPoint = null;
413 previousPoint = null;
413 }
414 }
414 }
415 }
415
416
416 /**
417 /**
417 * MAIN EXECUTION
418 * MAIN EXECUTION
418 */
419 */
419
420
420 var data = getDataAccordingToRanges(initial_ranges);
421 var data = getDataAccordingToRanges(initial_ranges);
421 generateCheckboxes(data);
422 generateCheckboxes(data);
422
423
423 //main plot
424 //main plot
424 var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
425 var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
425
426
426 //overview
427 //overview
427 var overview = YAHOO.widget.Flot(overviewContainer,
428 var overview = YAHOO.widget.Flot(overviewContainer,
428 overview_dataset, overview_options);
429 overview_dataset, overview_options);
429
430
430 //show initial selection on overview
431 //show initial selection on overview
431 overview.setSelection(initial_ranges);
432 overview.setSelection(initial_ranges);
432
433
433 plot.subscribe("plotselected", plotselected);
434 plot.subscribe("plotselected", plotselected);
434 plot.subscribe("plothover", plothover);
435 plot.subscribe("plothover", plothover);
435
436
436 overview.subscribe("plotselected", function (ranges) {
437 overview.subscribe("plotselected", function (ranges) {
437 plot.setSelection(ranges);
438 plot.setSelection(ranges);
438 });
439 });
439
440
440 // user choices on overview
441 // user choices on overview
441 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
442 YUE.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
442 }
443 }
443
444
444 SummaryPlot(${h.js(c.ts_min)}, ${h.js(c.ts_max)}, ${h.js(c.commit_data)}, ${h.js(c.overview_data)});
445 SummaryPlot(${h.js(c.ts_min)}, ${h.js(c.ts_max)}, ${h.js(c.commit_data)}, ${h.js(c.overview_data)});
445 </script>
446 </script>
446
447
447 </%def>
448 </%def>
General Comments 0
You need to be logged in to leave comments. Login now