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 import NavigationWidget, ColorMap, TimelineRuler, NumberRuler
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.11.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.11-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sprintify_navigation-1.0.11.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.11.tar.gz
Algorithm Hash digest
SHA256 d7050977be3a5fdef75b9c9902c08ff4bf8d93c8115720bcfc770c02ea633d30
MD5 f8fed3601fd785eba06ecd85fe11d2d0
BLAKE2b-256 b9bc6422d4890f98010e8e45185342fb93fcef9d3fd97132f1c593976cb27608

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sprintify_navigation-1.0.11-py3-none-any.whl
Algorithm Hash digest
SHA256 2f91766a2812b267c7e218e2b936f2fa640ceda7f22724ce6bc1397ce68311d9
MD5 3a8781aaaa343b4c078e1dbe1b22c477
BLAKE2b-256 25f34e062c132830cd9b78d824db74b6c81c1057e9c8328ced326be961e0b23c

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