draw/graphviz
PHP library for generating and rendering Graphviz DOT graphs. Build graphs programmatically, export DOT, and produce images (PNG/SVG/PDF) via the Graphviz CLI, with support for nodes, edges, attributes, and layouts for diagrams and dependency graphs.
Installation Add the package via Composer:
composer require mpoiriert/graphviz
Require the package in your project:
use Mpoiriert\Graphviz\Graphviz;
First Use Case: Basic Graph Creation Create a simple directed graph:
$graph = new Graphviz();
$graph->setType('digraph'); // or 'graph' for undirected
$graph->addNode('A');
$graph->addNode('B');
$graph->addEdge('A', 'B');
echo $graph->getDot();
Outputs:
digraph G {
A;
B;
A -> B;
}
Where to Look First
src/Graphviz.php for methods like addNode(), addEdge(), and setType().Dynamic Graph Generation Useful for visualizing Laravel relationships (e.g., Eloquent models, route maps):
$graph = new Graphviz();
$graph->setType('digraph')
->setLabel('Laravel Route Graph');
foreach (Route::getRoutes() as $route) {
$graph->addNode($route->uri(), ['label' => $route->methods()[0]]);
}
Integration with Blade Render graphs directly in views:
// In a controller
$graph = (new Graphviz())->addNode('Home')->addNode('About')->addEdge('Home', 'About');
return view('graph', ['dot' => $graph->getDot()]);
<!-- In a Blade template -->
<pre>{{ $dot }}</pre>
Custom Styling Apply attributes to nodes/edges for visual distinction:
$graph->addNode('Admin', ['shape' => 'box', 'style' => 'filled', 'color' => 'red']);
$graph->addEdge('Admin', 'User', ['label' => 'has_many', 'color' => 'blue']);
Debugging Relationships
Generate DOT files for Eloquent models to visualize belongsTo, hasMany, etc.:
$graph = new Graphviz();
$graph->setType('digraph')
->setLabel('User Model Relationships');
$graph->addNode('User', ['shape' => 'ellipse']);
$graph->addNode('Post', ['shape' => 'ellipse']);
$graph->addEdge('User', 'Post', ['label' => 'hasMany']);
// Save to file
file_put_contents('user_relationships.dot', $graph->getDot());
API Documentation Use graphs to visualize API endpoints and their relationships:
$graph = new Graphviz();
$graph->setType('digraph')
->setLabel('API Endpoints');
$graph->addNode('/users', ['shape' => 'folder']);
$graph->addNode('/users/{id}', ['shape' => 'box']);
$graph->addEdge('/users', '/users/{id}', ['label' => 'GET']);
Graphviz Binary
Ensure the Graphviz CLI tools are installed to render .dot files:
dot -Tpng input.dot -o output.png
Automate this in Laravel with Artisan commands or queues.
Storage
Store generated DOT files in storage/app/graphs/ and serve them via Laravel’s filesystem:
$path = storage_path('app/graphs/example.dot');
file_put_contents($path, $graph->getDot());
Testing Test graph generation in PHPUnit by comparing DOT output:
public function testGraphGeneration()
{
$graph = new Graphviz();
$graph->addNode('Test');
$this->assertStringContainsString('Test;', $graph->getDot());
}
No Automatic Rendering
The package only generates DOT syntax; you must use Graphviz’s CLI or a library like graphviz-php to render images. Example:
// ❌ Won't work (DOT-only)
$graph->renderToPng(); // Method does not exist
DOT Syntax Quirks
$graph->addNode('Node with "quotes"', ['label' => 'Node\\ with\\ "quotes"']);
\\n for multi-line labels:
$graph->addNode('Multi\nLine', ['label' => 'Multi\\nLine']);
Performance Avoid generating thousands of nodes in a single graph; DOT files can become unwieldy. For large graphs:
subgraph cluster_* syntax:
$graph->addSubgraph('cluster_users', [
'A', 'B', 'C'
]);
Validate DOT Output Use Graphviz’s online DOT editor to test generated DOT files before integration.
Common Errors
dot -Tplain -o /dev/null input.dot # Checks for syntax errors
addNode() and addEdge() calls. Example:
$graph->addEdge('A', 'B'); // ❌ Fails if 'B' wasn’t added as a node
Reuse Graphs
Extend Graphviz for domain-specific graphs:
class EloquentGraph extends Graphviz {
public function addModel(string $model, array $attributes = []): self {
$this->addNode(class_basename($model), $attributes);
return $this;
}
}
Laravel Service Provider Bind the package for easy access:
// In AppServiceProvider
$this->app->singleton(Graphviz::class, function () {
return new Graphviz();
});
Now inject Graphviz anywhere:
public function __construct(private Graphviz $graph) {}
Dynamic Attributes
Use compact() to dynamically set node/edge attributes:
$attributes = compact('label', 'shape', 'color');
$graph->addNode('Node', $attributes);
Cluster Subgraphs Group related nodes for cleaner visuals:
$graph->addSubgraph('cluster_admin', [
'Admin', 'User', 'Role'
], [
'label' => 'Admin Panel',
'style' => 'filled',
'color' => 'lightgrey'
]);
Version Compatibility
The package has no dependencies beyond PHP, but test with PHP 8.0+ for type safety. If using older PHP, ensure Graphviz class methods are called statically or via instantiation.
How can I help you explore Laravel packages today?