mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-12 23:45:10 +00:00
Include chart with report
This commit is contained in:
@@ -22,7 +22,6 @@ use Illuminate\Support\Collection;
|
|||||||
*/
|
*/
|
||||||
interface CategoryChartGeneratorInterface
|
interface CategoryChartGeneratorInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $entries
|
* @param Collection $entries
|
||||||
*
|
*
|
||||||
@@ -58,4 +57,11 @@ interface CategoryChartGeneratorInterface
|
|||||||
*/
|
*/
|
||||||
public function pieChart(array $data): array;
|
public function pieChart(array $data): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function reportPeriod(array $entries): array;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -142,6 +142,41 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function reportPeriod(array $entries): array
|
||||||
|
{
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'labels' => array_keys($entries),
|
||||||
|
'datasets' => [
|
||||||
|
0 => [
|
||||||
|
'label' => trans('firefly.earned'),
|
||||||
|
'data' => [],
|
||||||
|
],
|
||||||
|
1 => [
|
||||||
|
'label' => trans('firefly.spent'),
|
||||||
|
'data' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'count' => 2,
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($entries as $label => $entry) {
|
||||||
|
// data set 0 is budgeted
|
||||||
|
// data set 1 is spent:
|
||||||
|
$data['datasets'][0]['data'][] = round($entry['earned'], 2);
|
||||||
|
$data['datasets'][1]['data'][] = round(bcmul($entry['spent'], '-1'), 2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $entries
|
* @param array $entries
|
||||||
*
|
*
|
||||||
|
@@ -152,6 +152,43 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param CRI $repository
|
||||||
|
* @param Category $category
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
* @param Collection $accounts
|
||||||
|
*/
|
||||||
|
public function reportPeriod(CRI $repository, Category $category, Carbon $start, Carbon $end, Collection $accounts)
|
||||||
|
{
|
||||||
|
$cache = new CacheProperties;
|
||||||
|
$cache->addProperty($start);
|
||||||
|
$cache->addProperty($end);
|
||||||
|
$cache->addProperty('category-period-chart');
|
||||||
|
$cache->addProperty($accounts->pluck('id')->toArray());
|
||||||
|
$cache->addProperty($category);
|
||||||
|
if ($cache->has()) {
|
||||||
|
|
||||||
|
return $cache->get();
|
||||||
|
}
|
||||||
|
$report = $repository->getCategoryPeriodReport(new Collection([$category]), $accounts, $start, $end, true);
|
||||||
|
$periods = Navigation::listOfPeriods($start, $end);
|
||||||
|
|
||||||
|
|
||||||
|
// join them:
|
||||||
|
$result = [];
|
||||||
|
foreach (array_keys($periods) as $period) {
|
||||||
|
$nice = $periods[$period];
|
||||||
|
$result[$nice] = [
|
||||||
|
'earned' => $report['income'][$category->id]['entries'][$period] ?? '0',
|
||||||
|
'spent' => $report['expense'][$category->id]['entries'][$period] ?? '0',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$data = $this->generator->reportPeriod($result);
|
||||||
|
|
||||||
|
return Response::json($data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param CRI $repository
|
* @param CRI $repository
|
||||||
* @param Category $category
|
* @param Category $category
|
||||||
|
@@ -89,8 +89,11 @@ function displayAjaxPartial(data, holder) {
|
|||||||
// trigger list thing
|
// trigger list thing
|
||||||
listLengthInitial();
|
listLengthInitial();
|
||||||
|
|
||||||
// budget thing
|
// budget thing in year and multi year report:
|
||||||
$('.budget-chart-activate').unbind('click').on('click', clickBudgetChart);
|
$('.budget-chart-activate').unbind('click').on('click', clickBudgetChart);
|
||||||
|
|
||||||
|
// category thing in year and multi year report:
|
||||||
|
$('.category-chart-activate').unbind('click').on('click', clickCategoryChart);
|
||||||
}
|
}
|
||||||
|
|
||||||
function failAjaxPartial(uri, holder) {
|
function failAjaxPartial(uri, holder) {
|
||||||
@@ -100,6 +103,18 @@ function failAjaxPartial(uri, holder) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clickCategoryChart(e) {
|
||||||
|
"use strict";
|
||||||
|
var link = $(e.target);
|
||||||
|
var categoryId = link.data('category');
|
||||||
|
|
||||||
|
// this url is different from the one below. this is something that must be fixed
|
||||||
|
var URL = 'chart/category/' + categoryId + '/report-period/' + startDate + '/' + endDate + '/' + accountIds;
|
||||||
|
var container = 'category_chart';
|
||||||
|
columnChart(URL, container);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function clickBudgetChart(e) {
|
function clickBudgetChart(e) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var link = $(e.target);
|
var link = $(e.target);
|
||||||
|
@@ -6,6 +6,7 @@ $(function () {
|
|||||||
drawChart();
|
drawChart();
|
||||||
|
|
||||||
loadAjaxPartial('budgetPeriodReport', budgetPeriodReportUri);
|
loadAjaxPartial('budgetPeriodReport', budgetPeriodReportUri);
|
||||||
|
loadAjaxPartial('categoryPeriodReport', categoryPeriodReportUri);
|
||||||
});
|
});
|
||||||
|
|
||||||
function drawChart() {
|
function drawChart() {
|
||||||
|
@@ -114,6 +114,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{# same thing but for categories #}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'categories'|_ }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body no-padding table-responsive loading" id="categoryPeriodReport">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# and the same chart too! #}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'chart'|_ }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<canvas height="400" id="category_chart" style="width:100%;height:400px;"></canvas>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block styles %}
|
{% block styles %}
|
||||||
<link rel="stylesheet" href="css/bootstrap-sortable.css" type="text/css" media="all"/>
|
<link rel="stylesheet" href="css/bootstrap-sortable.css" type="text/css" media="all"/>
|
||||||
@@ -141,6 +169,7 @@
|
|||||||
var incExpReportUri = '{{ route('reports.data.incExpReport', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}';
|
var incExpReportUri = '{{ route('reports.data.incExpReport', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}';
|
||||||
|
|
||||||
var budgetPeriodReportUri = '{{ route('reports.data.budgetPeriodReport', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}';
|
var budgetPeriodReportUri = '{{ route('reports.data.budgetPeriodReport', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}';
|
||||||
|
var categoryPeriodReportUri = '{{ route('reports.data.categoryPeriodReport', [start.format('Ymd'), end.format('Ymd'), accountIds]) }}';
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="js/ff/reports/default/all.js"></script>
|
<script type="text/javascript" src="js/ff/reports/default/all.js"></script>
|
||||||
|
@@ -124,6 +124,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# and the same chart too! #}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'chart'|_ }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<canvas height="400" id="category_chart" style="width:100%;height:400px;"></canvas>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@@ -221,6 +221,7 @@ Route::group(
|
|||||||
Route::get('/chart/category/{category}/period', ['uses' => 'Chart\CategoryController@currentPeriod']);
|
Route::get('/chart/category/{category}/period', ['uses' => 'Chart\CategoryController@currentPeriod']);
|
||||||
Route::get('/chart/category/{category}/period/{date}', ['uses' => 'Chart\CategoryController@specificPeriod']);
|
Route::get('/chart/category/{category}/period/{date}', ['uses' => 'Chart\CategoryController@specificPeriod']);
|
||||||
Route::get('/chart/category/{category}/all', ['uses' => 'Chart\CategoryController@all']);
|
Route::get('/chart/category/{category}/all', ['uses' => 'Chart\CategoryController@all']);
|
||||||
|
Route::get('/chart/category/{category}/report-period/{start_date}/{end_date}/{accountList}', ['uses' => 'Chart\CategoryController@reportPeriod']);
|
||||||
|
|
||||||
// these charts are used in reports (category reports):
|
// these charts are used in reports (category reports):
|
||||||
Route::get(
|
Route::get(
|
||||||
|
Reference in New Issue
Block a user