Events by day stats added. DAY() DQL function added.
This commit is contained in:
parent
8544d9c7c3
commit
bfc40d595c
|
@ -57,6 +57,9 @@ doctrine:
|
|||
auto_generate_proxy_classes: "%kernel.debug%"
|
||||
naming_strategy: doctrine.orm.naming_strategy.underscore
|
||||
auto_mapping: true
|
||||
dql:
|
||||
string_functions:
|
||||
DAY: Skobkin\Bundle\PointToolsBundle\DQL\Day
|
||||
|
||||
doctrine_migrations:
|
||||
dir_name: "%kernel.root_dir%/DoctrineMigrations"
|
||||
|
|
2
composer.lock
generated
2
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "f92c288e2df400d18133f9cfdfd97bbb",
|
||||
"content-hash": "9b374e1b2cb413fbab3f0633d6f81c1a",
|
||||
"packages": [
|
||||
{
|
||||
"name": "csa/guzzle-bundle",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Skobkin\Bundle\PointToolsBundle\Controller;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Skobkin\Bundle\PointToolsBundle\DTO\DailyEvents;
|
||||
use Skobkin\Bundle\PointToolsBundle\DTO\TopUserDTO;
|
||||
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||
use Skobkin\Bundle\PointToolsBundle\Service\UserApi;
|
||||
|
@ -49,22 +50,63 @@ class UserController extends Controller
|
|||
|
||||
public function topAction(): Response
|
||||
{
|
||||
$topUsers = $this->getDoctrine()->getManager()->getRepository('SkobkinPointToolsBundle:User')->getTopUsers();
|
||||
|
||||
$topChart = $this->createTopUsersGraph($topUsers);
|
||||
$userRepo = $this->getDoctrine()->getManager()->getRepository('SkobkinPointToolsBundle:User');
|
||||
$subscriptionsRecordsRepo = $this->getDoctrine()->getManager()->getRepository('SkobkinPointToolsBundle:SubscriptionEvent');
|
||||
$topUsers = $userRepo->getTopUsers();
|
||||
$eventsByDay = $subscriptionsRecordsRepo->getLastEventsByDay();
|
||||
|
||||
return $this->render('@SkobkinPointTools/User/top.html.twig', [
|
||||
'top_users' => $topUsers,
|
||||
'top_chart' => $topChart,
|
||||
//'top_users' => $topUsers,
|
||||
'events_dynamic_chat' => $this->createEventsDynamicChart($eventsByDay),
|
||||
'top_chart' => $this->createTopUsersGraph($topUsers),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo move to the service
|
||||
*
|
||||
* @param TopUserDTO[] $topUsers
|
||||
* @param DailyEvents[] $eventsByDay
|
||||
*/
|
||||
private function createEventsDynamicChart(array $eventsByDay = []): Highchart
|
||||
{
|
||||
$translator = $this->get('translator');
|
||||
|
||||
$chartData = [
|
||||
'titles' => [],
|
||||
'events' => [],
|
||||
];
|
||||
|
||||
foreach ($eventsByDay as $day) {
|
||||
$chartData['titles'][] = $day->getDate()->format('d.m');
|
||||
$chartData['events'][] = $day->getEventsCount();
|
||||
}
|
||||
|
||||
$series = [[
|
||||
'name' => $translator->trans('Events'),
|
||||
'data' => $chartData['events'],
|
||||
]];
|
||||
|
||||
$ob = new Highchart();
|
||||
$ob->chart->renderTo('eventschart');
|
||||
$ob->chart->type('line');
|
||||
$ob->title->text($translator->trans('Events by day'));
|
||||
$ob->xAxis->title(['text' => null]);
|
||||
$ob->xAxis->categories($chartData['titles']);
|
||||
$ob->yAxis->title(['text' => $translator->trans('amount')]);
|
||||
$ob->plotOptions->bar([
|
||||
'dataLabels' => [
|
||||
'enabled' => true,
|
||||
]
|
||||
]);
|
||||
$ob->series($series);
|
||||
|
||||
return $ob;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo move to the service
|
||||
*
|
||||
* @return Highchart
|
||||
* @param TopUserDTO[] $topUsers
|
||||
*/
|
||||
private function createTopUsersGraph(array $topUsers = []): Highchart
|
||||
{
|
||||
|
|
26
src/Skobkin/Bundle/PointToolsBundle/DQL/Day.php
Normal file
26
src/Skobkin/Bundle/PointToolsBundle/DQL/Day.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Skobkin\Bundle\PointToolsBundle\DQL;
|
||||
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\Lexer;
|
||||
|
||||
class Day extends FunctionNode
|
||||
{
|
||||
public $dateExpression;
|
||||
|
||||
public function parse(\Doctrine\ORM\Query\Parser $parser)
|
||||
{
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||
|
||||
$this->dateExpression = $parser->ArithmeticPrimary();
|
||||
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||
}
|
||||
|
||||
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
|
||||
{
|
||||
return 'date_trunc(\'day\', '.$this->dateExpression->dispatch($sqlWalker).')';
|
||||
}
|
||||
}
|
35
src/Skobkin/Bundle/PointToolsBundle/DTO/DailyEvents.php
Normal file
35
src/Skobkin/Bundle/PointToolsBundle/DTO/DailyEvents.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Skobkin\Bundle\PointToolsBundle\DTO;
|
||||
|
||||
/**
|
||||
* Events count by day
|
||||
*/
|
||||
class DailyEvents
|
||||
{
|
||||
/**
|
||||
* @var \DateTime
|
||||
*/
|
||||
private $date;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $eventsCount;
|
||||
|
||||
public function __construct(string $date, int $eventsCount)
|
||||
{
|
||||
$this->date = new \DateTime($date);
|
||||
$this->eventsCount = $eventsCount;
|
||||
}
|
||||
|
||||
public function getDate(): \DateTime
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
public function getEventsCount(): int
|
||||
{
|
||||
return $this->eventsCount;
|
||||
}
|
||||
}
|
|
@ -93,4 +93,34 @@ class SubscriptionEventRepository extends EntityRepository
|
|||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SubscriptionEvent[]
|
||||
*/
|
||||
public function getLastEventsByDay(int $days = 30): array
|
||||
{
|
||||
$qb = $this->createQueryBuilder('se');
|
||||
|
||||
$rows = $qb
|
||||
->select([
|
||||
'NEW Skobkin\Bundle\PointToolsBundle\DTO\DailyEvents(DAY(se.date), COUNT(se))',
|
||||
'DAY(se.date) as day',
|
||||
])
|
||||
->groupBy('day')
|
||||
->orderBy('day', 'DESC')
|
||||
->setMaxResults($days)
|
||||
->getQuery()->getResult()
|
||||
;
|
||||
|
||||
$result = [];
|
||||
|
||||
// Removing unnecessary element, saving DTO
|
||||
// @todo remove crutches, refactor query
|
||||
foreach ($rows as $row) {
|
||||
unset($row['day']);
|
||||
$result[] = reset($row);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -10,8 +10,13 @@
|
|||
|
||||
{% block content %}
|
||||
<script type="text/javascript">
|
||||
// Top chart
|
||||
{{ chart(top_chart) }}
|
||||
// Events by day chart
|
||||
{{ chart(events_dynamic_chat) }}
|
||||
</script>
|
||||
|
||||
<div id="topchart" style="min-width: 400px; height: 600px; margin: 0 auto;"></div>
|
||||
|
||||
<div id="eventschart" style="min-width: 400px; height: 600px; margin: 0 auto;"></div>
|
||||
{% endblock %}
|
||||
|
|
Loading…
Reference in a new issue