LVGL 图表(lv_chart)自定义

在使用图表的过程中略有感悟,所以简单记录一下

目录

一、自定义点的折线图

二、旋转折线图

2.1 旋转折线图实现

2.2 旋转后折线图更新形式的实现

三、修改x轴范围


一、自定义点的折线图

        我们用lv_chart的折线图LV_CHART_TYPE_LINE类型,只能设置y值,x值自动增加,对于想要实现不规则折线图的我来说完全不够用

散点图可自定义(x,y),设置任意点,但没线

结合这两个,可以如下配置散点图,以实现自定义折线图

简单来说就是隐去散点图的点,再让线显示出来

就是类似如下效果

实现代码

void user_chart_test(lv_timer_t* timer) 
{
    LV_UNUSED(timer);
    lv_obj_t *chart = timer->user_data;
    
    lv_chart_set_next_value2(chart,ser_test,lv_rand(0,100),lv_rand(0,100));
}

void lv_example_chart_test(void)
{   
    chart_test = lv_chart_create(lv_scr_act());
    lv_obj_set_width(chart_test, 500);
    lv_obj_set_height(chart_test, 500);
    lv_obj_set_x(chart_test, 15);
    lv_obj_set_y(chart_test, 170);

    lv_obj_set_style_size(chart_test, 0, LV_PART_INDICATOR);
    lv_chart_set_type(chart_test, LV_CHART_TYPE_SCATTER);
    lv_chart_set_axis_tick(chart_test, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 6, 5, true, 40);
    lv_chart_set_axis_tick(chart_test, LV_CHART_AXIS_PRIMARY_X, 10, 5, 10, 1, true, 30);
    lv_chart_set_point_count(chart_test, 10);
    lv_chart_set_range(chart_test, LV_CHART_AXIS_PRIMARY_Y, 0, 100);
    ser_test = lv_chart_add_series(chart_test, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
     
    lv_timer_create(user_chart_test, 1000, chart_test);
}

二、旋转折线图

        lvgl本身不支持旋转lv_chart,我试过很多ai提供的方式:交换x、y的值、把图表创建在lv_canvas上等等,都未实现

        然后在上述一 的启发下,仍是以散点图出发,交换x、y值,即实现竖直的折线图

2.1 旋转折线图实现

        就是将图表旋转90°,因为项目有需要,故需要将这个组件进行旋转,找了很多资料都无法实现,最后看他们的底层代码,研究出来的,就是散点图画线,交换点的x,y值,就能实现

实现代码:

int index_i = 0;
#define POINT_COUNT 400  // 最大点数
int Ymin = 0;
int Ymax = POINT_COUNT;
int xEdge = 0;
int yEdge = 0;
int chart_Remainder = 0;
void update_chart(lv_chart_t * chart,lv_chart_series_t *ser,lv_coord_t x) 
{

    int y = index_i;
    chart_Remainder = index_i % POINT_COUNT;
    if(chart_Remainder == POINT_COUNT-1)
    {
        xEdge = x;
        yEdge = index_i;
    }
    if(index_i  >= POINT_COUNT-1)
    {
        ser->x_points[(index_i+1) % POINT_COUNT] = LV_CHART_POINT_NONE;
        ser->y_points[(index_i+1) % POINT_COUNT] = LV_CHART_POINT_NONE;
    }
    if(chart_Remainder == 0)
    {
        ser->x_points[0] = xEdge;
        ser->y_points[0] = yEdge;
        
    }else
    {
        ser->x_points[chart_Remainder] = x;
        ser->y_points[chart_Remainder] = y;
    }
    printf("x[%d]=%d  y[%d]=%d\n",chart_Remainder,(int)ser->x_points[chart_Remainder],chart_Remainder,(int)ser->y_points[chart_Remainder]);
    index_i++;


    //图表滚动  
    if(index_i > (POINT_COUNT*2)/5 && index_i < (POINT_COUNT*9)/10)
    {
        lv_coord_t move = 1000/(((POINT_COUNT*9)/10) - (POINT_COUNT*2)/5);
        lv_obj_scroll_by(chart, 0, -move, LV_ANIM_ON); 
    }
        

    //图表y范围变化
    if(index_i >= Ymax-10)
    {
        lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, Ymax += 1 , Ymin += 1);
    }
        
    lv_chart_refresh(chart); // 刷新图表
}


void user_add_data_test(lv_timer_t* timer) 
{
    LV_UNUSED(timer);
    lv_obj_t *chart = timer->user_data;
    
    update_chart(chart,ser,lv_rand(10,90));
}

void lv_example_chart_6(void)
{

    chart = lv_chart_create(ui_Eddy_Panel);
    lv_obj_set_width(chart, 300);
    lv_obj_set_height(chart, 790);
    lv_obj_set_x(chart, 15);
    lv_obj_set_y(chart, 170);

    lv_obj_set_style_size(chart, 0, LV_PART_INDICATOR);
    lv_chart_set_type(chart, LV_CHART_TYPE_SCATTER);
    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);
    lv_chart_set_point_count(chart, POINT_COUNT);
    lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT);
    lv_obj_refresh_ext_draw_size(chart);
    lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, POINT_COUNT, 0);
    //lv_obj_add_event_cb(chart, User_eddy_Chart_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
    lv_chart_set_zoom_y(chart, 500);

    ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
    lv_chart_set_all_value(chart,ser,LV_CHART_POINT_NONE);
     
    lv_timer_create(user_add_data_test, 30, chart);



}

可以实现如下效果

2.2 旋转后折线图更新形式的实现

        旋转后的折线图,在到最大点数时,会将尾部最后一个点与下一个新点连在一块,形不成连续的波形,通过修改设置点的方式可实现,代码实现在 2.1代码

        形成效果如下:

三、修改x轴范围

        在使用lv_chart中,我发现折线图无法修改x轴的范围,研究了下是底层某个文件限制了这个的实现,我修改了,可以实现折线图的x轴范围的调整,但不确定会不会影响其他,仅供借鉴

修改lvgl/src/extra/widgets/chart/lv_chart.c的        static void draw_x_ticks(lv_obj_t * obj, lv_draw_ctx_t * draw_ctx, lv_chart_axis_t axis)        函数中,改成如下

就可以实现修改了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值