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.

278 lines
5.8 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. reject(error);
  177. });
  178. });
  179. }
  180. /**
  181. * Adds the base person to the graph.
  182. *
  183. * @param username
  184. * @returns {Promise<any>}
  185. */
  186. function addSelfToGraph(username)
  187. {
  188. return new Promise(function(resolve, reject)
  189. {
  190. queryAPIByUser("", username, function(data)
  191. {
  192. addPersonToGraph(data);
  193. resolve();
  194. },
  195. function(error)
  196. {
  197. reject(error);
  198. });
  199. });
  200. }
  201. function bringUpProfileView(id)
  202. {
  203. for(var i = 0; i < nodes.length; i++)
  204. {
  205. if(nodes[i].id === id)
  206. {
  207. profileGen(nodes[i].name, "profileGen");
  208. }
  209. }
  210. }
  211. /**
  212. * Creates a graph
  213. * @param username
  214. * @param containerName
  215. * @param graphsTitle
  216. */
  217. function createFriendsGraph(username, containerName, graphsTitle)
  218. {
  219. nodes = [];
  220. edges = [];
  221. addSelfToGraph(username).then(function()
  222. {
  223. addFriends(username, API_FOLLOWERS).then(function()
  224. {
  225. addFriends(username, API_FOLLOWING).then(function()
  226. {
  227. createConnections().then(function()
  228. {
  229. var container = document.getElementById(containerName);
  230. var data =
  231. {
  232. nodes: nodes,
  233. edges: edges
  234. };
  235. var network = new vis.Network(container, data, options);
  236. network.on("click", function (params) {
  237. params.event = "[original event]";
  238. document.getElementById('eventSpan').innerHTML = '<h2>Click event:</h2>' + JSON.stringify(params, null, 4);
  239. if(Number(this.getNodeAt(params.pointer.DOM)) !== NaN)
  240. {
  241. bringUpProfileView(Number(this.getNodeAt(params.pointer.DOM)));
  242. }
  243. });
  244. });
  245. });
  246. })
  247. }).catch(function(error)
  248. {
  249. console.log(error);
  250. $("#" + graphsTitle).html("Error Fetching Data From API");
  251. });
  252. }