LVGL 控件之图表部件(lv_chart)


一、图表

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_SCATTERX/Y 图画点和点之间的线

上表的模式主要配置图表数据绘画类型,一般常用的模式是 LV_CHART_TYPE_LINELV_CHART_TYPE_BAR。下面我们使用一个示意图来描述这两种模式的图表,如下图所示:

3、显示数据

在不同类型的图表中,数据序列的表示方式各不相同:

  1. 条形图:数据序列由一系列具有相同填充(颜色或纹理)的条形表示。
  2. 折线图(也称为图形):数据序列用单线表示。

图表的数据序列可调用函数 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_PRIMARYLV_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 设置多个方向。

设置图表游标的位置具有两个方式,如下所示:

  1. lv_chart_set_cursor_pos(chart, cursor, &point)) 函数的 Pos 形参是一个指向 lv_point_t 变量的指针。例如 lv_point_t point ={10,20};如果图表被滚动,游标将保持在相同的位置。
  2. 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()获取当前被压点的指数
评论 41
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值