Spaces:
No application file
No application file
| namespace Mautic\CoreBundle\Helper\Chart; | |
| use Mautic\CoreBundle\Helper\ColorHelper; | |
| abstract class AbstractChart | |
| { | |
| use DateRangeUnitTrait; | |
| /** | |
| * Datasets of the chart. | |
| * | |
| * @var array | |
| */ | |
| protected $datasets = []; | |
| /** | |
| * Labels of the time axe. | |
| * | |
| * @var array | |
| */ | |
| protected $labels = []; | |
| /** | |
| * Date from. | |
| * | |
| * @var \DateTimeInterface|\DateTime | |
| */ | |
| protected $dateFrom; | |
| /** | |
| * Date to. | |
| * | |
| * @var \DateTimeInterface|\DateTime | |
| */ | |
| protected $dateTo; | |
| /** | |
| * Timezone data is requested to be in. | |
| * | |
| * @var \DateTimeZone | |
| */ | |
| protected $timezone; | |
| /** | |
| * Time unit. | |
| * | |
| * @var string | |
| */ | |
| protected $unit; | |
| /** | |
| * True if unit is H, i, or s. | |
| * | |
| * @var bool | |
| */ | |
| protected $isTimeUnit = false; | |
| /** | |
| * amount of items. | |
| * | |
| * @var int | |
| */ | |
| protected $amount; | |
| /** | |
| * Default Mautic colors. | |
| * | |
| * @var array | |
| */ | |
| public $colors = ['#4E5D9D', '#00B49C', '#FD9572', '#FDB933', '#757575', '#9C4E5C', '#694535', '#596935']; | |
| /** | |
| * Get chart time unit. | |
| * | |
| * @return string | |
| */ | |
| public function getUnit() | |
| { | |
| return $this->unit; | |
| } | |
| /** | |
| * Create a DateInterval time unit. | |
| * | |
| * @param string $unit | |
| * | |
| * @return \DateInterval | |
| */ | |
| public function getUnitInterval($unit = null) | |
| { | |
| if (!$unit) { | |
| $unit = $this->unit; | |
| } | |
| $isTime = in_array($unit, ['H', 'i', 's']) ? 'T' : ''; | |
| if ('i' == $unit) { | |
| $unit = 'M'; | |
| } | |
| return new \DateInterval('P'.$isTime.'1'.strtoupper($unit)); | |
| } | |
| /** | |
| * Helper function to shorten/truncate a string. | |
| * | |
| * @param string $string | |
| * @param int $length | |
| * @param string $append | |
| * | |
| * @return string | |
| */ | |
| public static function truncate($string, $length = 100, $append = '...') | |
| { | |
| $string = trim($string); | |
| if (strlen($string) > $length) { | |
| $string = wordwrap($string, $length); | |
| $string = explode("\n", $string, 2); | |
| $string = $string[0].$append; | |
| } | |
| return $string; | |
| } | |
| /** | |
| * Sets the clones of the date range and validates it. | |
| */ | |
| public function setDateRange(\DateTimeInterface $dateFrom, \DateTimeInterface $dateTo): void | |
| { | |
| $this->timezone = $dateFrom->getTimezone(); | |
| /** @var \DateTime $dateFrom */ | |
| $this->dateFrom = clone $dateFrom; | |
| /** @var \DateTime $dateTo */ | |
| $this->dateTo = clone $dateTo; | |
| // a diff of two identical dates returns 0, but we expect 24 hours | |
| if ($dateFrom == $dateTo) { | |
| $this->dateTo->modify('+1 day'); | |
| } | |
| // If today, adjust dateTo to be end of today if unit is not time based or to the current hour if it is | |
| if (!$this->isTimeUnit) { | |
| $this->dateTo->setTime(23, 59, 59); | |
| return; | |
| } | |
| // If time aware and the to date is today, set the stats to the current hour to avoid empty future hours in graphs | |
| $now = new \DateTime(); | |
| if ($now->format('Y-m-d') === $this->dateTo->format('Y-m-d')) { | |
| $this->dateTo = $now; | |
| } | |
| } | |
| /** | |
| * Modify the date to add one current time unit to it and subtract 1 second. | |
| * Can be used to get the current day results. | |
| */ | |
| public function addOneUnitMinusOneSec(\DateTime &$date): void | |
| { | |
| $date->add($this->getUnitInterval())->modify('-1 sec'); | |
| } | |
| /** | |
| * Count amount of time slots of a time unit from a date range. | |
| * | |
| * @return int | |
| */ | |
| public function countAmountFromDateRange() | |
| { | |
| switch ($this->unit) { | |
| case 's': | |
| $amount = $this->dateTo->diff($this->dateFrom)->format('%s'); | |
| ++$amount; | |
| break; | |
| case 'i': | |
| $amount = $this->dateTo->diff($this->dateFrom)->format('%i'); | |
| ++$amount; | |
| break; | |
| case 'd': | |
| $amount = ($this->dateTo->diff($this->dateFrom)->format('%a') + 1); | |
| break; | |
| case 'W': | |
| $dayAmount = $this->dateTo->diff($this->dateFrom)->format('%a'); | |
| $amount = (ceil($dayAmount / 7) + 1); | |
| break; | |
| case 'm': | |
| $amount = $this->dateTo->diff($this->dateFrom)->format('%y') * 12 + $this->dateTo->diff($this->dateFrom)->format('%m'); | |
| // Add 1 month if there are some days left | |
| if ($this->dateTo->diff($this->dateFrom)->format('%d') > 0) { | |
| ++$amount; | |
| } | |
| // Add 1 month if count of days are greater or equal than in date to | |
| if ($this->dateFrom->format('d') >= $this->dateTo->format('d')) { | |
| ++$amount; | |
| } | |
| break; | |
| case 'H': | |
| $dateDiff = $this->dateTo->diff($this->dateFrom); | |
| $amount = $dateDiff->h + $dateDiff->days * 24; | |
| ++$amount; | |
| break; | |
| default: | |
| $amount = ($this->dateTo->diff($this->dateFrom)->format('%'.$this->unit) + 1); | |
| break; | |
| } | |
| return $amount; | |
| } | |
| /** | |
| * Generate unique color for the dataset. | |
| * | |
| * @param int $datasetId | |
| * | |
| * @return ColorHelper | |
| */ | |
| public function configureColorHelper($datasetId) | |
| { | |
| $colorHelper = new ColorHelper(); | |
| if (isset($this->colors[$datasetId])) { | |
| $color = $colorHelper->setHex($this->colors[$datasetId]); | |
| } else { | |
| $color = $colorHelper->buildRandomColor(); | |
| } | |
| return $color; | |
| } | |
| } | |