Website for visualizing a persons github network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
7.1 KiB

  1. var nodes;
  2. var edges;
  3. var options = {
  4. nodes: {
  5. borderWidth:4,
  6. size:30,
  7. color: {
  8. border: '#222222',
  9. background: '#666666'
  10. },
  11. font:{color:'#eeeeee'}
  12. },
  13. edges: {
  14. color: 'lightgray'
  15. }
  16. };
  17. /**
  18. * Checks if a user is a node in the graph
  19. *
  20. * @param userID
  21. * @returns {boolean}
  22. */
  23. function alreadyInGraph(userID)
  24. {
  25. for(var i = 0; i < nodes.length; i++)
  26. {
  27. if(nodes[i].id === userID)
  28. {
  29. return true;
  30. }
  31. }
  32. return false;
  33. }
  34. /**
  35. * adds a person to the nodes list
  36. *
  37. * @param profileData
  38. */
  39. function addPersonToGraph(profileData)
  40. {
  41. nodes.push(
  42. {
  43. id:profileData.id,
  44. name:profileData.login,
  45. shape: 'circularImage',
  46. image:profileData.avatar_url
  47. });
  48. }
  49. /**
  50. * Adds the followers/following of a person
  51. * to the graph
  52. *
  53. * @param username
  54. * @param apiPath
  55. * @returns {Promise<any>}
  56. */
  57. function addFriends(username, apiPath, page)
  58. {
  59. console.log(username + " page=" + page);
  60. updateProgress();
  61. return new Promise(function(resolve, reject)
  62. {
  63. queryAPIByUser(apiPath + "?page=" + page, username, function(data)
  64. {
  65. console.log(data);
  66. console.log(data.length);
  67. for(var i = 0; i < data.length; i++)
  68. {
  69. if(!alreadyInGraph(data[i].id))
  70. {
  71. addPersonToGraph(data[i]);
  72. }
  73. }
  74. if(page < 50 && data.length === 30)
  75. {
  76. addFriends(username, apiPath, page+ 1).then(function()
  77. {
  78. resolve();
  79. })
  80. }
  81. else
  82. {
  83. resolve();
  84. }
  85. },
  86. function(error)
  87. {
  88. reject(error);
  89. })
  90. });
  91. }
  92. /**
  93. * Greedy function which checks to see if a edge is in the graphs
  94. *
  95. * @param id1
  96. * @param id2
  97. * @returns {boolean}
  98. */
  99. function edgeInGraph(id1, id2)
  100. {
  101. console.log("edge check");
  102. for(var i = 0;i < edges.length; i++)
  103. {
  104. if(edges[i].from === id1 && edges[i].to === id2)
  105. {
  106. return true;
  107. }
  108. if(edges[i].to === id1 && edges[i].from === id2)
  109. {
  110. return true;
  111. }
  112. }
  113. return false;
  114. }
  115. /**
  116. * Adds a connection to the graph
  117. *
  118. * @param person1
  119. * @param person2
  120. */
  121. function addConnection(person1, person2)
  122. {
  123. if(person1.id !== person2.id)
  124. {
  125. if(alreadyInGraph(person2.id) && !edgeInGraph(person1.id, person2.id))
  126. {
  127. edges.push(
  128. {
  129. from: person1.id,
  130. to: person2.id
  131. });
  132. }
  133. }
  134. }
  135. function processConnections(user, apiPoint, page)
  136. {
  137. updateProgress();
  138. return new Promise(function(resolve, reject)
  139. {
  140. queryAPIByUser(apiPoint + "?page=" + page, user.name,
  141. function(data)
  142. {
  143. for(var i = 0; i < data.length; i++)
  144. {
  145. addConnection(user, data[i])
  146. }
  147. if(page < 50 && data.length === 30)
  148. {
  149. processConnections(user, apiPoint, page + 1).then(function()
  150. {
  151. resolve();
  152. });
  153. }
  154. else
  155. {
  156. resolve();
  157. }
  158. }, function(error)
  159. {
  160. console.log(error);
  161. resolve();
  162. })
  163. })
  164. }
  165. /**
  166. * Processes all the connections of a user and adds them to the graph
  167. *
  168. * @param user has .id and .name
  169. * @returns {Promise<any>}
  170. */
  171. function processUserConnections(user)
  172. {
  173. return new Promise(function(resolve, reject)
  174. {
  175. processConnections(user, API_FOLLOWING, 1).then(function()
  176. {
  177. processConnections(user, API_FOLLOWERS, 1).then(function()
  178. {
  179. resolve();
  180. })
  181. })
  182. });
  183. }
  184. /**
  185. * Creates connections between all the nodes in
  186. * the graph.
  187. *
  188. * @returns {Promise<any>}
  189. */
  190. function createConnections()
  191. {
  192. return new Promise(function(resolve, reject)
  193. {
  194. var prom = [];
  195. for(var i = 0; i < nodes.length; i++)
  196. {
  197. prom.push(processUserConnections(nodes[i]));
  198. }
  199. Promise.all(prom).then(function()
  200. {
  201. resolve();
  202. }).catch(function(error)
  203. {
  204. console.log(error);
  205. resolve();
  206. });
  207. });
  208. }
  209. var total = 1;
  210. var indexed = 0;
  211. var progressID;
  212. function updateProgress()
  213. {
  214. indexed++;
  215. var percent = parseInt((indexed/total)*100);
  216. $("#" + progressID).html("<div class=\"progress\">\n" +
  217. " <div class=\"progress-bar progress-bar-striped progress-bar-animated\" role=\"progressbar\" style=\"width: " + percent + "%\" aria-valuenow=\"" + percent + "\" aria-valuemin=\"0\" aria-valuemax=\"100\"></div>\n" +
  218. "</div>");
  219. console.log();
  220. }
  221. /**
  222. * Adds the base person to the graph.
  223. *
  224. * @param username
  225. * @returns {Promise<any>}
  226. */
  227. function addSelfToGraph(username)
  228. {
  229. return new Promise(function(resolve, reject)
  230. {
  231. queryAPIByUser("", username, function(data)
  232. {
  233. total = (data.followers + data.following) * 2;
  234. addPersonToGraph(data);
  235. resolve();
  236. },
  237. function(error)
  238. {
  239. reject(error);
  240. });
  241. });
  242. }
  243. function bringUpProfileView(id)
  244. {
  245. for(var i = 0; i < nodes.length; i++)
  246. {
  247. if(nodes[i].id === id)
  248. {
  249. profileGen(nodes[i].name, "profileGen");
  250. }
  251. }
  252. }
  253. /**
  254. * Creates a graph
  255. * @param username
  256. * @param containerName
  257. * @param graphsTitle
  258. */
  259. function createFriendsGraph(username, containerName, graphsTitle)
  260. {
  261. progressID = graphsTitle;
  262. nodes = [];
  263. edges = [];
  264. addSelfToGraph(username).then(function()
  265. {
  266. addFriends(username, API_FOLLOWERS,1).then(function()
  267. {
  268. addFriends(username, API_FOLLOWING,1).then(function()
  269. {
  270. createConnections().then(function()
  271. {
  272. console.log("cleared div");
  273. $("#" + progressID).html("");
  274. var container = document.getElementById(containerName);
  275. var data =
  276. {
  277. nodes: nodes,
  278. edges: edges
  279. };
  280. var network = new vis.Network(container, data, options);
  281. network.on("click", function (params)
  282. {
  283. params.event = "[original event]";
  284. if(Number(this.getNodeAt(params.pointer.DOM)) !== NaN)
  285. {
  286. bringUpProfileView(Number(this.getNodeAt(params.pointer.DOM)));
  287. }
  288. });
  289. });
  290. });
  291. })
  292. }).catch(function(error)
  293. {
  294. $("#" + graphsTitle).html("Error Fetching Data From API");
  295. alert("Invalid User");
  296. });
  297. }