Skip to content

Conversation

@bablokb
Copy link

@bablokb bablokb commented Jul 29, 2022

This PR addresses the second part of #48. It adds another parameter to the constructor (dyn_xpitch). If set to true, the xpitch is constant and the sparkline grows until it fills the defined width. This greatly reduces redrawing, since the drawing primitives are only recreated if necessary.

The default behavior (dyn_xpitch=True) will always fill the complete width, thus needing to delete+recreate all primitives for every value added (old behavior).

Note that once max_items were added to the sparkline, the behavior is identical.

I also added some other minor optimizations, like keeping track of y_top/y_bottom while adding values instead of calculating these limits every a time again when adding a value.

@tannewt tannewt requested a review from a team July 29, 2022 17:14
Copy link

@FoamyGuy FoamyGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Thank you for the improvements.

Tested successfully on Feather TFT. This script illustrates the difference pretty well:

import random import time import board import displayio import terminalio from adafruit_display_text import label from adafruit_display_shapes.sparkline import Sparkline from adafruit_display_shapes.line import Line from adafruit_display_shapes.rect import Rect display = board.DISPLAY ########################################## # Create background bitmaps and sparklines ########################################## # Baseline size of the sparkline chart, in pixels. chart_width = display.width - 40 chart_height = display.height - 40 font = terminalio.FONT line_color = 0xFFFFFF # Setup the first bitmap and sparkline # This sparkline has no background bitmap # mySparkline1 uses a vertical y range between 0 to 10 and will contain a # maximum of 40 items sparkline1 = Sparkline( width=chart_width, height=chart_height, max_items=40, y_min=0, y_max=10, x=20, y=20, dyn_xpitch=False, color=line_color, ) # Label the y-axis range text_xoffset = -10 text_label1a = label.Label( font=font, text=str(sparkline1.y_top), color=line_color ) # yTop label text_label1a.anchor_point = (1, 0.5) # set the anchorpoint at right-center text_label1a.anchored_position = ( sparkline1.x + text_xoffset, sparkline1.y, ) # set the text anchored position to the upper right of the graph text_label1b = label.Label( font=font, text=str(sparkline1.y_bottom), color=line_color ) # yTop label text_label1b.anchor_point = (1, 0.5) # set the anchorpoint at right-center text_label1b.anchored_position = ( sparkline1.x + text_xoffset, sparkline1.y + chart_height, ) # set the text anchored position to the upper right of the graph bounding_rectangle = Rect( sparkline1.x, sparkline1.y, chart_width, chart_height, outline=line_color ) # Create a group to hold the sparkline, text, rectangle and tickmarks # append them into the group (my_group) # # Note: In cases where display elements will overlap, then the order the # elements are added to the group will set which is on top. Latter elements # are displayed on top of former elemtns. my_group = displayio.Group() my_group.append(sparkline1) my_group.append(text_label1a) my_group.append(text_label1b) my_group.append(bounding_rectangle) total_ticks = 10 for i in range(total_ticks + 1): x_start = sparkline1.x - 5 x_end = sparkline1.x y_both = int(round(sparkline1.y + (i * (chart_height) / (total_ticks)))) if y_both > sparkline1.y + chart_height - 1: y_both = sparkline1.y + chart_height - 1 my_group.append(Line(x_start, y_both, x_end, y_both, color=line_color)) # Set the display to show my_group that contains the sparkline and other graphics display.show(my_group) # Start the main loop while True: # Turn off auto_refresh to prevent partial updates of the screen during updates # of the sparkline drawing display.auto_refresh = False # add_value: add a new value to a sparkline # Note: The y-range for mySparkline1 is set to 0 to 10, so all these random # values (between 0 and 10) will fit within the visible range of this sparkline sparkline1.add_value(random.uniform(0, 10)) if len(sparkline1.values()) > sparkline1._max_items-1: sparkline1.clear_values() # Turn on auto_refresh for the display display.auto_refresh = True # The display seems to be less jittery if a small sleep time is provided # You can adjust this to see if it has any effect time.sleep(0.01) 
@FoamyGuy FoamyGuy merged commit bcd9e5c into adafruit:main Aug 14, 2022
adafruit-adabot added a commit to adafruit/Adafruit_CircuitPython_Bundle that referenced this pull request Aug 15, 2022
Updating https://github.com/adafruit/Adafruit_CircuitPython_IS31FL3741 to 1.3.4 from 1.3.3: > Merge pull request adafruit/Adafruit_CircuitPython_IS31FL3741#19 from tekktrik/dev/use-protocol-typing Updating https://github.com/adafruit/Adafruit_CircuitPython_LIS3MDL to 1.1.19 from 1.1.18: > Merge pull request adafruit/Adafruit_CircuitPython_LIS3MDL#21 from tekktrik/dev/add-typing Updating https://github.com/adafruit/Adafruit_CircuitPython_datetime to 1.2.0 from 1.1.10: > Merge pull request adafruit/Adafruit_CircuitPython_datetime#20 from tekktrik/fix/fix-dst-error Updating https://github.com/adafruit/Adafruit_CircuitPython_Display_Shapes to 2.5.3 from 2.5.2: > Merge pull request adafruit/Adafruit_CircuitPython_Display_Shapes#53 from bablokb/sparkline_opt2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants