#include "../../lv_examples.h" #if LV_USE_CHART && LV_DRAW_SW_COMPLEX && LV_BUILD_EXAMPLES static void hook_division_lines(lv_event_t * e); static void add_faded_area(lv_event_t * e); static void draw_event_cb(lv_event_t * e); /** * Add a faded area effect to the line chart and make some division lines ticker */ void lv_example_chart_5(void) { /*Create a chart*/ lv_obj_t * chart = lv_chart_create(lv_screen_active()); lv_chart_set_type(chart, LV_CHART_TYPE_LINE); /*Show lines and points too*/ lv_obj_set_size(chart, 200, 150); lv_obj_set_style_pad_all(chart, 0, 0); lv_obj_set_style_radius(chart, 0, 0); lv_obj_center(chart); lv_chart_set_div_line_count(chart, 5, 7); lv_obj_add_event(chart, draw_event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL); lv_obj_add_flag(chart, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y); uint32_t i; for(i = 0; i < 10; i++) { lv_chart_set_next_value(chart, ser, lv_rand(10, 80)); } } static void draw_event_cb(lv_event_t * e) { lv_draw_task_t * draw_task = lv_event_get_draw_task(e); lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc; if(base_dsc->part == LV_PART_ITEMS && draw_task->type == LV_DRAW_TASK_TYPE_LINE) { add_faded_area(e); } /*Hook the division lines too*/ if(base_dsc->part == LV_PART_MAIN && draw_task->type == LV_DRAW_TASK_TYPE_LINE) { hook_division_lines(e); } } static void add_faded_area(lv_event_t * e) { lv_obj_t * obj = lv_event_get_target(e); lv_draw_task_t * draw_task = lv_event_get_draw_task(e); lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc; const lv_chart_series_t * ser = lv_chart_get_series_next(obj, NULL); /*Draw a triangle below the line witch some opacity gradient*/ lv_draw_line_dsc_t * draw_line_dsc = draw_task->draw_dsc; lv_draw_triangle_dsc_t tri_dsc; lv_draw_triangle_dsc_init(&tri_dsc); tri_dsc.p[0].x = draw_line_dsc->p1_x; tri_dsc.p[0].y = draw_line_dsc->p1_y; tri_dsc.p[1].x = draw_line_dsc->p2_x; tri_dsc.p[1].y = draw_line_dsc->p2_y; tri_dsc.p[2].x = draw_line_dsc->p1_y < draw_line_dsc->p2_y ? draw_line_dsc->p1_x : draw_line_dsc->p2_x; tri_dsc.p[2].y = LV_MAX(draw_line_dsc->p1_y, draw_line_dsc->p2_y); tri_dsc.bg_grad.dir = LV_GRAD_DIR_VER; lv_coord_t full_h = lv_obj_get_height(obj); lv_coord_t fract_uppter = (int32_t)(LV_MIN(draw_line_dsc->p1_y, draw_line_dsc->p2_y) - obj->coords.y1) * 255 / full_h; lv_coord_t fract_lower = (int32_t)(LV_MAX(draw_line_dsc->p1_y, draw_line_dsc->p2_y) - obj->coords.y1) * 255 / full_h; tri_dsc.bg_grad.stops[0].color = ser->color; tri_dsc.bg_grad.stops[0].opa = 255 - fract_uppter; tri_dsc.bg_grad.stops[0].frac = 0; tri_dsc.bg_grad.stops[1].color = ser->color; tri_dsc.bg_grad.stops[1].opa = 255 - fract_lower; tri_dsc.bg_grad.stops[1].frac = 255; lv_draw_triangle(base_dsc->layer, &tri_dsc); /*Draw rectangle below the triangle*/ lv_draw_rect_dsc_t rect_dsc; lv_draw_rect_dsc_init(&rect_dsc); rect_dsc.bg_grad.dir = LV_GRAD_DIR_VER; rect_dsc.bg_grad.stops[0].color = ser->color; rect_dsc.bg_grad.stops[0].frac = 0; rect_dsc.bg_grad.stops[0].opa = 255 - fract_lower; rect_dsc.bg_grad.stops[1].color = ser->color; rect_dsc.bg_grad.stops[1].frac = 255; rect_dsc.bg_grad.stops[1].opa = 0; lv_area_t rect_area; rect_area.x1 = (int32_t)draw_line_dsc->p1_x; rect_area.x2 = (int32_t)draw_line_dsc->p2_x - 1; rect_area.y1 = (int32_t)LV_MAX(draw_line_dsc->p1_y, draw_line_dsc->p2_y) - 1; rect_area.y2 = (int32_t)obj->coords.y2; lv_draw_rect(base_dsc->layer, &rect_dsc, &rect_area); } static void hook_division_lines(lv_event_t * e) { lv_draw_task_t * draw_task = lv_event_get_draw_task(e); lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc; lv_draw_line_dsc_t * line_dsc = draw_task->draw_dsc; /*Vertical line*/ if(line_dsc->p1_x == line_dsc->p2_x) { line_dsc->color = lv_palette_lighten(LV_PALETTE_GREY, 1); if(base_dsc->id1 == 3) { line_dsc->width = 2; line_dsc->dash_gap = 0; line_dsc->dash_width = 0; } else { line_dsc->width = 1; line_dsc->dash_gap = 6; line_dsc->dash_width = 6; } } /*Horizontal line*/ else { if(base_dsc->id1 == 2) { line_dsc->width = 2; line_dsc->dash_gap = 0; line_dsc->dash_width = 0; } else { line_dsc->width = 2; line_dsc->dash_gap = 6; line_dsc->dash_width = 6; } if(base_dsc->id1 == 1 || base_dsc->id1 == 3) { line_dsc->color = lv_palette_main(LV_PALETTE_GREEN); } else { line_dsc->color = lv_palette_lighten(LV_PALETTE_GREY, 1); } } } #endif