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.

333 lines
7.1 KiB

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