is it prohibited to use transition interval same as redraw interval? - d3.js

I've been trying D3 for a day or two now. So I'm a D3 newbie but have lots of C/C++, Java, PHP, Javascript, etc background.
I started from the tutorials page github.com/mbostock/d3/wiki/Tutorials, and went fairly meticulously through
- Introduction
- Three Little Circles
- Thinking with Joins
- How Selections Work
first trying examples verbatim, sometimes trying different changes to see if I understand the results.
I then jumped to A Bar Chart, Part 1, and Part 2.
I ended up with results pretty much exactly as expected by the end of Part 2. The tutorial only has code fragments and I don't see a spot in the tutorial where it says "here is the full finished result you should end up with", nonetheless I end up with this http://jsbin.com/oqetuw/2/edit and it looks to be working identically to the tutorial.
Note for those who haven't tried this tutorial, the key points I'm asking about are the redraw interval, 1500 ms, the transition duration, 1000 ms, and the transition ease function, which the tutorial doesn't use or specify, but I've googled to find that it defaults to cubic-in-out.
As my goal is for a continuous smooth scrolling across the screen, I changed the redraw interval to 1000, and the transition ease function to "linear", and the result is here http://jsbin.com/ijumuv/1/edit
And these are the only changes as shown here:
$ diff tut2.09.html tut2.10.html
33c33
< }, 1500);
---
> }, 1000);
78a79
> .ease("linear")
82a84
> .ease("linear")
86a89
> .ease("linear")
The strange behaviour, and thus the question is, why do occasionally the bars that reach the left edge seem to bounce back and accumulate from left to right, behind the main bars? (and also occasionally get cleared)
Undoing only the 1500 -> 1000 change, the problem seems never to happen (so it is scrolling every 1.5 s, with each scroll duration being 1 s). So it would seem maybe if D3 is busy still doing the transition, it fails to remove them? or some other explanation I can't figure yet.
Thanks in advance for any tips.

Yeah, there are issues with d3 transitions. When the interval and duration are both 1000, there is high chance for the redraw operations to occur before the prior transition() on that selection is finished. And that messes with the data binding, or something along those lines.
I modified your code such that it continuously checks whether the previous redraw transition has finished before calling the next one. This is by no means "good javascript", but it does illustrate the issue, and some way around it. To understand what I added, just look for all occurrences of __readyForNext in the code. It should make sense.

Related

How can I make transitions between dc.js charts smooth when I have a map with more than 20k points?

I've recently built a smaller version of a prototype data explorer incorporating crossfilter, dc.js, and leaflet.markerCluster. The small version, (prototype dashboard), works properly. The problem I am having is when I try to scale it up to 20k points or more.
The charts still render correctly, and the map works to update the charts smoothly when zooming or panning, but when I interact with one of the charts, the transitions between the other charts are no longer smooth. They jump to their next position rather than smoothly transitioning.
I tried removing the map and this restored the transitions between the other charts to a nice smooth transition again.
I'm wondering if the re-rendering process is getting caught up with the 20k points each time an interaction occurs.
If anyone has any suggestions about where I might look for a solution I'd be grateful.
Thanks for posting a block, that makes things easier to test.
I simulated a lot more points by generating 200 rows for each of yours ~ 46k rows. I saw only a little stuttering at 100x ~ 23k rows (2017 iMac with plenty of RAM).
Leaflet.markercluster is known to be slow with more than 10K points. With 46k rows it took about 475ms for Leaflet.markercluster to clear and add the Leaflet layers:
Since there is only one thread in JavaScript (unless you use workers), D3 needs to get timeouts (actually requestAnimationFrame) every 16ms or so in order to produce fluid animation.
One workaround is to delay the map redrawing 500ms until the others have done:
dc.override(mapChart, 'redraw', function() {
window.setTimeout(() => mapChart._redraw(), 500);
});
Fork of your block with workaround.
Of course, this also makes the map take 500ms longer to redraw. And if you click around fast enough, the last map redraw will still be running when it's trying to draw the charts.
You could also try the chunked addLayers options but I think you would have to set the chunkedInterval so low that it would also slow down the markerclusters.
Processing this much data efficiently is possible in JavaScript - obviously crossfilter has no problem here. I don’t know if the cloistering algorithm is inherently too expensive. Someone on the issue suggested pre-aggregating the points, but I think this would mean you wouldn't be able to see individual points.

How do I make an exponential growing chart line on D3.js

I want to make a similar chart like on the picture below, that is drawing a line to a point which increases over time. Numbers on the bottom are seconds (how many passed).
example chart
I want to implement this with D3.js, but I do not really understand how to implement it.
I began to look to the side of d3-zoom. But I do not understand how I can make a dynamically growing line. Any similar examples you saw? Thank you
I think https://bl.ocks.org/pjsier/28d1d410b64dcd74d9dab348514ed256 might be helpful. Just increase the duration of the transition to get the similar effect of your example.
function transition(path) {
path.transition()
.duration(10000)
.attrTween("stroke-dasharray", tweenDash);
}

Recursive/recurring animation events in D3

I'm trying to make recurring transitions in D3 that will keep repeating indefinitely. Specifically, I'm working with a map and I want the background stars to occasionally flicker. The problem with transitions is that it appears they're all run ahead of time, so it will try to do the infinite recursion ahead of time and the page will never load. I found a related example (recursive d3 animation issue) that isn't infinite. My only other idea is to somehow use the d3 timer, but I'm not entirely sure how to go about that either. Any tips are appreciated.
Right, you can’t schedule an infinite number of transitions ahead of time. :) However, you can repeatedly schedule a new transition when the old transition ends (or starts), using transition.each to listen for end (or start) events.
Take a look at the chained transitions example for an infinitely-repeating animation. Whenever a circle transition starts, it also schedules an identical following transition, allowing the transition to repeat indefinitely.
Alternatively, you could use setInterval or setTimeout to create transitions repeatedly, as in the concurrent transitions example. Unlike the chained transitions example I linked, this approach won’t guarantee exact synchronization of chained transitions, but if all you want is an occasional background flicker, it might be a slightly simpler approach.

how to keep one jqplot from obscuring the previous

My need is to draw a basic x-axis, y-axis plot of several lines, with the lines becoming known in sequence as the user enters data. jqPlot appears to have the ability (unlike flot, at least as I understand it) to add to an existing plot. My experimentation thus far is:
$.jqplot('dpCum',[ld.fCumPairFwd[0]],{axes:{xaxis:{min:0,max:2500},yaxis:{min:0,max:200000}}});
$.jqplot('dpCum',[ld.fCumPairAft[0]],{axes:{xaxis:{min:0,max:2500},yaxis:{min:0,max:200000}}});
which produces two lines as I want them, except the background of the 2nd obscures the the 1st line. In practice, the data for the 2nd line won't be known until the user responds to the 1st line, and then they're going to want to see both at once.
I've made a couple of passes at the jqplot documentation (it's capabilities are obviously impressive) but how to keep existing lines visible as new lines are added escapes me. I'm thinking there may be some kind of z-axis opacity, but haven't been able to understand it yet.
The answer to your problem, I believe, is to use the replot() method and paint a new plot with the modified data set.
This approach is presented in the following sample. Please notice I made only the series with index 0 responsive to clicks. On click on the series' data points another is painted.
EDIT: The reason I went for replot() was that I couldn't figure out how to draw just a single series. I tried the approach presented by #Mark here with no success. He might know better though. I am rather fresh to jqPlot myself. Also taking into account that when we add a new series some points might reach outside the current scale, therefore, since redraw() doesn't rescale as mentioned here by the jqPlot author - though in my case it will work since we reinitialize the graph. Thus, I think if you also will not manage to apply single series draw you might try using the redraw() method instead, taking from the doc I think it is less expensive to call.
Maybe actually in this case you will not use replot() or redraw(), as in the sample I am making a new plot each time. Therefore, it seems to me to be more appropriate to call destroy() on the previous graph before we paint the new one. This is what currently is in the code sample.

How I do I make controls/elements move with inertia?

Modern UI's are starting to give their UI elments nice inertia when moving. Tabs slide in, page transitions, even some listboxes and scroll elments have nice inertia to them (the iphone for example). What is the best algorythm for this? It is more than just gravity as they speed up, and then slow down as they fall into place. I have tried various formulae's for speeding up to a maximum (terminal) velocity and then slowing down but nothing I have tried "feels" right. It always feels a little bit off. Is there a standard for this, or is it just a matter of playing with various numbers until it looks/feels right?
You're talking about two different things here.
One is momentum - giving things residual motion when you release them from a drag. This is simply about remembering the velocity of a thing when the user releases it, then applying that velocity to the object every frame and also reducing the velocity every frame by some amount. How you reduce velocity every frame is what you experiment with to get the feel right.
The other thing is ease-in and ease-out animation. This is about smoothly accelerating/decelerating objects when you move them between two positions, instead of just linearly interpolating. You do this by simply feeding your 'time' value through a sigmoid function before you use it to interpolate an object between two positions. One such function is
smoothstep(t) = 3*t*t - 2*t*t*t [0 <= t <= 1]
This gives you both ease-in and ease-out behaviour. However, you'll more commonly see only ease-out used in GUIs. That is, objects start moving snappily, then slow to a halt at their final position. To achieve that you just use the right half of the curve, ie.
smoothstep_eo(t) = 2*smoothstep((t+1)/2) - 1
Mike F's got it: you apply a time-position function to calculate the position of an object with respect to time (don't muck around with velocity; it's only useful when you're trying to figure out what algorithm you want to use.)
Robert Penner's easing equations and demo are superb; like the jQuery demo, they demonstrate visually what the easing looks like, but they also give you a position time graph to give you an idea of the equation behind it.
What you are looking for is interpolation. Roughly speaking, there are functions that vary from 0 to 1 and when scaled and translated create nice looking movement. This is quite often used in Flash and there are tons of examples: (NOTE: in Flash interpolation has picked up the name "tweening" and the most popular type of interpolation is known as "easing".)
Have a look at this to get an intuitive feel for the movement types:
SparkTable: Visualize Easing Equations.
When applied to movement, scaling, rotation an other animations these equations can give a sense of momentum, or friction, or bouncing or elasticity. For an example when applied to animation have a look at Robert Penners easing demo. He is the author of the most popular series of animation functions (I believe Adobe's built in ones are based on his). This type of transition works equally as well on alpha's (for fade in).
There is a bit of method to the usage. easeInOut start slow, speeds up and the slows down. easeOut starts fast and slows down (like friction) and easeIn starts slow and speeds up (like momentum). Depending on the feel you want you choose the appropriate one. Then you choose between Sine, Expo, Quad and so on for the strength of the effect. The others are easy to work out by their names (e.g. Bounce bounces, Back goes a little further then comes back like an elastic).
Here is a link to the equations from the popular Tweener library for AS3. You should be able to rewrite these in JavaScript (or any other language) with little to no trouble.
It's playing with the numbers.. What feels good is good.
I've tried to develop magic formulas myself for years. In the end the ugly hack always felt best. Just make sure you somehow time your animations properly and don't rely on some kind of redraw/refresh rate. These tend to change based on the OS.
Im no expert on this either, but I beleive they are done with quadratic formulas, that, when given the correct parameters, start fast or slow and dramatically increase or decrease towards the end until a certain point is reached.

Resources