<commit_before>"use strict";

$("#draw-form").submit(function draw() {
    $("svg").remove();
    $(".last-updated").hide();
    $("#update-button").hide();
    $("#layout-opts").hide();
    $("#node-info").html("");
    $("#show-filter-modal-button").show();

    var cluster = $("#cluster").val();
    var edgeType = $("#edge-type").val();
    var levels = $("#levels").val();
    var layout = $("#layout").val();
    var aggregation = $("#aggregation")
        .change(function() { aggregation = $(this).prop("checked"); update(); })
        .prop("checked");

    var w = $("#canvas").innerWidth(),
        h = $("#canvas").innerHeight();

    var zoom = d3.behavior.zoom()
        .scaleExtent([0.1, 10])
        .on("zoom", function() {
            svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        });
    
    var svg = d3.select("#canvas").append("svg:svg")
        .attr("width", w)
        .attr("height", h)

    svg.append("svg:rect")
        .attr("width", w)
        .attr("height", h)
        .style("fill", "none")
        .style("stroke", "#000")
        .style("pointer-events", "all");

    svg = svg.call(zoom)
        .on("dblclick.zoom", null)
        .append("g");

    var svgPaths = svg.append("g");
    var svgLines = svg.append("g");
    var svgLabels = svg.append("g");
    var svgNodes = svg.append("g");

    var color = d3.scale.category20();
    var size = d3.scale.log();

    var radius = parseInt($("#radius").val());
    
    var graph = new dagre.graphlib.Graph()
        .setGraph({})
        .setDefaultEdgeLabel(function() { return {}; });

    var visibleGraph = graph;
    var filterFunction = undefined;

    switch(layout) {
        case "force-tree":
        case "force":
            var force = d3.layout.force()
                .gravity($("#gravity").val())
                .distance(40)
                .charge($("#charge").val())
                .size([w, h]);
            
            var isForceRunnnig = true;
            $("#pause-force-layout").click(function(e) {
                if (isForceRunnnig) {
                    force.stop();
                } else {
                    force.resume();
                }
                isForceRunnnig = !isForceRunnnig;
            });

            var drag = force.drag()
                .on("dragstart", function(d) { 
                    isForceRunnnig = true;
                    d3.event.sourceEvent.stopPropagation();
                })
                .on("dragend", function(d) { 
                    if (d3.event.sourceEvent.shiftKey) {
                        d.fixed = !d.fixed;
                    }
                    force.start();
                });
                

            $("#layout-opts").show();

            $("#gravity") .change(function() { force.gravity(this.value);     update(); });
            $("#charge")  .change(function() { force.charge(this.value);      update(); });
            $("#radius")  .change(function() { radius = parseInt(this.value); update(); });
            break;
        case "dagre":
            break;
    }

    d3.json("/neo?levels=" + levels + "&type=" + edgeType + "&cluster=" + cluster, load);

    function update() {
        var visibleGraph = filterFunction? smartFilter(graph, filterFunction): graph;

        if (aggregation) {
            visibleGraph = aggregate(visibleGraph);
        }
        
        var nodes = visibleGraph.getNodes(),
            links = visibleGraph.getLinks(),
            labeledLinks = links.filter(function(d) { return d.target.number && d.target.number > 1; });

        var link = svgLines.selectAll("line.link")
            .data(links, function(d) { return d.source.id + "-" + d.target.id; });

        link.enter().insert("line")
            .attr("class", "link");

        link.exit().remove();

        var label = svgLabels.selectAll("text.label")
            .data(labeledLinks, function(d) { return d.source.id + "-" + d.target.id + "-n" + d.target.number;  });

        label.enter().insert("text")
            .attr("class", "label")
            .text(function(d) { return d.target.number; });

        label.exit().remove();

        var node = svgNodes.selectAll("g.node")
            .data(nodes, function(d) { return d.id;});

        var nodeEnter = node.enter().append("g")
            .attr("class", "node")
            .on("click", handleClick)
            .on("dblclick", dblclick);

        nodeEnter.append("circle")
            .style("fill", function(d) { return color(d.type); })
            .style("stroke", function(d) { return d.size? "green": "red" });
            
        var circle = svg.selectAll("circle")
            .attr("r", function(d) {
            return 3 * Math.log(d.size + 1) + radius;
        });   

        nodeEnter.append("text")
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .text(function(d) { return d.type; });
        
        node.exit().remove();

        var tick = function tick(e) {

            if (layout === "force-tree") {
                var k = 10 * e.alpha;
                
                // groups.forEach(function(group) {
                //     var nodes = group.values;
                //     for (var i = 1; i < nodes.length; ++i) {
                //         var dx = nodes[i].x - nodes[0].x;
                //         var dy = nodes[i].y - nodes[0].y;
                //         nodes[i].x -= k * dx / Math.abs(dx);
                //         nodes[i].y -= k * dy / Math.abs(dy);
                //     }
                // });

                links.forEach(function(link) {
                    link.source.y -= k;
                    link.target.y += k;
                });


                var group = svgPaths.selectAll("path")
                    .data(groups)
                        .attr("d", groupPath)
                    .enter().insert("path", "circle")
                        .style("fill", groupFill)
                        .style("stroke", groupFill)
                        .style("stroke-width", radius * 6)
                        .style("stroke-linejoin", "round")
                        .style("opacity", .2)
                        .attr("d", groupPath);

                group.exit().remove();
            }            <commit_msg>Fix bug with force-tree layout<commit_after>"use strict";

$("#draw-form").submit(function draw() {
    $("svg").remove();
    $(".last-updated").hide();
    $("#update-button").hide();
    $("#layout-opts").hide();
    $("#node-info").html("");
    $("#show-filter-modal-button").show();

    var cluster = $("#cluster").val();
    var edgeType = $("#edge-type").val();
    var levels = $("#levels").val();
    var layout = $("#layout").val();
    var aggregation = $("#aggregation")
        .change(function() { aggregation = $(this).prop("checked"); update(); })
        .prop("checked");

    var w = $("#canvas").innerWidth(),
        h = $("#canvas").innerHeight();

    var zoom = d3.behavior.zoom()
        .scaleExtent([0.1, 10])
        .on("zoom", function() {
            svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        });
    
    var svg = d3.select("#canvas").append("svg:svg")
        .attr("width", w)
        .attr("height", h)

    svg.append("svg:rect")
        .attr("width", w)
        .attr("height", h)
        .style("fill", "none")
        .style("stroke", "#000")
        .style("pointer-events", "all");

    svg = svg.call(zoom)
        .on("dblclick.zoom", null)
        .append("g");

    var svgPaths = svg.append("g");
    var svgLines = svg.append("g");
    var svgLabels = svg.append("g");
    var svgNodes = svg.append("g");

    var color = d3.scale.category20();
    var size = d3.scale.log();

    var radius = parseInt($("#radius").val());
    
    var graph = new dagre.graphlib.Graph()
        .setGraph({})
        .setDefaultEdgeLabel(function() { return {}; });

    var visibleGraph = graph;
    var filterFunction = undefined;

    switch(layout) {
        case "force-tree":
        case "force":
            var force = d3.layout.force()
                .gravity($("#gravity").val())
                .distance(40)
                .charge($("#charge").val())
                .size([w, h]);
            
            var isForceRunnnig = true;
            $("#pause-force-layout").click(function(e) {
                if (isForceRunnnig) {
                    force.stop();
                } else {
                    force.resume();
                }
                isForceRunnnig = !isForceRunnnig;
            });

            var drag = force.drag()
                .on("dragstart", function(d) { 
                    isForceRunnnig = true;
                    d3.event.sourceEvent.stopPropagation();
                })
                .on("dragend", function(d) { 
                    if (d3.event.sourceEvent.shiftKey) {
                        d.fixed = !d.fixed;
                    }
                    force.start();
                });
                

            $("#layout-opts").show();

            $("#gravity") .change(function() { force.gravity(this.value);     update(); });
            $("#charge")  .change(function() { force.charge(this.value);      update(); });
            $("#radius")  .change(function() { radius = parseInt(this.value); update(); });
            break;
        case "dagre":
            break;
    }

    d3.json("/neo?levels=" + levels + "&type=" + edgeType + "&cluster=" + cluster, load);

    function update() {
        var visibleGraph = filterFunction? smartFilter(graph, filterFunction): graph;

        if (aggregation) {
            visibleGraph = aggregate(visibleGraph);
        }
        
        var nodes = visibleGraph.getNodes(),
            links = visibleGraph.getLinks(),
            labeledLinks = links.filter(function(d) { return d.target.number && d.target.number > 1; });

        var link = svgLines.selectAll("line.link")
            .data(links, function(d) { return d.source.id + "-" + d.target.id; });

        link.enter().insert("line")
            .attr("class", "link");

        link.exit().remove();

        var label = svgLabels.selectAll("text.label")
            .data(labeledLinks, function(d) { return d.source.id + "-" + d.target.id + "-n" + d.target.number;  });

        label.enter().insert("text")
            .attr("class", "label")
            .text(function(d) { return d.target.number; });

        label.exit().remove();

        var node = svgNodes.selectAll("g.node")
            .data(nodes, function(d) { return d.id;});

        var nodeEnter = node.enter().append("g")
            .attr("class", "node")
            .on("click", handleClick)
            .on("dblclick", dblclick);

        nodeEnter.append("circle")
            .style("fill", function(d) { return color(d.type); })
            .style("stroke", function(d) { return d.size? "green": "red" });
            
        var circle = svg.selectAll("circle")
            .attr("r", function(d) {
            return 3 * Math.log(d.size + 1) + radius;
        });   

        nodeEnter.append("text")
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .text(function(d) { return d.type; });
        
        node.exit().remove();

        var tick = function tick(e) {

            if (layout === "force-tree") {
                var k = 10 * e.alpha;
                
                // groups.forEach(function(group) {
                //     var nodes = group.values;
                //     for (var i = 1; i < nodes.length; ++i) {
                //         var dx = nodes[i].x - nodes[0].x;
                //         var dy = nodes[i].y - nodes[0].y;
                //         nodes[i].x -= k * dx / Math.abs(dx);
                //         nodes[i].y -= k * dy / Math.abs(dy);
                //     }
                // });

                links.forEach(function(link) {
                    link.source.y -= k;
                    link.target.y += k;
                });


                var group = svgPaths.selectAll("path")
                    .data(groups)
                    .attr("d", groupPath);
                
                group.enter()
                    .insert("path", "circle")
                    .style("fill", groupFill)
                    .style("stroke", groupFill)
                    .style("stroke-width", radius * 6)
                    .style("stroke-linejoin", "round")
                    .style("opacity", .2)
                    .attr("d", groupPath);

                group.exit().remove();
            }            
{'fraction_non_alphanumeric': 0.18015604066514304, 'fraction_numerical': 0.005201355504767909, 'mean_word_length': 1.4853113983548767, 'pattern_counts': {'":': 8, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4071154', 'n_tokens_mistral': 3714, 'n_tokens_neox': 3540, 'n_words': 667}