layercake icon indicating copy to clipboard operation
layercake copied to clipboard

Two plots on one <Canvas> causes update loop?

Open abalmos opened this issue 2 years ago • 5 comments

Thank you for writing LayerCake, it is a fantastic base to make custom plots on top of! We are moving from a more "component" based library and really enjoy the control Layer Cake provides. Particularly being able to trivally combine SVG (ease) with Canvas (high volume data layers).

That said, I have been playing with Canvas based plots today in anticipation of needing to plot a large amount of data soon. It seems that putting two components in one <Canvas> results in an update loop that never ends.

I wonder if I am doing something wrong?

You can see the issue in this REPL. It works as shown with two <Canvas> tags. You can see the issue by moving <Scatter /> into <Line />'s <Canvas> (while also commenting the two scaleLayer and clear rect lines from <Scatter />). WARNING: It will bind up your tab as soon as the REPL rebuilds.

Also, I wonder if multiple <Canvas> is better in the end anyway?

abalmos avatar Nov 17 '21 06:11 abalmos

Hey @abalmos, sorry I didn't see this earlier. Hm that is interesting and I hadn't seen that before. The issue seems to be that Svelte believes the $ctx variable is modified on lines 22 and 24 in Scatter.svelte when the fillStyle and strokeStyle are being set. Check out this example that works in one <Canvas> tag without those lines.

I'm not sure if there's a workaround since this seems to be just how Svelte's reactivity works but maybe @rich-harris has some other ideas. It would be nice if you didn't have to add multiple canvas tags for every layer although that seems like a fine workaround. It's just kind of a lame imposition that you need to have a specific pattern when using <Canvas> tags and so I should add that to the docs if that is indeed the case. Either way, if there is a better pattern, then the examples should be updated and explained in the docs, too.

mhkeller avatar Dec 03 '21 20:12 mhkeller

I haven't tested this but one idea is to create a wrapper that loads the two components from within the :if ($ctx) block but not sure if that will solve it.

mhkeller avatar Dec 03 '21 20:12 mhkeller

I'm told this is a svelte bug and hopefully will be fixed soon.

mhkeller avatar Dec 08 '21 21:12 mhkeller

@mhkeller thanks for checking into this. My attention was stolen away from the project, but I will return soon. Is there a Svelte issue to track?

abalmos avatar Dec 08 '21 22:12 abalmos

It may be this one: https://github.com/sveltejs/svelte/issues/4933

mhkeller avatar Dec 15 '21 05:12 mhkeller

FYI I added this to the docs: https://github.com/mhkeller/layercake/commit/e459efff16f627507c80364de53d0b22a79884b0

mhkeller avatar Dec 24 '22 18:12 mhkeller