Flowcharting / README.md
westland's picture
Add USER_MANUAL.md and expand README.md with detailed math and architecture
9970a69
|
Raw
History Blame Contribute Delete
7.34 kB

A newer version of the Streamlit SDK is available: 1.60.0

Upgrade
metadata
title: B&W Flowchart Sketcher
emoji: ๐Ÿ“Š
colorFrom: gray
colorTo: gray
sdk: streamlit
sdk_version: 1.35.0
app_file: app.py
pinned: false
license: mit

B&W Flowchart Sketcher (Web & Desktop)

A premium, interactive utility to sketch clean, high-contrast, black-and-white flowcharts. This repository bundles two interfaces:

  1. Interactive Tkinter Desktop App (flowchart_app.py): Supports canvas drag-and-drop node adjustments, visual drafting gridlines, and project serialization.
  2. Streamlit Web Application (app.py): Designed for cloud deployment (Hugging Face Spaces) with interactive slider coordinates for node tuning.

๐Ÿ“– Table of Contents


๐Ÿ—๏ธ Architecture & Schema Design

Both the desktop and web clients rely on a shared data schema managed by a backend model:

  +------------------+       +---------------------+
  |   Desktop GUI    |       |       Web GUI       |
  | (flowchart_app)  |       |      (app.py)       |
  +--------+---------+       +----------+----------+
           |                            |
           +-------------+--------------+
                         |
                         v
             +-----------+-----------+
             |   FlowchartModel      |
             |   - nodes {}          |
             |   - edges []          |
             +-----------+-----------+
                         |
           +-------------+-------------+
           |                           |
           v                           v
  +--------+--------+         +--------+--------+
  |  Pillow Export  |         |  JSON Project   |
  | (Vector-like)   |         |  Save/Load      |
  +-----------------+         +-----------------+
  • Node: Houses coordinates (x, y), dimension bounding boxes (w, h) matched to the shape, designation (short ID), shape name, and description.
  • Edge: Houses connectivity mappings (u -> v) and styling properties (style = straight/curved/dotted).
  • FlowchartModel: Provides path parsing (e.g. A -> B -> C), topological sorting layout, and JSON imports/exports.

๐Ÿ“ Mathematical Engine (Shapes & Ray Intersection)

To produce professional-grade diagrams, connector lines and arrowheads must terminate precisely at the boundary of a node shape, rather than drawing to its coordinate center (which causes overlaps).

The mathematical engine calculates boundary intersections for every shape dynamically:

1. Ellipses (Circles & Ovals)

An oval centered at $(x_c, y_c)$ with semi-axes $a$ (horizontal radius) and $b$ (vertical radius) satisfies: (xโˆ’xc)2a2+(yโˆ’yc)2b2=1\frac{(x - x_c)^2}{a^2} + \frac{(y - y_c)^2}{b^2} = 1

To find where a ray in direction $(dx, dy)$ intersects the boundary, we solve for $t$: t=1dx2a2+dy2b2t = \frac{1}{\sqrt{\frac{dx^2}{a^2} + \frac{dy^2}{b^2}}} The boundary intersection point is $(x_c + t \cdot dx, y_c + t \cdot dy)$.

2. Polygons (Squares, Diamonds, Inverted Triangles)

For shapes represented by vertices, we cast a ray from the center $(x_c, y_c)$ to $(x_c + 10000 \cdot dx, y_c + 10000 \cdot dy)$ to ensure it crosses the boundary. We perform 2D segment-segment intersection against all edges of the polygon.

Given ray segment $AB$ and polygon edge $CD$: Pint=A+t(Bโˆ’A)=C+u(Dโˆ’C)P_{int} = A + t(B - A) = C + u(D - C) Solving this linear system yields parameters $t$ and $u$. An intersection is valid if $0 \le t \le 1$ and $0 \le u \le 1$.

3. Curved Connector Splines

Curved connectors are drawn using quadratic Bezier curves parameterized by $t \in [0, 1]$: B(t)=(1โˆ’t)2Pstart+2(1โˆ’t)tPctrl+t2PendB(t) = (1-t)^2 P_{start} + 2(1-t)t P_{ctrl} + t^2 P_{end}

  • The control point $P_{ctrl}$ is computed by taking the midpoint of the node centers and offsetting it perpendicularly by 45 pixels.
  • The boundary points $P_{start}$ and $P_{end}$ are computed using the ray-casting intersection formulas directed at $P_{ctrl}$.
  • The arrowhead at $P_{end}$ is drawn aligned to the tangent vector $P_{end} - P_{ctrl}$, which represents the instantaneous direction of the curve at $t=1$.

๐Ÿงฎ Hierarchical Auto-Layout Solver

The layout solver uses a Layered Hierarchical Graph Layout algorithm:

  1. In-Degree Calculation: Build an adjacency list and count incoming edges for every node.
  2. Topological Leveling (BFS): Node levels are assigned. Nodes with in-degree = 0 start at Level 0. Outgoing neighbors are pushed to Level $L + 1$. Loops or cycles are broken by selecting a starter node when in-degrees are cyclic.
  3. Coordinate Allocation:
    • Levels are mapped to vertical coordinates ($Y$-coordinate) spaced 140px apart.
    • Nodes within the same level are sorted alphabetically (to ensure layout stability) and distributed symmetrically along the horizontal center ($X$-coordinate) with 150px spacing.

โœ๏ธ Consistent Text-Wrapping Engine

Because Tkinter Canvas and Pillow use different text-rendering engines, we implemented a custom, unified word-wrapper:

  • Font metrics are queried dynamically using font.measure in Tkinter and draw.textlength in Pillow.
  • The wrapper walks through the description, building text lines word-by-word. It splits to a new line as soon as the measured width exceeds the shape's specific maximum text boundaries.
  • Maximum margins are customized for each shape to prevent text from overflowing corners (e.g. diamonds restrict width to $58%$ of node width, whereas squares allow up to $82%$).

๐ŸŽจ Pillow Cropping & Vector-Like Rendering

When exporting a PNG:

  1. The app calculates the bounding box of the entire flowchart: $$x_{min} = \min(x_i - w_i/2),\quad x_{max} = \max(x_i + w_i/2)$$ $$y_{min} = \min(y_i - h_i/2),\quad y_{max} = \max(y_i + h_i/2)$$
  2. It expands this box by a 50px margin on all sides.
  3. The Pillow engine creates an image matching these exact cropped dimensions and applies a coordinate offset of $-(x_{min} - \text{margin}), -(y_{min} - \text{margin})$ to all drawing routines.
  4. Shapes are rendered with crisp black borders, clean fills, and drop shadows offset by $+4\text{px}$ in light-gray, generating a beautiful modern aesthetic.

๐Ÿš€ Getting Started

Prerequisites

Ensure Python is installed and fetch dependencies:

pip install Pillow streamlit

Running the Desktop Application

python flowchart_app.py

Running the Web Application Locally

streamlit run app.py

๐ŸŒ Deployment on Hugging Face

This project is pre-configured for Hugging Face Spaces using the Streamlit SDK.

  1. Create a new Space on Hugging Face and choose the Streamlit SDK.
  2. Link your local directory to the Git remote of the Space:
    git remote add origin https://huggingface.co/spaces/your-username/your-space-name
    
  3. Push to Hugging Face:
    git push -u origin main --force