lv_chart: add secondary Y axis and ability to reverse label order (#1194)
This commit is contained in:
committed by
embeddedt
parent
9c8e0f0552
commit
3dc57783ad
@@ -60,6 +60,13 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
|
||||
{
|
||||
const lv_font_t * font = style->text.font;
|
||||
lv_coord_t w;
|
||||
|
||||
/*No need to waste processor time if string is empty*/
|
||||
if (txt[0] == '\0')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if((flag & LV_TXT_FLAG_EXPAND) == 0) {
|
||||
/*Normally use the label's width as width*/
|
||||
w = lv_area_get_width(coords);
|
||||
|
||||
@@ -24,11 +24,22 @@
|
||||
#define LV_CHART_AXIS_TO_LABEL_DISTANCE 4
|
||||
#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
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
const char * list_start;
|
||||
const char * current_pos;
|
||||
uint8_t items_left;
|
||||
uint8_t is_reverse_iter;
|
||||
} lv_chart_label_iterator_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
@@ -44,6 +55,9 @@ 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 void lv_chart_get_next_label(lv_chart_label_iterator_t * iterator, char * buf);
|
||||
static inline bool lv_chart_is_tick_with_label(uint8_t tick_num, lv_chart_axis_cfg_t * axis);
|
||||
static lv_chart_label_iterator_t lv_chart_create_label_iter(const char * list, uint8_t iterator_dir);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@@ -96,10 +110,13 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->margin = 0;
|
||||
memset(&ext->x_axis, 0, sizeof(ext->x_axis));
|
||||
memset(&ext->y_axis, 0, sizeof(ext->y_axis));
|
||||
memset(&ext->secondary_y_axis, 0, sizeof(ext->secondary_y_axis));
|
||||
ext->x_axis.major_tick_len = LV_CHART_TICK_LENGTH_AUTO;
|
||||
ext->x_axis.minor_tick_len = LV_CHART_TICK_LENGTH_AUTO;
|
||||
ext->y_axis.major_tick_len = LV_CHART_TICK_LENGTH_AUTO;
|
||||
ext->y_axis.minor_tick_len = LV_CHART_TICK_LENGTH_AUTO;
|
||||
ext->secondary_y_axis.major_tick_len = LV_CHART_TICK_LENGTH_AUTO;
|
||||
ext->secondary_y_axis.minor_tick_len = LV_CHART_TICK_LENGTH_AUTO;
|
||||
|
||||
if(ancestor_design_f == NULL) ancestor_design_f = lv_obj_get_design_cb(new_chart);
|
||||
if(ancestor_signal == NULL) ancestor_signal = lv_obj_get_signal_cb(new_chart);
|
||||
@@ -132,6 +149,7 @@ lv_obj_t * lv_chart_create(lv_obj_t * par, const lv_obj_t * copy)
|
||||
ext->margin = ext_copy->margin;
|
||||
memcpy(&ext->x_axis, &ext_copy->x_axis, sizeof(lv_chart_axis_cfg_t));
|
||||
memcpy(&ext->y_axis, &ext_copy->y_axis, sizeof(lv_chart_axis_cfg_t));
|
||||
memcpy(&ext->secondary_y_axis, &ext_copy->secondary_y_axis, sizeof(lv_chart_axis_cfg_t));
|
||||
|
||||
/*Refresh the style with new signal function*/
|
||||
lv_obj_refresh_style(new_chart);
|
||||
@@ -463,6 +481,21 @@ void lv_chart_set_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_
|
||||
ext->y_axis.minor_tick_len = minor_tick_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the length of the tick marks on the secondary y axis
|
||||
* @param chart pointer to the chart
|
||||
* @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically
|
||||
* (where labels are added)
|
||||
* @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically
|
||||
* (where no labels are added)
|
||||
*/
|
||||
void lv_chart_set_secondary_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len)
|
||||
{
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
ext->secondary_y_axis.major_tick_len = major_tick_len;
|
||||
ext->secondary_y_axis.minor_tick_len = minor_tick_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the x-axis tick count and labels of a chart
|
||||
* @param chart pointer to a chart object
|
||||
@@ -497,6 +530,23 @@ void lv_chart_set_y_tick_texts(lv_obj_t * chart, const char * list_of_values, ui
|
||||
ext->y_axis.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the secondary y-axis tick count and labels of a chart
|
||||
* @param chart pointer to a chart object
|
||||
* @param list_of_values list of string values, terminated with \n, except the last
|
||||
* @param num_tick_marks if list_of_values is NULL: total number of ticks per axis
|
||||
* else number of ticks between two value labels
|
||||
* @param options extra options
|
||||
*/
|
||||
void lv_chart_set_secondary_y_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
|
||||
lv_chart_axis_options_t options)
|
||||
{
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
ext->secondary_y_axis.num_tick_marks = num_tick_marks;
|
||||
ext->secondary_y_axis.list_of_values = list_of_values;
|
||||
ext->secondary_y_axis.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the margin around the chart, used for axes value and ticks
|
||||
* @param chart pointer to an chart object
|
||||
@@ -1046,65 +1096,187 @@ static void lv_chart_draw_areas(lv_obj_t * chart, const lv_area_t * mask)
|
||||
}
|
||||
}
|
||||
|
||||
static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
/**
|
||||
* Create iterator for newline-separated list
|
||||
* @param list pointer to newline-separated labels list
|
||||
* @param iterator_dir LV_CHART_ITERATOR_FORWARD or LV_CHART_LABEL_ITERATOR_REVERSE
|
||||
* @return lv_chart_label_iterator_t
|
||||
*/
|
||||
static lv_chart_label_iterator_t lv_chart_create_label_iter(const char * list, uint8_t iterator_dir)
|
||||
{
|
||||
lv_chart_label_iterator_t iterator = {0};
|
||||
uint8_t j;
|
||||
|
||||
iterator.list_start = list;
|
||||
|
||||
/* count number of list items */
|
||||
for(j = 0; list[j] != '\0'; j++) {
|
||||
if(list[j] == '\n')
|
||||
iterator.items_left++;
|
||||
}
|
||||
|
||||
if(iterator_dir == LV_CHART_LABEL_ITERATOR_FORWARD) {
|
||||
iterator.is_reverse_iter = 0;
|
||||
iterator.current_pos = list;
|
||||
} else {
|
||||
iterator.is_reverse_iter = 1;
|
||||
// -1 to skip '\0' at the end of the string
|
||||
iterator.current_pos = list + j - 1;
|
||||
}
|
||||
iterator.items_left++;
|
||||
return iterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next label from iterator created by lv_chart_create_label_iter()
|
||||
* @param iterator iterator to get label from
|
||||
* @param[out] buf buffer to point next label to
|
||||
*/
|
||||
static void lv_chart_get_next_label(lv_chart_label_iterator_t * iterator, char * buf)
|
||||
{
|
||||
uint8_t label_len = 0;
|
||||
if (iterator->is_reverse_iter) {
|
||||
const char * label_start;
|
||||
/* count the length of the current label*/
|
||||
while ((*iterator->current_pos != '\n') &&
|
||||
(iterator->current_pos != iterator->list_start)) {
|
||||
iterator->current_pos--;
|
||||
label_len++;
|
||||
}
|
||||
|
||||
label_start = iterator->current_pos;
|
||||
|
||||
if (*iterator->current_pos == '\n') {
|
||||
/* do not copy \n symbol, +1 to skip it*/
|
||||
label_start++;
|
||||
/* skip newline*/
|
||||
iterator->current_pos--;
|
||||
} else {
|
||||
/* it is last label in list (first one from the beginning )*/
|
||||
label_len++;
|
||||
}
|
||||
|
||||
/* do not allow output buffer overflow */
|
||||
if (label_len > LV_CHART_AXIS_TICK_LABEL_MAX_LEN) {
|
||||
label_len = LV_CHART_AXIS_TICK_LABEL_MAX_LEN;
|
||||
}
|
||||
|
||||
strncpy(buf, label_start, label_len);
|
||||
} else {
|
||||
/* search for tick string */
|
||||
while(iterator->current_pos[label_len] != '\n' &&
|
||||
iterator->current_pos[label_len] != '\0') {
|
||||
/* do not overflow the buffer, but move to the end of the current label */
|
||||
if(label_len < LV_CHART_AXIS_TICK_LABEL_MAX_LEN) {
|
||||
buf[label_len] = iterator->current_pos[label_len];
|
||||
label_len++;
|
||||
} else {
|
||||
label_len++;
|
||||
}
|
||||
}
|
||||
|
||||
iterator->current_pos += label_len;
|
||||
|
||||
/* do not allow output buffer overflow */
|
||||
if (label_len > LV_CHART_AXIS_TICK_LABEL_MAX_LEN) {
|
||||
label_len = LV_CHART_AXIS_TICK_LABEL_MAX_LEN;
|
||||
}
|
||||
|
||||
if(*iterator->current_pos == '\n') iterator->current_pos++;
|
||||
}
|
||||
|
||||
/* terminate the string */
|
||||
buf[label_len] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there should be a label next to tick with given
|
||||
* number
|
||||
* @param tick_num number of the tick to check
|
||||
* @param axis pointer to struct containing info on the axis
|
||||
* @return true if label should be located next to current tick
|
||||
*/
|
||||
static inline bool lv_chart_is_tick_with_label(uint8_t tick_num, lv_chart_axis_cfg_t * axis)
|
||||
{
|
||||
return ((tick_num == 0) || ((tick_num % axis->num_tick_marks) == 0));
|
||||
}
|
||||
|
||||
static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask, uint8_t which_axis)
|
||||
{
|
||||
lv_chart_ext_t * ext = lv_obj_get_ext_attr(chart);
|
||||
lv_chart_axis_cfg_t * y_axis = (which_axis == LV_CHART_AXIS_PRIMARY_Y) ?
|
||||
&ext->y_axis : &ext->secondary_y_axis;
|
||||
|
||||
if(ext->y_axis.list_of_values != NULL || ext->y_axis.num_tick_marks != 0) {
|
||||
if(y_axis->list_of_values != NULL || y_axis->num_tick_marks != 0) {
|
||||
|
||||
const lv_style_t * style = lv_obj_get_style(chart);
|
||||
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
|
||||
|
||||
uint8_t i, j;
|
||||
uint8_t list_index;
|
||||
uint8_t num_of_labels;
|
||||
uint8_t num_scale_ticks;
|
||||
uint8_t major_tick_len, minor_tick_len;
|
||||
int8_t major_tick_len, minor_tick_len;
|
||||
uint8_t iter_dir;
|
||||
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
lv_coord_t x_ofs = chart->coords.x1;
|
||||
lv_coord_t x_ofs;
|
||||
lv_chart_label_iterator_t iter;
|
||||
lv_coord_t y_ofs = chart->coords.y1;
|
||||
lv_coord_t h = lv_obj_get_height(chart);
|
||||
lv_coord_t w = lv_obj_get_width(chart);
|
||||
char buf[LV_CHART_AXIS_TICK_LABEL_MAX_LEN + 1]; /* up to N symbols per label + null terminator */
|
||||
|
||||
/* chose correct side of the chart */
|
||||
if(which_axis == LV_CHART_AXIS_PRIMARY_Y)
|
||||
x_ofs = chart->coords.x1;
|
||||
else
|
||||
x_ofs = chart->coords.x2;
|
||||
|
||||
/* calculate the size of tick marks */
|
||||
if(ext->y_axis.major_tick_len == LV_CHART_TICK_LENGTH_AUTO)
|
||||
if(y_axis->major_tick_len == LV_CHART_TICK_LENGTH_AUTO)
|
||||
major_tick_len = (int32_t)w * LV_CHART_AXIS_MAJOR_TICK_LEN_COE;
|
||||
else
|
||||
major_tick_len = ext->y_axis.major_tick_len;
|
||||
major_tick_len = y_axis->major_tick_len;
|
||||
|
||||
if(ext->y_axis.minor_tick_len == LV_CHART_TICK_LENGTH_AUTO)
|
||||
if(y_axis->minor_tick_len == LV_CHART_TICK_LENGTH_AUTO)
|
||||
minor_tick_len = major_tick_len * LV_CHART_AXIS_MINOR_TICK_LEN_COE;
|
||||
else
|
||||
minor_tick_len = ext->y_axis.minor_tick_len;
|
||||
minor_tick_len = y_axis->minor_tick_len;
|
||||
|
||||
/* count the '\n'-s to determine the number of options */
|
||||
list_index = 0;
|
||||
num_of_labels = 0;
|
||||
if(ext->y_axis.list_of_values != NULL) {
|
||||
for(j = 0; ext->y_axis.list_of_values[j] != '\0'; j++) {
|
||||
if(ext->y_axis.list_of_values[j] == '\n') num_of_labels++;
|
||||
}
|
||||
|
||||
num_of_labels++; /* last option in the at row*/
|
||||
/* tick lines on secondary y axis are drawn in other direction*/
|
||||
if(which_axis == LV_CHART_AXIS_SECONDARY_Y) {
|
||||
major_tick_len *= -1;
|
||||
minor_tick_len *= -1;
|
||||
}
|
||||
|
||||
iter_dir = (y_axis->options & LV_CHART_AXIS_INVERSE_LABELS_ORDER) ? LV_CHART_LABEL_ITERATOR_REVERSE : LV_CHART_LABEL_ITERATOR_FORWARD;
|
||||
iter = lv_chart_create_label_iter(y_axis->list_of_values, iter_dir);
|
||||
|
||||
/*determine the number of options */
|
||||
num_of_labels = iter.items_left;
|
||||
|
||||
/* we can't have string labels without ticks step, set to 1 if not specified */
|
||||
if(ext->y_axis.num_tick_marks == 0) ext->y_axis.num_tick_marks = 1;
|
||||
if(y_axis->num_tick_marks == 0) y_axis->num_tick_marks = 1;
|
||||
|
||||
/* calculate total number of ticks */
|
||||
if(num_of_labels < 2)
|
||||
num_scale_ticks = ext->y_axis.num_tick_marks;
|
||||
num_scale_ticks = y_axis->num_tick_marks;
|
||||
else
|
||||
num_scale_ticks = (ext->y_axis.num_tick_marks * (num_of_labels - 1));
|
||||
num_scale_ticks = (y_axis->num_tick_marks * (num_of_labels - 1));
|
||||
|
||||
for(i = 0; i < (num_scale_ticks + 1); i++) { /* one extra loop - it may not exist in the list, empty label */
|
||||
/* first point of the tick */
|
||||
p1.x = x_ofs - 1;
|
||||
p1.x = x_ofs;
|
||||
|
||||
/* move extra pixel out of chart boundary */
|
||||
if (which_axis == LV_CHART_AXIS_PRIMARY_Y)
|
||||
p1.x--;
|
||||
else
|
||||
p1.x++;
|
||||
|
||||
/* second point of the tick */
|
||||
if((num_of_labels != 0) && (i == 0 || i % ext->y_axis.num_tick_marks == 0))
|
||||
if((num_of_labels != 0) && (i == 0 || i % y_axis->num_tick_marks == 0))
|
||||
p2.x = p1.x - major_tick_len; /* major tick */
|
||||
else
|
||||
p2.x = p1.x - minor_tick_len; /* minor tick */
|
||||
@@ -1113,31 +1285,25 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
p2.y = p1.y =
|
||||
y_ofs + (int32_t)((int32_t)(h - style->line.width) * i) / num_scale_ticks;
|
||||
|
||||
if(i != num_scale_ticks)
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
else if((ext->y_axis.options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0)
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
if(y_axis->options & LV_CHART_AXIS_INVERSE_LABELS_ORDER) {
|
||||
/*if label order is inversed last tick have number 0*/
|
||||
if(i != 0)
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
else if((y_axis->options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0)
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
} else {
|
||||
if(i != num_scale_ticks)
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
else if((y_axis->options & LV_CHART_AXIS_DRAW_LAST_TICK) != 0)
|
||||
lv_draw_line(&p1, &p2, mask, style, opa_scale);
|
||||
}
|
||||
|
||||
/* draw values if available */
|
||||
if(num_of_labels != 0) {
|
||||
/* add text only to major tick */
|
||||
if(i == 0 || i % ext->y_axis.num_tick_marks == 0) {
|
||||
/* search for tick string */
|
||||
j = 0;
|
||||
while(ext->y_axis.list_of_values[list_index] != '\n' &&
|
||||
ext->y_axis.list_of_values[list_index] != '\0') {
|
||||
/* do not overflow the buffer, but move to the end of the current label */
|
||||
if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN)
|
||||
buf[j++] = ext->y_axis.list_of_values[list_index++];
|
||||
else
|
||||
list_index++;
|
||||
}
|
||||
if(lv_chart_is_tick_with_label(i, y_axis)) {
|
||||
|
||||
/* this was a string, but not end of the list, so jump to the next string */
|
||||
if(ext->y_axis.list_of_values[list_index] == '\n') list_index++;
|
||||
|
||||
/* terminate the string */
|
||||
buf[j] = '\0';
|
||||
lv_chart_get_next_label(&iter, buf);
|
||||
|
||||
/* reserve appropriate area */
|
||||
lv_point_t size;
|
||||
@@ -1145,8 +1311,16 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
LV_COORD_MAX, LV_TXT_FLAG_CENTER);
|
||||
|
||||
/* set the area at some distance of the major tick len left of the tick */
|
||||
lv_area_t a = {(p2.x - size.x - LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.y - size.y / 2),
|
||||
(p2.x - LV_CHART_AXIS_TO_LABEL_DISTANCE), (p2.y + size.y / 2)};
|
||||
lv_area_t a = {.y1 = p2.y - size.y / 2, .y2 = p2.y + size.y / 2};
|
||||
|
||||
if(which_axis == LV_CHART_AXIS_PRIMARY_Y) {
|
||||
a.x1 = p2.x - size.x - LV_CHART_AXIS_TO_LABEL_DISTANCE;
|
||||
a.x2 = p2.x - LV_CHART_AXIS_TO_LABEL_DISTANCE;
|
||||
} else {
|
||||
a.x1 = p2.x + LV_CHART_AXIS_TO_LABEL_DISTANCE;
|
||||
a.x2 = p2.x + size.x + LV_CHART_AXIS_TO_LABEL_DISTANCE;
|
||||
}
|
||||
|
||||
lv_draw_label(&a, mask, style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL, -1, -1, NULL);
|
||||
}
|
||||
}
|
||||
@@ -1169,6 +1343,7 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
uint8_t num_of_labels;
|
||||
uint8_t num_scale_ticks;
|
||||
uint8_t major_tick_len, minor_tick_len;
|
||||
lv_chart_label_iterator_t iter;
|
||||
lv_point_t p1;
|
||||
lv_point_t p2;
|
||||
lv_coord_t x_ofs = chart->coords.x1;
|
||||
@@ -1188,16 +1363,9 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
else
|
||||
minor_tick_len = ext->x_axis.minor_tick_len;
|
||||
|
||||
/* count the '\n'-s to determine the number of options */
|
||||
list_index = 0;
|
||||
num_of_labels = 0;
|
||||
if(ext->x_axis.list_of_values != NULL) {
|
||||
for(j = 0; ext->x_axis.list_of_values[j] != '\0'; j++) {
|
||||
if(ext->x_axis.list_of_values[j] == '\n') num_of_labels++;
|
||||
}
|
||||
|
||||
num_of_labels++; /* last option in the at row*/
|
||||
}
|
||||
/*determine the number of options */
|
||||
iter = lv_chart_create_label_iter(ext->x_axis.list_of_values, LV_CHART_LABEL_ITERATOR_FORWARD);
|
||||
num_of_labels = iter.items_left;
|
||||
|
||||
/* we can't have string labels without ticks step, set to 1 if not specified */
|
||||
if(ext->x_axis.num_tick_marks == 0) ext->x_axis.num_tick_marks = 1;
|
||||
@@ -1229,23 +1397,8 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
/* draw values if available */
|
||||
if(num_of_labels != 0) {
|
||||
/* add text only to major tick */
|
||||
if(i == 0 || i % ext->x_axis.num_tick_marks == 0) {
|
||||
/* search for tick string */
|
||||
j = 0;
|
||||
while(ext->x_axis.list_of_values[list_index] != '\n' &&
|
||||
ext->x_axis.list_of_values[list_index] != '\0') {
|
||||
/* do not overflow the buffer, but move to the end of the current label */
|
||||
if(j < LV_CHART_AXIS_TICK_LABEL_MAX_LEN)
|
||||
buf[j++] = ext->x_axis.list_of_values[list_index++];
|
||||
else
|
||||
list_index++;
|
||||
}
|
||||
|
||||
/* this was a string, but not end of the list, so jump to the next string */
|
||||
if(ext->x_axis.list_of_values[list_index] == '\n') list_index++;
|
||||
|
||||
/* terminate the string */
|
||||
buf[j] = '\0';
|
||||
if(lv_chart_is_tick_with_label(i, &(ext->x_axis))) {
|
||||
lv_chart_get_next_label(&iter, buf);
|
||||
|
||||
/* reserve appropriate area */
|
||||
lv_point_t size;
|
||||
@@ -1264,7 +1417,8 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
|
||||
|
||||
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_y_ticks(chart, mask, LV_CHART_AXIS_PRIMARY_Y);
|
||||
lv_chart_draw_y_ticks(chart, mask, LV_CHART_AXIS_SECONDARY_Y);
|
||||
lv_chart_draw_x_ticks(chart, mask);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,8 +65,9 @@ typedef struct
|
||||
|
||||
/** Data of axis */
|
||||
enum {
|
||||
LV_CHART_AXIS_SKIP_LAST_TICK = 0x00, /**< don't draw the last tick */
|
||||
LV_CHART_AXIS_DRAW_LAST_TICK = 0x01 /**< draw the last tick */
|
||||
LV_CHART_AXIS_SKIP_LAST_TICK = 0x00, /**< don't draw the last tick */
|
||||
LV_CHART_AXIS_DRAW_LAST_TICK = 0x01, /**< draw the last tick */
|
||||
LV_CHART_AXIS_INVERSE_LABELS_ORDER = 0x02 /**< draw tick labels in an inversed order*/
|
||||
};
|
||||
typedef uint8_t lv_chart_axis_options_t;
|
||||
|
||||
@@ -93,6 +94,7 @@ typedef struct
|
||||
lv_chart_type_t type; /*Line, column or point chart (from 'lv_chart_type_t')*/
|
||||
lv_chart_axis_cfg_t y_axis;
|
||||
lv_chart_axis_cfg_t x_axis;
|
||||
lv_chart_axis_cfg_t secondary_y_axis;
|
||||
uint16_t margin;
|
||||
uint8_t update_mode : 1;
|
||||
struct
|
||||
@@ -259,6 +261,16 @@ void lv_chart_set_x_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_
|
||||
*/
|
||||
void lv_chart_set_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len);
|
||||
|
||||
/**
|
||||
* Set the length of the tick marks on the secondary y axis
|
||||
* @param chart pointer to the chart
|
||||
* @param major_tick_len the length of the major tick or `LV_CHART_TICK_LENGTH_AUTO` to set automatically
|
||||
* (where labels are added)
|
||||
* @param minor_tick_len the length of the minor tick, `LV_CHART_TICK_LENGTH_AUTO` to set automatically
|
||||
* (where no labels are added)
|
||||
*/
|
||||
void lv_chart_set_secondary_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_t minor_tick_len);
|
||||
|
||||
/**
|
||||
* Set the x-axis tick count and labels of a chart
|
||||
* @param chart pointer to a chart object
|
||||
@@ -270,6 +282,17 @@ void lv_chart_set_y_tick_length(lv_obj_t * chart, uint8_t major_tick_len, uint8_
|
||||
void lv_chart_set_x_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
|
||||
lv_chart_axis_options_t options);
|
||||
|
||||
/**
|
||||
* Set the secondary y-axis tick count and labels of a chart
|
||||
* @param chart pointer to a chart object
|
||||
* @param list_of_values list of string values, terminated with \n, except the last
|
||||
* @param num_tick_marks if list_of_values is NULL: total number of ticks per axis
|
||||
* else number of ticks between two value labels
|
||||
* @param options extra options
|
||||
*/
|
||||
void lv_chart_set_secondary_y_tick_texts(lv_obj_t * chart, const char * list_of_values, uint8_t num_tick_marks,
|
||||
lv_chart_axis_options_t options);
|
||||
|
||||
/**
|
||||
* Set the y-axis tick count and labels of a chart
|
||||
* @param chart pointer to a chart object
|
||||
|
||||
Reference in New Issue
Block a user