1 #if LV_BUILD_TEST
2 #include "../lvgl.h"
3 #include "../../lvgl_private.h"
4
5 #include "unity/unity.h"
6
7 static lv_obj_t * active_screen = NULL;
8 static lv_obj_t * chart = NULL;
9
10 static lv_color_t red_color;
11
setUp(void)12 void setUp(void)
13 {
14 active_screen = lv_screen_active();
15 chart = lv_chart_create(active_screen);
16
17 red_color = lv_palette_main(LV_PALETTE_RED);
18 }
19
tearDown(void)20 void tearDown(void)
21 {
22 /* Is there a way to destroy a chart without having to call remove_series for each of it series? */
23 lv_obj_clean(active_screen);
24 }
25
26 /* NOTE: Default chart type is LV_CHART_TYPE_LINE */
test_chart_add_series(void)27 void test_chart_add_series(void)
28 {
29 lv_chart_series_t * red_series;
30
31 red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y);
32
33 TEST_ASSERT_NOT_NULL_MESSAGE(red_series, "Red series not added to chart");
34 TEST_ASSERT_NULL_MESSAGE(red_series->x_points, "X points in non scatter chart should not point to anything");
35
36 lv_chart_remove_series(chart, red_series);
37 }
38
test_chart_set_point_count_increments(void)39 void test_chart_set_point_count_increments(void)
40 {
41 lv_chart_series_t * red_series;
42 red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y);
43
44 uint16_t points_in_series = lv_chart_get_point_count(chart);
45 uint16_t new_point_count = points_in_series * 2;
46 lv_chart_set_point_count(chart, new_point_count);
47
48 TEST_ASSERT_EQUAL_MESSAGE(new_point_count, lv_chart_get_point_count(chart),
49 "Actual points in chart are less than expected");
50 lv_chart_remove_series(chart, red_series);
51 }
52
test_chart_set_point_count_decrements(void)53 void test_chart_set_point_count_decrements(void)
54 {
55 lv_chart_series_t * red_series;
56 red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y);
57 uint16_t points_in_series = lv_chart_get_point_count(chart);
58 uint16_t new_point_count = points_in_series / 2;
59
60 lv_chart_set_point_count(chart, new_point_count);
61
62 TEST_ASSERT_EQUAL_MESSAGE(new_point_count, lv_chart_get_point_count(chart),
63 "Actual points in chart are more than expected");
64 lv_chart_remove_series(chart, red_series);
65 }
66
test_chart_set_point_count_as_same(void)67 void test_chart_set_point_count_as_same(void)
68 {
69 lv_chart_series_t * red_series;
70 red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y);
71 uint16_t points_in_series = lv_chart_get_point_count(chart);
72 uint16_t new_point_count = points_in_series;
73
74 lv_chart_set_point_count(chart, new_point_count);
75
76 TEST_ASSERT_EQUAL_MESSAGE(new_point_count, lv_chart_get_point_count(chart),
77 "Actual points is not equal to original point count");
78 lv_chart_remove_series(chart, red_series);
79 }
80
test_chart_set_new_point_count_as_zero(void)81 void test_chart_set_new_point_count_as_zero(void)
82 {
83 lv_chart_series_t * red_series;
84 red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y);
85
86 lv_chart_set_point_count(chart, 0u);
87
88 TEST_ASSERT_EQUAL_MESSAGE(1u, lv_chart_get_point_count(chart), "Actual points in chart are more than 1");
89 lv_chart_remove_series(chart, red_series);
90 }
91
test_chart_point_is_added_at_the_end_of_a_series(void)92 void test_chart_point_is_added_at_the_end_of_a_series(void)
93 {
94 lv_chart_series_t * red_series;
95 red_series = lv_chart_add_series(chart, red_color, LV_CHART_AXIS_SECONDARY_Y);
96
97 TEST_ASSERT_NOT_NULL_MESSAGE(red_series, "Red series not added to chart");
98 TEST_ASSERT_NULL_MESSAGE(red_series->x_points, "X points in non scatter chart should not point to anything");
99
100 lv_chart_remove_series(chart, red_series);
101 }
102
test_chart_one_point_when_setting_point_count_to_zero(void)103 void test_chart_one_point_when_setting_point_count_to_zero(void)
104 {
105 lv_chart_set_point_count(chart, 0u);
106 TEST_ASSERT_EQUAL(1u, lv_chart_get_point_count(chart));
107 }
108
chart_event_cb(lv_event_t * e)109 static void chart_event_cb(lv_event_t * e)
110 {
111 lv_event_code_t code = lv_event_get_code(e);
112 lv_obj_t * obj = lv_event_get_target(e);
113
114 if(code == LV_EVENT_DRAW_TASK_ADDED) {
115 lv_draw_task_t * draw_task = lv_event_get_param(e);
116 lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;
117
118 lv_chart_type_t chart_type = lv_chart_get_type(obj);
119 if(chart_type == LV_CHART_TYPE_LINE && base_dsc->part != LV_PART_INDICATOR) return;
120 if(chart_type == LV_CHART_TYPE_BAR && base_dsc->part != LV_PART_ITEMS) return;
121
122 const lv_chart_series_t * ser = NULL;
123 for(uint32_t i = 0; i < base_dsc->id1 + 1; i++) {
124 ser = lv_chart_get_series_next(obj, ser);
125 }
126
127 char buf[8];
128 lv_snprintf(buf, sizeof(buf), "%"LV_PRIu32, ser->y_points[base_dsc->id2]);
129
130 lv_point_t text_size;
131 lv_text_get_size(&text_size, buf, LV_FONT_DEFAULT, 0, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE);
132
133 lv_area_t txt_area;
134 txt_area.x1 = draw_task->area.x1 + lv_area_get_width(&draw_task->area) / 2 - text_size.x / 2;
135 txt_area.x2 = txt_area.x1 + text_size.x;
136 txt_area.y2 = draw_task->area.y1 - LV_DPX(15);
137 txt_area.y1 = txt_area.y2 - text_size.y;
138
139 lv_area_t bg_area;
140 bg_area.x1 = txt_area.x1 - LV_DPX(8);
141 bg_area.x2 = txt_area.x2 + LV_DPX(8);
142 bg_area.y1 = txt_area.y1 - LV_DPX(8);
143 bg_area.y2 = txt_area.y2 + LV_DPX(8);
144
145 lv_draw_rect_dsc_t rect_dsc;
146 lv_draw_rect_dsc_init(&rect_dsc);
147 rect_dsc.bg_color = ser->color;
148 rect_dsc.radius = LV_DPX(5);
149 lv_draw_rect(base_dsc->layer, &rect_dsc, &bg_area);
150
151 lv_draw_label_dsc_t label_dsc;
152 lv_draw_label_dsc_init(&label_dsc);
153 label_dsc.color = lv_color_white();
154 label_dsc.font = LV_FONT_DEFAULT;
155 label_dsc.text = buf;
156 label_dsc.text_local = true;
157 lv_draw_label(base_dsc->layer, &label_dsc, &txt_area);
158 }
159 }
160
test_draw_task_hooking(void)161 void test_draw_task_hooking(void)
162 {
163 lv_obj_t * chart_wrapper = lv_obj_create(lv_screen_active());
164 lv_obj_set_size(chart_wrapper, 600, 300);
165 lv_obj_center(chart_wrapper);
166
167 lv_obj_set_parent(chart, chart_wrapper);
168 lv_obj_set_size(chart, lv_pct(200), lv_pct(100));
169 lv_obj_add_flag(chart, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);
170 lv_chart_set_div_line_count(chart, 0, 21);
171 lv_chart_set_point_count(chart, 21);
172 lv_obj_add_event_cb(chart, chart_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);
173
174 lv_chart_series_t * chart_set1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_YELLOW), 0);
175 lv_chart_series_t * chart_set2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), 0);
176 lv_chart_series_t * chart_set3 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), 0);
177 lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 700);
178
179 int32_t points[21] = {0, 31, 59, 81, 95, 100, 95, 81, 59, 31, 0, -31, -59, -81, -95, -100, -95, -81, -59, -31, 0};
180
181 for(uint32_t i = 0; i < 21; i++) {
182 lv_chart_set_next_value(chart, chart_set1, points[i] + 100);
183 lv_chart_set_next_value(chart, chart_set2, points[i] + 300);
184 lv_chart_set_next_value(chart, chart_set3, points[i] + 500);
185 }
186
187 lv_obj_scroll_to_x(chart_wrapper, 300, LV_ANIM_OFF);
188
189 lv_chart_set_type(chart, LV_CHART_TYPE_LINE);
190 TEST_ASSERT_EQUAL_SCREENSHOT("widgets/chart_line_draw_hook.png");
191
192 lv_chart_set_type(chart, LV_CHART_TYPE_BAR);
193 TEST_ASSERT_EQUAL_SCREENSHOT("widgets/chart_bar_draw_hook.png");
194 }
195
196 #endif
197