From 87ae6c66d18156bb796dcc6198f21811c87c6b08 Mon Sep 17 00:00:00 2001 From: TheFirstAvenger Date: Sat, 15 Jun 2024 15:42:39 -0400 Subject: [PATCH] Download graph as SVG --- CHANGELOG.md | 1 + lib/flame_on/component.ex | 6 +++ lib/flame_on/component.html.heex | 4 ++ lib/flame_on/svg.ex | 72 ++++++++++++++++++-------------- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b30282..fc06cf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Next +- Add "Download graph as SVG" feature - `Phoenix.HTML` 4.0 - Bandit.Pipeline.run as default MFA when available (it's now the default in `mix phx_new`) - Fix issue with changeset form not honoring initial node diff --git a/lib/flame_on/component.ex b/lib/flame_on/component.ex index a768b2c..294a659 100644 --- a/lib/flame_on/component.ex +++ b/lib/flame_on/component.ex @@ -16,6 +16,7 @@ defmodule FlameOn.Component do |> assign(:capture_timed_out?, false) |> assign(:root_block, root_block) |> assign(:viewing_block, root_block) + |> assign(:html_render, nil) |> assign(:view_block_path, []) {:ok, socket} @@ -30,6 +31,10 @@ defmodule FlameOn.Component do {:ok, socket} end + def update(%{html_render: html}, socket) do + {:ok, assign(socket, :html_render, html)} + end + def update(assigns, socket) do target_node = Map.get(assigns, :node, Node.self()) capture_changeset = Map.put(CaptureSchema.changeset(target_node), :action, :validate) @@ -45,6 +50,7 @@ defmodule FlameOn.Component do |> assign(:capture_timed_out?, false) |> assign(:id, assigns.id) |> assign(:target_node, target_node) + |> assign(:html_render, nil) else socket end diff --git a/lib/flame_on/component.html.heex b/lib/flame_on/component.html.heex index 4d944eb..07bac2c 100644 --- a/lib/flame_on/component.html.heex +++ b/lib/flame_on/component.html.heex @@ -138,6 +138,10 @@ Capture Timed Out
<% end %> + <%= if @html_render do %> + Base.encode64(@html_render)} download="flame_on.svg" target="_blank">Download graph as SVG + <% end %> + <%= if not is_nil(@viewing_block) do %> <%= if @view_block_path do %> <%= for %Block{} = block <- @view_block_path do %> diff --git a/lib/flame_on/svg.ex b/lib/flame_on/svg.ex index 4bc911f..fb6faa3 100644 --- a/lib/flame_on/svg.ex +++ b/lib/flame_on/svg.ex @@ -12,36 +12,46 @@ defmodule FlameOn.SVG do |> assign(:block_height, 25) |> assign(:top_block, top_block) - ~H""" - - - <%= for block <- @blocks do %> - <%= render_flame_on_block(%{ - block: block, - block_height: @block_height, - duration_ratio: @duration_ratio, - top_block: @top_block, - parent: @parent, - socket: @socket - }) %> - <% end %> - - """ + rendered = + ~H""" + + + <%= for block <- @blocks do %> + <%= render_flame_on_block(%{ + block: block, + block_height: @block_height, + duration_ratio: @duration_ratio, + top_block: @top_block, + parent: @parent, + socket: @socket + }) %> + <% end %> + + """ + + html = + rendered + |> Phoenix.HTML.Safe.to_iodata() + |> IO.iodata_to_binary() + + send_update(assigns.parent, html_render: html) + + rendered end defp render_flame_on_block(%{block: %Block{function: nil}}), do: "" @@ -63,7 +73,7 @@ defmodule FlameOn.SVG do <%= mfa_to_string(@block.function) %> - <%= format_integer(@block.duration) %>µs (<%= trunc(@block.duration * 100 / @top_block.duration) %>%) <%= mfa_to_string(@block.function) %> + <%= format_integer(@block.duration) %>µs (<%= trunc(@block.duration * 100 / @top_block.duration) %>%) <%= mfa_to_string(@block.function) %> <% end %>