<commit_before>// version 0.1
(function () {
    /**
     * vanilla JS implementation
     * of jQuery.extend()
     */
    d3._extend = function (defaults, options) {
        var extended = {},
            prop;
        for (prop in defaults) {
            if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
                extended[prop] = defaults[prop];
            }
        }
        for (prop in options) {
            if (Object.prototype.hasOwnProperty.call(options, prop)) {
                extended[prop] = options[prop];
            }
        }
        return extended;
    };

    /**
     * converts strings like "10px" to 10
     */
    d3._pxToNumber = function (val) {
        return parseFloat(val.replace('px'));
    };

    /**
     * gets window height
     */
    d3._windowHeight = function () {
        return window.innerHeight || document.documentElement.clientHeight || 600;
    };

    /**
     * netjsongraph.js main function
     */
    d3.netJsonGraph = function(url, opts) {
        // default options, overridable
        opts = d3._extend({
            el: "body",
            metadata: true,
            defaultStyle: true,
            tooltipDelay: 300,
            scaleExtent: [0.25, 5],
            charge: -130,
            linkDistance: 40,
            linkStrength: 0.2,
            friction: 0.9,  // d3 default
            chargeDistance: Infinity,  // d3 default
            theta: 0.8,  // d3 default
            gravity: 0.1,
            // by default, high density areas have longer links
            linkDistanceFunc: function(d){
                var val = opts.linkDistance;
                if (d.source.linkCount >= 4 && d.target.linkCount >= 4) {
                    return val * 2;
                }
                return val;
            },
            // called on zoom and pan
            redraw: function () {
                panner.attr("transform", "translate(" + d3.event.translate + ") " +
                                         "scale(" + d3.event.scale + ")");
                tooltip.style("visibility", "hidden");
            },
            /**
             * converts NetJSON NetworkGraph
             * to the data structure consumed by d3
             */
            prepareData: function(graph) {
                var nodesMap = {},
                    nodes = graph.nodes.slice(), // copy
                    links = graph.links.slice(), // copy
                    nodes_length = graph.nodes.length;
                links_length = graph.links.length;
                for (var i = 0; i < nodes_length; i++) {
                    // count how many links every node has
                    nodes[i].linkCount = 0;
                    nodesMap[nodes[i].id] = i;
                }
                for (var c = 0; c < links_length; c++) {
                    var sourceIndex = nodesMap[links[c].source],
                        targetIndex = nodesMap[links[c].target];
                    // ensure source and target exist
                    if (!nodes[sourceIndex]) { throw("source '" + links[c].source + "' not found"); }
                    if (!nodes[targetIndex]) { throw("target '" + links[c].target + "' not found"); }
                    links[c].source = sourceIndex;
                    links[c].target = targetIndex;
                    // add link count to both ends
                    nodes[sourceIndex].linkCount++;
                    nodes[targetIndex].linkCount++;
                }
                return { "nodes": nodes, "links": links };
            },
            /**
             * called when a node is clicked
             */
            onClickNode: function (n) {
                var html = "<p><b>id</b>: " + n.id + "</p>";
                if (n.label) { html += "<p><b>label</b>: " + n.label + "</p>"; }
                if (n.properties) {
                    for (key in n.properties) {
                        if (!n.properties.hasOwnProperty(key)) { continue; }
                        key = key.replace("_", " ");
                        html += "<p><b>"+key+"</b>: " + n.properties[key] + "</p>";
                    }
                }
                if (n.linkCount) { html += "<p><b>links</b>: " + n.linkCount + "</p>"; }
                overlayInner.html(html);
                overlay.style("display", "block");
                // set "open" class to current node
                removeOpenClass();
                d3.select(this).attr("class", "njg-node njg-open");
            },
            /**
             * called when a node is clicked
             */
            onClickLink: function (l) {
                var html = "<p><b>source</b>: " + (l.source.label || l.source.id) + "</p>";
                html += "<p><b>target</b>: " + (l.target.label || l.target.id) + "</p>";
                html += "<p><b>cost</b>: " + l.cost + "</p>";
                if (l.properties) {
                    for (key in l.properties) {
                        if (!l.properties.hasOwnProperty(key)) { continue; }
                        key = key.replace("_", " ");
                        html += "<p><b>"+key+"</b>: " + l.properties[key] + "</p>";
                    }
                }
                overlayInner.html(html);
                overlay.style("display", "block");
                // set "open" class to current link
                removeOpenClass();
                d3.select(this).attr("class", "njg-link njg-open");
            }
        }, opts);

        if (opts.el == "body" && d3._pxToNumber(d3.select("body").style("height")) < 60) {
            var body = d3.select("body"),
                rect = body.node().getBoundingClientRect();
            body.style("height", d3._windowHeight() - rect.top - rect.bottom + "px");
        }

        var el = d3.select(opts.el)
                   .style("position", "relative"),
            width = d3._pxToNumber(el.style('width')),
            height = d3._pxToNumber(el.style('height')),
            force = d3.layout.force()
                      .charge(opts.charge)
                      .linkStrength(opts.linkStrength)
                      .linkDistance(opts.linkDistanceFunc)
                      .friction(opts.friction)
                      .chargeDistance(opts.chargeDistance)
                      .theta(opts.theta)
                      .gravity(opts.gravity)
                      // width is easy to get, if height is 0 take the height of the body<commit_msg>Fixed bug in properties visualization<commit_after>// version 0.1
(function () {
    /**
     * vanilla JS implementation
     * of jQuery.extend()
     */
    d3._extend = function (defaults, options) {
        var extended = {},
            prop;
        for (prop in defaults) {
            if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
                extended[prop] = defaults[prop];
            }
        }
        for (prop in options) {
            if (Object.prototype.hasOwnProperty.call(options, prop)) {
                extended[prop] = options[prop];
            }
        }
        return extended;
    };

    /**
     * converts strings like "10px" to 10
     */
    d3._pxToNumber = function (val) {
        return parseFloat(val.replace('px'));
    };

    /**
     * gets window height
     */
    d3._windowHeight = function () {
        return window.innerHeight || document.documentElement.clientHeight || 600;
    };

    /**
     * netjsongraph.js main function
     */
    d3.netJsonGraph = function(url, opts) {
        // default options, overridable
        opts = d3._extend({
            el: "body",
            metadata: true,
            defaultStyle: true,
            tooltipDelay: 300,
            scaleExtent: [0.25, 5],
            charge: -130,
            linkDistance: 40,
            linkStrength: 0.2,
            friction: 0.9,  // d3 default
            chargeDistance: Infinity,  // d3 default
            theta: 0.8,  // d3 default
            gravity: 0.1,
            // by default, high density areas have longer links
            linkDistanceFunc: function(d){
                var val = opts.linkDistance;
                if (d.source.linkCount >= 4 && d.target.linkCount >= 4) {
                    return val * 2;
                }
                return val;
            },
            // called on zoom and pan
            redraw: function () {
                panner.attr("transform", "translate(" + d3.event.translate + ") " +
                                         "scale(" + d3.event.scale + ")");
                tooltip.style("visibility", "hidden");
            },
            /**
             * converts NetJSON NetworkGraph
             * to the data structure consumed by d3
             */
            prepareData: function(graph) {
                var nodesMap = {},
                    nodes = graph.nodes.slice(), // copy
                    links = graph.links.slice(), // copy
                    nodes_length = graph.nodes.length;
                links_length = graph.links.length;
                for (var i = 0; i < nodes_length; i++) {
                    // count how many links every node has
                    nodes[i].linkCount = 0;
                    nodesMap[nodes[i].id] = i;
                }
                for (var c = 0; c < links_length; c++) {
                    var sourceIndex = nodesMap[links[c].source],
                        targetIndex = nodesMap[links[c].target];
                    // ensure source and target exist
                    if (!nodes[sourceIndex]) { throw("source '" + links[c].source + "' not found"); }
                    if (!nodes[targetIndex]) { throw("target '" + links[c].target + "' not found"); }
                    links[c].source = sourceIndex;
                    links[c].target = targetIndex;
                    // add link count to both ends
                    nodes[sourceIndex].linkCount++;
                    nodes[targetIndex].linkCount++;
                }
                return { "nodes": nodes, "links": links };
            },
            /**
             * called when a node is clicked
             */
            onClickNode: function (n) {
                var html = "<p><b>id</b>: " + n.id + "</p>";
                if (n.label) { html += "<p><b>label</b>: " + n.label + "</p>"; }
                if (n.properties) {
                    for (key in n.properties) {
                        if (!n.properties.hasOwnProperty(key)) { continue; }
                        html += "<p><b>"+ key.replace(/_/g, " ") +"</b>: " + n.properties[key] + "</p>";
                    }
                }
                if (n.linkCount) { html += "<p><b>links</b>: " + n.linkCount + "</p>"; }
                overlayInner.html(html);
                overlay.style("display", "block");
                // set "open" class to current node
                removeOpenClass();
                d3.select(this).attr("class", "njg-node njg-open");
            },
            /**
             * called when a node is clicked
             */
            onClickLink: function (l) {
                var html = "<p><b>source</b>: " + (l.source.label || l.source.id) + "</p>";
                html += "<p><b>target</b>: " + (l.target.label || l.target.id) + "</p>";
                html += "<p><b>cost</b>: " + l.cost + "</p>";
                if (l.properties) {
                    for (key in l.properties) {
                        if (!l.properties.hasOwnProperty(key)) { continue; }
                        html += "<p><b>"+ key.replace(/_/g, " ") +"</b>: " + l.properties[key] + "</p>";
                    }
                }
                overlayInner.html(html);
                overlay.style("display", "block");
                // set "open" class to current link
                removeOpenClass();
                d3.select(this).attr("class", "njg-link njg-open");
            }
        }, opts);

        if (opts.el == "body" && d3._pxToNumber(d3.select("body").style("height")) < 60) {
            var body = d3.select("body"),
                rect = body.node().getBoundingClientRect();
            body.style("height", d3._windowHeight() - rect.top - rect.bottom + "px");
        }

        var el = d3.select(opts.el)
                   .style("position", "relative"),
            width = d3._pxToNumber(el.style('width')),
            height = d3._pxToNumber(el.style('height')),
            force = d3.layout.force()
                      .charge(opts.charge)
                      .linkStrength(opts.linkStrength)
                      .linkDistance(opts.linkDistanceFunc)
                      .friction(opts.friction)
                      .chargeDistance(opts.chargeDistance)
                      .theta(opts.theta)
                      .gravity(opts.gravity)
                      // width is easy to get, if height is 0 take the height of the body
{'fraction_non_alphanumeric': 0.14017094017094017, 'fraction_numerical': 0.00916860916860917, 'mean_word_length': 1.247424480530819, 'pattern_counts': {'":': 4, '<': 73, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7107828', 'n_tokens_mistral': 3540, 'n_tokens_neox': 3306, 'n_words': 759}