Important: unclear posts may not receive useful answers.
Before posting
Get familiar with Markdown to format and structure your post
Be sure to update lvgl from the latest version from the master branch.
Be sure you have checked the relevant part of the documentation.
If applicable use the Simulator to eliminate hardware related issues.
Delete this section if you read and applied the mentioned points.
Description
I have a chart that looks like this
I want to add it minor division lines that will provide additional resolution in reading the values. Here is an example one I mean but of course I will pick a color and line thickness that will make the minor division lines less visible than the primary divisions.
What MCU/Processor/Board and compiler are you using?
STM32411CE black pill.
What LVGL version are you using?
I can upgrade to the latest if needed.
What do you want to achieve?
Adding horizontal and vertical minor division lines that are less visible than the major division lines which are on axis tick values.
What have you tried so far?
Reading the LVGL Chart documentation
Code to reproduce
Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.
The code block(s) should be formatted like:
/*You code here*/
Screenshot and/or video
If possible, add screenshots and/or videos about the current state.
Thanks @kisvegabor. Are there some drawing hooks that I can use to modify the rendering or do I actually need to modify the chart’s source code? (I let platformio to manage the LVGL library so local code modifications will break it).
As for for lv_line widget, can I make it displayed below the data graphs and major divisions and above the chart background? (Is it possible to tell the chart not to draw the background without incurring a significant rendering time due to the use of non opaque colors?).
Thanks @kisvegabor. I think this is what I am looking for. Will spend time trying to understand the example.
If I got it correctly, the hook doesn’t add division lines but just modify the look of some lines based on their ids. In other words, without the hook to the total number of vertical and horizontal lines will be the same and they will all be dash/broken lines. Is it so?
My upgrade to V8 is going slow so I decided to patch LVGL V7 to support minor division lines until I will complete the upgrade to V8. I took a different approach of using the minor division lines spec from the main background part and controlling the selection of the minor div lines using a user provided bit mask.
It looks good but has a minor artifact at the top of the chart because of the vertical minor division lines intersect with the top line of the frame and are drawn after it. I believe this will also happen with the callback approach of V8, unless it will also have some prioritization of the drawing of the div lines.
That’s a good point. Will this also solve the crossings, inside the chart area, of major and minor divisions, where the minor is drawn after the major?
Rendering all the minors before all the majors may give the cleanest outcome.
In v8 you could save all the major positions, make LVGL not render them, and on the last minor draw the majors. But - as LVGL is open source - you can add custom behaviour in the code directly too.
Yes, I think so. BTW, with this approach, will the user also be able to define zero division lines and once getting this callback render all the divisions manually?
Another approach would be to let the callback also specify the priority of the line (e.g. 0 to 3) such that in the first path LVGL draws only priority 0 and buffers the rest and then draws them in consecutive passes automatically. This way users don’t have to add logic to manage their buffered lines.
Interesting idea but I think an event before and after drawing all the div lines is more powerful. E.g. in some cases, you might want to draw skew, circular or radial division lines.
I’m thinking about sending the same event as for division line but instead of
obj_draw_dsc.line_dsc = &line_dsc; //Keep it to show that the event is related to lines
obj_draw_dsc.p1 = NULL;
obj_draw_dsc.p2 = NULL;
obj_draw_dsc.id = 0xFFFFFFFF;
to indicate these are not related to any specific line.
My understanding is that you want to encode two or more events types in the same callback signature. If so, how about a straight forward C encoding as an enum for the type and a matching union for the values? It will allow you to add more event types in the future in a straight forward way. Are there performance concerns?
BTW, you will also need to specify if each callback gets a copy of the original line_dsc (intuitive?) or the left over from previous call (confusing?).
Using an enum seems complicated because the widget types are independent but the enum should be shared. E.g. there is an event for the main part. lv_obj sends an event when it draws the background rectangle. The div lines f the chart also uses the line style fror the main part so they also send an event when the chart draws the div line. An enum could look like:
@kisvegabor, if having a enum will be confusing, not having it will be even more confusing since the enum doesn’t introduce the multiple cases of calling the callback but clarifies them.
Isn’t this enum similar to the PARTs enum where some values are used at the obj level and some at the chart and series levels? In that case, can’t this enum be defined near the PARTs enum?
Edit: BTW, having the enum will make it much easier for you to describe the various cases in the documentation.
Parts are independent of the widget type but with this enum we want to express the deepest widget-specific stuff.
Anyway, I agree that the current method is vague in some places.
I’m thinking about letting the widget register there values. E.g. DRAW_ARC_BG = lv_register_draw_part() but
It’s complicated for the Micropython binding
It’s not clear when to call these registrations s the widget types doesn’t have init functions
So in summary:
The current approach is vauge
The enums are hard to extend by inherited widget types
The dynamic registration is problematic for the above-mentioned reasons.
Let’s sleep on it, hopefully, we will get a good idea
If we stored the class of the sender object in lv_obj_draw_part_dsc_t we could use widget specific enum.
Examples for LV_EVENT_DRAW_PART_BEGIN events:
When the chart’s background is drawn. dsc->class_p == &lv_obj_class shows that now lv_obj draws and dsc->enum (stupid name, just for the example) can be DRAW_OBJ_...