diff --git a/lv_objx/lv_chart.c b/lv_objx/lv_chart.c index d0f7c4d67..b3ac83880 100644 --- a/lv_objx/lv_chart.c +++ b/lv_objx/lv_chart.c @@ -58,8 +58,6 @@ static lv_signal_func_t ancestor_signal; */ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy) { - - LV_LOG_TRACE("chart create started"); /*Create the ancestor basic object*/ @@ -153,6 +151,8 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color) return NULL; } + ser->start_point = 0; + uint16_t i; lv_coord_t * p_tmp = ser->points; for(i = 0; i < ext->point_cnt; i++) { @@ -179,8 +179,11 @@ void lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * serie) return; for(uint32_t i = 0; i < ext->point_cnt; i++) { - serie->points[i] = -1; + serie->points[i] = LV_CHART_POINT_DEF; } + + serie->start_point = 0; + } /*===================== @@ -254,18 +257,44 @@ void lv_chart_set_point_count(lv_obj_t * chart, uint16_t point_cnt) if(point_cnt < 1) point_cnt = 1; LL_READ_BACK(ext->series_ll, ser) { - ser->points = lv_mem_realloc(ser->points, sizeof(lv_coord_t) * point_cnt); - lv_mem_assert(ser->points); - if(ser->points == NULL) return; - /*Initialize the new points*/ - if(point_cnt > point_cnt_old) { - for(i = point_cnt_old - 1; i < point_cnt; i++) { - ser->points[i] = def; + if(ser->start_point != 0) { + lv_coord_t * new_points = lv_mem_alloc(sizeof(lv_coord_t) * point_cnt); + lv_mem_assert(new_points); + if(new_points == NULL) return; + + if(point_cnt >= point_cnt_old) { + for(i = 0; i < point_cnt_old; i++) { + new_points[i] = ser->points[(i + ser->start_point) % point_cnt_old]; /*Copy old contents to new array*/ + } + for(i = point_cnt_old; i < point_cnt; i++) { + new_points[i] = def; /*Fill up the rest with default value*/ + } + } else { + for(i = 0; i < point_cnt; i++) { + new_points[i] = ser->points[(i + ser->start_point) % point_cnt_old]; /*Copy old contents to new array*/ + } + } + + /*Switch over pointer from old to new*/ + lv_mem_free(ser->points); + ser->points = new_points; + } else { + ser->points = lv_mem_realloc(ser->points, sizeof(lv_coord_t) * point_cnt); + lv_mem_assert(ser->points); + if(ser->points == NULL) return; + /*Initialize the new points*/ + if(point_cnt > point_cnt_old) { + for(i = point_cnt_old - 1; i < point_cnt; i++) { + ser->points[i] = def; + } } } + + ser->start_point = 0; } ext->point_cnt = point_cnt; + lv_chart_refresh(chart); } @@ -323,6 +352,7 @@ void lv_chart_init_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t for(i = 0; i < ext->point_cnt; i++) { ser->points[i] = y; } + ser->start_point = 0; lv_chart_refresh(chart); } @@ -336,27 +366,24 @@ void lv_chart_set_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t * { lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); memcpy(ser->points, y_array, ext->point_cnt * (sizeof(lv_coord_t))); + ser->start_point = 0; lv_chart_refresh(chart); } /** - * Shift all data right and set the most right data on a data line + * Shift all data left and set the rightmost data on a data line * @param chart pointer to chart object * @param ser pointer to a data series on 'chart' - * @param y the new value of the most right data + * @param y the new value of the rightmost data */ void lv_chart_set_next(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y) { lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); - uint16_t i; - for(i = 0; i < ext->point_cnt - 1; i++) { - ser->points[i] = ser->points[i + 1]; - } + 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; - ser->points[ext->point_cnt - 1] = y; lv_chart_refresh(chart); - } /*===================== @@ -582,6 +609,8 @@ static void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask) lv_coord_t x_ofs = chart->coords.x1; lv_coord_t y_ofs = chart->coords.y1; int32_t y_tmp; + lv_coord_t p_prev; + lv_coord_t p_act; lv_chart_series_t * ser; lv_opa_t opa_scale = lv_obj_get_opa_scale(chart); lv_style_t style; @@ -595,7 +624,9 @@ static void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask) p1.x = 0 + x_ofs; p2.x = 0 + x_ofs; - y_tmp = (int32_t)((int32_t) ser->points[0] - ext->ymin) * h; + + p_prev = ser->start_point; + y_tmp = (int32_t)((int32_t) ser->points[p_prev] - ext->ymin) * h; y_tmp = y_tmp / (ext->ymax - ext->ymin); p2.y = h - y_tmp + y_ofs; @@ -605,12 +636,16 @@ static void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask) p2.x = ((w * i) / (ext->point_cnt - 1)) + x_ofs; - y_tmp = (int32_t)((int32_t) ser->points[i] - ext->ymin) * h; + p_act = (ser->start_point + i) % ext->point_cnt; + + y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h; y_tmp = y_tmp / (ext->ymax - ext->ymin); p2.y = h - y_tmp + y_ofs; - if(ser->points[i - 1] >= 0 && ser->points[i] >= 0) + if(ser->points[p_prev] != LV_CHART_POINT_DEF && ser->points[p_act] != LV_CHART_POINT_DEF) lv_draw_line(&p1, &p2, mask, &style, opa_scale); + + p_prev = p_act; } } } @@ -631,6 +666,7 @@ static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask) lv_coord_t x_ofs = chart->coords.x1; lv_coord_t y_ofs = chart->coords.y1; int32_t y_tmp; + lv_coord_t p_act; lv_chart_series_t * ser; uint8_t series_cnt = 0; lv_style_t style_point; @@ -651,14 +687,14 @@ static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask) cir_a.x1 = ((w * i) / (ext->point_cnt - 1)) + x_ofs; cir_a.x2 = cir_a.x1 + style_point.body.radius; cir_a.x1 -= style_point.body.radius; - - y_tmp = (int32_t)((int32_t) ser->points[i] - ext->ymin) * h; + p_act = (ser->start_point + i) % ext->point_cnt; + y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h; y_tmp = y_tmp / (ext->ymax - ext->ymin); cir_a.y1 = h - y_tmp + y_ofs; cir_a.y2 = cir_a.y1 + style_point.body.radius; cir_a.y1 -= style_point.body.radius; - if(ser->points[i] >= 0) + if(ser->points[p_act] != LV_CHART_POINT_DEF) lv_draw_rect(&cir_a, mask, &style_point, lv_obj_get_opa_scale(chart)); } series_cnt++; @@ -695,6 +731,7 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask) col_a.y2 = chart->coords.y2; lv_coord_t x_act; + printf("\n", y_tmp); /*Go through all points*/ for(i = 0; i < ext->point_cnt; i ++) { @@ -709,12 +746,14 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask) col_a.x2 = col_a.x1 + col_w; x_act += col_w; - y_tmp = (int32_t)((int32_t) ser->points[i] - ext->ymin) * h; + lv_coord_t p_act = (ser->start_point + i) % ext->point_cnt; + y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h; y_tmp = y_tmp / (ext->ymax - ext->ymin); + printf("ytmp:%d\n", y_tmp); col_a.y1 = h - y_tmp + chart->coords.y1; mask_ret = lv_area_intersect(&col_mask, mask, &col_a); - if(mask_ret != false && ser->points[i] >= 0) { + if(mask_ret != false && ser->points[p_act] != LV_CHART_POINT_DEF) { lv_draw_rect(&chart->coords, &col_mask, &rects, lv_obj_get_opa_scale(chart)); } } diff --git a/lv_objx/lv_chart.h b/lv_objx/lv_chart.h index 2f1a43b37..08d4c4eea 100644 --- a/lv_objx/lv_chart.h +++ b/lv_objx/lv_chart.h @@ -36,6 +36,7 @@ typedef struct { lv_coord_t * points; lv_color_t color; + uint16_t start_point; } lv_chart_series_t; /*Data of chart */ @@ -52,9 +53,9 @@ typedef struct uint8_t type :4; /*Line, column or point chart (from 'lv_chart_type_t')*/ struct { lv_coord_t width; /*Line width or point radius*/ - uint8_t num; /*Number of data lines in dl_ll*/ - lv_opa_t opa; /*Opacity of data lines*/ - lv_opa_t dark; /*Dark level of the point/column bottoms*/ + uint8_t num; /*Number of data lines in dl_ll*/ + lv_opa_t opa; /*Opacity of data lines*/ + lv_opa_t dark; /*Dark level of the point/column bottoms*/ } series; } lv_chart_ext_t;