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.
- 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.
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("");
+
+ 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/friendsGraph.js b/public/js/friendsGraph.js
index 28f97c0..6669834 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..a6f0579 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,31 @@ 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
+ });
+ console.log("past");
+}
+/*
+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
diff --git a/public/js/profileGen.js b/public/js/profileGen.js
index 85b6f8f..8e6f972 100644
--- a/public/js/profileGen.js
+++ b/public/js/profileGen.js
@@ -45,7 +45,7 @@ function profileGen(username, container)
(user.company != null ? "Company: "+user.company+"" : "")+
(orgsReturn != [] ? ""+orgsReturn+"" : "")+ " \
\
-