diff --git a/app/Generator/Chart/Category/CategoryChartGeneratorInterface.php b/app/Generator/Chart/Category/CategoryChartGeneratorInterface.php index e0444c1cba..2b95ba820b 100644 --- a/app/Generator/Chart/Category/CategoryChartGeneratorInterface.php +++ b/app/Generator/Chart/Category/CategoryChartGeneratorInterface.php @@ -37,6 +37,13 @@ interface CategoryChartGeneratorInterface */ public function all(Collection $entries): array; + /** + * @param array $entries + * + * @return array + */ + public function mainReportChart(array $entries): array; + /** * @param Collection $categories * @param Collection $entries diff --git a/app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php b/app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php index eb03606c2c..7aea9c65cd 100644 --- a/app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php +++ b/app/Generator/Chart/Category/ChartJsCategoryChartGenerator.php @@ -118,6 +118,51 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface return $data; } + /** + * @param array $entries + * + * @return array + */ + public function mainReportChart(array $entries): array + { + + $data = [ + 'count' => 0, + 'labels' => array_keys($entries), + 'datasets' => [], + ]; + + + foreach ($entries as $row) { + foreach ($row['in'] as $categoryId => $amount) { + // get in: + $data['datasets'][$categoryId . 'in']['data'][] = round($amount, 2); + + // get out: + $opposite = $row['out'][$categoryId]; + $data['datasets'][$categoryId . 'out']['data'][] = round($opposite, 2); + + // set name: + $data['datasets'][$categoryId . 'out']['label'] = $row['name'][$categoryId] . ' (' . strtolower(strval(trans('firefly.expenses'))) . ')'; + $data['datasets'][$categoryId . 'in']['label'] = $row['name'][$categoryId] . ' (' . strtolower(strval(trans('firefly.income'))) . ')'; + + } + } + + // remove empty rows: + foreach ($data['datasets'] as $key => $content) { + if (array_sum($content['data']) === 0.0) { + unset($data['datasets'][$key]); + } + } + + // re-key the datasets array: + $data['datasets'] = array_values($data['datasets']); + $data['count'] = count($data['datasets']); + + return $data; + } + /** * * @param Collection $entries diff --git a/app/Http/Controllers/Chart/CategoryReportController.php b/app/Http/Controllers/Chart/CategoryReportController.php index b19d03c156..1d376cf841 100644 --- a/app/Http/Controllers/Chart/CategoryReportController.php +++ b/app/Http/Controllers/Chart/CategoryReportController.php @@ -19,12 +19,14 @@ use FireflyIII\Generator\Chart\Category\CategoryChartGeneratorInterface; use FireflyIII\Generator\Report\Category\MonthReportGenerator; use FireflyIII\Helpers\Collector\JournalCollector; use FireflyIII\Http\Controllers\Controller; +use FireflyIII\Models\Category; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use Illuminate\Support\Collection; use Log; +use Navigation; use Response; @@ -260,6 +262,57 @@ class CategoryReportController extends Controller return Response::json($data); } + /** + * @param Collection $accounts + * @param Collection $categories + * @param Carbon $start + * @param Carbon $end + * + * @return \Illuminate\Http\JsonResponse + */ + public function mainChart(Collection $accounts, Collection $categories, Carbon $start, Carbon $end) + { + // determin optimal period: + $period = '1D'; + $format = 'month_and_day'; + if ($start->diffInMonths($end) > 1) { + $period = '1M'; + $format = 'month'; + } + if ($start->diffInMonths($end) > 13) { + $period = '1Y'; + $format = 'year'; + } + Log::debug(sprintf('Period is %s', $period)); + $data = []; + $current = clone $start; + while ($current < $end) { + $currentEnd = Navigation::endOfPeriod($current, $period); + $expenses = $this->groupByCategory($this->getExpenses($accounts, $categories, $current, $currentEnd)); + $income = $this->groupByCategory($this->getIncome($accounts, $categories, $current, $currentEnd)); + $label = $current->formatLocalized(strval(trans('config.' . $format))); + $data[$label] = [ + 'in' => [], + 'out' => [], + ]; + + /** @var Category $category */ + foreach ($categories as $category) { + // get sum, and get label: + $categoryId = $category->id; + $data[$label]['name'][$categoryId] = $category->name; + $data[$label]['in'][$categoryId] = $income[$categoryId] ?? '0'; + $data[$label]['out'][$categoryId] = $expenses[$categoryId] ?? '0'; + } + + $current = Navigation::addPeriod($current, $period, 0); + } + + $data = $this->generator->mainReportChart($data); + return Response::json($data); + } + + /** * @param Collection $accounts * @param Collection $categories diff --git a/public/js/ff/reports/category/month.js b/public/js/ff/reports/category/month.js index 46bbf5cb47..b9786d68fc 100644 --- a/public/js/ff/reports/category/month.js +++ b/public/js/ff/reports/category/month.js @@ -42,12 +42,15 @@ function drawChart() { "use strict"; // month view: + stackedColumnChart('chart/category-report-in-out/' + accountIds + '/' + categoryIds + '/' + startDate + '/' + endDate, 'in-out-chart'); // draw pie chart of income, depending on "show other transactions too": redrawPieChart('categories-in-pie-chart', catInUri); redrawPieChart('categories-out-pie-chart', catOutUri); redrawPieChart('accounts-in-pie-chart', accInUri); redrawPieChart('accounts-out-pie-chart', accOutUri); + + } function redrawPieChart(container, uri) { diff --git a/resources/views/reports/category/month.twig b/resources/views/reports/category/month.twig index 4a7ca59700..4f07f6d1c6 100644 --- a/resources/views/reports/category/month.twig +++ b/resources/views/reports/category/month.twig @@ -148,15 +148,21 @@
- - - big chart here - - Show income / expenses per period. Differs per report: month = per day, year = per month, multi-year = per year. - In a bar chart, possibly grouped by expense/revenue account. - +
+
+

{{ 'income_and_expenses'|_ }}

+
+
+ +
+
+ {# + big chart here + Show income / expenses per period. Differs per report: month = per day, year = per month, multi-year = per year. + In a bar chart, possibly grouped by expense/revenue account. + #}
diff --git a/routes/web.php b/routes/web.php index bc61e74842..bff941d52f 100755 --- a/routes/web.php +++ b/routes/web.php @@ -227,12 +227,8 @@ Route::group( ['uses' => 'Chart\CategoryReportController@accountExpense'] ); Route::get( - '/chart/category-report-income/{accountList}/{categoryList}/{start_date}/{end_date}', - ['uses' => 'Chart\CategoryReportController@mainIncomeChart'] - ); - Route::get( - '/chart/category-report-expenses/{accountList}/{categoryList}/{start_date}/{end_date}', - ['uses' => 'Chart\CategoryReportController@mainExpenseChart'] + '/chart/category-report-in-out/{accountList}/{categoryList}/{start_date}/{end_date}', + ['uses' => 'Chart\CategoryReportController@mainChart'] ); // piggy banks: