Fork me on GitHub
#reagent
<
2017-09-26
>
borkdude08:09:43

I have strange things happening on a function that draws a chart using D3. Let’s say we have a function draw! which receives a dom-node and then draws a chart. What happens is that the related Reagent component can update while it’s drawing, so we have a concurrency problem.

borkdude09:09:11

Don’t know if there is an elegant way to solve this. Maybe delegate the drawing to a Re-frame event.

p-himik09:09:53

I think it shouldn't happen unless you use web workers or setTimeout or a similar mechanism inside draw!.

borkdude09:09:54

Or maybe core.async

borkdude09:09:40

@p-himik It’s hard to debug this one, since it doesn’t occur all the time

p-himik09:09:18

Do you do anything related to setTimeout or web workers inside draw!? If not, do you call some D3 functions? Probably they include some code that does use setTimeout.

borkdude09:09:39

I don’t know the internals of D3, but I don’t use setTimeout myself

borkdude09:09:17

I assume React waits for an update if a previous one is still in progress? Never really thought about this until now

borkdude09:09:35

yes, I’m using that pattern

borkdude09:09:17

The annoying thing is also when something goes wrong in the draw! function which does a lot of d3 interop, I don’t see any errors in the console

reefersleep09:09:43

that sucks 😕

reefersleep09:09:41

Guess you’ll have to guard against error-causing values? (I’m guessing that this is what causes the errors)

reefersleep09:09:18

At least you can rule that spectrum of errors our by speccing the args or something like that

p-himik09:09:15

Just a wild guess, but the absence of errors in the console when the errors are happening could be caused by js promises that don't have a final handler that logs these errors.

borkdude09:09:26

That could be, and also be the cause of the concurrency problem

borkdude09:09:35

Where does the d3 community hang out

borkdude09:09:49

ah, that’s what I searched for, thanks!

borkdude10:09:50

I think I found where it went wrong. d3 adds .-x and .-y values to my clojurescript data. A lot of the same hash-maps will be re-used on an optimistic update… except for one or two. Those have .-x nil. And then the d3 algorithm doesn’t recompute all of those .-x values and gets confused. The solution is to clear them. Mutable data on immutable hash-maps!

borkdude10:09:56

Maybe I should copy them to js arrays instead of using them directly…

pesterhazy10:09:55

sounds like you're using something not the way it's intended to be used

borkdude10:09:06

Well d3 adds properties to the data you feed it

pesterhazy10:09:43

I assume it doesn't expect a PersistenArrayMap/PersistentVector though?

borkdude10:09:46

It expects an array of data and some functions that can get values out of that data. That’s what I did. I just passed an array of hash-maps + some functions like :foobar which works just fine.

borkdude10:09:19

But not when you run it a second time, because it added properties to those maps… which is an implementation detail to me