What is the logic behind lv_chart_set_axis_tick

So below (part of) my code to get the X and Y scaling the way I would like.
First the code to create the chart

//Create the chart
lv_obj_t* chart = lv_chart_create(parent);
lv_obj_set_align(chart, LV_ALIGN_CENTER);
lv_chart_set_type(chart, LV_CHART_TYPE_LINE);
lv_obj_set_size(chart, 400, 300);

//Set the axis
lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 10, 5, 5, 3, true, 50);
lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 11, 1, true, 50);
lv_obj_set_style_size(chart, 0, LV_PART_INDICATOR);

//Generate some dummy data
float graphData[NUMBEROFSAMPLES];
for (size_t i = 0; i < NUMBEROFSAMPLES; i++)
{
	graphData[i] = lv_rand(0, 100)/50.0;
}

//Determine the maximum and minimum values
float minVal = 0;
float maxVal = 0;
for (int i = 0; i < NUMBEROFSAMPLES; i++) {
	if (graphData[i] < minVal) {
		minVal = graphData[i];
	}
	if (graphData[i] > maxVal) {
		maxVal = graphData[i];
	}
}

//ToDo: Determine the multiplier
int multiplier = 50;

//Convert the floats to integers
static lv_coord_t graphDataInt[NUMBEROFSAMPLES];
for (int i = 0; i < NUMBEROFSAMPLES; i++) {
   graphDataInt[i] = graphData[i] * multiplier;
}

//Set the Y range
lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, minVal * multiplier, maxVal * multiplier);

//Set the data
lv_chart_series_t* chartSeries = lv_chart_add_series(chart, lv_color_hex(0x808080), LV_CHART_AXIS_PRIMARY_Y);
lv_chart_set_ext_y_array(chart, chartSeries, graphDataInt);
lv_chart_set_point_count(chart, NUMBEROFSAMPLES);

//Set the event data
static EventData_t eventData;
eventData.multiplier = multiplier;
eventData.hour = 12;
eventData.min = 50;
eventData.sec = 10;

//Prepare the callback
lv_obj_add_event_cb(chart, DrawCallbackEvent, LV_EVENT_DRAW_PART_BEGIN, &eventData);

And next the callback (and yes, I know the way the X axis is done is not correct, but that is something I leave for the reader.

static void DrawCallbackEvent(lv_event_t* e)
{
    //Get the event descriptor
    lv_obj_draw_part_dsc_t* dsc = lv_event_get_draw_part_dsc(e);

    //Check what part we are updating. Only proceed if we are updating one of the tick label(s)
    if (!lv_obj_draw_part_check_type(dsc, &lv_chart_class, LV_CHART_DRAW_PART_TICK_LABEL))
        return;

    //Check this is a callback for a major tick (minor ticks have 0 here)
    if (dsc->text == NULL)
        return;

    //Get the multiplier from the user data
    EventData_t *eventData = (EventData_t*)lv_event_get_user_data(e);

    //If we are editing the Y axis
    if (dsc->id == LV_CHART_AXIS_PRIMARY_Y)
    {
        //update the label with the modified multiplier
        lv_snprintf(dsc->text, dsc->text_length, "%.2f", (float)dsc->value / eventData->multiplier);
    }
    else if (dsc->id == LV_CHART_AXIS_PRIMARY_X)
    {
        //ToDo: improve this logic
        switch (dsc->value)
        {
            case 0:
                lv_snprintf(dsc->text, dsc->text_length, "%02d:%02d:%02d", eventData->hour - 1, eventData->min, eventData->sec);
                break;
            case 1:
                lv_snprintf(dsc->text, dsc->text_length, "%02d:%02d:%02d", eventData->hour, eventData->min - 45, eventData->sec);
                break;
            case 2:
                lv_snprintf(dsc->text, dsc->text_length, "%02d:%02d:%02d", eventData->hour, eventData->min - 30, eventData->sec);
                break;
            case 3:
                lv_snprintf(dsc->text, dsc->text_length, "%02d:%02d:%02d", eventData->hour, eventData->min - 15, eventData->sec);
                break;
            case 4:
                lv_snprintf(dsc->text, dsc->text_length, "%02d:%02d:%02d", eventData->hour, eventData->min, eventData->sec);
                break;
        }
    }
}

And finally the result
image

1 Like