LVGL chart学习-创建简单折线图

1、代码仓库

学习的LVGL代码来自下面的链接,感谢开源的大佬lv_demo_hub: - LVGL DEMO 仓库 - 目的:可快速评估LVGL组件,了解LVGL能做些什么 - 支持:ubuntu(gcc)、windows(X64 vs2022)、linux arm(sigmastar SSD2XX) (gitee.com)

2、创建简单折线图 

int app_chart_1(lv_obj_t *parent)
{
    /*Create a chart*/
    lv_obj_t *chart;
    chart = lv_chart_create(parent);
    lv_obj_set_size(chart, 200, 150);
    lv_obj_center(chart);
    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_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
    lv_chart_series_t *ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_SECONDARY_Y);

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

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

    lv_chart_refresh(chart); /*Required after direct set*/
    return 0;
}

3、代码解析

我们可以将折线图的实现分为两个步骤

3.1 创建图表并设置图表的大小和位置

 lv_obj_t *chart;
 chart = lv_chart_create(parent);//创建图表
 lv_obj_set_size(chart, 200, 150);//设置图表的大小
 lv_obj_center(chart);//使图表处于屏幕中央
 lv_chart_set_type(chart, LV_CHART_TYPE_LINE);//设置图表的类型为折线型

前面几句都是经常用到的,很好理解,lv_chart_set_type(chart, LV_CHART_TYPE_LINE);这句顾名思义,就是设置图表的类型,我们可以跳进去看看它有什么类型

enum {
    LV_CHART_TYPE_NONE,     /**< Don't draw the series*/
    LV_CHART_TYPE_LINE,     /**< Connect the points with lines*/
    LV_CHART_TYPE_BAR,      /**< Draw columns*/
    LV_CHART_TYPE_SCATTER,  /**< Draw points and lines in 2D (x,y coordinates)*/
};

第一个是什么都不干,肯定不选它,第二个就是我们所需要的折线图,

第三个是BAR,是柱状图

第四个是画一些单独的点的图

3.2 往图表里面加入我们需要的数据

我们看到这两条函数,很明显就是往图表里面添加数据的

 lv_chart_series_t *ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
 lv_chart_series_t *ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_SECONDARY_Y);

 我们看一下函数原型

lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_chart_axis_t axis)
{
    LV_LOG_INFO("begin");//打印一句开始

    LV_ASSERT_OBJ(obj, MY_CLASS);//先确定一下是不是我们现在绘制的图表类型,ASSERT类似于断言

    lv_chart_t * chart    = (lv_chart_t *)obj;//强转一下
    lv_chart_series_t * ser = _lv_ll_ins_head(&chart->series_ll);//创建一个lv_chart_series_t的变量插入到图表的链表头部
    LV_ASSERT_MALLOC(ser);//判断分配内存是否成功
    if(ser == NULL) return NULL;//如果分频失败就退出

    lv_coord_t def = LV_CHART_POINT_NONE;

    ser->color  = color;//设置颜色
    ser->y_points = lv_mem_alloc(sizeof(lv_coord_t) * chart->point_cnt);//分配y轴点的内存(默认是10个)
    LV_ASSERT_MALLOC(ser->y_points);//判断分配内存是否成功

    if(chart->type == LV_CHART_TYPE_SCATTER) {//如果图表类型是散点图
        ser->x_points = lv_mem_alloc(sizeof(lv_coord_t) * chart->point_cnt);
        LV_ASSERT_MALLOC(ser->x_points);
    }
    if(ser->y_points == NULL) {//如果分配失败就从链表中删除,并释放内存
        _lv_ll_remove(&chart->series_ll, ser);
        lv_mem_free(ser);
        return NULL;
    }
    /*感觉是做一些初始化*/
    ser->start_point = 0;
    ser->y_ext_buf_assigned = false;
    ser->hidden = 0;
    ser->x_axis_sec = axis & LV_CHART_AXIS_SECONDARY_X ? 1 : 0;
    ser->y_axis_sec = axis & LV_CHART_AXIS_SECONDARY_Y ? 1 : 0;

    uint16_t i;
    lv_coord_t * p_tmp = ser->y_points;//
    for(i = 0; i < chart->point_cnt; i++) {
        *p_tmp = def;
        p_tmp++;
    }

    return ser;
}

第一个参数是一个lv_obj_t对象,第二个是设置颜色,第三个是什么呢?

enum {
    LV_CHART_AXIS_PRIMARY_Y     = 0x00,
    LV_CHART_AXIS_SECONDARY_Y   = 0x01,
    LV_CHART_AXIS_PRIMARY_X     = 0x02,
    LV_CHART_AXIS_SECONDARY_X   = 0x04,
    _LV_CHART_AXIS_LAST
};
typedef uint8_t lv_chart_axis_t;

进入后,我们发现它是个枚举类型,可以通过这个图来理解

继续往下看到有两种给折线赋值的方式,我们先看到这个函数

lv_chart_set_next_value(chart, ser1, 10);

猜测是往第一个折线加入一个数值为10的点,看一下函数原型,大概就是这个意思,具体的我也看不懂。。。

void lv_chart_set_next_value(lv_obj_t * obj, lv_chart_series_t * ser, lv_coord_t value)
{
    LV_ASSERT_OBJ(obj, MY_CLASS);//判断一下是不是对应的图表类
    LV_ASSERT_NULL(ser);//判断是否为空

    lv_chart_t * chart  = (lv_chart_t *)obj;
    ser->y_points[ser->start_point] = value;//设置点的y轴坐标
    invalidate_point(obj, ser->start_point);//绘制点
    ser->start_point = (ser->start_point + 1) % chart->point_cnt;//为下一个点的绘制做准备
    invalidate_point(obj, ser->start_point);//有点没看懂
}

另外一种就更简单粗暴,ser2->y_points[0] = 90;直接给点赋值了,最后调用

lv_chart_refresh(chart);对图表进行刷新,其实就是对图表进行重绘制,就完成了绘制。

void lv_chart_refresh(lv_obj_t * obj)
{
    LV_ASSERT_OBJ(obj, MY_CLASS);

    lv_obj_invalidate(obj);//告诉底层我要重绘这个对象
}

  • 15
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值