Passing a 'speed' to a transition loop

10 views
Skip to first unread message

Adam Davies

unread,
Sep 16, 2016, 10:10:32 AM9/16/16
to d3-js
Hi All,

I am new to both JS and D3 so please don't hammer me too much!

I'm trying to create a group of objects which transition from one side of an svg to another, this works great using the example http://bl.ocks.org/mbostock/1125997

However, each of the groups of objects should have its own 'speed', which is working OK
You'll have to excuse the way the code works as it is being written for use in a proprietary application which is also where the data comes from, its also very rough and ready at the moment as I am focused on getting the animation correct before tidying it up.

This is the code which works and the 'fish' move forwards and backwards:



var fishArray = [];
var fishSizeArray = [];
var fishSpeedArray = [];

//load the data
for (var f=0; f < _this.Data.Rows.length; f++ ) {
var row = _this.Data.Rows[f];
var dim1 = row[0].text;
var measure1 = parseFloat(row[1].text);
var measure2 = parseFloat(row[2].text);

fishArray = fishArray.concat(dim1);
fishSizeArray = fishSizeArray.concat(measure1);
fishSpeedArray = fishSpeedArray.concat(measure2);
}

//do some setup

var padding = {top: 20, right: 20, bottom: 40, left: 40};
var width = _this.GetWidth() - padding.right - padding.left;
var height = _this.GetHeight() - padding.top - padding.bottom;
//build the chart

var chart = d3.select("#" + divName)
    .append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "chart")
//give it some colour
d3.select("#" + divName)
.style("background", "#98AFC7");



//make our fish group
var fishyGroup = chart.append("g")
//.attr("transform", function(d, i) { return "translate(0," + (i+1)*60 + ")"; });

///build the fishies
var fishyWishy = fishyGroup.selectAll("g")
.data(fishArray)
.enter().append("g")
.attr("transform", function(d, i) { return "translate(50," + height*Math.random()+ ")"; });
//give the fish a body
fishyWishy.append("ellipse")
.attr("rx", (function(d,i) {return(fishSizeArray[i])*2;})) //make the bodies slightly random shapes
.attr("ry", function(d,i) {return(fishSizeArray[i]);})

.attr("fill","red")
.style("stroke","black")
//give the fish a tail
fishyWishy.append("polygon")
.style("stroke","black")
.attr("points","-40,-10 -30,0 -40,10")
.attr("fill","red")
fishyWishy.transition()
.duration(function(d,i) {return(fishSpeedArray[i]);}) 
.delay(100)
.each(swim);

function swim() { var fish = d3.select(this); (function repeat() { fish = fish.transition() .attr("transform", function(d, i) { return "translate("+(width)+"," + height*Math.random() + ")"; }) //make our fishy go back the other way .transition() .attr("transform", function(d, i) { return "translate(0," + height*Math.random()+ ")"; }) .each("end", repeat); })(); }



Now this doesn't work brilliantly as the fish 'swim' backwards on the return leg, so what I had thought was to let them swim off the edge and come back around, the code for which would be like this:



function swim() { var fish = d3.select(this); (function repeat() { fish = fish.transition() .attr("transform", function(d, i) { return "translate("+(width+100)+"," + height*Math.random() + ")"; }) //make our fishy go back the other way .transition() .attr("transform", function(d, i) { return "translate(-100," + height*Math.random()+ ")"; }) .duration(100) //in reality this would be 1 .each("end", repeat); })();


But obviously what happens is that the duration variable is now set to 100ms so they swim fine and go back to the start, but obviously then for subsequent loops the swim speed is fixed at 100ms

I'm just drawing a blank on how to solve this issue.


Reply all
Reply to author
Forward
0 new messages