<commit_before>app.directive('prscatterplot', function() {
    function link(scope, el, attr) {
        var width = 620;         // width of the svg element
        var height = 580;         // height of the svg element
        scope.canvas_width = 540;   // width of the canvas
        scope.canvas_height = 540;  // height of the canvas
        var margin = {            // used mainly for positioning the axes' labels
            top: 0,
            right: 0,
            bottom: height - scope.canvas_height,
            left: width - scope.canvas_width
        };
        scope.x_cat;                // chosen plot parameter for x-axis
        scope.y_cat;                // chosen plot parameter for y-axis
        scope.x_transform;          // chosen transform for x-data
        scope.y_transform;          // chosen transform for y-data
        scope.show_heat = false;    // whether to show heat map
        scope.x_pre_scale;          // pre-scale factor for x data
        scope.y_pre_scale;          // pre-scale factor for y data
        scope.clusters;
        var cluster_radius = 4.5;
        scope.transition_ms = 2000;
        var x_data;               // x data series to plot
        var y_data;               // y data series to plot
        var x_range;              // used for "auto-range" for chosen x category
        var y_range;              // used for "auto-range" for chosen y category
        var x_scale;              // function to convert x data to svg pixels
        var y_scale;              // function to convert y data to svg pixels
        var flow_data;            // FCS data
        scope.parameter_list = [];  // flow data column names
        var subsample_count = 10000;  // Number of events to subsample

        // Transition variables
        scope.prev_position = [];         // prev_position [x, y, color] pairs
        scope.transition_count = 0;       // used to cancel old transitions

        scope.$watch('data', function(data) {
            if (!data) {
                return;
            }

            // reset the parameter list
            scope.parameter_list = [];

            // Grab our column names
            scope.data[0].parameters.forEach(function (p) {
                scope.parameter_list.push(p.channel);
            });

            scope.x_cat = scope.parameter_list[0];
            scope.y_cat = scope.parameter_list[0];

            scope.x_pre_scale = '0.01';
            scope.y_pre_scale = '0.01';

            // render initial data points in the center of plot
            scope.prev_position = scope.data.map(function (d) {
                return [scope.canvas_width / 2, scope.canvas_height / 2, "rgba(96, 96, 212, 1.0)"];
            });
            scope.prev_position.forEach(scope.circle);

            scope.clusters = cluster_plot_area.selectAll("circle").data(data);

            scope.clusters.enter()
                .append("circle")
                    .attr("cx", 0)
                    .attr("cy", 0)
                    .attr("r", cluster_radius)
                    .on("mouseover", function(d) {  // setup our mouseover
                        tooltip.style("visibility", "visible");
                        tooltip.text("something");
                    })
                    .on("mousemove", function(){return tooltip.style("top",
                        (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10) + "px");})
                    .on("mouseout", function(){return tooltip.style("visibility", "hidden");});

            scope.render_plot();
        });

        scope.svg = d3.select("#scatterplot")
            .append("svg")
            .attr("width", width)
            .attr("height", height);

        // create canvas for plot, it'll just be square as the axes will be drawn
        // using svg...will have a top and right margin though
        d3.select("#scatterplot")
            .append("canvas")
            .attr("id", "canvas_plot")
            .attr("style", "position:absolute;left: " + margin.left + "px; top: " + margin.top + "px;")<commit_msg>add tooltip for clusters<commit_after>app.directive('prscatterplot', function() {
    function link(scope, el, attr) {
        var width = 620;         // width of the svg element
        var height = 580;         // height of the svg element
        scope.canvas_width = 540;   // width of the canvas
        scope.canvas_height = 540;  // height of the canvas
        var margin = {            // used mainly for positioning the axes' labels
            top: 0,
            right: 0,
            bottom: height - scope.canvas_height,
            left: width - scope.canvas_width
        };
        scope.x_cat;                // chosen plot parameter for x-axis
        scope.y_cat;                // chosen plot parameter for y-axis
        scope.x_transform;          // chosen transform for x-data
        scope.y_transform;          // chosen transform for y-data
        scope.show_heat = false;    // whether to show heat map
        scope.x_pre_scale;          // pre-scale factor for x data
        scope.y_pre_scale;          // pre-scale factor for y data
        scope.clusters;
        var cluster_radius = 4.5;
        scope.transition_ms = 2000;
        var x_data;               // x data series to plot
        var y_data;               // y data series to plot
        var x_range;              // used for "auto-range" for chosen x category
        var y_range;              // used for "auto-range" for chosen y category
        var x_scale;              // function to convert x data to svg pixels
        var y_scale;              // function to convert y data to svg pixels
        var flow_data;            // FCS data
        scope.parameter_list = [];  // flow data column names
        var subsample_count = 10000;  // Number of events to subsample

        // Transition variables
        scope.prev_position = [];         // prev_position [x, y, color] pairs
        scope.transition_count = 0;       // used to cancel old transitions

        // A tooltip for displaying the point's event values
        var tooltip = d3.select("body")
            .append("div")
            .attr("id", "tooltip")
            .style("position", "absolute")
            .style("z-index", "100")
            .style("visibility", "hidden");

        scope.$watch('data', function(data) {
            if (!data) {
                return;
            }

            // reset the parameter list
            scope.parameter_list = [];

            // Grab our column names
            scope.data[0].parameters.forEach(function (p) {
                scope.parameter_list.push(p.channel);
            });

            scope.x_cat = scope.parameter_list[0];
            scope.y_cat = scope.parameter_list[0];

            scope.x_pre_scale = '0.01';
            scope.y_pre_scale = '0.01';

            // render initial data points in the center of plot
            scope.prev_position = scope.data.map(function (d) {
                return [scope.canvas_width / 2, scope.canvas_height / 2, "rgba(96, 96, 212, 1.0)"];
            });
            scope.prev_position.forEach(scope.circle);

            scope.clusters = cluster_plot_area.selectAll("circle").data(data);

            scope.clusters.enter()
                .append("circle")
                    .attr("cx", 0)
                    .attr("cy", 0)
                    .attr("r", cluster_radius)
                    .on("mouseover", function(d) {  // setup our mouseover
                        tooltip.style("visibility", "visible");

                        var popup_text = "";

                        // find x_cat value
                        d.parameters.forEach(function (p) {
                            if (p.channel == scope.x_cat) {
                                popup_text = popup_text + "x: " + (Math.round(p.location * 100) / 100).toString();
                            }
                        });
                        d.parameters.forEach(function (p) {
                            if (p.channel == scope.y_cat) {
                                popup_text = popup_text + " y: " + (Math.round(p.location * 100) / 100).toString();
                            }
                        });

                        tooltip.text(popup_text);
                    })
                    .on("mousemove", function(){return tooltip.style("top",
                        (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10) + "px");})
                    .on("mouseout", function(){return tooltip.style("visibility", "hidden");});

            scope.render_plot();
        });

        scope.svg = d3.select("#scatterplot")
            .append("svg")
            .attr("width", width)
            .attr("height", height)
            .attr("style", "z-index: 1000");

        // create canvas for plot, it'll just be square as the axes will be drawn
        // using svg...will have a top and right margin though
        d3.select("#scatterplot")
            .append("canvas")
            .attr("id", "canvas_plot")
            .attr("style", "position:absolute;left: " + margin.left + "px; top: " + margin.top + "px;")
{'fraction_non_alphanumeric': 0.1148950059841149, 'fraction_numerical': 0.014361875748014362, 'mean_word_length': 1.4221343873517787, 'pattern_counts': {'":': 0, '<': 3, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '396640', 'n_tokens_mistral': 2550, 'n_tokens_neox': 2355, 'n_words': 652}