Exemple #1
0
 public function __construct($table, $currentDataTable, $pastDataTable, $columnToRead, $considerMovers, $considerNew, $considerDisappeared)
 {
     parent::__construct($table, $pastDataTable, 'growth', $columnToRead, $quotientPrecision = 1);
     $this->currentDataTable = $currentDataTable;
     $this->considerMovers = $considerMovers;
     $this->considerNew = $considerNew;
     $this->considerDisappeared = $considerDisappeared;
 }
 /**
  * Given the Row evolution dataTable, and the associated metadata,
  * enriches the metadata with min/max values, and % change between the first period and the last one
  * @param array $metadata
  * @param DataTable\Map $dataTable
  */
 private function enhanceRowEvolutionMetaData(&$metadata, $dataTable)
 {
     // prepare result array for metrics
     $metricsResult = array();
     foreach ($metadata['metrics'] as $metric => $name) {
         $metricsResult[$metric] = array('name' => $name);
         if (!empty($metadata['logos'][$metric])) {
             $metricsResult[$metric]['logo'] = $metadata['logos'][$metric];
         }
     }
     unset($metadata['logos']);
     $subDataTables = $dataTable->getDataTables();
     $firstDataTable = reset($subDataTables);
     $firstDataTableRow = $firstDataTable->getFirstRow();
     $lastDataTable = end($subDataTables);
     $lastDataTableRow = $lastDataTable->getFirstRow();
     // Process min/max values
     $firstNonZeroFound = array();
     foreach ($subDataTables as $subDataTable) {
         // $subDataTable is the report for one period, it has only one row
         $firstRow = $subDataTable->getFirstRow();
         foreach ($metadata['metrics'] as $metric => $label) {
             $value = $firstRow ? floatval($firstRow->getColumn($metric)) : 0;
             if ($value > 0) {
                 $firstNonZeroFound[$metric] = true;
             } else {
                 if (!isset($firstNonZeroFound[$metric])) {
                     continue;
                 }
             }
             if (!isset($metricsResult[$metric]['min']) || $metricsResult[$metric]['min'] > $value) {
                 $metricsResult[$metric]['min'] = $value;
             }
             if (!isset($metricsResult[$metric]['max']) || $metricsResult[$metric]['max'] < $value) {
                 $metricsResult[$metric]['max'] = $value;
             }
         }
     }
     // Process % change between first/last values
     foreach ($metadata['metrics'] as $metric => $label) {
         $first = $firstDataTableRow ? floatval($firstDataTableRow->getColumn($metric)) : 0;
         $last = $lastDataTableRow ? floatval($lastDataTableRow->getColumn($metric)) : 0;
         // do not calculate evolution if the first value is 0 (to avoid divide-by-zero)
         if ($first == 0) {
             continue;
         }
         $change = CalculateEvolutionFilter::calculate($last, $first, $quotientPrecision = 0);
         $change = CalculateEvolutionFilter::prependPlusSignToNumber($change);
         $metricsResult[$metric]['change'] = $change;
     }
     $metadata['metrics'] = $metricsResult;
 }
Exemple #3
0
 /**
  * Calculates the evolution from one value to another and returns HTML displaying
  * the evolution percent. The HTML includes an up/down arrow and is colored red, black or
  * green depending on whether the evolution is negative, 0 or positive.
  *
  * No HTML is returned if the current value and evolution percent are both 0.
  *
  * @param string $date The date of the current value.
  * @param int $currentValue The value to calculate evolution to.
  * @param string $pastDate The date of past value.
  * @param int $pastValue The value in the past to calculate evolution from.
  * @return string|false The HTML or `false` if the evolution is 0 and the current value is 0.
  * @api
  */
 protected function getEvolutionHtml($date, $currentValue, $pastDate, $pastValue)
 {
     $evolutionPercent = CalculateEvolutionFilter::calculate($currentValue, $pastValue, $precision = 1);
     // do not display evolution if evolution percent is 0 and current value is 0
     if ($evolutionPercent == 0 && $currentValue == 0) {
         return false;
     }
     $titleEvolutionPercent = $evolutionPercent;
     if ($evolutionPercent < 0) {
         $class = "negative-evolution";
         $img = "arrow_down.png";
     } else {
         if ($evolutionPercent == 0) {
             $class = "neutral-evolution";
             $img = "stop.png";
         } else {
             $class = "positive-evolution";
             $img = "arrow_up.png";
             $titleEvolutionPercent = '+' . $titleEvolutionPercent;
         }
     }
     $title = Piwik::translate('General_EvolutionSummaryGeneric', array(Piwik::translate('General_NVisits', $currentValue), $date, Piwik::translate('General_NVisits', $pastValue), $pastDate, $titleEvolutionPercent));
     $result = '<span class="metricEvolution" title="' . $title . '"><img style="padding-right:4px" src="plugins/MultiSites/images/' . $img . '"/><strong';
     if (isset($class)) {
         $result .= ' class="' . $class . '"';
     }
     $result .= '>' . $evolutionPercent . '</strong></span>';
     return $result;
 }
Exemple #4
0
 /**
  * Sets the total evolution metadata for a datatable returned by $this->buildDataTable
  * given data for the last period.
  *
  * @param DataTable|DataTable\Map $dataTable
  * @param DataTable|DataTable\Map $pastData
  * @param array $apiMetrics Metrics info.
  */
 private function setPastDataMetadata($dataTable, $pastData, $apiMetrics)
 {
     if ($dataTable instanceof DataTable\Map) {
         $pastArray = $pastData->getDataTables();
         foreach ($dataTable->getDataTables() as $subTable) {
             $this->setPastDataMetadata($subTable, current($pastArray), $apiMetrics);
             next($pastArray);
         }
     } else {
         // calculate total visits/actions/revenue for past data
         $this->setMetricsTotalsMetadata($pastData, $apiMetrics);
         foreach ($apiMetrics as $label => $metricInfo) {
             // get the names of metadata to set
             $totalMetadataName = self::getTotalMetadataName($label);
             $lastPeriodTotalMetadataName = self::getLastPeriodMetadataName($totalMetadataName);
             $totalEvolutionMetadataName = self::getTotalMetadataName($metricInfo[self::METRIC_EVOLUTION_COL_NAME_KEY]);
             // set last period total
             $pastTotal = $pastData->getMetadata($totalMetadataName);
             $dataTable->setMetadata($lastPeriodTotalMetadataName, $pastTotal);
             // calculate & set evolution
             $currentTotal = $dataTable->getMetadata($totalMetadataName);
             $evolution = CalculateEvolutionFilter::calculate($currentTotal, $pastTotal);
             $dataTable->setMetadata($totalEvolutionMetadataName, $evolution);
         }
     }
 }
Exemple #5
0
 /**
  * Utility method that calculates evolution values for a set of current & past values
  * and sets properties on a View w/ HTML that displays the evolution percents.
  *
  * @param string $date The date of the current values.
  * @param array $currentValues Array mapping view property names w/ present values.
  * @param string $lastPeriodDate The date of the period in the past.
  * @param array $previousValues Array mapping view property names w/ past values. Keys
  *                              in this array should be the same as keys in $currentValues.
  * @return array Added current values
  */
 private function addEvolutionPropertiesToView($date, $currentValues, $lastPeriodDate, $previousValues)
 {
     foreach ($previousValues as $name => $pastValue) {
         $currentValue = $currentValues[$name];
         $evolutionName = $name . 'Evolution';
         $currentValueFormatted = NumberFormatter::getInstance()->format($currentValue);
         $pastValueFormatted = NumberFormatter::getInstance()->format($pastValue);
         $currentValues[$evolutionName] = array('currentValue' => $currentValue, 'pastValue' => $pastValue, 'tooltip' => Piwik::translate('General_EvolutionSummaryGeneric', array(Piwik::translate('General_NVisits', $currentValueFormatted), $date, Piwik::translate('General_NVisits', $pastValueFormatted), $lastPeriodDate, CalculateEvolutionFilter::calculate($currentValue, $pastValue, $precision = 1))));
     }
     return $currentValues;
 }
Exemple #6
0
 /**
  * Add a new sparkline to be displayed to the view.
  *
  * Each sparkline can consist of one or multiple metrics. One metric consists of a value and a description. By
  * default the value is shown first, then the description. The description can optionally contain a '%s' in case
  * the value shall be displayed within the description. If multiple metrics are given, they will be separated by
  * a comma.
  *
  * @param array $requestParamsForSparkline You need to at least set a module / action eg
  *                                         array('columns' => array('nb_visit'), 'module' => '', 'action' => '')
  * @param int|float|string|array $value Either the metric value or an array of values.
  * @param string|array $description Either one description or an array of descriptions. If an array, both
  *                                         $value and $description need the same amount of array entries.
  *                                         $description[0] should be the description for $value[0].
  *                                         $description should be already translated. If $value should appear
  *                                         somewhere within the text a `%s` can be used in the translation.
  * @param array|null $evolution            Optional array containing at least the array keys 'currentValue' and
  *                                         'pastValue' which are needed to calculate the correct percentage.
  *                                         An optional 'tooltip' can be set as well. Eg
  *                                         array('currentValue' => 10, 'pastValue' => 20,
  *                                               'tooltip' => '10 visits in 2015-07-26 compared to 20 visits in 2015-07-25')
  * @param int $order                       Defines the order. The lower the order the earlier the sparkline will be
  *                                         displayed. By default the sparkline will be appended to the end.
  * @throws \Exception In case an evolution parameter is set but has wrong data structure
  */
 public function addSparkline($requestParamsForSparkline, $value, $description, $evolution = null, $order = null)
 {
     $metrics = array();
     if (is_array($value)) {
         $values = $value;
     } else {
         $values = array($value);
     }
     if (!is_array($description)) {
         $description = array($description);
     }
     if (!empty($requestParamsForSparkline['columns']) && is_array($requestParamsForSparkline['columns']) && count($requestParamsForSparkline['columns']) === count($values)) {
         $columns = array_values($requestParamsForSparkline['columns']);
     } elseif (!empty($requestParamsForSparkline['columns']) && is_string($requestParamsForSparkline['columns']) && count($values) === 1) {
         $columns = array($requestParamsForSparkline['columns']);
     } else {
         $columns = array();
     }
     if (count($values) === count($description)) {
         foreach ($values as $index => $value) {
             $metrics[] = array('column' => isset($columns[$index]) ? $columns[$index] : '', 'value' => $value, 'description' => $description[$index]);
         }
     } else {
         $msg = 'The number of values and descriptions need to be the same to add a sparkline. ';
         $msg .= 'Values: ' . implode(', ', $values) . ' Descriptions: ' . implode(', ', $description);
         throw new \Exception($msg);
     }
     if (empty($metrics)) {
         return;
     }
     $sparkline = array('url' => $this->getUrlSparkline($requestParamsForSparkline), 'metrics' => $metrics, 'order' => $this->getSparklineOrder($order));
     if (!empty($evolution)) {
         if (!is_array($evolution) || !array_key_exists('currentValue', $evolution) || !array_key_exists('pastValue', $evolution)) {
             throw new \Exception('In order to show an evolution in the sparklines view a currentValue and pastValue array key needs to be present');
         }
         $evolutionPercent = CalculateEvolutionFilter::calculate($evolution['currentValue'], $evolution['pastValue'], $precision = 1);
         // do not display evolution if evolution percent is 0 and current value is 0
         if ($evolutionPercent != 0 || $evolution['currentValue'] != 0) {
             $sparkline['evolution'] = array('percent' => $evolutionPercent, 'tooltip' => !empty($evolution['tooltip']) ? $evolution['tooltip'] : null);
         }
     }
     $this->sparklines[] = $sparkline;
 }