LiveFlow - A Phoenix LiveView library for building interactive node-based diagrams.
LiveFlow provides components and utilities for creating flow diagrams similar to React Flow or Svelte Flow, but using Phoenix LiveView and LiveComponents.
Quick Start
# In your LiveView
defmodule MyAppWeb.FlowLive do
use MyAppWeb, :live_view
alias LiveFlow.{State, Node, Edge}
def mount(_params, _session, socket) do
flow = State.new(
nodes: [
Node.new("1", %{x: 100, y: 100}, %{label: "Start"}),
Node.new("2", %{x: 300, y: 200}, %{label: "End"})
],
edges: [
Edge.new("e1", "1", "2")
]
)
{:ok, assign(socket, flow: flow)}
end
def render(assigns) do
~H"""
<.live_component
module={LiveFlow.Components.Flow}
id="my-flow"
flow={@flow}
opts={%{controls: true, background: :dots}}
/>
"""
end
endComponents
LiveFlow.Components.Flow- Main flow container componentLiveFlow.Components.NodeWrapper- Node wrapper componentLiveFlow.Components.Edge- Edge rendering componentLiveFlow.Components.Handle- Handle component for connections
Data Structures
LiveFlow.Node- Node structLiveFlow.Edge- Edge structLiveFlow.Handle- Handle structLiveFlow.Viewport- Viewport (pan/zoom) stateLiveFlow.State- Main state container
Path Types
LiveFlow.Paths.Bezier- Smooth curved pathsLiveFlow.Paths.Straight- Direct linesLiveFlow.Paths.Step- Orthogonal paths with 90° turnsLiveFlow.Paths.Smoothstep- Orthogonal paths with rounded corners
Summary
Functions
Animates nodes of the flow rendered with id to new positions.
Creates a new flow state with the given nodes and edges.
Functions
@spec animate_positions( Phoenix.LiveView.Socket.t(), String.t(), LiveFlow.State.t(), map() | list(), keyword() ) :: Phoenix.LiveView.Socket.t()
Animates nodes of the flow rendered with id to new positions.
Instead of updating the state right away, the client animates the nodes
(and their edges) and pushes the final positions back as an
lf:node_change event, which the usual node change handling applies.
positions is a map (or list of {id, position}) of node IDs to
%{x: x, y: y}. For child nodes the position is relative to the parent,
like LiveFlow.Node.position.
Options
:duration- Animation duration in milliseconds (default:300):fit_view- Also fit the view to the final positions,trueor%{padding: 0.1}(default:false)
Examples
positions = LiveFlow.Layout.tree(flow, direction: :lr)
{:noreply, LiveFlow.animate_positions(socket, "my-flow", flow, positions)}
@spec create_flow(keyword()) :: LiveFlow.State.t()
Creates a new flow state with the given nodes and edges.
Examples
iex> LiveFlow.create_flow(
...> nodes: [
...> %{id: "1", position: %{x: 0, y: 0}, data: %{label: "A"}},
...> %{id: "2", position: %{x: 100, y: 100}, data: %{label: "B"}}
...> ],
...> edges: [
...> %{id: "e1", source: "1", target: "2"}
...> ]
...> )
See LiveFlow.Edge.new/4.
See LiveFlow.Node.new/4.
See LiveFlow.State.new/1.