Edit in JSFiddle

// Inaccurate data representation, ho!
// The data we'll be using is stored as a CSV in a text block in the HTML section.
// See the comments preceded with TOFIX to see where data is skewed.

//////////////////////////////////////////////////////////////////////////////
// Parameters
//////////////////////////////////////////////////////////////////////////////

var width = 500;
var height = 500;

var colorMax = d3.rgb(26, 93, 173);
var colorMin = d3.rgb(238, 41, 61);

//////////////////////////////////////////////////////////////////////////////
// Derived values
//////////////////////////////////////////////////////////////////////////////

// Donut chart parameters:
var rMax = Math.min(width / 2, height / 2);
var rMin = rMax / 2;
var rCenter = rMin / 2;

//////////////////////////////////////////////////////////////////////////////
// Helper functions
//////////////////////////////////////////////////////////////////////////////

var translate = function(x, y)
	{return "translate(" + x + "," + y + ")";}

var roundTo = function(value, decimals)
{
    var push = Math.pow(10, decimals);
    var rounded = Math.round(value * push);
    var pull = rounded / push;
    return pull;
}

//////////////////////////////////////////////////////////////////////////////
// Parse data into a JavaScript object
//////////////////////////////////////////////////////////////////////////////

// Get the block of text with the ID data (see the HTML).
var csv = d3.select("#data").text();

// Treat the block of text as a CSV document.
// d3.csv.parse converts the data into an array of JS objects.
var data = d3.csv.parse(csv, function(d)
{
    // Note that CSVs are read as text. The unary + converts them into numbers.
    var obj = {
        year: +d["Year"],
        dollars: +d["Nominal Dollars"],
        percent: +d["Percent"],
        adjusted: +d["Adjusted for 2014"]
        // TOFIX: We don't even use the data adjusted for inflation!
    };
    return obj;
});

//////////////////////////////////////////////////////////////////////////////
// Generate DOM elements
//////////////////////////////////////////////////////////////////////////////

var header = d3.select("body")
	.append("p")
	.style("text-align", "center")
	.text("Amount of US Federal Budget alloted for NASA")
	;

// Determine the range of values allowed for the slider.
var minYear = d3.min(data, function(d){return d.year;});
var maxYear = d3.max(data, function(d){return d.year;});

// Determine the initial value of the slider.
var maxPercent = d3.max(data, function(d){return d.percent;});
var defaultObj = data.filter(function(d){return (d.percent === maxPercent);})[0];
var defaultYear = defaultObj.year;

// Create the DOM elements for the slider.
var sliderContainer = d3.select("body")
	.append("p")
	.style("text-align", "center")
	;
var label = sliderContainer
    .append("label")
    .attr("for", "time") // Tag for the slider.
	.style("display", "block")

    .text("Year: " + defaultYear)
    ;

var slider = sliderContainer
	.append("input")
	.attr("type", "range")
	.attr("id", "time") // ID for the label.
	.style("display", "block")
	// The following three styles center the slider.
    .style("position", "relative")
	.style("margin-left", "auto")
	.style("margin-right", "auto")

	// TOFIX: We really should use minYear instead of defaultYear,
	// but we want to make an inaccurate point, no?
	.attr("min", defaultYear)
	.attr("max", maxYear)
	.attr("value", defaultYear)
	// Whenever the user moves the slider, update the label and graphic.
	.on("change", function() // Can also use "mouseup" or "input". 5165579
        {
        	label.text("Year: " + this.value);
        	update();
        })
	;

// Prepare a container for the SVG graphic.
var svgContainer = d3.select("body")
	.append("p")
	.style("text-align", "center")
	;

var svg = svgContainer.append("svg")
	.attr("width", width)
	.attr("height", height)
	;

var g = svg.append("g")
	.attr("transform", translate(width / 2, height / 2))
	;

//////////////////////////////////////////////////////////////////////////////
// D3 mappers and graphic generators.
//////////////////////////////////////////////////////////////////////////////

// Scale the dollar value per datum to a radius value.
var rScale = d3.scale.log()
	// TOFIX: I could use this scale instead, but this would be accurate!
	// 	d3.scale.sqrt()
	.domain(d3.extent(data, function(d){return d.dollars;}))
	.range([rMin, rMax]);

// Scale the percentage value per datum to an angle value.
var thetaScale = d3.scale.pow().exponent(2)
	// TOFIX: I could use this scale instead, but this would be accurate!
	//	d3.scale.linear()
	.domain(d3.extent(data, function(d){return d.percent;}))
	// TOFIX: I could use this scale instead, but this would be accurate!
	//	.domain([0, 1])
	.range([0, 2 * Math.PI]);

// Scale the percentage value per datum to a RGB value.
var colorScale = d3.scale.pow().exponent(2)
	// TOFIX: I could use this scale instead, but this would be accurate!
	//	d3.scale.linear()
	.domain(d3.extent(data, function(d){return d.percent;}))
	// TOFIX: I could use this scale instead, but this would be accurate!
	//	.domain([0, 1])
	.range([colorMin, colorMax]);

// Quick function to get r from the datum.
var getR = function(d){return rScale(d.dollars);}

// Quick function to get theta from the datum.
var getTheta = function(d){return thetaScale(d.percent);}

// Quick function to get color from the datum.
var getColor = function(d){return colorScale(d.percent);}

// Generates an arc corresponding to the datum.
var arc = d3.svg.arc()
	.innerRadius(rCenter)
	.outerRadius(function(d){return getR(d);})
	.startAngle(0)
	.endAngle(function(d){return getTheta(d);})
	;

// Generates the rest of the arc ring corresponding to the datum.
var ring = d3.svg.arc()
	.innerRadius(rCenter)
	.outerRadius(function(d){return d;})
	.startAngle(0)
	.endAngle(2 * Math.PI)
	;

//////////////////////////////////////////////////////////////////////////////
// Generate and animate the SVG
//////////////////////////////////////////////////////////////////////////////

// Initialize variables to keep track of the previous value and this value,
// in order to animate smoothly.
var prevYear = +slider.node().value;
var year = prevYear;

// These values are singleton arrays.
// We keep them as singletons because D3 expects arrays as parameters.
// (After all, D3 stands for DATA-driven documents, not datum-driven documents.)
var prevDatum = data.filter(function(d){return (d.year === prevYear);});
var datum = prevDatum;

// This function is called whenever the user moves the slider.
var update = function()
{
    // Update the year according to the new slider value.
    year = +slider.node().value; // The value is initially a string, hence the +.
    datum = data.filter(function(d){return (d.year === year);});
    
    // Determine how to animate the arc depending on the change of datum.
    var arcTween = function(d)
    {
        var rInterpolator =
			d3.interpolate(prevDatum[0].dollars, datum[0].dollars);
        var thetaInterpolator =
            d3.interpolate(prevDatum[0].percent, datum[0].percent);
        
        var tween = function(t)
        {
            // Make a dummy object that has the parameters needed for arc.
            var tweenObject =
               {
                   dollars: rInterpolator(t),
                   percent: thetaInterpolator(t)
               }
            return arc(tweenObject);
        }
        return tween;
    }
    
	// Update the data given, using the same index.
	// We do not provide a selector function for data, since we want to keep the same index.
	var join = g.selectAll("g").data(datum);
    
    // For every new element in the join, we create a group (and more later).
    var gEnter = join.enter().append("g");
    // For every updated element in the join, we do stuff later.
	var gUpdate = join;
    // For every element that left the join, we remove it.
    join.exit().remove();

    // Create and update the ring.
    gEnter
    	.append("path")
    	.attr("id", "ring")
    	.attr("fill", "gray")
		.attr("d", function(d){return ring(getR(d));})
    	;
    gUpdate.select("#ring").transition()
    	.attr("d", function(d){return ring(getR(d));});

    // Create and update the arc.
    gEnter
        .append("path")
    	.attr("id", "slice")
        .attr("stroke", "black")
        .attr("fill", function(d){return getColor(d);})
		.attr("d", function(d){return arc(d);})
        ;
    gUpdate.select("#slice").transition()
		.attr("fill", function(d){return getColor(d);})
    	.attrTween("d", arcTween)
    	.each("end", function()
            {
        		// We update prevYear and prevDatum only when the animation ends,
        		// as otherwise, there is a race condition.
        		prevYear = year;
        		prevDatum = datum;
    		})
    	;
    
    // Create and update the text for dollars.
    gEnter
    	.append("text")
    	.attr("id", "dollars")
    	.attr("transform", translate(0, -10)) // arbitrary translation
    	.attr("text-anchor", "middle")
    	.attr("dominant-baseline", "middle")
    	.text(function(d){return "$" + d.dollars + " m";});
    gUpdate.select("#dollars")
    	.text(function(d){return "$" + d.dollars + " m";});
    
    // Create and update the text for percent.
    gEnter
		.append("text")
    	.attr("id", "percent")
    	.attr("transform", translate(0, 10)) // arbitrary translation
    	.attr("text-anchor", "middle")
    	.attr("dominant-baseline", "middle")
    	.text(function(d){return roundTo(d.percent * 100, 2)  + "%";});
    gUpdate.select("#percent")
    	.text(function(d){return roundTo(d.percent * 100, 2)  + "%";});
}

// Render SVG for the first time.
update();
<!-- This is the data set as a CSV. -->
<pre style = "display:none" id = "data">
Year,Nominal Dollars,Percent,Adjusted for 2014
1958,89,0.0010,732
1959,145,0.0020,1185
1960,401,0.0050,3222
1961,744,0.0090,5918
1962,1257,0.0118,9900
1963,2552,0.0229,19836
1964,4171,0.0352,32002
1965,5092,0.0431,38448
1966,5933,0.0441,43554
1967,5425,0.0345,38633
1968,4722,0.0265,32274
1969,4251,0.0231,27550
1970,3752,0.0192,23000
1971,3382,0.0161,19862
1972,3423,0.0148,19477
1973,3312,0.0135,17742
1974,3255,0.0121,15704
1975,3269,0.0098,14452
1976,3671,0.0099,15345
1977,4002,0.0098,15707
1978,4164,0.0091,15190
1979,4380,0.0087,14349
1980,4959,0.0084,14314
1981,5537,0.0082,14488
1982,6155,0.0083,15170
1983,6853,0.0085,16365
1984,7055,0.0083,16150
1985,7251,0.0077,16028
1986,7403,0.0075,16065
1987,7591,0.0076,15893
1988,9092,0.0085,18280
1989,11036,0.0096,21168
1990,12429,0.0099,22618
1991,13878,0.0105,24235
1992,13961,0.0101,23668
1993,14305,0.0101,23546
1994,13695,0.0094,21979
1995,13378,0.0088,20879
1996,13881,0.0089,21042
1997,14360,0.0090,21280
1998,14194,0.0086,20712
1999,13636,0.0080,19467
2000,13428,0.0075,18547
2001,14095,0.0076,18940
2002,14405,0.0072,19045
2003,14610,0.0068,18885
2004,15152,0.0066,19078
2005,15602,0.0063,19001
2006,15125,0.0057,17844
2007,15861,0.0058,18194
2008,17833,0.0060,19700
2009,17782,0.0057,19714
2010,18724,0.0052,20423
2011,18448,0.0051,17833
2012,17770,0.0050,17471
2013,16865,0.0049,17219
2014,17647,0.0050,17647
</pre>
p
{
    /* Font applied to each paragraph (but not the SVG). */
    font-family: "Titillium Web", "Helvetica Neue", Helvetica, Arial, sans-serif;
}