LVGL chart图表:双线的实时刷新,可用于数据采集

琢磨了好久的chart图标终于搞定了,现在做了一个完整的双线刷新分享一下。版本为8.3

这边lvgl的前言知识就不介绍了,只介绍chart图标部分,头文件只需要#include "lvgl"。然后开始创建图表,过程我就不写了,最后有完整的代码。设置图标的大小和位置,适应你的屏幕,我这边用的是480*320的屏幕。

	schart = lv_obj_create(lv_scr_act());
	lv_obj_set_size(schart, 480, 320);
	lv_obj_set_scrollbar_mode(schart, LV_SCROLLBAR_MODE_OFF);   //关闭滚动条


	lv_obj_set_style_bg_opa(schart, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_color(schart, lv_color_hex(0xE8E8E8), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(schart, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);

	chart_init = lv_chart_create(schart);
	lv_chart_set_zoom_x(chart_init, 256);//不进行缩放
	lv_chart_set_zoom_y(chart_init, 256);//
    lv_obj_set_pos(chart_init, 20, -15); //位置
	lv_obj_set_size(chart_init, 400, 290);//大小

接着设定图表内部结构,起始位置与边界的距离,折线图,整个屏幕的点数,创建线条。

//    lv_obj_set_style_pad_all(chart_init, 5, LV_STATE_DEFAULT);      //图表0刻度线与边框的距离
//    lv_obj_set_style_pad_bottom(chart_init, 5, LV_STATE_DEFAULT);   //
//    lv_obj_set_style_pad_top(chart_init, 5, LV_STATE_DEFAULT);      //

	lv_chart_set_type(chart_init, LV_CHART_TYPE_LINE);          //线状图
	lv_obj_set_style_size(chart_init, 0, LV_PART_INDICATOR);    //设置为折线图        默认为点线图

	lv_chart_set_div_line_count(chart_init, 5, 11);     //背景线条,横竖个数
	lv_chart_set_point_count(chart_init, 50);           //整个屏幕绘制的点数
    lv_chart_set_axis_tick(chart_init, LV_CHART_AXIS_PRIMARY_X, 5, 3, 11, 5, true, 40);//底部线范围

	lv_chart_set_range(chart_init, LV_CHART_AXIS_PRIMARY_Y, 0, 100);     //左边线的范围
	lv_chart_set_axis_tick(chart_init, LV_CHART_AXIS_PRIMARY_Y, 5, 3, 5, 5, true, 40);
	lv_chart_set_range(chart_init, LV_CHART_AXIS_SECONDARY_Y, 0, 100);   //右边线的范围
	lv_chart_set_axis_tick(chart_init, LV_CHART_AXIS_SECONDARY_Y, 5, 3, 5, 5, true, 40);
	chart_left= lv_chart_add_series(chart_init, lv_color_hex(0x000000), LV_CHART_AXIS_PRIMARY_Y);       //创建左边线
    chart_right = lv_chart_add_series(chart_init, lv_color_hex(0xff0000), LV_CHART_AXIS_SECONDARY_Y);   //创建右边线

 背景线条就是横竖的个数,具体部件信息请参考其他博主的帖子。再对图表进行样式调整。

最后设置刷新模式,创建回调函数,定时器。PC性能高可以实现每10毫秒的数据刷新,单片机上左移方式的刷新像拉窗帘,建议使用循环刷新。

    lv_obj_add_event_cb(chart_init, draw_label_event_cb_1, LV_EVENT_DRAW_PART_BEGIN, NULL);     //回调函数
    lv_chart_set_update_mode(chart_init,LV_CHART_UPDATE_MODE_CIRCULAR);     //设置循环刷新
    timer = lv_timer_create(add_data, 10, chart_init);        //创建定时器

在回调函数中设置各方向的文字和线条的颜色,上方的没有用到,设置方法一样。

static void draw_label_event_cb_1(lv_event_t* e)  //设置单方向颜色
{
    lv_obj_draw_part_dsc_t* dsc = lv_event_get_draw_part_dsc(e);
    if (!lv_obj_draw_part_check_type(dsc, &lv_chart_class, LV_CHART_DRAW_PART_TICK_LABEL)) return;

    if (dsc->id == LV_CHART_AXIS_PRIMARY_Y && dsc->text)        //左
    {
        dsc->label_dsc->color = lv_color_hex(0x000000);
        dsc->line_dsc->color = lv_color_hex(0x000000);
    }
    else if (dsc->id == LV_CHART_AXIS_SECONDARY_Y && dsc->text)//右
    {
        dsc->label_dsc->color = lv_color_hex(0xff0000);
        dsc->line_dsc->color = lv_color_hex(0xff0000);
    }
    else if (dsc->id == LV_CHART_AXIS_PRIMARY_X && dsc->text)  //下
    {
        dsc->label_dsc->color = lv_color_hex(0x00ff00);
        dsc->line_dsc->color = lv_color_hex(0x00ff00);
    }
}

定时器部分刷新模式有两种,循环刷新和一直左移,主程序中设置的是循环刷新,这边调用设置全部数值的函数进行清屏,LVGL 7版本有lv_chart_clear_series函数进行清屏,现在使用的是8.3版本LV_CHART_POINT_NONE就是清屏参数。

数据采集用随机数代替,外部数据采集只需要传参就行。注释掉的代码为自适应范围.

static void add_data(lv_timer_t * t)
{
    lv_obj_t * chart = t->user_data;

    if(temp++==50)          //循环状态下超出屏幕清屏
    {
        lv_chart_set_all_value(chart,chart_left,LV_CHART_POINT_NONE);
        lv_chart_set_all_value(chart,chart_right,LV_CHART_POINT_NONE);temp=0;
    }
//    if(temp++==50)          //先循环,超出屏幕左移
//    {
//        lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT);
//    }



    //随机函数,对100取余,只要=>0的数据
    lv_chart_set_next_value(chart, chart_left, lv_rand(0,100)); //数据检测
    lv_chart_set_next_value(chart, chart_right, lv_rand(0,100));//数据检测

//    date_left = lv_rand(0,100);
//    if(date_left>max_left)
//    {
//        max_left = date_left/10*10+10;
//        lv_chart_set_range(chart_init, LV_CHART_AXIS_PRIMARY_Y, 0, max_left);
//    }
//    date_right = lv_rand(0,100);
//    if(date_right>max_right)
//    {
//        max_right = date_right/10*10+10;
//        lv_chart_set_range(chart_init, LV_CHART_AXIS_SECONDARY_Y, 0, max_right);
//    }
//    lv_chart_set_next_value(chart, chart_left, date_left);
//    lv_chart_set_next_value(chart, chart_right, date_right);
}

本人第一次发帖,不太熟悉过程,就勉强这样吧。最后附源码。

#include "lvgl.h"

lv_timer_t * timer;
lv_obj_t *schart;
lv_chart_series_t *chart_init;
lv_chart_series_t *chart_left;
lv_chart_series_t *chart_right;
int temp,max_left=40,max_right=40;
int date,date_left,date_right;
static void draw_label_event_cb_1(lv_event_t* e)  //设置单方向颜色
{
    lv_obj_draw_part_dsc_t* dsc = lv_event_get_draw_part_dsc(e);
    if (!lv_obj_draw_part_check_type(dsc, &lv_chart_class, LV_CHART_DRAW_PART_TICK_LABEL)) return;

    if (dsc->id == LV_CHART_AXIS_PRIMARY_Y && dsc->text)        //左
    {
        dsc->label_dsc->color = lv_color_hex(0x000000);
        dsc->line_dsc->color = lv_color_hex(0x000000);
    }
    else if (dsc->id == LV_CHART_AXIS_SECONDARY_Y && dsc->text)//右
    {
        dsc->label_dsc->color = lv_color_hex(0xff0000);
        dsc->line_dsc->color = lv_color_hex(0xff0000);
    }
    else if (dsc->id == LV_CHART_AXIS_PRIMARY_X && dsc->text)  //下
    {
        dsc->label_dsc->color = lv_color_hex(0x00ff00);
        dsc->line_dsc->color = lv_color_hex(0x00ff00);
    }
}

static void add_data(lv_timer_t * t)
{
    lv_obj_t * chart = t->user_data;

    if(temp++==50)          //循环状态下超出屏幕清屏
    {
        lv_chart_set_all_value(chart,chart_left,LV_CHART_POINT_NONE);
        lv_chart_set_all_value(chart,chart_right,LV_CHART_POINT_NONE);temp=0;
    }
//    if(temp++==50)          //先循环,超出屏幕左移
//    {
//        lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT);
//    }



    //随机函数,对100取余,只要=>0的数据
    lv_chart_set_next_value(chart, chart_left, lv_rand(0,100)); //数据检测
    lv_chart_set_next_value(chart, chart_right, lv_rand(0,100));//数据检测

//    date_left = lv_rand(0,100);
//    if(date_left>max_left)
//    {
//        max_left = date_left/10*10+10;
//        lv_chart_set_range(chart_init, LV_CHART_AXIS_PRIMARY_Y, 0, max_left);
//    }
//    date_right = lv_rand(0,100);
//    if(date_right>max_right)
//    {
//        max_right = date_right/10*10+10;
//        lv_chart_set_range(chart_init, LV_CHART_AXIS_SECONDARY_Y, 0, max_right);
//    }
//    lv_chart_set_next_value(chart, chart_left, date_left);
//    lv_chart_set_next_value(chart, chart_right, date_right);
}

void double_line_chart()
{

	schart = lv_obj_create(lv_scr_act());
	lv_obj_set_size(schart, 480, 320);
	lv_obj_set_scrollbar_mode(schart, LV_SCROLLBAR_MODE_OFF);   //关闭滚动条


	lv_obj_set_style_bg_opa(schart, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_color(schart, lv_color_hex(0xE8E8E8), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(schart, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);

	chart_init = lv_chart_create(schart);
	lv_chart_set_zoom_x(chart_init, 256);//不进行缩放
	lv_chart_set_zoom_y(chart_init, 256);//
    lv_obj_set_pos(chart_init, 20, -15); //位置
	lv_obj_set_size(chart_init, 400, 290);//大小
//    lv_obj_set_style_pad_all(chart_init, 5, LV_STATE_DEFAULT);      //图表0刻度线与边框的距离
//    lv_obj_set_style_pad_bottom(chart_init, 5, LV_STATE_DEFAULT);   //
//    lv_obj_set_style_pad_top(chart_init, 5, LV_STATE_DEFAULT);      //

	lv_chart_set_type(chart_init, LV_CHART_TYPE_LINE);          //线状图
	lv_obj_set_style_size(chart_init, 0, LV_PART_INDICATOR);    //设置为折线图        默认为点线图

	lv_chart_set_div_line_count(chart_init, 5, 11);     //背景线条,横竖个数
	lv_chart_set_point_count(chart_init, 50);           //一个画面绘制的点数
    lv_chart_set_axis_tick(chart_init, LV_CHART_AXIS_PRIMARY_X, 5, 3, 11, 5, true, 40);//底部线范围

	lv_chart_set_range(chart_init, LV_CHART_AXIS_PRIMARY_Y, 0, 40);     //左边线的范围
	lv_chart_set_axis_tick(chart_init, LV_CHART_AXIS_PRIMARY_Y, 5, 3, 5, 5, true, 40);
	lv_chart_set_range(chart_init, LV_CHART_AXIS_SECONDARY_Y, 0, 40);   //右边线的范围
	lv_chart_set_axis_tick(chart_init, LV_CHART_AXIS_SECONDARY_Y, 5, 3, 5, 5, true, 40);
	chart_left= lv_chart_add_series(chart_init, lv_color_hex(0x000000), LV_CHART_AXIS_PRIMARY_Y);       //创建左边线
    chart_right = lv_chart_add_series(chart_init, lv_color_hex(0xff0000), LV_CHART_AXIS_SECONDARY_Y);   //创建右边线




    //样式创建      主界面
	lv_obj_set_style_bg_opa(chart_init, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_color(chart_init, lv_color_hex(0xffffff), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(chart_init, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_border_width(chart_init, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_border_opa(chart_init, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_border_color(chart_init, lv_color_hex(0xe8e8e8), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_border_side(chart_init, LV_BORDER_SIDE_FULL, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_radius(chart_init, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_line_width(chart_init, 2, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_line_color(chart_init, lv_color_hex(0xe8e8e8), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_line_opa(chart_init, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_width(chart_init, 0, LV_PART_MAIN|LV_STATE_DEFAULT);

    //样式创建      其他部件
	lv_obj_set_style_text_color(chart_init, lv_color_hex(0x000000), LV_PART_TICKS|LV_STATE_DEFAULT);
	lv_obj_set_style_text_font(chart_init, &lv_font_montserrat_16, LV_PART_TICKS|LV_STATE_DEFAULT);
	lv_obj_set_style_text_opa(chart_init, 255, LV_PART_TICKS|LV_STATE_DEFAULT);
	lv_obj_set_style_line_width(chart_init, 2, LV_PART_TICKS|LV_STATE_DEFAULT);
	lv_obj_set_style_line_color(chart_init, lv_color_hex(0x000000), LV_PART_TICKS|LV_STATE_DEFAULT);
	lv_obj_set_style_line_opa(chart_init, 255, LV_PART_TICKS|LV_STATE_DEFAULT);



    lv_obj_add_event_cb(chart_init, draw_label_event_cb_1, LV_EVENT_DRAW_PART_BEGIN, NULL);     //回调函数
    lv_chart_set_update_mode(chart_init,LV_CHART_UPDATE_MODE_CIRCULAR);     //设置循环刷新
    timer = lv_timer_create(add_data, 1000, chart_init);        //创建定时器
}

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值