So I have this page and I’m thinking of making a new version of it with LiveView:
As you can see, there are many different graphs on the page. Currently on the frontend I have a JS system where each graph is its own component and defines what kind of data it is interested in. Since many graphs can be interested in the same data (such as the two language lists), I don’t want to duplicate queries.
Additionally, the page is live updated, so all the graphs get the new data and decide what to do with it.
Now I’m wondering how to structure this with LiveView. I just started hammering it directly and got the top bar and top languages list working, but obviously the LV module will become a mess with all the data retrievals. So I want to structure it in a cleaner way. I have some ideas but would be nice to get yours.
A final aim here is that some time in the future, the specific graphs and their positions could be configurable, so if possible, I don’t want to hardcode them in the template. But I don’t know what LV’s change tracking would think of that.
My plan is to do something like this for now (pseudo-ish):
defmodule ProfileLive do
@graphs [
TopBarGraph,
Last2WeeksGraph,
TopLanguagesGraph,
...
]
And then somehow render the stuff based on that list (then later it could be made configurable). The modules would have something like
defmodule TopBarGraph do
def wants_data(), do: MapSet.new([:user, :total_xp, :recent_xp, :date_xps])
...
end
and then the LV module would combine the needed datas and retrieve those, providing them to the graphs. Does that sound reasonable?
But if the data needs are dynamic like that, I would need to render the component in a generic way like
<%= live_component(@socket, TopBarGraph, data: @TopBarGraph_data) %>
right? I can think of a couple other ways too, but I’m not sure which of them would work with LV’s change tracking so it doesn’t have to render everything on every update.
I think I can get the live updates working once I figure out a good structure for the basic setup. So, any ideas welcome. Have you done anything similar?