icingaweb2/library/Icinga/Chart/Unit/CalendarUnit.php

168 lines
3.5 KiB
PHP

<?php
/* Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */
namespace Icinga\Chart\Unit;
use DateTime;
/**
* Calendar Axis Unit that transforms timestamps into user-readable values
*
*/
class CalendarUnit extends LinearUnit
{
/**
* Constant for a minute
*/
const MINUTE = 60;
/**
* Constant for an hour
*/
const HOUR = 3600;
/**
* Constant for a day
*/
const DAY = 864000;
/**
* Constant for ~a month
* 30 Days, this is sufficient for our needs
*/
const MONTH = 2592000; // x
/**
* An array containing all labels that will be displayed
*
* @var array
*/
private $labels = array();
/**
* The date format to use
*
* @var string
*/
private $dateFormat = 'd-m';
/**
* The time format to use
*
* @var string
*/
private $timeFormat = 'g:i:s';
/**
* Create the labels for the given dataset
*/
private function createLabels()
{
$this->labels = array();
$duration = $this->getMax() - $this->getMin();
if ($duration <= self::HOUR) {
$unit = self::MINUTE;
} elseif ($duration <= self::DAY) {
$unit = self::HOUR;
} elseif ($duration <= self::MONTH) {
$unit = self::DAY;
} else {
$unit = self::MONTH;
}
$this->calculateLabels($unit);
}
/**
* Calculate the labels for this dataset
*
* @param integer $unit The unit to use as the basis for calculation
*/
private function calculateLabels($unit)
{
$fac = new DateTime();
$duration = $this->getMax() - $this->getMin();
// Calculate number of ticks, but not more than 30
$tickCount = ($duration/$unit * 10);
if ($tickCount > 30) {
$tickCount = 30;
}
$step = $duration / $tickCount;
$format = $this->timeFormat;
if ($unit === self::DAY) {
$format = $this->dateFormat;
} elseif ($unit === self::MONTH) {
$format = $this->dateFormat;
}
for ($i = 0; $i <= $duration; $i += $step) {
$this->labels[] = $fac->setTimestamp($this->getMin() + $i)->format($format);
}
}
/**
* Add a dataset to this CalendarUnit and update labels
*
* @param array $dataset The dataset to update
* @param int $idx The index to use for determining the data
*
* @return $this Fluid interface
*/
public function addValues(array $dataset, $idx = 0)
{
parent::addValues($dataset, $idx);
$this->createLabels();
return $this;
}
/**
* Return the current axis relative position
*
* @return int The position of the next tick (between 0 and 100)
*/
public function current()
{
return 100 * (key($this->labels) / count($this->labels));
}
/**
* Move to next tick
*/
public function next()
{
next($this->labels);
}
/**
* Return the current tick caption
*
* @return string
*/
public function key()
{
return current($this->labels);
}
/**
* Return true when the iterator is in a valid range
*
* @return bool
*/
public function valid()
{
return current($this->labels) !== false;
}
/**
* Rewind the internal array
*/
public function rewind()
{
reset($this->labels);
}
}