Data Visualization Tools for Laravel
Build powerful DataGrids, Charts, Metrics, and more with a unified visualization layer for Laravel.
What You Can Build
DataGrids
Create and manage data grids with columns, actions, sorting, filtering, and saveable views for tabular data.
Charts
Build dynamic charts with multiple dataset types including line, bar, pie, doughnut, scatter, and area charts.
Metrics
Display scalar aggregates โ totals, counts, averages โ as single-value KPI cards with optional floating filters.
How It Works
From schema definition to rendered visualization
Define Schema
Columns, datasets, labels
Build Query
Eloquent query generation
Apply Filters
Filter, sort, normalize
Render
JSON response to frontend
Built for Developers
Saveable Views
Let users save their filter sets, sorts, and column visibility as named views they can switch between and recall later.
Pluggable Filters
Twelve built-in filter operations for equality, ranges, sets, and strings. Add your own by implementing a simple contract.
Artisan Scaffolding
Spin up new visualizations instantly with make:datagrid and make:chart commands.
Authorization
Gate-based permissions on every visualization via a trait. Actions can carry their own authorization rules on top.
Floating Filters
Filter by fields that never appear in the visualization itself โ perfect for scoping data by date ranges, users, or categories.
Inline & Bulk Actions
Expose per-row and multi-row operations with optional Eloquent model binding and built-in authorization.
Built-In Testing Support
The Pest plugin ships a fluent tester for every visualization type. Assert column schemas, apply filter sets, and verify row data โ all in a single readable chain.
Read the docsit('filters users by name', function () {
User::factory()->create(['name' => 'Andrew']);
User::factory()->create(['name' => 'John']);
dataGrid(UsersDataGrid::class)
->assertHasColumn('Name')
->assertHasColumn('Email')
->usingFilterSets(fn (VisualizationData $data) =>
$data->addAndFilterSet(
fn (FilterBuilder $b) => $b->contains('Name', 'Andrew')
))
->assertRowCount(1)
->assertRowMatches(['Name' => 'Andrew']);
});