LVGL-lv_chart

下面图片从左到右,依次是折线图、区域图、锚点图

​​​​​​​

 

可以看到,这里的代码还是相对比较多的,不过其实也没有那么复杂,大多数还是在设置每个点的数据而已,那么这里我们先分析几个比较重要的API,首先就是图表类型,上面几幅图中我们展示了好几种图表类型,其实我们通过lv_chart_set_type这个函数就可以很简单的设置我们所要显示的图表类型,那么默认的类型有哪些呢?我们还是来看一下图表类型的枚举结构体:

** Chart types*/
enum {
    LV_CHART_TYPE_NONE          = 0x00, /**< 不显示(隐藏)*/
    LV_CHART_TYPE_LINE          = 0x01, /**< 折线*/
    LV_CHART_TYPE_COLUMN        = 0x02, /**< 柱形*/
    LV_CHART_TYPE_POINT         = 0x04, /**< 点*/
    LV_CHART_TYPE_VERTICAL_LINE = 0x08, /**< 竖直线*/
    LV_CHART_TYPE_AREA          = 0x10, /**< 区域*/

};

typedef uint8_t lv_chart_type_t;
static void chart_test(void)
{
    /*Create chart1*/
    lv_obj_t * chart1;
    chart1 = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart1, 200, 150);
    lv_obj_align(chart1, NULL, LV_ALIGN_CENTER, 0, 0);
    lv_chart_set_type(chart1, LV_CHART_TYPE_AREA );   /*Show lines and points too*/
    lv_chart_set_series_opa(chart1, LV_OPA_70);       /*Opacity of the data series*/
    lv_chart_set_series_width(chart1, 4);            /*Line width and point radious*/
	  lv_chart_set_range(chart1, 0, 100);
	
		/*Create chart2*/
	  lv_obj_t * chart2;
    chart2 = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart2, 200, 150);
    lv_obj_align(chart2, NULL, LV_ALIGN_CENTER, -250, 0);
    lv_chart_set_type(chart2, LV_CHART_TYPE_LINE );   /*Show lines and points too*/
    lv_chart_set_series_opa(chart2, LV_OPA_70);       /*Opacity of the data series*/
    lv_chart_set_series_width(chart2, 4);            /*Line width and point radious*/
		lv_chart_set_range(chart2, 0, 100);
	
		/*Create chart3*/
		lv_obj_t * chart3;
    chart3 = lv_chart_create(lv_scr_act(), NULL);
    lv_obj_set_size(chart3, 200, 150);
    lv_obj_align(chart3, NULL, LV_ALIGN_CENTER, 250, 0);
    lv_chart_set_type(chart3, LV_CHART_TYPE_POINT );   /*Show lines and points too*/
    lv_chart_set_series_opa(chart3, LV_OPA_70);       /*Opacity of the data series*/
    lv_chart_set_series_width(chart3, 4);            /*Line width and point radious*/
		lv_chart_set_range(chart3, 0, 100);
	
    /*Add two data series*/
    lv_chart_series_t * ser1 = lv_chart_add_series(chart1, LV_COLOR_RED);
    lv_chart_series_t * ser2 = lv_chart_add_series(chart1, LV_COLOR_GREEN);

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

    /*Directly set points on 'dl2'*/
    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_refresh(chart1); /*Required after direct set*/
		
		    /*Add two data series*/
    lv_chart_series_t * ser3 = lv_chart_add_series(chart2, LV_COLOR_RED);
    lv_chart_series_t * ser4 = lv_chart_add_series(chart2, LV_COLOR_GREEN);

    /*Set the next points on 'dl1'*/
    lv_chart_set_next(chart2, ser3, 10);
    lv_chart_set_next(chart2, ser3, 10);
    lv_chart_set_next(chart2, ser3, 10);
    lv_chart_set_next(chart2, ser3, 10);
    lv_chart_set_next(chart2, ser3, 10);
    lv_chart_set_next(chart2, ser3, 10);
    lv_chart_set_next(chart2, ser3, 10);
    lv_chart_set_next(chart2, ser3, 30);
    lv_chart_set_next(chart2, ser3, 70);
    lv_chart_set_next(chart2, ser3, 90);

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

    lv_chart_refresh(chart2); /*Required after direct set*/
		
		    /*Add two data series*/
    lv_chart_series_t * ser5 = lv_chart_add_series(chart3, LV_COLOR_RED);
    lv_chart_series_t * ser6 = lv_chart_add_series(chart3, LV_COLOR_GREEN);

    /*Set the next points on 'dl1'*/
    lv_chart_set_next(chart3, ser5, 10);
    lv_chart_set_next(chart3, ser5, 10);
    lv_chart_set_next(chart3, ser5, 10);
    lv_chart_set_next(chart3, ser5, 10);
    lv_chart_set_next(chart3, ser5, 10);
    lv_chart_set_next(chart3, ser5, 10);
    lv_chart_set_next(chart3, ser5, 10);
    lv_chart_set_next(chart3, ser5, 30);
    lv_chart_set_next(chart3, ser5, 70);
    lv_chart_set_next(chart3, ser5, 90);

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

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


默认的图表类型一共有这些,而且图表类型还可以叠加,比如我们想要即画点又连起曲线来,可以这样设置:

lv_chart_set_type(chart, LV_CHART_TYPE_LINE | LV_CHART_TYPE_POINT);

然后是lv_chart_set_series_opa这个函数,其主要作用是设置我们画的点或者柱形的透明度的,取值范围是 0 ~ 255,0的时候是完全透明,255的时候完全不透明,这里的透明与不透明是相对于我们的网格来说的。

再就是lv_chart_set_series_width这个函数,主要是就是设置我们画的点的直径或者线宽等,当然对区域覆盖的图表类型来说是不起作用的。

然后lv_chart_set_range这个函数是设置的数据区间,就是我们纵坐标的最小值和最大值。

设置完上面的这些基本属性后,就是给我们的图表设置数据了,毕竟图表的作用就是用来展示数据的,再填充数据前我们要先增加图表序列,就是那根红线或者绿线,我们通过lv_chart_add_series这个函数去增加,其中第二个参数是数据点的颜色,返回值是指向图表序列结构的一个指针结构体,那么这个结构体都有哪些成员呢,我们可以看一下源码:

1typedef struct
2{
3    lv_coord_t * points;
4    lv_color_t color;
5    uint16_t start_point;
6} lv_chart_series_t;

那么我们可以通过例程的两种方式向图表数据,第一种就是通过lv_chart_set_next函数不断的去填充数据,其中第一个参数是我们的图表对象,然后第二个参数是我们的数据序列对象,第三个参数是我们的数据值,我们还可以用第二种方式去设置我们的图表中的数据,就是直接对结构体成员的每个数据点直接复制,不过最重要的是在我们设置完成数据后,一定要调用lv_chart_refresh这个函数,否则数据是不会刷新显示的!

#include "gui_user.h"

static void update_chart(lv_task_t *t);
static void obj_event_cb(lv_obj_t * obj, lv_event_t event);



static const uint8_t *list_value_x = "0\n1\n2\n3\n4\n5\n6\n7\n\8\n\9";
static const uint8_t *list_value_y = "100\n90\n80\n70\n60\n50\n40\n30\n20\n10\n0";


static lv_chart_series_t *ser_light;
static lv_task_t *task;


lv_obj_t * app_light_create(lv_obj_t *parent,void *user_data)
{
	(void)user_data;

	static lv_style_t style_label_info;
	static lv_style_t style_chart;

	lv_obj_t *obj = lv_app_common_int(lv_scr_act(), "光照");
	lv_obj_set_event_cb(obj, obj_event_cb);

	lv_style_copy(&style_label_info, &lv_style_plain_color);
	if (gui_current_theme == THEME_NEMO)
		style_label_info.text.color = LV_COLOR_WHITE;
	else
		style_label_info.text.color = LV_COLOR_BLACK;
	style_label_info.text.font = &gb2312_puhui16;

	lv_style_copy(&style_chart, &lv_style_plain_color);
	if (gui_current_theme == THEME_NEMO)
		style_chart.text.color = LV_COLOR_WHITE;
	else
		style_chart.text.color = LV_COLOR_BLACK;


	lv_obj_t * label = lv_label_create(obj,NULL);
	lv_label_set_style(label,LV_LABEL_STYLE_MAIN,&style_label_info);
	lv_label_set_text(label,"图表反映环境光照强度");
	lv_obj_align(label,obj,LV_ALIGN_IN_TOP_MID,0,70);

	lv_obj_t *chart = lv_chart_create(obj, NULL);		/* 创建图表控件 */
	lv_obj_align(chart, NULL, LV_ALIGN_IN_TOP_MID, 0, 120);	/* 设置位置 */
	lv_chart_set_point_count(chart, 10);					/* 设置显示的点数量 */
	lv_chart_set_series_width(chart, 4);					/* 设置线宽度 */
	lv_chart_set_range(chart, 0, 100);					/* 设置范围0-100 */
	lv_chart_set_div_line_count(chart, 9, 5);			/* 设置分割线的数量 */
	lv_chart_set_margin(chart, 50);						/* 设置标注的扩展长度 */
	lv_chart_set_type(chart, LV_CHART_TYPE_POINT | LV_CHART_TYPE_LINE);	/* 显示方式 显示点和线 */

	lv_chart_set_x_tick_texts(chart, list_value_x, 1, LV_CHART_AXIS_DRAW_LAST_TICK);	/* 设置标注的文本 */

	lv_obj_set_size(chart, 300, 300);						/* 设置控件尺寸 */

	lv_chart_set_x_tick_length(chart, 10, 10);			/* 刻度线长度 */

	lv_chart_set_y_tick_texts(chart, list_value_y, 1, LV_CHART_AXIS_DRAW_LAST_TICK);	/* 设置标注的文本 */
    lv_chart_set_y_tick_length(chart, 10, 10);			/* 刻度线长度 */

	lv_chart_set_style(chart,LV_CHART_STYLE_MAIN,&style_chart);


	ser_light = lv_chart_add_series(chart, LV_COLOR_BLUE);	/* 创建线条 */

	task = lv_task_create(update_chart, 500, LV_TASK_PRIO_LOW, chart);	/* 创建定期更新的任务 */

	return obj;
}

static void update_chart(lv_task_t *t)
{
	/* 更新图表 */
	lv_chart_set_next(t->user_data, ser_light, gui_hal_adc_light_get_ratio());
}


static void obj_event_cb(lv_obj_t * obj, lv_event_t event)
{
	switch (event)
	{
	case LV_EVENT_DELETE:
		if (task != NULL)
		{
			lv_task_del(task);
		}
		
		break;
	default:
		break;
	}
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
【RT-Thread作品秀】基于 lvgl 的漏电保护装置校验仪 UI 界面设计作者:赵加文 概述低压漏电引起的各种安全事故已经严重影响到生产生活,威胁到生命财产安全。而解决这一现象的设备就是漏电保护开关,漏电保护开关的漏报率、误报率是很关键的参数,因此有必要对漏电保护开关的性能进行测试。因此,漏电保护装置校验仪是很有必要的。 开发环境硬件:ART-Pi 开发板,正点原子 480*272 4.3寸 RGB 屏幕 RT-Thread版本:4.0.3 开发工具及版本: RT-Thread Studio 2.0.0 :编写 编译 调试 下载代码 STM32CubeMX 6.1.0: codeBlocks 20.03:用于在 PC 机上进行 lvgl 模拟 MCU_Font V2.0: 用于转换中文,然后使得中文能够在 lvgl 中显示 RT-Thread使用情况概述在 UI 设计的整个过程中,使用到 RT-Thread 的部分主要有以下几个方面: 内核部分:动态线程,信号量 组件部分:PIN 设备、I2C 设备、TOUCH 设备框架、LCD 设备框架、finsh 组件 软件包部分:littlevgl2rtt、gt9147 硬件框架软件框架说明系统整体流程图: 软件模块说明整个UI 系统设计所遵循的是 lvgl 图形库的一个回调函数的机制,将各个事件与对应的操作所绑定起来,当滑动滑条时对应的滑条的回调函数就会被触发,那么就会执行滑条回调函数的内容,当滑动点击文本框时,文本框对应的回调函数就会被触发,进而创建键盘的控件,通过键盘输入所需要的数据。 演示效果图片展示: 演示视频: 比赛感悟这次参赛,之前还没有使用过 RT-Thread studio 这个集成开发环境,这次在使用 ART-Pi 的时候全程是使用 RT-Thread studio 这个开发环境,在使用的过程中也碰到了很多问题,有时候明明配置了相关组件,但是保存之后,并没有代码添加到工程里。现在也没有弄明白问题出在哪里,虽然存在着这里问题,但是在使用的过程中,还是非常的方便,整个开发过程就如同搭积木一样方便,与 RTT操作系统贴合的非常的紧密。 除此之外,便是在使用 lvgl 的过程中碰到了很多的问题,现在网上的教程基本是 lvgl v6 版本的教程,关于 lvgl v7 版本的教程很少,而且 v6版本与 V7 版本的 API 相差很大,不能按照 V6 版本来使用 V7 ,在这个过程中摸索了好多,同时也感受到了 lvgl 的魅力,使用在嵌入式系统上是非常不错的选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值