Browse Source

Merge branch 'master' of github.com:jrtechs/github-graphs

pull/11/head
Bryce Murphy 5 years ago
parent
commit
7daa027579
15 changed files with 383 additions and 48 deletions
  1. +2
    -1
      package.json
  2. +45
    -0
      public/404.html
  3. +87
    -0
      public/FriendsGraph.html
  4. +15
    -6
      public/about.css
  5. +43
    -3
      public/about.html
  6. BIN
      public/favicon.ico
  7. BIN
      public/img/DolphinCroissant.png
  8. BIN
      public/img/graphExample.png
  9. +20
    -4
      public/index.html
  10. +111
    -11
      public/js/friendsGraph.js
  11. +0
    -1
      public/js/githubAPI.js
  12. +4
    -3
      public/logo.svg
  13. +44
    -3
      public/style.css
  14. +12
    -13
      routes/api.js
  15. +0
    -3
      server.js

+ 2
- 1
package.json View File

@ -21,6 +21,7 @@
"express": "^4.16.4", "express": "^4.16.4",
"express-session": "^1.15.6", "express-session": "^1.15.6",
"fs": "0.0.1-security", "fs": "0.0.1-security",
"got": "^9.6.0"
"got": "^9.6.0",
"memory-cache": "^0.2.0"
} }
} }

+ 45
- 0
public/404.html View File

@ -0,0 +1,45 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div id="header-bar" class="d-flex flex-column flex-md-row shadow-sm align-items-center">
<div id="header-title">
<a href="./index.html">
<img id="logo" class="text-center" src="./logo.svg" />
</a>
</div>
<ul id="navigation" class="nav justify-content-end">
<li class="nav-item">
<a href="./GraphTest.html">
Generate graphs
</a>
</li>
<div class="nav-sep"></div>
<li class="nav-item">
<a href="https://github.com/jrtechs/github-graphs">
View on GitHub
</a>
</li>
<div class="nav-sep"></div>
<li class="nav-item">
<a href="./about.html">
About
</a>
</li>
</ul>
</div>
<div class="main">
<div id="content" class="error container text-center">
<h1 id="error-code">404</h1>
<img id="dcimg" src="./img/DolphinCroissant.png" />
<p style="padding-top: 25px;">Yeah, that page doesn't exist.</p>
<p>Maybe if you weren't so adventurous you'd avoid screens like this :)</p>
</div>
</div>
</body>
</html>

+ 87
- 0
public/FriendsGraph.html View File

@ -0,0 +1,87 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="./favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="./style.css" />
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous">
</script>
<script src="js/githubAPI.js"></script>
<script src="js/friendsGraph.js"></script>
<script src="js/profileGen.js"></script>
<script type="text/javascript" src="js/vis/vis.js"></script>
<link href="js/vis/vis-network.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="header-bar" class="d-flex flex-column flex-md-row shadow-sm align-items-center">
<div id="header-title">
<a href="./index.html">
<img id="logo" class="text-center" src="./logo.svg" />
</a>
</div>
<ul id="navigation" class="nav justify-content-end">
<li class="nav-item">
<a href="./GraphTest.html">
Generate graphs
</a>
</li>
<div class="nav-sep"></div>
<li class="nav-item">
<a href="https://github.com/jrtechs/github-graphs">
View on GitHub
</a>
</li>
<div class="nav-sep"></div>
<li class="nav-item">
<a href="./about.html">
About
</a>
</li>
</ul>
</div>
<div class="main container">
<div class="row" id="searchBarTop">
<nav class="navbar navbar-light bg-light justify-content-between">
<a class="navbar-brand">Create Graph</a>
<form class="form-inline">
<input class="form-control mr-sm-2" id='txtUsername' type="search" placeholder="GitHub Username" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" onclick='createGraphs()' type='button'>Look Up</button>
</form>
</nav>
</div>
<div class="row">
<div class="col-md-10 col-12">
<h2 id="graphLabel"></h2>
<div id="myGraph" class="w-100"></div>
<pre id="eventSpan"></pre>
</div>
<div class="col-md-2 col-12 w-100">
<div id="profileGen"></div>
</div>
</div>
</body>
<script>
function createGraphs()
{
options.width = $("#myGraph").width() + "px";
options.height = "700px";
const inputedName = $("#txtUsername").val();
createFriendsGraph(inputedName, "myGraph", "graphLabel");
profileGen(inputedName, "profileGen");
$("#searchBarTop").html("");
}
</script>
</html>

+ 15
- 6
public/about.css View File

@ -9,17 +9,26 @@
top: 20%; top: 20%;
height: 80px; height: 80px;
background-color: rgb(208, 208, 208); background-color: rgb(208, 208, 208);
border-radius: 20px 20px 0px 0px;
border-radius: 20px 20px 0px 0px
} }
#content-body { #content-body {
position: relative; position: relative;
background-color: rgb(242, 242, 242); background-color: rgb(242, 242, 242);
border-radius: 0px 0px 20px 20px; border-radius: 0px 0px 20px 20px;
} }
.plink {
.card-deck {
position: relative;
padding-top: 20px;
}
.rounder {
border-radius: 20px !important;
} }
body {
background-color: #232323;
.avatar {
border-radius: 10px 10px 10px 10px !important;
top: 10px;
position: relative;
width: 70%;
}
.plink {
color: rgb(250, 152, 33);
} }

+ 43
- 3
public/about.html View File

@ -3,6 +3,8 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="./favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="./style.css" /> <link rel="stylesheet" href="./style.css" />
<link rel="stylesheet" href="./about.css" /> <link rel="stylesheet" href="./about.css" />
@ -11,12 +13,12 @@
<div id="header-bar" class="d-flex flex-column flex-md-row shadow-sm align-items-center"> <div id="header-bar" class="d-flex flex-column flex-md-row shadow-sm align-items-center">
<div id="header-title"> <div id="header-title">
<a href="./index.html"> <a href="./index.html">
<img id="logo" src="./logo.svg" />
<img id="logo" class="text-center" src="./logo.svg" />
</a> </a>
</div> </div>
<ul id="navigation" class="nav justify-content-end"> <ul id="navigation" class="nav justify-content-end">
<li class="nav-item"> <li class="nav-item">
<a href="./generate">
<a href="./GraphTest.html">
Generate graphs Generate graphs
</a> </a>
</li> </li>
@ -34,7 +36,7 @@
</li> </li>
</ul> </ul>
</div> </div>
<div id="main">
<div>
<div id="content" class="container"> <div id="content" class="container">
<div id="content-title"> <div id="content-title">
<h1 class="big-title text-center">What is this?</h1> <h1 class="big-title text-center">What is this?</h1>
@ -52,6 +54,44 @@
This project was made for participation in <a class="plink" href="https://brickhack.io/">BrickHack V</a>. This project was made for participation in <a class="plink" href="https://brickhack.io/">BrickHack V</a>.
</p> </p>
</div> </div>
<div id="content-title" style="border-radius: 20px;">
<h1 class="big-title text-center">Developers</h1>
</div>
<div class="card-deck">
<div class="card rounder">
<img class="avatar mx-auto d-block" src="https://avatars0.githubusercontent.com/u/13894625?s=400&v=4" />
<div class="card-header text-center m-title">
Jeff
</div>
<div class="card-body">
<p>
did stuff
</p>
</div>
</div>
<div class="card rounder">
<img class="avatar mx-auto d-block" src="https://avatars0.githubusercontent.com/u/32306409?s=400&v=4" />
<div class="card-header text-center m-title">
Bryce
</div>
<div class="card-body">
<p>
also did stuff
</p>
</div>
</div>
<div class="card rounder">
<img class="avatar mx-auto d-block" src="https://avatars3.githubusercontent.com/u/32624140?s=400&v=4" />
<div class="card-header text-center m-title">
Alex
</div>
<div class="card-body">
<p>
kinda did stuff
</p>
</div>
</div>
</div>
</div> </div>
</div> </div>
</body> </body>

BIN
public/favicon.ico View File

Before After

BIN
public/img/DolphinCroissant.png View File

Before After
Width: 512  |  Height: 512  |  Size: 13 KiB

BIN
public/img/graphExample.png View File

Before After
Width: 1292  |  Height: 1418  |  Size: 765 KiB

+ 20
- 4
public/index.html View File

@ -1,8 +1,10 @@
<!doctype html>
<!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="./favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="./style.css" /> <link rel="stylesheet" href="./style.css" />
</head> </head>
@ -10,12 +12,12 @@
<div id="header-bar" class="d-flex flex-column flex-md-row shadow-sm align-items-center"> <div id="header-bar" class="d-flex flex-column flex-md-row shadow-sm align-items-center">
<div id="header-title"> <div id="header-title">
<a href="./index.html"> <a href="./index.html">
<img id="logo" src="./logo.svg" />
<img id="logo" class="text-center" src="./logo.svg" />
</a> </a>
</div> </div>
<ul id="navigation" class="nav justify-content-end"> <ul id="navigation" class="nav justify-content-end">
<li class="nav-item"> <li class="nav-item">
<a href="./generate">
<a href="./FriendsGraph.html">
Generate graphs Generate graphs
</a> </a>
</li> </li>
@ -33,6 +35,20 @@
</li> </li>
</ul> </ul>
</div> </div>
<div class="main container">
<div class="row">
<div class="side-txt">
<div class="text-title text-center" style="padding-top: 15px;">
<h1 class="m-title">How to get started:</h1>
</div>
<div class="text-content">
<p style="position: relative; padding-left: 10px; padding-right: 10px;">
Head over to the 'Generate graphs' page and enter the username of the user you want to generate your graph around.
</p>
</div>
</div>
<img class="side-img img-fluid" src="./img/graphExample.png" />
</div>
</div>
</body> </body>
</html> </html>

+ 111
- 11
public/js/friendsGraph.js View File

@ -4,7 +4,7 @@ var nodes;
var edges; var edges;
const options = {
var options = {
nodes: { nodes: {
borderWidth:4, borderWidth:4,
size:30, size:30,
@ -19,6 +19,13 @@ const options = {
} }
}; };
/**
* Checks if a user is a node in the graph
*
* @param userID
* @returns {boolean}
*/
function alreadyInGraph(userID) function alreadyInGraph(userID)
{ {
for(var i = 0; i < nodes.length; i++) for(var i = 0; i < nodes.length; i++)
@ -32,6 +39,11 @@ function alreadyInGraph(userID)
} }
/**
* adds a person to the nodes list
*
* @param profileData
*/
function addPersonToGraph(profileData) function addPersonToGraph(profileData)
{ {
nodes.push( nodes.push(
@ -43,6 +55,15 @@ function addPersonToGraph(profileData)
}); });
} }
/**
* Adds the followers/following of a person
* to the graph
*
* @param username
* @param apiPath
* @returns {Promise<any>}
*/
function addFriends(username, apiPath) function addFriends(username, apiPath)
{ {
return new Promise(function(resolve, reject) return new Promise(function(resolve, reject)
@ -66,34 +87,75 @@ function addFriends(username, apiPath)
} }
/**
* Greedy function which checks to see if a edge is in the graphs
*
* @param id1
* @param id2
* @returns {boolean}
*/
function edgeInGraph(id1, id2)
{
for(var i = 0;i < edges.length; i++)
{
if(edges[i].from === id1 && edges[i].to === id2)
{
return true;
}
if(edges[i].to === id1 && edges[i].from === id2)
{
return true;
}
}
return false;
}
/**
* Adds a connection to the graph
*
* @param person1
* @param person2
*/
function addConnection(person1, person2) function addConnection(person1, person2)
{ {
edges.push(
if(person1.id !== person2.id)
{
if(alreadyInGraph(person2.id) && !edgeInGraph(person1.id, person2.id))
{ {
from: person1.id,
to: person2.id
});
edges.push(
{
from: person1.id,
to: person2.id
});
}
}
} }
function processUserConnections(userName)
/**
* Processes all the connections of a user and adds them to the graph
*
* @param user has .id and .name
* @returns {Promise<any>}
*/
function processUserConnections(user)
{ {
return new Promise(function(resolve, reject) return new Promise(function(resolve, reject)
{ {
queryAPIByUser(API_FOLLOWING, userName,
queryAPIByUser(API_FOLLOWING, user.name,
function(data) function(data)
{ {
for(var i = 0; i < data.length; i++) for(var i = 0; i < data.length; i++)
{ {
addConnection(user, data[i])
} }
queryAPIByUser(API_FOLLOWERS, userName, function(data2)
queryAPIByUser(API_FOLLOWERS, user.name, function(data2)
{ {
for(var i = 0; i < data2.length; i++) for(var i = 0; i < data2.length; i++)
{ {
addConnection(user, data2[i]);
} }
resolve(); resolve();
}, },
@ -109,6 +171,13 @@ function processUserConnections(userName)
}); });
} }
/**
* Creates connections between all the nodes in
* the graph.
*
* @returns {Promise<any>}
*/
function createConnections() function createConnections()
{ {
return new Promise(function(resolve, reject) return new Promise(function(resolve, reject)
@ -116,7 +185,7 @@ function createConnections()
var prom = []; var prom = [];
for(var i = 0; i < nodes.length; i++) for(var i = 0; i < nodes.length; i++)
{ {
prom.push(processUserConnections(nodes[i].name));
prom.push(processUserConnections(nodes[i]));
} }
Promise.all(prom).then(function() Promise.all(prom).then(function()
@ -130,6 +199,12 @@ function createConnections()
} }
/**
* Adds the base person to the graph.
*
* @param username
* @returns {Promise<any>}
*/
function addSelfToGraph(username) function addSelfToGraph(username)
{ {
return new Promise(function(resolve, reject) return new Promise(function(resolve, reject)
@ -148,7 +223,23 @@ function addSelfToGraph(username)
} }
function bringUpProfileView(id)
{
for(var i = 0; i < nodes.length; i++)
{
if(nodes[i].id === id)
{
profileGen(nodes[i].name, "profileGen");
}
}
}
/**
* Creates a graph
* @param username
* @param containerName
* @param graphsTitle
*/
function createFriendsGraph(username, containerName, graphsTitle) function createFriendsGraph(username, containerName, graphsTitle)
{ {
nodes = []; nodes = [];
@ -168,6 +259,15 @@ function createFriendsGraph(username, containerName, graphsTitle)
edges: edges edges: edges
}; };
var network = new vis.Network(container, data, options); var network = new vis.Network(container, data, options);
network.on("click", function (params) {
params.event = "[original event]";
document.getElementById('eventSpan').innerHTML = '<h2>Click event:</h2>' + JSON.stringify(params, null, 4);
if(Number(this.getNodeAt(params.pointer.DOM)) !== NaN)
{
bringUpProfileView(Number(this.getNodeAt(params.pointer.DOM)));
}
});
}); });
}); });
}) })

+ 0
- 1
public/js/githubAPI.js View File

@ -32,7 +32,6 @@ const API_ORGANIZATIONS = "/orgs";
*/ */
function queryAPIByUser(apiPath, user, successCallBack, errorCallBack) { function queryAPIByUser(apiPath, user, successCallBack, errorCallBack) {
const urlpath = APIROOT + API_USER_PATH + user + apiPath; const urlpath = APIROOT + API_USER_PATH + user + apiPath;
console.log(urlpath);
$.ajax({ $.ajax({
type:'GET', type:'GET',
url: urlpath, url: urlpath,

+ 4
- 3
public/logo.svg
File diff suppressed because it is too large
View File


+ 44
- 3
public/style.css View File

@ -20,20 +20,46 @@
} }
#header-title { #header-title {
width: 30%; width: 30%;
padding-left: 20px;
font-size: 25px; font-size: 25px;
} }
#logo { #logo {
height: 60px; height: 60px;
} }
#error-code {
font-family: Comfortaa;
font-size: 200px;
color: rgb(208, 208, 208);
}
#navigation { #navigation {
width: 70%; width: 70%;
padding-right: 20px !important; padding-right: 20px !important;
} }
.error {
color: rgb(208, 208, 208);
}
#dcimg {
width: 300px;
}
.big-title { .big-title {
font-family: Comfortaa; font-family: Comfortaa;
font-weight: bold; font-weight: bold;
font-size: 60px; font-size: 60px;
text-wrap: avoid;
}
.m-title {
font-family: Comfortaa;
font-weight: normal;
font-size: 150%;
}
.text-title {
height: 60px;
background-color: rgb(208, 208, 208);
border-radius: 20px 0px 0px 0px;
}
.text-content {
height: 335px;
background-color: rgb(242, 242, 242);
border-radius: 0px 0px 0px 20px;
} }
.nav-sep { .nav-sep {
position: relative; position: relative;
@ -52,9 +78,24 @@
text-decoration: none; text-decoration: none;
} }
.nav-item a:hover { .nav-item a:hover {
color: rgb(57, 163, 225);
color: rgb(250, 152, 33);
text-decoration: none; text-decoration: none;
} }
.side-img {
display: grid;
position: relative;
width: 50%;
border-radius: 0px 20px 20px 0px;
}
.side-txt {
display: grid;
position: relative;
width: 50%;
}
.main {
position: relative;
top: 20px;
}
body { body {
background-color: rgb(242, 242, 242);
background-color: #232323;
} }

+ 12
- 13
routes/api.js View File

@ -25,18 +25,17 @@ function queryGitHubAPI(requestURL)
{ {
if(apiData == null) if(apiData == null)
{ {
const queryRUL = GITHUB_API + requestURL + authenticate;
got(queryRUL, { json: true }).then(response =>
{
resolve(response.body);
cache.put(requestURL, response.body);
}).catch(error =>
{
resolve(response.body);
cache.put(requestURL, response.body);
});
const queryRUL = GITHUB_API + requestURL + authenticate;
got(queryRUL, { json: true }).then(response =>
{
resolve(response.body);
cache.put(requestURL, response.body);
}).catch(error =>
{
resolve(response.body);
cache.put(requestURL, response.body);
});
} }
else else
@ -47,11 +46,11 @@ function queryGitHubAPI(requestURL)
} }
routes.get('/*', (request, result) => routes.get('/*', (request, result) =>
{ {
const gitHubAPIURL = request.url; const gitHubAPIURL = request.url;
result.setHeader('Content-Type', 'application/json');
queryGitHubAPI(gitHubAPIURL).then(function(data) queryGitHubAPI(gitHubAPIURL).then(function(data)
{ {
result.write(JSON.stringify(data)); result.write(JSON.stringify(data));

+ 0
- 3
server.js View File

@ -25,9 +25,6 @@ const routes = require('./routes');
app.use('/', routes); app.use('/', routes);
app.listen(configLoader.getConfiguration().port, () => app.listen(configLoader.getConfiguration().port, () =>
console.log(`App listening on port ${configLoader.getPort()}!`) console.log(`App listening on port ${configLoader.getPort()}!`)
); );

Loading…
Cancel
Save