Add form for analytics forecasting #409

This commit is contained in:
Kendrick Chan 2020-05-23 23:07:00 +08:00
parent 760f823794
commit 06d3aa3b27
5 changed files with 172 additions and 16 deletions

View file

@ -186,7 +186,7 @@ main_menu:
acl: analytics.menu acl: analytics.menu
label: Analytics label: Analytics
icon: flaticon-graphic icon: flaticon-graphic
- id: analytics_forecast - id: analytics_forecast_form
acl: analytics.forecast acl: analytics.forecast
label: Forecasting label: Forecasting
parent: analytics parent: analytics

View file

@ -1,6 +1,11 @@
#geofence # analytics
analytics_forecast: analytics_forecast_form:
path: /analytics/forecast path: /analytics/forecast
controller: App\Controller\AnalyticsController::forecast controller: App\Controller\AnalyticsController::forecastForm
methods: [GET] methods: [GET]
analytics_forecast_submit:
path: /analytics/forecast
controller: App\Controller\AnalyticsController::forecastSubmit
methods: [POST]

View file

@ -26,21 +26,53 @@ class AnalyticsController extends Controller
* @Menu(selected="analytics_forecast") * @Menu(selected="analytics_forecast")
* @IsGranted("analytics.forecast") * @IsGranted("analytics.forecast")
*/ */
public function forecast(EntityManagerInterface $em) public function forecastForm(EntityManagerInterface $em)
{ {
$hub_list = [ 6, 4, 36, 7, 8, 126, 127, 18, 12, 9, 60, 10, 21, 135 ]; $hub_ids = [ 6, 4, 36, 7, 8, 126, 127, 18, 12, 9, 60, 10, 21, 135 ];
$hub_data = []; $all_hubs = $em->getRepository(Hub::class)->findAll();
foreach ($hub_list as $hub_id)
$hub_list = [];
foreach ($all_hubs as $hub)
{ {
$hub_data[$hub_id] = $this->generateHubData($em, $hub_id, 5000, new DateTime()); $hub_list[$hub->getID()] = $hub->getName() . ' - ' . $hub->getBranch();
} }
$params = [ $params = [
'hub_list' => $hub_list,
'default_hubs' => $hub_ids,
];
return $this->render('analytics/forecast_form.html.twig', $params);
}
/**
* @Menu(selected="analytics_forecast")
* @IsGranted("analytics.forecast")
*/
public function forecastSubmit(EntityManagerInterface $em, Request $req)
{
$hub_list = $req->request->get('hub_ids', []);
$distances = $req->request->get('distances', []);
$today = DateTime::createFromFormat('d M Y', $req->request->get('date'));
error_log(print_r($hub_list, true));
// $hub_list = [ 6, 4, 36, 7, 8, 126, 127, 18, 12, 9, 60, 10, 21, 135 ];
$hub_data = [];
foreach ($hub_list as $key => $hub_id)
{
$dist = $distances[$key];
$hub_data[$hub_id] = $this->generateHubData($em, $hub_id, $dist, $today);
}
$params = [
'date' => $today,
'hub_list' => $hub_data, 'hub_list' => $hub_data,
]; ];
return $this->render('analytics/forecast.html.twig', $params); return $this->render('analytics/forecast_submit.html.twig', $params);
} }
protected function generateHubData($em, $hub_id, $distance_limit, DateTime $today) protected function generateHubData($em, $hub_id, $distance_limit, DateTime $today)
@ -58,6 +90,9 @@ class AnalyticsController extends Controller
// initialize counters // initialize counters
$c_weekday = []; $c_weekday = [];
$c_day = []; $c_day = [];
// counter to check instances of hourly weekdays, so we can get average
$c_week_count = [];
// loop through job orders // loop through job orders
foreach ($jos as $jo) foreach ($jos as $jo)
@ -68,6 +103,7 @@ class AnalyticsController extends Controller
$day = $date->format('d'); $day = $date->format('d');
$weekday = $date->format('l'); $weekday = $date->format('l');
$hour = $date->format('H'); $hour = $date->format('H');
$week = $date->format('W');
// year day // year day
if (!isset($c_day[$year][$month][$day])) if (!isset($c_day[$year][$month][$day]))
@ -76,8 +112,19 @@ class AnalyticsController extends Controller
// weekday // weekday
if (!isset($c_weekday[$year][$month][$weekday][$hour])) if (!isset($c_weekday[$year][$month][$weekday][$hour]))
$c_weekday[$year][$month][$weekday][$hour] = 0; {
$c_weekday[$year][$month][$weekday][$hour]++; $c_weekday[$year][$month][$weekday][$hour]['total'] = 0;
$c_weekday[$year][$month][$weekday][$hour]['count'] = 0;
}
$c_weekday[$year][$month][$weekday][$hour]['total']++;
if (!isset($c_week_count[$year][$month][$week][$weekday][$hour]))
{
// error_log('week detected - ' . $week);
$c_week_count[$year][$month][$week][$weekday][$hour] = 1;
$c_weekday[$year][$month][$weekday][$hour]['count']++;
}
} }
// error_log(print_r($c_weekday, true)); // error_log(print_r($c_weekday, true));
@ -180,7 +227,13 @@ class AnalyticsController extends Controller
// get hour data // get hour data
if (isset($year_data[$month][$weekday][$hour])) if (isset($year_data[$month][$weekday][$hour]))
$data[$id]['y' . $year] = $year_data[$month][$weekday][$hour]; {
$year_id = 'y' . $year;
$data[$id][$year_id] = $year_data[$month][$weekday][$hour]['total'];
$data[$id][$year_id . '_count'] = $year_data[$month][$weekday][$hour]['count'];
$data[$id][$year_id . '_average'] = ceil($year_data[$month][$weekday][$hour]['total'] / $year_data[$month][$weekday][$hour]['count']);
}
} }
} }

View file

@ -0,0 +1,96 @@
{% extends 'base.html.twig' %}
{% block body %}
<!-- BEGIN: Subheader -->
<div class="m-subheader">
<div class="d-flex align-items-center">
<div class="mr-auto">
<h3 class="m-subheader__title">Analytics - Forecasting</h3>
</div>
</div>
</div>
<!-- END: Subheader -->
<div class="m-content">
<!--Begin::Section-->
<div class="row">
<div class="col-xl-12">
<div class="m-portlet m-portlet--mobile">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<span class="m-portlet__head-icon">
<i class="fa fa-building"></i>
</span>
<h3 class="m-portlet__head-text">
Forecasting Variables
</h3>
</div>
</div>
</div>
<form id="row-form" class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" method="post" action="{{ url('analytics_forecast_submit') }}">
<div class="m-portlet__body">
<div class="form-group m-form__group row no-border">
<div class="col-lg-6">
<label data-field="date">Date</label>
<div class="input-group date dp">
<input type="text" name="date" id="date" class="form-control m-input" value="{{ "now"|date('d M Y') }}" readonly placeholder="Select a date" >
<span class="input-group-addon">
<i class="la la-calendar glyphicon-th"></i>
</span>
</div>
<div class="form-control-feedback hide" data-field="date"></div>
</div>
</div>
{% for hub_id in default_hubs %}
<div class="row no-border" style="padding-left: 30px; padding-right: 30px; padding-bottom: 10px;">
<div class="col-lg-6">
<select name="hub_ids[]" class="form-control m-input">
{% for key, label in hub_list %}
<option value="{{ key }}" {{ hub_id == key ? ' selected' : ''}}>{{ label }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="name"></div>
</div>
<div class="col-lg-3">
<input type="text" name="distances[]" class="form-control m-input" value="5000">
<div class="form-control-feedback hide" data-field="branch"></div>
</div>
</div>
{% endfor %}
</div>
<div class="m-portlet__foot m-portlet__foot--fit">
<div class="m-form__actions m-form__actions--solid m-form__actions--right">
<div class="row">
<div class="col-lg-12">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
$(function() {
// datepicker
$(".dp").datepicker({
format: "dd M yyyy",
todayHighlight: true,
autoclose: true,
pickerPosition: 'top-left',
bootcssVer: 3,
clearBtn: true
});
});
</script>
{% endblock %}

View file

@ -5,7 +5,7 @@
<div class="m-subheader"> <div class="m-subheader">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
<div class="mr-auto"> <div class="mr-auto">
<h3 class="m-subheader__title">Analytics Forecasting</h3> <h3 class="m-subheader__title">Analytics Forecasting - {{ date | date('M - l') }}</h3>
</div> </div>
</div> </div>
</div> </div>
@ -58,6 +58,7 @@ categoryAxis.title.text = "Date";
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis()); var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.title.text = "Orders"; valueAxis.title.text = "Orders";
valueAxis.maxPrecision = 0;
// year day // year day
var s2018 = chart.series.push(new am4charts.LineSeries()); var s2018 = chart.series.push(new am4charts.LineSeries());
@ -92,19 +93,20 @@ xAxis.dataFields.category = "hour";
xAxis.title.text = "Hour"; xAxis.title.text = "Hour";
var yAxis = chart2.yAxes.push(new am4charts.ValueAxis()); var yAxis = chart2.yAxes.push(new am4charts.ValueAxis());
yAxis.title.text = "Orders"; yAxis.title.text = "Orders";
yAxis.maxPrecision = 0;
var l2018 = chart2.series.push(new am4charts.LineSeries()); var l2018 = chart2.series.push(new am4charts.LineSeries());
l2018.name = "2018"; l2018.name = "2018";
l2018.stroke = am4core.color("#0000FF"); l2018.stroke = am4core.color("#0000FF");
l2018.strokeWidth = 2; l2018.strokeWidth = 2;
l2018.dataFields.valueY = "y2018"; l2018.dataFields.valueY = "y2018_average";
l2018.dataFields.categoryX = "hour"; l2018.dataFields.categoryX = "hour";
var l2019 = chart2.series.push(new am4charts.LineSeries()); var l2019 = chart2.series.push(new am4charts.LineSeries());
l2019.name = "2019"; l2019.name = "2019";
l2019.stroke = am4core.color("#FF0000"); l2019.stroke = am4core.color("#FF0000");
l2019.strokeWidth = 3; l2019.strokeWidth = 3;
l2019.dataFields.valueY = "y2019"; l2019.dataFields.valueY = "y2019_average";
l2019.dataFields.categoryX = "hour"; l2019.dataFields.categoryX = "hour";
{% endfor %} {% endfor %}