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.

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