A simple Elixir charting library that generates easy to customize charts for Phoenix and LiveView.
- Easily generate pie charts, column charts, bar charts, progress counters, and line charts
- Generates responsive and accessible SVGs as LiveView components
- Provides advanced styling like gradients and rounded corners
- Smooth animations for updating live data to the UI
We've worked hard to ensure Uncharted Phoenix is both screen reader and keyboard accessible. Learn more about our approach here: Accessibility Documentation
Add this to your mix.exs deps:
{:uncharted_phoenix, "~> 0.2.0"}
To render any of the built-in UnchartedPhoenix chart components, pass an Uncharted.chart to the render/2 function:
my_chart = %Uncharted.BaseChart{...}
# Inside of a LiveView or LiveComponent .leex template:
<%= UnchartedPhoenix.render(@socket, @my_chart) %>By defining an implementation of the Uncharted.Component protocol for all of Uncharted's built-in chart types, UnchartedPhoenix.render/2 knows how to render the appropriate kind of chart based on the dataset of the Uncharted.BaseChart struct you pass in. For example, if you pass a chart with a %Uncharted.BarChart.Dataset{} to UnchartedPhoenix.render/2, UnchartedPhoenix will render the UnchartedPhoenix.LiveBarComponent for you and handle other setup the component needs to attach event handlers, such as giving the component an ID.
If you wish to render more than one of the same type of chart in the same view, you can override the default ID by defining a value for the %Uncharted.BaseChart{} struct's :component_id field.
By default, if you do not set the :component_id field on the BaseChart, UnchartedPhoenix will give the LiveComponent it renders an id equal to the stringified version of the dataset module defined on the BaseChart, i.e. if you pass a BaseChart with an Uncharted.BarChart.Dataset to UnchartedPhoenix.render/2, the id of the LiveBarComponent that gets rendered will be "Uncharted.BarChart.Dataset". If you define a component_id on your BaseChart struct, the component_id will be appended to the default id like this: "Uncharted.BarChart.Dataset__#{my_custom_component_id}".
column_chart = %BaseChart{
title: "Cheese Coney Consumption by Neighborhood",
colors: colors,
width: 700,
height: 400,
dataset: %ColumnChart.Dataset{
axes: %BaseAxes{
magnitude_axis: %MagnitudeAxis{
max: 10_000,
min: 0
}
},
data: Cincy.get()
}
}defp bar_chart do
memory_data = MemoryChart.get()
data = MemoryChart.convert_to_datum(memory_data)
%BaseChart{
title: "Live Beam Memory Stats",
width: 600,
height: 400,
colors: %{
blue: "#36D1DC",
rosy_gradient: %Gradient{
start_color: "#642B73",
stop_color: "#C6426E"
}
},
dataset: %BarChart.Dataset{
axes: %BaseAxes{
magnitude_axis: %MagnitudeAxis{
max: MemoryChart.chart_max(memory_data),
min: 0
}
},
data: data
}
}
endpie_chart = %BaseChart{
title: "Best kind of pie",
colors: %{
rose_gradient: %Gradient{
start_color: "#642B73",
stop_color: "#C6426E"
},
blue_gradient: %Gradient{
start_color: "#36D1DC",
stop_color: "#5B86E5"
},
red_gradient: %Gradient{
start_color: "#FF9486",
stop_color: "#FF1379"
}
},
dataset: %PieChart.Dataset{
data: [
%BaseDatum{
name: "Pecan",
fill_color: :red_gradient,
values: [20.0]
},
%BaseDatum{
name: "Blueberry",
fill_color: :blue_gradient,
values: [28.0]
},
%BaseDatum{
name: "Pumpkin",
fill_color: :rose_gradient,
values: [35.0]
},
%BaseDatum{
name: "Chocolate",
fill_color: :blue_gradient,
values: [17.0]
}
]
}
}line_chart = %BaseChart{
title: "Live Line Chart",
colors: colors,
width: 700,
height: 400,
dataset: %ColumnChart.Dataset{
axes: %XYAxes{
x: %MagnitudeAxis{
max: 700,
min: 0
},
y: %MagnitudeAxis{
max: 2500,
min: 0
}
},
data: [
%BaseDatum{
name: "Point 1",
fill_color: :blue_gradient,
values: [70, 500]
},
%BaseDatum{
name: "Point 2",
fill_color: :blue_gradient,
values: [150, 1000]
},
%BaseDatum{
name: "Point 3",
fill_color: :blue_gradient,
values: [350, 1600]
},
%BaseDatum{
name: "Point 4",
fill_color: :blue_gradient,
values: [450, 1500]
},
%BaseDatum{
name: "Point 5",
fill_color: :blue_gradient,
values: [550, 2000]
}
]
}
}defp progress_chart(from: %BaseChart{} = chart) do
memory = Memory.get()
%BaseChart{
chart
| title: "Process Memory / Total",
colors: %{
rose_gradient: %Gradient{
start_color: "#642B73",
stop_color: "#C6426E"
},
blue_gradient: %Gradient{
start_color: "#36D1DC",
stop_color: "#5B86E5"
},
red_gradient: %Gradient{
start_color: "#FF9486",
stop_color: "#FF1379"
},
gray: "#e2e2e2"
},
dataset: %ProgressChart.Dataset{
background_stroke_color: :gray,
label: "Proc Memory",
secondary_label: "(% Of Total)",
to_value: memory.total,
current_value: memory.process,
percentage_text_fill_color: :blue_gradient,
percentage_fill_color: :rose_gradient,
label_fill_color: :rose_gradient,
doughnut_width: 5,
progress_shape: :round
}
}
endBase chart configuration allows you to define set solid colors and gradients for any chart you will use within the application.
colors = %{
blue: "#6bdee4"
}colors = %{
rose_gradient: %Gradient{
start_color: "#642B73",
stop_color: "#C6426E"
}
}You can configure the color and width of grid lines, as well as whether or not to display them. Set line_color to a string or the atom key of a set base color or gradient (see above). Set line_width to an integer to change the width of grid lines. Set display_lines to false to hide grid lines along that axis. Set show_gridlines on XYAxes or BaseAxes to false to hide all grid lines.
%MagnitudeAxis{
line_color: "#efefef"
line_width: 2,
display_lines: true
}



