Source: Community_AutocorrelationBased.js

/**
 * This function calculates the autocorrelation based metric for communities. This metric measures the amount of visual
 * overlap between the different communities by taking the community label of the central node into account. It is calculated
 * for every node of the graph and all neighboring nodes inside a given square determined by the filerArea are taken into account
 * for the calculation. When all the nodes, surrounding the currently chosen node, come from the same community, then the calculated
 * metric value is 0, which indicates a perfect preservation of the community structure. However, when nodes, surrounding the currently
 * chosen node, come from different communities, the closer the nodes are to the chosen one, the more community structure degrades.
 * @param {Array} nodes contains all nodes of the graph
            <p>var nodes = [ </p>
                        <p>id: "id1"</p>
                        <p>index: 0</p>
                        ​​​<p>module: 0</p>
                        <p>​​​​px: 453.8701275147519</p>
                        <p>​​​​py: 136.9204945170503</p>
                        <p>​​​​weight: 13</p>
                        <p>​​​​x: 453.8623762824847</p>
                        <p>​​​​y: 136.32544736132093;</p>
                        <p> ]</p>
 <p>any type of string can be used as id</p>
 * @param {number} N is the amount of nodes in the graph
 * @param {number} filterArea is the size of the area around the node
 * @returns {Array} array of objects which contains the calculated metric for every node
 */
function Community_AutocorrelationBased(nodes, N, filterArea)
{
    var region = filterArea;
    var avgCommunityDist = 0;
    var dataPoints = [];
    var a = 0;
    var minCom = Infinity;

    for (var node in nodes) {

        var nodesInsideRegion = [];
        a = a+1;

        for (var n in nodes) {

            if ((nodes[n].x <= nodes[node].x + region) && (nodes[n].x >= nodes[node].x - region)
                && (nodes[n].y <= nodes[node].y + region) && (nodes[n].y >= nodes[node].y - region)) {

                nodesInsideRegion.push(nodes[n]);

            }
        }

        var communityDistribution = 0; //community distribution for one node inside a region

        for (var i in nodesInsideRegion)
        {
            //calculate normalized distance between node "node" and node "n"
            var xDist = Math.abs(nodes[node].x - nodesInsideRegion[i].x);
            var yDist = Math.abs(nodes[node].y - nodesInsideRegion[i].y);
            var normDist = Math.sqrt( xDist*xDist + yDist*yDist );

            //check whether they belong to the same community
            var sameCommunity = 1;
            if(nodes[node].module === nodesInsideRegion[i].module)
            {
                //belong to the same community -> then set to 0
                sameCommunity = 0;
            }

           communityDistribution = communityDistribution + (((1-normDist)*sameCommunity) / (1-normDist));
            if(communityDistribution < minCom)
            {
                minCom = communityDistribution;
            }
        }


        //store the calculated community distribution for displaying on the heat map
        dataPoints[a] = {
            x: nodes[node].x,
            y: nodes[node].y,
            comDistr: communityDistribution
        };

        avgCommunityDist = avgCommunityDist + communityDistribution;
        nodesInsideRegion = []; //reset region for next iteration
    }

    avgCommunityDist = avgCommunityDist/N;

    dataPoints[0] = {
        x: 0,
        y: 0,
        comDistr: minCom//avgCommunityDist
    };

    return dataPoints;
}