uneca/plotly-chart-editor
Reactive Plotly.js chart builder for Laravel via Livewire. Sidebar-driven editor to configure traces and layout, multi-language UI (EN/FR/PT/ES), multiple sync modes and persistence options. Requires Plotly.js 3.x (peer dep), Alpine, PHP 8.4+.
Installation:
composer require uneca/plotly-chart-editor
Load Plotly.js (via CDN or npm) and include these Blade directives in your layout:
@plotlyChartEditorStyles
@plotlyChartEditorScripts
@livewireStyles
@livewireScripts
First Use Case: Embed the editor in a Blade view with minimal props:
<livewire:plotly-editor
:data-sources="$rawDataset"
:trace-types="['bar', 'line']"
/>
Where $rawDataset is an associative array of column names and values (e.g., ['Country' => ['Ghana', 'Kenya'], 'Population' => [34, 55]]).
Quick Preview: Wrap the component in a flex container for full-page layout:
<div class="h-screen flex flex-col">
<livewire:plotly-editor :data-sources="$rawDataset" />
</div>
Server → Client: Pass raw data (dataSources), initial traces (data), and layout (layout) as props.
Client → Server: Use sync-mode to control when changes are sent:
manual: Requires user click on "Save" (default).auto: Debounced sync (~500ms) after mutations.hybrid: Auto-sync + explicit "Save" button.Example with hybrid mode:
<livewire:plotly-editor
:data-sources="$rawDataset"
:sync-mode="'hybrid'"
@chart-synced="saveChart"
/>
Option A: Livewire Wrapping (Recommended for Laravel Apps) Wrap the editor in a parent Livewire component to handle persistence:
// ParentComponent.php
#[On('chart-synced')]
public function saveChart(array $data, array $layout): void {
$this->chart->update(['traces' => $data, 'layout' => $layout]);
}
<livewire:parent-component :chart="$chart" />
Option B: Event Listeners
Listen to the ChartSynced Laravel event:
// EventServiceProvider.php
protected $listen = [
\Uneca\PlotlyChartEditor\Events\ChartSynced::class => [
\App\Listeners\SaveChart::class,
],
];
Enable/disable trace types via the trace-types prop:
<livewire:plotly-editor
:trace-types="['scatter', 'bar', 'pie']"
:preload-schema="true" <!-- Loads schema for all enabled types -->
/>
Override default styles by publishing assets:
php artisan vendor:publish --tag="plotly-chart-editor-assets"
Modify resources/css/plotly-chart-editor.css to adjust --plotly-editor-* theme variables.
Validate incoming chart data in controllers:
use Uneca\PlotlyChartEditor\Rules\ValidChartConfig;
$request->validate([
'chart' => ['required', new ValidChartConfig],
]);
Data Mismatch Warnings:
dataSources columns have unequal lengths, the editor shows a non-blocking warning. Ensure all columns are the same length.Plotly.js Dependency:
<script src="https://cdn.plot.ly/plotly-3.5.0.min.js"></script>
Sync Mode Confusion:
auto mode syncs debounced changes but hides the "Save" button. Use hybrid if you need both auto-sync and explicit saves.Alpine Store Direct Access:
Alpine.store('chartBuilder') outside the component’s methods. Use the provided store methods (e.g., addTrace()).Trace Type Profiles:
php artisan vendor:publish --tag="plotly-chart-editor-config"
config/plotly-chart-editor.php to add new profiles.Check Sync Events:
plotly-chart-editor:synced in browser console:
window.addEventListener('plotly-chart-editor:synced', (e) => {
console.log('Synced data:', e.detail);
});
Inspect Alpine Store:
<button x-on:click="console.log(Alpine.store('chartBuilder'))">
Debug Store
</button>
Validate DataSources:
dataSources is an associative array with consistent column lengths:
$dataSources = [
'xAxis' => [1, 2, 3],
'yAxis' => [10, 20, 30], // Must match length of 'xAxis'
];
Disable Auto-Sync for Large Datasets:
sync-mode="manual" to reduce debounced syncs:
<livewire:plotly-editor :sync-mode="'manual'" />
Preload Schema:
:preload-schema="false" if you only use a subset of trace types to reduce initial load time.Disable Unused Features:
<livewire:plotly-editor
:show-export="false"
:show-data-viewer="false"
/>
Custom Trace Types:
config/plotly-chart-editor.php:
'profiles' => [
'my-custom-type' => [
'groups' => [
'data' => ['x', 'y', 'text'],
'style' => ['color', 'opacity'],
],
],
],
Override Translations:
resources/lang/en/plotly-chart-editor.php.Alpine Store Extensions:
resources/js/plotly-chart-editor.js:
Alpine.store('chartBuilder', () => ({
// Existing methods...
customMethod() {
// Your logic
},
}));
Validation Rules:
ValidChartConfig by copying the rule class and overriding passes():
class CustomValidChartConfig extends ValidChartConfig {
public function passes($attribute, $value) {
// Custom logic
return parent::passes($attribute, $value);
}
}
How can I help you explore Laravel packages today?