Skip to content

Commit

Permalink
Fix js issue with displaying multiple dashboard charts
Browse files Browse the repository at this point in the history
  • Loading branch information
sampoyigi committed Jul 30, 2019
1 parent 8befbac commit 6ddda74
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 85 deletions.
7 changes: 7 additions & 0 deletions app/admin/controllers/Dashboard.php
Expand Up @@ -34,6 +34,7 @@ public function initDashboardContainer()
{
$this->containerConfig['canSetDefault'] = AdminAuth::isSuperUser();
$this->containerConfig['defaultWidgets'] = $this->getDefaultWidgets();
$this->containerConfig['canAddAndDelete'] = $this->canAddAndDeleteWidgets();

new DashboardContainer($this, $this->containerConfig);
}
Expand Down Expand Up @@ -91,4 +92,10 @@ protected function getDefaultWidgets()
],
];
}

protected function canAddAndDeleteWidgets()
{
return $this->getUser()->hasPermission('Admin.Dashboard.Add')
AND $this->getUser()->hasPermission('Admin.Dashboard.Delete');
}
}
91 changes: 11 additions & 80 deletions app/admin/dashboardwidgets/Charts.php
Expand Up @@ -5,22 +5,28 @@
use Admin\Models\Orders_model;
use Admin\Models\Reservations_model;
use Admin\Models\Reviews_model;
use Carbon\Carbon;
use DateInterval;
use DatePeriod;
use DB;
use Illuminate\Support\Collection;
use Admin\Traits\HasChartDatasets;

/**
* Charts dashboard widget.
*/
class Charts extends BaseDashboardWidget
{
use HasChartDatasets;

/**
* @var string A unique alias to identify this widget.
*/
protected $defaultAlias = 'charts';

protected $datasetOptions = [
'label' => null,
'data' => [],
'fill' => TRUE,
'backgroundColor' => null,
'borderColor' => null,
];

public function initialize()
{
$this->setProperty('rangeFormat', 'MMMM D, YYYY');
Expand All @@ -44,17 +50,6 @@ public function render()
return $this->makePartial('charts/charts');
}

public function loadAssets()
{
$this->addJs('~/app/system/assets/ui/js/vendor/moment.min.js', 'moment-js');
$this->addJs('vendor/daterange/daterangepicker.js', 'daterangepicker-js');
$this->addCss('vendor/daterange/daterangepicker.css', 'daterangepicker-css');

$this->addJs('vendor/chartjs/Chart.min.js', 'chartsjs-js');
$this->addCss('css/charts.css', 'charts-css');
$this->addJs('js/charts.js', 'charts-js');
}

public function listContext()
{
return [
Expand Down Expand Up @@ -85,17 +80,6 @@ public function listContext()
];
}

public function onFetchDatasets()
{
$start = post('start');
$end = post('end');

$start = Carbon::parse($start);
$end = Carbon::parse($end);

return $this->getDatasets($start, $end);
}

protected function getDatasets($start, $end)
{
$result = [];
Expand All @@ -105,57 +89,4 @@ protected function getDatasets($start, $end)

return $result;
}

protected function makeDataset($config, $start, $end)
{
list($r, $g, $b) = sscanf($config['color'], '#%02x%02x%02x');
$backgroundColor = sprintf('rgba(%s, %s, %s, 0.5)', $r, $g, $b);
$borderColor = sprintf('rgb(%s, %s, %s)', $r, $g, $b);

return [
'label' => lang($config['label']),
'data' => $this->queryDatasets($config, $start, $end),
'fill' => TRUE,
'backgroundColor' => $backgroundColor,
'borderColor' => $borderColor,
];
}

protected function queryDatasets($config, $start, $end)
{
$modelClass = $config['model'];
$dateColumnName = $config['column'];

$dateColumn = DB::raw('DATE_FORMAT('.$dateColumnName.', "%Y-%m-%d") as x');
$query = $modelClass::select($dateColumn, DB::raw('count(*) as y'));
$query->whereBetween($dateColumnName, [$start, $end])->groupBy('x');

$dateRanges = $this->getDatePeriod($start, $end);

return $this->getPointsArray($dateRanges, $query->get());
}

protected function getDatePeriod($start, $end)
{
return new DatePeriod(
Carbon::parse($start),
new DateInterval('P1D'),
Carbon::parse($end)
);
}

protected function getPointsArray($dateRanges, Collection $result)
{
$points = [];
$keyedResult = $result->keyBy('x');
foreach ($dateRanges as $date) {
$x = $date->format('Y-m-d');
$points[] = [
'x' => $x,
'y' => $keyedResult->get($x) ?? 0,
];
}

return $points;
}
}
8 changes: 6 additions & 2 deletions app/admin/dashboardwidgets/charts/assets/js/charts.js
Expand Up @@ -13,7 +13,7 @@
var ChartControl = function (element, options) {
this.options = options
this.$el = $(element)
this.$rangeEl = this.$el.find('[data-control="daterange"]')
this.$rangeEl = $(options.rangeSelector)
this.chartJs = null
this.rangePicker = null

Expand All @@ -25,6 +25,8 @@
ChartControl.DEFAULTS = {
alias: undefined,
rangeFormat: 'MMMM D, YYYY',
rangeSelector: '[data-control="daterange"]',
rangeParentSelector: '.chart-toolbar',
responsive: true,
type: 'line',
options: {
Expand Down Expand Up @@ -75,7 +77,9 @@
}

ChartControl.prototype.initDateRange = function () {
this.$rangeEl.daterangepicker(ChartControl.DATE_RANGE_DEFAULTS, $.proxy(this.onRangeSelected, this))
var options = ChartControl.DATE_RANGE_DEFAULTS
options.parentEl = this.options.rangeParentSelector
this.$rangeEl.daterangepicker(options, $.proxy(this.onRangeSelected, this))
this.rangePicker = this.$rangeEl.data('daterangepicker');

this.onRangeSelected(ChartControl.DATE_RANGE_DEFAULTS.startDate, ChartControl.DATE_RANGE_DEFAULTS.endDate)
Expand Down
8 changes: 7 additions & 1 deletion app/admin/dashboardwidgets/charts/charts.php
Expand Up @@ -4,10 +4,16 @@
class="chart-container"
data-control="chart"
data-alias="<?= $this->alias; ?>"
data-range-selector="#<?= $this->alias; ?>-daterange"
data-range-parent-selector="#<?= $this->alias; ?>-daterange-parent"
data-range-format="<?= $this->property('rangeFormat'); ?>"
>
<div class="chart-toolbar d-flex justify-content-end pb-3">
<div
id="<?= $this->alias; ?>-daterange-parent"
class="chart-toolbar d-flex justify-content-end pb-3"
>
<button
id="<?= $this->alias; ?>-daterange"
class="btn btn-light btn-sm"
data-control="daterange"
>
Expand Down
94 changes: 94 additions & 0 deletions app/admin/traits/HasChartDatasets.php
@@ -0,0 +1,94 @@
<?php

namespace Admin\Traits;

use Carbon\Carbon;
use DateInterval;
use DatePeriod;
use DB;
use Illuminate\Support\Collection;

trait HasChartDatasets
{
public function loadAssets()
{
$this->addJs('~/app/system/assets/ui/js/vendor/moment.min.js', 'moment-js');
$this->addJs('~/app/admin/dashboardwidgets/charts/assets/vendor/daterange/daterangepicker.js', 'daterangepicker-js');
$this->addCss('~/app/admin/dashboardwidgets/charts/assets/vendor/daterange/daterangepicker.css', 'daterangepicker-css');

$this->addJs('~/app/admin/dashboardwidgets/charts/assets/vendor/chartjs/Chart.min.js', 'chartsjs-js');
$this->addCss('~/app/admin/dashboardwidgets/charts/assets/css/charts.css', 'charts-css');
$this->addJs('~/app/admin/dashboardwidgets/charts/assets/js/charts.js', 'charts-js');
}

public function onFetchDatasets()
{
$start = post('start');
$end = post('end');

$start = Carbon::parse($start);
$end = Carbon::parse($end);

return $this->getDatasets($start, $end);
}

protected function getDatasets($start, $end)
{
$config = [];
$results[] = $this->makeDataset($config, $start, $end);

return $results;
}

protected function makeDataset($config, $start, $end)
{
list($r, $g, $b) = sscanf($config['color'], '#%02x%02x%02x');
$backgroundColor = sprintf('rgba(%s, %s, %s, 0.5)', $r, $g, $b);
$borderColor = sprintf('rgb(%s, %s, %s)', $r, $g, $b);

return array_merge($this->datasetOptions, [
'label' => lang($config['label']),
'data' => $this->queryDatasets($config, $start, $end),
'backgroundColor' => $backgroundColor,
'borderColor' => $borderColor,
]);
}

protected function queryDatasets($config, $start, $end)
{
$modelClass = $config['model'];
$dateColumnName = $config['column'];

$dateColumn = DB::raw('DATE_FORMAT('.$dateColumnName.', "%Y-%m-%d") as x');
$query = $modelClass::select($dateColumn, DB::raw('count(*) as y'));
$query->whereBetween($dateColumnName, [$start, $end])->groupBy('x');

$dateRanges = $this->getDatePeriod($start, $end);

return $this->getPointsArray($dateRanges, $query->get());
}

protected function getDatePeriod($start, $end)
{
return new DatePeriod(
Carbon::parse($start),
new DateInterval('P1D'),
Carbon::parse($end)
);
}

protected function getPointsArray($dateRanges, Collection $result)
{
$points = [];
$keyedResult = $result->keyBy('x');
foreach ($dateRanges as $date) {
$x = $date->format('Y-m-d');
$points[] = [
'x' => $x,
'y' => $keyedResult->get($x) ?? 0,
];
}

return $points;
}
}
6 changes: 4 additions & 2 deletions app/admin/widgets/DashboardContainer.php
Expand Up @@ -193,12 +193,14 @@ public function onUpdateWidget()

$widget = $this->findWidgetByAlias($alias);

$widget->setProperties(post('fields'));
$widget->setProperties(post($alias.'_fields'));

$this->saveWidgetProperties($alias, $widget->getProperties());

$widget->initialize();

$this->widgetsDefined = FALSE;

return $this->onRenderWidgets();
}

Expand Down Expand Up @@ -358,7 +360,7 @@ protected function getFormWidget($alias, $widget)
$formConfig['data'] = $this->getWidgetPropertyValues($widget);
$formConfig['previewMode'] = $this->previewMode;
$formConfig['alias'] = $this->alias.'Form'.'-'.$alias;
$formConfig['arrayName'] = 'fields';
$formConfig['arrayName'] = $alias.'_fields';

$formWidget = $this->makeWidget('Admin\Widgets\Form', $formConfig);
$formWidget->bindToController();
Expand Down

0 comments on commit 6ddda74

Please sign in to comment.