LiveCharts allows you to render static and dynamic charts in Phoenix LiveView applications.
LiveCharts currently comes with support for ApexCharts out of the box, but it
can work with any JS charting library that has a LiveCharts.Adapter
defined.
To see live demos, visit: livecharts.stax3.com.
Add :live_charts
to your mix.exs
dependencies:
defp deps do
[
{:live_charts, "~> 0.3.0"},
]
end
Then include the LiveCharts hooks in your app.js
:
// Import the JS file
import LiveCharts from "live_charts"
// Include the hooks
let liveSocket = new LiveSocket("/live", Socket, {
params: {_csrf_token: csrfToken},
hooks: {
// your other hooks...
// e.g. SomeCustomHook,
// Expand LiveCharts hooks at the end
...LiveCharts.Hooks,
},
});
LiveCharts may optionally be configured to set the default adapter or JSON encoding library. It currently defaults to the following:
# config/config.exs
config :live_charts,
adapter: LiveCharts.Adapter.ApexCharts,
json_library: Jason
LiveCharts tracks a chart's data and configuration in a %Chart{}
struct.
Before it can be rendered, you need to build this struct.
my_chart =
LiveCharts.build(%{
# (Optional) a unique string id to differentiate the chart from other
# charts on the same page. If not set, a random id will be assigned
# to the chart.
id: "my-custom-chart-id",
# Set the chart type. Supports `:line`, `:bar`, `:pie`, `:donut`,
# `:area`, and many more. For a full list of supported types, see the
# adapter or JS library documentation.
type: :bar,
# A list of series data with all the datapoints to chart. Format of
# this data is determined by the adapter/JS library. This may also
# be empty, if you plan to push dynamic updates to the chart over
# the socket later.
series: [
%{name: "Sales", data: [10, 20, 30, 40, 50]},
],
# (Optional) Other library and adapter-specific options.
options: %{
xaxis: %{
categories: [2021, 2022, 2023, 2024, 2025]
},
},
# (Optional) set the adapter to use for the chart. If not set, uses
# the global adapter configured in `config.exs` (defaults to
# `LiveCharts.Adapter.ApexCharts`).
adapter: LiveCharts.Adapter.ApexCharts,
})
For a full list of options, see the official ApexCharts docs and
the LiveCharts.Adapter.ApexCharts
adapter information on HexDocs.
You can also view live demos here.
With a LiveCharts.Chart
struct defined, you can now assign
it in your liveview:
def mount(_params, _session, socket) do
socket =
socket
|> assign(:page_title, "Page with charts!")
|> assign(:my_chart, my_chart)
{:ok, socket}
end
To then render the chart in a heex template, use LiveCharts.chart/1
component:
<LiveCharts.chart chart={@my_chart} />
This will re-render the chart on the page any time the chart
assign is changed or updated.
If the chart needs to be updated often, a better strategy is to only push the new data instead of rebuilding the entire chart and re-rendering it. You can do so by calling:
LiveCharts.push_update(socket, chart.id, updated_series)
Let's say we want to render a line chart that starts out empty, but as we get datapoints from an external source, we want to push them to the users' browsers.
We'll start by assigning a line chart to the LiveView:
@impl true
def mount(_params, _session, socket) do
# Build an empty chart with custom settings
chart = LiveCharts.build(%{
type: :line,
series: [],
options: %{
xaxis: %{type: "datetime"},
yaxis: %{min: 0, max: 100},
chart: %{
animations: %{enabled: true, easing: "linear"},
zoom: %{enabled: false}
}
}
})
socket =
socket
|> assign(:chart, chart)
|> assign(:chart_data, [])
{:ok, socket}
end
Then, render the empty chart in your heex template:
<LiveCharts.chart chart={@chart} />
Assuming you already have a mechanism in place to receive new data points in the liveview, you can then update the chart data and push it over the socket:
@impl true
def handle_info({:chart_datapoint, {x, y}}, socket) do
%{chart: chart, chart_data: data} = socket.assigns
data = [%{x: x, y: y} | data]
series = [%{data: Enum.reverse(data)}]
socket =
socket
|> assign(:chart_data, data)
|> LiveCharts.push_update(chart, series)
{:noreply, socket}
end
We have used handle_info/2
here, but chart updates could just as easily be pushed from other
liveview callbacks. E.g. from handle_event/3
when the user triggers an event or
handle_async/3
when an async task is completed.
A live demo is also available on livecharts.stax3.com.
Stax3 helps startups craft expressive and engaging solutions for their software needs. If you're looking for expertise for your Elixir/Phoenix projects, we can help! Talk to us at [email protected].
LiveCharts is licensed under the MIT License.