Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 100 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ $chart->options([

# Advanced Chartjs options

The basic options() method allows you to add simple key-value pair based options. Using the optionsRaw() method it's possible to add more complex nested Chartjs options in raw json format and to used nested calls to the options for plugins:
The basic options() method allows you to add simple key-value pair based options. Using the optionsRaw() method it's possible to add more complex nested Chartjs options in raw JavaScript format and to use JavaScript functions for callbacks:

Passing string format raw options to the chart like a json:
## Basic Raw Options

Passing string format raw options to the chart like a JavaScript object:
```php
$chart->optionsRaw("{
scales: {
Expand All @@ -113,6 +115,102 @@ $chart->optionsRaw("{
}");
```

## Number Formatting with JavaScript Functions

For advanced number formatting (like currency display), you can use JavaScript functions in your optionsRaw:

```php
$chart->optionsRaw('{
responsive: true,
plugins: {
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || "";
if (label) {
label += ": ";
}
if (context.parsed.y !== null) {
label += "R$ " + context.parsed.y.toLocaleString("pt-BR", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
return label;
}
}
}
},
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value, index, values) {
return "R$ " + value.toLocaleString("pt-BR", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
}
}
}
}');
```

For US dollar formatting:
```php
$chart->optionsRaw('{
responsive: true,
plugins: {
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || "";
if (label) {
label += ": ";
}
if (context.parsed.y !== null) {
label += "$" + context.parsed.y.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
return label;
}
}
}
},
scales: {
y: {
ticks: {
callback: function(value, index, values) {
return "$" + value.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
}
}
}
}');
```

## Troubleshooting optionsRaw

If your number formatting isn't working:

1. **Check JavaScript syntax**: Ensure your JavaScript object syntax is valid. You can use either quoted (`"responsive": true`) or unquoted (`responsive: true`) property names.

2. **Verify function placement**: Callback functions should be placed in the correct Chart.js option paths:
- Tooltip formatting: `plugins.tooltip.callbacks.label`
- Axis tick formatting: `scales.y.ticks.callback` (or `scales.x.ticks.callback`)

3. **Test with browser console**: Open your browser's developer console to check for JavaScript errors that might prevent the functions from executing.

4. **Check Chart.js version compatibility**: Ensure your callback function syntax matches your Chart.js version. This package supports Chart.js v2, v3, and v4.

5. **Validate locale support**: Make sure the locale you're using (like "pt-BR") is supported by the browser's `toLocaleString()` method.

# Examples

1 - Line Chart:
Expand Down
217 changes: 217 additions & 0 deletions examples/ChartController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
<?php

/*
* Complete working example for the user's issue
* This demonstrates exactly how to implement number formatting in Laravel ChartJS
*/

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use IcehouseVentures\LaravelChartjs\Facades\Chartjs;

class ChartController extends Controller
{
/**
* Brazilian Real number formatting example
* This is exactly what the user was trying to achieve
*/
public function brazilianNumberFormatting()
{
$chart = Chartjs::build()
->name('salesChart')
->type('bar')
->size(['width' => 600, 'height' => 400])
->labels(['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho'])
->datasets([
[
'label' => 'Vendas 2024',
'data' => [12345.67, 23456.78, 18945.32, 29876.43, 35467.89, 41234.56],
'backgroundColor' => 'rgba(54, 162, 235, 0.6)',
'borderColor' => 'rgba(54, 162, 235, 1)',
'borderWidth' => 1,
],
[
'label' => 'Vendas 2023',
'data' => [10234.56, 19876.54, 16543.21, 25432.10, 31098.76, 37654.32],
'backgroundColor' => 'rgba(255, 99, 132, 0.6)',
'borderColor' => 'rgba(255, 99, 132, 1)',
'borderWidth' => 1,
]
])
->optionsRaw('{
responsive: true,
plugins: {
title: {
display: true,
text: "Vendas Mensais"
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || "";
if (label) {
label += ": ";
}
if (context.parsed.y !== null) {
label += "R$ " + context.parsed.y.toLocaleString("pt-BR", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
return label;
}
}
}
},
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: "Valores (R$)"
},
ticks: {
callback: function(value, index, values) {
return "R$ " + value.toLocaleString("pt-BR", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
}
},
x: {
title: {
display: true,
text: "Meses"
}
}
}
}');

return view('charts.sales', compact('chart'));
}

/**
* US Dollar formatting example
*/
public function usDollarFormatting()
{
$chart = Chartjs::build()
->name('revenueChart')
->type('line')
->size(['width' => 600, 'height' => 400])
->labels(['Q1', 'Q2', 'Q3', 'Q4'])
->datasets([
[
'label' => 'Revenue 2024',
'data' => [125000.50, 187500.75, 156750.25, 234000.00],
'backgroundColor' => 'rgba(75, 192, 192, 0.2)',
'borderColor' => 'rgba(75, 192, 192, 1)',
'borderWidth' => 2,
'fill' => false,
]
])
->optionsRaw('{
responsive: true,
plugins: {
title: {
display: true,
text: "Quarterly Revenue"
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || "";
if (label) {
label += ": ";
}
if (context.parsed.y !== null) {
label += "$" + context.parsed.y.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
return label;
}
}
}
},
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: "Revenue (USD)"
},
ticks: {
callback: function(value, index, values) {
return "$" + value.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
}
}
}
}');

return view('charts.revenue', compact('chart'));
}

/**
* Alternative approach using quoted JSON syntax (user's original approach)
* This also works perfectly fine
*/
public function quotedSyntaxExample()
{
$chart = Chartjs::build()
->name('quotedChart')
->type('bar')
->size(['width' => 600, 'height' => 400])
->labels(['Jan', 'Feb', 'Mar'])
->datasets([
[
'label' => 'Sales',
'data' => [1234.56, 2345.67, 3456.78],
'backgroundColor' => 'rgba(153, 102, 255, 0.6)',
]
])
->optionsRaw('{
"responsive": true,
"plugins": {
"tooltip": {
"callbacks": {
"label": function(context) {
let label = context.dataset.label || "";
if (label) {
label += ": ";
}
if (context.parsed.y !== null) {
label += "R$ " + context.parsed.y.toLocaleString("pt-BR", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
return label;
}
}
}
},
"scales": {
"y": {
"ticks": {
"callback": function(value, index, values) {
return "R$ " + value.toLocaleString("pt-BR", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
}
}
}
}');

return view('charts.quoted-example', compact('chart'));
}
}
42 changes: 42 additions & 0 deletions examples/sales.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{{-- resources/views/charts/sales.blade.php --}}
@extends('layouts.app')

@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-header">{{ __('Sales Dashboard') }}</div>

<div class="card-body">
<h4>Monthly Sales with Brazilian Real Formatting</h4>
<p>This chart demonstrates proper number formatting in tooltips and Y-axis labels.</p>

{{-- Laravel ChartJS component --}}
<div style="width: 100%; max-width: 800px; margin: 0 auto;">
<x-chartjs-component :chart="$chart" />
</div>

<div class="mt-4">
<h5>Features demonstrated:</h5>
<ul>
<li>✓ Brazilian Real currency formatting (R$ 1.234,56)</li>
<li>✓ Custom tooltip callbacks with locale-specific number formatting</li>
<li>✓ Y-axis tick formatting with currency symbols</li>
<li>✓ Responsive chart design</li>
<li>✓ Multi-dataset support</li>
</ul>
</div>

<div class="mt-4">
<h6>Technical Details:</h6>
<p>This chart uses the <code>optionsRaw()</code> method with JavaScript functions
to format numbers using <code>toLocaleString("pt-BR")</code> for Brazilian
Portuguese formatting with proper decimal places.</p>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
Loading