Merge pull request #1512 from CachetHQ/ajax-charts
Load metrics via AJAX
This commit is contained in:
@@ -12,29 +12,11 @@
|
|||||||
namespace CachetHQ\Cachet\Composers;
|
namespace CachetHQ\Cachet\Composers;
|
||||||
|
|
||||||
use CachetHQ\Cachet\Models\Metric;
|
use CachetHQ\Cachet\Models\Metric;
|
||||||
use CachetHQ\Cachet\Repositories\Metric\MetricRepository;
|
|
||||||
use Illuminate\Contracts\View\View;
|
use Illuminate\Contracts\View\View;
|
||||||
use Illuminate\Support\Facades\Config;
|
use Illuminate\Support\Facades\Config;
|
||||||
|
|
||||||
class MetricsComposer
|
class MetricsComposer
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var \CachetHQ\Cachet\Repositories\Metric\MetricRepository
|
|
||||||
*/
|
|
||||||
protected $metricRepository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new home controller instance.
|
|
||||||
*
|
|
||||||
* @param \CachetHQ\Cachet\Repositories\Metric\MetricRepository $metricRepository
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct(MetricRepository $metricRepository)
|
|
||||||
{
|
|
||||||
$this->metricRepository = $metricRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metrics view composer.
|
* Metrics view composer.
|
||||||
*
|
*
|
||||||
@@ -45,22 +27,11 @@ class MetricsComposer
|
|||||||
public function compose(View $view)
|
public function compose(View $view)
|
||||||
{
|
{
|
||||||
$metrics = null;
|
$metrics = null;
|
||||||
$metricData = [];
|
|
||||||
if ($displayMetrics = Config::get('setting.display_graphs')) {
|
if ($displayMetrics = Config::get('setting.display_graphs')) {
|
||||||
$metrics = Metric::where('display_chart', 1)->orderBy('id')->get();
|
$metrics = Metric::where('display_chart', 1)->orderBy('id')->get();
|
||||||
|
|
||||||
$metrics->map(function ($metric) use (&$metricData) {
|
|
||||||
$metricData[$metric->id] = [
|
|
||||||
'last_hour' => $this->metricRepository->listPointsLastHour($metric),
|
|
||||||
'today' => $this->metricRepository->listPointsToday($metric),
|
|
||||||
'week' => $this->metricRepository->listPointsForWeek($metric),
|
|
||||||
'month' => $this->metricRepository->listPointsForMonth($metric),
|
|
||||||
];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->withDisplayMetrics($displayMetrics)
|
$view->withDisplayMetrics($displayMetrics)
|
||||||
->withMetrics($metrics)
|
->withMetrics($metrics);
|
||||||
->withMetricData($metricData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,10 @@
|
|||||||
namespace CachetHQ\Cachet\Http\Controllers;
|
namespace CachetHQ\Cachet\Http\Controllers;
|
||||||
|
|
||||||
use CachetHQ\Cachet\Dates\DateFactory;
|
use CachetHQ\Cachet\Dates\DateFactory;
|
||||||
|
use CachetHQ\Cachet\Http\Controllers\Api\AbstractApiController;
|
||||||
use CachetHQ\Cachet\Models\Incident;
|
use CachetHQ\Cachet\Models\Incident;
|
||||||
|
use CachetHQ\Cachet\Models\Metric;
|
||||||
|
use CachetHQ\Cachet\Repositories\Metric\MetricRepository;
|
||||||
use Exception;
|
use Exception;
|
||||||
use GrahamCampbell\Binput\Facades\Binput;
|
use GrahamCampbell\Binput\Facades\Binput;
|
||||||
use Illuminate\Routing\Controller;
|
use Illuminate\Routing\Controller;
|
||||||
@@ -21,8 +24,25 @@ use Illuminate\Support\Facades\Config;
|
|||||||
use Illuminate\Support\Facades\View;
|
use Illuminate\Support\Facades\View;
|
||||||
use Jenssegers\Date\Date;
|
use Jenssegers\Date\Date;
|
||||||
|
|
||||||
class StatusPageController extends Controller
|
class StatusPageController extends AbstractApiController
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \CachetHQ\Cachet\Repositories\Metric\MetricRepository
|
||||||
|
*/
|
||||||
|
protected $metricRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new status page controller instance.
|
||||||
|
*
|
||||||
|
* @param \CachetHQ\Cachet\Repositories\Metric\MetricRepository $metricRepository
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(MetricRepository $metricRepository)
|
||||||
|
{
|
||||||
|
$this->metricRepository = $metricRepository;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the status page.
|
* Displays the status page.
|
||||||
*
|
*
|
||||||
@@ -100,4 +120,37 @@ class StatusPageController extends Controller
|
|||||||
return View::make('incident')
|
return View::make('incident')
|
||||||
->withIncident($incident);
|
->withIncident($incident);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns metrics in a readily formatted way.
|
||||||
|
*
|
||||||
|
* @param \CachetHQ\Cachet\Models\Metric $metric
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function getMetrics(Metric $metric)
|
||||||
|
{
|
||||||
|
$metricData = [];
|
||||||
|
$type = Binput::get('filter', 'last_hour');
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
case 'last_hour':
|
||||||
|
$metricData = $this->metricRepository->listPointsLastHour($metric);
|
||||||
|
break;
|
||||||
|
case 'today':
|
||||||
|
$metricData = $this->metricRepository->listPointsToday($metric);
|
||||||
|
break;
|
||||||
|
case 'week':
|
||||||
|
$metricData = $this->metricRepository->listPointsForWeek($metric);
|
||||||
|
break;
|
||||||
|
case 'month':
|
||||||
|
$metricData = $this->metricRepository->listPointsForMonth($metric);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->item([
|
||||||
|
'metric' => $metric->toArray(),
|
||||||
|
'items' => $metricData,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ class StatusPageRoutes
|
|||||||
'as' => 'incident',
|
'as' => 'incident',
|
||||||
'uses' => 'StatusPageController@showIncident',
|
'uses' => 'StatusPageController@showIncident',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$router->get('metrics/{metric}', [
|
||||||
|
'as' => 'metrics',
|
||||||
|
'uses' => 'StatusPageController@getMetrics',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,73 +33,72 @@
|
|||||||
</li>
|
</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
</ul>
|
</ul>
|
||||||
<script type="text/json" id="metricData">
|
|
||||||
{!! json_encode($metric_data) !!}
|
|
||||||
</script>
|
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
Chart.defaults.global.pointHitDetectionRadius = 1;
|
Chart.defaults.global.pointHitDetectionRadius = 1;
|
||||||
Chart.defaults.global.scaleBeginAtZero = true;
|
Chart.defaults.global.scaleBeginAtZero = true;
|
||||||
|
|
||||||
var charts = JSON.parse(document.getElementById('metricData').text);
|
var charts = {},
|
||||||
|
defaultData = {
|
||||||
var defaultData = {
|
showTooltips: false,
|
||||||
showTooltips: false,
|
labels: [],
|
||||||
labels: [],
|
datasets: [{
|
||||||
datasets: [{
|
fillColor: "{{ $theme_metrics }}",
|
||||||
// fillColor: "rgba(220,220,220,0.1)",
|
pointColor: "{{ color_darken($theme_metrics, -0.1) }}",
|
||||||
fillColor: "{{$theme_metrics}}",
|
pointStrokeColor: "{{ color_darken($theme_metrics, -0.1) }}",
|
||||||
// strokeColor: "{{ $theme_metrics }}",
|
pointHighlightFill: "{{ color_darken($theme_metrics, -0.2) }}",
|
||||||
pointColor: "{{ color_darken($theme_metrics, -0.1) }}",
|
pointHighlightStroke: "{{ color_darken($theme_metrics, -0.2) }}",
|
||||||
pointStrokeColor: "{{ color_darken($theme_metrics, -0.1) }}",
|
data: []
|
||||||
pointHighlightFill: "{{ color_darken($theme_metrics, -0.2) }}",
|
}],
|
||||||
pointHighlightStroke: "{{ color_darken($theme_metrics, -0.2) }}",
|
};
|
||||||
data: []
|
|
||||||
}],
|
|
||||||
};
|
|
||||||
|
|
||||||
$('a[data-filter-type]').on('click', function(e) {
|
$('a[data-filter-type]').on('click', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
var $this = $(this);
|
var $this = $(this), $li, $canvas;
|
||||||
|
|
||||||
// Change the selected view.
|
$li = $this.parents('li');
|
||||||
var $li = $this.parents('li')
|
|
||||||
$li.find('a[data-toggle=dropdown] span.filter').text($this.text());
|
$li.find('a[data-toggle=dropdown] span.filter').text($this.text());
|
||||||
|
$canvas = $li.find('canvas');
|
||||||
var $canvas = $li.find('canvas');
|
|
||||||
|
|
||||||
$canvas.data('metric-group', $this.data('filter-type'));
|
$canvas.data('metric-group', $this.data('filter-type'));
|
||||||
drawChart($canvas);
|
drawChart($canvas);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('canvas[data-metric-id]').each(function() {
|
$('canvas[data-metric-id]').each(function() {
|
||||||
var $this = $(this);
|
drawChart($(this));
|
||||||
drawChart($this);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function drawChart($el) {
|
function drawChart($el) {
|
||||||
|
var chartConfig = defaultData;
|
||||||
var metricId = $el.data('metric-id');
|
var metricId = $el.data('metric-id');
|
||||||
var metricGroup = $el.data('metric-group');
|
var metricGroup = $el.data('metric-group');
|
||||||
|
|
||||||
charts[metricId].context = document.getElementById("metric-"+metricId).getContext("2d");
|
if (typeof charts[metricId] === 'undefined') {
|
||||||
|
charts[metricId] = {
|
||||||
if (typeof charts[metricId].chart !== 'undefined') {
|
context: document.getElementById("metric-"+metricId).getContext("2d"),
|
||||||
charts[metricId].chart.destroy();
|
chart: null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var chartConfig = defaultData;
|
var chart = charts[metricId];
|
||||||
var charter = charts[metricId][metricGroup];
|
|
||||||
|
|
||||||
chartConfig.labels = _.keys(charter);
|
$.getJSON('/metrics/'+metricId, { filter: metricGroup }).done(function (result) {
|
||||||
chartConfig.datasets[0].data = _.values(charter);
|
var data = result.data.items;
|
||||||
|
chartConfig.labels = _.keys(data);
|
||||||
|
chartConfig.datasets[0].data = _.values(data);
|
||||||
|
|
||||||
charts[metricId].chart = new Chart(charts[metricId].context).Line(chartConfig, {
|
if (chart.chart !== null) {
|
||||||
tooltipTemplate: $el.data('metric-name') + ": <{{ '%' }}= value %> " + $el.data('metric-suffix'),
|
chart.chart.destroy();
|
||||||
scaleShowVerticalLines: true,
|
}
|
||||||
scaleShowLabels: false,
|
|
||||||
responsive: true,
|
chart.chart = new Chart(chart.context).Line(chartConfig, {
|
||||||
maintainAspectRatio: false
|
tooltipTemplate: $el.data('metric-name') + ": <{{ '%' }}= value %> " + $el.data('metric-suffix'),
|
||||||
|
scaleShowVerticalLines: true,
|
||||||
|
scaleShowLabels: false,
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: false
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
|
|||||||
Reference in New Issue
Block a user