Chart (lv_chart)
Visualize data as lines, curves, bars, stacked bars, or scatter plots.
Overview
Charts visualize numeric data. They support:
- Multiple data series, added and removed at any time
- Up to four built-in axes (left/right Y, bottom/top X)
- Optional background division lines, cursors, and per-point markers
- Live updates through several update modes
- Scrolling and zooming
- Showing or hiding individual series, points, and cursors
Chart Basics
A chart is built from a few independent pieces, each covered in its own section below:
- a type (line / curve / bar / stacked / scatter) — see Chart type
- one or more data series, each pinned to one of the four built-in axes — see Data series
- a fixed point count that sizes every series' value array — see Number of points
- optional cursors to mark a location on the chart — see Cursor
- an update mode controlling how
lv_chart_set_next_valuereshapes the series — see Update modes
Drawing order is back-to-front: background and division lines, then data series in the order they were added, then cursors in the order they were added. The most recently added series and cursor sit on top.
Styling
-
LV_PART_MAINThe background of the chart. Uses the typical background and line style properties (for division lines). Padding makes the series area smaller. For BAR and STACKED chartspad_columnsets the space between bars in the same data series. -
LV_PART_SCROLLBARA scrollbar used if the chart is zoomed. See base widget's documentation for details. -
LV_PART_ITEMSRefers to the LINE or BAR data series.- LINE chart: line properties are used by lines.
width,height,bg_colorandradiusare used to set the appearance of points on the line. - Bar chart: The typical background properties are used to style the
bars.
pad_columnsets the space between columns in the same data series.
- LINE chart: line properties are used by lines.
-
LV_PART_INDICATORRefers to points on LINE- and SCATTER-charts (small circles or squares [with possibly-rounded corners]). -
LV_PART_CURSORLine properties are used to style cursors.width,height,bg_colorandradiusare used to set the appearance of the cursor's "point" showing its location. If eitherwidthorheightare set to 0, only the cursor's lines are drawn.
Chart type
For scatter charts each data point is an (X, Y) pair, and the series
binds to both an X axis and a Y axis with LV_CHART_AXIS_PRIMARY_X | LV_CHART_AXIS_PRIMARY_Y.
This C example also tints each point between red and blue based on its
position and fades older samples — both effects are driven from
LV_EVENT_DRAW_TASK_ADDED, so they stay in C even though the chart
itself is pure widget config:
A chart can be one of the following types:
LV_CHART_TYPE_NONE: Do not display any data. Can be used to hide chart's data.LV_CHART_TYPE_LINE: Draw lines between data points. Data points can also be illustrated if theirwidth,height,bg_colorandradiusstyles (forLV_PART_ITEMS) are set and bothwidthandheighthave non-zero values.LV_CHART_TYPE_CURVE: Similar to the LINE type, but it draws Bezier curves between data points.LV_USE_VECTOR_GRAPHICSand a draw unit (e.g. VGLite, or ThorVG for software rendering) need to be enabled. It also supports theline_dash_gap/widthstyle properties.LV_CHART_TYPE_BAR: Draw individual vertical bars for each point in each series.LV_CHART_TYPE_STACKED: Draw vertical stacked bars where multiple data series are displayed as segments within a single bar for each data point. Supports only positive values.LV_CHART_TYPE_SCATTER: X/Y chart drawing point's and optionally lines between the points if line-width style values forLV_PART_ITEMSis a non-zero value, and the point's Y-value is something other thanLV_CHART_POINT_NONE. (Drawing of individual points on a SCATTER chart can be suppressed if their Y-values are set toLV_CHART_POINT_NONE.)
Charts start their life as LINE charts. You can change a chart's type with
lv_chart_set_type(chart, LV_CHART_TYPE_...).
Data series
You can add any number of data series to a chart by using
lv_chart_add_series(chart, color, axis).
This allocates (and returns a pointer to) an lv_chart_series_t structure
which remembers the color and axis you specified, and comes pre-allocated
with an array of chart->point_cnt int32_t Y-values, all set to
LV_CHART_POINT_NONE. (A SCATTER chart also comes with a pre-allocated array of
the same number of X-values.)
axis specifies which axis is used to scale its values, and may be one of the following:
LV_CHART_AXIS_PRIMARY_Y: Left axisLV_CHART_AXIS_SECONDARY_Y: Right axisLV_CHART_AXIS_PRIMARY_X: Bottom axisLV_CHART_AXIS_SECONDARY_X: Top axis
When adding a data series to a SCATTER chart, bit-wise OR your selected Y axis (primary or secondary) with one of the X-axis values.
If you wish to have the chart use your own Y-value array instead of the one provided, you can do so with
lv_chart_set_series_ext_y_array(chart, series, value_array).
You are responsible for ensuring the array you provide contains at least
chart->point_cnt elements in it.
value_array should look like this: int32_t * value_array[num_points]. Only
the array's pointer is saved in the series so its contents need to remain available
for the life of the series, i.e. the array needs to be global, static or dynamically
allocated.
Call lv_chart_refresh(chart) when a chart's data has changed to
signal that the chart should be re-rendered next time a display refresh occurs.
You do not need to do this if you are using the provided value array(s) and
setting values with lv_chart_set_...value_...() functions. See below
for more information about these functions.
A pointer to the Y-value array of a series can be obtained with
lv_chart_get_series_y_array(chart, series). This is true whether you are using
the provided Y-value array or provided your own.
For SCATTER-type charts,
lv_chart_set_series_ext_x_array(chart, series, value_array)and-
lv_chart_get_series_x_array(chart, series)
can be used as well.
Modifying data
Four ways to write a series value:
| Function | Use when |
|---|---|
lv_chart_set_series_value_by_id(chart, ser, id, v) | updating one specific point by index |
lv_chart_set_next_value(chart, ser, v) | streaming live data — paired with Update modes |
lv_chart_set_all_values(chart, ser, v) | filling the whole series with one value |
ser->points[i] = v + lv_chart_refresh(chart) | bulk writes where the helpers would be overhead |
Use LV_CHART_POINT_NONE to hide a point. Scatter charts have
_set_series_value_by_id2 / _set_next_value2 variants that take both X
and Y.
Update modes
lv_chart_set_next_value writes into the series according to the chart's
update mode (set with lv_chart_set_update_mode):
LV_CHART_UPDATE_MODE_SHIFT— shift older points left, new value on the right.LV_CHART_UPDATE_MODE_CIRCULAR— overwrite oldest in place, leaving a gap that marks the write head (ECG-style).
Number of points
The number of points in the series can be modified by
lv_chart_set_point_count(chart, point_num). The default value is 10.
Note: this affects the number of points processed when an external
value array is assigned to a series, so you also need to be sure any external
array so provided contains at least point_num elements.
Handling large numbers of points
On LINE charts, if the number of points is greater than the pixels horizontally, the Chart will draw only vertical lines to make the drawing of large amount of data effective. If there are, let's say, 10 points to a pixel, LVGL searches the smallest and the largest value and draws a vertical lines between them to ensure no peaks are missed.
Vertical range
You can specify the minimum and maximum values in Y-direction with
lv_chart_set_axis_range(chart, axis, min, max). axis can be
LV_CHART_AXIS_PRIMARY_Y (left Y axis) or
LV_CHART_AXIS_SECONDARY_Y (right Y axis).
The value of the points will be scaled proportionally. The default range is: 0..100.
Division lines
The number of horizontal and vertical division lines can be modified by
lv_chart_set_div_line_count(chart, hdiv_num, vdiv_num). The default
settings are 3 horizontal and 5 vertical division lines. If there is a
visible border on a side and no padding on that side, the division line
would be drawn on top of the border and in this case it is not drawn so
as not to hide the chart border.
Override default start point for series
If you want a plot to start from a point other than the default which is
point[0] of the series, you can set an alternative index with the
function lv_chart_set_x_start_point(chart, series, id) where id is
the new zero-based index position to start plotting from.
Note that LV_CHART_UPDATE_MODE_SHIFT also changes the
start_point.
Tick marks and labels
With the help of Scale, vertical and horizontal scales can be added in a very flexible way. See the examples 2 below to learn more.
Scrolling/Zooming
To zoom the chart all you need to do is wrap it in a parent container and set the chart's width and/or height to a larger value. Doing this will cause the chart to be scrollable in its parent --- the parent container provides the scrollable "view window".
Cursor
Add a cursor with lv_chart_add_cursor(chart, color, dir). dir is one
or more LV_DIR_* values OR'd together — they pick which lines extend
from the cursor point. A new cursor starts hidden; place it with one of:
lv_chart_set_cursor_pos(chart, cursor, &point)— anchor at(x, y)in chart coordinates; the cursor scrolls with the chart.lv_chart_set_cursor_point(chart, cursor, series, point_id)— attach to a data point; the cursor follows it as values change.
Pass LV_CHART_POINT_NONE as the point_id to hide without removing.
lv_chart_get_point_pos_by_id returns a point's pixel coordinates if
you need to set up a cursor via lv_chart_set_cursor_pos.
Pressed-point tooltip
LV_EVENT_VALUE_CHANGED fires when the user presses a chart point;
lv_chart_get_pressed_point returns the index. This C example reads that
index and floats a small tooltip with the pressed value above the chart —
the kind of inspection helper XML can't drive on its own because it
requires a callback.
Drawing customisations
Chart styling stops at the part level — to vary appearance per data point
or paint custom shapes alongside the series, hook
LV_EVENT_DRAW_TASK_ADDED. The callback receives every draw task the chart
emits and may mutate the fill/stroke descriptors before they execute, or
draw extra shapes on the chart's layer.
Recolour bars between green and red based on their value:
Add a vertical gradient fill beneath a line series and restyle the division lines:
Events
LV_EVENT_VALUE_CHANGEDSent when a new point on the chart is pressed.lv_chart_get_pressed_point(chart)returns the zero-based index of the pressed point.
Learn more about Events emitted by all Widgets.
Last updated on