pastDataTable = $pastDataTable; $this->isRevenueEvolution = $columnToAdd == 'revenue_evolution'; } /** * Returns the difference between the column in the specific row and its * sister column in the past DataTable. * * @param Row $row * @return int|float */ protected function getDividend($row) { $currentValue = $row->getColumn($this->columnValueToRead); // if the site this is for doesn't support ecommerce & this is for the revenue_evolution column, // we don't add the new column if ($currentValue === false && $this->isRevenueEvolution && !Site::isEcommerceEnabledFor($row->getColumn('label')) ) { return false; } $pastRow = $this->getPastRowFromCurrent($row); if ($pastRow) { $pastValue = $pastRow->getColumn($this->columnValueToRead); } else { $pastValue = 0; } return $currentValue - $pastValue; } /** * Returns the value of the column in $row's sister row in the past * DataTable. * * @param Row $row * @return int|float */ protected function getDivisor($row) { $pastRow = $this->getPastRowFromCurrent($row); if (!$pastRow) { return 0; } return $pastRow->getColumn($this->columnNameUsedAsDivisor); } /** * Calculates and formats a quotient based on a divisor and dividend. * * Unlike ColumnCallbackAddColumnPercentage's, * version of this method, this method will return 100% if the past * value of a metric is 0, and the current value is not 0. For a * value representative of an evolution, this makes sense. * * @param int|float $value The dividend. * @param int|float $divisor * @return string */ protected function formatValue($value, $divisor) { $value = self::getPercentageValue($value, $divisor, $this->quotientPrecision); $value = self::appendPercentSign($value); $value = Common::forceDotAsSeparatorForDecimalPoint($value); return $value; } /** * Utility function. Returns the current row in the past DataTable. * * @param Row $row The row in the 'current' DataTable. * @return bool|Row */ protected function getPastRowFromCurrent($row) { return $this->pastDataTable->getRowFromLabel($row->getColumn('label')); } /** * Calculates the evolution percentage for two arbitrary values. * * @param float|int $currentValue The current metric value. * @param float|int $pastValue The value of the metric in the past. We measure the % change * from this value to $currentValue. * @param float|int $quotientPrecision The quotient precision to round to. * @param bool $appendPercentSign Whether to append a '%' sign to the end of the number or not. * * @return string The evolution percent, eg `'15%'`. */ public static function calculate($currentValue, $pastValue, $quotientPrecision = 0, $appendPercentSign = true) { $number = self::getPercentageValue($currentValue - $pastValue, $pastValue, $quotientPrecision); if ($appendPercentSign) { return NumberFormatter::getInstance()->formatPercent($number, $quotientPrecision); } return NumberFormatter::getInstance()->format($number, $quotientPrecision); } public static function appendPercentSign($number) { return $number . '%'; } public static function prependPlusSignToNumber($number) { if ($number > 0) { $number = '+' . $number; } return $number; } /** * Returns an evolution percent based on a value & divisor. */ private static function getPercentageValue($value, $divisor, $quotientPrecision) { if ($value == 0) { $evolution = 0; } elseif ($divisor == 0) { $evolution = 100; } else { $evolution = ($value / $divisor) * 100; } $evolution = round($evolution, $quotientPrecision); return $evolution; } }