Source: script.js

$('document').ready(function(){
    var svg = d3.select("#vis");
    var width = svg.node().getBoundingClientRect().width;
    var height = svg.node().getBoundingClientRect().height;


    var network;
    var legend;

    var data = [{value:"miserables.json", text:"Miserables", label: function(d) {return d.id;}},
                {value:"songs.json", text:"Songs", label: function(d) {return d.artist + " - " + d.name;}},
                /*{value:"basic_sample2.graphml", text:"Basic Sample", label: function(d) {return d.id;}},*/
                {value:"social_networks_of_wikipedia.graphml", text:"Wikipedia", label: function(d) {return d.username}},
                {value:"got-graph.graphml", text:"Game of Thrones", label: function(d) {return d.name}},
                {value:"informatik_bachelor.graphml", text:"Informatik Bachelor TU", label: function(d) {return d.id;}},
                {value:"meiste_studien.graphml", text:"LVAs TU Wien", label: function(d) {return d.name;}} /*,
                {value:"connector_example.graphml", text:"Connector Example", label: function(d) {return d.id}},
                {value:"connector_example_2.graphml", text:"Connector Example 2", label: function(d) {return d.id}}*/];

    var select = document.getElementById("dataSelect");

    for(var i = 0; i< data.length; i++) {
        var option = document.createElement("a");
        option.setAttribute("class", "dropdown-item");
        option.setAttribute("value", data[i].value);
        option.label = data[i].label;
        option.innerText = data[i].text;
        select.appendChild(option);
    }

    $('#dataSelect').find('a').on('click', function(){
        var selection = $(this)[0];
        $('#dataSelect').find('.select').each(function(){
            $(this).attr("class", "dropdown-item");
        });

        selection.setAttribute("class", "dropdown-item select");

        document.getElementById('dataText').innerText = ("Data: " + selection.innerText);

        var type = selection.getAttribute("value").split(".");
        type = type[type.length - 1];
        var label = selection.label;

        switch (type) {
            case "json":
                d3.json("data/" + selection.getAttribute("value"), function (error, graph) {
                    if (error) throw error;
                    var nxG = convertGraphToNetworkXFormat(graph);
                    createNetwork(graph, nxG, label);
                });
                break;

            case "graphml":
                d3.xml("data/" + selection.getAttribute("value"), function (error, xml){
                    if (error) throw error;
                    var graph = loadGraphML(xml);
                    var nxG = convertGraphToNetworkXFormat(graph);
                    createNetwork(graph, nxG, label);
                });
                break;

            default:
                console.log("unsupported type");

        }

        if($("#collapseMotifs").hasClass("show")) {
            $("#motifsBtn-hide").trigger("click");
        }
        if ($("#headingLegend").hasClass("show")) {
            $("#legendBtn-show").trigger("click");
        }
    });

    $('#motifSelect').find('a').on('click', function(e) {
        if( (e.target.tagName === "DIV") || (e.target.tagName === "INPUT")) {
            return false;
        }

        var selection = $(this);
        var feather = selection.children(0).children(0).get(0);

        if(selection[0].getAttribute("class").includes("select")) {
            selection[0].setAttribute("class", "dropdown-item motif");
            feather.setAttribute("class", "feather feather-check btn-link collapse");
            if(selection[0].getAttribute("id") !== "fan-select") {
                selection.children(0).get(1).setAttribute("class", "motif-input collapse");
            }

        } else {
            selection[0].setAttribute("class", "dropdown-item motif select");
            feather.setAttribute("class", "feather feather-check btn-link collapse show");
            if(selection[0].getAttribute("id") !== "fan-select") {
                selection.children(0).get(1).setAttribute("class", "motif-input collapse show");
            }
        }
    });

    $('#group-submit').on('click', function(l) {
        var deselect = [];
        deselect[MotifEnum.CLIQUE] = false;
        deselect[MotifEnum.CONNECTOR] = false;
        deselect[MotifEnum.FAN] = false;

        if ($("#clique-select").attr("class").includes("select")) {
            var min = $("#cliqueMin").val();
            var max = $("#cliqueMax").val();
            if (network && min >= 4) {
                deselect[MotifEnum.CLIQUE] = {min: min, max: max};
            }
        } else {
            if (network) {
                deselect[MotifEnum.CLIQUE] = true;
            }
        }

        if ($("#fan-select").attr("class").includes("select")) {
            if (network) {
                deselect[MotifEnum.FAN] = {min: 0, max: 0};
            }
        } else {
            if(network) {
                deselect[MotifEnum.FAN] = true;
            }
        }

        if ($("#connector-select").attr("class").includes("select")) {
            var min = $("#connectorMin").val();
            var max = $("#connectorMax").val();
            if (network && min >= 2) {
                deselect[MotifEnum.CONNECTOR] = {min: min, max: max};
            }
        } else {
            if(network) {
                deselect[MotifEnum.CONNECTOR] = true;
            }
        }

        deselect.forEach(function (value, key) {
            if(value === true) {
                network.collapseMotifs(key, -1, -1);
            }
        });

        deselect.forEach(function (value, key) {
            if(value !== true) {
                network.collapseMotifs(key, value.min, value.max);
            }
        });
        if($("#collapseLegend").hasClass("show")) {
            $("#legendBtn-hide").trigger("click");
        }
        if ($("#headingLegend").hasClass("show")) {
            $("#motifBtn-show").trigger("click");
        }
        setLegend();
    });

    $('#legendBtn-show').on('click', function (l) {
        var element = $('#headingLegend').get(0);
        var classes = element.getAttribute("class");
        var i = classes.indexOf("show");

        if (i) {
            element.setAttribute("class", classes.slice(0, i-1));
            element = $('#collapseLegend').get(0);
            element.setAttribute("class", element.getAttribute("class") + " show");
        }
    });
    $('#motifBtn-show').on('click', function (l) {
        var element = $('#headingLegend').get(0);
        var classes = element.getAttribute("class");
        var i = classes.indexOf("show");

        if (i) {
            element.setAttribute("class", classes.slice(0, i-1));
            element = $('#collapseMotifs').get(0);
            element.setAttribute("class", element.getAttribute("class") + " show");
        }
    });

    $('#legendBtn-hide').on('click', function (l) {
        var element = $('#collapseLegend').get(0);
        var classes = element.getAttribute("class");
        var i = classes.indexOf("show");

        if (i) {
            element.setAttribute("class", classes.slice(0, i-1));
            element = $('#headingLegend').get(0);
            element.setAttribute("class", element.getAttribute("class") + " show");
        }
    });

    $('#motifsBtn-hide').on('click', function (l) {
        var element = $('#collapseMotifs').get(0);
        var classes = element.getAttribute("class");
        var i = classes.indexOf("show");

        if (i) {
            element.setAttribute("class", classes.slice(0, i-1));
            element = $('#headingLegend').get(0);
            element.setAttribute("class", element.getAttribute("class") + " show");
        }
    });

    /**
     * Creates a Network.
     * @param {Object} graph - Graph structure to be visualized.
     * @param {Object} nxGraph - Network X graph structure of graph.
     * @param {Function} label - Function returning the label of a node object.
     */
    function createNetwork(graph, nxGraph, label) {
        var first = true;
        if(network) {
            first = false;
            network.clearNetwork();
        }

        network = new Network(graph, nxGraph, svg, width, height, label);
        svg.selectAll("*").remove();
        network.setUpNetwork(svg);

        var s;
        var k = Object.keys(graph.nodes[0]);
        k.splice(k.indexOf("id"), 1);
        s = "" + k;
        s = s.slice(0, s.indexOf(','));
        s = s.charAt(0).toUpperCase() + s.slice(1);
        setDropDownSelects("colorSelect", k.slice(0, k.length - 5));
        $('#colorSelect a').get(0).setAttribute("class","dropdown-item select");
        network.setColorAttribute(k[0]);
        document.getElementById('colorText').innerText = ("Color by: " + s);
        legend = network.getLegend();
        setLegend();
        if(first) {
            var element = $('#collapseLegend').get(0);
            element.setAttribute("class", element.getAttribute("class") + " show");
        }

        $('#colorSelect').find('a').on('click', function () {
            var selection = $(this)[0];
            $('#colorSelect').find('.select').each(function(){
                $(this).attr("class", "dropdown-item");
            });

            selection.setAttribute("class", "dropdown-item select");

            network.setColorAttribute(selection.getAttribute("value"));
            legend = network.getLegend();
            setLegend();
            var s = selection.innerText.charAt(0).toUpperCase() + selection.innerText.slice(1);
            document.getElementById('colorText').innerText = ("Color by: " + s);
        });
    }

    /**
     * Sets the legend of the graph coloring.
     */
    function setLegend() {
        var legendHTML = d3.select("#collapseLegend");
        legendHTML.selectAll("div.legend-item").remove();

        legendHTML.selectAll("div")
            .data(Object.keys(legend))
            .enter()
            .append("div")
            .attr("class", "legend-item");

        var legendItem = d3.selectAll(".legend-item");

        legendItem.data(Object.keys(legend))
            .append("div")
            .attr("class", "legend-color")
            .style("background", function (d) {
                return legend[d];
            });

        legendItem.data(Object.keys(legend))
            .append("div")
            .attr("class", "legend-label")
            .text(function (d) {
                return d;
            });

        var motifHTML = d3.select("#collapseMotifs");
        motifHTML.selectAll("#clique-container").remove();
        motifHTML.selectAll("#fan-container").remove();
        motifHTML.selectAll("#connector-container").remove();
        motifHTML.selectAll(".legendspacing").remove();


        cl = network.getCliques();
        if (cl != undefined && Object.keys(cl.motifs).length != 0) {
            motifHTML.append("div").attr("id", "clique-container");

            m = cl.motifs;
            d3.select("#clique-container").selectAll("div")
                .data(Object.keys(m))
                .enter()
                .append("div")
                .attr("class", "motif-item clique-item")
                .attr("id", function(d) {
                    return "clique" + d
                })
                .on("click", function(d) {
                    network.toggleGlyph(d);
                })
                .on("mouseover", function(d) {
                    network.highlightMotif(d);
                })
                .on("mouseout", function(d) {
                    network.unlightMotif(d);
                });
            var cliqueItem = d3.selectAll(".clique-item");
            cliqueItem.data(Object.keys(m))
                .append("div")
                .attr("class", "legend-motif-color")
                .style("background", function (d) {
                    return network.getMotifColor(d);
                });
            cliqueItem.data(Object.keys(m))
                .append("div")
                .attr("class", "legend-label")
                .text("Clique")
            Object.keys(m).forEach(function(k) {
                var arr = m[k];
                d3.select("#clique" + k).selectAll(".motif-subitem")
                    .data(arr)
                    .enter()
                    .append("div")
                    .attr("class", "motif-subitem")
                    .text(function(d) {
                        return network.getNodeLabel(d);
                    });
            });
        }

        fn = network.getFans();
        if (fn != undefined && Object.keys(fn.motifs).length != 0) {
            motifHTML.append("div").attr("id", "fan-container");

            m = fn.motifs;
            d3.select("#fan-container").selectAll("div")
                .data(Object.keys(m))
                .enter()
                .append("div")
                .attr("class", "motif-item fan-item")
                .attr("id", function(d) {
                    return "fan" + d;
                })
                .on("click", function(d) {
                    network.toggleGlyph(d);
                })
                .on("mouseover", function(d) {
                    network.highlightMotif(d);
                })
                .on("mouseout", function(d) {
                    network.unlightMotif(d);
                });;
            var fanItem = d3.selectAll(".fan-item");
            fanItem.data(Object.keys(m))
                .append("div")
                .attr("class", "legend-motif-color")
                .style("background", function (d) {
                    return network.getMotifColor(d);
                });
            fanItem.data(Object.keys(m))
                .append("div")
                .attr("class", "legend-label")
                .text("Fan");   
            Object.keys(m).forEach(function(k) {
                var arr = m[k];
                d3.select("#fan" + k).selectAll(".motif-subitem")
                    .data(arr)
                    .enter()
                    .append("div")
                    .attr("class", "motif-subitem")
                    .text(function(d) {
                        return network.getNodeLabel(d);
                    });         
            });
        }

        con = network.getConnectors();
        if (con != undefined && Object.keys(con.motifs).length != 0) {
            motifHTML.append("div").attr("id", "connector-container");

            m = con.motifs;
            d3.select("#connector-container").selectAll("div")
                .data(Object.keys(m))
                .enter()
                .append("div")
                .attr("class", "motif-item connector-item")
                .attr("id", function(d) {
                    return "connector" + d;
                })
                .on("click", function(d) {
                    network.toggleGlyph(d);
                })
                .on("mouseover", function(d) {
                    network.highlightMotif(d);
                })
                .on("mouseout", function(d) {
                    network.unlightMotif(d);
                });;
            var connectorItem = d3.selectAll(".connector-item");
            connectorItem.data(Object.keys(m))
                .append("div")
                .attr("class", "legend-motif-color")
                .style("background", function (d) {
                    return network.getMotifColor(d);
                });
            connectorItem.data(Object.keys(m))
                .append("div")
                .attr("class", "legend-label")
                .text("Connector");     
            Object.keys(m).forEach(function(k) {
                var arr = m[k];
                d3.select("#connector" + k).selectAll(".motif-subitem")
                    .data(arr)
                    .enter()
                    .append("div")
                    .attr("class", "motif-subitem")
                    .text(function(d) {
                        return network.getNodeLabel(d);
                    });         
            });      
        }

        motifHTML.append("div").attr("class", "legendspacing");
    }
});

/**
 * Sets label of the chosen selection.
 * @param {String} id - HTMLElement id of element to append childNodes.
 * @param {Array} keys - Keys.
 */
function setDropDownSelects(id, keys) {
    var htmlElement = document.getElementById(id);
    htmlElement.innerHTML = "";

    for(var i = 0; i< keys.length; i++) {
        var option = document.createElement("a");
        option.setAttribute("class", "dropdown-item");
        option.setAttribute("value", keys[i]);
        option.innerText = keys[i].charAt(0).toUpperCase() + keys[i].slice(1);
        htmlElement.appendChild(option);
    }
}