Skip to main content

A navigation widget based on PySide6

Project description

Sprintify Navigation

A navigation widget for PySide6 that handles large datasets efficiently. Built for interactive time-series visualization, Gantt charts, stock data, heatmaps - anything that needs smooth pan/zoom.

Sprintify Navigation Demo

## What it does
  • A toolbox to build specialized interactive navigation UIs
  • Easy to understand for AIs and humans
  • Built for time-series, Gantt charts, stock data, heatmaps, scatter plots, and more
  • Smooth pan/zoom with mouse wheel and drag
  • Renders only visible data (handles millions of points)
  • Dark/light mode through ColorMap
  • Mouse wheel pan/zoom, click-drag pan
  • Simple drawing API for rects, lines, text, or custom QPainter

Get started

pip install sprintify-navigation

Basic usage:

from sprintify.navigation.colors.modes import ColorMap
from sprintify.navigation.rulers import TimelineRuler, NumberRuler
from sprintify.navigation.navigation_widget import NavigationWidget
from PySide6.QtWidgets import QMainWindow, QApplication
from PySide6.QtGui import QBrush, QPen
from datetime import datetime, timedelta


class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.color_map = ColorMap(darkmode=True)

        # Setup rulers
        self.h_ruler = TimelineRuler(datetime(2024, 1, 1), datetime(2024, 12, 31))
        self.v_ruler = NumberRuler(0, 100, reverse=True)

        # Create widget
        self.widget = NavigationWidget(self.h_ruler, self.v_ruler, self.color_map)
        self.setCentralWidget(self.widget)

        # Draw stuff
        blue = self.color_map.get_saturated_color("blue", "fill")
        self.widget.draw_rects(
            "my_rects",
            lambda: [
                (datetime(2024, 3, 1), 20, timedelta(days=30), 15),
                (datetime(2024, 6, 1), 50, timedelta(days=45), 20),
            ],
            brush=QBrush(blue)
        )


if __name__ == "__main__":
    app = QApplication([])
    window = MyWindow()
    window.show()
    app.exec()

Examples

Check the examples/ folder for complete working apps:

Stock App

Stock App

stock_app.py - Real stock data via yfinance.

Scheduling App

Scheduling App

scheduling_app.py - Employee shifts (200 people, ItemRuler usage).

Navigation App

Navigation App

navigation_app.py - Random lines and Squares

Rulers

TimelineRuler

Date/time on horizontal axis. Auto-formats years/months/days/hours depending on zoom.

ruler = TimelineRuler(datetime(2024, 1, 1), datetime(2024, 12, 31))

NumberRuler

Numeric axis with SI units (k, M, G, etc). Can reverse for top-to-bottom.

ruler = NumberRuler(0, 10000, reverse=False)

ItemRuler

Categorical data - one band per item (employees, stocks, products, etc).

ruler = ItemRuler(
    item_count=100,
    default_pixels_per_item=40,
    min_pixels_per_item=20,
    max_pixels_per_item=150
)

Drawing

Rectangles

widget.draw_rects("layer_name", get_rects_func, brush=QBrush(color), pen=QPen(border))
# get_rects_func returns [(x, y, width, height), ...]

Lines

widget.draw_lines("layer_name", get_lines_func, pen=QPen(color, width))
# get_lines_func returns [(x1, y1, x2, y2), ...]

Text

widget.draw_texts("layer_name", get_texts_func, pen=QPen(color), font=QFont("Arial", 12))
# get_texts_func returns [(text, x, y), ...]

Custom drawing

def my_draw(painter):
    painter.setPen(QPen(Qt.red, 2))
    painter.drawEllipse(x, y, w, h)

widget.add_draw_command("custom", my_draw)

Colors

ColorMap handles theming:

color_map = ColorMap(darkmode=True)

# UI colors
bg = color_map.get_object_color("surface-base")
border = color_map.get_object_color("border")
text = color_map.get_object_color("text-base")

# Data viz colors
red = color_map.get_saturated_color("red", "fill")
blue = color_map.get_saturated_color("blue", "border")

Available: red, green, blue, cyan, orange, purple, pink, teal, lime, amber, grey

Controls

  • Wheel: Pan horizontal/vertical
  • Ctrl+Wheel: Zoom at mouse position
  • Alt+Wheel: Zoom vertical axis (NumberRuler only)
  • Click+Drag: Pan both axes

Performance tips

Only fetch visible data:

def get_visible_rects():
    start = self.h_ruler.visible_start
    end = self.h_ruler.visible_stop
    
    return [
        (x, y, w, h) 
        for x, y, w, h in all_data 
        if x + w >= start and x <= end
    ]

widget.draw_rects("rects", get_visible_rects, brush=QBrush(color))

Custom labels

ruler = ItemRuler(item_count=50)
widget = NavigationWidget(h_ruler, ruler, color_map)
widget.left_ruler_widget.get_label = lambda i: f"Employee {i+1}"

Ruler combinations

Mix rulers for different visualizations:

# Gantt chart
NavigationWidget(TimelineRuler(...), ItemRuler(...), color_map)

# Stock chart
NavigationWidget(TimelineRuler(...), NumberRuler(...), color_map)

# Correlation matrix
NavigationWidget(ItemRuler(...), ItemRuler(...), color_map)

# Scatter plot
NavigationWidget(NumberRuler(...), NumberRuler(...), color_map)

Architecture

Simple model-view split:

  • Rulers: Handle coordinate transforms, zoom, pan math
  • RulerWidgets: Render ticks/labels, handle mouse events
  • DrawingWidget: Canvas for data visualization
  • NavigationWidget: Composite putting it all together

Requirements

  • Python 3.8+
  • PySide6
  • yfinance (optional, only for stock example)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sprintify_navigation-1.0.13.tar.gz (18.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sprintify_navigation-1.0.13-py3-none-any.whl (20.9 kB view details)

Uploaded Python 3

File details

Details for the file sprintify_navigation-1.0.13.tar.gz.

File metadata

  • Download URL: sprintify_navigation-1.0.13.tar.gz
  • Upload date:
  • Size: 18.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.12.3

File hashes

Hashes for sprintify_navigation-1.0.13.tar.gz
Algorithm Hash digest
SHA256 f7693d1cffd0151f703f69f58a2e879a53d2b716c3938a3abcc4e9dffada431d
MD5 010c96932b69ddaf59b6a1399c395cbf
BLAKE2b-256 69d4ac64636668785b7829b893a73f91fd83550db0602cb6c786b21b00a272f4

See more details on using hashes here.

File details

Details for the file sprintify_navigation-1.0.13-py3-none-any.whl.

File metadata

File hashes

Hashes for sprintify_navigation-1.0.13-py3-none-any.whl
Algorithm Hash digest
SHA256 2d313cf65fbd0baf8424bb855fc667898296acad1d07eedd359f313ecde0d266
MD5 58f529e11dc4ea1d9475986f2119ba43
BLAKE2b-256 be6491eb25494ca163121fb168610f324a0ecf4ea0823304a215869c8b970547

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page