琢磨了好久的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); //创建定时器
}