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).

Sales Heatmap App

Navigation App

sales_heatmap_app.py - Sales correlation between products (ItemRuler x ItemRuler).

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.14.tar.gz (18.2 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.14-py3-none-any.whl (21.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sprintify_navigation-1.0.14.tar.gz
  • Upload date:
  • Size: 18.2 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.14.tar.gz
Algorithm Hash digest
SHA256 563758836e9de43546353e7c8ba9479f76835f8f3742e564c2508df2cc3b5d2b
MD5 6a21b19fb5169dabb8a97da0497f6bfc
BLAKE2b-256 a58df7f19e400594b32b809a80eace21a538ae51c2fd425d7b2cfd73daa151f1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for sprintify_navigation-1.0.14-py3-none-any.whl
Algorithm Hash digest
SHA256 cd36c50aed27b0a96ffd3cf29394474edc6b0cb4c3d156a9c840459c3348383f
MD5 4bb5807f08f0da43bb81c945b1ebe939
BLAKE2b-256 0c0c5f41a4b09fbd541ef31c451624e9c4e913026739b1620aadd7a7e89d5b69

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