first commit
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
<div class="row trips_containers">
|
||||
<div class="col-lg-4">
|
||||
<div class="summary-wrapper">
|
||||
<div class="sw-header">
|
||||
<p class="text-center"><strong>Activity</strong></p>
|
||||
<span class="currency">$</span>
|
||||
<span class="total-amount"><?=number_format($trip_report['total_amount'], 2)?></span>
|
||||
<p class="description">
|
||||
<?php
|
||||
$checkDateRangeExist = ( isset( $start_date ) and !empty( $start_date ) ) and ( isset( $end_date ) and !empty( $end_date ) );
|
||||
if ( $checkDateRangeExist ) {
|
||||
printf( 'Total money spent from %s to %s', $start_date, $end_date );
|
||||
} else {
|
||||
printf( 'Total money spent last %s days', $trip_report['data']['days'] );
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="sw-content">
|
||||
<?php foreach($trip_report['report'] as $category) { ?>
|
||||
<div class="item-summary <?php echo count($category['items']) > 0 ? 'active' : '' ?>" data-type="<?php echo $category['type'] ?>">
|
||||
<div class="category"><?=$category['type']?></div>
|
||||
<div class="amount">
|
||||
<p class="currency">$</p>
|
||||
<p class="category-total"><?=number_format($category['spent'], 2)?></p>
|
||||
<p class="right-icon"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-arrow-right-circle" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
|
||||
<path fill-rule="evenodd" d="M7.646 11.354a.5.5 0 0 1 0-.708L10.293 8 7.646 5.354a.5.5 0 1 1 .708-.708l3 3a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708 0z"/>
|
||||
<path fill-rule="evenodd" d="M4.5 8a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5z"/>
|
||||
</svg></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<p class="transport-category"></p>
|
||||
<div class="details-wrapper">
|
||||
<table id="transportDetails" style="background-color:aliceblue" class="table table-striped table-hover table-bordered table-condensed">
|
||||
<thead class="bg-indigo">
|
||||
<tr>
|
||||
<th>Data Source</th>
|
||||
<th>ID</th>
|
||||
<th>Import ID</th>
|
||||
<th>Member ID</th>
|
||||
<th>Amount</th>
|
||||
<th>Currency</th>
|
||||
<th>Description</th>
|
||||
<th>Time</th>
|
||||
<th>Category</th>
|
||||
<th>Provider Category</th>
|
||||
<th>Merchant Name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
const tripData = JSON.parse('<?php echo json_encode($trip_report) ?>');
|
||||
const memberID = (tripData.data || {}).member_id || '';
|
||||
$(document).ready(function() {
|
||||
$('.item-summary.active').on('click', function(e) {
|
||||
const transportType = $(this).data('type');
|
||||
const transportData = tripData.report.find(item => item.type === transportType) || {items: []};
|
||||
const transportItems = parseTransportDetails(transportData.items);
|
||||
const transportItemsHtml = transportItems.map(item => {
|
||||
return gernerateDetail(item);
|
||||
}).join(' ');
|
||||
|
||||
$('.transport-category').text(transportType);
|
||||
$('#transportDetails tbody').html(transportItemsHtml);
|
||||
});
|
||||
|
||||
// find and get first category which has data for display on table
|
||||
let firstData = null;
|
||||
for(let i = 0; i < tripData.report.length; i++) {
|
||||
const item = tripData.report[i];
|
||||
if (!item || !item.items || !item.items.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
firstData = item;
|
||||
break;
|
||||
}
|
||||
|
||||
if (firstData) {
|
||||
const transportItems = parseTransportDetails(firstData.items);
|
||||
const transportItemsHtml = transportItems.map(item => {
|
||||
return gernerateDetail(item);
|
||||
}).join(' ');
|
||||
|
||||
$('.transport-category').text(firstData.type || '');
|
||||
$('#transportDetails tbody').html(transportItemsHtml);
|
||||
}
|
||||
// End find and get first data
|
||||
});
|
||||
|
||||
function parseTransportDetails($data) {
|
||||
return $data.map(item => {
|
||||
return Object.assign({}, item, {
|
||||
currency: formatCurrency(item.currency),
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
function formatCurrency(currency) {
|
||||
return currency.replace(/[0-9]/g, '');
|
||||
}
|
||||
|
||||
function gernerateDetail(data) {
|
||||
let data_source = '';
|
||||
if(data.hasOwnProperty('import_id') && data.import_id){
|
||||
data_source = 'Bank';
|
||||
}else if(data.hasOwnProperty('trackedemail_item_id') && data.trackedemail_item_id){
|
||||
data_source = 'Email';
|
||||
}
|
||||
return `
|
||||
<tr>
|
||||
<td>${data_source}</td>
|
||||
<td>${data.id || ''}</td>
|
||||
<td>${data.import_id || ''}</td>
|
||||
<td>${data.member_id || memberID || ''}</td>
|
||||
<td>${data.cost || ''}</td>
|
||||
<td>${data.currency || ''}</td>
|
||||
<td>${data.description || ''}</td>
|
||||
<td>${data.travel_date || ''}</td>
|
||||
<td>${data.category || ''}</td>
|
||||
<td>${data.provider_category || ''}</td>
|
||||
<td>${data.transport_provider_name || ''}</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,26 @@
|
||||
<hr/>
|
||||
<h4 class="text-center">Activities cards</h4>
|
||||
<table class="activities-cards-table table-bordered table-condensed table-hover table-striped table-condensed d-none mb-15" style="background-color:#f0f8ff;" width="100%">
|
||||
<thead class="bg-indigo">
|
||||
<tr>
|
||||
<th>Card ID</th>
|
||||
<th>Description</th>
|
||||
<th>Action</th>
|
||||
<th>Card Icon</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($activities_cards ?? [] as $item){ ?>
|
||||
<tr>
|
||||
<td><?=$item['card_id']??''?></td>
|
||||
<td><?=$item['detail_data']['description']??''?></td>
|
||||
<td><?=$item['detail_data']['action']??''?></td>
|
||||
<td><?=$item['detail_data']['card_icon']??''?></td>
|
||||
</tr>
|
||||
<?php }
|
||||
if(empty($activities_cards ?? [])){
|
||||
echo '<tr class="text-center"><td colspan="100%">Empty result</td></tr>';
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
// EMISSIONS CALC
|
||||
$emissions = $emission_charts = [];
|
||||
// filter by range date
|
||||
$checkDateRangeExist = ( isset( $start_date ) and !empty( $start_date ) ) and ( isset( $end_date ) and !empty( $end_date ) );
|
||||
if ( $checkDateRangeExist ) {
|
||||
$start_date = str_replace( '-', '/', $start_date );
|
||||
$end_date = str_replace('-', '/', $end_date);
|
||||
$emission_data['report'] = array_filter( $emission_data['report'], function( $e ) use ( $start_date, $end_date ) {
|
||||
$report_time = strtotime( $e['date'] );
|
||||
if ( $report_time >= strtotime( $start_date ) and $report_time <= strtotime( $end_date ) ) {
|
||||
return $e;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
$emissionTotalItems = isset($emission_data["report"]) ? count($emission_data["report"]) : 0;
|
||||
|
||||
// do not separation by date if have date range params
|
||||
if ( ! $checkDateRangeExist ) {
|
||||
if ($emissionTotalItems >= 7) {
|
||||
$emissions['7D'] = array_reverse(array_slice($emission_data['report'], 0, 7));
|
||||
}
|
||||
if ($emissionTotalItems >= 30) {
|
||||
$emissions['30D'] = array_reverse(array_slice($emission_data['report'], 0, 30));
|
||||
if ($emissionTotalItems > 30) {
|
||||
$emissions[$emissionTotalItems . 'D'] = array_reverse($emission_data['report']);
|
||||
}
|
||||
} elseif ($emissionTotalItems > 0) {
|
||||
$emissions[$emissionTotalItems . 'D'] = array_reverse($emission_data['report']);
|
||||
}
|
||||
} else {
|
||||
$emissions['dateranges'] = array_reverse( $emission_data['report'] );
|
||||
}
|
||||
|
||||
foreach ($emissions as $key_day => $ems) {
|
||||
$em_chart = [
|
||||
'labels' => [],
|
||||
'data' => [],
|
||||
'total_value' => 0
|
||||
];
|
||||
$total = 0;
|
||||
foreach ($ems as $em) {
|
||||
$total+=$em['value'];
|
||||
}
|
||||
foreach ($ems as $em) {
|
||||
$em_chart['labels'][] = $em['date'].'/'.$total;
|
||||
$em_chart['data'][] = round($em['value'],2);//($em['value']*100/$total);
|
||||
|
||||
}
|
||||
$em_chart['total_value'] += $total;
|
||||
$emission_charts[$key_day] = $em_chart;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="col-lg-7 overflow-auto">
|
||||
<?php
|
||||
foreach ($emissions as $key_day => $ems) {
|
||||
?>
|
||||
<div class="table_emission_wrap" id="table_emission_wrap_<?= $key_day ?>">
|
||||
<table class="table_emission table table-striped table-border-solid"
|
||||
id="table_emission_<?= $key_day ?>">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>#</th>
|
||||
<th>Date</th>
|
||||
<th>Emission</th>
|
||||
<th>GAS</th>
|
||||
<th>GAS Emission</th>
|
||||
<th>Merchant name</th>
|
||||
<th>Transaction amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$ii = 0;
|
||||
foreach ($ems as $rows) {
|
||||
$ii++;
|
||||
echo '<tr>';
|
||||
echo '<td>' . $ii . '</td>';
|
||||
echo '<td>' . $ii . '</td>';
|
||||
echo '<td>' . $rows["date"] . '</td>';
|
||||
echo '<td><span' . ($rows["value"] > 0 ? ' style="font-weight:bold;"' : '') . '>' . number_format($rows["value"], 2) . '</span></td>';
|
||||
echo '<td><span' . ($rows["value"] > 0 ? ' style="font-weight:bold;"' : '') . '>' . number_format($rows["gas"], 2) . '</span></td>';
|
||||
echo '<td><span' . ($rows["value"] > 0 ? ' style="font-weight:bold;"' : '') . '>' . number_format($rows["gas_emission"], 2) . '</span></td>';
|
||||
echo '<td>' . $rows["merchant_name"]??'-' . '</td>';
|
||||
echo '<td>' . $rows["amount"]??'-' . '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col-lg-5 overflow-auto">
|
||||
<h4 class="text-center">Emission Chart</h4>
|
||||
<?php if ( !$checkDateRangeExist ): ?>
|
||||
<div class="text-center" style="margin-bottom: 8px;">
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<?php
|
||||
foreach (array_keys($emission_charts) as $id) {
|
||||
echo '<button type="button" id="btn_switch_emission_' . $id . '" class="btn_switch_emission btn btn-outline-secondary" onclick="fn_show_emission_(\'' . $id . '\')">' . $id . '</button>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<?php
|
||||
foreach ((array_keys($emission_charts)) as $em_chart_id) {
|
||||
echo '<canvas class="emission_chart" id="emission_chart_' . $em_chart_id . '" height="500px" width="800px"></canvas>';
|
||||
}
|
||||
?>
|
||||
|
||||
<div>
|
||||
<?php
|
||||
$activities_cards = $emission_data['options']['cards']??[];
|
||||
include( __DIR__ . '/cards.php' ); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var emission_charts = <?php echo json_encode($emission_charts); ?>;
|
||||
var emission_keys = <?php echo json_encode(array_keys($emission_charts)); ?>;
|
||||
$(function () {
|
||||
emission_keys.forEach(function (id) {
|
||||
$('#table_emission_' + id).DataTable({
|
||||
"columnDefs": [
|
||||
{
|
||||
"targets": [1],
|
||||
"visible": false,
|
||||
"searchable": false
|
||||
}
|
||||
],
|
||||
"order": [[2, "desc"]]
|
||||
});
|
||||
});
|
||||
for (var chart_id in emission_charts) {
|
||||
var em_chart = emission_charts[chart_id];
|
||||
var ctx = document.getElementById("emission_chart_" + chart_id);
|
||||
if ( ctx == null ) {
|
||||
continue;
|
||||
}
|
||||
new Chart(ctx, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: em_chart.labels,
|
||||
datasets: [{
|
||||
label: numberWithCommas(em_chart.total_value.toFixed(2)) + ' kg/CO2',
|
||||
data: em_chart.data,
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {},
|
||||
plugins: { labels: { render: 'value' } },
|
||||
// plugins: {
|
||||
// labels: {
|
||||
// render: function (args) {
|
||||
// console.log(args);
|
||||
// let sum = em_chart.data.reduce(function(a, b) { return a + b; }, 0);
|
||||
// var prc = (args.value*100/sum);
|
||||
// return prc > 0 ? prc.toFixed(1) + '%' : '';
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function(tooltipItem) {
|
||||
var total = parseFloat(tooltipItem.label.split('/')[1]);
|
||||
var prc = parseFloat(tooltipItem.yLabel)*100/total;
|
||||
return tooltipItem.yLabel+'kg/CO2 - '+prc.toFixed(1) + "%";
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
display: true,
|
||||
ticks: {
|
||||
min: 0,
|
||||
},
|
||||
}],
|
||||
xAxes: [{
|
||||
display: true,
|
||||
ticks: {
|
||||
callback: function (value) {
|
||||
return value.split("/")[0];
|
||||
},
|
||||
},
|
||||
}],
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function fn_show_emission_(id) {
|
||||
$('.emission_chart').hide();
|
||||
$('#emission_chart_' + id).show();
|
||||
|
||||
$('.table_emission_wrap').hide();
|
||||
$('#table_emission_wrap_' + id).show();
|
||||
|
||||
$(".btn_switch_emission").removeClass('btn-success');
|
||||
$("#btn_switch_emission_" + id).addClass('btn-success');
|
||||
}
|
||||
|
||||
if (emission_keys.length > 0) {
|
||||
//trigger show first days default
|
||||
fn_show_emission_(emission_keys[0]);
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,120 @@
|
||||
<div class="col-lg-12 overflow-auto">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Total or City Data</th>
|
||||
<th scope="col">Users Data</th>
|
||||
<th scope="col" class="text-center">Plot</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row" style="max-width: 25%">
|
||||
<table class="table table-striped">
|
||||
<?php
|
||||
$ii = $radar_data_sum_value = 0;
|
||||
foreach ($radar_data["report"][0] as $rows) {
|
||||
$radar_data_sum_value += $rows['value']??0;
|
||||
}
|
||||
foreach ($radar_data["report"][0] as &$rows) {
|
||||
$ii++;
|
||||
$prc = $rows["value"]>0?$rows["value"]*100/$radar_data_sum_value:0;
|
||||
$rows['prc'] = round($prc, 2);
|
||||
echo '<tr>';
|
||||
echo '<td>'.$ii.'</td>';
|
||||
echo '<td>'.$rows["axis"].'</td>';
|
||||
echo '<td title="'.$rows['value'].'">'.$rows['prc'].'%</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</th>
|
||||
<td style="max-width: 25%">
|
||||
<table class="table table-striped">
|
||||
<?php
|
||||
$ii = 0;
|
||||
$radar_data_sum_value = 0;
|
||||
foreach ($radar_data["report"][1] as &$rows) {
|
||||
$radar_data_sum_value += $rows['value']??0;
|
||||
}
|
||||
foreach ($radar_data["report"][1] as &$rows) {
|
||||
$ii++;
|
||||
$prc = $rows["value"]>0?$rows["value"]*100/$radar_data_sum_value:0;
|
||||
$rows['prc'] = round($prc, 2);
|
||||
echo '<tr>';
|
||||
echo '<td>'.$ii.'</td>';
|
||||
echo '<td>'.$rows["axis"].'</td>';
|
||||
echo '<td title="'.$rows['value'].'" '.($rows['prc']>0?'style="font-weight:bold;"':'').'>'.$rows['prc'].'%</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</td>
|
||||
<td style="width: 50%">
|
||||
<canvas id="personaltyRadarChart"></canvas>
|
||||
<script>
|
||||
var radar_data = <?php echo json_encode($radar_data) ?>;
|
||||
var radar_labels = [], radar_data_value_total = [],
|
||||
radar_data_value_user = [];
|
||||
radar_data.report[0].forEach(function (element, ielement) {
|
||||
radar_labels.push(element.axis);
|
||||
radar_data_value_total.push(element.prc);
|
||||
});
|
||||
radar_data_value_user = radar_data.report[1].reduce(function (a, b) {
|
||||
a.push(parseFloat(b.prc));
|
||||
return a;
|
||||
}, []);
|
||||
var marksCanvas = document.getElementById("personaltyRadarChart");
|
||||
var marksData = {
|
||||
labels: radar_labels,
|
||||
datasets: [{
|
||||
label: "Your travel",
|
||||
backgroundColor: "rgba(200,0,0,0.2)",
|
||||
data: radar_data_value_user
|
||||
}, {
|
||||
label: "Avg person in your city",
|
||||
backgroundColor: "rgba(0,0,200,0.2)",
|
||||
data: radar_data_value_total
|
||||
}]
|
||||
};
|
||||
var radarChart = new Chart(marksCanvas, {
|
||||
type: 'radar',
|
||||
data: marksData,
|
||||
options: {
|
||||
backgroundColor: 'red',
|
||||
scale: {
|
||||
gridLines: {
|
||||
circular: true
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
},
|
||||
pointLabels: {
|
||||
fontSize: 14,
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
labels: {
|
||||
render: 'percentage',
|
||||
fontColor: function (data) {
|
||||
var rgb = chartHexToRgb(data.dataset.backgroundColor[data.index]);
|
||||
var threshold = 140;
|
||||
var luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;
|
||||
return luminance > threshold ? 'black' : 'white';
|
||||
},
|
||||
precision: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<?php
|
||||
$activities_cards = $radar_data['options']['cards']??[];
|
||||
include( __DIR__ . '/cards.php' ); ?>
|
||||
</div>
|
||||
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
$spents = [];
|
||||
if (isset($speding_category7) && isset($speding_category7["report"])) {
|
||||
$spents['7D'] = $speding_category7;
|
||||
}
|
||||
if (isset($speding_category30) && isset($speding_category30["report"])) {
|
||||
$spents['30D'] = $speding_category30;
|
||||
}
|
||||
if (isset($speding_category) && isset($speding_category["report"])) {
|
||||
$spents['60D'] = $speding_category;
|
||||
}
|
||||
if (isset($speding_category_daysrange) && isset($speding_category_daysrange['report'])) {
|
||||
$spents['daysrange'] = $speding_category_daysrange;
|
||||
}
|
||||
$spent_charts = [];
|
||||
$colors = ["#3e95cd", "#8e5ea2", "#3cba9f", "#e8c3b9", "#c45850", "#969696"];
|
||||
$spent_keys = array_keys($spents);
|
||||
$checkDateRangeExist = ( isset( $start_date ) and !empty( $start_date ) ) and ( isset( $end_date ) and !empty( $end_date ) );
|
||||
?>
|
||||
|
||||
<div class="col-lg-4 overflow-auto">
|
||||
<?php
|
||||
foreach ($spents as $spent_id => $spent) {
|
||||
?>
|
||||
<div class="spent_table_wrap" id="spent_table_wrap_<?= $spent_id ?>">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">Type</th>
|
||||
<th scope="col">Amount</th>
|
||||
<th scope="col">Percent</th>
|
||||
<th scope="col">Detail</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$ii = 0;
|
||||
$spent_chart_item = [
|
||||
'labels' => [],
|
||||
'total_spent' => 0,
|
||||
'datasets' => [
|
||||
'data' => [],
|
||||
'backgroundColor' => []
|
||||
]
|
||||
];
|
||||
$total_spent = 0;
|
||||
foreach ($spent["report"] as $rows) {
|
||||
$total_spent += (float)$rows['spent'];
|
||||
}
|
||||
|
||||
foreach ($spent["report"] as $rows) {
|
||||
$ii++;
|
||||
$prc = $total_spent > 0 ? ((float)$rows['spent']??0)*100/($total_spent?:1) : 0;
|
||||
echo '<tr>';
|
||||
echo '<td>'.$ii.'</td>';
|
||||
echo '<td>'.$rows["type"].'</td>';
|
||||
echo '<td>'.$rows["spent"].'</td>';
|
||||
echo '<td '.($prc>0?'style="font-weight:bold;"':'').'>'.number_format($prc,2,'.','').'%</td>';
|
||||
echo '<td></td>';
|
||||
echo '</tr>';
|
||||
//echo "<tr><td>$ii</td><td>" . $rows["type"] . "</td><td>" . $rows["spent"] . "</td><td></td></tr>";
|
||||
$spent_chart_item['labels'][] = $rows["type"] ?? '-';
|
||||
$spent_chart_item['datasets']['data'][] = (float)$rows["spent"] ?? 0;
|
||||
$spent_chart_item['datasets']['backgroundColor'][] = isset($colors[$ii - 1]) ? $colors[$ii - 1] : '#49ff00';
|
||||
}
|
||||
$spent_chart_item['total_spent'] = $total_spent;
|
||||
$spent_charts[$spent_id] = $spent_chart_item;
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class="col-lg-8 overflow-auto">
|
||||
<?php if ( ! $checkDateRangeExist ): ?>
|
||||
<div class="text-center" style="margin-bottom: 8px;">
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<?php
|
||||
foreach ($spent_keys as $id) {
|
||||
echo '<button type="button" id="btn_switch_spent_' . $id . '"
|
||||
class="btn_switch_spent btn btn-outline-secondary"
|
||||
onclick="fn_show_spent_(\'' . $id . '\')">' . $id . '</button>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<?php
|
||||
foreach ($spent_keys as $id) {
|
||||
echo '<canvas id="spent_category_chart_' . $id . '" class="spent_chart" width="800" height="450"></canvas>';
|
||||
}
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
function chartHexToRgb(hex) {
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
}
|
||||
|
||||
var spent_categore_charts = <?=json_encode($spent_charts)?>;
|
||||
var spent_keys = <?=json_encode(array_keys($spent_charts))?>;
|
||||
for (var spent_id in spent_categore_charts) {
|
||||
var spent_char_data = spent_categore_charts[spent_id];
|
||||
var showTitle = '<?php echo !$checkDateRangeExist ? 'true' : 'false'; ?>';
|
||||
var _title;
|
||||
if ( showTitle == 'true' ) {
|
||||
_title = 'Spend Category Chart ' + spent_id;
|
||||
} else {
|
||||
_title = 'Spend Category Chart from ' + '<?php if ( isset( $start_date ) ) echo $start_date; ?>' + ' to ' + '<?php if ( isset( $end_date ) ) echo $end_date; ?>';
|
||||
}
|
||||
|
||||
var ctx = document.getElementById("spent_category_chart_" + spent_id);
|
||||
if ( ctx == null ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
new Chart(ctx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: spent_char_data.labels,
|
||||
datasets: [
|
||||
{
|
||||
backgroundColor: spent_char_data.datasets.backgroundColor,
|
||||
data: spent_char_data.datasets.data,
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: [_title,'Total Spend: $'+spent_char_data.total_spent]
|
||||
},
|
||||
tooltips: {
|
||||
enabled: true
|
||||
},
|
||||
plugins: {
|
||||
labels: {
|
||||
textShadow: true,
|
||||
render: function (args) {
|
||||
return args.percentage+'%\n$'+args.value;
|
||||
},
|
||||
fontColor: function (data) {
|
||||
var rgb = chartHexToRgb(data.dataset.backgroundColor[data.index]);
|
||||
var threshold = 140;
|
||||
var luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;
|
||||
return luminance > threshold ? 'black' : 'white';
|
||||
},
|
||||
precision: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fn_show_spent_(id) {
|
||||
$('.spent_chart').hide();
|
||||
$('#spent_category_chart_' + id).show();
|
||||
|
||||
$('.spent_table_wrap').hide();
|
||||
$('#spent_table_wrap_' + id).show();
|
||||
|
||||
$(".btn_switch_spent").removeClass('btn-success');
|
||||
$("#btn_switch_spent_" + id).addClass('btn-success');
|
||||
}
|
||||
|
||||
if (spent_keys.length > 0) {
|
||||
//trigger show first days default
|
||||
fn_show_spent_(spent_keys[0]);
|
||||
}
|
||||
</script>
|
||||
<div>
|
||||
<?php
|
||||
$activities_cards = $speding_category7['options']['cards']??[];
|
||||
include( __DIR__ . '/cards.php' ); ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,334 @@
|
||||
<?php
|
||||
$ttrs = $ttrCharts = [];
|
||||
$ttrTotalItems = isset($timetravel_data['report']) ? count($timetravel_data['report']) : 0;
|
||||
|
||||
$checkDateRangeExist = ( isset( $start_date ) and !empty( $start_date ) ) and ( isset( $end_date ) and !empty( $end_date ) );
|
||||
|
||||
if ( !$checkDateRangeExist ) {
|
||||
if ($ttrTotalItems >= 7) {
|
||||
$ttrs['7D'] = array_slice($timetravel_data['report'], -7, 7, true);
|
||||
}
|
||||
if ($ttrTotalItems >= 30) {
|
||||
$ttrs['30D'] = array_slice($timetravel_data['report'], -30, 30, true);
|
||||
if ($ttrTotalItems > 30) {
|
||||
$ttrs[$ttrTotalItems . 'D'] = $timetravel_data['report'];
|
||||
}
|
||||
} elseif ($ttrTotalItems > 0) {
|
||||
$ttrs[$ttrTotalItems . 'D'] = $timetravel_data['report'];
|
||||
}
|
||||
} else {
|
||||
$ttrs['dateranges'] = ( $ttrTotalItems > 0 ) ? array_reverse( $timetravel_data['report'] ) : array();
|
||||
}
|
||||
|
||||
$timeTravelledTotal7 = $timeTravelledTotal30 = $timeTravelledTotal60 = $daterangesTravelledTotal = $daysCounter = 0;
|
||||
if ($ttrTotalItems > 0) {
|
||||
//array_reverse to get newest
|
||||
foreach (array_reverse($timetravel_data['report']) as $k => $v) {
|
||||
$daysCounter++;
|
||||
$timeTravelled = 0;
|
||||
|
||||
if (isset($v[$k])) {
|
||||
$timeTravelled = 0;//$v[$k]['duration'] ?? 0;
|
||||
foreach ($v[$k] as $item_k){
|
||||
$timeTravelled+=$item_k['duration']??0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$checkDateRangeExist ) {
|
||||
if ($daysCounter <= 7) {
|
||||
$timeTravelledTotal7 += $timeTravelled;
|
||||
}
|
||||
if ($daysCounter <= 30) {
|
||||
$timeTravelledTotal30 += $timeTravelled;
|
||||
}
|
||||
if ($daysCounter <= 60) {
|
||||
$timeTravelledTotal60 += $timeTravelled;
|
||||
}
|
||||
} else {
|
||||
$daterangesTravelledTotal += $timeTravelled;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="col-lg-5 overflow-auto">
|
||||
<div class="f-two-tables" style="display: flex; flex-direction: column">
|
||||
<div class="table-responsive" style="order:1;margin-top: 10px;">
|
||||
<table class="table table-striped table-hover table-bordered table-condensed">
|
||||
<thead class="bg-indigo">
|
||||
<tr>
|
||||
<th></th>
|
||||
<?php if ( !$checkDateRangeExist ): ?>
|
||||
<th>7 days</th>
|
||||
<th>30 days</th>
|
||||
<th>60 days</th>
|
||||
<?php else: ?>
|
||||
<th><?php printf( 'from %s to %s', $start_date, $end_date ); ?></th>
|
||||
<?php endif ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th class="text-center">Total Time traveled</th>
|
||||
<?php if ( !$checkDateRangeExist ): ?>
|
||||
<td class="sys-ttv" data-minutes="<?=$timeTravelledTotal7??0?>"><?= $timeTravelledTotal7 ?? 0 ?> <strong></strong></td>
|
||||
<td class="sys-ttv" data-minutes="<?=$timeTravelledTotal30??0?>"><?= $timeTravelledTotal30 ?? 0 ?> <strong></strong></td>
|
||||
<td class="sys-ttv" data-minutes="<?=$timeTravelledTotal60??0?>"><?= $timeTravelledTotal60 ?? 0 ?> <strong></strong></td>
|
||||
<?php else: ?>
|
||||
<td><?php echo $daterangesTravelledTotal ?? 0; ?></td>
|
||||
<?php endif ?>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php if ( $ttrs ): ?>
|
||||
<?php foreach ( $ttrs as $totalDays => $timetravelDataReportFiltered ): ?>
|
||||
<div class="table-responsive timetravel_table_wrap"
|
||||
id="timetravel_table_wrap_<?= $totalDays ?>"
|
||||
style="order: 2; margin-top: 10px;">
|
||||
<table id="timetravel_table_<?= $totalDays ?>"
|
||||
class="table table-striped table-bordered"
|
||||
style="width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Transport Mode</th>
|
||||
<th>Transport Mode</th>
|
||||
<th>Merchant Name</th>
|
||||
<th>Distance Travelled</th>
|
||||
<th>Time Travelled</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$ttrChart = [
|
||||
'labels' => [],
|
||||
'data' => [],
|
||||
'total_minutes' => 0
|
||||
];
|
||||
$curTimeTravelledPoint = 0;
|
||||
|
||||
foreach ($timetravelDataReportFiltered as $k => $v) {
|
||||
$transportMode = $marchantName = '-';
|
||||
$distance = $v['distance'] ?? 0;
|
||||
$date = $v['date'] ?? '-';
|
||||
$marchantName = $transportMode = '-';
|
||||
$timeTravelled = $v['duration']??0;
|
||||
if (isset($v[$k])) {
|
||||
$category_default = $v[$k]['category']??'';
|
||||
$merchant_name_default = $v[$k]['merchant_name']??'';
|
||||
foreach ($v[$k] as $child){
|
||||
$timeTravelled += $child['duration']??0;
|
||||
echo '<tr>';
|
||||
echo '<td>' . ($child['category']??$category_default) . '</td>';
|
||||
echo '<td>' . ($child['category']??$category_default) . '</td>';
|
||||
echo '<td>' . ($child['merchant_name']??$merchant_name_default) . '</td>';
|
||||
echo '<td>' . $distance . '</td>';
|
||||
echo '<td>' . $child['duration'] . '</td>';
|
||||
echo '<td>' . $date . '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
}else{
|
||||
echo '<tr>';
|
||||
echo '<td>' . $transportMode . '</td>';
|
||||
echo '<td>' . $transportMode . '</td>';
|
||||
echo '<td>' . $marchantName . '</td>';
|
||||
echo '<td>' . $distance . '</td>';
|
||||
echo '<td>' . $timeTravelled . '</td>';
|
||||
echo '<td>' . $date . '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
$curTimeTravelledPoint += $timeTravelled; // time increase
|
||||
//final chart
|
||||
$ttrChart['labels'][] = $date;
|
||||
$ttrChart['data'][] = $curTimeTravelledPoint;
|
||||
$ttrChart['total_minutes'] += $timeTravelled;
|
||||
}
|
||||
//push charts
|
||||
$ttrCharts[$totalDays] = $ttrChart;
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
window.toHHMM = function (sec) {
|
||||
var sec_num = parseInt(sec, 10); // don't forget the second param
|
||||
var hours = Math.floor(sec_num / 3600);
|
||||
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
|
||||
var seconds = sec_num - (hours * 3600) - (minutes * 60);
|
||||
|
||||
if (hours < 10) {hours = "0"+hours;}
|
||||
if (minutes < 10 && hours>0) {minutes = "0"+minutes;}
|
||||
if (seconds < 10) {seconds = "0"+seconds;}
|
||||
if(parseInt(hours)>0){
|
||||
return hours+'h '+minutes+'m';
|
||||
}
|
||||
return minutes+'m';
|
||||
}
|
||||
// format time in total time traveled
|
||||
$(function(){
|
||||
$('td.sys-ttv').each(function(){
|
||||
let minutes = $(this).data('minutes') || 0;
|
||||
$(this).find('strong').first().html('<br/>'+toHHMM(minutes*60));
|
||||
});
|
||||
});
|
||||
|
||||
var timetravel_charts = <?php echo json_encode($ttrCharts); ?>;
|
||||
var timetravel_keys = <?php echo json_encode(array_keys($ttrs)); ?>;
|
||||
$(function () {
|
||||
timetravel_keys.forEach(function (id) {
|
||||
$('#timetravel_table_' + id).DataTable({
|
||||
"columnDefs": [
|
||||
{
|
||||
"targets": [1],
|
||||
"visible": false,
|
||||
"searchable": false
|
||||
}
|
||||
],
|
||||
"order": [[5, "desc"]]
|
||||
});
|
||||
});
|
||||
for (var chart_id in timetravel_charts) {
|
||||
var ctx = document.getElementById('timetravel_chart_' + chart_id);
|
||||
if ( ctx == null ) {
|
||||
continue;
|
||||
}
|
||||
ctx = ctx.getContext('2d');
|
||||
var yticks = {
|
||||
min: 0, // it is for ignoring negative step.
|
||||
beginAtZero: true,
|
||||
callback: function(value, index, values) {
|
||||
if (Math.floor(value) === value) {
|
||||
return value+'m';
|
||||
}
|
||||
}
|
||||
};
|
||||
if(timetravel_charts[chart_id].total_minutes>0){
|
||||
yticks = {
|
||||
beginAtZero: true,
|
||||
callback: function(label, index, labels) {
|
||||
return toHHMM(parseInt(label)*60);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
new Chart(ctx, {
|
||||
// The type of chart we want to create
|
||||
type: 'line', // also try bar or other graph types
|
||||
// The data for our dataset
|
||||
data: {
|
||||
labels: timetravel_charts[chart_id].labels,
|
||||
// Information about the dataset
|
||||
datasets: [{
|
||||
label: "Time travel",
|
||||
backgroundColor: 'lightblue',
|
||||
borderColor: 'royalblue',
|
||||
data: timetravel_charts[chart_id].data,
|
||||
}]
|
||||
},
|
||||
// Configuration options
|
||||
options: {
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
title: function(tooltipItem, data) {
|
||||
return data['labels'][tooltipItem[0]['index']];
|
||||
},
|
||||
label: function (tooltipItem, data) {
|
||||
return toHHMM(tooltipItem.value*60);
|
||||
},
|
||||
},
|
||||
backgroundColor: '#FFF',
|
||||
titleFontSize: 16,
|
||||
titleFontColor: '#0066ff',
|
||||
bodyFontColor: '#000',
|
||||
bodyFontSize: 14,
|
||||
displayColors: false
|
||||
},
|
||||
layout: {
|
||||
padding: 10,
|
||||
},
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Time travelled (' + toHHMM(timetravel_charts[chart_id].total_minutes*60) + ')'
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
scaleLabel: {
|
||||
display: true,
|
||||
labelString: 'Time value'
|
||||
},
|
||||
ticks: yticks,
|
||||
}],
|
||||
xAxes: [{
|
||||
scaleLabel: {
|
||||
display: true,
|
||||
labelString: chart_id
|
||||
},
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
},
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function fn_show_ttr(id) {
|
||||
$('.timetravel_chart').hide();
|
||||
$('#timetravel_chart_' + id).show();
|
||||
|
||||
$('.timetravel_table_wrap').hide();
|
||||
$('#timetravel_table_wrap_' + id).show();
|
||||
|
||||
$(".btn_switch_ttr").removeClass('btn-success');
|
||||
$("#btn_switch_ttr_" + id).addClass('btn-success');
|
||||
}
|
||||
|
||||
if (timetravel_keys.length > 0) {
|
||||
//trigger show first default
|
||||
fn_show_ttr(timetravel_keys[0]);//timetravel_keys.length - 1
|
||||
}
|
||||
</script>
|
||||
<div class="col-lg-7 overflow-auto">
|
||||
<?php if ($ttrTotalItems > 0) { ?>
|
||||
<h4>Time Travel Chart</h4>
|
||||
<?php if ( !$checkDateRangeExist ): ?>
|
||||
<div class="text-center" style="margin-bottom: 8px;">
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<?php
|
||||
foreach (array_keys($ttrs) as $id) {
|
||||
echo '<button type="button" id="btn_switch_ttr_' . $id . '" class="btn_switch_ttr btn btn-outline-secondary" onclick="fn_show_ttr(\'' . $id . '\')">' . $id . '</button>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<!-- Members online -->
|
||||
<div class="panel">
|
||||
<div class="panel-body">
|
||||
<?php
|
||||
foreach ($ttrCharts as $totalDays => $chart) {
|
||||
echo ' <canvas class="timetravel_chart" id="timetravel_chart_' . $totalDays . '" width="400" height="200"></canvas>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /members online -->
|
||||
<?php } ?>
|
||||
|
||||
|
||||
<div>
|
||||
<?php
|
||||
$activities_cards = $timetravel_data['options']['cards']??[];
|
||||
include( __DIR__ . '/cards.php' ); ?>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user