extern void custom_chart_draw_event_cb(lv_event_t * e);
extern void custom_chart_hide_cb(lv_event_t * e);
custom_chart_draw_event_cb(e);
custom_chart_hide_cb(e);
void custom_chart_draw_event_cb(lv_event_t * e)
{
lv_obj_t * obj = lv_event_get_target(e);
lv_chart_t * chart = (lv_chart_t *)obj;
lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
if(dsc->part != LV_PART_ITEMS || !dsc->p1 || !dsc->p2) return;
lv_opa_t bg_opa = 40;
lv_chart_series_t * ser = (lv_chart_series_t *)dsc->sub_part_ptr;
if(ser == NULL) return;
uint16_t curr_idx = dsc->id;
uint16_t next_idx = dsc->id + 1;
if (curr_idx < 0 || next_idx > chart->point_cnt - 1) return;
lv_coord_t curr_y = ser->y_points[curr_idx];
lv_coord_t next_y = ser->y_points[next_idx];
if (curr_y <= 0 || next_y <= 0) {
return;
}
lv_color_t grad_color = lv_obj_get_style_bg_grad_color(obj, LV_PART_ITEMS | LV_STATE_DEFAULT);
lv_grad_dir_t grad_dir = lv_obj_get_style_bg_grad_dir(obj, LV_PART_ITEMS | LV_STATE_DEFAULT);
if (grad_dir == LV_GRAD_DIR_NONE) {
lv_draw_mask_line_param_t line_mask_param;
lv_draw_mask_line_points_init(&line_mask_param, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y, LV_DRAW_MASK_LINE_SIDE_BOTTOM);
int16_t line_mask_id = lv_draw_mask_add(&line_mask_param, NULL);
lv_draw_rect_dsc_t draw_rect_dsc;
lv_draw_rect_dsc_init(&draw_rect_dsc);
draw_rect_dsc.bg_color = dsc->line_dsc->color;
draw_rect_dsc.bg_opa = bg_opa;
lv_area_t a;
a.x1 = dsc->p1->x;
a.x2 = dsc->p2->x - 1;
a.y1 = LV_MIN(dsc->p1->y, dsc->p2->y);
a.y2 = obj->coords.y2;
lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
lv_draw_mask_free_param(&line_mask_param);
lv_draw_mask_remove_id(line_mask_id);
} else if (grad_dir == LV_GRAD_DIR_HOR) {
lv_coord_t pad_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj, LV_PART_MAIN);
lv_coord_t pad_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj, LV_PART_MAIN);
lv_coord_t x1_ofs = obj->coords.x1 + pad_left - lv_obj_get_scroll_left(obj);
lv_coord_t x2_ofs = obj->coords.x2 - pad_right - lv_obj_get_scroll_right(obj);
lv_draw_mask_line_param_t line_mask_param1;
lv_draw_mask_line_points_init(&line_mask_param1, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y, LV_DRAW_MASK_LINE_SIDE_BOTTOM);
int16_t line_mask_id1 = lv_draw_mask_add(&line_mask_param1, NULL);
lv_draw_mask_line_param_t line_mask_param2;
lv_draw_mask_line_points_init(&line_mask_param2, dsc->p2->x, LV_MIN(dsc->p1->y, dsc->p2->y), dsc->p2->x, obj->coords.y2, LV_DRAW_MASK_LINE_SIDE_LEFT);
int16_t line_mask_id2 = lv_draw_mask_add(&line_mask_param2, NULL);
lv_draw_mask_line_param_t line_mask_param3;
lv_draw_mask_line_points_init(&line_mask_param3, dsc->p1->x, LV_MIN(dsc->p1->y, dsc->p2->y), dsc->p1->x, obj->coords.y2, LV_DRAW_MASK_LINE_SIDE_RIGHT);
int16_t line_mask_id3 = lv_draw_mask_add(&line_mask_param3, NULL);
lv_draw_rect_dsc_t draw_rect_dsc;
lv_draw_rect_dsc_init(&draw_rect_dsc);
draw_rect_dsc.bg_opa = bg_opa;
draw_rect_dsc.bg_grad.stops[0].color = dsc->line_dsc->color;
draw_rect_dsc.bg_grad.stops[1].color = grad_color;
draw_rect_dsc.bg_grad.stops[0].frac = 0;
draw_rect_dsc.bg_grad.stops[1].frac = 255;
draw_rect_dsc.bg_grad.dir = LV_GRAD_DIR_HOR;
lv_area_t a;
a.x1 = x1_ofs;
a.x2 = x2_ofs + 1;
a.y1 = LV_MIN(dsc->p1->y, dsc->p2->y);
a.y2 = obj->coords.y2;
lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
lv_draw_mask_free_param(&line_mask_param1);
lv_draw_mask_free_param(&line_mask_param2);
lv_draw_mask_free_param(&line_mask_param3);
lv_draw_mask_remove_id(line_mask_id1);
lv_draw_mask_remove_id(line_mask_id2);
lv_draw_mask_remove_id(line_mask_id3);
} else if (grad_dir == LV_GRAD_DIR_VER) {
lv_coord_t pad_top = lv_obj_get_style_pad_top(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj, LV_PART_MAIN);
lv_coord_t pad_bottom = lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN) + lv_obj_get_style_border_width(obj, LV_PART_MAIN);
lv_coord_t y1_ofs = obj->coords.y1 + pad_top - lv_obj_get_scroll_top(obj);
lv_coord_t y2_ofs = obj->coords.y2 - pad_bottom - lv_obj_get_scroll_bottom(obj);
lv_chart_series_t * ser = (lv_chart_series_t *)dsc->sub_part_ptr;
lv_chart_t * chart = (lv_chart_t *)obj;
uint16_t point_cnt = chart->point_cnt;
lv_coord_t max_point = 0;
lv_coord_t max_point_y = 0;
for (uint16_t i = 0; i < point_cnt; i++) {
if (ser->y_points[i] == LV_CHART_POINT_NONE) continue;
max_point = LV_MAX(max_point, ser->y_points[i]);
}
if (ser->y_axis_sec == 0) {
max_point_y = y2_ofs - (max_point - chart->ymin[0]) * (y2_ofs - y1_ofs) / (chart->ymax[0] - chart->ymin[0]);
} else {
max_point_y = y2_ofs - (max_point - chart->ymin[1]) * (y2_ofs - y1_ofs) / (chart->ymax[1] - chart->ymin[1]);
}
lv_draw_mask_line_param_t line_mask_param;
lv_draw_mask_line_points_init(&line_mask_param, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y, LV_DRAW_MASK_LINE_SIDE_BOTTOM);
int16_t line_mask_id = lv_draw_mask_add(&line_mask_param, NULL);
lv_draw_rect_dsc_t draw_rect_dsc;
lv_draw_rect_dsc_init(&draw_rect_dsc);
draw_rect_dsc.bg_opa = bg_opa;
draw_rect_dsc.bg_grad.stops[0].color = dsc->line_dsc->color;
draw_rect_dsc.bg_grad.stops[1].color = grad_color;
draw_rect_dsc.bg_grad.stops[0].frac = 0;
draw_rect_dsc.bg_grad.stops[1].frac = 255;
draw_rect_dsc.bg_grad.dir = LV_GRAD_DIR_VER;
lv_area_t a;
a.x1 = dsc->p1->x;
a.x2 = dsc->p2->x - 1;
a.y1 = max_point_y;
a.y2 = obj->coords.y2;
lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
lv_draw_mask_free_param(&line_mask_param);
lv_draw_mask_remove_id(line_mask_id);
}
}
void custom_chart_hide_cb(lv_event_t * e)
{
lv_obj_t * obj = lv_event_get_target(e);
lv_chart_t * chart = (lv_chart_t *)obj;
lv_obj_draw_part_dsc_t * dsc = (lv_obj_draw_part_dsc_t *)lv_event_get_draw_part_dsc(e);
lv_chart_series_t * ser = (lv_chart_series_t *)dsc->sub_part_ptr;
if(ser == NULL) return;
if(dsc->part == LV_PART_ITEMS) {
if(dsc->p1 && dsc->p2 && dsc->line_dsc) {
uint16_t curr_idx = dsc->id;
uint16_t next_idx = dsc->id + 1;
if (curr_idx >= 0 && next_idx < chart->point_cnt) {
lv_coord_t curr_y = ser->y_points[curr_idx];
lv_coord_t next_y = ser->y_points[next_idx];
if (curr_y <= 0 || next_y <= 0) {
dsc->line_dsc->opa = LV_OPA_TRANSP;
} else {
dsc->line_dsc->opa = LV_OPA_COVER;
}
}
if (dsc->rect_dsc) {
dsc->rect_dsc->bg_color = dsc->line_dsc->color;
dsc->rect_dsc->border_color = lv_color_make(0x00, 0x00, 0x00);
}
} else if(!dsc->p1 && !dsc->p2) {
if (dsc->rect_dsc) {
dsc->rect_dsc->border_color = dsc->rect_dsc->bg_color;
dsc->rect_dsc->bg_color = lv_color_make(0x00, 0x00, 0x00);
}
}
}
}