UI设计工具文档UI设计工具文档
反馈
  • AC791
  • AC792
  • AC63
  • GPMCU
  • AD14/15/17/18/AD104
  • AD16
  • AD24
  • AC82
  • AW30
  • AW31
反馈
  • AC791
  • AC792
  • AC63
  • GPMCU
  • AD14/15/17/18/AD104
  • AD16
  • AD24
  • AC82
  • AW30
  • AW31
  • 1.工具前言

    • 1.1.工具首页
    • 1.2.前言说明
  • 2.快速使用

    • 2.1.快速使用
    • 2.2.快速上手
    • 2.3.板子配置
    • 2.4.视频教程
    • 2.5.硬件资料
  • 3.控件说明

    • 3.1.控件说明
    • 3.2.基础控件

      • 页面
      • 按钮
      • 图片按钮
      • 标签
      • 图片
      • 文本框
      • 开关
      • 数字微调器
      • 复选框
      • 下拉框
      • 进度条
      • Lottie动画
      • 帧动画
      • 图表
      • 滑动条
      • 弧线
      • 仪表盘
    • 3.3.菜单控件

      • 圆弧菜单
      • 齿轮菜单
      • 列表菜单
      • 曲线菜单
      • 网格菜单
      • 万花筒菜单
      • 多边形菜单
    • 3.4.容器控件

      • 通用容器
      • Flex布局
  • 4.高级功能

    • 4.1.时间轴动画
    • 4.2.模型绑定
    • 4.3.资源管理
    • 4.4.国际化
    • 4.5.硬件仿真
    • 4.6.自动化测试
    • 4.7.控件组
    • 4.8.菜单管理
    • 4.9.页面管理
    • 4.10.动态页面
  • 5.插件系统

    • 5.1.插件说明
    • 5.2.开发指南
    • 5.3.字体合并
    • 5.4.图片编辑
    • 5.5.截图
    • 5.6.项目合并
    • 5.7.项目属性编辑
    • 5.8.视频转图片
  • 6.使用案例

    • 6.1.倒计时案例
  • 7.常见问题

    • 7.1.问题说明
    • 7.2.编译问题
    • 7.3.LVGL问题
    • 7.4.仿真问题
    • 7.5.UI工具问题
    • 7.6.其他问题
  • 8.工具杂项

    • 8.1.杂项1
    • 8.2.杂项2

图表

图表组件用于在屏幕上显示动态数据,支持多种类型的图表(如折线图、柱状图等),并允许用户自定义轴线和刻度设置。通过配置属性,可以调整网格线的数量、每个序列的数据点数以及更新模式等参数,以适应不同的应用场景

本章目录
  • 1. 属性
    • 1.1. 图表数据
    • 1.2. 轴线
    • 1.3. 图表类型
    • 1.4. 更新模式
  • 2. 样式
  • 3. 使用
    • 3.1. 折线图
    • 3.2. 柱状图
    • 3.3. 自定义折现图
本章正文

属性

PropertyDescription
Div Row水平网格线数量
Div Col垂直网格线数量
Point Count每个序列的数据点数量
Chart Type图表类型(折线图/柱状图)
Update Mode更新模式(移位/循环)
Zoom XX轴缩放比例
Zoom YY轴缩放比例
Chart Data图表数据系列
Axis Tick轴线刻度设置

图表数据

PropertyDescription
Chart Color数据系列颜色
Chart Points数据系列点数
Chart Axis数据系列关联的轴(左侧或右侧)

轴线

PropertyDescription
Axis Name轴线名称
Min数值范围最小值
Max数值范围最大值
Major Len主刻度线长度
Minor Len次刻度线长度
Major Count主刻度线数量
Minor Count次刻度线数量
Tick En刻度线是否显示
Label En刻度线标签是否显示
Draw Size绘制刻度所需额外空间
Text刻度线标签文本格式

图表类型

  • 折线图:连接数据点的线条,可选择性地在数据点上显示标记
  • 柱状图:以垂直柱形显示数据

更新模式

  • 移位:新数据添加到右侧,旧数据向左移动
  • 循环:数据以循环方式添加,如心电图显示

样式

StylePartDescription
Line ColorMain直线(网格线)颜色
Line WidthMain直线(网格线)宽度
Line OpacityMain直线(网格线)透明度
Line Dash WidthMain直线(网格线)虚线宽度
Line Dash GapMain直线(网格线)虚线间距
Line ColorTicks刻度线颜色
Line WidthTicks刻度线宽度
Line OpacityTicks刻度线透明度
Line WidthItems折线图中的线条宽度
Bg OpacityItems折线图中的背景(堆积效果)透明度,当透明度不为0时,工具会自动生成事件回调来实现折线堆积效果
Bg Grad ColorItems折线图中的背景(堆积效果)渐变颜色
Bg Grad DirItems折线图中的背景(堆积效果)渐变方向
Border ColorIndicator数据点边框颜色
Border WidthIndicator数据点边框宽度
Border OpacityIndicator数据点边框透明度
Border SideIndicator数据点边框位置
SizeIndicator数据点大小

使用

折线图

  • 控件属性
  • 仿真

柱状图

  • 控件属性
  • 仿真

自定义折现图

  • 控件属性
  • 控件样式
  • 控件事件

extern void custom_chart_draw_event_cb(lv_event_t * e);
extern void custom_chart_hide_cb(lv_event_t * e);
custom_chart_draw_event_cb(e);
custom_chart_hide_cb(e);


//在custom.c中实现

void custom_chart_draw_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);
	lv_chart_t * chart = (lv_chart_t *)obj;
    lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
    
    // 只处理图表部分和线段绘制
    if(dsc->part != LV_PART_ITEMS || !dsc->p1 || !dsc->p2) return;

    // 确保不透明度不为0
    // lv_opa_t bg_opa = lv_obj_get_style_bg_opa(obj, LV_PART_ITEMS | LV_STATE_DEFAULT);
    // if(bg_opa == LV_OPA_TRANSP) return;
    lv_opa_t bg_opa = 40; // 设置渐变背景的透明度

    // 获取系列数据和点索引
    lv_chart_series_t * ser = (lv_chart_series_t *)dsc->sub_part_ptr;
    if(ser == NULL) return;
    

    uint16_t curr_idx = dsc->id;
    uint16_t next_idx = dsc->id + 1;
    if (curr_idx < 0 || next_idx > chart->point_cnt - 1) return;

    lv_coord_t curr_y = ser->y_points[curr_idx];
    lv_coord_t next_y = ser->y_points[next_idx];

    if (curr_y <= 0 || next_y <= 0) {
        return; // 如果y值小于等于0,则不绘制渐变背景
    }

    //渐变背景绘制
    lv_color_t grad_color = lv_obj_get_style_bg_grad_color(obj, LV_PART_ITEMS | LV_STATE_DEFAULT);
    lv_grad_dir_t grad_dir = lv_obj_get_style_bg_grad_dir(obj, LV_PART_ITEMS | LV_STATE_DEFAULT);
    if (grad_dir == LV_GRAD_DIR_NONE) {
        lv_draw_mask_line_param_t line_mask_param;
        lv_draw_mask_line_points_init(&line_mask_param, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y, LV_DRAW_MASK_LINE_SIDE_BOTTOM);
        int16_t line_mask_id = lv_draw_mask_add(&line_mask_param, NULL);

        lv_draw_rect_dsc_t draw_rect_dsc;
        lv_draw_rect_dsc_init(&draw_rect_dsc);
        draw_rect_dsc.bg_color = dsc->line_dsc->color;
        draw_rect_dsc.bg_opa = bg_opa;

        lv_area_t a;
        a.x1 = dsc->p1->x;
        a.x2 = dsc->p2->x - 1;
        a.y1 = LV_MIN(dsc->p1->y, dsc->p2->y);
        a.y2 = obj->coords.y2;
        lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);

        lv_draw_mask_free_param(&line_mask_param);
        lv_draw_mask_remove_id(line_mask_id);
    } else if (grad_dir == LV_GRAD_DIR_HOR) {
        lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj, LV_PART_MAIN);
        lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj, LV_PART_MAIN);
        lv_coord_t x1_ofs = obj->coords.x1 + pad_left - lv_obj_get_scroll_left(obj);
        lv_coord_t x2_ofs = obj->coords.x2 - pad_right - lv_obj_get_scroll_right(obj);

        lv_draw_mask_line_param_t line_mask_param1;
        lv_draw_mask_line_points_init(&line_mask_param1, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y, LV_DRAW_MASK_LINE_SIDE_BOTTOM);
        int16_t line_mask_id1 = lv_draw_mask_add(&line_mask_param1, NULL);

        lv_draw_mask_line_param_t line_mask_param2;
        lv_draw_mask_line_points_init(&line_mask_param2, dsc->p2->x, LV_MIN(dsc->p1->y, dsc->p2->y), dsc->p2->x, obj->coords.y2, LV_DRAW_MASK_LINE_SIDE_LEFT);
        int16_t line_mask_id2 = lv_draw_mask_add(&line_mask_param2, NULL);

        lv_draw_mask_line_param_t line_mask_param3;
        lv_draw_mask_line_points_init(&line_mask_param3, dsc->p1->x, LV_MIN(dsc->p1->y, dsc->p2->y), dsc->p1->x, obj->coords.y2, LV_DRAW_MASK_LINE_SIDE_RIGHT);
        int16_t line_mask_id3 = lv_draw_mask_add(&line_mask_param3, NULL);

        // 当图表的数据超过两条时,这里渲染的颜色会有问题,所有数据的颜色都变成了第一条数据的颜色
        lv_draw_rect_dsc_t draw_rect_dsc;
        lv_draw_rect_dsc_init(&draw_rect_dsc);
        draw_rect_dsc.bg_opa = bg_opa;
        draw_rect_dsc.bg_grad.stops[0].color = dsc->line_dsc->color;
        draw_rect_dsc.bg_grad.stops[1].color = grad_color;
        draw_rect_dsc.bg_grad.stops[0].frac = 0;
        draw_rect_dsc.bg_grad.stops[1].frac = 255;
        draw_rect_dsc.bg_grad.dir = LV_GRAD_DIR_HOR;

        lv_area_t a;
        a.x1 = x1_ofs;
        a.x2 = x2_ofs + 1;
        a.y1 = LV_MIN(dsc->p1->y, dsc->p2->y);
        a.y2 = obj->coords.y2;
        lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);

        lv_draw_mask_free_param(&line_mask_param1);
        lv_draw_mask_free_param(&line_mask_param2);
        lv_draw_mask_free_param(&line_mask_param3);
        lv_draw_mask_remove_id(line_mask_id1);
        lv_draw_mask_remove_id(line_mask_id2);
        lv_draw_mask_remove_id(line_mask_id3);
    } else if (grad_dir == LV_GRAD_DIR_VER) {
        lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj, LV_PART_MAIN);
        lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj, LV_PART_MAIN);
        lv_coord_t y1_ofs = obj->coords.y1 + pad_top - lv_obj_get_scroll_top(obj);
        lv_coord_t y2_ofs = obj->coords.y2 - pad_bottom - lv_obj_get_scroll_bottom(obj);
        lv_chart_series_t * ser = (lv_chart_series_t *)dsc->sub_part_ptr;
        lv_chart_t * chart = (lv_chart_t *)obj;
        uint16_t point_cnt = chart->point_cnt;
        lv_coord_t max_point = 0;
        lv_coord_t max_point_y = 0;
        for (uint16_t i = 0; i < point_cnt; i++) {
            if (ser->y_points[i] == LV_CHART_POINT_NONE) continue;
            max_point = LV_MAX(max_point, ser->y_points[i]);
        }
        if (ser->y_axis_sec == 0) {
            max_point_y = y2_ofs - (max_point - chart->ymin[0]) * (y2_ofs - y1_ofs) / (chart->ymax[0] - chart->ymin[0]);
        } else {
            max_point_y = y2_ofs - (max_point - chart->ymin[1]) * (y2_ofs - y1_ofs) / (chart->ymax[1] - chart->ymin[1]);
        }

        lv_draw_mask_line_param_t line_mask_param;
        lv_draw_mask_line_points_init(&line_mask_param, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y, LV_DRAW_MASK_LINE_SIDE_BOTTOM);
        int16_t line_mask_id = lv_draw_mask_add(&line_mask_param, NULL);

        lv_draw_rect_dsc_t draw_rect_dsc;
        lv_draw_rect_dsc_init(&draw_rect_dsc);
        draw_rect_dsc.bg_opa = bg_opa;
        draw_rect_dsc.bg_grad.stops[0].color = dsc->line_dsc->color;
        draw_rect_dsc.bg_grad.stops[1].color = grad_color;
        draw_rect_dsc.bg_grad.stops[0].frac = 0;
        draw_rect_dsc.bg_grad.stops[1].frac = 255;
        draw_rect_dsc.bg_grad.dir = LV_GRAD_DIR_VER;

        lv_area_t a;
        a.x1 = dsc->p1->x;
        a.x2 = dsc->p2->x - 1;
        a.y1 = max_point_y;
        a.y2 = obj->coords.y2;
        lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);

        lv_draw_mask_free_param(&line_mask_param);
        lv_draw_mask_remove_id(line_mask_id);
    }
}

void custom_chart_hide_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);
    lv_chart_t * chart = (lv_chart_t *)obj;
    lv_obj_draw_part_dsc_t * dsc = (lv_obj_draw_part_dsc_t *)lv_event_get_draw_part_dsc(e);

    lv_chart_series_t * ser = (lv_chart_series_t *)dsc->sub_part_ptr;
    if(ser == NULL) return;

    if(dsc->part == LV_PART_ITEMS) {
        if(dsc->p1 && dsc->p2 && dsc->line_dsc) {
            uint16_t curr_idx = dsc->id;
            uint16_t next_idx = dsc->id + 1;

            if (curr_idx >= 0 && next_idx < chart->point_cnt) {
                lv_coord_t curr_y = ser->y_points[curr_idx];
                lv_coord_t next_y = ser->y_points[next_idx];

                //如果两点有y值小于等于0,则不绘制折线
                if (curr_y <= 0 || next_y <= 0) {
                    dsc->line_dsc->opa = LV_OPA_TRANSP;
                } else {
                    dsc->line_dsc->opa = LV_OPA_COVER;
                }
            }

            if (dsc->rect_dsc) {
                dsc->rect_dsc->bg_color = dsc->line_dsc->color;
                dsc->rect_dsc->border_color = lv_color_make(0x00, 0x00, 0x00);
            }
        } else if(!dsc->p1 && !dsc->p2) {
            // 修改折现的最后一点的样式
            if (dsc->rect_dsc) {
                dsc->rect_dsc->border_color = dsc->rect_dsc->bg_color;
                dsc->rect_dsc->bg_color = lv_color_make(0x00, 0x00, 0x00);
            }
        }
    }
}

  • 仿真
上一页
帧动画
下一页
滑动条