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.

329 lines
6.9 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. updateProgress();
  60. return new Promise(function(resolve, reject)
  61. {
  62. queryAPIByUser(apiPath + "?page=" + page, username, function(data)
  63. {
  64. for(var i = 0; i < data.length; i++)
  65. {
  66. if(!alreadyInGraph(data[i].id))
  67. {
  68. addPersonToGraph(data[i]);
  69. }
  70. }
  71. if(page < 50 && data.length === 30)
  72. {
  73. addFriends(username, apiPath, page+ 1).then(function()
  74. {
  75. resolve();
  76. })
  77. }
  78. else
  79. {
  80. resolve();
  81. }
  82. },
  83. function(error)
  84. {
  85. reject(error);
  86. })
  87. });
  88. }
  89. /**
  90. * Greedy function which checks to see if a edge is in the graphs
  91. *
  92. * @param id1
  93. * @param id2
  94. * @returns {boolean}
  95. */
  96. function edgeInGraph(id1, id2)
  97. {
  98. for(var i = 0;i < edges.length; i++)
  99. {
  100. if(edges[i].from === id1 && edges[i].to === id2)
  101. {
  102. return true;
  103. }
  104. if(edges[i].to === id1 && edges[i].from === id2)
  105. {
  106. return true;
  107. }
  108. }
  109. return false;
  110. }
  111. /**
  112. * Adds a connection to the graph
  113. *
  114. * @param person1
  115. * @param person2
  116. */
  117. function addConnection(person1, person2)
  118. {
  119. if(person1.id !== person2.id)
  120. {
  121. if(alreadyInGraph(person2.id) && !edgeInGraph(person1.id, person2.id))
  122. {
  123. edges.push(
  124. {
  125. from: person1.id,
  126. to: person2.id
  127. });
  128. }
  129. }
  130. }
  131. function processConnections(user, apiPoint, page)
  132. {
  133. return new Promise(function(resolve, reject)
  134. {
  135. queryAPIByUser(apiPoint + "?page=" + page, user.name,
  136. function(data)
  137. {
  138. for(var i = 0; i < data.length; i++)
  139. {
  140. addConnection(user, data[i])
  141. }
  142. if(page < 50 && data.length === 30)
  143. {
  144. processConnections(user, apiPoint, page + 1).then(function()
  145. {
  146. resolve();
  147. });
  148. }
  149. else
  150. {
  151. resolve();
  152. }
  153. }, function(error)
  154. {
  155. console.log(error);
  156. resolve();
  157. })
  158. })
  159. }
  160. /**
  161. * Processes all the connections of a user and adds them to the graph
  162. *
  163. * @param user has .id and .name
  164. * @returns {Promise<any>}
  165. */
  166. function processUserConnections(user)
  167. {
  168. return new Promise(function(resolve, reject)
  169. {
  170. processConnections(user, API_FOLLOWING, 1).then(function()
  171. {
  172. processConnections(user, API_FOLLOWERS, 1).then(function()
  173. {
  174. updateProgress();
  175. resolve();
  176. })
  177. })
  178. });
  179. }
  180. /**
  181. * Creates connections between all the nodes in
  182. * the graph.
  183. *
  184. * @returns {Promise<any>}
  185. */
  186. function createConnections()
  187. {
  188. return new Promise(function(resolve, reject)
  189. {
  190. var prom = [];
  191. for(var i = 0; i < nodes.length; i++)
  192. {
  193. prom.push(processUserConnections(nodes[i]));
  194. }
  195. Promise.all(prom).then(function()
  196. {
  197. resolve();
  198. }).catch(function(error)
  199. {
  200. console.log(error);
  201. resolve();
  202. });
  203. });
  204. }
  205. var total = 1;
  206. var indexed = 0;
  207. var progressID;
  208. function updateProgress()
  209. {
  210. indexed++;
  211. var percent = parseInt((indexed/total)*100);
  212. $("#" + progressID).html("<div class=\"progress\">\n" +
  213. " <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" +
  214. "</div>");
  215. console.log();
  216. }
  217. /**
  218. * Adds the base person to the graph.
  219. *
  220. * @param username
  221. * @returns {Promise<any>}
  222. */
  223. function addSelfToGraph(username)
  224. {
  225. return new Promise(function(resolve, reject)
  226. {
  227. queryAPIByUser("", username, function(data)
  228. {
  229. total = (data.followers + data.following);
  230. addPersonToGraph(data);
  231. resolve();
  232. },
  233. function(error)
  234. {
  235. reject(error);
  236. });
  237. });
  238. }
  239. function bringUpProfileView(id)
  240. {
  241. for(var i = 0; i < nodes.length; i++)
  242. {
  243. if(nodes[i].id === id)
  244. {
  245. profileGen(nodes[i].name, "profileGen");
  246. }
  247. }
  248. }
  249. /**
  250. * Creates a graph
  251. * @param username
  252. * @param containerName
  253. * @param graphsTitle
  254. */
  255. function createFriendsGraph(username, containerName, graphsTitle)
  256. {
  257. progressID = graphsTitle;
  258. nodes = [];
  259. edges = [];
  260. addSelfToGraph(username).then(function()
  261. {
  262. addFriends(username, API_FOLLOWERS,1).then(function()
  263. {
  264. addFriends(username, API_FOLLOWING,1).then(function()
  265. {
  266. createConnections().then(function()
  267. {
  268. $("#" + progressID).html("");
  269. var container = document.getElementById(containerName);
  270. var data =
  271. {
  272. nodes: nodes,
  273. edges: edges
  274. };
  275. var network = new vis.Network(container, data, options);
  276. network.on("click", function (params)
  277. {
  278. params.event = "[original event]";
  279. if(Number(this.getNodeAt(params.pointer.DOM)) !== NaN)
  280. {
  281. bringUpProfileView(Number(this.getNodeAt(params.pointer.DOM)));
  282. }
  283. });
  284. });
  285. });
  286. })
  287. }).catch(function(error)
  288. {
  289. $("#" + graphsTitle).html("Error Fetching Data From API");
  290. alert("Invalid User");
  291. });
  292. }