Source: src/mainfunctions.js

 /**
 * 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();
            }