From e55b4e81c1de558bfc2a60b15512d9b56562c5d3 Mon Sep 17 00:00:00 2001 From: Bryce Murphy Date: Sun, 17 Feb 2019 04:05:18 -0500 Subject: [PATCH 1/3] some more cleanup --- public/FriendsGraph.html | 1 - public/GraphGenerator.html | 4 ++-- public/js/friendsGraph.js | 4 ++-- public/js/githubAPI.js | 32 +++++++++++++++++++++++++++++++- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/public/FriendsGraph.html b/public/FriendsGraph.html index a9156bd..044fc69 100644 --- a/public/FriendsGraph.html +++ b/public/FriendsGraph.html @@ -71,7 +71,6 @@ options.height = "700px"; createFriendsGraph(username, "myGraph", "graphLoading"); profileGen(username, "profileGen"); - $("#searchBarTop").html(""); } if(findGetParameter("name") !== null) diff --git a/public/GraphGenerator.html b/public/GraphGenerator.html index ea681a9..6b99e5c 100644 --- a/public/GraphGenerator.html +++ b/public/GraphGenerator.html @@ -110,7 +110,7 @@ Creates a web chart of the specified organization and all associated repos.

- +

@@ -145,5 +145,5 @@ var oname = fetchOrgInput(); window.location.href = "./OrgRepoGraph.html?name=" + oname; } - + \ No newline at end of file diff --git a/public/js/friendsGraph.js b/public/js/friendsGraph.js index 07bf5e4..2158e32 100644 --- a/public/js/friendsGraph.js +++ b/public/js/friendsGraph.js @@ -291,9 +291,9 @@ function bringUpProfileView(id) * @param containerName * @param graphsTitle */ -function createFriendsGraph(username, containerName, graphsProgres) +function createFriendsGraph(username, containerName, graphsTitle) { - progressID = graphsProgres; + progressID = graphsTitle; nodes = []; edges = []; diff --git a/public/js/githubAPI.js b/public/js/githubAPI.js index 3d4a8b9..df6b827 100644 --- a/public/js/githubAPI.js +++ b/public/js/githubAPI.js @@ -11,6 +11,10 @@ const APIROOT = "api"; const API_USER_PATH = "/users/"; +const API_ORG_PATH = "/orgs/"; + +const API_REPOS = "/repos/"; + const API_FOLLOWING = "/following"; const API_FOLLOWERS = "/followers"; @@ -42,4 +46,30 @@ function queryAPIByUser(apiPath, user, successCallBack, errorCallBack) { error:errorCallBack, timeout: 4000 }); -} \ No newline at end of file +} + +function queryAPIByOrg(apiPath, org, successCallBack, errorCallBack) { + const urlpath = APIROOT + API_ORG_PATH + org + apiPath; + $.ajax({ + type:'GET', + url: urlpath, + crossDomain: true, + dataType: "json", + success: successCallBack, + error:errorCallBack, + timeout: 4000 + }); +} +/* +function queryAPIByRepo(apiPath, org, successCallBack, errorCallBack) { + const urlpath = APIROOT + API_ORG_PATH + org + apiPath; + $.ajax({ + type:'GET', + url: urlpath, + crossDomain: true, + dataType: "json", + success: successCallBack, + error:errorCallBack, + timeout: 4000 + }); +}*/ \ No newline at end of file From 68326b0274fd2c9a6c0b5b330b66c5913cbc75bb Mon Sep 17 00:00:00 2001 From: jrtechs Date: Sun, 17 Feb 2019 04:09:43 -0500 Subject: [PATCH 2/3] Fixed bug with profile and added content to the about page. --- public/about.html | 17 +++++++++++++---- public/js/profileGen.js | 5 ++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/public/about.html b/public/about.html index c6db7a5..22bf82e 100644 --- a/public/about.html +++ b/public/about.html @@ -46,7 +46,14 @@

- jeff this is where you can write a bunch about the project + This is an interactive website which allows you to make graphs of the github network. + Currently we have three types of graphs-- the most popular of which is our friends graph. + The friends graphs helps you visualize clusters of friends/collaborators on GitHub. + This can be used to spot clusters within organizations and schools. +

+

+ This is an open source project, all the source code can be found on github. + New collaborators are always welcomed; look at our github repository for contributing guidelines.

@@ -55,6 +62,8 @@

This project was completed in 24 hours for participation in BrickHack V at the Rochester Institute of Technology. + We hope that this project will make people more interested in learning about big data analytics. + The visual aspect of this website makes learning about topics such as clustering and graph databases more intuitive.

@@ -68,7 +77,7 @@

- did stuff + I did a large chunk of work with the backend pulling data from github and generating the graphs with visJS.

- also did stuff + Worked on pulling api data from github to create the mini profile display and some graphs.

- kinda did stuff + Worked on the front end design of the website and designed graphic art for this website.

" +
"; $("#"+container).html(html); }) }, () => { @@ -79,8 +79,7 @@ function parseOrgs(name) { resolve(orgs_final.join(" ")); }) }, (error) => { - console.error("error getting orgs"); - reject(error); + resolve([]); }); }) } From 2d1a8c17373011ee4a05e9f063f6816e0a3f139f Mon Sep 17 00:00:00 2001 From: Bryce Murphy Date: Sun, 17 Feb 2019 04:20:32 -0500 Subject: [PATCH 3/3] pls fix --- public/OrgRepoGraph.html | 84 ++++++++ public/js/createOrgRepoGraph.js | 336 ++++++++++++++++++++++++++++++++ public/js/githubAPI.js | 1 + 3 files changed, 421 insertions(+) create mode 100644 public/OrgRepoGraph.html create mode 100644 public/js/createOrgRepoGraph.js diff --git a/public/OrgRepoGraph.html b/public/OrgRepoGraph.html new file mode 100644 index 0000000..71a0906 --- /dev/null +++ b/public/OrgRepoGraph.html @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + +
+ +
+
+

+
+

+            
+
+
+
+
+ + +
+ + + + \ No newline at end of file diff --git a/public/js/createOrgRepoGraph.js b/public/js/createOrgRepoGraph.js new file mode 100644 index 0000000..c19fd40 --- /dev/null +++ b/public/js/createOrgRepoGraph.js @@ -0,0 +1,336 @@ + +var nodes; + +var edges; + + +var options = { + nodes: { + borderWidth:4, + size:30, + color: { + border: '#222222', + background: '#666666' + }, + font:{color:'#eeeeee'} + }, + edges: { + color: 'lightgray' + } +}; + + +/** + * Checks if a user is a node in the graph + * + * @param userID + * @returns {boolean} + */ +function alreadyInGraph(userID) +{ + for(var i = 0; i < nodes.length; i++) + { + if(nodes[i].id === userID) + { + return true; + } + } + return false; +} + + +/** + * adds a person to the nodes list + * + * @param profileData + */ +function addSelfAsOrg(orgData) { + nodes.push( { + id:orgData.id, + name:orgData.login, + image:orgData.avatar_url + }); +} + +function addSelfAsRepo(repoData) { + nodes.push( { + id:repoData.id, + name:repoData.name, + image:repoData.avatar_url + }); + console.log(repoData.name); +} + + +/** + * Adds the followers/following of a person + * to the graph + * + * @param username + * @param apiPath + * @returns {Promise} + */ +function addRepos(orgName, apiPath, page) +{ + console.log(orgName + " page=" + page); + updateProgress(); + return new Promise(function(resolve, reject) { + queryAPIByOrg(apiPath + "?page=" + page, orgName, function(data) { + console.log(data); + console.log(data.length); + var prom = []; + for(var i = 0; i < data.length; i++) { + if(!alreadyInGraph(data[i].id)) { + prom.push(addRepoToGraph(data[i])); + } + } + Promise.all(prom).then( () => { + if(data.length === 30) { + addRepos(orgName, apiPath, page+ 1).then(function() { + resolve(); + }) + } + else { + resolve(); + } + }) + }, + function(error) { + reject(error); + }) + }); +} + + +/** + * Greedy function which checks to see if a edge is in the graphs + * + * @param id1 + * @param id2 + * @returns {boolean} + */ +function edgeInGraph(id1, id2) +{ + console.log("edge check"); + 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) +{ + if(person1.id !== person2.id) + { + if(alreadyInGraph(person2.id) && !edgeInGraph(person1.id, person2.id)) + { + edges.push( + { + from: person1.id, + to: person2.id + }); + } + } +} + + +function processConnections(user, apiPoint, page) +{ + updateProgress(); + return new Promise(function(resolve, reject) + { + queryAPIByUser(apiPoint + "?page=" + page, user.name, + function(data) + { + for(var i = 0; i < data.length; i++) + { + addConnection(user, data[i]) + } + if(data.length === 30) + { + processConnections(user, apiPoint, page + 1).then(function() + { + resolve(); + }); + } + else + { + resolve(); + } + }, function(error) + { + console.log(error); + resolve(); + }) + }) +} + + +/** + * Processes all the connections of a user and adds them to the graph + * + * @param user has .id and .name + * @returns {Promise} + */ +function processUserConnections(user) +{ + return new Promise(function(resolve, reject) + { + + processConnections(user, API_FOLLOWING, 1).then(function() + { + processConnections(user, API_FOLLOWERS, 1).then(function() + { + resolve(); + }) + }) + }); +} + + +/** + * Creates connections between all the nodes in + * the graph. + * + * @returns {Promise} + */ +function createConnections() +{ + return new Promise(function(resolve, reject) + { + var prom = []; + for(var i = 0; i < nodes.length; i++) + { + prom.push(processUserConnections(nodes[i])); + } + + Promise.all(prom).then(function() + { + resolve(); + }).catch(function(error) + { + console.log(error); + resolve(); + }); + }); +} + + +var total = 1; +var indexed = 0; +var progressID; + + +function updateProgress() +{ + indexed++; + + var percent = parseInt((indexed/total)*100); + + $("#" + progressID).html("
\n" + + "
\n" + + "
"); + + console.log(); +} + +/** + * Adds the base person to the graph. + * + * @param username + * @returns {Promise} + */ +function addOrgToGraph(orgname) { + return new Promise(function(resolve, reject) { + queryAPIByOrg("", orgname, function(data) { + total = (data.public_repos) * 2; + addSelfAsOrg(data); + resolve(); + }, + function(error) { + reject(error); + }); + + }); +} + +function addRepoToGraph(repo) { + return new Promise(function(resolve, reject) { + console.log("in repo"); + console.log(repo); + addSelfAsRepo(repo); + resolve(); + /* + queryAPIByRepo(repo.name, orgname, function(data) { + //total = (data.followers + data.following) * 2; + addSelfAsRepo(data); + resolve(); + console.log("did it"); + }, + function(error) { + reject(error); + });*/ + + }); +} + + +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 createOrgRepoGraph(orgname, containerName, graphsTitle) +{ + progressID = graphsTitle; + + nodes = []; + edges = []; + addOrgToGraph(orgname).then(function() { + addRepos(orgname, API_REPOS,1).then(function() { + $("#" + progressID).html(""); + + var container = document.getElementById(containerName); + var data = { + nodes: nodes, + edges: edges + }; + var network = new vis.Network(container, data, options); + + network.on("click", function (params) { + params.event = "[original event]"; + if(Number(this.getNodeAt(params.pointer.DOM)) !== NaN) { + bringUpProfileView(Number(this.getNodeAt(params.pointer.DOM))); + } + }); + }) + }).catch(function(error) { + alert("Invalid Organization"); + }); +} \ No newline at end of file diff --git a/public/js/githubAPI.js b/public/js/githubAPI.js index df6b827..a6f0579 100644 --- a/public/js/githubAPI.js +++ b/public/js/githubAPI.js @@ -59,6 +59,7 @@ function queryAPIByOrg(apiPath, org, successCallBack, errorCallBack) { error:errorCallBack, timeout: 4000 }); + console.log("past"); } /* function queryAPIByRepo(apiPath, org, successCallBack, errorCallBack) {