Chart (lv_chart)

Visualize data as lines, curves, bars, stacked bars, or scatter plots.

Edit on GitHub

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_value reshapes 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_MAIN The 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 charts pad_column sets the space between bars in the same data series.

  • LV_PART_SCROLLBAR A scrollbar used if the chart is zoomed. See base widget's documentation for details.

  • LV_PART_ITEMS Refers to the LINE or BAR data series.

    • LINE chart: line properties are used by lines. width, height, bg_color and radius are used to set the appearance of points on the line.
    • Bar chart: The typical background properties are used to style the bars. pad_column sets the space between columns in the same data series.
  • LV_PART_INDICATOR Refers to points on LINE- and SCATTER-charts (small circles or squares [with possibly-rounded corners]).

  • LV_PART_CURSOR Line properties are used to style cursors. width, height, bg_color and radius are used to set the appearance of the cursor's "point" showing its location. If either width or height are 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 their width, height, bg_color and radius styles (for LV_PART_ITEMS) are set and both width and height have non-zero values.
  • LV_CHART_TYPE_CURVE: Similar to the LINE type, but it draws Bezier curves between data points. LV_USE_VECTOR_GRAPHICS and a draw unit (e.g. VGLite, or ThorVG for software rendering) need to be enabled. It also supports the line_dash_gap/width style 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 for LV_PART_ITEMS is a non-zero value, and the point's Y-value is something other than LV_CHART_POINT_NONE. (Drawing of individual points on a SCATTER chart can be suppressed if their Y-values are set to LV_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:

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,

can be used as well.

Modifying data

Four ways to write a series value:

FunctionUse 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):

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:

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

Learn more about Events emitted by all Widgets.

Last updated on

On this page