Change Y labels format in primary/secondary series

Description

Hi all, i would like to format y labels in a certain way: if i got 100, i want to print 1, so i need to divide the number i got by 100, having at max 1 decimal.

What MCU/Processor/Board and compiler are you using?

ESP32S3

What LVGL version are you using?

8.2.0

What do you want to achieve?

Having the graph labels formatted as follows: x/100 where x is the number to print at tick label.
In my application i update the range of the graph periodically, so the labels must change with the format i want as the program goes

What have you tried so far?

I tried some solutions in web but none worked

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.

One of the examples in the documentation for lv_chart shows how to attach a callback to LV_EVENT_DRAW_PART_BEGIN so you can intercept when these get drawn and modify them as you please for the X axis - presumably it works for the Y axis too!

Hi, i have tried exaclty that code, but it seems not to work, because i need to format the labels multiple times.
I think it is because of the event type

lv_obj_add_event(chart, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);

which is not right for me @kisvegabor, sorry to disturb you, do you have any solution to this?
Thank you in advance

The correct function is lv_obj_add_event_cb ()

Maybe you can post the code of your draw_event_cb ()?

i wrote something like this

static void draw_event_cb(lv_event_t * e)
{
    lv_obj_draw_part_dsc_t *dsc = lv_event_get_draw_part_dsc(e);

    if (dsc->class_p == &lv_chart_class && dsc->part == LV_CHART_PART_TICKS && dsc->id == LV_CHART_AXIS_PRIMARY_Y && dsc->text) {
        // Divide il valore per 100
        float value = *((float *)dsc->value);
        value /= 100.0;

        // Formatta il testo delle etichette con il nuovo valore
        lv_snprintf(dsc->text, dsc->text_length, "%.1f", value);
    }
}

Two things:

  1. Your code may result in an exception because of this line:
float value = *((float *)dsc->value);

dsc->value is int32_t. It means it is a value and not a pointer to anything. So you should not cast this to a pointer (of any type) as you do. If you do this it might throw an exception because of illegal address access.

This code converts the int32_t value to a float value.

  float value = (float) dsc->value;
  value /= 100.0;

or in one line:

  float value = (float) dsc->value / 100.0;
  1. When you use lv_snprintf with float numbers you have to setup lv_conf.h appropriately. Look for LV_SPRINTF_USE_FLOAT. It should be set to 1 in case LV_SPRINTF_CUSTOM is set to 0

Managed to make it work by removing some conditions in the if guard.
here is the code.

Do you confirm that is correct? Thank you for your help and your time

static void draw_event_cb(lv_event_t * e)
{
	lv_obj_draw_part_dsc_t *dsc = lv_event_get_draw_part_dsc(e);

	if (dsc->id == LV_CHART_AXIS_PRIMARY_Y) {
		// Formatta il testo delle etichette con il nuovo valore
		lv_snprintf(dsc->text, dsc->text_length, "%.1f", (float) dsc->value / 100.0);
	}
}

// call this function when you init the ui
lv_obj_add_event_cb(ui_VoltageChart, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);