/* for mouseover, learning from this bl.ock: http://bl.ocks.org/mbostock/3902569 next steps: - manipulate data efficiently to include all years - show detailed information on hover - legends/axis - on click, large pretty text saying "if you made between X and Y in year Z, you would have paid k% in federal taxes (X' to Y' dollars)" */ // set variables for use throughout var barHeight = 5; var income_factor = 2000; var boxsize = 1000 var colorLow = '#ffffe5'; var colorHigh = '#004529'; // set up svg var svgHolder = d3.select("body") .append("svg") .attr("width", boxsize) .attr("height", boxsize); // set up div for tooltip var div = d3.select("body").append("div") .attr("class", "tooltip") .style("opacity", 1e-6); /* var focus = svgHolder.append("g") .attr("class", "focus"); // .style("display", "none"); focus.append("text") .attr("x", 9) .attr("y", 0) .attr("dy", ".35em"); */ // build color scale from low to high marginal tax rate function setColorScale(max) { return d3.scale.linear() .domain([0, max]) .interpolate(d3.interpolateRgb) .range([colorLow, colorHigh]) } // function drawRectangles(svg, mydata) { var maxTax = 0; var maxIncome = 0; // find max tax rate and max income in dataset // change 0 to 1 for income floor, so can use log scale mydata.forEach(function(d) { if (+d.marginal_tax_rate > maxTax) { maxTax = +d.marginal_tax_rate; }; if (+d.income_floor > maxIncome) { maxIncome = +d.income_floor; }; if (+d.income_floor == 0) { d.income_floor = 1; } }) // replace 'na' with max of dataset; maybe will preprocess instead? mydata.forEach(function(d) { if (d.income_ceiling == 'na') { d.income_ceiling = maxIncome; }; }) // set scales colorScale = setColorScale(maxTax); incomeScale = d3.scale.pow().exponent(.2).domain([1, maxIncome]).range([0, boxsize]); console.log(maxIncome) yearScale = d3.scale.linear().domain([1862, 2013]).range([500, 10]); // draw rectangles svg.selectAll("rect") .data(mydata) .enter() .append("rect") .attr("x", function(d, i) { // x start is determined by income floor return incomeScale(+d.income_floor); }) .attr("y", function(d, i) { return yearScale(+d.tax_year) //return (2013 - +d.tax_year) * barHeight; }) .attr("width", function(d) { // width is difference between scaled floor and scaled income ceiling values return incomeScale(+d.income_ceiling) - incomeScale(+d.income_floor) }) .attr("height", barHeight) .attr("stroke", 'white') .attr("fill", function(d) { return colorScale(+d.marginal_tax_rate); }) .on("mouseover", function() { div.transition() .duration(500) .style("opacity", 1); }) .on("mouseout", function() { div.transition() .duration(500) .style("opacity", 1e-6); }) .on("mousemove", function(d) { console.log(this); var coord = d3.mouse(this); var income = incomeScale.invert(coord[0]); div .text('year: ' + Math.ceil(yearScale.invert(coord[1])) + ', income: ' + d3.formatPrefix(income).scale(income).toFixed() + d3.formatPrefix(income).symbol) .style("left", (coord[0] + 20) + "px") .style("top", coord[1] + "px"); /* focus.attr("transform", "translate(" + coord[0] + "," + coord[1] + ")"); focus.select("text").text('check this out'); */ }) var prefix = d3.formatPrefix(13759402); console.log(prefix.symbol); // "M" console.log(prefix.scale(13759402).toFixed()); } d3.csv("fed_income_tax.csv", function(error, dataset) { drawRectangles(svgHolder, dataset); });