目录
- 一、图表
- 1、组成
- 2、类型
- 3、显示数据
- 3.1 lv_chart_set_ext_y_array/lv_chart_set_ext_x_array
- 3.2 lv_chart_set_next_value
- 3.3 lv_chart_set_all_value
- 3.4 lv_chart_set_value_by_id
- 3.5 在数组中手动设置
- 4、设置数据点数量
- 5、辅助功能
- 5.1 垂直范围
- 5.2 分隔线
- 5.3 设置默认起始点
- 5.4 刻度线和刻度线标签
- 5.5 缩放
- 5.6 游标
- 6、API 函数
一、图表
1、组成
图表部件由六个部分组成,如下表所示:
组成部分 | 描述 |
---|---|
LV_PART_MAIN | 主要设置背景属性和线条(用于分隔线)相关的样式属性 |
LV_PART_SCROLLBAR | 主要设置缩放图表时使用的滚动条 |
LV_PART_ITEMS | 根据图表类型(折线图和条形图)设置 折线图:设置线属性,如宽度、高度、bg_color 和半径 条形图:背景属性 |
LV_PART_INDICATOR | 设置折线图和散点图上的点(小圆或小方)的属性 |
LV_PART_CURSOR | 设置游标,比如它的宽度、高度、bg_color 和半径 |
LV_PART_TICKS | 设置线条和文本样式属性用于设置刻度的样式 |
lv_obj_t *chart = lv_chart_create(lv_scr_act());
lv_obj_center(chart);
LV_CHART_AXIS_PRIMARY_Y
: 左轴LV_CHART_AXIS_SECONDARY_Y
: 右轴LV_CHART_AXIS_PRIMARY_X
: 下轴LV_CHART_AXIS_SECONDARY_X
: 上轴
这些属性在后面添加数据的时候会用到。
2、类型
图表的类型分为两种,这两种类型分为折线图和条形图,这些图表的类型是由函数 lv_chart_set_type
设置,该函数可设置四种模式,这些模式如下表所示:
模式 | 描述 |
---|---|
LV_CHART_TYPE_NONE | 隐藏数据显示 |
LV_CHART_TYPE_LINE | 点与点连接成线(折线图) |
LV_CHART_TYPE_BAR | 条形图 |
LV_CHART_TYPE_SCATTER | X/Y 图画点和点之间的线 |
上表的模式主要配置图表数据绘画类型,一般常用的模式是 LV_CHART_TYPE_LINE
和 LV_CHART_TYPE_BAR
。下面我们使用一个示意图来描述这两种模式的图表,如下图所示:
3、显示数据
在不同类型的图表中,数据序列的表示方式各不相同:
- 条形图:数据序列由一系列具有相同填充(颜色或纹理)的条形表示。
- 折线图(也称为图形):数据序列用单线表示。
图表的数据序列可调用函数 lv_chart_add_series(chart, color, axis)
添加,其中 axis 就是在第一小节中提到的四个属性之一,表示数据缩放方向。
默认情况下,图表部件只支持 10 个数据点。面我们分别地讲解五种添加数据的过程。
3.1 lv_chart_set_ext_y_array/lv_chart_set_ext_x_array
函数 lv_chart_set_ext_y_array
是为 Y 轴数据点设置一个外部阵列,该函数一般用在折线图和条形图类型。函数 lv_chart_set_ext_x_array
是为 X 轴数据点设置一个外部阵列,该函数一般用在 LV_CHART_TYPE_SCATTER
类型上。
例:
static const lv_coord_t example_data[] = {
25, 26, 27, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
};
void my_gui(void) {
lv_obj_t *chart = lv_chart_create(lv_scr_act()); /* 创建图表部件 */
lv_obj_set_size(chart, 200, 150); /* 设置图表大小 */
lv_obj_center(chart); /* 中间对齐 */
lv_chart_set_type(chart, LV_CHART_TYPE_LINE); /* 设置折线图类型 */
/* 添加数据序列 */
lv_chart_series_t* ser1 = lv_chart_add_series(chart,
lv_palette_main(LV_PALETTE_RED),
LV_CHART_AXIS_SECONDARY_X);
/* 为 Y 轴数据点设置一个外部阵列 */
lv_chart_set_ext_y_array(chart, ser1, (lv_coord_t*)example_data);
lv_chart_refresh(chart); /* 更新图表 */
}
3.2 lv_chart_set_next_value
该函数主要设置图表的下一个数值,使用该函数添加数据到图表的模式具有两种,如下表所示:
模式 | 描述 |
---|---|
LV_CHART_UPDATE_MODE_SHIFT | 将旧数据移到左边,并将新数据添加到右边 |
LV_CHART_UPDATE_MODE_CIRCULAR | 以循环的方式添加新数据,就像心电图一样 |
上述的模式是由 lv_chart_set_update_mode
设置,图表会根据这些模式来设置添加数据的方式。
例:
static lv_obj_t *chart;
static lv_obj_t *chart1;
static void add_data(lv_timer_t* timer) {
LV_UNUSED(timer);
lv_chart_set_next_value(chart, timer->user_data, lv_rand(20, 90));
}
static void lv_add_data(lv_timer_t* timer) {
LV_UNUSED(timer);
lv_chart_set_next_value(chart1, timer->user_data, lv_rand(20, 90));
}
void my_gui(void) {
chart = lv_chart_create(lv_scr_act()); /* 创建图表部件 */
lv_obj_set_size(chart, 200, 150); /* 设置图表大小 */
lv_obj_center(chart); /* 中间对齐 */
/* 将旧数据移到左边 */
lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT);
/* 添加数据序列 */
lv_chart_series_t* ser1 = lv_chart_add_series(chart,
lv_palette_main(LV_PALETTE_RED),
LV_CHART_AXIS_SECONDARY_X);
lv_timer_create(add_data, 200, ser1); /* 创建定时器 */
lv_chart_refresh(chart); /* 更新图表 */
chart1 = lv_chart_create(lv_scr_act());
lv_obj_set_size(chart1, 200, 150);
/* 对齐 */
lv_obj_align_to(chart1, chart,LV_ALIGN_OUT_BOTTOM_MID,0,20);
/* 添加数据序列 */
lv_chart_series_t* ser2 = lv_chart_add_series(chart1,
lv_palette_main(LV_PALETTE_RED),
LV_CHART_AXIS_SECONDARY_X);
/* 以循环的方式添加新数据 */
lv_chart_set_update_mode(chart1, LV_CHART_UPDATE_MODE_CIRCULAR);
lv_timer_create(lv_add_data, 200, ser2); /* 创建定时器 */
lv_chart_refresh(chart1); /* 更新图表 */
}
3.3 lv_chart_set_all_value
该函数是把所有的数据都初始化为一个数值。前面我们讲解到图表部件只支持 10 个数据点,如果我们使用这个函数初始化数据点,则这些数据点的数值都是一样的。
3.4 lv_chart_set_value_by_id
此函数主要修改某个数据点的数值,前面我们讲到图表部件默认只支持 10 数据点,这些数据点是从 0 开始自增。
3.5 在数组中手动设置
使用 lv_chart_add_series
函数所返回的数据序列指针的成员变量 y_points
或者 x_points
数组设置数值,如 ser2->y_points[0] = 90
。
上述五种添加数据的方式常用的是第一种和第二种方式,这些方式都必须在后面调用函数 lv_chart_refresh
更新数据。
4、设置数据点数量
前面提过,图表部件默认只支持 10 个数据点,如果我们具有11 个数据,那么图表先显示前 10 个数据,而第 11 个数据会将图表的 10 个数据逐一往左移位,最后把第一个数据点的数值去除了。下面我们使用一个示意图来讲解上述的过程,如下图所示:
我们可以通过调用函数 lv_chart_set_point_count
来设置该图表所支持的数据点。注意:当一个外部缓冲区被分配给一个序列时,这也会影响处理的点数,所以你需要确保外部数组足够大。
lv_chart_set_point_count(chart, 20);
5、辅助功能
5.1 垂直范围
垂直范围是指图表所添加的数据不能超出这个范围。图表默认的垂直范围为 0~100
,我们可以手动调用函数 lv_chart_set_range
设置垂直范围。注意:设置垂直范围的数据序列必须是 LV_CHART_AXIS_PRIMARY
和 LV_CHART_AXIS_SECONDARY
。
原本图像显示如上图,现在将范围设置为 0~50
:
lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 50);
5.2 分隔线
LVGL 的图表部件默认设置为 3 条水平分隔线和 5 条垂直分隔线,如果某边有可见的边框且该边没有填充,则分割线将绘制在边框的顶部。图表部件分割线是调用函数 lv_chart_set_div_line_count
设置,该函数的第二和第三个形参表示水平和垂直分割线的数量。
lv_chart_set_div_line_count(chart, 10, 10);
5.3 设置默认起始点
如果用户想让绘图从一个点开始而不是默认值point [0]点开始,我们可以使用函数 lv_chart_set_x_start_point(chart, ser, id)
设置一个替代索引,其中 id 是开始绘图的新索引位置。
5.4 刻度线和刻度线标签
刻度由刻度标签和刻度线组成,若要进一步设置刻度样式,就需要引入刻度定位器(locator)和刻度格式器(formatter)的概念。刻度定位器用来设置刻度线的位置;刻度格式器用来设置刻度标签的显示样式。
刻度线和刻度线标签的需要用户调用函数 lv_chart_set_axis_tick
添加到当前图表中,该函数具有八个形参,这些形参主要设置刻度线和刻度线的标签。
void lv_chart_set_axis_tick(lv_obj_t * obj,
lv_chart_axis_t axis,
lv_coord_t major_len,
lv_coord_t minor_len,
lv_coord_t major_cnt,
lv_coord_t minor_cnt,
bool label_en,
lv_coord_t draw_size)
- obj:指向图表对象的指针
- axis:计数的轴:
LV_CHART_AXIS_X / PRIMARY_Y / SECONDARY_Y
- major_len:主刻度长度
- minor_len:小刻度长度
- major_cnt:主刻度的数量
- minor_cnt:小刻度的数量
- label_en:true:启用在主刻度上绘制标签
- draw_size:绘制刻度和标签所需的额外大小
lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 6, 5, true, 40);
lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 10, 5, 10, 1, true, 30);
5.5 缩放
图表缩放指的是局部放大或缩小图表,可以更方便的查看图表数据。LVGL 的图表缩放接口由两个函数设置,一个是 lv_chart_set_zoom_x
对 X 轴缩放;另一个是 lv_chart_set_zoom_y
对 Y 轴缩放。它们的的第二个形参表示缩放因子,如果缩放因子为 256,则图表没有缩放;如果
缩放因子大于 256 且小于等于 512,则图表进行缩放。
5.6 游标
图表游标可以查看数据是否溢出指定的范围。图表游标需要用户调用函数 lv_chart_add_cursor
添加,该函数具有三个形参,它们分别指向图表对象、游标颜色以及游标的方向。游标的方向形参可以设置 LV_DIR_NONE/RIGHT/UP/LEFT/DOWN/HOR/VER/ALL
配置项并告诉游标应该在哪个方向绘制。可以通过 OR 设置多个方向。
设置图表游标的位置具有两个方式,如下所示:
lv_chart_set_cursor_pos(chart, cursor, &point))
函数的 Pos 形参是一个指向lv_point_t
变量的指针。例如lv_point_t point ={10,20}
;如果图表被滚动,游标将保持在相同的位置。lv_chart_set_cursor_point (chart, cursor, series, point_id)
将游标粘在一个点上。 如果点的位置改变(滚动),游标将随着点移动。
lv_chart_cursor_t* cursor;
cursor = lv_chart_add_cursor(chart, lv_palette_main(LV_PALETTE_GREEN), LV_DIR_BOTTOM);
lv_point_t point = {20, 30};
lv_chart_set_cursor_pos(chart, cursor, &point);
6、API 函数
函数 | 描述 |
---|---|
lv_chart_create() | 创建图表对象 |
lv_chart_set_type() | 为图表设置一个新的类型 |
lv_chart_set_point_count() | 设置数据线上的点数 |
lv_chart_set_range() | 设置轴上的最小和最大y 值 |
lv_chart_set_update_mode() | 设置图表对象的更新模式 |
lv_chart_set_div_line_count() | 设置水平和垂直分隔线的数量 |
lv_chart_set_zoom_x() | 按X 方向放大图表 |
lv_chart_set_zoom_y() | 按Y 方向放大图表 |
lv_chart_get_zoom_x() | 获取X 缩放数值 |
lv_chart_get_zoom_y() | 获取Y 缩放数值 |
lv_chart_set_axis_tick() | 设置轴线上的划线数 |
lv_chart_get_type() | 获取图表的类型 |
lv_chart_get_point_count() | 获取图表上每条数据线的数据点数字 |
lv_chart_get_x_start_point() | 获取数据数组中x 轴起点的当前索引 |
lv_chart_get_point_pos_by_id() | 获取图表中一个点的位置 |
lv_chart_refresh() | 如果图表的数据线发生了变化,请刷新图表 |
lv_chart_add_series() | 添加数据序列到图表 |
lv_chart_remove_series() | 从图表中释放并删除数据序列 |
lv_chart_hide_series() | 隐藏/取消隐藏图表的单个数据系列 |
lv_chart_set_series_color() | 改变一个数据系列的颜色 |
lv_chart_set_x_start_point() | 设置数据数组中x 轴起点的索引 |
lv_chart_get_series_next() | 下一个数据系列 |
lv_chart_add_cursor() | 添加一个给定颜色的游标 |
lv_chart_set_cursor_pos() | 设置游标在点的坐标 |
lv_chart_set_cursor_point() | 把游标固定在一个点上 |
lv_chart_get_cursor_point() | 获取游标在点的坐标 |
lv_chart_set_all_value() | 用一个值初始化序列中的所有数据点 |
lv_chart_set_next_value() | 根据更新模式策略设置下一个点的Y 值 |
lv_chart_set_next_value2() | 根据更新模式策略设置下一个点的X 和Y 值 |
lv_chart_set_value_by_id() | 直接根据索引设置图表序列中单个点的y 值 |
lv_chart_set_value_by_id2() | 根据索引直接设置图表系列的单个点的x和y值(只能在LV_CHART_TYPE_SCATTER 类型图表设置) |
lv_chart_set_ext_y_array() | 设置用于图表的y 数据点的外部数组 |
lv_chart_set_ext_x_array() | 设置用于图表的x 数据点的外部数组 |
lv_chart_get_y_array() | 获取一个系列的y 值的数组 |
lv_chart_get_x_array() | 获取一个系列的x 值的数组 |
lv_chart_get_pressed_point() | 获取当前被压点的指数 |