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