A powerful and elegant Filament widget plugin for creating interactive organizational charts. Built on top of Highcharts, this package provides a fluent API for visualizing your company's hierarchy with style.
- π¨ Beautiful & Interactive - Smooth, responsive charts with hover effects and animations
- ποΈ Fluent Builder API - Intuitive, chainable methods for building complex hierarchies
- π€ Employee Profiles - Support for profile images, titles, and custom styling
- π― Fully Customizable - Control colors, layout, height, and orientation
- π± Responsive Design - Works seamlessly on desktop, tablet, and mobile
- π Multi-language - Built-in support for English and Arabic (easily extensible)
- β Smart Validation - Automatic error checking and helpful debugging tools
- π Database Ready - Easily integrate with Eloquent models
- π¨ Artisan Command - Quick scaffold widgets with
make:organization-chart
- Requirements
- Installation
- Quick Start
- Usage Examples
- API Reference
- Customization
- Building from Source
- Contributing
- License
- PHP: 8.1 or higher
- Laravel: 10.x or 11.x or 12.x
- Filament: 3.x or 4.x
- Composer: 2.x
composer require yacoubalhaidari/organization-chartThe package assets are automatically published during installation. If needed, you can republish them:
php artisan filament:assetsUse the artisan command to scaffold a new organization chart widget:
php artisan make:organization-chart CompanyOrgChartThis creates a ready-to-use widget at app/Filament/Widgets/CompanyOrgChartWidget.php.
Add the widget to your Filament Panel Provider (e.g., app/Providers/Filament/AdminPanelProvider.php):
use App\Filament\Widgets\CompanyOrgChartWidget;
public function panel(Panel $panel): Panel
{
return $panel
->widgets([
CompanyOrgChartWidget::class,
]);
}That's it! π Visit your Filament dashboard to see your organization chart.
Generate a widget with pre-configured examples:
php artisan make:organization-chart MyCompanyThis creates a widget with:
- 4 executive-level positions (CEO, CTO, CFO, COO)
- Profile images and custom colors
- Commented examples for departments and teams
- Best practices and proper structure
Alternatively, create a widget manually:
<?php
namespace App\Filament\Widgets;
use YacoubAlhaidari\OrganizationChart\OrganizationChartWidget;
use YacoubAlhaidari\OrganizationChart\OrganizationChartBuilder;
class CompanyOrgChart extends OrganizationChartWidget
{
protected string $view = 'organization-chart::widget-without-description';
public function mount(): void
{
$builder = OrganizationChartBuilder::make()
->title('Company Structure')
->height(700)
->inverted(true);
$builder->executiveLevel([
['CEO', 'CTO'],
['CEO', 'CFO'],
]);
$builder->executiveNodes([
[
'id' => 'CEO',
'title' => 'Chief Executive Officer',
'name' => 'Your Name',
'color' => '#6366f1',
],
[
'id' => 'CTO',
'title' => 'Chief Technology Officer',
'name' => 'Tech Director',
'color' => '#3b82f6',
],
[
'id' => 'CFO',
'title' => 'Chief Financial Officer',
'name' => 'Finance Director',
'color' => '#10b981',
],
]);
$this->builder($builder);
}
}public function mount(): void
{
$builder = OrganizationChartBuilder::make()
->title('Our Company')
->height(600)
->inverted(true)
->executiveLevel([
['CEO', 'CTO'],
['CEO', 'CFO'],
['CEO', 'COO'],
])
->executiveNodes([
[
'id' => 'CEO',
'title' => 'Chief Executive Officer',
'name' => 'Sarah Johnson',
'image' => 'https://i.pravatar.cc/150?img=1',
'color' => '#6366f1',
],
[
'id' => 'CTO',
'title' => 'CTO',
'name' => 'Michael Chen',
'image' => 'https://i.pravatar.cc/150?img=2',
'color' => '#3b82f6',
],
[
'id' => 'CFO',
'title' => 'CFO',
'name' => 'Emily Davis',
'color' => '#10b981',
],
[
'id' => 'COO',
'title' => 'COO',
'name' => 'David Martinez',
'color' => '#f59e0b',
],
]);
$this->builder($builder);
}public function mount(): void
{
$builder = OrganizationChartBuilder::make()
->title('Complete Organization')
->height(800)
// Executives
->executiveLevel([
['CEO', 'CTO'],
['CEO', 'VP Sales'],
])
->executiveNodes([
['id' => 'CEO', 'name' => 'CEO', 'title' => 'Chief Executive Officer'],
['id' => 'CTO', 'name' => 'CTO', 'color' => '#3b82f6'],
['id' => 'VP Sales', 'name' => 'VP Sales', 'color' => '#10b981'],
])
// Departments
->departments([
['CTO', 'Engineering Dept'],
['CTO', 'Product Dept'],
['VP Sales', 'Sales Dept'],
])
->departmentNodes([
['id' => 'Engineering Dept', 'name' => 'Engineering'],
['id' => 'Product Dept', 'name' => 'Product'],
['id' => 'Sales Dept', 'name' => 'Sales'],
])
// Teams
->teams([
['Engineering Dept', 'Frontend Team'],
['Engineering Dept', 'Backend Team'],
])
->teamNodes([
['id' => 'Frontend Team', 'name' => 'Frontend'],
['id' => 'Backend Team', 'name' => 'Backend'],
]);
$this->builder($builder);
}public function mount(): void
{
$executives = Employee::where('level', 'executive')
->with('manager')
->get();
$builder = OrganizationChartBuilder::make()
->title('Company Hierarchy')
->height(700)
->executiveLevel(
$executives->map(fn($e) => [
$e->manager?->name ?? 'Board',
$e->name
])->toArray()
)
->executiveNodes(
$executives->map(fn($e) => [
'id' => $e->name,
'title' => $e->job_title,
'name' => $e->full_name,
'image' => $e->avatar_url,
'color' => $e->department_color,
])->toArray()
);
$this->builder($builder);
}public function mount(): void
{
$builder = OrganizationChartBuilder::make()
->title('Horizontal Organization')
->height(500)
->inverted(false) // Horizontal layout
->executiveLevel([
['Board', 'President'],
['President', 'VP Operations'],
['President', 'VP Marketing'],
])
->executiveNodes([
['id' => 'Board', 'name' => 'Board of Directors'],
['id' => 'President', 'name' => 'President'],
['id' => 'VP Operations', 'name' => 'VP Operations'],
['id' => 'VP Marketing', 'name' => 'VP Marketing'],
]);
$this->builder($builder);
}| Command | Description | Example |
|---|---|---|
make:organization-chart |
Generate a new widget | php artisan make:organization-chart CompanyChart |
Command Usage:
# Create a widget named CompanyOrgChartWidget
php artisan make:organization-chart CompanyOrgChart
# Create a widget named TeamStructureWidget
php artisan make:organization-chart TeamStructure
# Widget suffix is added automatically
php artisan make:organization-chart Sales # Creates SalesWidget.php| Method | Parameters | Default | Description |
|---|---|---|---|
title() |
string $title |
'Organization Chart' |
Set chart title |
height() |
int $pixels |
700 |
Set height in pixels |
inverted() |
bool $inverted |
true |
Vertical (true) or horizontal (false) |
Example:
$builder->title('My Company')
->height(800)
->inverted(true);| Method | Description | Returns |
|---|---|---|
executiveLevel(array $relationships) |
Define top-level relationships | self |
departments(array $relationships) |
Define department relationships | self |
teams(array $relationships) |
Define team relationships | self |
Relationship Format: [['parentId', 'childId'], ...]
Example:
$builder->executiveLevel([
['CEO', 'CTO'],
['CEO', 'CFO'],
])
->departments([
['CTO', 'Engineering Dept'],
['CFO', 'Finance Dept'],
]);| Method | Description | Level |
|---|---|---|
executiveNodes(array $nodes) |
Define executive details | Executive |
departmentNodes(array $nodes) |
Define department details | Department |
teamNodes(array $nodes) |
Define team details | Team |
nodes(array $nodes) |
Define all nodes at once | All |
Node Properties:
| Property | Type | Required | Description | Example |
|---|---|---|---|---|
id |
string |
β Yes | Unique identifier | 'CEO' |
name |
string |
β Yes | Display name | 'John Smith' |
title |
string |
No | Job title | 'Chief Executive Officer' |
image |
string |
No | Profile photo URL | 'https://example.com/photo.jpg' |
color |
string |
No | Hex color | '#3b82f6' |
column |
int |
No | Column position | 0, 1, 2 |
Example:
$builder->executiveNodes([
[
'id' => 'CEO',
'name' => 'John Smith',
'title' => 'Chief Executive Officer',
'image' => 'https://example.com/ceo.jpg',
'color' => '#6366f1',
],
]);| Method | Returns | Description |
|---|---|---|
validate() |
array |
Check for errors |
getMissingNodes() |
array |
Get missing node IDs |
getAllRequiredIds() |
array |
Get all required IDs |
getSummary() |
array |
Get statistics |
Example:
$builder = OrganizationChartBuilder::make()
->executiveLevel([['CEO', 'CTO']])
->executiveNodes([
['id' => 'CEO', 'name' => 'CEO'],
]);
$validation = $builder->validate();
// Returns: ['valid' => false, 'errors' => ['Missing node: CTO']]
$missing = $builder->getMissingNodes();
// Returns: ['CTO']Use the alternative view without description:
protected string $view = 'organization-chart::widget-without-description';->executiveNodes([
['id' => 'CEO', 'name' => 'CEO', 'color' => '#6366f1'], // Indigo
['id' => 'CTO', 'name' => 'CTO', 'color' => '#3b82f6'], // Blue
['id' => 'CFO', 'name' => 'CFO', 'color' => '#10b981'], // Green
])->executiveNodes([
[
'id' => 'CEO',
'name' => 'Sarah Johnson',
'image' => asset('storage/avatars/ceo.jpg'),
],
])Publish and customize translation files:
php artisan vendor:publish --tag=organization-chart-translationsEdit in:
lang/vendor/organization-chart/en/widget.php(English)lang/vendor/organization-chart/ar/widget.php(Arabic)
Control widget width:
class CompanyOrgChart extends OrganizationChartWidget
{
protected int | string | array $columnSpan = 'full'; // Full width
// Or specific spans:
// protected int | string | array $columnSpan = 2;
}If you're contributing or want to build assets from source:
- Node.js 16.x or higher
- NPM 8.x or higher
# Navigate to package directory
cd packages/organization-chart
# Install dependencies
npm install
# Build assets (production)
npm run build
# Or watch for changes (development)
npm run dev| Command | Description |
|---|---|
npm run build |
Build CSS and JS for production |
npm run build:css |
Build CSS only |
npm run build:js |
Build JS only |
npm run dev |
Same as build (no watch mode) |
Publish the updated assets to your Filament application:
# From your Laravel project root
php artisan filament:assetspackages/organization-chart/
βββ src/
β βββ Commands/
β β βββ MakeOrganizationChartCommand.php
β βββ OrganizationChartServiceProvider.php
β βββ OrganizationChartWidget.php
β βββ OrganizationChartBuilder.php
βββ resources/
β βββ js/
β β βββ organization-chart.js # Source JavaScript
β βββ css/
β β βββ organization-chart.css # Source CSS
β βββ dist/ # Compiled assets
β β βββ organization-chart.js
β β βββ organization-chart.css
β βββ views/
β β βββ widget.blade.php
β β βββ widget-without-description.blade.php
β βββ lang/
β βββ en/widget.php
β βββ ar/widget.php
βββ composer.json
βββ package.json
βββ build.js # esbuild configuration
βββ postcss.config.js # PostCSS configuration
βββ README.md
Problem: Widget shows but chart is blank.
Solutions:
- Clear cache:
php artisan optimize:clear - Republish assets:
php artisan filament:assets - Check browser console for JavaScript errors
- Verify Highcharts is loaded
Problem: Relationships reference undefined IDs.
Solution: Use validation to find issues:
$missing = $builder->getMissingNodes();
// Returns array of missing node IDsProblem: Styles or JavaScript not working.
Solutions:
- Re-publish:
php artisan filament:assets --force - Clear browser cache (Ctrl+F5)
- Check public directory permissions
- Verify assets exist in
public/js/yacoubalhaidari/andpublic/css/yacoubalhaidari/
Contributions are welcome! Here's how you can help:
- Fork the repository
- Clone your fork
- Install dependencies:
composer install && npm install - Make your changes
- Build assets:
npm run build - Test your changes
- Submit a pull request
- Follow PSR-12 coding standards
- Write clear commit messages
- Add tests for new features
- Update documentation as needed
- Ensure assets build without errors
Please open an issue on GitHub with:
- Clear description of the problem
- Steps to reproduce
- Expected vs actual behavior
- Environment details (PHP, Laravel, Filament versions)
This package is open-sourced software licensed under the MIT License.
Yacoub Al-haidari
- Email: yacoub@yacoubalhaidari.com
- GitHub: @yacoubalhaidari
Built With:
- Filament - The elegant admin panel framework
- Highcharts - Interactive charting library
- Laravel - The PHP framework for web artisans
If you find this package helpful, please consider:
- β Starring the repository
- π Reporting issues
- π‘ Suggesting new features
- π Improving documentation
- π Contributing code
Made with β€οΈ for the Filament community
