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.

342 lines
7.2 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. var nodes;
  2. var edges;
  3. var options = {
  4. nodes: {
  5. shape: 'dot',
  6. size: 40,
  7. borderWidth:4,
  8. color: {
  9. border: '#222222',
  10. background: '#666666'
  11. },
  12. font:{
  13. color:'#eeeeee',
  14. size: 12
  15. },
  16. },
  17. edges: {
  18. color: 'lightgray'
  19. }
  20. };
  21. /**
  22. * Checks if a user is a node in the graph
  23. *
  24. * @param userID
  25. * @returns {boolean}
  26. */
  27. function alreadyInGraph(userID)
  28. {
  29. for(var i = 0; i < nodes.length; i++)
  30. {
  31. if(nodes[i].id === userID)
  32. {
  33. return true;
  34. }
  35. }
  36. return false;
  37. }
  38. /**
  39. * Adds the followers/following of a person
  40. * to the graph
  41. *
  42. * @param username
  43. * @param apiPath
  44. * @returns {Promise<any>}
  45. */
  46. function addRepos(orgName, apiPath, page)
  47. {
  48. console.log(orgName + " page=" + page);
  49. updateProgress();
  50. return new Promise(function(resolve, reject) {
  51. queryAPIByOrg(apiPath + "?page=" + page, orgName, function(data) {
  52. console.log(data);
  53. console.log(data.length);
  54. var prom = [];
  55. for(var i = 0; i < data.length; i++) {
  56. if(!alreadyInGraph(data[i].id)) {
  57. prom.push(addRepoToGraph(data[i]));
  58. }
  59. }
  60. Promise.all(prom).then( () => {
  61. if(data.length === 30) {
  62. addRepos(orgName, apiPath, page+ 1).then(function() {
  63. resolve();
  64. })
  65. }
  66. else {
  67. resolve();
  68. }
  69. })
  70. },
  71. function(error) {
  72. reject(error);
  73. })
  74. });
  75. }
  76. /**
  77. * Greedy function which checks to see if a edge is in the graphs
  78. *
  79. * @param id1
  80. * @param id2
  81. * @returns {boolean}
  82. */
  83. function edgeInGraph(id1, id2)
  84. {
  85. console.log("edge check");
  86. for(var i = 0;i < edges.length; i++)
  87. {
  88. if(edges[i].from === id1 && edges[i].to === id2)
  89. {
  90. return true;
  91. }
  92. if(edges[i].to === id1 && edges[i].from === id2)
  93. {
  94. return true;
  95. }
  96. }
  97. return false;
  98. }
  99. /**
  100. * Adds a connection to the graph
  101. *
  102. * @param person1
  103. * @param person2
  104. */
  105. function addConnection(person1, person2)
  106. {
  107. if(person1.id !== person2.id)
  108. {
  109. if(alreadyInGraph(person2.id) && !edgeInGraph(person1.id, person2.id))
  110. {
  111. edges.push(
  112. {
  113. from: person1.id,
  114. to: person2.id
  115. });
  116. }
  117. }
  118. }
  119. function processConnections(user, apiPoint, page)
  120. {
  121. updateProgress();
  122. return new Promise(function(resolve, reject)
  123. {
  124. queryAPIByUser(apiPoint + "?page=" + page, user.name,
  125. function(data)
  126. {
  127. for(var i = 0; i < data.length; i++)
  128. {
  129. addConnection(user, data[i])
  130. }
  131. if(data.length === 30)
  132. {
  133. processConnections(user, apiPoint, page + 1).then(function()
  134. {
  135. resolve();
  136. });
  137. }
  138. else
  139. {
  140. resolve();
  141. }
  142. }, function(error)
  143. {
  144. console.log(error);
  145. resolve();
  146. })
  147. })
  148. }
  149. /**
  150. * Processes all the connections of a user and adds them to the graph
  151. *
  152. * @param user has .id and .name
  153. * @returns {Promise<any>}
  154. */
  155. function processUserConnections(user)
  156. {
  157. return new Promise(function(resolve, reject)
  158. {
  159. processConnections(user, API_FOLLOWING, 1).then(function()
  160. {
  161. processConnections(user, API_FOLLOWERS, 1).then(function()
  162. {
  163. updateProgress();
  164. resolve();
  165. })
  166. })
  167. });
  168. }
  169. /**
  170. * Creates connections between all the nodes in
  171. * the graph.
  172. *
  173. * @returns {Promise<any>}
  174. */
  175. function createConnections()
  176. {
  177. return new Promise(function(resolve, reject)
  178. {
  179. var prom = [];
  180. for(var i = 0; i < nodes.length; i++)
  181. {
  182. prom.push(processUserConnections(nodes[i]));
  183. }
  184. Promise.all(prom).then(function()
  185. {
  186. resolve();
  187. }).catch(function(error)
  188. {
  189. console.log(error);
  190. resolve();
  191. });
  192. });
  193. }
  194. function bringUpProfileView(id)
  195. {
  196. for(var i = 0; i < nodes.length; i++)
  197. {
  198. if(nodes[i].id === id) {
  199. profileGen(nodes[i].name, "profileGen");
  200. }
  201. }
  202. }
  203. function addOrgUserToGraph(profileData)
  204. {
  205. nodes.push(
  206. {
  207. id:profileData.id,
  208. name:profileData.login,
  209. shape: 'circularImage',
  210. image:profileData.avatar_url
  211. });
  212. }
  213. function connectOrgUsers()
  214. {
  215. return new Promise(function(resolve, reject)
  216. {
  217. resolve();
  218. })
  219. }
  220. function addOrgUsers(orgname, page)
  221. {
  222. return new Promise(function(resolve, reject)
  223. {
  224. queryAPIByOrg(API_ORG_MEMBERS + "?page=" + page, orgname, function(data)
  225. {
  226. for(var i = 0;i < data.length; i++)
  227. {
  228. addOrgUserToGraph(data[i]);
  229. }
  230. if(data.length === 30)
  231. {
  232. addOrgUsers(orgname, page + 1).then(function()
  233. {
  234. resolve();
  235. });
  236. }
  237. else
  238. {
  239. total = 2*(data.length + (page * 30));
  240. resolve();
  241. }
  242. }, function(error)
  243. {
  244. console.log(error);
  245. resolve();
  246. })
  247. })
  248. }
  249. function bringUpProfileView(id)
  250. {
  251. for(var i = 0; i < nodes.length; i++)
  252. {
  253. if(nodes[i].id === id)
  254. {
  255. profileGen(nodes[i].name, "profileGen");
  256. }
  257. }
  258. }
  259. var total = 1;
  260. var indexed = 0;
  261. function updateProgress()
  262. {
  263. indexed++;
  264. var percent = parseInt((indexed/total)*100);
  265. $("#graphLoading").html("<div class=\"progress\">\n" +
  266. " <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" +
  267. "</div>");
  268. console.log();
  269. }
  270. /**
  271. * Creates a graph
  272. * @param username
  273. * @param containerName
  274. * @param graphsTitle
  275. */
  276. function createOrgRepoGraph(orgname, containerName, graphsTitle)
  277. {
  278. progressID = graphsTitle;
  279. nodes = [];
  280. edges = [];
  281. addOrgUsers(orgname, 1).then(function()
  282. {
  283. createConnections().then( () => {
  284. var container = document.getElementById(containerName);
  285. var data = {
  286. nodes: nodes,
  287. edges: edges
  288. };
  289. var network = new vis.Network(container, data, options);
  290. network.on("click", function (params) {
  291. params.event = "[original event]";
  292. if(Number(this.getNodeAt(params.pointer.DOM)) !== NaN) {
  293. bringUpProfileView(Number(this.getNodeAt(params.pointer.DOM)));
  294. }
  295. });
  296. $("#graphLoading").html("");
  297. });
  298. }).catch(function(error) {
  299. alert("Invalid Organization");
  300. });
  301. }