Graph database Analysis of the Steam 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.

306 lines
5.9 KiB

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