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.

335 lines
7.1 KiB

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