diff --git a/lib/music_library_web/components/chart_components.ex b/lib/music_library_web/components/chart_components.ex index 79943895..adc4c16b 100644 --- a/lib/music_library_web/components/chart_components.ex +++ b/lib/music_library_web/components/chart_components.ex @@ -7,12 +7,16 @@ defmodule MusicLibraryWeb.ChartComponents do ## Examples <.vertical_bar_chart data={[{"Artist 1", 5}, {"Artist 2", 3}]} + label_fn={&elem(&1, 0)} + value_fn={&elem(&1, 1)} width={400} height={300} bar_color="rgb(79, 70, 229)" /> """ - attr :data, :list, required: true, doc: "List of {label, value} tuples" + attr :data, :list, required: true + attr :label_fn, :any, required: true + attr :value_fn, :any, required: true attr :width, :integer, default: 400 attr :height, :integer, default: 300 attr :bar_color, :string, default: "rgb(79, 70, 229)" @@ -23,7 +27,7 @@ defmodule MusicLibraryWeb.ChartComponents do assigns = assigns |> assign(:padding, 40) - |> assign(:max_value, max_value(assigns.data)) + |> assign(:max_value, max_value(assigns.data, assigns.value_fn)) # Account for labels |> assign(:chart_width, assigns.width - 150) # Account for bottom padding @@ -54,8 +58,8 @@ defmodule MusicLibraryWeb.ChartComponents do <% end %> <%!-- Bars and labels --%> - <%= for {{label, value}, index} <- Enum.with_index(@data) do %> - <% bar_width = @chart_width * value / @max_value %> + <%= for {datum, index} <- Enum.with_index(@data) do %> + <% bar_width = @chart_width * @value_fn.(datum) / @max_value %> <% y = @padding / 2 + index * (@bar_height + 4) %> <%!-- Label --%> @@ -64,9 +68,9 @@ defmodule MusicLibraryWeb.ChartComponents do y={y + @bar_height / 2 + 4} text-anchor="end" class={["text-xs fill-zinc-500 dark:fill-zinc-400", @label_click && "cursor-pointer"]} - phx-click={@label_click && @label_click.(label)} + phx-click={@label_click && @label_click.(datum)} > - {truncate_label(label, 20)} + {truncate_label(@label_fn.(datum), 20)} <%!-- Bar --%> @@ -78,7 +82,7 @@ defmodule MusicLibraryWeb.ChartComponents do fill={@bar_color} class="opacity-80 hover:opacity-100 transition-opacity" > - {label}: {value} + {@label_fn.(datum)}: {@value_fn.(datum)} <%!-- Value label --%> @@ -87,16 +91,16 @@ defmodule MusicLibraryWeb.ChartComponents do y={y + @bar_height / 2 + 4} class="text-xs fill-zinc-500 dark:fill-zinc-400" > - {value} + {@value_fn.(datum)} <% end %> """ end - defp max_value(data) do - {_, max} = Enum.max_by(data, fn {_, value} -> value end) - max + defp max_value(data, value_fn) do + max = Enum.max_by(data, value_fn) + value_fn.(max) end defp calculate_bar_height(data, available_height) do diff --git a/lib/music_library_web/live/stats_live/index.html.heex b/lib/music_library_web/live/stats_live/index.html.heex index 456c2962..22758c8d 100644 --- a/lib/music_library_web/live/stats_live/index.html.heex +++ b/lib/music_library_web/live/stats_live/index.html.heex @@ -79,8 +79,12 @@ width={600} height={35 * length(@records_by_artist)} bar_color="rgb(79, 70, 229)" + label_fn={fn {artist, _count} -> artist end} + value_fn={fn {_artist, count} -> count end} label_click={ - fn label -> JS.navigate(~p"/collection?#{%{query: ~s(artist:"#{label}")}}") end + fn {artist, _count} -> + JS.navigate(~p"/collection?#{%{query: ~s(artist:"#{artist}")}}") + end } class="w-full" /> @@ -97,8 +101,10 @@ width={600} height={35 * length(@records_by_genre)} bar_color="rgb(244, 63, 94)" + label_fn={fn {genre, _count} -> genre end} + value_fn={fn {_genre, count} -> count end} label_click={ - fn label -> JS.navigate(~p"/collection?#{%{query: ~s(genre:"#{label}")}}") end + fn {genre, _count} -> JS.navigate(~p"/collection?#{%{query: ~s(genre:"#{genre}")}}") end } class="w-full" />