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.

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