State Visualization

Viewflow FSM includes built-in visualization capabilities to help you understand and communicate the structure of your state machines.

Basic Chart Generation

You can generate a visual representation of your FSM states and transitions using the chart() function:

from viewflow.fsm import chart
from myapp.flow import ReportFlow

# Generate DOT language representation
dot_graph = chart(ReportFlow.state_field)

# Print the DOT representation
print(dot_graph)

The chart() function returns a string in DOT language format, which can be rendered with tools like Graphviz.

Rendering in Django Views

To display a state machine chart in a Django view:

from django.http import HttpResponse
from viewflow.fsm import chart
from .flow import ReportFlow

def flow_chart_view(request):
    """Render the FSM chart as an HTTP response."""
    dot_graph = chart(ReportFlow.state_field)
    return HttpResponse(dot_graph, content_type='text/plain')

For a more practical application, you can use a package like pydot to convert the DOT representation to an image:

import pydot
from django.http import HttpResponse
from viewflow.fsm import chart
from .flow import ReportFlow

def flow_chart_image(request):
    """Render the FSM chart as a PNG image."""
    dot_graph = chart(ReportFlow.state_field)

    # Convert DOT to PNG using pydot
    graphs = pydot.graph_from_dot_data(dot_graph)
    graph = graphs[0]
    png_data = graph.create_png()

    return HttpResponse(png_data, content_type='image/png')

Chart Customization

You can customize the chart output by providing options to the chart() function:

from viewflow.fsm import chart
from .flow import ReportFlow

# Custom chart with specific attributes
dot_graph = chart(
    ReportFlow,
    title="Report Approval Process",
    node_options={'shape': 'box', 'style': 'filled', 'fillcolor': '#f5f5f5'},
    edge_options={'fontsize': '11'},
    graph_options={'rankdir': 'LR'}  # Left to right layout
)

Integration with Admin and Viewsets

The FSM visualization is automatically integrated with Django admin when using FlowAdminMixin and with viewsets when using FlowViewsMixin.

For admin integration, the chart is displayed on the change form page when the appropriate templates are included:

# admin.py
from django.contrib import admin
from viewflow.fsm import FlowAdminMixin
from .models import Report
from .flow import ReportFlow

@admin.register(Report)
class ReportAdmin(FlowAdminMixin, admin.ModelAdmin):
    flow_class = ReportFlow
    # ... other admin configuration ...

For viewset integration, the chart is available at the chart/ URL pattern:

# viewset.py
from viewflow.fsm import FlowViewsMixin
from viewflow.views import ModelViewSet
from .models import Report
from .flow import ReportFlow

class ReportViewSet(FlowViewsMixin, ModelViewSet):
    model = Report
    flow_class = ReportFlow
    # ... other viewset configuration ...

Understanding the Chart

The generated chart follows these visual conventions:

  • States: Represented as nodes (boxes or circles)
  • Transitions: Represented as directed edges (arrows) between states
  • Start State: Often highlighted with a different color
  • End States: Sometimes represented with double borders

This visualization helps developers, stakeholders, and users understand:

  1. All possible states in the system
  2. Valid transitions between states
  3. The overall flow of the process
  4. Potential deadends or circular paths

Example Chart Output

A simple FSM for a document review process might look like this in DOT language:

digraph {
    graph [rankdir=TB, size="8,8"];
    node [shape=box, style="filled", fillcolor="#f5f5f5", fontsize=10];
    edge [fontsize=9];

    NEW [label="NEW", fillcolor="#e1f5fe"];
    UNDER_REVIEW [label="UNDER REVIEW"];
    APPROVED [label="APPROVED"];
    REJECTED [label="REJECTED"];
    PUBLISHED [label="PUBLISHED", fillcolor="#e8f5e9"];

    NEW -> UNDER_REVIEW [label="submit"];
    UNDER_REVIEW -> APPROVED [label="approve"];
    UNDER_REVIEW -> REJECTED [label="reject"];
    APPROVED -> PUBLISHED [label="publish"];
    REJECTED -> NEW [label="revise"];
}

This represents a document flow where new documents are submitted for review, can be approved or rejected, and approved documents can be published.