Source: communicator.js

/**
 * Handles the communication between client and server.
 * @module Communicator
 */

/**
 * Provides the server with the cluster features and the number of clusters.
 * Then pulls the cluster result from the server
 *
 * @param {function} dataReceivedCallback Function that is called when the cluser result was received
 */
function getSupernodesFromServer(dataReceivedCallback) {
    $.post("/setClusterFeatures", {
        features: selectedClusterFeatures,
        noClusters: guiController.clusters,
    });

    $.get("/getSupernodes", function (clusters) {
        try {
            clusterResult = $.parseJSON(clusters);
            allSupernodes = clusterResult["supernodes"];
            //TODO: remove edgeMatrices since we only render the low detail view as default
            //edgeMatrices = clusterResult["edgeMatrices"]
            lowDetailSuperNodeEdgeMatrices = clusterResult["lowDetailSuperNodeEdgeMatrices"];
            lowDetailSuperNodePositionsMultipleEdgeSets = clusterResult["lowDetailSuperNodePositions"];
            console.log("recieved supernodes from server");
            if (dataReceivedCallback != undefined) {
                dataReceivedCallback();
            }
        }
        //print the error message sent by the server
        catch (err) {
            console.log(err);
            console.log(clusters);
        }
    })
}

/**
 * Provides the server with the IDs of the selected supernodes
 * Then pulls the edge matrices and wordClouds for these supernodes from the server.
 *
 * @param {function} dataReceivedCallback Function that is called when the edge matrices were received
 */
function getEdgesOfSelectedSupernodesFromServer(dataReceivedCallback) {
    //we only need to send the IDs of the selected supernodes
    let selectedSNodesIDs = [];
    supernodes.forEach(function (supernode) {
        if (supernode == undefined) {
            console.log("PLEASE WAIT. SUPERNODES ARE NOT JET COMPUTED!");
            return;
        }
        selectedSNodesIDs.push(supernode.id);
    })

    $.post("/setSelectedSupernodes", {
        selectedSNodes: selectedSNodesIDs,
    });

    $.get("/getEdgeMatricesOfSelectedSupernodes", function (eMatrices) {
        try {
            edgeMatrices = $.parseJSON(eMatrices);
            console.log("recieved edgeMatrices from server");
            if (dataReceivedCallback != undefined)
                dataReceivedCallback();
        }
        //print the error message sent by the server
        catch (err) {
            console.log(err);
            console.log(eMatrices);
        }
    })

    generateWordCloudsOnServer(createWordCloudRenderObjects);
}


/**
 * Provides the server with the word Cloud attribute.
 * Then loads the the wordClouds.
 *
 * @param {function} dataReceivedCallback Function that is called after all wordClouds were loaded
 */
function generateWordCloudsOnServer(dataReceivedCallback) {

    $.post("/setWordCloudAttribute", {
        wCAttribute: wordCloudAttribute
    });

    $.get("/getWordCloudsOfSelectedSupernodes", function (wCloudIDs) {
        try {
            var wordCloudIDs = $.parseJSON(wCloudIDs);
            console.log("recieved wordCloudIDs from server");

            wordCloudMaterials = {}
            loadWordClouds(wordCloudIDs, dataReceivedCallback);
        
        }
        //print the error message sent by the server
        catch (err) {
            console.log(err);
            console.log(wCloudIDs);
        }
    })
}


/**
 * loads all wordClouds into Three.Materials
 *
 * @param {array} wordCloudIDs
 * @param {function} materialLoadedCallback Function that is called after all wordClouds were loaded
 */
async function loadWordClouds(wordCloudIDs, materialLoadedCallback) {
    // map array to promises
    const promises = wordCloudIDs.map(loadWordCloudTexture);
    // wait until all promises are resolved
    await Promise.all(promises);
    console.log("generated wordCloud materials");
    if (materialLoadedCallback != undefined) {
        materialLoadedCallback();
    }
}

/**
 * loads a wordClouds image from the disk into a Three.Material
 *
 * @param {Number} wordCloudID
 * @returns a promise to load a word cloud texture and create a material
 */
async function loadWordCloudTexture(wordCloudID) {
    return new Promise(resolve => loader.load(
        // resource URL
        'http://localhost:5000/get_wordCloud/' + wordCloudAttribute + "_" + wordCloudID + '.png',

        // onLoad callback
        function (texture) {
            wordCloudMaterials[wordCloudID] = new THREE.MeshBasicMaterial({
                map: texture,
                transparent: true
            });
            resolve();
        }
    ));
}