NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Storium Usergraph // @namespace usergraph.storium.com // @description Graph users and games in storium // @include https://storium.com/user/* // @version 1.4.0 // @require https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.0/vis.min.js // @resource vis_CSS https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.0/vis.min.css // @resource font_CSS http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css // @grant GM_addStyle // @grant GM_getResourceText // @grant GM_getValue // @grant GM_setValue // ==/UserScript== var data={}; // Primary data for the graph var network; // Insert CSS info for the graph // var vis_CssSrc = GM_getResourceText ("vis_CSS"); var font_CssSrc = GM_getResourceText ("font_CSS"); GM_addStyle (vis_CssSrc); GM_addStyle (font_CssSrc); // ----------------------- // // Get url and user details // var aryURL = window.location.href.split("/"); var user = aryURL[aryURL.length -1].trim().toLowerCase(); // ----------------------- // function buildUserObject() { var objUser = {}; var games = []; var gameSlugs = []; objUser.id = user; objUser.updated = new Date(); $('table.profile-table a').each(function() { var href = $(this).prop("href"); var name = $(this).text(); if (href.indexOf("/game/") !== -1) { var aryGameURL = href.split("/"); var gameSlug = aryGameURL[aryGameURL.length -1].trim().toLowerCase() var objGame = {}; objGame.name = name; objGame.slug = gameSlug; objGame.url = href; if (gameSlugs.indexOf(objGame.slug) == -1) { gameSlugs.push(objGame.slug); games.push(objGame); } } }); objUser.games = games; return objUser; } function loadData() { var strIn = GM_getValue("data",""); data = {}; if (strIn!="") { data = JSON.parse(strIn); } } function saveData() { GM_setValue("data",JSON.stringify(data)); } function removeUser(strUser) { delete data[strUser]; } function main() { console.log("Start script: Storium Usergraph"); loadData(); switch (user) { case "usergraph": drawGraph(data); break; case "usergraph-dot": drawGraph(data,"dot"); break; case "cleardata": clearData(); break; case "": break; default: var objUser = buildUserObject(); data[objUser.id] = objUser; saveData(); break; } console.log("End script: Storium Usergraph"); } function clearData() { data = {}; saveData(); $('body div').remove(); $('body').append("<div id='graphData' style='width: 100%; height: 100%; border: thin solid gray;'>Graph Data Cleared!</div>"); } function graphRefresh() { drawGraph(data); } function setButtons() { console.log("Settign Buttons"); var arySelected = network.getSelectedNodes(); if (arySelected.length > 0 && arySelected[0].substr(0,1) == "@") { console.log("disab"); $("#deleteNode").removeAttr("disabled"); } else { console.log("enab"); $("#deleteNode").attr("disabled","disabled"); } } function drawGraph(data, mode) { $('body div').remove(); $('body').append("<div id='mynetwork' style='width: 100%; height: 100%; border: thin solid gray;'></div>"); if (mode === undefined) { mode = "graph"; } if (mode==="graph") { $('body').append("<i id='statusFlag' class='fa fa-flag' style='color: green; position: absolute; top: 0px; left: 0px;'></i>"); } // create an array with nodes var nodes = []; var nodeNames = []; var nodeReserve = {}; // create an array with edges var edges = []; for (var userID in data) { var objUser = data[userID]; if (objUser.games.length > 0) { nodes.push({id: '@' + objUser.id, label: '@' + objUser.id, group: 'user'}); var arrayLength = objUser.games.length; for (var i = 0; i < arrayLength; i++) { var game = objUser.games[i]; if (nodeNames.indexOf(game.slug) == -1) { if (nodeReserve[game.slug] != undefined) { nodeNames.push(game.slug); nodes.push({id: game.slug, title: game.name, group: 'game'}); edges.push(nodeReserve[game.slug]); edges.push({from: '@' + objUser.id, to: game.slug }); } else { nodeReserve[game.slug] = {from: '@' + objUser.id, to: game.slug }; } } else { edges.push({from: '@' + objUser.id, to: game.slug }); } } } } switch (mode) { case "graph": // Add delete buttons var $btnPanel = $("<div style='position: absolute; top: 5px; right:5px; border: thin solid black' id='divBtn'></div>"); var $btnDel = $("<button id='deleteNode' disabled='disabled'>Delete</button>"); var $btnSave = $("<button id='saveNodes'>Save</button>"); var $btnRedraw = $("<button id='redrawNodes'>Redraw</button>"); $btnRedraw.click(function() { graphRefresh(); }); $btnSave.click(function() { saveData(); $('#statusFlag').css("color","green"); }); $btnDel.click(function() { var arySelected = network.getSelectedNodes(); if (arySelected.length > 0 && arySelected[0].substr(0,1) == "@") { var strUser = arySelected[0].substr(1); console.log("Deleting user: " + strUser); $('#statusFlag').css("color","red"); removeUser(strUser); network.deleteSelected(); } }); $btnPanel.append($btnDel); $btnPanel.append($btnSave); $btnPanel.append($btnRedraw); $("body").append($btnPanel); // create a network var container = document.getElementById('mynetwork'); // provide the data in the vis format var dataIn = { nodes: new vis.DataSet(nodes), edges: new vis.DataSet(edges) }; var options = { groups: { user: {color:{background:'red'}, mass: 10, shape: 'icon', icon: { face: 'FontAwesome', code: '\uf0c0', color: 'green' } }, game: {shape: "dot" } }, "edges": { "smooth": { "forceDirection": "none" } }, "physics": { "barnesHut": { "damping": 0.45, "avoidOverlap": 0.25 }, "minVelocity": 0.5 }, "layout": {"improvedLayout": false} } // initialize your network! network = new vis.Network(container, dataIn, options); network.on("selectNode", function() { setButtons() } ); network.on("deselectNode", function() { setButtons() } ); break; case "dot": var strDot = ""; strDot += "graph G {\n" for (var i = 0; i < nodes.length; i++) { var objNode = nodes[i]; strDot += " \"" + objNode.id + "\" [" switch (objNode.group) { case "user": strDot += "style=filled,color=green,label=\"" + objNode.label + "\"" break; case "game": strDot += "label=\"" + objNode.title + "\"" break; } strDot += "];\n" } for (var i = 0; i < edges.length; i++) { var objEdge = edges[i]; strDot += " \"" + objEdge.from + "\" -- \"" + objEdge.to + "\";\n" } strDot += "}" var $pre = $("<pre id='dotCode'></pre>").html(strDot); $('#mynetwork').append($pre); break; default: } } main();