function createZoomableContainer(group, width, height) { var zoom = d3.behavior.zoom() .scaleExtent([ 0.90, 5 ]) .on('zoom', zoomed); group.call(zoom); var rect = group.append('rect') .attr('width', width) .attr('height', height) .style('fill', 'none') .style('pointer-events', 'all'); var container = group.append('g'); function zoomed() { container.attr('transform', 'translate(' + d3.event.translate + ')scale(' + d3.event.scale + ')'); } group.on('dblclick.zoom', null); return container; } var raw = null; d3.csv('passing_stats.csv', function(error, data) { raw = data; }); var id0 = window.setInterval(function() { if (raw != null) { var columns = [ 'Rk', 'Cmp', 'Passing Attempts', 'Pct', 'Passing Yards', 'Y/A', 'AY/A', 'Passing TD', 'Interceptions', 'Rate', 'Rushing Attempts', 'Rushing Yards', 'Rushing Avg', 'Rushing TD' ]; var absoluteWidth = 1000; var plotsPerRow = columns.length; var plotWidth = absoluteWidth / plotsPerRow; var plotHeight = absoluteWidth / plotsPerRow; var plotPadding = 10; var radius = 0.75; var viewportWidth = 800; var viewportHeight = 400; var svg = d3.select('#chart0') .append('svg') .attr('width', viewportWidth) .attr('height', viewportHeight); var container = createZoomableContainer(svg, viewportWidth, viewportHeight); var groups = []; for (var i = 0; i < columns.length * columns.length / plotsPerRow; ++i) { for (var j = 0; j < plotsPerRow; ++j) { var group = container.append('g') .attr('transform', 'translate(' + plotWidth * j + ',' + plotHeight * i + ')') .attr('class', 'small') .on('dblclick', function() { var axes = d3.select(this).attr('data').split(','); drawDetailedView(axes[0], axes[1]); }); groups.push(group); } } var datasets = []; var color = new ColorMap(); var k = 0; for (i = 0; i < columns.length; ++i) { for (j = 0; j < columns.length; ++j) { if (i != j) { var dataset = []; raw.forEach(function(v) { dataset.push({ x: Number(v[columns[j]]), y: Number(v[columns[i]]), name: v['Player'], conference: v['Conf'], color: color.byConference(v['Conf']), radius: radius, layer: 0 }); }); datasets.push(dataset); } else { datasets.push(columns[i]); // diagonal title } groups[k].attr('data', columns[j] + ',' + columns[i]); ++k; } } var fontSize = 10; datasets.forEach(function(ds, i) { if (typeof(ds) != 'string') { var scatterplot = new Scatterplot( groups[i], datasets[i], plotWidth, plotHeight, plotPadding); groups[i].append('rect') .attr('width', plotWidth) .attr('height', plotHeight) .style('fill', 'none') .style('pointer-events', 'all'); scatterplot.draw(); } else { var words = ds.split(' '); words.forEach(function(word, w) { groups[i].append('text') .attr('x', 0) .attr('y', plotHeight / 2 + fontSize * w) .attr('class', 'axis-title') .text(word) .attr('style', 'font-size: ' + fontSize + 'px'); }); } }); window.clearInterval(id0); drawDetailedView('Passing Attempts', 'Passing Yards'); } }, 100); function drawDetailedView(xaxis, yaxis) { d3.select('#chart1').select('svg').remove(); var width = 800; var height = 500; var padding = 50; var dataset = []; var color = new ColorMap(); var radius = 5; raw.forEach(function(v) { dataset.push({ x: Number(v[xaxis]), y: Number(v[yaxis]), name: v['Player'], conference: v['Conf'], color: color.byConference(v['Conf']), radius: radius, layer: 0 }); }); var svg = d3.select('#chart1') .append('svg') .attr('width', width) .attr('height', height); var scatterplot = new Scatterplot(svg, dataset, width, height, padding); scatterplot.draw(); scatterplot.makeHoverLabels(function(d) { return d.name; }); scatterplot.drawAxisLabels(yaxis, xaxis); var lg = svg.append('g') .attr('transform', 'translate(100,50)'); var legend = new Legend(lg); legend.draw(color.getConferenceColors()); var last = null; var detail = new Detail(svg, width - padding, height - padding, width * 0.21, height * 0.15, 10, 9); scatterplot.each(function() { d3.select(this) .on('click', function(d) { if (last != null) { last.color = color.byConference(last.conference); last.radius = radius; last.layer = 0; } d.color = 'orange'; d.radius = radius * 2; d.layer = 1; last = d; scatterplot.draw(); var details; raw.forEach(function(r) { if (d.name == r['Player']) { details = [ 'Rank: ' + r['Rk'], 'Name: ' + r['Player'], 'School: ' + r['School'], xaxis + ': ' + r[xaxis], yaxis + ': ' + r[yaxis] ]; } }); if (details) { detail.update(details); } }); }); }