/**
* Inits global data variables
*/
/** Initiates the global variables
*/
function InitGlobalDataVariables() {
pointsSet = undefined;
previousColor = [];
previoslyhoveredNode = undefined;
selectedPropertyIndex = undefined;//holds the index of the most recently selected numerical property (by the user)
previousColor = [];//used in resume colors
searchExprWellDefined = undefined;
allNodes = [];
foundNodes = [];
}
/**Is called when the user selects a file to upload */
function LoadLocalDataSet() {
var x = document.getElementById("dataFile");
var txt = "";
if ('files' in x) {
if (x.files.length == 0) {
txt = "Select a file.";
} else {
var file = x.files[0];
LoadDataFromFile(file);
}
}
}
/** Loads data from file and makes initializations necessary to render data points
@param {file} file - The file selected by the user
*/
function LoadDataFromFile(file) {
var reader = new FileReader();
reader.readAsText(file);
reader.onloadend = function (e) {
var contents = e.target.result;
InitGlobalDataVariables();
var data = JSON.parse(contents);
defineCombo(data);
InitDrawing(data);
loadFirstTime = false;
}
}
/** Initializes rendering frame and draws the graph in an initial scene
* @param {dictionary} data - The dictionary of points as loaded from the json file
*/
function InitDrawing(data) {
LoadDataInGraph(data);
if (loadFirstTime) {
renderFrame = graph.renderIn("frame");
}
redrawInitialScene();
}
/** Initializes the check boxes and the event handlers for the checkboxes */
function InitEventHandlers() {
sizeAtShow.checked = true;
show_popup.checked = true;
show_found_nodes.checked = false;
sizeAtShow.onchange = function () {
HandleSizeAttenuationChange();
}
show_found_nodes.onchange = function () {
HandleShowFoundNodesChange();
}
}
/** What to do when the user clicks on the size attenuation box */
function HandleSizeAttenuationChange()
{
var sizeAtBool = sizeAtShow.checked;
if (sizeAtBool) {
size_attenuation = true;
node_size = 0.016;
}
else {
size_attenuation = false;
node_size = 10;
}
redrawSameScene();
}
/** What to do when the "show found nodes" box is changed */
function HandleShowFoundNodesChange()
{
if (show_found_nodes.checked) {
LoadOnlyFoundNodes();
}
else {
LoadAllNodes();
}
redrawSameScene();
}
/** Loads only the points that result from a search in the graph. At least 15 nodes are loaded, however. */
function LoadOnlyFoundNodes() {
RemoveAllNodes();
for (var i = 0; i < foundNodes.length; i++) {
graph.addNode(foundNodes[i]);
}
var n = graph.getNodes().length;
//cause it does not work well for a small amount of nodes (problem with the graphics)
if (n < 15)
{
for (var i = 0; i < 15 - n; i++)
{
graph.addNode(allNodes[i]);
}
}
}
/** Loads all points from the data file in the graph */
function LoadAllNodes() {
for (var i = 0; i < allNodes.length; i++) {
graph.addNode(allNodes[i]);
}
}
/**Initializes the graph */
function InitializeGraph() {
return G.graph({
sizeAttenuation: size_attenuation,//whether to change the size of the nodes for a 3D effect or not
nodeImage: "imgs/disc.png",
nodeImageTransparent: true,
antialias: true,
bgColor: 'lightgrey',//'lightskyblue',
nodeSize: node_size,//10,//0.016,//change to 10 if sizeAttenuation = false, otherwise the nodes are too small and not visible
edgeWidth: 0.005,//change to 1 if sizeAttenuation = false. Update 11/10/2016: This should be programmed.
hover: function (node) {//what should happen when a user hovers over a node with the mouse
HandleNodeHovering(node);
}/*,
mousedown: function (node) {//what should happen when a user clicks on a node. Disabled at the moment
HandleNodeClicking(node);
}*/
});
}
/** Defines what happens when a user hovers over a node (point)
* @param {Graph.node} node - a node from the graph that was hovered over
*/
function HandleNodeHovering(node) {
if (previoslyhoveredNode != undefined)//if some node was hovered before, return its color
{ previoslyhoveredNode.setColorHex("#" + previosHoveredcolor); }
previosHoveredcolor = node.getColor();
previoslyhoveredNode = node;
node.setColor("white");//make hovered node white
redrawSameScene();
var categories = node._categoriesValues;
var text = node.getId(); //+ "<br>" + props[0] + "<br>" + props[2] + "<br>" + props[4]
//if (node._expandable) { text = "Click to open! <br> " + text; }
if (show_popup.checked) {
$("#label").text("");
for (var i = 0; i < categories.length; i++) { text += "<br>" + categories[i]; }
myPop.attachHTML(text);
myPop.show(cursorX, cursorY, 0, 0); //params are: x, y, width, height. 3 and 5 are number of pixels relative to the node where the message should appear(you can play with these numbers)
}
else {
for (var i = 0; i < categories.length; i++) { text += " ; " + categories[i]; }
$("#label").text("Point info: " + text);
}
}
/** Prepares the initial colors of the points based on their coordinates. Optional.
* @param {list} coords - The three coordinates of the point
*/
function PrepareColorZero(coords) {
var red = Math.floor((coords[0] * coords[0] * 1643 % 256) + 1);
var green = Math.floor((coords[1] * coords[1] * 328 % 256) + 1);
var blue = Math.floor((coords[2] * coords[2] * 487 % 256) + 1);
return "rgb(" + red + "," + green + "," + blue + ")";
}
/** Takes a point from data and makes a node of the graph out of it
* @param {list} data - a list of points
* @param {string} key - the id of the point
* @param {string} colorpoint - the desired color of the point
*/
function PrepareNodeAndAddIt(data, key, colorPoint) {
var point = data[key];
var pointid = key;
var coords = point.Coordinates;
var nodecategories = point.Categories;
var nodeProperties = point.Properties;
var node = G.node(coords, {
id: pointid,
categoriesValues: nodecategories,
propertiesValues: nodeProperties,
color: colorPoint,
});
node.addTo(graph);
var node = graph.getNode(key);
node.setColor(colorPoint);
}
/**Loads all data in the graph
* @param {dictionary} data - the data as loaded from the json file
*/
function LoadDataInGraph(data) {
RemoveAllNodes();
var level = 0;
for (var key in data) {
if (key != "NamesOfProperties") {
AddNode(data, key);
}
}
var nodes = graph.getNodes();
for (var i = 0 ; i < nodes.length; i++)
{
allNodes.push(nodes[i]);
}
}
/**Adds a node from data into the graph
* @param {dictionary} data - the data as loaded from the json file
* @param {string} key - the ID of the node
*/
function AddNode(data, key) {
var point = data[key];
var coords = point.Coordinates;
var colorNode = PrepareColorZero(coords);
PrepareNodeAndAddIt(data, key, colorNode);
}
/**
* Removes all nodes from the graph. The graph is empty afterwards
*/
function RemoveAllNodes() {
var numberOfNodes = graph.getNodes().length;
for (var i = 0; i < numberOfNodes; i++) {
graph.removeLastNode();
}
}
/** Colorizes the nodes in different shades of a certain color based on intensity of a property
* @param {Three.color} col - the color in which to colorize
* @param {indexOfProperty} - the index of the property based on which to colorize
*/
function Colorize(col, indexOfProperty)//colorizes the nodes that are already loaded in the graph.
{
// init max and min value of property accross nodes
var max = graph._nodes[0]._propertiesValues[indexOfProperty];
var min = max;
for (var i = 0; i < graph._nodes.length; i++) {
var value = graph._nodes[i]._propertiesValues[indexOfProperty];
if (value > max) { max = value; }
if (value < min) { min = value; }
}
var range = max - min;
//find the max intensity for red or blue or green
var maxColor = col[1][0];
if (col[1][1] > maxColor) { maxColor = col[1][1]; }
if (col[1][2] > maxColor) { maxColor = col[1][2]; }
//adjust the RGB components
var redNew = col[1][0];
var greenNew = col[1][1];
if (maxColor > 0) {
var factor = 255 / maxColor;
redNew = factor * col[1][0];
greenNew = factor * col[1][1];
blueNew = factor * col[1][2];
}
//colorize the nodes with different shades of the color, according to the selected property intensity
for (var i = 0; i < graph._nodes.length; i++) {
var node = graph._nodes[i];
var value = node._propertiesValues[indexOfProperty];
var red = col[1][0];
var green = col[1][1];
var blue = col[1][2];
if (range > 0) {
red = Math.floor(redNew * (value - min) / range);
green = Math.floor(greenNew * (value - min) / range);
blue = Math.floor(blueNew * (value - min) / range);
}
var color = "rgb(" + red + "," + green + "," + blue + ")";
ChangeColor(node, color);
}
redrawSameScene();
}
/** Redraws the graph in the same scene. The position of the camera will not change. */
function redrawSameScene() {
if (size_attenuation) {
renderFrame.reDrawMeInSameScene();
}
else { renderFrame.reDrawMeInSameSceneWithoutSizeAttenuation();}
}
/** Redraws the graph in the initial scene. The camera is re-positioned to look at all points */
function redrawInitialScene() {
if (size_attenuation) {
renderFrame.reDrawMe();
}
else { renderFrame.reDrawMeWithoutSizeAttenuation(); }
}
/** Changes the color of a node
* @param {Graph.node} node - the node that changes color
* @param {Three.color} color - the new color of the node*/
function ChangeColor(node, color) {
var id = node.getId();
previousColor[id] = node.getColor();
node.setColor(color);
}
/** Returns the color of a node to its previous color
* * @param {Graph.node} node - the node that changes color
*/
function ReturnPreviousColor(node) {
var id = node.getId();
var color = previousColor[id];
if (color != undefined) {
node.setColorHex("#" + color);
}
}
/** Returns the color of all nodes to their previous colors
*/
function ReturnAllColors() {
var nodes = graph.getNodes();
for (var i = 0; i < nodes.length; i++) {
ReturnPreviousColor(nodes[i]);
}
redrawSameScene();
}