diff --git a/src/widgets/chart/lv_chart.c b/src/widgets/chart/lv_chart.c index 2b32884da..55b7932a2 100644 --- a/src/widgets/chart/lv_chart.c +++ b/src/widgets/chart/lv_chart.c @@ -188,6 +188,7 @@ void lv_chart_set_zoom_x(lv_obj_t * obj, uint16_t zoom_x) lv_chart_t * chart = (lv_chart_t *)obj; if(chart->zoom_x == zoom_x) return; + if(LV_ZOOM_NONE > zoom_x) zoom_x = LV_ZOOM_NONE; chart->zoom_x = zoom_x; lv_obj_refresh_self_size(obj); @@ -202,6 +203,7 @@ void lv_chart_set_zoom_y(lv_obj_t * obj, uint16_t zoom_y) lv_chart_t * chart = (lv_chart_t *)obj; if(chart->zoom_y == zoom_y) return; + if(LV_ZOOM_NONE > zoom_y) zoom_y = LV_ZOOM_NONE; chart->zoom_y = zoom_y; lv_obj_refresh_self_size(obj); @@ -345,26 +347,38 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_cha LV_ASSERT_OBJ(obj, MY_CLASS); lv_chart_t * chart = (lv_chart_t *)obj; + + /* Allocate space for a new series and add it to the chart series linked list */ lv_chart_series_t * ser = _lv_ll_ins_head(&chart->series_ll); LV_ASSERT_MALLOC(ser); if(ser == NULL) return NULL; - lv_coord_t def = LV_CHART_POINT_NONE; - - ser->color = color; + /* Allocate memory for point_cnt points, handle failure below */ ser->y_points = lv_malloc(sizeof(lv_coord_t) * chart->point_cnt); LV_ASSERT_MALLOC(ser->y_points); if(chart->type == LV_CHART_TYPE_SCATTER) { ser->x_points = lv_malloc(sizeof(lv_coord_t) * chart->point_cnt); LV_ASSERT_MALLOC(ser->x_points); + if(NULL == ser->x_points) { + lv_free(ser->y_points); + _lv_ll_remove(&chart->series_ll, ser); + lv_free(ser); + return NULL; + } } + else { + ser->x_points = NULL; + } + if(ser->y_points == NULL) { _lv_ll_remove(&chart->series_ll, ser); lv_free(ser); return NULL; } + /* Set series properties on successful allocation */ + ser->color = color; ser->start_point = 0; ser->y_ext_buf_assigned = false; ser->hidden = 0; @@ -372,6 +386,7 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_cha ser->y_axis_sec = axis & LV_CHART_AXIS_SECONDARY_Y ? 1 : 0; uint16_t i; + const lv_coord_t def = LV_CHART_POINT_NONE; lv_coord_t * p_tmp = ser->y_points; for(i = 0; i < chart->point_cnt; i++) { *p_tmp = def; diff --git a/src/widgets/chart/lv_chart.h b/src/widgets/chart/lv_chart.h index 1506460ef..4642c7b00 100644 --- a/src/widgets/chart/lv_chart.h +++ b/src/widgets/chart/lv_chart.h @@ -271,7 +271,7 @@ void lv_chart_refresh(lv_obj_t * obj); * @param obj pointer to a chart object * @param color color of the data series * @param axis the y axis to which the series should be attached (::LV_CHART_AXIS_PRIMARY_Y or ::LV_CHART_AXIS_SECONDARY_Y) - * @return pointer to the allocated data series + * @return pointer to the allocated data series or NULL on failure */ lv_chart_series_t * lv_chart_add_series(lv_obj_t * obj, lv_color_t color, lv_chart_axis_t axis); diff --git a/tests/src/test_cases/test_chart.c b/tests/src/test_cases/test_chart.c new file mode 100644 index 000000000..ac38a5f05 --- /dev/null +++ b/tests/src/test_cases/test_chart.c @@ -0,0 +1,119 @@ +#if LV_BUILD_TEST +#include "../lvgl.h" + +#include "unity/unity.h" + +static lv_obj_t * active_screen = NULL; +static lv_obj_t * chart = NULL; + +static lv_color_t red_color; + +void setUp(void) +{ + active_screen = lv_scr_act(); + chart = lv_chart_create(active_screen); + + red_color = lv_palette_main(LV_PALETTE_RED); +} + +void tearDown(void) +{ + /* Is there a way to destroy a chart without having to call remove_series for each of it series? */ +} + +/* NOTE: Default chart type is LV_CHART_TYPE_LINE */ +void test_chart_add_series(void) +{ + lv_chart_series_t * red_series; + + red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y); + + TEST_ASSERT_NOT_NULL_MESSAGE(red_series, "Red series not added to chart"); + TEST_ASSERT_NULL_MESSAGE(red_series->x_points, "X points in non scatter chart should not point to anything"); + + lv_chart_remove_series(chart, red_series); +} + +void test_chart_set_point_count_increments(void) +{ + lv_chart_series_t * red_series; + red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y); + + uint16_t points_in_serie = lv_chart_get_point_count(chart); + uint16_t new_point_count = points_in_serie * 2; + lv_chart_set_point_count(chart, new_point_count); + + TEST_ASSERT_EQUAL_MESSAGE(new_point_count, lv_chart_get_point_count(chart), + "Actual points in chart are less than expected"); + lv_chart_remove_series(chart, red_series); +} + +void test_chart_set_point_count_decrements(void) +{ + lv_chart_series_t * red_series; + red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y); + uint16_t points_in_serie = lv_chart_get_point_count(chart); + uint16_t new_point_count = points_in_serie / 2; + + lv_chart_set_point_count(chart, new_point_count); + + TEST_ASSERT_EQUAL_MESSAGE(new_point_count, lv_chart_get_point_count(chart), + "Actual points in chart are more than expected"); + lv_chart_remove_series(chart, red_series); +} + +void test_chart_set_point_count_as_same(void) +{ + lv_chart_series_t * red_series; + red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y); + uint16_t points_in_serie = lv_chart_get_point_count(chart); + uint16_t new_point_count = points_in_serie; + + lv_chart_set_point_count(chart, new_point_count); + + TEST_ASSERT_EQUAL_MESSAGE(new_point_count, lv_chart_get_point_count(chart), + "Actual points is not equal to original point count"); + lv_chart_remove_series(chart, red_series); +} + +void test_chart_set_new_point_count_as_zero(void) +{ + lv_chart_series_t * red_series; + red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y); + + lv_chart_set_point_count(chart, 0u); + + TEST_ASSERT_EQUAL_MESSAGE(1u, lv_chart_get_point_count(chart), "Actual points in chart are more than 1"); + lv_chart_remove_series(chart, red_series); +} + +void test_chart_point_is_added_at_the_end_of_a_serie(void) +{ + lv_chart_series_t * red_series; + red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y); + + TEST_ASSERT_NOT_NULL_MESSAGE(red_series, "Red series not added to chart"); + TEST_ASSERT_NULL_MESSAGE(red_series->x_points, "X points in non scatter chart should not point to anything"); + + lv_chart_remove_series(chart, red_series); +} + +void test_chart_one_point_when_setting_point_count_to_zero(void) +{ + lv_chart_set_point_count(chart, 0u); + TEST_ASSERT_EQUAL(1u, lv_chart_get_point_count(chart)); +} + +void test_chart_set_zoom_y_to_none_when_factor_is_less_than_256(void) +{ + lv_chart_set_zoom_y(chart, 128); + TEST_ASSERT_EQUAL(LV_ZOOM_NONE, lv_chart_get_zoom_y(chart)); +} + +void test_chart_set_zoom_x_to_none_when_factor_is_less_than_256(void) +{ + lv_chart_set_zoom_x(chart, 128); + TEST_ASSERT_EQUAL(LV_ZOOM_NONE, lv_chart_get_zoom_x(chart)); +} + +#endif