Browse Source

Created a basic games and friends graph

games-graph
jrtechs 3 years ago
parent
commit
f79568fb38
3 changed files with 473 additions and 1 deletions
  1. +107
    -0
      website/gamesGraph.html
  2. +365
    -0
      website/js/gamesGraph.js
  3. +1
    -1
      website/js/steamAPI.js

+ 107
- 0
website/gamesGraph.html View File

@ -0,0 +1,107 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Friends - Steam Graphs</title>
<link rel="icon" href="./favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="./style.css" />
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous">
</script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous">
</script>
<script src="js/steamAPI.js"></script>
<script src="js/gamesGraph.js"></script>
<script src="js/profileGen.js"></script>
<script src="js/utilities.js"></script>
<script type="text/javascript" src="js/vis/vis.js"></script>
<link href="js/vis/vis-network.min.css" rel="stylesheet" type="text/css" />
</head>
<body class="friends-graph-page">
<nav class="navbar navbar-dark bg-dark navbar-expand-md">
<a class="navbar-brand" href="/"><img src="img/githubgraph-logo.svg" alt=""></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#main-menu" aria-controls="main-menu" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="main-menu" class="collapse navbar-collapse">
<ul class="navbar-nav flex-fill justify-content-end">
<li class="nav-item">
<a class="nav-link" href="./GraphGenerator.html">Generate graphs</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://github.com/jrtechs/github-graphs/">View on GitHub</a>
</li>
<li class="nav-item">
<a class="nav-link" href="./about.html">About</a>
</li>
</ul>
</div>
</nav>
<div class="main">
<div class="container-fluid container-xl">
<div class="row pt-5">
<div class="col-lg-3 col-md-4 col-12"></div>
<div class="col-lg-9 col-md-8 col-12">
<div class="d-flex align-items-baseline justify-content-between my-4">
<div class="d-flex align-items-center">
<svg class="mr-3" width="36" height="36" viewBox="0 0 36 36" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M18 0C8.064 0 0 8.064 0 18C0 27.936 8.064 36 18 36C27.936 36 36 27.936 36 18C36 8.064 27.936 0 18 0ZM18 5.4C20.988 5.4 23.4 7.812 23.4 10.8C23.4 13.788 20.988 16.2 18 16.2C15.012 16.2 12.6 13.788 12.6 10.8C12.6 7.812 15.012 5.4 18 5.4ZM18 30.96C15.8613 30.96 13.7559 30.4308 11.8715 29.4194C9.98707 28.4081 8.3822 26.9462 7.2 25.164C7.254 21.582 14.4 19.62 18 19.62C21.582 19.62 28.746 21.582 28.8 25.164C27.6178 26.9462 26.0129 28.4081 24.1285 29.4194C22.2441 30.4308 20.1387 30.96 18 30.96Z"
fill="white" />
</svg>
<h1 class="text-white font-weight-bold">Interactive friend chart</h1>
</div>
<div>
<a id="TimelineLink" class="text-light" href="#">View repo timeline</a>
</div>
</div>
</div>
</div>
<div class="row pb-4">
<div class="col-lg-3 col-md-4 col-12">
<div id="profileGen"></div>
</div>
<div class="col-lg-9 col-md-8 col-12">
<div class="card shadow text-white bg-dark border-white">
<h2 id="graphLoading"></h2>
<div id="myGraph" class="w-100"></div>
</div>
</div>
</div>
</div>
</div>
</body>
<script>
$(function () {
$('[data-toggle="tooltip"]').tooltip();
});
function createGraphs(id)
{
options.width = $("#myGraph").width() + "px";
options.height = "700px";
createGameGraphs(id, "myGraph", "graphLoading");
profileGen(id, "profileGen");
}
if(findGetParameter("id") !== null)
{
createGraphs(findGetParameter("id"))
}
$('#TimelineLink').attr("href", "TimeLineGraph.html?name=" + findGetParameter("name"));
</script>
</html>

+ 365
- 0
website/js/gamesGraph.js View File

@ -0,0 +1,365 @@
/** Nodes in the vis js graph */
var nodes;
/** Edges used to make the Vis JS graph*/
var edges;
/** Used for the loading bar */
var total = 1;
var indexed = 0;
var progressID;
/** Github id of the user being indexed */
var baseID;
/**
* Vis js graph options
*/
var options = {
nodes: {
borderWidth:4,
size:30,
color: {
border: '#222222',
background: '#666666'
},
font:{color:'#eeeeee'}
},
edges: {
color: 'lightgray'
}
};
/**
* Checks if a user is a node in the graph
*
* @param userID
* @returns {boolean}
*/
function alreadyInGraph(username)
{
for(var i = 0; i < nodes.length; i++)
{
if(nodes[i].id === username)
{
return true;
}
}
return false;
}
/**
* adds a person to the nodes list
*
* @param profileData
*/
function addPersonToGraph(profileData)
{
addManualToGraph(profileData.id, profileData.avatar);
for(var i = 0; i < profileData.friends.length; i++)
{
addManualToGraph(profileData.friends[i].id,
profileData.friends[i].avatar);
}
}
function addManualToGraph(id,avatar)
{
nodes.push(
{
id:id,
shape: 'circularImage',
image:avatar
});
}
/**
* Adds the followers/following of a person
* to the graph
*
* @param username
* @param apiPath
* @returns {Promise<any>}
*/
function addFriends(username)
{
updateProgress();
return new Promise((resolve, reject)=>
{
getPersonAPI(username, (data)=>
{
for(var i = 0; i < data.length; i++)
{
if(!alreadyInGraph(data[i].login))
{
addPersonToGraph(data[i]);
}
}
resolve();
},
(error)=>
{
reject(error);
})
});
}
/**
* Greedy function which checks to see if a edge is in the graphs
*
* @param id1
* @param id2
* @returns {boolean}
*/
function edgeInGraph(id1, id2)
{
for(var i = 0;i < edges.length; i++)
{
if((edges[i].to === id1 && edges[i].from === id2) ||
(edges[i].from === id1 && edges[i].to === id2))
{
return true;
}
}
return false;
}
/**
* Adds a connection to the graph
*
* @param person1
* @param person2
*/
function addConnection(id1, id2)
{
if(id1 !== id2)
{
if(alreadyInGraph(id2) && !edgeInGraph(id1, id2))
{
network.body.data.edges.add([{
from: id1,
to: id2
}]);
}
}
}
/**
* Processes all the connections of a user and adds them to the graph
*
* @param user has .id and .name
* @returns {Promise<any>}
*/
function processUserConnections(node)
{
return new Promise((resolve, reject)=>
{
getPersonAPI(node.id,
(data) => {
updateProgress();
for (var i = 0; i < data.friends.length; i++) {
addConnection(node.id, data.friends[i].id)
}
resolve();
}, (error) => {
console.log(error);
resolve();
});
});
}
function processUserGames(node)
{
return new Promise((resolve, reject)=>
{
getUserGames(node.id,
(data) => {
for (var i = 0; i < data.length; i++) {
addConnection(node.id, "" +data[i].appID)
}
resolve();
}, (error) => {
console.log(error);
resolve();
});
});
}
/**
* Creates connections between all the nodes in
* the graph.
*
* @returns {Promise<any>}
*/
async function createConnections() {
for (var i = 0; i < nodes.length; i++)
{
await processUserConnections(nodes[i]);
await processUserGames(nodes[i]);
}
}
/**
* Updates progress bar for loading the JS graph
*/
function updateProgress()
{
indexed++;
if(indexed >= total)
{
$("#" + progressID).html("");
}
else
{
const percent = parseInt((indexed/total)*100);
$("#" + progressID).html("<div class=\"progress\">\n" +
" <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" +
"</div>");
}
}
function getSteamImgURL(game)
{
return "http://media.steampowered.com/steamcommunity/public/images/apps/" + game.appID + "/" + game.icon + ".jpg"
}
function addGamesToGraph(games)
{
console.log("adding base player games to graph");
for(var i = 0; i < games.length; i++)
{
var gameLogo = getSteamImgURL(games[i]);
console.log(gameLogo);
nodes.push(
{
id:"" +games[i].appID,
image:gameLogo,
shape: 'image',
size: 30,
});
}
}
var selfData;
/**
* Adds the base person to the graph.
*
* @param username
* @returns {Promise<any>}
*/
function addSelfToGraph(id)
{
return new Promise((resolve, reject)=>
{
getPersonAPI(id, (data)=>
{
selfData = data;
baseID = data.id;
total = data.friends.length;
addPersonToGraph(data);
getUserGames(id, (games)=>
{
console.log(games);
addGamesToGraph(games);
resolve();
},
(error2)=>
{
console.log(error2);
reject();
});
},
(error)=>
{
reject(error);
});
});
}
/**
* Used for the on graph click event
*
* @param github id
*/
function bringUpProfileView(uname)
{
console.log(uname);
if(uname === selfData.id)
{
profileGen(selfData, "profileGen");
}
else
{
for(var i = 0; i < selfData.friends.length; i++)
{
if(selfData.friends[i].id === uname)
{
profileGen(selfData.friends[i], "profileGen");
}
}
}
}
var network;
nodes = [];
edges = [];
/**
* Creates a graph
* @param username
* @param containerName
* @param progressBarID
*/
function createGameGraphs(username, containerName, progressBarID)
{
progressID = progressBarID;
addSelfToGraph(username).then(()=>
{
$("#" + progressID).html("");
var container = document.getElementById(containerName);
var data =
{
nodes: nodes,
edges: edges
};
network = new vis.Network(container, data, options);
bringUpProfileView(selfData.id);
network.on("click", function (params)
{
if(Number(this.getNodeAt(params.pointer.DOM)) !== NaN)
{
bringUpProfileView(this.getNodeAt(params.pointer.DOM));
}
});
createConnections().then(()=>
{
// $("#" + progressID).html("");
console.log("Finished");
})
}).catch((error)=>
{
//$("#" + graphsTitle).html("Error Fetching Data From API");
// alert("Invalid User");
console.log(error);
});
}

+ 1
- 1
website/js/steamAPI.js View File

@ -31,7 +31,7 @@ function getPersonAPI(userID, suc, err)
function getUserGames(userID, suc, err)
{
//ex: http://localhost:7000/api/repositories/jwflory
const urlpath = APIROOT + "/repositories/" + userID;
const urlpath = APIROOT + "/games/" + userID;
runAjax(urlpath, suc, err);
}

Loading…
Cancel
Save