1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

Merge pull request #951 from ali-rostami/master

add LV_CHART_MODE_CIRCULAR feature to chart objects.
This commit is contained in:
Gabor Kiss-Vamosi 2019-05-10 14:58:20 +02:00 committed by GitHub
commit 77d43069e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 175 additions and 41 deletions

View File

@ -487,6 +487,8 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
}
ext->pressed_date.year = 0;
ext->pressed_date.month = 0;
ext->pressed_date.day = 0;
} else if(calculate_touched_day(calendar, &p)) {
if(ext->btn_pressing != 0) lv_obj_invalidate(calendar);
ext->btn_pressing = 0;
@ -494,10 +496,11 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
if(ext->btn_pressing != 0) lv_obj_invalidate(calendar);
ext->btn_pressing = 0;
ext->pressed_date.year = 0;
ext->pressed_date.month = 0;
ext->pressed_date.day = 0;
}
} else if(sign == LV_SIGNAL_PRESS_LOST) {
lv_calendar_ext_t * ext = lv_obj_get_ext_attr(calendar);
ext->pressed_date.year = 0;
ext->btn_pressing = 0;
lv_obj_invalidate(calendar);
@ -522,7 +525,6 @@ static lv_res_t lv_calendar_signal(lv_obj_t * calendar, lv_signal_t sign, void *
if(res != LV_RES_OK) return res;
}
ext->pressed_date.year = 0;
ext->btn_pressing = 0;
lv_obj_invalidate(calendar);
} else if(sign == LV_SIGNAL_CONTROL) {

View File

@ -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"
@ -42,6 +43,9 @@ 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_draw_axes(lv_obj_t * chart, const lv_area_t * mask);
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
@ -79,6 +83,7 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
if(ext == NULL) return NULL;
lv_ll_init(&ext->series_ll, sizeof(lv_chart_series_t));
ext->series.num = 0;
ext->ymin = LV_CHART_YMIN_DEF;
ext->ymax = LV_CHART_YMAX_DEF;
@ -86,6 +91,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;
@ -155,7 +161,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) {
@ -393,12 +398,35 @@ void lv_chart_set_points(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t y
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);
ser->points[ser->start_point] =
y; /*This was the place of the former left most value, after shifting it is the rightmost*/
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_UPDATE_MODE_CIRCULAR) {
ser->points[ser->start_point] = y;
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);
if(ext->type & LV_CHART_TYPE_AREA) lv_chart_inv_lines(chart, ser->start_point);
ser->start_point = (ser->start_point + 1) % ext->point_cnt;/*update the x for next incoming y*/
}
}
/**
* Set update mode of the chart object.
* @param chart pointer to a chart object
* @param update mode
*/
void lv_chart_set_update_mode(lv_obj_t * chart, lv_chart_update_mode_t update_mode)
{
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->update_mode == update_mode) return;
ext->update_mode = update_mode;
lv_obj_invalidate(chart);
}
/**
@ -705,21 +733,24 @@ static void lv_chart_draw_lines(lv_obj_t * chart, const lv_area_t * mask)
{
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;
for(i = 1; i < ext->point_cnt; i++) {
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;
y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin) * h;
y_tmp = y_tmp / (ext->ymax - ext->ymin);
@ -762,8 +793,10 @@ static void lv_chart_draw_points(lv_obj_t * chart, const lv_area_t * mask)
style_point.body.radius = ext->series.width;
/*Go through all data lines*/
LV_LL_READ_BACK(ext->series_ll, ser)
{
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);
@ -771,9 +804,11 @@ 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;
cir_a.y2 = cir_a.y1 + style_point.body.radius;
cir_a.y1 -= style_point.body.radius;
@ -822,15 +857,17 @@ static void lv_chart_draw_cols(lv_obj_t * chart, const lv_area_t * mask)
x_act += chart->coords.x1 + x_ofs;
/*Draw the current point of all data line*/
LV_LL_READ_BACK(ext->series_ll, ser)
{
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;
@ -861,6 +898,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;
@ -873,8 +911,8 @@ static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mas
style.line.width = ext->series.width;
/*Go through all data lines*/
LV_LL_READ_BACK(ext->series_ll, ser)
{
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;
@ -884,9 +922,11 @@ static void lv_chart_draw_vertical_lines(lv_obj_t * chart, const lv_area_t * mas
p2.y = h - y_tmp + y_ofs;
p1.y = p2.y;
for(i = 0; i < ext->point_cnt; i++) {
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;
@ -894,11 +934,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;
}
@ -929,8 +969,8 @@ static void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask)
lv_style_copy(&style, &lv_style_plain);
/*Go through all data lines*/
LV_LL_READ_BACK(ext->series_ll, ser)
{
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;
@ -945,8 +985,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);
@ -1199,4 +1239,80 @@ static void lv_chart_draw_axes(lv_obj_t * chart, const lv_area_t * mask)
lv_chart_draw_y_ticks(chart, mask);
lv_chart_draw_x_ticks(chart, 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, 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;
if(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(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);
}
}
}
/**
* invalid area of the new point data lines on a chart
* @param chart pointer to chart object
* @param mask mask, inherited from the design function
*/
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_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;
lv_inv_area(lv_obj_get_disp(chart), &cir_a);
}
/**
* invalid area of the new column data lines on a chart
* @param chart pointer to chart object
* @param mask mask, inherited from the design function
*/
static void lv_chart_inv_cols(lv_obj_t * chart, uint16_t i)
{
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
lv_area_t col_a;
lv_coord_t w = lv_obj_get_width(chart);
lv_coord_t col_w = w / ((ext->series.num + 1) * ext->point_cnt); /* Suppose + 1 series as separator*/
lv_coord_t x_ofs = col_w / 2; /*Shift with a half col.*/
lv_coord_t x_act;
x_act = (int32_t)((int32_t) w * i) / ext->point_cnt;
x_act += chart->coords.x1 + x_ofs;
lv_obj_get_coords(chart, &col_a);
col_a.x1 = x_act;
col_a.x2 = col_a.x1 + col_w;
lv_inv_area(lv_obj_get_disp(chart), &col_a);
}
#endif

View File

@ -44,6 +44,14 @@ enum {
};
typedef uint8_t lv_chart_type_t;
/*Chart update mode*/
enum
{
LV_CHART_UPDATE_MODE_SHIFT,
LV_CHART_UPDATE_MODE_CIRCULAR,
};
typedef uint8_t lv_chart_update_mode_t;
typedef struct
{
lv_coord_t * points;
@ -81,6 +89,7 @@ typedef struct
lv_chart_axis_cfg_t y_axis;
lv_chart_axis_cfg_t x_axis;
uint16_t margin;
uint8_t update_mode: 1;
struct
{
lv_coord_t width; /*Line width or point radius*/
@ -201,6 +210,13 @@ 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);
/**
* Set update mode of the chart object.
* @param chart pointer to a chart object
* @param update mode
*/
void lv_chart_set_update_mode(lv_obj_t * chart, lv_chart_update_mode_t update_mode);
/**
* Set the style of a chart
* @param chart pointer to a chart object