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.

344 lines
7.1 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 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. resolve();
  164. })
  165. })
  166. });
  167. }
  168. /**
  169. * Creates connections between all the nodes in
  170. * the graph.
  171. *
  172. * @returns {Promise<any>}
  173. */
  174. function createConnections()
  175. {
  176. return new Promise(function(resolve, reject)
  177. {
  178. var prom = [];
  179. for(var i = 0; i < nodes.length; i++)
  180. {
  181. prom.push(processUserConnections(nodes[i]));
  182. }
  183. Promise.all(prom).then(function()
  184. {
  185. resolve();
  186. }).catch(function(error)
  187. {
  188. console.log(error);
  189. resolve();
  190. });
  191. });
  192. }
  193. var total = 1;
  194. var indexed = 0;
  195. var progressID;
  196. function updateProgress()
  197. {
  198. indexed++;
  199. var percent = parseInt((indexed/total)*100);
  200. $("#" + progressID).html("<div class=\"progress\">\n" +
  201. " <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" +
  202. "</div>");
  203. console.log();
  204. }
  205. function bringUpProfileView(id)
  206. {
  207. for(var i = 0; i < nodes.length; i++)
  208. {
  209. if(nodes[i].id === id) {
  210. profileGen(nodes[i].name, "profileGen");
  211. }
  212. }
  213. }
  214. function addOrgUserToGraph(profileData)
  215. {
  216. nodes.push(
  217. {
  218. id:profileData.id,
  219. name:profileData.login,
  220. shape: 'circularImage',
  221. image:profileData.avatar_url
  222. });
  223. }
  224. function connectOrgUsers()
  225. {
  226. return new Promise(function(resolve, reject)
  227. {
  228. resolve();
  229. })
  230. }
  231. function addOrgUsers(orgname, page)
  232. {
  233. return new Promise(function(resolve, reject)
  234. {
  235. queryAPIByOrg(API_ORG_MEMBERS + "?page=" + page, orgname, function(data)
  236. {
  237. for(var i = 0;i < data.length; i++)
  238. {
  239. addOrgUserToGraph(data[i]);
  240. }
  241. if(data.length === 30)
  242. {
  243. addOrgUsers(orgname, page + 1).then(function()
  244. {
  245. resolve();
  246. });
  247. }
  248. else
  249. {
  250. resolve();
  251. }
  252. }, function(error)
  253. {
  254. console.log(error);
  255. resolve();
  256. })
  257. })
  258. }
  259. function bringUpProfileView(id)
  260. {
  261. for(var i = 0; i < nodes.length; i++)
  262. {
  263. if(nodes[i].id === id)
  264. {
  265. profileGen(nodes[i].name, "profileGen");
  266. }
  267. }
  268. }
  269. /**
  270. * Creates a graph
  271. * @param username
  272. * @param containerName
  273. * @param graphsTitle
  274. */
  275. function createOrgRepoGraph(orgname, containerName, graphsTitle)
  276. {
  277. progressID = graphsTitle;
  278. nodes = [];
  279. edges = [];
  280. addOrgUsers(orgname, 1).then(function()
  281. {
  282. $("#" + progressID).html("");
  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. });
  297. }).catch(function(error) {
  298. alert("Invalid Organization");
  299. });
  300. }