<commit_before>var d3 = require("d3");
var cloud = require("d3-cloud");

var _ = require("underscore");

const COLOR_SELECTION = ["#8dd3c7", "#bebada", "#fb8072", "#80b1d3", "#fdb462", "#b3de69", "#fccde5", "#bc80bd", "#ccebc5", "#ffed6f"];

var ttCounter = 0

function D3Tooltip (d3, selector) {
    this.d3 = d3
    this.id = 'd3-tooltip-' + ttCounter
    this.class = 'd3-tooltip'
    this.$el =  d3.select(selector).append('div')
        .attr('class', this.class)
        .attr('id', this.id)
        .style('opacity', 0)
        .style('position', 'absolute')
        .style('pointer-events', 'none')
    ttCounter += 1
    this.html = function(html) {
        this.$el.html(html)
    }
    this.show = function() {
        var xPos = this.d3.event.pageX - $(selector).offset().left + 10;
        var yPos = this.d3.event.pageY - $(selector).offset().top + 10;
        this.$el.transition().duration(200).style('opacity', .9)
        this.$el.style('left', xPos + 'px')
                .style('top', (yPos - 28) + 'px')
    }
    this.move = function() {
        var xPos = this.d3.event.pageX - $(selector).offset().left + 10;
        var yPos = this.d3.event.pageY - $(selector).offset().top - 28;
        this.$el.style('left', xPos + 'px')
                .style('top', (yPos - 28) + 'px')
    }
    this.hide = function() {
        this.$el.transition().duration(500).style('opacity', 0)
    }
}

class Visual {
    constructor(selector, data, config) {
        this.selector = selector || "body";
        this.config = config || {};
        this.init();
        this.set(data, config);
    }

    setConfig(config) {
        config = config || {};
        var color_selection = config.color || COLOR_SELECTION;
        var color =  d3.scaleOrdinal(color_selection);
        this.config = {
            key: config.key || "id",
            value_key: config.value_key || "percent",
            tooltip: config.tooltip,
            get_text: config.get_text,
            center_text: config.center_text,
            total: config.total || 0,
            width: config.width || 300,
            height: config.height || 50,
            color_selection: color_selection,
            color: (config.color_key)? color.domain(config.color_key) : color,
        }
    }

    set(data, config) {
        this.setConfig(config);
        this.render(data);
    }
    init(data, config) { /* Override in subclasses */ }
    render(data) { /* Override in subclasses */ }
}

class PieChart extends Visual {
    init() {
        var width = this.config.width || $(this.selector).width() || 300;
        var height = width;
        this.radius = Math.min(width, height) / 2;

        this.svg = d3.select(this.selector)
            .append("svg")
            .attr("width", width)
            .attr("height", height)
            .append("g")
            .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

        this.svg.append("g").attr("class", "slices");
        this.svg.append("g").attr("class", "labelName");
        this.svg.append("g").attr("class", "labelValue");
        this.svg.append("g").attr("class", "lines");

        var self = this;
        this.pie = d3.pie().sort(null).value(function(d) {
            return d[self.config.value_key];
        });
        this.arc = d3.arc().outerRadius(this.radius * 0.8) .innerRadius(this.radius * 0.4);
        this.outerArc = d3.arc().innerRadius(this.radius * 0.9).outerRadius(this.radius * 0.9);
    }
    render(data) {
        var arc = this.arc;
        var config = this.config;


        var g = this.svg.selectAll(".arc")
            .data(this.pie(data))
            .enter().append("g")
            .attr("class", "arc");

        var path = g.append("path")
                .attr("d", arc)
                .style("fill", function (d) {
                    return config.color(d.data[config.key]);
                });

        if(config.tooltip) {
            if(!this.tooltip) {
                this.tooltip = new D3Tooltip(d3, this.selector);
            }
            var tip = this.tooltip;
            path.on("mouseover", function(d) {
                    tip.html(config.tooltip(d))
                    tip.show()
                }).on("mousemove", function(d) {
                    tip.move();
                })
                .on("mouseout", function(d) {
                    tip.hide();
                })
        }

        if (config.get_text) {
            g.append("text")
                .style("text-anchor", "middle")
                .style("font-size", "8pt")
                .attr("transform", function (d) {
                    return "translate(" + arc.centroid(d) + ")";
                }).attr("dy", ".35em").text(config.get_text);
        }

        if(config.center_text) {
            g.append("text")
                .attr("text-anchor", "middle")
                .attr('font-size', '14pt')
                .attr("dy", "0em")
                .text(config.total);

            g.append("text")
                .attr("text-anchor", "middle")
                .attr('font-size', '10pt')
                .attr("dy", "1em")
                .text(config.center_text);
        }
    }
}

class Legend extends Visual {
    render(data) {
        var legend = d3.select(this.selector).append("table").attr('class','legend');
        var leg = {};
        var color = this.color;
        var config = this.config;

        var tr = legend.append("tbody").selectAll("tr").data(data).enter().append("tr");

        // create the first column for each segment.
        tr.append("td").append("svg").attr("width", '16').attr("height", '16').append("rect")
            .attr("width", '16').attr("height", '16')
            .attr("fill", function(d){ return config.color(d[config.key]); });

        // create the second column for each segment.
        tr.append("td").text(config.get_text);
    };
}


class TagCloud extends Visual {

    init() {
        var width = $(this.selector).width();
        this.svg = d3.select(this.selector).append("svg").attr("width", width);
    }
    render(data) {
        if(!data.length) {
            return;
        }

        // var words = "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.";
        // words = words.split(" ");
        // for (var i = 0; i < words.length; ++i) {
        //     data.push({"tag_name": words[i], "count": Math.floor(Math.random() * 100)});
        // }



        var config = this.config;
        var svg = this.svg;
        var width = svg.attr("width");
        var selector = this.selector;<commit_msg>Removed commented out code<commit_after>var d3 = require("d3");
var cloud = require("d3-cloud");

var _ = require("underscore");

const COLOR_SELECTION = ["#8dd3c7", "#bebada", "#fb8072", "#80b1d3", "#fdb462", "#b3de69", "#fccde5", "#bc80bd", "#ccebc5", "#ffed6f"];

var ttCounter = 0

function D3Tooltip (d3, selector) {
    this.d3 = d3
    this.id = 'd3-tooltip-' + ttCounter
    this.class = 'd3-tooltip'
    this.$el =  d3.select(selector).append('div')
        .attr('class', this.class)
        .attr('id', this.id)
        .style('opacity', 0)
        .style('position', 'absolute')
        .style('pointer-events', 'none')
    ttCounter += 1
    this.html = function(html) {
        this.$el.html(html)
    }
    this.show = function() {
        var xPos = this.d3.event.pageX - $(selector).offset().left + 10;
        var yPos = this.d3.event.pageY - $(selector).offset().top + 10;
        this.$el.transition().duration(200).style('opacity', .9)
        this.$el.style('left', xPos + 'px')
                .style('top', (yPos - 28) + 'px')
    }
    this.move = function() {
        var xPos = this.d3.event.pageX - $(selector).offset().left + 10;
        var yPos = this.d3.event.pageY - $(selector).offset().top - 28;
        this.$el.style('left', xPos + 'px')
                .style('top', (yPos - 28) + 'px')
    }
    this.hide = function() {
        this.$el.transition().duration(500).style('opacity', 0)
    }
}

class Visual {
    constructor(selector, data, config) {
        this.selector = selector || "body";
        this.config = config || {};
        this.init();
        this.set(data, config);
    }

    setConfig(config) {
        config = config || {};
        var color_selection = config.color || COLOR_SELECTION;
        var color =  d3.scaleOrdinal(color_selection);
        this.config = {
            key: config.key || "id",
            value_key: config.value_key || "percent",
            tooltip: config.tooltip,
            get_text: config.get_text,
            center_text: config.center_text,
            total: config.total || 0,
            width: config.width || 300,
            height: config.height || 50,
            color_selection: color_selection,
            color: (config.color_key)? color.domain(config.color_key) : color,
        }
    }

    set(data, config) {
        this.setConfig(config);
        this.render(data);
    }
    init(data, config) { /* Override in subclasses */ }
    render(data) { /* Override in subclasses */ }
}

class PieChart extends Visual {
    init() {
        var width = this.config.width || $(this.selector).width() || 300;
        var height = width;
        this.radius = Math.min(width, height) / 2;

        this.svg = d3.select(this.selector)
            .append("svg")
            .attr("width", width)
            .attr("height", height)
            .append("g")
            .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

        this.svg.append("g").attr("class", "slices");
        this.svg.append("g").attr("class", "labelName");
        this.svg.append("g").attr("class", "labelValue");
        this.svg.append("g").attr("class", "lines");

        var self = this;
        this.pie = d3.pie().sort(null).value(function(d) {
            return d[self.config.value_key];
        });
        this.arc = d3.arc().outerRadius(this.radius * 0.8) .innerRadius(this.radius * 0.4);
        this.outerArc = d3.arc().innerRadius(this.radius * 0.9).outerRadius(this.radius * 0.9);
    }
    render(data) {
        var arc = this.arc;
        var config = this.config;


        var g = this.svg.selectAll(".arc")
            .data(this.pie(data))
            .enter().append("g")
            .attr("class", "arc");

        var path = g.append("path")
                .attr("d", arc)
                .style("fill", function (d) {
                    return config.color(d.data[config.key]);
                });

        if(config.tooltip) {
            if(!this.tooltip) {
                this.tooltip = new D3Tooltip(d3, this.selector);
            }
            var tip = this.tooltip;
            path.on("mouseover", function(d) {
                    tip.html(config.tooltip(d))
                    tip.show()
                }).on("mousemove", function(d) {
                    tip.move();
                })
                .on("mouseout", function(d) {
                    tip.hide();
                })
        }

        if (config.get_text) {
            g.append("text")
                .style("text-anchor", "middle")
                .style("font-size", "8pt")
                .attr("transform", function (d) {
                    return "translate(" + arc.centroid(d) + ")";
                }).attr("dy", ".35em").text(config.get_text);
        }

        if(config.center_text) {
            g.append("text")
                .attr("text-anchor", "middle")
                .attr('font-size', '14pt')
                .attr("dy", "0em")
                .text(config.total);

            g.append("text")
                .attr("text-anchor", "middle")
                .attr('font-size', '10pt')
                .attr("dy", "1em")
                .text(config.center_text);
        }
    }
}

class Legend extends Visual {
    render(data) {
        var legend = d3.select(this.selector).append("table").attr('class','legend');
        var leg = {};
        var color = this.color;
        var config = this.config;

        var tr = legend.append("tbody").selectAll("tr").data(data).enter().append("tr");

        // create the first column for each segment.
        tr.append("td").append("svg").attr("width", '16').attr("height", '16').append("rect")
            .attr("width", '16').attr("height", '16')
            .attr("fill", function(d){ return config.color(d[config.key]); });

        // create the second column for each segment.
        tr.append("td").text(config.get_text);
    };
}


class TagCloud extends Visual {

    init() {
        var width = $(this.selector).width();
        this.svg = d3.select(this.selector).append("svg").attr("width", width);
    }
    render(data) {
        if(!data.length) {
            return;
        }

        var config = this.config;
        var svg = this.svg;
        var width = svg.attr("width");
        var selector = this.selector;
{'fraction_non_alphanumeric': 0.16684921504198613, 'fraction_numerical': 0.015626140927345746, 'mean_word_length': 1.904156064461408, 'pattern_counts': {'":': 2, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7251644', 'n_tokens_mistral': 4384, 'n_tokens_neox': 4156, 'n_words': 856}