Add pagination support to the servicematrix

refs #4180
This commit is contained in:
Johannes Meyer 2014-03-13 16:26:14 +01:00
parent dbab546f0a
commit 617b6822d7
4 changed files with 133 additions and 98 deletions

View File

@ -41,6 +41,11 @@ title = "Services"
url = "monitoring/list/services"
priority = 50
[Overview.Servicematrix]
title = "Servicematrix"
url = "monitoring/list/servicematrix"
priority = 51
[Overview.Servicegroups]
title = "Servicegroups"
url = "monitoring/list/servicegroups"

View File

@ -4,7 +4,10 @@
namespace Icinga\Data;
use \Zend_Paginator;
use Icinga\Data\BaseQuery;
use Icinga\Application\Icinga;
use Icinga\Web\Paginator\Adapter\QueryAdapter;
class PivotTable
{
@ -13,121 +16,144 @@ class PivotTable
*
* @var BaseQuery
*/
protected $query;
protected $baseQuery;
/**
* The column to use for the x axis
* The query to fetch the x axis labels
*
* @var BaseQuery
*/
protected $xAxisQuery;
/**
* The query to fetch the y axis labels
*
* @var BaseQuery
*/
protected $yAxisQuery;
/**
* The column that contains the labels for the x axis
*
* @var string
*/
protected $xAxisColumn;
/**
* The column to use for the y axis
* The column that contains the labels for the y axis
*
* @var string
*/
protected $yAxisColumn;
protected $limit;
protected $offset;
protected $verticalLimit;
protected $horizontalLimit;
/**
* Create a new pivot table
*
* @param BaseQuery $query The query to fetch as pivot table
* @param string $xAxisColumn The column to use for the x axis
* @param string $yAxisColumn The column to use for the y axis
* @param string $xAxisColumn The column that contains the labels for the x axis
* @param string $yAxisColumn The column that contains the labels for the y axis
*/
public function __construct(BaseQuery $query, $xAxisColumn, $yAxisColumn)
{
$this->query = $query;
$this->baseQuery = $query;
$this->xAxisColumn = $xAxisColumn;
$this->yAxisColumn = $yAxisColumn;
}
public function limit($limit = null, $offset = null)
{
$this->limit = $limit;
$this->offset = $offset;
return $this;
}
public function getLimit()
{
if ($this->limit === null) {
return 20;
}
return $this->limit;
}
public function getOffset()
{
if ($this->limit === null) {
return 20;
}
return $this->offset;
}
public function verticalLimit($limit = null, $offset = null)
{
// TODO: Trigger limit by calling $this->limit()?
if ($limit === null) {
$limit = $this->getLimit();
}
if ($offset === null) {
$offset = $this->getOffset();
}
$this->verticalLimit = $limit;
$this->verticalOffset = $offset;
return $this;
}
public function paginateVertical($limit = null, $offset = null)
{
$this->verticalLimit($limit, $offset);
return Paginator($this);
}
public function getVerticalLimit()
{
if ($this->verticalLimit === null) {
return 20;
}
return $this->verticalLimit;
}
public function getVerticalOffset()
{
if ($this->verticalLimit === null) {
return 20;
}
return $this->verticalOffset;
$this->prepareQueries();
}
/**
* Fetch the values to label the x axis with
* Prepare the queries used for the pre processing
*/
protected function fetchXAxis()
protected function prepareQueries()
{
$query = clone $this->query;
$query->setColumns(array($this->xAxisColumn));
return $query->fetchColumn();
$this->xAxisQuery = clone $this->baseQuery;
$this->xAxisQuery->distinct();
$this->xAxisQuery->setColumns(array($this->xAxisColumn));
$this->yAxisQuery = clone $this->baseQuery;
$this->yAxisQuery->distinct();
$this->yAxisQuery->setColumns(array($this->yAxisColumn));
}
/**
* Fetch the values to label the y axis with
* Return the value for the given request parameter
*
* @param string $axis The axis for which to return the parameter ('x' or 'y')
* @param string $param The parameter name to return
* @param int $default The default value to return
*
* @return int
*/
protected function fetchYAxis()
protected function getPaginationParameter($axis, $param, $default = null)
{
$query = clone $this->query;
$query->setColumns(array($this->yAxisColumn));
return $query->fetchColumn();
$request = Icinga::app()->getFrontController()->getRequest();
$value = $request->getParam($param, '');
if (strpos($value, ',') > 0) {
$parts = explode(',', $value, 2);
return intval($parts[$axis === 'x' ? 0 : 1]);
}
return $default !== null ? $default : 0;
}
/**
* Return a pagination adapter for the x axis query
*
* $limit and $page are taken from the current request if not given.
*
* @param int $limit The maximum amount of entries to fetch
* @param int $page The page to set as current one
*
* @return Zend_Paginator
*/
public function paginateXAxis($limit = null, $page = null)
{
if ($limit === null || $page === null) {
if ($limit === null) {
$limit = $this->getPaginationParameter('x', 'limit', 20);
}
if ($page === null) {
$page = $this->getPaginationParameter('x', 'page', 1);
}
}
$this->xAxisQuery->limit($limit, $page > 0 ? ($page - 1) * $limit : 0);
$paginator = new Zend_Paginator(new QueryAdapter($this->xAxisQuery));
$paginator->setItemCountPerPage($limit);
$paginator->setCurrentPageNumber($page);
return $paginator;
}
/**
* Return a pagination adapter for the y axis query
*
* $limit and $page are taken from the current request if not given.
*
* @param int $limit The maximum amount of entries to fetch
* @param int $page The page to set as current one
*
* @return Zend_Paginator
*/
public function paginateYAxis($limit = null, $page = null)
{
if ($limit === null || $page === null) {
if ($limit === null) {
$limit = $this->getPaginationParameter('y', 'limit', 20);
}
if ($page === null) {
$page = $this->getPaginationParameter('y', 'page', 1);
}
}
$this->yAxisQuery->limit($limit, $page > 0 ? ($page - 1) * $limit : 0);
$paginator = new Zend_Paginator(new QueryAdapter($this->yAxisQuery));
$paginator->setItemCountPerPage($limit);
$paginator->setCurrentPageNumber($page);
return $paginator;
}
/**
@ -137,22 +163,24 @@ class PivotTable
*/
public function toArray()
{
$xAxis = $this->fetchXAxis();
$yAxis = $this->fetchYAxis();
$this->query->where($this->xAxisColumn, $xAxis)->where($this->yAxisColumn, $yAxis);
$xAxis = $this->xAxisQuery->fetchColumn();
$yAxis = $this->yAxisQuery->fetchColumn();
$pivot = array();
foreach ($this->query->fetchAll() as $row) {
if (!array_key_exists($row->{$this->yAxisColumn}, $pivot)) {
$defaults = array();
foreach ($xAxis as $label) {
$defaults[$label] = null;
}
$pivot[$row->{$this->yAxisColumn}] = $defaults;
}
if (!empty($xAxis) && !empty($yAxis)) {
$this->baseQuery->where($this->xAxisColumn, $xAxis)->where($this->yAxisColumn, $yAxis);
$pivot[$row->{$this->yAxisColumn}][$row->{$this->xAxisColumn}] = $row;
foreach ($this->baseQuery->fetchAll() as $row) {
if (!array_key_exists($row->{$this->yAxisColumn}, $pivot)) {
$defaults = array();
foreach ($xAxis as $label) {
$defaults[$label] = null;
}
$pivot[$row->{$this->yAxisColumn}] = $defaults;
}
$pivot[$row->{$this->yAxisColumn}][$row->{$this->xAxisColumn}] = $row;
}
}
return $pivot;

View File

@ -481,7 +481,9 @@ class Monitoring_ListController extends Controller
)
);
$this->view->matrix = $dataview->pivot('service_description', 'host_name')->toArray();
$this->view->pivot = $dataview->pivot('service_description', 'host_name');
$this->view->horizontalPaginator = $this->view->pivot->paginateXAxis();
$this->view->verticalPaginator = $this->view->pivot->paginateYAxis();
}
/**

View File

@ -9,7 +9,7 @@
<div class="content" data-base-target="_next">
<table class="pivot servicestates">
<?php $hasHeader = false; ?>
<?php foreach ($this->matrix as $host_name => $serviceStates): ?>
<?php foreach ($this->pivot->toArray() as $host_name => $serviceStates): ?>
<?php if (!$hasHeader): ?>
<thead>
<tr>