Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datalabel formatter #16

Closed
RosiersRobin opened this issue May 2, 2023 · 13 comments
Closed

Datalabel formatter #16

RosiersRobin opened this issue May 2, 2023 · 13 comments
Labels
done enhancement New feature or request

Comments

@RosiersRobin
Copy link

Hi,

How can I make use of the datalabel formatter?

I have the following array I return;

return [
            'chart' => [
                'type' => 'bar',
                'height' => 300,
                'animations' => [
                    'enabled' => false
                ],
            ],
            'series' => [
                [
                    'name' => 'Sales',
                    'data' => $totalSoldByProduct->pluck('total_revenue')->toArray(),
                ],
            ],
            'xaxis' => [
                'categories' => $totalSoldByProduct->pluck('name')->toArray(),
                'labels' => [
                    'style' => [
                        'colors' => '#9ca3af',
                        'fontWeight' => 600,
                    ],
                ],
            ],
            'yaxis' => [
                'labels' => [
                    'style' => [
                        'colors' => '#9ca3af',
                        'fontWeight' => 600,
                    ],
                ],
            ],
            'dataLabels' => [
                'enabled' => true,
                'formatter' => 'function(val, opts) {
                    return "Sold " + val;
                }',
                'style' => [
                    'colors' => ['#fff'],
                ],
            ],
            'colors' => ['#1da6e7'],
        ];

As you see, there is a formatter;

 'formatter' => 'function(val, opts) {
                    return "Sold " + val;
                }',

But this does not work? How can I achieve this to work?

@leandrocfe
Copy link
Owner

Hi,

How can I make use of the datalabel formatter?

I have the following array I return;

return [
            'chart' => [
                'type' => 'bar',
                'height' => 300,
                'animations' => [
                    'enabled' => false
                ],
            ],
            'series' => [
                [
                    'name' => 'Sales',
                    'data' => $totalSoldByProduct->pluck('total_revenue')->toArray(),
                ],
            ],
            'xaxis' => [
                'categories' => $totalSoldByProduct->pluck('name')->toArray(),
                'labels' => [
                    'style' => [
                        'colors' => '#9ca3af',
                        'fontWeight' => 600,
                    ],
                ],
            ],
            'yaxis' => [
                'labels' => [
                    'style' => [
                        'colors' => '#9ca3af',
                        'fontWeight' => 600,
                    ],
                ],
            ],
            'dataLabels' => [
                'enabled' => true,
                'formatter' => 'function(val, opts) {
                    return "Sold " + val;
                }',
                'style' => [
                    'colors' => ['#fff'],
                ],
            ],
            'colors' => ['#1da6e7'],
        ];

As you see, there is a formatter;

 'formatter' => 'function(val, opts) {
                    return "Sold " + val;
                }',

But this does not work? How can I achieve this to work?

Hi! We can't use the formatter function in the current version. I have plans to include it in the next version.
Maybe you can transform it in you query or using a map function

@MdMotahir
Copy link

@leandrocfe we need the 'formatter' function. cause when we try to pass the time value in the y-axis it's not showing the y-axis label correctly.

@leandrocfe
Copy link
Owner

@leandrocfe we need the 'formatter' function. cause when we try to pass the time value in the y-axis it's not showing the y-axis label correctly.

If it is urgent, you can publish the views and customize what you want.
I have plans to do it but now I don't know when.

@VictorCano
Copy link

Could adding something like this into chart.blade be a viable default alternative?

initChart: function(options = null) {

    options = options ?? @js($getCachedOptions)

    
    if (options.dataLabels && options.dataLabels.formatter) {
        options.dataLabels.formatter = eval(options.dataLabels.formatter)
    }

    
    if (options.yaxis && options.yaxis.labels && options.yaxis.labels.formatter) {
        options.yaxis.labels.formatter = eval(options.yaxis.labels.formatter)
    }
    
    
    if (options.xaxis && options.xaxis.labels && options.xaxis.labels.formatter) {
        options.xaxis.labels.formatter = eval(options.xaxis.labels.formatter)
    }

    if (this.darkModeEnabled) {
        options.theme.mode = this.mode
    }

    this.chart = new ApexCharts(document.querySelector('#{{ $chartId }}'), options)

    return this.chart.render()
}

And in the options array of the widget:

'yaxis' => [
    'labels' => [
        'formatter' => '(val, index) => {
            return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
            }',
    ],
],

We managed to do it this way, if you think this could be a viable approach I can review with all the other available formats and send a PR.

@leandrocfe leandrocfe added the enhancement New feature or request label Aug 18, 2023
@aldesrahim
Copy link

hello, is there any updates yet ? thanks

@webtamizhan
Copy link

I fixed myself by changing the view file. In my case i have 4 widgets in a page and i just to need to format currency only for Piechart widget, so i am done the following.

  1. Add chartId on your chart widget.(Optional)

protected static string $chartId = "XXXXX"; \\ if you have multiple chart widget, then this will help you only changes

  1. Once you published the view, goto the chart.blade.php file.
  2. Slightly change the options by overriding the options config by following.
 @if($chartId === 'XXXXX')
      console.log('rendered Options',   options);
      let tmpOptions = options;
      tmpOptions.yaxis = {
          labels: {
              formatter: (value) => {
                  if (typeof value !== 'undefined') {
                  let USDollar = new Intl.NumberFormat('en-US', {
                      style: 'currency',
                      currency: 'USD',
                  });
                      return USDollar.format(value);
                  } else {
                      return null;
                  }
              }
          }
      };
      this.chart = new ApexCharts(document.querySelector('#{{ $chartId }}'), tmpOptions)
  @else
      this.chart = new ApexCharts(document.querySelector('#{{ $chartId }}'), options)
  @endif
  1. If you used any filters on the widget, you can listen the emit event like the following.
 $wire.on('updateOptions', async ({ options }) => {
         @if($chartId === 'XXXXX')
                  console.log('updateOptions', JSON.parse(options));
                  let tmpOptions = JSON.parse(options);
                  tmpOptions.yaxis = {
                      labels: {
                          formatter: (value) => {
                              if (typeof value !== 'undefined') {
                              let USDollar = new Intl.NumberFormat('en-US', {
                                  style: 'currency',
                                  currency: 'USD',
                              });
                                  return USDollar.format(value);
                              } else {
                                  return null;
                              }
                          }
                      }
                  };
                  this.chart.updateOptions(tmpOptions, true, true, true);
          @else
                  this.chart.updateOptions(options, false, true, true);
          @endif
 });

I hope someone need this!

@KostasKostogloy
Copy link

KostasKostogloy commented Nov 9, 2023

My fix for latest version goes like this.

  1. Publish the package's views: php artisan vendor:publish --tag="filament-apex-charts-views"
  2. Edit chart.blade.php
  3. Change init():
init() {
    this.$wire.$on('updateOptions', ({ options }) => {
        if (options.dataLabels?.formatter) {
            options.dataLabels.formatter = eval(options.dataLabels.formatter)
        }
    
    
        if (options.yaxis?.labels?.formatter) {
            options.yaxis.labels.formatter = eval(options.yaxis.labels.formatter)
        }
    
    
        if (options.xaxis?.labels?.formatter) {
            options.xaxis.labels.formatter = eval(options.xaxis.labels.formatter)
        }
        this.chart.updateOptions(options, false, true, true);
    });
    
    this.options.theme = { mode: this.theme };
    this.options.chart.background = 'inherit';
    if (this.options.dataLabels?.formatter) {
        this.options.dataLabels.formatter = eval(this.options.dataLabels.formatter)
    }
    
    
    if (this.options.yaxis?.labels?.formatter) {
        this.options.yaxis.labels.formatter = eval(this.options.yaxis.labels.formatter)
    }
    
    
    if (this.options.xaxis?.labels?.formatter) {
        this.options.xaxis.labels.formatter = eval(this.options.xaxis.labels.formatter)
    }
    
    this.chart = new ApexCharts($refs.{{ $chartId }}, this.options);
    this.chart.render();
}

@flolanger
Copy link

Since the latest version, the fix from @KostasKostogloy doesn't work anymore, because the init() is gone now from the views...

Any updates, when the formatter will be supported or what workaround is suggested now?

@aldesrahim
Copy link

aldesrahim commented Dec 27, 2023

Since the latest version, the fix from @KostasKostogloy doesn't work anymore, because the init() is gone now from the views...

Any updates, when the formatter will be supported or what workaround is suggested now?

I've similar issue, just publish all blade files using the old ones (before last update), and manually load apexchart asset inside AppServiceProvider using this command

FilamentAsset::register([
    Js::make('apexcharts', __DIR__.'/../../resources/js/apexcharts.min.js'),
], package: 'leandrocfe/filament-apex-charts');

blade files that i've published (using the old ones)
image

And with the old blade files, you can try the old workaround for Datalabel formatter by @KostasKostogloy

@glennjacobs
Copy link

I've submitted a PR for review which adds this functionality. See #55

If you want to use it now, you can simply put the view in resources/views/vendor/filament-apex-charts/widgets/components/chart.blade.php.

@flolanger
Copy link

I've submitted a PR for review which adds this functionality. See #55

If you want to use it now, you can simply put the view in resources/views/vendor/filament-apex-charts/widgets/components/chart.blade.php.

Thank you so much! ❤️

@glennjacobs
Copy link

My PR was incorrect. I've taken a different approach, which leaves the view intact and instead updates the distributed JS.

To use before being merged you can copy the built JS file to your public/js/app/components/apexcharts.js.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
done enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

9 participants