1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

chart: add lv_chart_set_series_axis and lv_chart_set_y_range

This commit is contained in:
Gabor Kiss-Vamosi 2020-06-26 20:31:20 +02:00
parent 91f64c8662
commit e678a2c599
5 changed files with 116 additions and 26 deletions

View File

@ -11,6 +11,8 @@ Available in the `dev` branch
- Add `lv_chart_get_x_start_point()` function - Get the current index of the x-axis start point in the data array
- Add `lv_chart_get_point_id()` function - Get an individual point value in the chart series directly based on index
- Add `ext_buf_assigned` bit field to `lv_chart_series_t` structure - it's true if external buffer is assigned to series
- Add `lv_chart_set_series_axis()` to assign series to primary or secondary axis
- Add `lv_chart_set_y_range()` to allow setting range of secondary y axis (based on `lv_chart_set_range` but extended with an axis parameter)
- Allow setting different font for the selected text in `lv_roller`
- Add `theme->apply_cb` to replace `theme->apply_xcb` to make it compatible with the MicroPython binding
- Add `lv_theme_set_base()` to allow easy extension of built-in (or any) themes.

View File

@ -176,6 +176,16 @@ static inline lv_obj_t * lv_page_get_scrl(lv_obj_t * page)
}
#endif
#endif /*LV_USE_API_EXTENSION_V6*/
/*---------------------
* V7.0 COMPATIBILITY
*--------------------*/
#if LV_USE_API_EXTENSION_V7
#if LV_USE_WIN
static inline lv_obj_t * lv_win_add_btn(lv_obj_t * win, const void * img_src)
@ -185,8 +195,14 @@ static inline lv_obj_t * lv_win_add_btn(lv_obj_t * win, const void * img_src)
#endif
#endif /*LV_USE_API_EXTENSION_V6*/
#if LV_USE_CHART
static inline void lv_chart_set_range(lv_obj_t * chart, lv_coord_t ymin, lv_coord_t ymax)
{
lv_chart_set_y_range(chart, LV_CHART_AXIS_PRIMARY_Y, ymin, ymax);
}
#endif
#endif /*LV_USE_API_EXTENSION_V6*/
/**********************
* MACROS
**********************/

View File

@ -289,6 +289,9 @@
#ifndef LV_USE_API_EXTENSION_V6
#define LV_USE_API_EXTENSION_V6 1
#endif
#ifndef LV_USE_API_EXTENSION_V7
#define LV_USE_API_EXTENSION_V7 1
#endif
/*========================
* Image decoder and cache

View File

@ -27,8 +27,6 @@
#define LV_CHART_PNUM_DEF 10
#define LV_CHART_AXIS_MAJOR_TICK_LEN_COE 1 / 15
#define LV_CHART_AXIS_MINOR_TICK_LEN_COE 2 / 3
#define LV_CHART_AXIS_PRIMARY_Y 1
#define LV_CHART_AXIS_SECONDARY_Y 0
#define LV_CHART_LABEL_ITERATOR_FORWARD 1
#define LV_CHART_LABEL_ITERATOR_REVERSE 0
@ -101,8 +99,12 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
_lv_ll_init(&ext->series_ll, sizeof(lv_chart_series_t));
ext->ymin = LV_CHART_YMIN_DEF;
ext->ymax = LV_CHART_YMAX_DEF;
uint8_t i;
for(i = 0; i < _LV_CHART_AXIS_LAST; i++) {
ext->ymin[i] = LV_CHART_YMIN_DEF;
ext->ymax[i] = LV_CHART_YMAX_DEF;
}
ext->hdiv_cnt = LV_CHART_HDIV_DEF;
ext->vdiv_cnt = LV_CHART_VDIV_DEF;
ext->point_cnt = LV_CHART_PNUM_DEF;
@ -118,7 +120,6 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
ext->secondary_y_axis.major_tick_len = LV_CHART_TICK_LENGTH_AUTO;
ext->secondary_y_axis.minor_tick_len = LV_CHART_TICK_LENGTH_AUTO;
lv_style_list_init(&ext->style_series_bg);
lv_style_list_init(&ext->style_series);
@ -133,7 +134,6 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
lv_obj_set_size(chart, LV_DPI * 3, LV_DPI * 2);
lv_theme_apply(chart, LV_THEME_CHART);
}
else {
lv_chart_ext_t * ext_copy = lv_obj_get_ext_attr(copy);
@ -142,11 +142,11 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
lv_style_list_copy(&ext->style_series_bg, &ext_copy->style_series_bg);
ext->type = ext_copy->type;
ext->ymin = ext_copy->ymin;
ext->ymax = ext_copy->ymax;
ext->hdiv_cnt = ext_copy->hdiv_cnt;
ext->vdiv_cnt = ext_copy->vdiv_cnt;
ext->point_cnt = ext_copy->point_cnt;
_lv_memcpy_small(ext->ymin, ext_copy->ymin, sizeof(ext->ymin));
_lv_memcpy_small(ext->ymax, ext_copy->ymax, sizeof(ext->ymax));
_lv_memcpy(&ext->x_axis, &ext_copy->x_axis, sizeof(lv_chart_axis_cfg_t));
_lv_memcpy(&ext->y_axis, &ext_copy->y_axis, sizeof(lv_chart_axis_cfg_t));
_lv_memcpy(&ext->secondary_y_axis, &ext_copy->secondary_y_axis, sizeof(lv_chart_axis_cfg_t));
@ -192,6 +192,7 @@ lv_chart_series_t * lv_chart_add_series(lv_obj_t * chart, lv_color_t color)
ser->start_point = 0;
ser->ext_buf_assigned = false;
ser->y_axis = LV_CHART_AXIS_PRIMARY_Y;
uint16_t i;
lv_coord_t * p_tmp = ser->points;
@ -249,20 +250,26 @@ void lv_chart_set_div_line_count(lv_obj_t * chart, uint8_t hdiv, uint8_t vdiv)
}
/**
* Set the minimal and maximal y values
* Set the minimal and maximal y values on an axis
* @param chart pointer to a graph background object
* @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y`
* @param ymin y minimum value
* @param ymax y maximum value
*/
void lv_chart_set_range(lv_obj_t * chart, lv_coord_t ymin, lv_coord_t ymax)
void lv_chart_set_y_range(lv_obj_t * chart, lv_chart_axis_t axis, lv_coord_t ymin, lv_coord_t ymax)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->ymin == ymin && ext->ymax == ymax) return;
if(axis >= _LV_CHART_AXIS_LAST) {
LV_LOG_WARN("Invalid axis: %d", axis);
return;
}
ext->ymin = ymin;
ext->ymax = ymax;
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
if(ext->ymin[axis] == ymin && ext->ymax[axis] == ymax) return;
ext->ymin[axis] = ymin;
ext->ymax[axis] = ymax;
lv_chart_refresh(chart);
}
@ -600,6 +607,28 @@ void lv_chart_set_point_id(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t
ser->points[id] = value;
}
/**
* Set the Y axis of a series
* @param chart pointer to a chart object
* @param ser pointer to series
* @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y`
*/
void lv_chart_set_series_axis(lv_obj_t * chart, lv_chart_series_t * ser, lv_chart_axis_t axis)
{
LV_ASSERT_OBJ(chart, LV_OBJX_NAME);
LV_ASSERT_NULL(ser);
if(axis >= _LV_CHART_AXIS_LAST) {
LV_LOG_WARN("Invalid axis: %d", axis);
return;
}
if( ser->y_axis == axis) return;
ser->y_axis = axis;
lv_chart_refresh(chart);
}
/*=====================
* Getter functions
*====================*/
@ -660,6 +689,19 @@ lv_coord_t lv_chart_get_point_id(lv_obj_t * chart, lv_chart_series_t * ser, uint
}
/**
* Get the Y axis of a series
* @param chart pointer to a chart object
* @param ser pointer to series
* @return `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y`
*/
lv_chart_axis_t lv_chart_get_series_axis(lv_obj_t * chart, lv_chart_series_t * ser)
{
LV_ASSERT_NULL(ser);
LV_UNUSED(chart);
return ser->y_axis;
}
/*=====================
* Other functions
*====================*/
@ -929,8 +971,8 @@ static void draw_series_line(lv_obj_t * chart, const lv_area_t * series_area, co
lv_coord_t p_act = start_point;
lv_coord_t p_prev = start_point;
int32_t y_tmp = (int32_t)((int32_t)ser->points[p_prev] - ext->ymin) * h;
y_tmp = y_tmp / (ext->ymax - ext->ymin);
int32_t y_tmp = (int32_t)((int32_t)ser->points[p_prev] - ext->ymin[ser->y_axis]) * h;
y_tmp = y_tmp / (ext->ymax[ser->y_axis] - ext->ymin[ser->y_axis]);
p2.y = h - y_tmp + y_ofs;
for(i = 0; i < ext->point_cnt; i++) {
@ -941,8 +983,8 @@ static void draw_series_line(lv_obj_t * chart, const lv_area_t * series_area, co
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);
y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin[ser->y_axis]) * h;
y_tmp = y_tmp / (ext->ymax[ser->y_axis] - ext->ymin[ser->y_axis]);
p2.y = h - y_tmp + y_ofs;
/*Don't draw the first point. A second point is also required to draw the line*/
@ -1065,8 +1107,8 @@ static void draw_series_column(lv_obj_t * chart, const lv_area_t * series_area,
col_dsc.bg_color = ser->color;
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);
y_tmp = (int32_t)((int32_t)ser->points[p_act] - ext->ymin[ser->y_axis]) * h;
y_tmp = y_tmp / (ext->ymax[ser->y_axis] - ext->ymin[ser->y_axis]);
col_a.y1 = h - y_tmp + series_area->y1;
if(ser->points[p_act] != LV_CHART_POINT_DEF) {

View File

@ -52,11 +52,20 @@ enum {
};
typedef uint8_t lv_chart_update_mode_t;
enum {
LV_CHART_AXIS_PRIMARY_Y,
LV_CHART_AXIS_SECONDARY_Y,
_LV_CHART_AXIS_LAST,
};
typedef uint8_t lv_chart_axis_t;
typedef struct {
lv_coord_t * points;
lv_color_t color;
uint16_t start_point;
uint8_t ext_buf_assigned : 1;
lv_chart_axis_t y_axis : 1;
} lv_chart_series_t;
/** Data of axis */
@ -80,8 +89,8 @@ typedef struct {
/*No inherited ext*/ /*Ext. of ancestor*/
/*New data for this type */
lv_ll_t series_ll; /*Linked list for the data line pointers (stores lv_chart_series_t)*/
lv_coord_t ymin; /*y min value (used to scale the data)*/
lv_coord_t ymax; /*y max value (used to scale the data)*/
lv_coord_t ymin[_LV_CHART_AXIS_LAST]; /*y min values for both axis (used to scale the data)*/
lv_coord_t ymax[_LV_CHART_AXIS_LAST]; /*y max values for both axis (used to scale the data)*/
uint8_t hdiv_cnt; /*Number of horizontal division lines*/
uint8_t vdiv_cnt; /*Number of vertical division lines*/
uint16_t point_cnt; /*Point number in a data line*/
@ -137,6 +146,7 @@ void lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * serie);
* Setter functions
*====================*/
/**
* Set the number of horizontal and vertical division lines
* @param chart pointer to a graph background object
@ -146,12 +156,13 @@ void lv_chart_clear_serie(lv_obj_t * chart, lv_chart_series_t * serie);
void lv_chart_set_div_line_count(lv_obj_t * chart, uint8_t hdiv, uint8_t vdiv);
/**
* Set the minimal and maximal y values
* Set the minimal and maximal y values on an axis
* @param chart pointer to a graph background object
* @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y`
* @param ymin y minimum value
* @param ymax y maximum value
*/
void lv_chart_set_range(lv_obj_t * chart, lv_coord_t ymin, lv_coord_t ymax);
void lv_chart_set_y_range(lv_obj_t * chart, lv_chart_axis_t axis, lv_coord_t ymin, lv_coord_t ymax);
/**
* Set a new type for a chart
@ -287,6 +298,14 @@ void lv_chart_set_ext_array(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_
*/
void lv_chart_set_point_id(lv_obj_t * chart, lv_chart_series_t * ser, lv_coord_t value, uint16_t id);
/**
* Set the Y axis of a series
* @param chart pointer to a chart object
* @param ser pointer to series
* @param axis `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y`
*/
void lv_chart_set_series_axis(lv_obj_t * chart, lv_chart_series_t * ser, lv_chart_axis_t axis);
/*=====================
* Getter functions
*====================*/
@ -321,6 +340,14 @@ uint16_t lv_chart_get_x_start_point(lv_chart_series_t * ser);
*/
lv_coord_t lv_chart_get_point_id(lv_obj_t * chart, lv_chart_series_t * ser, uint16_t id);
/**
* Get the Y axis of a series
* @param chart pointer to a chart object
* @param ser pointer to series
* @return `LV_CHART_AXIS_PRIMARY_Y` or `LV_CHART_AXIS_SECONDARY_Y`
*/
lv_chart_axis_t lv_chart_get_series_axis(lv_obj_t * chart, lv_chart_series_t * ser);
/*=====================
* Other functions
*====================*/