231 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			231 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace App\Traits;
 | |
| 
 | |
| use Akaunting\Apexcharts\Chart;
 | |
| use Balping\JsonRaw\Raw;
 | |
| 
 | |
| trait Charts
 | |
| {
 | |
|     public $bar = [
 | |
|         'colors' => [],
 | |
|         'labels' => [],
 | |
|         'values' => [],
 | |
|     ];
 | |
| 
 | |
|     public $donut = [
 | |
|         'colors' => [],
 | |
|         'labels' => [],
 | |
|         'values' => [],
 | |
|     ];
 | |
| 
 | |
|     public function addToDonutChart($color, $label, $value)
 | |
|     {
 | |
|         $this->donut['colors'][] = $color;
 | |
|         $this->donut['labels'][] = $label;
 | |
|         $this->donut['values'][] = (int) $value;
 | |
|     }
 | |
| 
 | |
|     public function addMoneyToDonutChart($color, $amount, $description = '')
 | |
|     {
 | |
|         $label = money($amount, setting('default.currency'), true)->formatForHumans();
 | |
| 
 | |
|         if (!empty($description)) {
 | |
|             $label .= ' - ' . $description;
 | |
|         }
 | |
| 
 | |
|         $this->addToDonutChart($color, $label, $amount);
 | |
|     }
 | |
| 
 | |
|     public function getDonutChart($name, $width = '100%', $height = 300, $limit = 10)
 | |
|     {
 | |
|         // Show donut prorated if there is no value
 | |
|         if (array_sum($this->donut['values']) == 0) {
 | |
|             foreach ($this->donut['values'] as $key => $value) {
 | |
|                 $this->donut['values'][$key] = 1;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Get 6 categories by amount
 | |
|         $colors = $labels = [];
 | |
|         $values = collect($this->donut['values'])->sort()->reverse()->take($limit)->all();
 | |
| 
 | |
|         foreach ($values as $id => $val) {
 | |
|             $colors[$id] = $this->donut['colors'][$id];
 | |
|             $labels[$id] = $this->donut['labels'][$id];
 | |
|         }
 | |
| 
 | |
|         $chart = new Chart();
 | |
| 
 | |
|         $chart->setType('donut')
 | |
|             ->setWidth($width)
 | |
|             ->setHeight($height)
 | |
|             ->setDefaultLocale($this->getDefaultLocaleOfChart())
 | |
|             ->setLocales($this->getLocaleTranslationOfChart())
 | |
|             ->setLabels(array_values($labels))
 | |
|             ->setColors(array_values($colors))
 | |
|             ->setDataset($name, 'donut', array_values($values));
 | |
| 
 | |
|         return $chart;
 | |
|     }
 | |
| 
 | |
|     public function addToBarChart($color, $label, $value)
 | |
|     {
 | |
|         $this->bar['colors'][] = $color;
 | |
|         $this->bar['labels'][] = $label;
 | |
|         $this->bar['values'][] = (int) $value;
 | |
|     }
 | |
| 
 | |
|     public function getBarChart($name, $width = '100%', $height = 160)
 | |
|     {
 | |
|         $chart = new Chart();
 | |
| 
 | |
|         $chart->setType('bar')
 | |
|             ->setWidth($width)
 | |
|             ->setHeight($height)
 | |
|             ->setDefaultLocale($this->getDefaultLocaleOfChart())
 | |
|             ->setLocales($this->getLocaleTranslationOfChart())
 | |
|             ->setLabels(array_values($this->bar['labels']))
 | |
|             ->setColors($this->bar['colors']);
 | |
| 
 | |
|         foreach ($this->bar['values'] as $key => $value) {
 | |
|             $chart->setDataset($this->bar['labels'][$key], 'bar', $value);
 | |
|         }
 | |
| 
 | |
|         return $chart;
 | |
|     }
 | |
| 
 | |
|     public function getChartLabelFormatter($type = 'money', $position = null)
 | |
|     {
 | |
|         $label = '';
 | |
|         $decimal_mark = str_replace("'", "\\'", config('money.' . setting('default.currency') . '.decimal_mark'));
 | |
|         $thousands_separator = str_replace("'", "\\'", config('money.' . setting('default.currency') . '.thousands_separator'));
 | |
|         $symbol = str_replace("'", "\\'", config('money.' . setting('default.currency') . '.symbol'));
 | |
|         $symbol_first = str_replace("'", "\\'", config('money.' . setting('default.currency') . '.symbol_first'));
 | |
|         $precision = str_replace("'", "\\'", config('money.' . setting('default.currency') . '.precision'));
 | |
|         $percent_position = $position ?: setting('localisation.percent_position');
 | |
| 
 | |
|         switch ($type) {
 | |
|             case 'percent':
 | |
|                 $label = new Raw("function(value) {
 | |
|                     " . ($percent_position == 'right' ? "return value + '%';" : "return '%' + value;") . "
 | |
|                 }");
 | |
|                 break;
 | |
|             default:
 | |
|                 $label = new Raw("function(value) {
 | |
|                     const moneySettings = {
 | |
|                         decimal: '" . $decimal_mark . "',
 | |
|                         thousands: '". $thousands_separator . "',
 | |
|                         symbol: '" . $symbol . "',
 | |
|                         isPrefix: '" . $symbol_first . "',
 | |
|                         precision: '" . $precision . "',
 | |
|                     };
 | |
| 
 | |
|                     const formattedCurrency = function (input, opt = moneySettings) {
 | |
|                         if (typeof input === 'number') {
 | |
|                             input = input.toFixed(fixed(opt.precision))
 | |
|                         }
 | |
| 
 | |
|                         function fixed (precision) {
 | |
|                             return Math.max(0, Math.min(precision, 20));
 | |
|                         };
 | |
| 
 | |
|                         function toStr(value) {
 | |
|                             return value ? value.toString() : '';
 | |
|                         };
 | |
| 
 | |
|                         function numbersToCurrency(numbers, precision) {
 | |
|                             var exp = Math.pow(10, precision);
 | |
|                             var float = parseFloat(numbers) / exp;
 | |
| 
 | |
|                             return float.toFixed(fixed(precision));
 | |
|                         };
 | |
| 
 | |
|                         function joinIntegerAndDecimal (integer, decimal, separator) {
 | |
|                             return decimal ? integer + separator + decimal : integer;
 | |
|                         };
 | |
| 
 | |
|                         if (typeof input === 'number') {
 | |
|                             input = input.toFixed(fixed(opt.precision));
 | |
|                         };
 | |
| 
 | |
|                         var negative = input.indexOf('-') >= 0 ? '-' : '';
 | |
|                         var numbers = toStr(input).replace(/\D+/g, '') || '0';
 | |
|                         var currency = numbersToCurrency(numbers, opt.precision);
 | |
|                         var parts = toStr(currency).split('.');
 | |
|                         var integer = parts[0].replace(/(\d)(?=(?:\d{3})+\b)/gm,  ('$1' + opt.thousands));
 | |
|                         var decimal = parts[1];
 | |
| 
 | |
|                         if (opt.isPrefix == 1) {
 | |
|                             return opt.symbol + negative + joinIntegerAndDecimal(integer, decimal, opt.decimal);
 | |
|                         }
 | |
| 
 | |
|                         return negative + joinIntegerAndDecimal(integer, decimal, opt.decimal) + opt.symbol;
 | |
|                     };
 | |
| 
 | |
|                     return formattedCurrency(value, moneySettings);
 | |
|                 }");
 | |
|         }
 | |
| 
 | |
|         return $label;
 | |
|     }
 | |
| 
 | |
|     public function getDefaultLocaleOfChart(): string
 | |
|     {
 | |
|         $default = 'en';
 | |
| 
 | |
|         $short = language()->getShortCode();
 | |
|         $long = language()->getLongCode();
 | |
| 
 | |
|         $short_path = public_path('vendor/apexcharts/locales/' . $short . '.json');
 | |
|         $long_path = public_path('vendor/apexcharts/locales/' . $long . '.json');
 | |
| 
 | |
|         if (is_file($short_path)) {
 | |
|             return $short;
 | |
|         }
 | |
| 
 | |
|         if (is_file($long_path)) {
 | |
|             return $long;
 | |
|         }
 | |
| 
 | |
|         return $default;
 | |
|     }
 | |
| 
 | |
|     public function getLocaleTranslationOfChart(?string $locale = null): array
 | |
|     {
 | |
|         $translations = [];
 | |
| 
 | |
|         $user_locale = $locale ?: $this->getDefaultLocaleOfChart();
 | |
| 
 | |
|         $locales = ($user_locale == 'en') ? [$user_locale] : [$user_locale, 'en'];
 | |
| 
 | |
|         foreach ($locales as $loc) {
 | |
|             $translations[] = json_decode(
 | |
|                 file_get_contents(
 | |
|                     public_path('vendor/apexcharts/locales/' . $loc . '.json')
 | |
|                 )
 | |
|             );
 | |
|         }
 | |
| 
 | |
|         return $translations;
 | |
|     }
 | |
| 
 | |
|     // @deprecated version 3.0.0
 | |
|     public function addToDonut($color, $label, $value)
 | |
|     {
 | |
|         $this->addToDonutChart($color, $label, $value);
 | |
|     }
 | |
| 
 | |
|     // @deprecated version 3.0.0
 | |
|     public function addMoneyToDonut($color, $amount, $description = '')
 | |
|     {
 | |
|         $this->addMoneyToDonutChart($color, $amount, $description);
 | |
|     }
 | |
| 
 | |
|     // @deprecated version 3.0.0
 | |
|     public function addToBar($color, $label, $value)
 | |
|     {
 | |
|         $this->addToBarChart($color, $label, $value);
 | |
|     }
 | |
| }
 |