Skip to content

performance: implement growing sparkline #53

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 14, 2022
Merged

performance: implement growing sparkline #53

merged 3 commits into from
Aug 14, 2022

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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants