forked from ladyada/Adafruit_CircuitPython_Display_Shapes
-
Notifications
You must be signed in to change notification settings - Fork 18
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
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FoamyGuy
approved these changes
Aug 14, 2022
There was a problem hiding this 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)
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
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.