Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jgravois's avatar

Chartisan with Livewire

I followed Kevin McKee's excellent Interactive Charts in his Multitenancy Series and was able to add a chart to my livewire component .. thanks, Kevin.

I explored the Chartisan package and found this:

Chartisan allows for customizing how the HTTP request is performed. You can pass a property called options to the chart constructor and it will be directly passed to the fetch() function as the second parameter. This allows modifying how the request is performed at a deeper level by having total control of how the HTTP request is performed and allows for instance, appending headers or changing the request method. You can also append query parameters as usual by appending them on the chart URL at the url property.

so in App\Charts\MonthlySalesChart.php I am trying to add in an additional parameter so that I can pass this in the constructor and retrieve chart data from different months.

class MonthlySalesChart extends BaseChart
{
    public function handler(Request $request, $dt): Chartisan
    {
        $monthlies = Invoice::mtd($dt);

        $labels = collect($monthlies)->pluck('last_name')->toArray();
        $totals = collect($monthlies)->pluck('gross')->toArray();

        return Chartisan::build()
            ->labels($labels)
            ->dataset('Sales', $totals);
    }
}

however when I do that, phpStorm has a hissy and tells me Declaration must be compatible with BaseChart->handler(request: \Illuminate\Http\Request) .

Clearly I didn't grasp the docs ... is anyone using Chartisan and able to pass in parameters?

Any insight is appreciated.

0 likes
14 replies
jgravois's avatar

not sure how I could do that ... the docs don't explain further than it can be done

automica's avatar

@jgravois aren't you calling chartisan via a route? if so you should be able to pass data to it that way.

automica's avatar

Documentation is a bit light for this. Especially with the mention of routes. Let me know how you get on.

jgravois's avatar

Documentation is too light on this so I am going to spin off in a new direction with keeping the current month in chart and providing a table of YTD rather than trying to do what I was trying of allowing the user to select a month and have the chart magically transform.

1 like
automica's avatar

@jgravois The presence of that $request is tantalizing....

I'll have a fiddle over the weekend and if I work out how to do it, i'll let you know.

jgravois's avatar

would be appreciated ... it would be a better UIX

automica's avatar

@jgravois I've given it a fiddle locally. To get data into the chart in the first place, you can change the url from using the chart helper

const chart = new Chartisan({
    el: '#chart',
   url: "@chart('sample_chart')",
});

to the one that you'll see if you run

php artisan route:list -c

so in my case:

const chart = new Chartisan({
    el: '#chart',
    url: 'api/chart/sample_chart?foo=foo1&bar=bar1&baz=baz1'
});
rodrigo.pedra's avatar

Or as @\chart(...) is a blade directive that will output the chart route he could try:

const chart = new Chartisan({
    el: '#chart',
   url: "@chart('sample_chart')?dt=2020-11-01",
});

And process dt as a query parameter, as I pointed out in my other response earlier.

automica's avatar

@rodrigo.pedra ah. that part of the docs is very light in explanation, which sparked my interest. Thanks for clarification on the blade directive

1 like
rodrigo.pedra's avatar

No worries @automica ,

I just posted a proof of concept down below using Alpine for changing the month dynamically.

Overall I am really impressed with Chartisan ease of use.

rodrigo.pedra's avatar

From the quote you used:

by having total control of how the HTTP request is performed and allows for instance, appending headers or changing the request method. You can also append query parameters as usual by appending them on the chart URL at the url property.

So the way to send additional parameters is to send them as query parameters.

In that sense your chart object would become:

class MonthlySalesChart extends BaseChart
{
    public function handler(Request $request): Chartisan
    {
        $dt = $request->query('dt');

        $monthlies = Invoice::mtd($dt);

        $labels = collect($monthlies)->pluck('last_name')->toArray();
        $totals = collect($monthlies)->pluck('gross')->toArray();

        return Chartisan::build()
            ->labels($labels)
            ->dataset('Sales', $totals);
    }
}

This way the method signature stays compatible with its base class method.

And in your JavaScript code you would append that as a query parameter, the same way it has on the code sample down below the quote you posted

chart.update({
  //                                            V added as query paremeters
  url: 'https://chartisan.dev/chart/example.json?start=01-01-2020&end=01-02-2020',
  options: {
    headers: {
      'Authorization': 'Bearer someauthenticationtoken'
    }
  }
})

Reference: https://chartisan.dev/documentation/frontend/updating#HTTP-Request

rodrigo.pedra's avatar

Proof of concept, with Alpine.js.

1 - Chart

<?php

namespace App\Charts;

use Chartisan\PHP\Chartisan;
use ConsoleTVs\Charts\BaseChart;
use Illuminate\Http\Request;

class MonthChart extends BaseChart
{
    public static array $datasets = [
        '2020-09' => [100, 80, 230],
        '2020-10' => [115, 75, 240],
        '2020-11' => [180, 93, 200],
    ];

    public function handler(Request $request): Chartisan
    {
        $month = $request->query('month');

        return Chartisan::build()
            ->labels(['Grocery', 'Appliances', 'Clothing'])
            ->dataset('Sales', self::$datasets[$month]);
    }
}

2 - Chart Registration

<?php

namespace App\Providers;

use App\Charts\MonthChart;
use ConsoleTVs\Charts\Registrar as Charts;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        //
    }

    public function boot(Charts $charts)
    {
        $charts->register([MonthChart::class]);
    }
}

3 - Route Registration

<?php

// ./routes/web.php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    $months = \array_keys(\App\Charts\MonthChart::$datasets);

    return view('chartisan', ['months' => $months]);
});

4 - Blade Template

<!DOCTYPE html>
{{-- ./resources/views/chartisan.blade.php --}}
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Chartisan example</title>
</head>
<body>
<div x-data="initChart('@chart('month_chart')', {{ \json_encode($months) }})">
    <div>
        <select x-model="month" x-on:change="updateChart()">
            <template x-for="item in months" :key="item">
                <option x-bind:value="item" x-text="item"></option>
            </template>
        </select>
    </div>

    <div id="chart" style="height: 350px;"></div>
</div>

<script>
function initChart(url, months) {
    const month = months[months.length - 1];

    return {
        url,
        months,
        month,
        chart: new Chartisan({el: '#chart', url: url + '?month=' + month}),
        updateChart() {
            this.chart.update({url: this.url + '?month=' + this.month});
        },
    };
}
</script>
<script src="https://unpkg.com/echarts/dist/echarts.min.js"></script>
<script src="https://unpkg.com/@chartisan/echarts/dist/chartisan_echarts.js"></script>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js"></script>
</body>
</html>

Hope it helps.

Please or to participate in this conversation.