//Speed & animation-control variables var maprate = 4760/12, pause=0, timepause=0, start = 0, interval, loop, dateiter; //Data parameter variables var minyr, maxyr, dates, years; //Selection variables var slider, handle, brush, timer, timeaxis, timescale = d3.time.scale(), datemark; var timepad = 100; //bottom padding for slider var width = Math.max(960, window.innerWidth), height = Math.max(700, window.innerHeight); // load data d3.csv("time.csv", type, function(error, data) { dates = d3.set(data.map(function(d) {return d.Date;})).values().map(function(z) {return new Date(z);}); years = d3.set(data.map(function(d) {return +d.Date.getFullYear();})).values().map(function(z) {return +z;}); minyr = d3.min(years); maxyr = d3.max(years); timescale .rangeRound([0,width - 40]) .clamp(true) ; timeaxis = d3.svg.axis() .scale(timescale) .orient("bottom") .tickSize(0) .tickPadding(12) .ticks(0) ; sliderbox = d3.select("#sliderbox") .attr("width",1800); timer = sliderbox.append("g"); timescale .domain([new Date(minyr,0,1),new Date(maxyr,12,31)]); timer .attr("class", "x axis") .attr("transform","translate(" + 20 + "," + Math.floor((height - (timepad/2))) + ")") .call(timeaxis) .select(".domain") brush = d3.svg.brush() .x(timescale) .extent([0,0]) .on("brush",function() { //Now separate into mousedown -> clearInterval, drag -> animate, mouseup -> setInterval components var mouseval = timescale.invert(d3.mouse(this)[0]); var val = new Date(mouseval.getFullYear(),12); var strval = val.toISOString(); dateiter = dates.map(function(d) {return d.toISOString();}).indexOf(strval); brush.extent([val,val]); //handle.attr("cx",timescale(val)); handle.attr("transform","translate(" + timescale(val) + ",0)") clearInterval(interval); update(data,val); interval = setInterval(loop,maprate); }) ; slider = timer .append("g") .attr("class","slider") .call(brush) ; slider.selectAll(".extent,.resize") .remove(); dateiter = 0; handle = slider .append("g") .attr("class","handle preload") .attr("transform","translate(" + timescale(dates[0]) + ",0)"); handle.append("line") .attr("class","datemark outer preload"); handle.append("line") .attr("class","datemark inner preload"); handle.append("text") .attr("class","datemark label") .attr("y",-12) .attr("x",0) .attr("text-anchor","middle"); d3.selectAll(".datemark.preload") // size of brush dragger .attr("x1",0) .attr("x2",0) .attr("y1",-5) .attr("y2",5); dateiter = 0; // date incrementer - start loop = function(){ clearInterval(interval); if ((timepause == 0 && pause == 0) || start == 0) { update(data,dates[dateiter]); if (dateiter < dates.length - 1) {++dateiter;} else { dateiter = 0; timepause=1; setTimeout(function(){timepause = 0;},3000); } } start = 1; interval = setInterval(loop, maprate); } interval = setInterval(loop, maprate); }); //end data callback function update(data,date) { var yr = date.getFullYear(); // spits out the years for slider var usedat = data.filter(yrfilter(yr)); var curr = [timescale(date)]; handle .transition(50) .attr("transform",function(d) {return "translate(" + Math.floor(curr) + ",0)"}); timer.selectAll(".datemark,.handle") // point that moves on timer .classed('preload',0); timer.select(".datemark.label") .text(d3.time.format("%Y")(date)); timer.select(".datemark.labelbox") .attr("height", 50) .attr("width", 50) .attr("x", 5) .attr("y",-12) .style("fill-opacity",0); var datapoints = d3.select("#points").selectAll("circle").data(data) .enter() .append("circle") .attr("class", function(d){return "dot " +d.Year}); var circles = d3.selectAll(".dot") .classed({'preload': false, 'loaded': true}) .data(usedat, function(d) { return d ? d.Radius : this.id; }, function(d) { return d ? d.x : this.id; }, function(d) { return d ? d.y : this.id; }); circles .transition() .duration(475) .attr("r", function(d){return d.Radius}) .attr("cx", function(d){return d.x}) .attr("cy", function(d){return d.y}) .style("fill", "#ff0000") .style("opacity", 1) .transition() .duration(300) .attr("r", function(d){return d.Radius}) .attr("cx", function(d){return d.x}) .attr("cy", function(d){return d.y}) .style("fill", "#ff0000") .style("opacity", 0.7) .transition() .duration(250) .attr("r", function(d){return d.Radius}) .attr("cx", function(d){return d.x}) .attr("cy", function(d){return d.y}) .style("fill", "#ff0000") .style("opacity", 0.5) .transition() .duration(150) .attr("r", function(d){return d.Radius}) .attr("cx", function(d){return d.x}) .attr("cy", function(d){return d.y}) .style("fill", "#ff0000") .style("opacity", 0.2) .remove(); } //end update //Filter by year. function yrfilter(year) { return function(element) { return element.Year == year; } } function type(d) { d.Year = +d.Year; d.Date = new Date(d.Year,12); return d; }