让你的GUI统计更直观?试试 LVGL『Chart图表控件』吧

一. LVGL GUI图表控件的概念

图表是可视化数据点的基本对象。它们支持折线图(将点与线连接和/或在其上绘制点)和柱形图。

二. LVGL GUI图表小部件和样式

图表的主要部分被称为 LV_CHART_PART_BG ,它使用所有典型的背景属性。该文本样式属性确定轴文本的风格和线条属性决定了刻度的风格。 填充值在侧面增加了一些空间,因此使序列区域更小。
填充也可用于为轴文本和刻度线留出空间。
组合的背景称为 LV_CHART_PART_SERIES_BG ,并放置在主要背景上。在此部分上绘制了分隔线和系列数据。除典型的背景样式属性外,分割线还使用线型属性。所述填充值告诉该部分与轴的文本
之间的空间。
组合的样式可以通过引用 LV_CHART_PART_SERIES 。对于列类型,使用以下属性:

  • radius:条的半径
  • padding_inner:相同 x 坐标的列之间的间隔

如果是线型,则使用以下属性:

  • 线属性来描述线
  • 点的大小半径
  • bg_opa:线条下方区域的整体不透明度
  • bg_main_stop:顶部以创建一个 alpha 褪色(0:在顶部透明,255:bg_opa 在顶部)
  • bg_grad_stop:底部 创建 alpha 渐变(0:底部透明,255:bg_opa 顶部)
  • bg_drag_dir:应该 LV_GRAD_DIR_VER 允许通过 bg_main_stop 和 bg_grad_stop 进行Alpha 淡入

来一段代码演示下

void lvgl_chart_style_test(void)
{
    /*Create a chart*/
    lv_obj_t* chart = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart, 200, 150);
    lv_obj_align(chart, NULL, LV_ALIGN_CENTER, -150, 0);
    lv_chart_set_type(chart, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    /*Add a faded are effect*/
    lv_obj_set_style_local_bg_opa(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT, LV_OPA_50); /*Max. opa.*/
    lv_obj_set_style_local_bg_grad_dir(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT, LV_GRAD_DIR_VER);
    lv_obj_set_style_local_bg_main_stop(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT, 255);    /*Max opa on the top*/
    lv_obj_set_style_local_bg_grad_stop(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT, 0);      /*Transparent on the bottom*/

    /*Add two data series*/
    lv_chart_series_t* ser1 = lv_chart_add_series(chart, LV_COLOR_GREEN);

    /*Set the next points on 'ser1'*/
    lv_chart_set_next(chart, ser1, 31);
    lv_chart_set_next(chart, ser1, 66);
    lv_chart_set_next(chart, ser1, 10);
    lv_chart_set_next(chart, ser1, 89);
    lv_chart_set_next(chart, ser1, 63);
    lv_chart_set_next(chart, ser1, 56);
    lv_chart_set_next(chart, ser1, 32);
    lv_chart_set_next(chart, ser1, 35);
    lv_chart_set_next(chart, ser1, 57);
    lv_chart_set_next(chart, ser1, 85);

    lv_chart_refresh(chart); /*Required after direct set*/

    lv_obj_t* chart2 = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart2, 200, 150);
    lv_obj_align(chart2, NULL, LV_ALIGN_CENTER, 150, 0);
    lv_chart_set_type(chart2, LV_CHART_TYPE_LINE);   /*Show lines and points too*/
    lv_obj_set_style_local_bg_color(chart2, LV_CHART_PART_BG, LV_STATE_DEFAULT, LV_COLOR_RED);

    lv_chart_series_t* chart2_ser1 = lv_chart_add_series(chart2, LV_COLOR_GREEN);
    /*Set the next points on 'ser1'*/
    lv_chart_set_next(chart2, chart2_ser1, 31);
    lv_chart_set_next(chart2, chart2_ser1, 66);
    lv_chart_set_next(chart2, chart2_ser1, 10);
    lv_chart_set_next(chart2, chart2_ser1, 89);
    lv_chart_set_next(chart2, chart2_ser1, 63);
    lv_chart_set_next(chart2, chart2_ser1, 56);
    lv_chart_set_next(chart2, chart2_ser1, 32);
    lv_chart_set_next(chart2, chart2_ser1, 35);
    lv_chart_set_next(chart2, chart2_ser1, 57);
    lv_chart_set_next(chart2, chart2_ser1, 85);
    //lv_chart_refresh(chart2); /*Required after direct set*/
}

三. LVGL GU图表控件的使用

1. 数组组合(Data series)

通过这个函数来申请数据集合lv_chart_add_series

2. 组合类型(Series' type)

通过这个函数lv_chart_set_type(chart, LV_CHART_TYPE_...),有记下值:

  • LV_CHART_TYPE_NONE-不显示任何数据。可用于隐藏。
  • LV_CHART_TYPE_LINE-在两点之间画线。
  • LV_CHART_TYPE_COLUMN-绘制列。

3. 修改数据(Modify the data)

有以下方法修改数据

  • Set the values manually in the array like ser1->points[3] = 7 and refresh the chart with lv_chart_refresh(chart).
  • Use lv_chart_set_point_id(chart, ser, value, id) where id is the index of the point you wish to update.
  • Use the lv_chart_set_next(chart, ser, value).
  • Initialize all points to a given value with: lv_chart_init_points(chart, ser, value).
  • Set all points from an array with: lv_chart_set_points(chart, ser, value_array).

下面我们就1、2、3小节写一个例子

void lvgl_chart_test(void)
{
    lv_coord_t pos_array[] = { 10,10,20,20,30,30 };
    /*Create a chart*/
    lv_obj_t* chart = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart, 200, 150);
    lv_obj_align(chart, NULL, LV_ALIGN_CENTER, -150, 0);
    lv_chart_set_type(chart, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    /*Add two data series*/
    lv_chart_series_t* ser1 = lv_chart_add_series(chart, LV_COLOR_RED);
    lv_chart_series_t* ser2 = lv_chart_add_series(chart, LV_COLOR_GREEN);
    lv_chart_series_t* ser3 = lv_chart_add_series(chart, LV_COLOR_BLACK);

    /*Set the next points on 'ser1'*/
    lv_chart_set_next(chart, ser1, 10);
    lv_chart_set_next(chart, ser1, 10);
    lv_chart_set_next(chart, ser1, 10);
    lv_chart_set_next(chart, ser1, 10);
    lv_chart_set_next(chart, ser1, 10);
    lv_chart_set_next(chart, ser1, 10);
    lv_chart_set_next(chart, ser1, 10);
    lv_chart_set_next(chart, ser1, 30);
    lv_chart_set_next(chart, ser1, 70);
    lv_chart_set_next(chart, ser1, 90);

    /*Directly set points on 'ser2'*/
    ser2->points[0] = 90;
    ser2->points[1] = 70;
    ser2->points[2] = 65;
    ser2->points[3] = 65;
    ser2->points[4] = 65;
    ser2->points[5] = 65;
    ser2->points[6] = 65;
    ser2->points[7] = 65;
    ser2->points[8] = 65;
    ser2->points[9] = 65;

    
    lv_chart_set_points(chart, ser3, pos_array);

    lv_chart_refresh(chart); /*Required after direct set*/


    /*Create a chart*/
    lv_obj_t* chart2 = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart2, 200, 150);
    lv_obj_align(chart2, NULL, LV_ALIGN_CENTER, 150, 0);
    lv_chart_set_type(chart2, LV_CHART_TYPE_COLUMN);   /*Show lines and points too*/
    lv_chart_series_t* chart2_ser1 = lv_chart_add_series(chart2, LV_COLOR_RED);
    lv_chart_set_points(chart2, chart2_ser1, pos_array);

    lv_chart_refresh(chart2); /*Required after direct set*/
}

4. 覆盖组合默认起点(Override default start point for series)

从serial特定的index绘制,使用这个函数lv_chart_set_x_start_point

我们来看下代码

void lvgl_chart_ovwrite_startp_test(void)
{
    lv_coord_t pos_array[] = {10,10,20,20,30,30 };
    lv_obj_t* chart = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart, 200, 150);
    lv_obj_align(chart, NULL, LV_ALIGN_CENTER, -150, 0);
    lv_chart_set_type(chart, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    lv_chart_series_t* ser1 = lv_chart_add_series(chart, LV_COLOR_GREEN);
    lv_chart_set_points(chart, ser1, pos_array);
    lv_chart_refresh(chart); /*Required after direct set*/


    lv_obj_t* chart2 = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart2, 200, 150);
    lv_obj_align(chart2, NULL, LV_ALIGN_CENTER, 150, 0);
    lv_chart_set_type(chart2, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    lv_chart_series_t* chart2_ser1 = lv_chart_add_series(chart2, LV_COLOR_GREEN);
    lv_chart_set_points(chart2, chart2_ser1, pos_array);
    lv_chart_set_x_start_point(chart2, chart2_ser1, 1);
    lv_chart_refresh(chart2); /*Required after direct set*/
}

有bug?????

5. 设置外部数据源(Set an external data source)

可以使用这个函数lv_chart_set_ext_array(chart, ser, array, point_cnt )来设置外部数据源,个人感觉跟lv_chart_set_points 这个类似

void lvgl_chart_ex_array_test(void)
{
    static lv_coord_t pos_array[] = { 10,10,20,20,30,30 };
    lv_obj_t* chart = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart, 200, 150);
    lv_obj_align(chart, NULL, LV_ALIGN_CENTER, -150, 0);
    lv_chart_set_type(chart, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    lv_chart_series_t* ser1 = lv_chart_add_series(chart, LV_COLOR_GREEN);
    lv_chart_set_ext_array(chart, ser1, pos_array,sizeof(pos_array)/sizeof(lv_coord_t));
    lv_chart_refresh(chart); /*Required after direct set*/

}

6. 获取当前数据表信息(Get current chart information)

有四个功能可获取有关图表的信息:

  • lv_chart_get_type(chart)  返回当前图表类型。
  • lv_chart_get_point_count(chart)  返回当前图表点数。
  • lv_chart_get_x_start_point(ser)  返回指定系列的当前绘图索引。
  • lv_chart_get_point_id(chart, ser, id)  返回指定系列的特定索引处的数据值

7. 更新方式(Update modes)

lv_chart_set_next 可以根据更新模式以两种方式运行:

  • LV_CHART_UPDATE_MODE_SHIFT-将旧数据向左移动,然后向右添加新数据。
  • LV_CHART_UPDATE_MODE_CIRCULAR-循环添加新数据(如 ECG心电图 图)。

可以使用更改更新模式。 lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_...)

8. 点数(Number of points)

可以使用这个函数来设置点数,lv_chart_set_point_count,默认是10个,我们来看一个程序,把两个图标都创建一个集合(数量为6),一个不设置点数(默认10个),一个设置为6,代码如下:

void lvgl_chart_point_test(void)
{
    lv_coord_t pos_array[] = { 10,10,20,20,30,30 };
    lv_obj_t* chart = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart, 200, 150);
    lv_obj_align(chart, NULL, LV_ALIGN_CENTER, -150, 0);
    lv_chart_set_type(chart, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    lv_chart_series_t* ser1 = lv_chart_add_series(chart, LV_COLOR_GREEN);
    lv_chart_set_points(chart, ser1, pos_array);
    lv_chart_refresh(chart); /*Required after direct set*/


    lv_obj_t* chart2 = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart2, 200, 150);
    lv_obj_align(chart2, NULL, LV_ALIGN_CENTER, 150, 0);
    lv_chart_set_type(chart2, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    lv_chart_series_t* chart2_ser1 = lv_chart_add_series(chart2, LV_COLOR_GREEN);
    lv_chart_set_points(chart2, chart2_ser1, pos_array);
    lv_chart_set_point_count(chart2,sizeof(pos_array)/sizeof(lv_coord_t));
    lv_chart_refresh(chart2); /*Required after direct set*/
}

9. 垂直范围(Vertical range)

垂直范围是用这个函数设置lv_chart_set_range(chart, y_min, y_max),默认范围是[0:100]

我们来看一个程序,把两个图表都创建一个集合(数量为6),一个默认范围([0:100]),一个设置为[0:50],代码如下:

void lvgl_chart_ver_range_test(void)
{
    lv_coord_t pos_array[] = { 10,10,20,20,30,30 };
    lv_obj_t* chart = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart, 200, 150);
    lv_obj_align(chart, NULL, LV_ALIGN_CENTER, -150, 0);
    lv_chart_set_type(chart, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    lv_chart_series_t* ser1 = lv_chart_add_series(chart, LV_COLOR_GREEN);
    lv_chart_set_points(chart, ser1, pos_array);
    lv_chart_set_point_count(chart, sizeof(pos_array) / sizeof(lv_coord_t));
    lv_chart_refresh(chart); /*Required after direct set*/


    lv_obj_t* chart2 = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart2, 200, 150);
    lv_obj_align(chart2, NULL, LV_ALIGN_CENTER, 150, 0);
    lv_chart_set_type(chart2, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    lv_chart_series_t* chart2_ser1 = lv_chart_add_series(chart2, LV_COLOR_GREEN);
    lv_chart_set_points(chart2, chart2_ser1, pos_array);
    lv_chart_set_point_count(chart2, sizeof(pos_array) / sizeof(lv_coord_t));
    lv_chart_set_range(chart2,0,50);
    lv_chart_refresh(chart2); /*Required after direct set*/
}

10. 分割线(Division lines)

在图表中的分隔线,默认为3条横线,5条竖线,就是这样

下面我们通过程序修改下成5

11. 刻度线以及标签(Tick marks and labels)

设置刻度数字的功能,通过lv_chart_set_x_tick_text这个函数设置X轴的文本,通过这个函数lv_chart_set_y_tick_text 设置Y轴文本。

另外lv_chart_set_x_tick_length是设置X轴刻度坐标,lv_chart_set_y_tick_length是设置Y轴刻度坐标,关于刻度长度看以下图就能看出来差异了

此图的程序为(需要注意一点,需要设置padding属性,否则文本一般消失不了)

void lvgl_chart_tick_label_test(void)
{
    lv_coord_t pos_array[] = { 10,20,30,40,50,60,70,80,90,100 };
    lv_obj_t* chart = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart, 300, 300);
    lv_obj_align(chart, NULL, LV_ALIGN_CENTER, -170, 0);
    lv_chart_set_type(chart, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    lv_chart_series_t* ser1 = lv_chart_add_series(chart, LV_COLOR_GREEN);
    lv_chart_set_points(chart, ser1, pos_array);
    lv_obj_set_style_local_pad_left(chart, LV_CHART_PART_BG, LV_STATE_DEFAULT, 80);
    lv_obj_set_style_local_pad_bottom(chart, LV_CHART_PART_BG, LV_STATE_DEFAULT, 80);
    lv_chart_set_y_tick_texts(chart, "100\n80\n60\n40\n20", 0, LV_CHART_AXIS_DRAW_LAST_TICK);
    lv_chart_set_x_tick_texts(chart, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10", 0, LV_CHART_AXIS_DRAW_LAST_TICK);
    lv_chart_refresh(chart); /*Required after direct set*/


    lv_obj_t* chart2 = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart2, 300, 300);
    lv_obj_align(chart2, NULL, LV_ALIGN_CENTER, 170, 0);
    lv_chart_set_type(chart2, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    lv_chart_series_t* chart2_ser1 = lv_chart_add_series(chart2, LV_COLOR_GREEN);
    lv_chart_set_points(chart2, chart2_ser1, pos_array);
    lv_obj_set_style_local_pad_left(chart2, LV_CHART_PART_BG, LV_STATE_DEFAULT, 80);
    lv_obj_set_style_local_pad_bottom(chart2, LV_CHART_PART_BG, LV_STATE_DEFAULT, 80);
    lv_chart_set_y_tick_length(chart2, 0, 0);
    lv_chart_set_x_tick_length(chart2, 0, 0);
    lv_chart_set_y_tick_texts(chart2, "100\n80\n60\n40\n20", 0, LV_CHART_AXIS_DRAW_LAST_TICK);
    lv_chart_set_x_tick_texts(chart2, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10", 0, LV_CHART_AXIS_DRAW_LAST_TICK);
    lv_chart_refresh(chart2); /*Required after direct set*/
}

12. 事件(Event)

至于基本事件,所以此章节不做介绍,详细看还没研究明白LVGL事件?跟好步伐,LVGL『Event事件』介绍走起!(点击我)

好了,完结了,更多精彩继续戳↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

 

 

  • 5
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
LVGL 是一个开源的 GUI 库,提供了多种现成的控件,如按钮、标签、列表等。如果你需要自定义控件,可以使用 LVGL 提供的绘图和事件处理接口实现。 下面是一个简单的示例,演示如何在 LVGL 中创建自定义控件: ```c // 自定义控件的绘制函数 static void draw_custom_control(lv_obj_t * obj, const lv_area_t * clip_area) { // 绘制控件的背景和边框 lv_draw_rect(&obj->coords, clip_area, LV_COLOR_WHITE, LV_COLOR_BLACK, LV_DRAW_BORDER | LV_DRAW_FULL_COVER); // 绘制控件的内容 lv_draw_label(&obj->coords, clip_area, LV_COLOR_BLACK, "Custom Control", NULL, LV_LABEL_ALIGN_CENTER); } // 自定义控件的事件处理函数 static bool custom_control_event_handler(lv_obj_t * obj, lv_event_t event) { if (event == LV_EVENT_CLICKED) { // 处理控件被点击的事件 lv_obj_set_style_local_bg_color(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED); } return false; } // 创建自定义控件 lv_obj_t * custom_control_create(lv_obj_t * parent) { lv_obj_t * obj = lv_obj_create(parent, NULL); // 设置控件的大小和位置 lv_obj_set_size(obj, 100, 50); lv_obj_set_pos(obj, 50, 50); // 设置控件的绘制函数和事件处理函数 lv_obj_set_draw_func(obj, draw_custom_control); lv_obj_set_event_cb(obj, custom_control_event_handler); return obj; } ``` 在上面的示例中,我们创建了一个名为 `custom_control` 的自定义控件。`draw_custom_control` 函数用于绘制控件,`custom_control_event_handler` 函数用于处理控件的事件。在 `custom_control_create` 函数中,我们创建了一个 LVGL 对象,并设置了它的大小、位置、绘制函数和事件处理函数。最后,我们将对象返回给调用者。 使用上面的代码,你可以创建自己的 LVGL 控件并为其添加功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wireless_Link

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值