<commit_before>// Clock Visualization

// Visualization of tracking data over 24 hours

(function(visualizations){
"use strict";
const CX = 0;
const CY = 0;
const CENTRE = CX + ',' + CY;
const DOT_TRANS = 'translate(305, 5)';
const HAND_TRANS = 'translate(205, 5)';
const TIME_TRANS = 'translate(0, 5)';
const SVG_NS = 'http://www.w3.org/2000/svg';
const TIME_X1 = -275;
const TIME_X2 = 270 ;
const TIME_Y = CY - 5;

var vizcanvas, times, timeslots, offsets;

// TODO: Make visualization an event emitter, so I can call on('connection', fn) and emit('connection', connection)

var clock = new Emitter();
visualizations.clock = clock;
clock.name = "clock";

clock.on('init', onInit);
clock.on('connection', onConnection);
clock.on('remove', onRemove);
clock.on('setFilter', setFilter);

function setFilter(){
    addon.emit('setFilter', 'filter24hours');
}

function onInit(connections){
    // draw clock dial
    console.log('initializing clock from %s connections', connections.length);
    vizcanvas = document.querySelector('.vizcanvas');
    aggregate.emit('init', connections);
    times = ['12 am', '1 am', '2 am', '3 am', '4 am', '5 am', '6 am', '7 am', '8 am', '9 am', '10 am', '11 am', '12 pm', '1 pm', '2 pm', '3 pm', '4 pm', '5 pm', '6 pm', '7 pm', '8 pm', '9 pm', '10 pm', '11 pm', '12 am'];
    timeslots = {};
    offsets = [':00', ':15', ':30', ':45'];
    times.slice(1).forEach(function(time){
        timeslots[time] = {':00': [], ':15': [], ':30': [], ':45': [] };
    });
    vizcanvas.setAttribute('viewBox', '-350 -495 700 500');
    drawTimes();
    updateTime();
    connections.forEach(function(connection){
        onConnection(connection);
    });
    fadeEarlierTrackers(timeToBucket(new Date()));
};

function onConnection(conn){
    // A connection has the following keys:
    // source (url), target (url), timestamp (int), contentType (str), cookie (bool), sourceVisited (bool), secure(bool), sourcePathDepth (int), sourceQueryDepth(int)
    var connection = aggregate.connectionAsObject(conn);
    aggregate.emit('connection', connection);
    var bucketIdx = timeToBucket(connection.timestamp);
    
    if (! clock.timeslots[bucketIdx]){
        var angle = -180 + (bucketIdx * 1.875); // in degrees
        clock.timeslots[bucketIdx] = {
            group: svg('g', {
                transform: 'rotate(' + angle + ' ' + CENTRE + ') ' + DOT_TRANS,
                bucketIdx: bucketIdx
            }),
            sourceNodes: [],
            targetNodes: [],
            connections: []
        }
        vizcanvas.appendChild(clock.timeslots[bucketIdx].group);
    }

    var bucket = clock.timeslots[bucketIdx];
    appendSourceNode(bucket,connection);
    appendTargetNode(bucket,connection);
    arrangeNodePosition(bucketIdx);
 
}


function appendSourceNode(bucket,connection){
    var sourceIdx = -1;
    // see if we've already added this source node to the visualization
    if ( bucket.sourceNodes.length > 0 ) {
        for (var i=0; i<bucket.sourceNodes.length; i++){
            if ( bucket.sourceNodes[i][connection.source] ){
                sourceIdx = i;
                break;
            }
        }
    }
 
    if ( sourceIdx < 0 ){ // this source node has not been added to the visulization
        var source = {};
        source[connection.source] = [ connection.target ];
        bucket.sourceNodes.push(source);
        var sourceg = svg('g', {
            'class': 'source node',
            'data-name': connection.source
        });
        sourceg.appendChild(svg('circle', {
            cx: 0,
            cy: 0,
            r: 4,
            'class': 'tracker'
        }));
        connection.view = sourceg;
        tooltip.add(sourceg);
        bucket.group.appendChild(sourceg);
    }
}


function appendTargetNode(bucket,connection){
    var targetIdx = -1;
    // see if we've already added this target node to the visualization
    if ( bucket.targetNodes.length > 0 ) {
        for (var i=0; i<bucket.targetNodes.length; i++){
            if ( bucket.targetNodes[i][connection.target] ){
                targetIdx = i;
                break;
            }
        }
    }

    if ( targetIdx < 0 ){ // this target node has not been added to the visulization
        var target = {};
        target[connection.target] = [ connection.source ];
        bucket.targetNodes.push(target);
        var targetg = svg('g', {
            'class': 'target node',
            'data-name': connection.target
        });
        targetg.appendChild(svg('circle', {
            cx: 0,
            cy: 0,
            r: 4,
            'class': 'tracker'
        }));
        connection.view = targetg;
        tooltip.add(targetg);
        bucket.group.appendChild(targetg);
    }
}
<commit_msg>code cleanup for issue #224 and #225<commit_after>// Clock Visualization

// Visualization of tracking data over 24 hours

(function(visualizations){
"use strict";
const CX = 0;
const CY = 0;
const CENTRE = CX + ',' + CY;
const DOT_TRANS = 'translate(305, 5)';
const HAND_TRANS = 'translate(205, 5)';
const TIME_TRANS = 'translate(0, 5)';
const SVG_NS = 'http://www.w3.org/2000/svg';
const TIME_X1 = -275;
const TIME_X2 = 270 ;
const TIME_Y = CY - 5;

var vizcanvas, times, timeslots, offsets;

// TODO: Make visualization an event emitter, so I can call on('connection', fn) and emit('connection', connection)

var clock = new Emitter();
visualizations.clock = clock;
clock.name = "clock";

clock.on('init', onInit);
clock.on('connection', onConnection);
clock.on('remove', onRemove);
clock.on('setFilter', setFilter);

function setFilter(){
    addon.emit('setFilter', 'filter24hours');
}

function onInit(connections){
    // draw clock dial
    console.log('initializing clock from %s connections', connections.length);
    vizcanvas = document.querySelector('.vizcanvas');
    aggregate.emit('init', connections);
    times = ['12 am', '1 am', '2 am', '3 am', '4 am', '5 am', '6 am', '7 am', '8 am', '9 am', '10 am', '11 am', '12 pm', '1 pm', '2 pm', '3 pm', '4 pm', '5 pm', '6 pm', '7 pm', '8 pm', '9 pm', '10 pm', '11 pm', '12 am'];
    timeslots = {};
    offsets = [':00', ':15', ':30', ':45'];
    times.slice(1).forEach(function(time){
        timeslots[time] = {':00': [], ':15': [], ':30': [], ':45': [] };
    });
    vizcanvas.setAttribute('viewBox', '-350 -495 700 500');
    drawTimes();
    updateTime();
    connections.forEach(function(connection){
        onConnection(connection);
    });
    fadeEarlierTrackers(timeToBucket(new Date()));
};

function onConnection(conn){
    // A connection has the following keys:
    // source (url), target (url), timestamp (int), contentType (str), cookie (bool), sourceVisited (bool), secure(bool), sourcePathDepth (int), sourceQueryDepth(int)
    var connection = aggregate.connectionAsObject(conn);
    aggregate.emit('connection', connection);
    var bucketIdx = timeToBucket(connection.timestamp);
    
    if (! clock.timeslots[bucketIdx]){
        var angle = -180 + (bucketIdx * 1.875); // in degrees
        clock.timeslots[bucketIdx] = {
            group: svg('g', {
                transform: 'rotate(' + angle + ' ' + CENTRE + ') ' + DOT_TRANS,
                bucketIdx: bucketIdx
            }),
            sourceNodes: [],
            targetNodes: [],
            connections: []
        }
        vizcanvas.appendChild(clock.timeslots[bucketIdx].group);
    }

    var bucket = clock.timeslots[bucketIdx];

    // see if we've already added this source node to the visualization
    // if not, create one
    var sourceIdx = -1;
    if ( bucket.sourceNodes.length > 0 ) {
        for (var i=0; i<bucket.sourceNodes.length; i++){
            if ( bucket.sourceNodes[i] == connection.source ){
                sourceIdx = i;
                break;
            }
        }
    }
    if ( sourceIdx < 0 ){
        bucket.sourceNodes.push(connection.source);
        appendNodeG(bucket,connection,"source");
    }
 
    // see if we've already added this target node to the visualization
    // if not, create one
    var targetIdx = -1;
    if ( bucket.targetNodes.length > 0 ) {
        for (var i=0; i<bucket.targetNodes.length; i++){
            if ( bucket.targetNodes[i] == connection.target ){
                targetIdx = i;
                break;
            }
        }
    }
    if ( targetIdx < 0 ){
        bucket.targetNodes.push(connection.target);
        appendNodeG(bucket,connection,"target");
    }
 
    // group source nodes closer to the center of the clock
    // and group target nodes further away
    arrangeNodePosition(bucketIdx);
 
}


function appendNodeG(bucket,connection,nodeType){
    console.log(connection);
    var g = svg('g', {
        'class': 'node ' + nodeType,
        'data-name': connection[nodeType]
    });
    g.appendChild(svg('circle', {
        cx: 0,
        cy: 0,
        r: 4,
        'class': 'tracker'
    }));

    // highlight this node if it belongs to the "colluded nodes" of the currently selected(clicked) node 
    if ( document.querySelector(".clicked-node") ){
        var clickedNodeName = document.querySelector(".clicked-node").getAttribute("data-name");
        if ( connection.source == clickedNodeName ){
            d3.select(g).classed("clicked-node", true);
        }
        for ( var key in aggregate.nodeForKey( clickedNodeName ) ){
            if ( key != clickedNodeName && key == connection[nodeType] ){
                d3.select(g).classed("colluded-"+nodeType, true);
            }
        }
    }
    connection.view = g;
    tooltip.add(g);
    bucket.group.appendChild(g);

}


{'fraction_non_alphanumeric': 0.15335696413678065, 'fraction_numerical': 0.023874061718098416, 'mean_word_length': 2.571481757259866, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3569653', 'n_tokens_mistral': 3051, 'n_tokens_neox': 2859, 'n_words': 768}