mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-23 20:00:33 -04:00
Adding charts to reports
This commit is contained in:
parent
c86802b88f
commit
dea48b83e2
@ -3,6 +3,9 @@
|
|||||||
namespace App\Ninja\Reports;
|
namespace App\Ninja\Reports;
|
||||||
|
|
||||||
use Auth;
|
use Auth;
|
||||||
|
use DateInterval;
|
||||||
|
use DatePeriod;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
class AbstractReport
|
class AbstractReport
|
||||||
{
|
{
|
||||||
@ -13,6 +16,7 @@ class AbstractReport
|
|||||||
|
|
||||||
public $totals = [];
|
public $totals = [];
|
||||||
public $data = [];
|
public $data = [];
|
||||||
|
public $chartData = [];
|
||||||
|
|
||||||
public function __construct($startDate, $endDate, $isExport, $options = false)
|
public function __construct($startDate, $endDate, $isExport, $options = false)
|
||||||
{
|
{
|
||||||
@ -141,4 +145,101 @@ class AbstractReport
|
|||||||
|
|
||||||
return join('', $reportParts);
|
return join('', $reportParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function addChartData($dimension, $date, $amount)
|
||||||
|
{
|
||||||
|
if (! isset($this->chartData[$dimension])) {
|
||||||
|
$this->chartData[$dimension] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$date = $this->formatDate($date);
|
||||||
|
|
||||||
|
if (! isset($this->chartData[$dimension][$date])) {
|
||||||
|
$this->chartData[$dimension][$date] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->chartData[$dimension][$date] += $amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function chartGroupBy()
|
||||||
|
{
|
||||||
|
$groupBy = empty($this->options['group_dates_by']) ? 'day' : $this->options['group_dates_by'];
|
||||||
|
|
||||||
|
if ($groupBy == 'monthyear') {
|
||||||
|
$groupBy = 'month';
|
||||||
|
}
|
||||||
|
|
||||||
|
return strtoupper($groupBy);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function formatDate($date)
|
||||||
|
{
|
||||||
|
$groupBy = $this->chartGroupBy();
|
||||||
|
$dateFormat = $groupBy == 'DAY' ? 'z' : ($groupBy == 'MONTH' ? 'm' : '');
|
||||||
|
|
||||||
|
return $date->format('Y' . $dateFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChartData()
|
||||||
|
{
|
||||||
|
$startDate = date_create($this->startDate);
|
||||||
|
$endDate = date_create($this->endDate);
|
||||||
|
$groupBy = $this->chartGroupBy();
|
||||||
|
|
||||||
|
/*
|
||||||
|
if ($groupBy == 'DAY') {
|
||||||
|
$groupBy = 'DAYOFYEAR';
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
$datasets = [];
|
||||||
|
$labels = [];
|
||||||
|
$totals = new stdClass();
|
||||||
|
|
||||||
|
foreach ($this->chartData as $dimension => $data) {
|
||||||
|
$endDate->modify('+1 '.$groupBy);
|
||||||
|
$interval = new DateInterval('P1'.substr($groupBy, 0, 1));
|
||||||
|
$period = new DatePeriod($startDate, $interval, $endDate);
|
||||||
|
$endDate->modify('-1 '.$groupBy);
|
||||||
|
$records = [];
|
||||||
|
|
||||||
|
foreach ($period as $date) {
|
||||||
|
$labels[] = $date->format('m/d/Y');
|
||||||
|
/*
|
||||||
|
if ($entityType == ENTITY_INVOICE) {
|
||||||
|
$labels[] = $d->format('m/d/Y');
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
$date = $this->formatDate($date);
|
||||||
|
$records[] = isset($data[$date]) ? $data[$date] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$color = '51,122,183';
|
||||||
|
/*
|
||||||
|
if ($entityType == ENTITY_INVOICE) {
|
||||||
|
$color = '51,122,183';
|
||||||
|
} elseif ($entityType == ENTITY_PAYMENT) {
|
||||||
|
$color = '54,193,87';
|
||||||
|
} elseif ($entityType == ENTITY_EXPENSE) {
|
||||||
|
$color = '128,128,128';
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
$record = new stdClass();
|
||||||
|
$record->data = $records;
|
||||||
|
$record->label = trans("texts.{$dimension}");
|
||||||
|
$record->lineTension = 0;
|
||||||
|
$record->borderWidth = 4;
|
||||||
|
$record->borderColor = "rgba({$color}, 1)";
|
||||||
|
$record->backgroundColor = "rgba({$color}, 0.1)";
|
||||||
|
$datasets[] = $record;
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = new stdClass();
|
||||||
|
$data->labels = $labels;
|
||||||
|
$data->datasets = $datasets;
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,10 @@ class ActivityReport extends AbstractReport
|
|||||||
$activity->present()->user,
|
$activity->present()->user,
|
||||||
$this->isExport ? strip_tags($activity->getMessage()) : $activity->getMessage(),
|
$this->isExport ? strip_tags($activity->getMessage()) : $activity->getMessage(),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$this->addChartData(ENTITY_ACTIVITY, $activity->created_at, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//dd($this->getChartData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
@if (Auth::user()->hasPermission('view_all'))
|
@if (Auth::user()->hasPermission('view_all'))
|
||||||
function loadChart(data) {
|
function loadChart(data) {
|
||||||
console.log(data);
|
|
||||||
var ctx = document.getElementById('chart-canvas').getContext('2d');
|
var ctx = document.getElementById('chart-canvas').getContext('2d');
|
||||||
if (window.myChart) {
|
if (window.myChart) {
|
||||||
window.myChart.config.data = data;
|
window.myChart.config.data = data;
|
||||||
|
91
resources/views/reports/chart_builder.blade.php
Normal file
91
resources/views/reports/chart_builder.blade.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
function loadChart(data) {
|
||||||
|
var ctx = document.getElementById('chart-canvas').getContext('2d');
|
||||||
|
if (window.myChart) {
|
||||||
|
window.myChart.config.data = data;
|
||||||
|
window.myChart.config.options.scales.xAxes[0].time.unit = chartGroupBy.toLowerCase();
|
||||||
|
window.myChart.config.options.scales.xAxes[0].time.round = chartGroupBy.toLowerCase();
|
||||||
|
window.myChart.update();
|
||||||
|
} else {
|
||||||
|
$('#progress-div').hide();
|
||||||
|
$('#chart-canvas').fadeIn();
|
||||||
|
window.myChart = new Chart(ctx, {
|
||||||
|
type: 'line',
|
||||||
|
data: data,
|
||||||
|
options: {
|
||||||
|
tooltips: {
|
||||||
|
mode: 'x-axis',
|
||||||
|
titleFontSize: 15,
|
||||||
|
titleMarginBottom: 12,
|
||||||
|
bodyFontSize: 15,
|
||||||
|
bodySpacing: 10,
|
||||||
|
callbacks: {
|
||||||
|
title: function(item) {
|
||||||
|
return moment(item[0].xLabel).format("{{ $account->getMomentDateFormat() }}");
|
||||||
|
},
|
||||||
|
label: function(item, data) {
|
||||||
|
/*
|
||||||
|
if (item.datasetIndex == 0) {
|
||||||
|
var label = " {!! trans('texts.invoices') !!}: ";
|
||||||
|
} else if (item.datasetIndex == 1) {
|
||||||
|
var label = " {!! trans('texts.payments') !!}: ";
|
||||||
|
} else if (item.datasetIndex == 2) {
|
||||||
|
var label = " {!! trans('texts.expenses') !!}: ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return label + formatMoney(item.yLabel, chartCurrencyId, account.country_id);
|
||||||
|
*/
|
||||||
|
|
||||||
|
return 'test';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
display: false,
|
||||||
|
fontSize: 18,
|
||||||
|
text: '{{ trans('texts.total_revenue') }}'
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
type: 'time',
|
||||||
|
time: {
|
||||||
|
unit: chartGroupBy,
|
||||||
|
round: chartGroupBy,
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
ticks: {
|
||||||
|
beginAtZero: true,
|
||||||
|
callback: function(label, index, labels) {
|
||||||
|
return roundSignificant(label);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var account = {!! $account !!};
|
||||||
|
var chartGroupBy = "{{ $report->chartGroupBy() }}";
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
var chartData = {!! json_encode($report->getChartData()) !!};
|
||||||
|
console.log(chartData);
|
||||||
|
loadChart(chartData);
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<canvas id="chart-canvas" style="background-color:white; padding:20px; width:100%; height: 250px;"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p> </p>
|
@ -81,7 +81,7 @@
|
|||||||
ticks: {
|
ticks: {
|
||||||
beginAtZero: true,
|
beginAtZero: true,
|
||||||
callback: function(label, index, labels) {
|
callback: function(label, index, labels) {
|
||||||
return label;
|
return roundSignificant(label);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}]
|
}]
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
@include('money_script')
|
@include('money_script')
|
||||||
|
|
||||||
|
<script src="{!! asset('js/Chart.min.js') !!}" type="text/javascript"></script>
|
||||||
|
|
||||||
<script src="{{ asset('js/daterangepicker.min.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script>
|
<script src="{{ asset('js/daterangepicker.min.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script>
|
||||||
<link href="{{ asset('css/daterangepicker.css') }}?no_cache={{ NINJA_VERSION }}" rel="stylesheet" type="text/css"/>
|
<link href="{{ asset('css/daterangepicker.css') }}?no_cache={{ NINJA_VERSION }}" rel="stylesheet" type="text/css"/>
|
||||||
|
|
||||||
@ -264,6 +266,9 @@
|
|||||||
</center>
|
</center>
|
||||||
|
|
||||||
@if (request()->report_type)
|
@if (request()->report_type)
|
||||||
|
|
||||||
|
@include('reports.chart_builder')
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user