From 7cf2b8f1c2d9a3b59343f8240e9bbc2e1c8b722e Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Sun, 24 Mar 2019 05:56:00 +0100 Subject: [PATCH] lv_chart fixes --- src/lv_objx/lv_chart.c | 99 +++++++++++++++++++++--------------------- src/lv_objx/lv_chart.h | 4 +- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/lv_objx/lv_chart.c b/src/lv_objx/lv_chart.c index 68339db40..51759cd6e 100644 --- a/src/lv_objx/lv_chart.c +++ b/src/lv_objx/lv_chart.c @@ -9,6 +9,7 @@ #include "lv_chart.h" #if LV_USE_CHART != 0 +#include "../lv_core/lv_refr.h" #include "../lv_draw/lv_draw.h" #include "../lv_themes/lv_theme.h" @@ -36,9 +37,9 @@ static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask); static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask); static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mask); static void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask); -static void lv_chart_inv_lines(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t i); -static void lv_chart_inv_points(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t i); -static void lv_chart_inv_cols(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t i); +static void lv_chart_inv_lines(lv_obj_t * chart, uint16_t i); +static void lv_chart_inv_points(lv_obj_t * chart, uint16_t i); +static void lv_chart_inv_cols(lv_obj_t * chart, uint16_t i); /********************** * STATIC VARIABLES **********************/ @@ -81,6 +82,7 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy) ext->vdiv_cnt = LV_CHART_VDIV_DEF; ext->point_cnt = LV_CHART_PNUM_DEF; ext->type = LV_CHART_TYPE_LINE; + ext->update_mode = LV_CHART_UPDATE_MODE_SHIFT; ext->series.opa = LV_OPA_COVER; ext->series.dark = LV_OPA_50; ext->series.width = 2; @@ -145,7 +147,6 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color) if(ser == NULL) return NULL; ser->color = color; - ser->points = lv_mem_alloc(sizeof(lv_coord_t) * ext->point_cnt); lv_mem_assert(ser->points); if(ser->points == NULL) { @@ -383,20 +384,19 @@ void lv_chart_set_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t * 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); - if(ext->update_mode == LV_CHART_MODE_SHIFT) { + 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_MODE_CIRCULAR) { - static uint16_t x = 0; - ser->points[x] = y; + } 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, x); - if(ext->type & LV_CHART_TYPE_COLUMN) lv_chart_inv_cols(chart, ser, x); - if(ext->type & LV_CHART_TYPE_POINT) lv_chart_inv_points(chart, ser, x); - if(ext->type & LV_CHART_TYPE_VERTICAL_LINE) lv_chart_inv_lines(chart, ser, x); + 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); - x = (x + 1) % ext->point_cnt;/*update the x for next incoming y*/ + ser->start_point = (ser->start_point + 1) % ext->point_cnt;/*update the x for next incoming y*/ } } @@ -638,10 +638,12 @@ static void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask) LV_LL_READ_BACK(ext->series_ll, ser) { style.line.color = ser->color; + lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; + p1.x = 0 + x_ofs; p2.x = 0 + x_ofs; - p_prev = ser->start_point; + p_prev = 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; @@ -652,7 +654,7 @@ 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; - p_act = (ser->start_point + i) % ext->point_cnt; + p_act = (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); @@ -695,6 +697,8 @@ static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask) /*Go through all data lines*/ LV_LL_READ_BACK(ext->series_ll, ser) { + lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; + style_point.body.main_color = ser->color; style_point.body.grad_color = lv_color_mix(LV_COLOR_BLACK, ser->color, ext->series.dark); @@ -702,7 +706,7 @@ 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; - p_act = (ser->start_point + i) % ext->point_cnt; + p_act = (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; @@ -753,13 +757,15 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask) /*Draw the current point of all data line*/ LV_LL_READ_BACK(ext->series_ll, ser) { + lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; + rects.body.main_color = ser->color; rects.body.grad_color = lv_color_mix(LV_COLOR_BLACK, ser->color, ext->series.dark); col_a.x1 = x_act; col_a.x2 = col_a.x1 + col_w; x_act += col_w; - lv_coord_t p_act = (ser->start_point + i) % ext->point_cnt; + lv_coord_t p_act = (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); col_a.y1 = h - y_tmp + chart->coords.y1; @@ -790,6 +796,7 @@ static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mas uint16_t i; lv_point_t p1; lv_point_t p2; + lv_coord_t p_act; lv_coord_t h = lv_obj_get_height(chart); lv_coord_t x_ofs = chart->coords.x1; lv_coord_t y_ofs = chart->coords.y1; @@ -803,6 +810,7 @@ static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mas /*Go through all data lines*/ LV_LL_READ_BACK(ext->series_ll, ser) { + lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; style.line.color = ser->color; p1.x = 0 + x_ofs; @@ -814,8 +822,9 @@ static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mas for(i = 0; i < ext->point_cnt; i++) { + p_act = (start_point + i) % ext->point_cnt; - y_tmp = (int32_t)((int32_t) ser->points[i] - ext->ymin) * h; + 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; @@ -824,11 +833,11 @@ static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mas p2.x++; } - if(ser->points[i] != LV_CHART_POINT_DEF) { + if(ser->points[p_act] != LV_CHART_POINT_DEF) { lv_draw_line(&p1, &p2, mask, &style, opa_scale); } - p2.x = ((w * i) / (ext->point_cnt - 1)) + x_ofs; + p2.x = ((w * p_act) / (ext->point_cnt - 1)) + x_ofs; p1.x = p2.x; p1.y = p2.y; } @@ -860,6 +869,7 @@ static void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask) /*Go through all data lines*/ LV_LL_READ_BACK(ext->series_ll, ser) { + lv_coord_t start_point = ext->update_mode == LV_CHART_UPDATE_MODE_SHIFT ? ser->start_point : 0; style.body.main_color = ser->color; p1.x = 0 + x_ofs; @@ -874,8 +884,8 @@ static void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask) p1.x = p2.x; p1.y = p2.y; - p2.x = ((w * i) / (ext->point_cnt - 1)) + x_ofs; - p_act = (ser->start_point + i) % ext->point_cnt; + p_act = (start_point + i) % ext->point_cnt; + p2.x = ((w * p_act) / (ext->point_cnt - 1)) + x_ofs; y_tmp = (int32_t)((int32_t) ser->points[p_act] - ext->ymin) * h; y_tmp = y_tmp / (ext->ymax - ext->ymin); @@ -901,31 +911,27 @@ static void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask) * invalid area of the new line data lines on a chart * @param obj pointer to chart object */ -static void lv_chart_inv_lines(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t i) +static void lv_chart_inv_lines(lv_obj_t * chart, uint16_t i) { lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); lv_coord_t w = lv_obj_get_width(chart); lv_coord_t x_ofs = chart->coords.x1; - lv_coord_t p_prev; - lv_coord_t p_act; if(i < ext->point_cnt) { - if(i == 0) { - p_prev = ser->start_point; - } else { - p_prev = (ser->start_point + (i - 1)) % ext->point_cnt; - } - p_act = (ser->start_point + i) % ext->point_cnt; + lv_area_t coords; + lv_obj_get_coords(chart, &coords); + if(i < ext->point_cnt - 1) { + coords.x1 = ((w * i) / (ext->point_cnt - 1)) + x_ofs - ext->series.width; + coords.x2 = ((w * (i + 1)) / (ext->point_cnt - 1)) + x_ofs + ext->series.width; + lv_inv_area(lv_obj_get_disp(chart), &coords); + } - if(ser->points[p_prev] != LV_CHART_POINT_DEF && ser->points[p_act] != LV_CHART_POINT_DEF) { - - lv_area_t coords; - lv_obj_get_coords(chart, &coords); - coords.x1 = ((w * i) / (ext->point_cnt - 1)) + x_ofs - ext->series.width; - coords.x2 = ((w * (i + 1)) / (ext->point_cnt - 1)) + x_ofs + ext->series.width; - lv_inv_area(&coords); - } + if(i > 0) { + coords.x1 = ((w * (i - 1)) / (ext->point_cnt - 1)) + x_ofs - ext->series.width; + coords.x2 = ((w * i) / (ext->point_cnt - 1)) + x_ofs + ext->series.width; + lv_inv_area(lv_obj_get_disp(chart), &coords); + } } } @@ -934,23 +940,20 @@ static void lv_chart_inv_lines(lv_obj_t * chart, lv_chart_series_t * ser, uint16 * @param chart pointer to chart object * @param mask mask, inherited from the design function */ -static void lv_chart_inv_points(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t i) +static void lv_chart_inv_points(lv_obj_t * chart, uint16_t i) { lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); lv_area_t cir_a; lv_coord_t w = lv_obj_get_width(chart); lv_coord_t x_ofs = chart->coords.x1; - lv_coord_t p_act; lv_obj_get_coords(chart, &cir_a); cir_a.x1 = ((w * i) / (ext->point_cnt - 1)) + x_ofs; cir_a.x2 = cir_a.x1 + ext->series.width; cir_a.x1 -= ext->series.width; - p_act = (ser->start_point + i) % ext->point_cnt; - if(ser->points[p_act] != LV_CHART_POINT_DEF) - lv_inv_area(&cir_a); + lv_inv_area(lv_obj_get_disp(chart), &cir_a); } /** @@ -958,7 +961,7 @@ static void lv_chart_inv_points(lv_obj_t * chart, lv_chart_series_t * ser, uint1 * @param chart pointer to chart object * @param mask mask, inherited from the design function */ -static void lv_chart_inv_cols(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t i) +static void lv_chart_inv_cols(lv_obj_t * chart, uint16_t i) { lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart); @@ -976,11 +979,7 @@ static void lv_chart_inv_cols(lv_obj_t * chart, lv_chart_series_t * ser, uint16_ col_a.x1 = x_act; col_a.x2 = col_a.x1 + col_w; - //lv_coord_t p_act = (ser->start_point + i) % ext->point_cnt; - - /*if(ser->points[p_act] != LV_CHART_POINT_DEF)*/ { - lv_inv_area(&col_a); - } + lv_inv_area(lv_obj_get_disp(chart), &col_a); } #endif diff --git a/src/lv_objx/lv_chart.h b/src/lv_objx/lv_chart.h index 28de00b01..14ec08af9 100644 --- a/src/lv_objx/lv_chart.h +++ b/src/lv_objx/lv_chart.h @@ -47,8 +47,8 @@ typedef uint8_t lv_chart_type_t; /*Chart update mode*/ enum { - LV_CHART_MODE_SHIFT, - LV_CHART_MODE_CIRCULAR, + LV_CHART_UPDATE_MODE_SHIFT, + LV_CHART_UPDATE_MODE_CIRCULAR, }; typedef uint8_t lv_chart_update_mode_t;