Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download graph as SVG #44

Merged
merged 1 commit into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions lib/flame_on/component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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)
Expand All @@ -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
Expand Down
4 changes: 4 additions & 0 deletions lib/flame_on/component.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@
Capture Timed Out<br />
<% end %>

<%= if @html_render do %>
<a href={"data:image/svg+xml;base64," <> Base.encode64(@html_render)} download="flame_on.svg" target="_blank">Download graph as SVG</a>
<% end %>

<%= if not is_nil(@viewing_block) do %>
<%= if @view_block_path do %>
<%= for %Block{} = block <- @view_block_path do %>
Expand Down
72 changes: 41 additions & 31 deletions lib/flame_on/svg.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,46 @@ defmodule FlameOn.SVG do
|> assign(:block_height, 25)
|> assign(:top_block, top_block)

~H"""
<svg width="1276" height={@block_height * @top_block.max_child_level} style="background-color: white;">
<style>
svg > svg {
cursor: pointer;
}

svg > svg > rect {
stroke: white;
rx: 5px;
}

svg > svg > text {
font-size: <%= @block_height / 2 %>px;
font-family: monospace;
dominant-baseline: middle;
}
</style>
<%= 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 %>
</svg>
"""
rendered =
~H"""
<svg width="1276" height={@block_height * @top_block.max_child_level} style="background-color: white;" xmlns="http://www.w3.org/2000/svg">
<style>
svg > svg {
cursor: pointer;
}

svg > svg > rect {
stroke: white;
rx: 5px;
}

svg > svg > text {
font-size: <%= @block_height / 2 %>px;
font-family: monospace;
dominant-baseline: middle;
}
</style>
<%= 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 %>
</svg>
"""

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: ""
Expand All @@ -63,7 +73,7 @@ defmodule FlameOn.SVG do
<rect width="100%" height="100%" style={"fill: #{color_for_function(@block.function)};"}></rect>
<text x={@block_height / 4} y={@block_height * 0.5}><%= mfa_to_string(@block.function) %></text>
<title>
<%= format_integer(@block.duration) %>&micro;s (<%= trunc(@block.duration * 100 / @top_block.duration) %>%) <%= mfa_to_string(@block.function) %>
<%= format_integer(@block.duration) %>&#181;s (<%= trunc(@block.duration * 100 / @top_block.duration) %>%) <%= mfa_to_string(@block.function) %>
</title>
</svg>
<% end %>
Expand Down
Loading