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.

297 lines
5.9 KiB

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