1- const DEV = 0 ; let bar_options = { axisX :{ onlyInteger :! 0 } , axisY :{ offset :100 , showGrid :! 1 } , horizontalBars :! 0 , reverseData :! 0 } , github_user = null ; document . location . hash ?github_user = document . location . hash . replace ( '#' , '' ) :document . location . href = '/' , document . title = `CoderStats(${ github_user } )` , document . getElementsByClassName ( 'brand' ) [ 0 ] . textContent = document . title ; let url_user = `https://api.github.com/users/${ github_user } ` , url_repos = `${ url_user } /repos?sort=pushed&per_page=100` , months_short = [ 'Jan' , 'Feb' , 'Mar' , 'Apr' , 'May' , 'Jun' , 'Jul' , 'Aug' , 'Sep' , 'Oct' , 'Nov' , 'Dec' ] ; let coder = new Vue ( { el :'#coder' , data :{ repos :[ ] , response :{ } , sort_orders :{ } , sort_key :'' , user :null } , computed :{ repos_pushed :function ( ) { return this . repos . filter ( ( a ) => a . pushed_at > a . created_at ) } , repos_pushed_ratio :function ( ) { return this . repos . length ?this . repos_pushed . length / this . repos . length :0 } , languages :function ( ) { return d3 . nest ( ) . key ( ( a ) => a . language ) . rollup ( ( a ) => a . length ) . entries ( this . repos_pushed . filter ( ( a ) => a . language ) ) . sort ( ( c , a ) => a . value - c . value ) } , issues :function ( ) { return this . repoRanking ( 'open_issues_count' ) } , forks :function ( ) { return this . repoRanking ( 'forks_count' ) } , stars :function ( ) { return this . repoRanking ( 'stargazers_count' ) } , total_forks :function ( ) { return d3 . sum ( this . forks , ( a ) => a . forks_count ) } , total_issues :function ( ) { return d3 . sum ( this . issues , ( a ) => a . open_issues_count ) } , total_stars :function ( ) { return d3 . sum ( this . stars , ( a ) => a . stargazers_count ) } } , filters :{ fixURL :( a ) => ( a . startsWith ( 'http' ) || ( a = `http://${ a } ` ) , a ) , formatDate :( a ) => { let b = new Date ( a ) ; return `${ b . getDate ( ) } ${ months_short [ b . getMonth ( ) ] } ${ b . getYear ( ) + 1900 } ` } , formatURL :( a ) => a . split ( '://' ) . pop ( ) . replace ( / \/ $ / , '' ) } , created :function ( ) { this . fetchRepos ( ) , this . fetchUser ( ) } , updated :function ( ) { let a = this . languages . slice ( 0 , 10 ) ; new Chartist . Bar ( '#language-ranking' , { labels :a . map ( ( a ) => a . key ) , series :[ a . map ( ( a ) => a . value ) ] } , bar_options ) , this . rankingGraph ( this . issues . slice ( 0 , 10 ) , 'open_issues_count' , '#issues-ranking' ) , this . rankingGraph ( this . forks . slice ( 0 , 10 ) , 'forks_count' , '#forks-ranking' ) , this . rankingGraph ( this . stars . slice ( 0 , 10 ) , 'stargazers_count' , '#stars-ranking' ) } , methods :{ fetchRepos :function ( ) { this . $http . get ( url_repos ) . then ( ( a ) => { this . response . repos = a , this . repos = a . body } ) } , fetchUser :function ( ) { this . $http . get ( url_user ) . then ( ( a ) => { this . response . user = a , this . user = a . body , this . user . name || ( this . user . name = this . user . login ) } ) } , order :function ( a ) { return 0 > this . sort_orders [ a ] ?'dsc' :'asc' } , rankingGraph :function ( a , b , c ) { a . length && new Chartist . Bar ( c , { labels :a . map ( ( a ) => a . name ) , series :[ a . map ( ( a ) => a [ b ] ) ] } , bar_options ) } , repoRanking :function ( c ) { return this . repos_pushed . filter ( ( a ) => a [ c ] ) . sort ( ( d , a ) => a [ c ] - d [ c ] ) } , sortBy :function ( c , d = 'number' ) { let e = 'string' === d ?'' :0 ; this . sort_key = c , this . sort_orders [ c ] = - 1 * ( this . sort_orders [ c ] || 1 ) , this . repos . sort ( ( f , a ) => { let b = f [ c ] || e , g = a [ c ] || e ; return 'string' === d && ( b = b . toLowerCase ( ) , g = g . toLowerCase ( ) ) , ( b === g ?0 :b > g ?1 :- 1 ) * this . sort_orders [ c ] } ) } } } ) ;
1+ const DEV = 0 ;
2+
3+ let bar_options = {
4+ axisX :{ onlyInteger :true } ,
5+ axisY :{ offset :100 , showGrid :false } ,
6+ horizontalBars :true ,
7+ reverseData :true
8+ } ;
9+
10+ let github_user = null ;
11+ if ( document . location . hash ) {
12+ github_user = document . location . hash . replace ( '#' , '' ) ;
13+ } else {
14+ document . location . href = '/' ;
15+ }
16+ // Set these values here because they are outside of vue's scope.
17+ let short_title = `CoderStats(${ github_user } )` ;
18+ document . title = document . title . replace ( 'CoderStats' , short_title ) ;
19+ document . getElementsByClassName ( 'brand' ) [ 0 ] . textContent = short_title ;
20+
21+ let url_user = `https://api.github.com/users/${ github_user } ` ,
22+ url_repos = `${ url_user } /repos?sort=pushed&per_page=100` ,
23+ months_short = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec' . split ( ' ' ) ;
24+
25+ if ( DEV ) {
26+ url_user = '/data/user.json' ;
27+ url_repos = '/data/repos.json' ;
28+ }
29+
30+ let coder = new Vue ( {
31+ el :'#coder' ,
32+ data :{
33+ repos :[ ] ,
34+ response :{ } ,
35+ sort_orders :{ } ,
36+ sort_key :'' ,
37+ user :null
38+ } ,
39+ computed :{
40+ // Only repos the user actually pushed at, i.e. no forks with no user commits.
41+ repos_pushed :function ( ) {
42+ return this . repos . filter ( d => d . pushed_at > d . created_at ) ;
43+ } ,
44+ repos_pushed_ratio :function ( ) {
45+ return this . repos . length ?this . repos_pushed . length / this . repos . length :0 ;
46+ } ,
47+ languages :function ( ) {
48+ return d3 . nest ( ) . key ( d => d . language ) . rollup ( leaves => leaves . length ) . entries ( this . repos_pushed . filter ( d => d . language ) ) . sort ( ( a , b ) => b . value - a . value ) ;
49+ } ,
50+ issues :function ( ) {
51+ return this . repoRanking ( 'open_issues_count' ) ;
52+ } ,
53+ forks :function ( ) {
54+ return this . repoRanking ( 'forks_count' ) ;
55+ } ,
56+ stars :function ( ) {
57+ return this . repoRanking ( 'stargazers_count' ) ;
58+ } ,
59+ total_forks :function ( ) {
60+ return d3 . sum ( this . forks , d => d . forks_count ) ;
61+ } ,
62+ total_issues :function ( ) {
63+ return d3 . sum ( this . issues , d => d . open_issues_count ) ;
64+ } ,
65+ total_stars :function ( ) {
66+ return d3 . sum ( this . stars , d => d . stargazers_count ) ;
67+ }
68+ } ,
69+ filters :{
70+ fixURL :value => {
71+ if ( ! value . startsWith ( 'http' ) ) {
72+ value = `http://${ value } ` ;
73+ }
74+ return value ;
75+ } ,
76+ formatDate :value => {
77+ let dt = new Date ( value ) ;
78+ return `${ dt . getDate ( ) } ${ months_short [ dt . getMonth ( ) ] } ${ dt . getYear ( ) + 1900 } ` ;
79+ } ,
80+ formatURL :value => {
81+ return value . split ( '://' ) . pop ( ) . replace ( / \/ $ / , '' ) ;
82+ }
83+ } ,
84+ created :function ( ) {
85+ this . fetchRepos ( ) ;
86+ this . fetchUser ( ) ;
87+ } ,
88+ updated :function ( ) {
89+ let language_ranking = this . languages . slice ( 0 , 10 ) ;
90+ new Chartist . Bar ( '#language-ranking' , {
91+ labels :language_ranking . map ( d => d . key ) ,
92+ series :[ language_ranking . map ( d => d . value ) ]
93+ } , bar_options ) ;
94+
95+ this . rankingGraph ( this . issues . slice ( 0 , 10 ) , 'open_issues_count' , '#issues-ranking' ) ;
96+ this . rankingGraph ( this . forks . slice ( 0 , 10 ) , 'forks_count' , '#forks-ranking' ) ;
97+ this . rankingGraph ( this . stars . slice ( 0 , 10 ) , 'stargazers_count' , '#stars-ranking' ) ;
98+ } ,
99+ methods :{
100+ fetchRepos :function ( ) {
101+ this . $http . get ( url_repos ) . then ( response => {
102+ this . response . repos = response ;
103+ this . repos = response . body ;
104+ } ) ;
105+ } ,
106+ fetchUser :function ( ) {
107+ this . $http . get ( url_user ) . then ( response => {
108+ this . response . user = response ;
109+ this . user = response . body ;
110+ if ( ! this . user . name ) this . user . name = this . user . login ;
111+ } ) ;
112+ } ,
113+ order :function ( key ) {
114+ // asc is default, because sort orders are initially unset
115+ return this . sort_orders [ key ] < 0 ?'dsc' :'asc' ;
116+ } ,
117+ rankingGraph :function ( series , property , selector ) {
118+ if ( series . length ) {
119+ new Chartist . Bar ( selector , {
120+ labels :series . map ( d => d . name ) ,
121+ series :[ series . map ( d => d [ property ] ) ]
122+ } , bar_options ) ;
123+ }
124+ } ,
125+ repoRanking :function ( property ) {
126+ return this . repos_pushed . filter ( d => d [ property ] ) . sort ( ( a , b ) => b [ property ] - a [ property ] ) ;
127+ } ,
128+ sortBy :function ( key , type = 'number' ) {
129+ let default_value = type === 'string' ?'' :0 ;
130+ this . sort_key = key ;
131+ this . sort_orders [ key ] = ( this . sort_orders [ key ] || 1 ) * - 1 ;
132+ this . repos . sort ( ( a , b ) => {
133+ let x = a [ key ] || default_value ,
134+ y = b [ key ] || default_value ;
135+ if ( type === 'string' ) {
136+ x = x . toLowerCase ( ) ;
137+ y = y . toLowerCase ( ) ;
138+ }
139+ return ( x === y ?0 :x > y ?1 :- 1 ) * this . sort_orders [ key ] ;
140+ } ) ;
141+ }
142+ }
143+ } ) ;