How to Transition Chart based on datepicker

Hi,
I’m trying to get this bar chart to transition when a new date is chosen from datepicker. I’ve set up the transition code how I think it should work but it just changes without the transition bit. I’ve done transitions before but for some reason, this is tripping me up.

Here is a link to the notebook.

Thank you for your time.

I think it’s due to the dependency between your cells. When you change the cell “day”, the cells “data” and “viewof riderchart” are recomputed. You surely would want to generate your chart once, and then only update it using its internal “updateChart” method (also: note that the argument “day” of this function is never used)

First of all I wanna say this is one of the trickiest patterns on Observable and you’re not alone! I’m still learning how to use it well myself, and I’ve been using Observable for years and I work here lol…

Severo’s right: because the whole chart depends on data, which depends on day, the whole chart gets destroyed and recreated whenever day changes, so it doesn’t even have a chance to transition.

I’ve made a few changes in this fork, which I just sent you as a suggestion so you can merge it: https://observablehq.com/compare/0dc83de85e454301@304...0559b22316a2e5c6@360

  1. I’ve pulled out the default value of the datepicker ("2020-10-19", my birthday!) to a new cell called defaultDay.

  2. I use defaultDay instead of day to compute data. That way, data doesn’t change when the datepicker changes. (If it did, then the whole chart gets blown away and remade every time, because it has all the initialization code that depends on data.)

  3. I removed viewof from the definition of riderchart (and from the reference in tooltip) because it’s currently unnecessary and was breaking the update cell so it never actually ran. You should use viewof when you want to dispatch events that set a value on the DOM node the cell returns; you’re not currently doing that, so you don’t need it. If you’re going to add that, you’ll need to tweak the update cell to also refer to the view, like: (viewof riderchart).updateChart(day).

  4. Finally, I changed the updateChart method to use the argument day to recompute the data, which is binds to the rects selection. I’m using .call instead of separate statements so that I can just declare the transition once, and to ensure that the children still have the updated data bound to them.

Now it works! Looks great! Cool project, hope this helps, let me know if you have questions.

6 Likes

Ooh also I recently worked on improving our embedding so I might as well embed the working result!

1 Like

Thanks @severo and @tophtucker for pointing out that the chart was being regenerated every time a new date was chosen. I didn’t realize that was the case but it’s obvious to me now that its been pointed out to me. Also, for explaining viewof to me. I’m still trying to get my head around it.

@tophtucker, I noticed that in the embedding url, it doesn’t seem to include the <style> cell that contains some of the css. Is this just the embedding for the chart cell or for the whole observable notebook?

1 Like

Ah yeah, a classic tricky issue with embedding! The embed only runs cells that reference or are referenced by the displayed cells. So it won’t insert the <style> tag into the document, so that CSS won’t have any effect in the embed. We call this an example of side effects; you can read more in our troubleshooting guide: https://observablehq.com/@observablehq/troubleshooting-embedding.

To fix that here, I’d insert the style directly into the SVG that’ll be embedded, like this (after naming the cell with the styles style):
svg.append(() => style);

Which I’ve added to my suggestion: https://observablehq.com/compare/0dc83de85e454301@304...0559b22316a2e5c6@362

1 Like

I was just thinking about this again, so here’s I used the minimap to help debug your transitions:




2 Likes

@tophtucker Thanks for the minimap explanation. This makes perfect sense!

Sorry for the cross-posting. Can anybody give me some hints about a similar problem here:

I’ve just read this thread but I still can’t wrap my head around that.