D3js - Smooth transition between 2 paths - javascript

I am 2 very different path and I'd like to smoothly change one to make it look like the other one. I have tried using the .transition() method applied on the "d" attribute but it gives very poor results.
Here is an example:
http://jsfiddle.net/yya0m0s0/1/
The d3 code I used is the following:
var svg = d3.select("body")
.append('svg')
.attr('width', '375px')
.attr('height', '490px');
svg.append('path').attr('d', d_t0);
svg.selectAll('path').transition()
.duration(3500).delay(1000)
.attr('d', d);
What is the best way to create the kind of transformations?
Many thanks

The problem here is that your first path only has 10 segments, and your second has 42 segments. The paths are so different that transitioning between them using the built-in path tweening is impossible.
D3 does a good job of tweening two paths that are similar in structure (same number of segments, and the same types of segments). Things start to get messier the more different the structures are.
Consider this example.
The first two path data d_1 and d_2 have the same number and type of segments, only the endpoints change. The transition between these is seamless.
The second two path data d_3 and d_4 have the same number of segments, but the final segment is a different type (line in d_3, quadratic curve in d_4). The transition is fine for all the points up to the last point, but then the final segment shows the same sort of jumpiness that you experienced in your example. This is because a quadratic curve requires a control-point, which must materialize out of thin air when the transition begins, causing the jump.
The bad news is that the only way around this problem is to create a custom tween function for your path data attribute. The good news is that this is a common issue and smart people have come up with solid solutions.
HERE is a good path tween function that Mike Bostock created.
When implemented on your example it gives a fairly smooth result: JSFiddle
Hope that helps.

Related

D3.js Arc Diagram - Tapered Ends

I have an arc diagram that is based on this blocks example, and I'd like to taper the ends of the arc path so that they are hidden behind the circles (or at least aren't wider than the circles themselves).
I have two thoughts and I'm not sure how feasible either of them are: a) modify d3.arc source code so that the resultant svg path has tapered ends, or b) instead of using d3.arc to generate the path, create my own cubic bezier function that takes in the x and y points of the source and target nodes and outputs a a curve that tapers to maybe half of its full width? Both of which I've never done before and would be floundering a bit trying to do.
Any tips, tricks, ideas, or general well wishes would be greatly appreciated.

d3 geo.path Transition

I have a maps of different countries. I want to transition every countries to another path (typically a rectangle or a circle).
If I do a classic transition, the transition is akward, as the SVG does not have the same number of nodes. I use a library (polymorph.js). This library ensures that the destination path has the same number of nodes. Sadly there are some artfacts ( circles are not really circle, and rectangles are a bit weird).
Example : http://bl.ocks.org/ufenegga/7302cdde0fd2b6814dda
I am looking for an algorithm that allows to transition nicely between the country path and a circle/rect
Can anybody help ?
Thanks
I find a working solution here : https://gist.github.com/ge045/2e7de433f1d1d5948bbd/revisions
If somebody can explains what is going on, so i'll be sure to understand how it works

D3JS - animate a circle along an svg path at a constant speed

I'd like to move a circle along a path using d3.js. I used the code from Mike Bostocks' website here:
http://bl.ocks.org/KoGor/8162640
I'd like to move my circle at a constant speed along the path and have it moving immediately after it has been added to my svg. I cannot see how to twist the code here to make it work.
Does anybody have an idea how to do this?
Best
You should just add a line
.ease("linear")
after .duration(7500), and you should be all set.
This is documentation on ease(), but you should read all that is related to transitions, while you ate at it...
Here is also a test example for various possibilities related to ease():

Key binding with d3.svg.path()

I have a simple d3.js time-series graph plotted as SVG circles. The circles are key bound so that when I remove data from end of the array, circles from right are removed and when I remove items from the beginning of the array, circles from left are removed on exit.remove().
var circles = svg.selectAll('circle')
.data(data, function(d){return d.key})
Now, I want to do the same with a SVG path.
Is there a way to apply key binding to SVG path?
I had a similar issue when I wanted to make a live-updating plot in d3 with an SVG path. d3 uses only one path element for an entire data sequence, i.e. for a given array there is one path drawn that can get very very long depending on your data. This means that d3 cannot simply remove bound data elements by removing DOM elements like circles. It would have to modify something like <path d="M0,0L1,0L2,1L3,2"> to <path d="M1,0L2,1L3,2">. I do not think d3 has this capability, unfortunately (Though you could code this yourself! You need to override d3.interpolateString and write some custom interpolator that notices the dropped points.)
This also means that you can't use D3's data selector, since data works on a group with multiple elements, like svg circles. You're going to have to use select("#yoursvgpath").datum(data) instead, which sets the data of a single element, where data is your data array.
Since I knew the hardware my code would run on was fast (desktop i7, ssd, etc...), I simply redrew the path every time I added or removed elements. Even still, it's pretty slow in Firefox (but fine in Chrome), especially when the number of points gets over around 10,000. To redraw, just call datum again and then re-apply your coordinate transformer (something like select("#yoursvgpath").attr("d", line) where line is your path data transformer). I ended up only redrawing every 5,000 data elements so that the path wasn't constantly being recalculated.
If any of this was confusing, I would definitely read up on making line charts in d3, it's quite a bit different (and less intuitive) than point-based charts. I'd also take a look at https://gist.github.com/mbostock/1642874 and http://bost.ocks.org/mike/selection/, for learning more about d3 selections and line charts.

Transitioning innerRadius of svg.arc - D3.js

I have a question, that is closely related to this one.
As opposed to the example, I also need to transition the innerRadius of the sunburst, hence the innerRadius property of the d3.svg.arc(). I know it has to be done in a similar fashion with respect to the transition of the "d" (with attrTween by storing the old innerRadius) but I didn't managed to do it.
Any suggestion? A code snippet would be great!
When you say "sunburst", do you mean a multi-colored Pie, where all the arcs are different? If so, the example "Multiple D3 Pie Charts Mixed In With Common HTML Layout Constructs" transitions the inner radius while drawing the pie (just search for the word transition in the code).
Another option is to look at this "Sunburst Coffee Flavor Wheel" example, which is more complex but shows how to transition multiple arcs, simultaneously.
I hope it helps.
Frank

Categories