使用LVGL的chart控件做一个渐变的条状图图表

#define __FLOOR_DATA_TO(v, step_floor_v)   v = (step_floor_v) + (((v <= 0) ? 0 : (v - 1)) / (step_floor_v)) * (step_floor_v);
#define BAR_NUM 24

 /*获取buf的最大最小值*/
void points_scan_max_min(lv_coord_t* buf, uint32_t points_cnt, lv_coord_t* _p_max, lv_coord_t* _p_min)
{
    lv_coord_t max_v = LV_COORD_MIN;
    lv_coord_t min_v = LV_COORD_MAX;
    if (_p_max || _p_min) {
        for (uint32_t i = 0; i < points_cnt; i++) {
            if (buf[i] > max_v) {
                max_v = buf[i];
            }

            if (buf[i] < min_v) {
                min_v = buf[i];
            }
        }
        if (_p_max) {
            *_p_max = max_v;
        }

        if (_p_min) {
            *_p_min = min_v;
        }
    }
}
/*使用lv_rand生成指定数量的随机数并且存入buf*/
void _generate_random_data(lv_coord_t* buf, uint16_t cnt, lv_coord_t min_val, lv_coord_t max_val)
{
    for (int i = 0; i < cnt; i++) {
        buf[i] = lv_rand(min_val, max_val);
    }
    for (int i = 0; i < cnt; i++) {
        printf("buf[%d]=%d ", i, buf[i]);
    }
    printf("\n");
}

/* 图表的绘制事件,修改x轴的标签为时间 */
static void chart_draw_event_cb(lv_event_t* e)
{
    lv_obj_draw_part_dsc_t* dsc = lv_event_get_draw_part_dsc(e);
    /* 如果绘制的是底下的x轴且绘制text的指针不为空存在 */
    if (dsc->id == LV_CHART_AXIS_PRIMARY_X && dsc->text) {
        const char* time[] = { "0:00", "6:00", "12:00", "18:00", "24:00" };
        lv_snprintf(dsc->text, dsc->text_length, "%s", time[dsc->value]);
    }
    /* 如果绘制的是条形图对象 */

    if (dsc->part == LV_PART_ITEMS) {
        //设置透明度
        dsc->rect_dsc->bg_opa = LV_OPA_COVER;
        //设置渐变方向
        dsc->rect_dsc->bg_grad.dir = LV_GRAD_DIR_VER;
        //设置渐变颜色
        dsc->rect_dsc->bg_grad.stops[0].color = lv_palette_main(LV_PALETTE_RED);
        dsc->rect_dsc->bg_grad.stops[1].color = lv_palette_main(LV_PALETTE_BLUE);
    }
}

int app_chart_1(lv_obj_t* parent)
{
    static lv_coord_t data_buf[BAR_NUM] = { 0 };
    lv_coord_t max_value = 0;
    lv_coord_t min_value = 0;
    lv_obj_set_style_bg_color(parent, lv_color_black(), LV_PART_MAIN);
    /*Create a chart*/
    lv_obj_t* chart = lv_chart_create(parent);

    /*添加ser*/
    lv_chart_series_t* ser = lv_chart_add_series(chart, lv_color_make(0, 245, 167), LV_CHART_AXIS_PRIMARY_Y);
    /* 设置图表大小 */
    lv_obj_set_size(chart, 280, 160);
    /* 设置为柱状图 */
    lv_chart_set_type(chart, LV_CHART_TYPE_BAR);

    /* 设置x轴上有24条柱 */
    lv_chart_set_point_count(chart, BAR_NUM);
    /* 设置左边的y轴的主要刻度有4条, 主要刻度长度为6,小刻度长度为0, 数量为1条(0条好像不行) */
    lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 6, 0, 4, 1, true, 60);
    /* 设置x轴的主要刻度有5条, 主要刻度长度为0 */
    lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 0, 0, 5, 1, true, 40);

    /*********** 设置LV_PART_TICKS的风格 ***********/
    //设置刻度标签的颜色
    lv_obj_set_style_text_color(chart, lv_color_white(), LV_PART_TICKS);
    //设置刻度标签的字体
    lv_obj_set_style_text_font(chart, &lv_font_montserrat_14, LV_PART_TICKS);
    //设置刻度标签的透明度
    lv_obj_set_style_text_opa(chart, LV_OPA_COVER, LV_PART_TICKS);
    //设置刻度的宽度
    lv_obj_set_style_line_width(chart, 1, LV_PART_TICKS);
    //设置刻度的颜色
    lv_obj_set_style_line_color(chart, lv_color_white(), LV_PART_TICKS);
    //设置刻度的透明度
    lv_obj_set_style_line_opa(chart, LV_OPA_COVER, LV_PART_TICKS);
    // 设置x轴标签离底部距离
    lv_obj_set_style_pad_bottom(chart, 4, LV_PART_TICKS);
    // 设置y轴标签离左边距离
    lv_obj_set_style_pad_left(chart, 2, LV_PART_TICKS);

    /*********** 设置LV_PART_MAIN的风格 ***********/
    // 设置y轴标签离底部距离
    lv_obj_set_style_pad_bottom(chart, 0, LV_PART_MAIN);
    //设置间距让柱状变细
    lv_obj_set_style_pad_column(chart, 6, LV_PART_MAIN);
    //设置背景圆角为0
    lv_obj_set_style_radius(chart, 0, LV_PART_MAIN);
    //设置背景为黑色
    lv_obj_set_style_bg_color(chart, lv_color_black(), LV_PART_MAIN);
    // 设置网格线条颜色
    lv_obj_set_style_line_color(chart, lv_color_black(), LV_PART_MAIN);
    // 设置网格线透明度
    lv_obj_set_style_line_opa(chart, 0, LV_PART_MAIN);
    // 设置网格线宽度
    lv_obj_set_style_line_width(chart, 0, LV_PART_MAIN);
    lv_obj_set_style_pad_top(chart, 0, LV_PART_MAIN);

    /*********** 设置LV_PART_ITEMS的风格 ***********/
    //设置柱状线条圆角
    lv_obj_set_style_radius(chart, 3, LV_PART_ITEMS);


    /*产生24个随机数*/
    _generate_random_data(data_buf, BAR_NUM, 100, 2000);
    /*获取数值的最大和最小值*/
    points_scan_max_min(data_buf, BAR_NUM, &max_value, &min_value);
    printf("max_value = %d, min_value = %d\n", max_value, min_value);
    // 将max_value设置为100的倍数,2987 -> 3000
    __FLOOR_DATA_TO(max_value, 100);

    /*设置图表的范围*/
    lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, max_value);
    //lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, min_value, max_value);

    /*设置图表的柱子数值*/
    lv_chart_set_ext_y_array(chart, ser, data_buf);

    /*添加绘制事件修改x轴的数值*/
    lv_obj_add_event_cb(chart, chart_draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
    //更新图表
    lv_chart_refresh(chart); /*Required after direct set*/
    //设置图表位置
    lv_obj_center(chart);
    return 0;
}

这个代码还是有点问题,最底下的柱状图覆盖了x轴,如果有大佬知道怎么修改比较好,请告诉我

  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在 C# 中,可以通过 `Thread` 类来创建线程,并在线程中更新 `Chart` 控件的数值。具体实现步骤如下: 1. 在窗体上添加 `Chart` 控件,并设置其 `ChartType` 属性为 `SeriesChartType.Line`。 2. 在窗体的构造函数中启动一个新线程,该线程每隔一段时间随机生成一个数值,并通过 `Invoke` 方法将该数值更新到 `Chart` 控件中。 下面是示例代码: ```csharp using System; using System.Threading; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; namespace ChartThreadDemo { public partial class Form1 : Form { private Random random = new Random(); public Form1() { InitializeComponent(); // 启动新线程 Thread thread = new Thread(new ThreadStart(UpdateChart)); thread.Start(); } private void UpdateChart() { while (true) { // 随机生成一个数值 int value = random.Next(100); // 将数值添加到 Chart 控件chart1.Invoke(new Action(() => { chart1.Series[0].Points.AddY(value); chart1.ChartAreas[0].AxisX.ScaleView.Scroll(ChartScrollStyle.Last); })); // 等待一段时间 Thread.Sleep(1000); } } } } ``` 上述代码中,`UpdateChart` 方法是线程的入口点,该方法使用 `Random` 类生成一个随机数值,并通过 `Invoke` 方法将数值添加到 `Chart` 控件中。在 `Invoke` 方法中,使用一个匿名方法来更新 `Chart` 控件,其中 `Series[0]` 表示 Chart 控件中第一个系列的数据,`Points` 属性表示该系列中的数据点,`AddY` 方法可以将一个数值添加到数据点中。`ChartAreas[0].AxisX.ScaleView.Scroll` 方法可以控制 Chart 控件的滚动,将其滚动到最后一个数据点的位置。 需要注意的是,在更新 Chart 控件时,需要使用 `Invoke` 方法跨线程访问控件,否则会抛出线程访问异常。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值