d3 transition interruption

Based on http://jsfiddle.net/lebolo/dt3qu9x0/, except this has enter transitions.

by Sumit Ridhal

HTML

<script src="http://d3js.org/d3.v3.js"></script>

CSS

svg {
    border: 1px solid black;
}
.shape {
    fill-opacity: 0.9;
}
label {
    margin-right: 10px;
}

JavaScript

$(function(){

// Setup container
var container = d3.selectAll('#svgContainer');
var width = 640,
    height = 480;
var nShapes = 50;

var transitionSelections = {};
var movingDuration = 750;

// Create random data
var filteredData,
    data = d3.range(nShapes).map(function(d, i) {
        return {
            id: i,
            x: Math.floor(Math.random() * width),
            y: Math.floor(Math.random() * height),
            r: Math.floor(Math.random() * width / 15),
            red: Math.floor(Math.random() * 100),
            blue: Math.floor(Math.random() * 100)
        };
    });

// Create filter functions
var filters = {
    red: function(d) {return d.red > 50;},
    blue: function(d) {return d.blue > 50;}
};

// Create SVG
var svg = container.append('svg')
.attr({
    width: width,
    height: height
});

// Hook up hover handlers for filters
$(".filter").hover(function(e) {
    onHover(e, this.dataset['filter']);
});

// Hook up click handlers for filters
$(".filter").change(function(e) {
    filterData();
    draw();
});

// Filter data and draw the canvas
filterData();
draw();



/**
 * Recalcualte filtered data
 */
 function filterData() {
    filteredData = data;
    
    $('.filter').each(function(idx, el) {
        var filterName = this.dataset['filter'];
        var filteredOut = !$(this).find("input").prop('checked');
        if (filteredOut) filteredData = filteredData.filter(function(d) {
            return !filters[filterName](d);
        });
    });
}

/**
 * Transition handler
 * @param selection the selection object
 * @param label the transition namespace
 * @param duration the transition duration
 * @param apply a function that applies transition attributes/styles
 * @param remove true if removing the element at end of transition
 */
 function trans(selection, label, duration, apply, remove) {
    selection.each(function(d) {
        // Create new transition if no current transition/selection
        if (!this.__transition__ ||...