Clearing last point of Chart / Add indicator of current point

Hi all,

The LV_CHART_UPDATE_MODE_CIRCULAR update mode is a great feature to presenting medical chart data like ECG, EGG, etc.
but it lack an indicator of the current point in series.
Is that me that don’t know the feature exists or that is not yet implemented in lv_chart ?
So I’m requesting a feature to clear some last point in the series like in this image below:

Regards,
TJ.

Hi,

Unfortunately it’s really not supported now out of the box.
If you want to do it manually you should add LV_CHART_POINT_DEF points to display “gaps”.

Hi,

Ok, I will take a look at LV_CHART_POINT_DEF I hope that can be used for my need.

Regards,
TJ.

Hi tjsyle,

I refer to the following code, which can clear a point, but cannot clear an area.

uint16_t next_p = cpu_ser->start_point % lv_chart_get_point_cnt(chart);
cpu_ser->points[next_p] = LV_CHART_POINT_DEF;

Have you solved it? I hope there is a better way to clear an area.@kisvegabor
Thanks.

1 Like

I’ve modified lv_chart_next like this, and it worked for me:

void lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y)
{
    LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
    LV_ASSERT_NULL(ser);

    lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
    if(ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT) {
        ser->points[ser->start_point] =
            y; /*This was the place of the former left most value, after shifting it is the rightmost*/
        ser->start_point = (ser->start_point + 1) % ext->point_cnt;
        lv_chart_refresh(chart);
    } else if(ext->update_mode == LV_CHART_UPDATE_MODE_CIRCULAR) {
        ser->points[ser->start_point] = y;

        if(ext->type & LV_CHART_TYPE_LINE) lv_chart_inv_lines(chart, ser->start_point);
        if(ext->type & LV_CHART_TYPE_COLUMN) lv_chart_inv_cols(chart, ser->start_point);
        if(ext->type & LV_CHART_TYPE_POINT) lv_chart_inv_points(chart, ser->start_point);
        if(ext->type & LV_CHART_TYPE_VERTICAL_LINE) lv_chart_inv_lines(chart, ser->start_point);
        if(ext->type & LV_CHART_TYPE_AREA) lv_chart_inv_lines(chart, ser->start_point);

        ser->start_point = (ser->start_point + 1) % ext->point_cnt; /*update the x for next incoming y*/
        
        /*THIS IS ADDED:
          Add one point break*/
        ser->points[ser->start_point] = LV_CHART_POINT_DEF;

        if(ext->type & LV_CHART_TYPE_LINE) lv_chart_inv_lines(chart, ser->start_point);
        if(ext->type & LV_CHART_TYPE_COLUMN) lv_chart_inv_cols(chart, ser->start_point);
        if(ext->type & LV_CHART_TYPE_POINT) lv_chart_inv_points(chart, ser->start_point);
        if(ext->type & LV_CHART_TYPE_VERTICAL_LINE) lv_chart_inv_lines(chart, ser->start_point);
        if(ext->type & LV_CHART_TYPE_AREA) lv_chart_inv_lines(chart, ser->start_point);

    }
}
2 Likes

@Lucifer

I’ve tried suggestion @kisvegabor about LV_CHART_POINT_DEF but not succeeded due my limited knowledge about lv_chart structure.
But then @kisvegabor update the detail, it’s worked great now.

1 Like

Thank you very mush.@kisvegabor @tjstyle

Here is my way of doing it in LVGL 8.3. I hope this will be useful for someone else wanting to do the same thing.

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;
    invalidate_point(obj, ser->start_point);
    ser->start_point = (ser->start_point + 1) % chart->point_cnt;
    invalidate_point(obj, ser->start_point);

    //the following code is added
    for (int gap = 0; gap < 10; gap++)
    {
        ser->y_points[(ser->start_point + gap) % chart->point_cnt] = LV_CHART_POINT_NONE;
        invalidate_point(obj, (ser->start_point + gap) % chart->point_cnt);
    }
}