Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattab <matthieu.aubry@gmail.com>2014-03-05 05:30:43 +0400
committermattab <matthieu.aubry@gmail.com>2014-03-05 05:30:43 +0400
commit69166694778fb3b13ea100e35e00f2e65b9cc93c (patch)
tree06bf05f12adc592187380163c7dc1066f1b8cd23
parent61be595cf13b8ad88c91fbd214d67ac6057408ed (diff)
parent4e51781c3d77189f551a2c39a5db11c8669bf530 (diff)
Merge remote-tracking branch 'origin/master'
-rw-r--r--core/Twig.php10
-rw-r--r--plugins/Insights/API.php235
-rw-r--r--plugins/Insights/Controller.php26
-rw-r--r--plugins/Insights/DataTable/Filter/ExcludeLowValue.php28
-rw-r--r--plugins/Insights/DataTable/Filter/Insight.php89
-rw-r--r--plugins/Insights/Insights.php3
-rw-r--r--plugins/Insights/Visualizations/Insight.php4
-rw-r--r--plugins/Insights/lang/en.json9
-rw-r--r--plugins/Insights/stylesheets/insightVisualization.less7
-rw-r--r--plugins/Insights/templates/index.twig5
-rw-r--r--plugins/Insights/templates/insightControls.twig50
-rw-r--r--plugins/Insights/templates/insightVisualization.twig52
-rw-r--r--plugins/Insights/templates/overviewWidget.twig37
-rw-r--r--plugins/Insights/templates/table_header.twig13
-rw-r--r--plugins/Insights/templates/table_row.twig15
-rw-r--r--plugins/Insights/tests/FilterExcludeLowValueTest.php33
-rw-r--r--plugins/Insights/tests/FilterInsightTest.php23
17 files changed, 439 insertions, 200 deletions
diff --git a/core/Twig.php b/core/Twig.php
index fd266d0b7b..4da7a364f8 100644
--- a/core/Twig.php
+++ b/core/Twig.php
@@ -9,6 +9,7 @@
namespace Piwik;
use Exception;
+use Piwik\Period\Range;
use Piwik\Translate;
use Piwik\Visualization\Sparkline;
use Piwik\View\RenderTokenParser;
@@ -63,6 +64,7 @@ class Twig
$this->addFilter_truncate();
$this->addFilter_notificiation();
$this->addFilter_percentage();
+ $this->addFilter_prettyDate();
$this->twig->addFilter(new Twig_SimpleFilter('implode', 'implode'));
$this->twig->addFilter(new Twig_SimpleFilter('ucwords', 'ucwords'));
@@ -187,6 +189,14 @@ class Twig
$this->twig->addFilter($notificationFunction);
}
+ protected function addFilter_prettyDate()
+ {
+ $prettyDate = new Twig_SimpleFilter('prettyDate', function ($dateString, $period) {
+ return Range::factory($period, $dateString)->getLocalizedShortString();
+ });
+ $this->twig->addFilter($prettyDate);
+ }
+
protected function addFilter_percentage()
{
$percentage = new Twig_SimpleFilter('percentage', function ($string, $totalValue, $precision = 1) {
diff --git a/plugins/Insights/API.php b/plugins/Insights/API.php
index f29d301c7a..9a95624fcf 100644
--- a/plugins/Insights/API.php
+++ b/plugins/Insights/API.php
@@ -31,39 +31,57 @@ class API extends \Piwik\Plugin\API
const ORDER_BY_ABSOLUTE = 'absolute';
const ORDER_BY_IMPORTANCE = 'importance';
- public function getInsightsOverview($idSite, $period, $date)
+ private $reportIds = array(
+ 'Actions_getPageUrls',
+ 'Actions_getPageTitles',
+ 'Actions_getDownloads',
+ 'Referrers_getAll',
+ 'Referrers_getKeywords',
+ 'Referrers_getCampaigns',
+ 'Referrers_getSocials',
+ 'Referrers_getSearchEngines',
+ 'UserCountry_getCountry',
+ );
+
+ public function getInsightsOverview($idSite, $period, $date, $segment = false)
{
Piwik::checkUserHasViewAccess(array($idSite));
+ $reportTableIds = array();
+
/** @var DataTable[] $tables */
- $reports = array(
- 'Actions_getPageUrls',
- 'Actions_getPageTitles',
- 'Actions_getDownloads',
- 'Referrers_getAll',
- 'Referrers_getKeywords',
- 'Referrers_getCampaigns',
- 'Referrers_getSocials',
- 'Referrers_getSearchEngines',
- 'UserCountry_getCountry',
- );
- // post event to add other reports?
+ $tables = array();
+ foreach ($this->reportIds as $reportId) {
+ $firstTableId = DataTable\Manager::getInstance()->getMostRecentTableId();
+ $table = $this->getInsights($idSite, $period, $date, $reportId, $segment, 3, 3, '', 2, 25);
+ $reportTableIds[] = $table->getId();
+ $this->deleteDataTables($firstTableId, $reportTableIds);
- $reportTableIds = array();
- $dataTableManager = DataTable\Manager::getInstance();
+ $tables[] = $table;
+ }
+
+ $map = new DataTable\Map();
+
+ foreach ($tables as $table) {
+ $map->addTable($table, $table->getMetadata('reportName'));
+ }
+
+ return $map;
+ }
+ public function getOverallMoversAndShakers($idSite, $period, $date, $segment = false)
+ {
+ Piwik::checkUserHasViewAccess(array($idSite));
+
+ $reportTableIds = array();
+
+ /** @var DataTable[] $tables */
$tables = array();
- foreach ($reports as $report) {
- $firstTableId = $dataTableManager->getMostRecentTableId();
- $table = $this->getInsightOverview($idSite, $period, $date, $report);
+ foreach ($this->reportIds as $reportId) {
+ $firstTableId = DataTable\Manager::getInstance()->getMostRecentTableId();
+ $table = $this->getMoversAndShakers($idSite, $period, $date, $reportId, $segment, 4, 4);
$reportTableIds[] = $table->getId();
- $lastTableId = $dataTableManager->getMostRecentTableId();
-
- for ($index = $firstTableId; $index <= $lastTableId; $index++) {
- if (!in_array($index, $reportTableIds)) {
- $dataTableManager->deleteTable($index);
- }
- }
+ $this->deleteDataTables($firstTableId, $reportTableIds);
$tables[] = $table;
}
@@ -77,18 +95,21 @@ class API extends \Piwik\Plugin\API
return $map;
}
- public function getInsightOverview($idSite, $period, $date, $reportUniqueId, $segment = false, $limitIncreaser = 4,
- $limitDecreaser = 4, $minVisitsPercent = 3, $minGrowthPercent = 25, $orderBy = 'absolute',
- $considerMovers = true, $considerNew = true, $considerDisappeared = false)
+ public function getMoversAndShakers($idSite, $period, $date, $reportUniqueId, $segment = false,
+ $limitIncreaser = 4, $limitDecreaser = 4)
{
+ $orderBy = 'absolute';
+ $minVisitsPercent = 2;
+ $minGrowthPercent = 30;
+ $minMoversPercent = 2;
+ $minNewPercent = 2;
+ $minDisappearedPercent = 2;
+
Piwik::checkUserHasViewAccess(array($idSite));
$metric = 'nb_visits';
- // consider disappeared if impact > 10%?
-
- $totalValue = $this->getTotalValue($idSite, $period, $date, $metric);
- $minVisits = $this->getMinVisits($totalValue, $minVisitsPercent);
+ $totalValue = $this->getTotalValue($idSite, $period, $date, $metric);
$report = $this->getReportByUniqueId($idSite, $reportUniqueId);
$currentReport = $this->requestReport($idSite, $period, $date, $report, $metric, $segment);
@@ -97,28 +118,29 @@ class API extends \Piwik\Plugin\API
// for faster performance just compare against last week?
$pastDate = Date::factory($date);
$pastDate = $pastDate->subDay(7);
- $lastDate = $pastDate->toString();
- $lastReport = $this->requestReport($idSite, 'week', $lastDate, $report, $metric, $segment);
+ $pastDate = $pastDate->toString();
+ $lastReport = $this->requestReport($idSite, 'week', $pastDate, $report, $metric, $segment);
$lastReport->filter('Piwik\Plugins\Insights\DataTable\Filter\Average', array($metric, 7));
+ $lastDate = Range::factory('week', $pastDate);
+ $lastDate = $lastDate->getRangeString();
} else {
$pastDate = Range::getLastDate($date, $period);
if (empty($pastDate[0])) {
- return new DataTable();
+ throw new \Exception('Not possible to calculate movers and shakers for this date/period combination');
}
$lastDate = $pastDate[0];
$lastReport = $this->requestReport($idSite, $period, $lastDate, $report, $metric, $segment);
}
- return $this->buildInsightsReport($period, $date, $limitIncreaser, $limitDecreaser, $minGrowthPercent, $orderBy, $currentReport, $lastReport, $metric, $considerMovers, $considerNew, $considerDisappeared, $minVisits, $report, $lastDate, $totalValue);
+ return $this->buildDataTable($report, $period, $date, $lastDate, $metric, $currentReport, $lastReport, $totalValue, $minVisitsPercent, $minMoversPercent, $minNewPercent, $minDisappearedPercent, $minGrowthPercent, $orderBy, $limitIncreaser, $limitDecreaser);
}
- // force $limitX and ignore minVisitsPercent, minGrowthPercent
public function getInsights(
- $idSite, $period, $date, $reportUniqueId, $limitIncreaser = 5, $limitDecreaser = 5,
+ $idSite, $period, $date, $reportUniqueId, $segment = false, $limitIncreaser = 5, $limitDecreaser = 5,
$filterBy = '', $minVisitsPercent = 2, $minGrowthPercent = 20,
- $comparedToXPeriods = 1, $orderBy = 'absolute', $segment = false)
+ $comparedToXPeriods = 1, $orderBy = 'absolute')
{
Piwik::checkUserHasViewAccess(array($idSite));
@@ -127,33 +149,36 @@ class API extends \Piwik\Plugin\API
$lastDate = Range::getDateXPeriodsAgo(abs($comparedToXPeriods), $date, $period);
+ if (empty($lastDate[0])) {
+ throw new \Exception('Not possible to calculate movers and shakers for this date/period combination');
+ }
+
$currentReport = $this->requestReport($idSite, $period, $date, $report, $metric, $segment);
$lastReport = $this->requestReport($idSite, $period, $lastDate[0], $report, $metric, $segment);
$totalValue = $this->getRelevantTotalValue($idSite, $period, $date, $currentReport, $metric);
- $minVisits = $this->getMinVisits($totalValue, $minVisitsPercent);
- $considerMovers = false;
- $considerNew = false;
- $considerDisappeared = false;
+ $minMoversPercent = -1;
+ $minNewPercent = -1;
+ $minDisappearedPercent = -1;
switch ($filterBy) {
case self::FILTER_BY_MOVERS:
- $considerMovers = true;
+ $minMoversPercent = 0;
break;
case self::FILTER_BY_NEW:
- $considerNew = true;
+ $minNewPercent = 0;
break;
case self::FILTER_BY_DISAPPEARED:
- $considerDisappeared = true;
+ $minDisappearedPercent = 0;
break;
default:
- $considerMovers = true;
- $considerNew = true;
- $considerDisappeared = true;
+ $minMoversPercent = 0;
+ $minNewPercent = 0;
+ $minDisappearedPercent = 0;
}
- return $this->buildInsightsReport($period, $date, $limitIncreaser, $limitDecreaser, $minGrowthPercent, $orderBy, $currentReport, $lastReport, $metric, $considerMovers, $considerNew, $considerDisappeared, $minVisits, $report, $lastDate[0], $totalValue);
+ return $this->buildDataTable($report, $period, $date, $lastDate[0], $metric, $currentReport, $lastReport, $totalValue, $minVisitsPercent, $minMoversPercent, $minNewPercent, $minDisappearedPercent, $minGrowthPercent, $orderBy, $limitIncreaser, $limitDecreaser);
}
private function requestReport($idSite, $period, $date, $report, $metric, $segment)
@@ -197,9 +222,9 @@ class API extends \Piwik\Plugin\API
return $orderByColumn;
}
- private function getMinVisits($totalValue, $minVisitsPercent)
+ private function getMinVisits($totalValue, $percent)
{
- $minVisits = ceil(($totalValue / 100) * $minVisitsPercent);
+ $minVisits = ceil(($totalValue / 100) * $percent);
return (int) $minVisits;
}
@@ -218,8 +243,9 @@ class API extends \Piwik\Plugin\API
private function getTotalValue($idSite, $period, $date, $metric)
{
- $visits = VisitsSummaryAPI::getInstance()->get($idSite, $period, $date, false, array($metric));
+ $visits = VisitsSummaryAPI::getInstance()->get($idSite, $period, $date, false, array($metric));
$totalValue = $visits->getFirstRow()->getColumn($metric);
+
return $totalValue;
}
@@ -236,8 +262,36 @@ class API extends \Piwik\Plugin\API
return $totalValue;
}
- private function buildInsightsReport($period, $date, $limitIncreaser, $limitDecreaser, $minGrowthPercent, $orderBy, $currentReport, $lastReport, $metric, $considerMovers, $considerNew, $considerDisappeared, $minVisits, $report, $lastDate, $totalValue)
+ /**
+ * @param array $reportMetadata
+ * @param string $period
+ * @param string $date
+ * @param string $lastDate
+ * @param string $metric
+ * @param DataTable $currentReport
+ * @param DataTable $lastReport
+ * @param int $totalValue
+ * @param int $minVisitsPercent Row must have at least min percent visits of totalVisits
+ * @param int $minVisitsMoversPercent Exclude rows who moved and the difference is not at least min percent
+ * visits of totalVisits. -1 excludes movers.
+ * @param int $minVisitsNewPercent Exclude rows who are new and the difference is not at least min percent
+ * visits of totalVisits. -1 excludes all new.
+ * @param int $minVisitsDisappearedPercent Exclude rows who are disappeared and the difference is not at least min
+ * percent visits of totalVisits. -1 excludes all disappeared.
+ * @param int $minGrowthPercent The actual growth of a row must be at least percent compared to the
+ * previous value (not total value)
+ * @param string $orderBy Order by absolute, relative, importance
+ * @param int $limitIncreaser
+ * @param int $limitDecreaser
+ * @return DataTable
+ */
+ private function buildDataTable($reportMetadata, $period, $date, $lastDate, $metric, $currentReport, $lastReport, $totalValue, $minVisitsPercent, $minVisitsMoversPercent, $minVisitsNewPercent, $minVisitsDisappearedPercent, $minGrowthPercent, $orderBy, $limitIncreaser, $limitDecreaser)
{
+ $minVisits = $this->getMinVisits($totalValue, $minVisitsPercent);
+ $minChangeMovers = 0;
+ $minIncreaseNew = 0;
+ $minDecreaseDisappeared = 0;
+
$dataTable = new DataTable();
$dataTable->filter(
'Piwik\Plugins\Insights\DataTable\Filter\Insight',
@@ -245,9 +299,9 @@ class API extends \Piwik\Plugin\API
$currentReport,
$lastReport,
$metric,
- $considerMovers,
- $considerNew,
- $considerDisappeared
+ $considerMovers = (-1 !== $minVisitsMoversPercent),
+ $considerNew = (-1 !== $minVisitsNewPercent),
+ $considerDisappeared = (-1 !== $minVisitsDisappearedPercent)
)
);
@@ -255,7 +309,7 @@ class API extends \Piwik\Plugin\API
'Piwik\Plugins\Insights\DataTable\Filter\MinGrowth',
array(
'growth_percent_numeric',
- $minGrowthPercent
+ $minGrowthPercent,
)
);
@@ -267,6 +321,42 @@ class API extends \Piwik\Plugin\API
)
);
+ if ($minVisitsNewPercent) {
+ $minIncreaseNew = $this->getMinVisits($totalValue, $minVisitsNewPercent);
+ $dataTable->filter(
+ 'Piwik\Plugins\Insights\DataTable\Filter\ExcludeLowValue',
+ array(
+ 'difference',
+ $minIncreaseNew,
+ 'isNew'
+ )
+ );
+ }
+
+ if ($minVisitsMoversPercent) {
+ $minChangeMovers = $this->getMinVisits($totalValue, $minVisitsMoversPercent);
+ $dataTable->filter(
+ 'Piwik\Plugins\Insights\DataTable\Filter\ExcludeLowValue',
+ array(
+ 'difference',
+ $minChangeMovers,
+ 'isMover'
+ )
+ );
+ }
+
+ if ($minVisitsDisappearedPercent) {
+ $minDecreaseDisappeared = $this->getMinVisits($totalValue, $minVisitsDisappearedPercent);
+ $dataTable->filter(
+ 'Piwik\Plugins\Insights\DataTable\Filter\ExcludeLowValue',
+ array(
+ 'difference',
+ $minDecreaseDisappeared,
+ 'isDisappeared'
+ )
+ );
+ }
+
$dataTable->filter(
'Piwik\Plugins\Insights\DataTable\Filter\OrderBy',
array(
@@ -284,14 +374,22 @@ class API extends \Piwik\Plugin\API
);
$dataTable->setMetadataValues(array(
- 'reportName' => $report['name'],
- 'metricName' => $report['metrics'][$metric],
+ 'reportName' => $reportMetadata['name'],
+ 'metricName' => $reportMetadata['metrics'][$metric],
'date' => $date,
'lastDate' => $lastDate,
'period' => $period,
- 'report' => $report,
+ 'report' => $reportMetadata,
'totalValue' => $totalValue,
- 'minVisits' => $minVisits
+ 'minValue' => $minVisits,
+ 'minChangeMovers' => $minChangeMovers,
+ 'minIncreaseNew' => $minIncreaseNew,
+ 'minDecreaseDisappeared' => $minDecreaseDisappeared,
+ 'minValuePercent' => $minVisitsPercent,
+ 'minGrowthPercent' => $minGrowthPercent,
+ 'minVisitsMoversPercent' => $minVisitsMoversPercent,
+ 'minVisitsNewPercent' => $minVisitsNewPercent,
+ 'minVisitsDisappearedPercent' => $minVisitsDisappearedPercent
));
return $dataTable;
@@ -301,6 +399,19 @@ class API extends \Piwik\Plugin\API
{
$processedReport = new ProcessedReport();
$report = $processedReport->getReportMetadataByUniqueId($idSite, $reportUniqueId);
+
return $report;
}
+
+ private function deleteDataTables($firstTableId, $dataTableIdsToBeIgnored)
+ {
+ $dataTableManager = DataTable\Manager::getInstance();
+ $lastTableId = $dataTableManager->getMostRecentTableId();
+
+ for ($index = $firstTableId; $index <= $lastTableId; $index++) {
+ if (!in_array($index, $dataTableIdsToBeIgnored)) {
+ $dataTableManager->deleteTable($index);
+ }
+ }
+ }
}
diff --git a/plugins/Insights/Controller.php b/plugins/Insights/Controller.php
index 8526052215..b9431f5a3c 100644
--- a/plugins/Insights/Controller.php
+++ b/plugins/Insights/Controller.php
@@ -18,7 +18,21 @@ use Piwik\View;
class Controller extends \Piwik\Plugin\Controller
{
- public function getInsightOverview()
+ public function getInsightsOverview()
+ {
+ $view = $this->prepareWidget($apiReport = 'getInsightsOverview');
+
+ return $view->render();
+ }
+
+ public function getOverallMoversAndShakers()
+ {
+ $view = $this->prepareWidget($apiReport = 'getOverallMoversAndShakers');
+
+ return $view->render();
+ }
+
+ private function prepareWidget($apiReport)
{
$idSite = Common::getRequestVar('idSite', null, 'int');
$period = Common::getRequestVar('period', null, 'string');
@@ -26,18 +40,14 @@ class Controller extends \Piwik\Plugin\Controller
Piwik::checkUserHasViewAccess(array($idSite));
- $view = new View('@Insights/index.twig');
+ $view = new View('@Insights/overviewWidget.twig');
$this->setBasicVariablesView($view);
- $view->moversAndShakers = API::getInstance()->getInsightsOverview($idSite, $period, $date);
- $view->showNoDataMessage = false;
- $view->showInsightsControls = false;
+ $view->reports = API::getInstance()->$apiReport($idSite, $period, $date);
$view->properties = array(
- 'show_increase' => true,
- 'show_decrease' => true,
'order_by' => 'absolute'
);
- return $view->render();
+ return $view;
}
}
diff --git a/plugins/Insights/DataTable/Filter/ExcludeLowValue.php b/plugins/Insights/DataTable/Filter/ExcludeLowValue.php
index aea5d1d9ea..2d2c3ede4b 100644
--- a/plugins/Insights/DataTable/Filter/ExcludeLowValue.php
+++ b/plugins/Insights/DataTable/Filter/ExcludeLowValue.php
@@ -14,11 +14,21 @@ class ExcludeLowValue extends DataTable\BaseFilter
{
private $minimumValue;
private $columnToRead;
+ private $columnToCheckToBeTrue;
- public function __construct($table, $columnToRead, $minimumValue)
+ /**
+ * @param DataTable $table
+ * @param string $columnToRead
+ * @param int $minimumValue
+ * @param string $columnToCheckToBeTrue if set, we will delete a row only if this column evaluates to true. If
+ * column does not evaluate to true we will not delete the row even if
+ * the value is lower than the minimumValue.
+ */
+ public function __construct($table, $columnToRead, $minimumValue, $columnToCheckToBeTrue = '')
{
$this->columnToRead = $columnToRead;
$this->minimumValue = $minimumValue;
+ $this->columnToCheckToBeTrue = $columnToCheckToBeTrue;
}
public function filter($table)
@@ -27,11 +37,17 @@ class ExcludeLowValue extends DataTable\BaseFilter
return;
}
- $minimumValue = $this->minimumValue;
- $isValueLowPopulation = function ($value) use ($minimumValue) {
- return $value < $minimumValue;
- };
+ foreach ($table->getRows() as $key => $row) {
- $table->filter('ColumnCallbackDeleteRow', array($this->columnToRead, $isValueLowPopulation));
+ if ($this->columnToCheckToBeTrue && !$row->getColumn($this->columnToCheckToBeTrue)) {
+ continue;
+ }
+
+ $value = $row->getColumn($this->columnToRead);
+
+ if ($this->minimumValue > $value) {
+ $table->deleteRow($key);
+ }
+ }
}
} \ No newline at end of file
diff --git a/plugins/Insights/DataTable/Filter/Insight.php b/plugins/Insights/DataTable/Filter/Insight.php
index 44d767cccf..699d9a6614 100644
--- a/plugins/Insights/DataTable/Filter/Insight.php
+++ b/plugins/Insights/DataTable/Filter/Insight.php
@@ -30,53 +30,69 @@ class Insight extends DataTable\Filter\CalculateEvolutionFilter
public function filter($table)
{
- foreach ($this->currentDataTable->getRows() as $key => $row) {
- $pastRow = $this->getPastRowFromCurrent($row);
- $oldValue = 0;
+ foreach ($this->currentDataTable->getRows() as $row) {
+ $this->addRowIfNewOrMover($table, $row);
+ }
- if (!$pastRow && !$this->considerNew) {
- continue;
+ if ($this->considerDisappeared) {
+ foreach ($this->pastDataTable->getRows() as $row) {
+ $this->addRowIfDisappeared($table, $row);
}
+ }
+ }
- if ($pastRow && $this->considerMovers) {
- $oldValue = $pastRow->getColumn($this->columnValueToRead);
- } elseif ($pastRow) {
- continue;
- }
+ private function addRowIfDisappeared(DataTable $table, DataTable\Row $row)
+ {
+ if ($this->getRowFromTable($this->currentDataTable, $row)) {
+ return;
+ }
- $difference = $this->getDividend($row);
- if ($difference === false) {
- continue;
- }
+ $newValue = 0;
+ $oldValue = $row->getColumn($this->columnValueToRead);
+ $difference = $newValue - $oldValue;
+
+ if ($oldValue == 0 && $newValue == 0) {
+ $growthPercentage = '0%';
+ } else {
+ $growthPercentage = '-100%';
+ }
- $newValue = $row->getColumn($this->columnValueToRead);
- $divisor = $this->getDivisor($row);
+ $this->addRow($table, $row, $growthPercentage, $newValue, $oldValue, $difference, $isDisappeared = true);
+ }
- $growthPercentage = $this->formatValue($difference, $divisor);
+ private function addRowIfNewOrMover(DataTable $table, DataTable\Row $row)
+ {
+ $pastRow = $this->getPastRowFromCurrent($row);
- $this->addRow($table, $row, $growthPercentage, $newValue, $oldValue, $difference);
+ if (!$pastRow && !$this->considerNew) {
+ return;
+ } elseif ($pastRow && !$this->considerMovers) {
+ return;
}
- if ($this->considerDisappeared) {
- foreach ($this->pastDataTable->getRows() as $key => $row) {
+ $isNew = false;
+ $isMover = false;
+ $isDisappeared = false;
+
+ if (!$pastRow) {
+ $isNew = true;
+ $oldValue = 0;
+ } else {
+ $isMover = true;
+ $oldValue = $pastRow->getColumn($this->columnValueToRead);
+ }
- if ($this->getRowFromTable($this->currentDataTable, $row)) {
- continue;
- }
+ $difference = $this->getDividend($row);
+ if ($difference === false) {
+ return;
+ }
- $newValue = 0;
- $oldValue = $row->getColumn($this->columnValueToRead);
- $difference = $newValue - $oldValue;
+ $newValue = $row->getColumn($this->columnValueToRead);
+ $divisor = $this->getDivisor($row);
- if ($oldValue == 0 && $newValue == 0) {
- $growthPercentage = '0%';
- } else {
- $growthPercentage = '-100%';
- }
+ $growthPercentage = $this->formatValue($difference, $divisor);
- $this->addRow($table, $row, $growthPercentage, $newValue, $oldValue, $difference);
- }
- }
+ $this->addRow($table, $row, $growthPercentage, $newValue, $oldValue, $difference, $isDisappeared, $isNew, $isMover);
}
private function getRowFromTable(DataTable $table, DataTable\Row $row)
@@ -84,7 +100,7 @@ class Insight extends DataTable\Filter\CalculateEvolutionFilter
return $table->getRowFromLabel($row->getColumn('label'));
}
- private function addRow(DataTable $table, DataTable\Row $row, $growthPercentage, $newValue, $oldValue, $difference)
+ private function addRow(DataTable $table, DataTable\Row $row, $growthPercentage, $newValue, $oldValue, $difference, $disappeared = false, $isNew = false, $isMover = false)
{
$columns = $row->getColumns();
$columns['growth_percent'] = $growthPercentage;
@@ -94,6 +110,9 @@ class Insight extends DataTable\Filter\CalculateEvolutionFilter
$columns['value_new'] = $newValue;
$columns['difference'] = $difference;
$columns['importance'] = abs($difference);
+ $columns['isDisappeared'] = $disappeared;
+ $columns['isNew'] = $isNew;
+ $columns['isMover'] = $isMover;
$table->addRowFromArray(array(DataTable\Row::COLUMNS => $columns));
}
diff --git a/plugins/Insights/Insights.php b/plugins/Insights/Insights.php
index 1753b32aa8..9c915ce99d 100644
--- a/plugins/Insights/Insights.php
+++ b/plugins/Insights/Insights.php
@@ -34,7 +34,8 @@ class Insights extends \Piwik\Plugin
public function addWidgets()
{
- WidgetsList::add('Insights_Category', 'Insights_OverviewWidgetTitle', 'Insights', 'getInsightOverview');
+ WidgetsList::add('Insights_WidgetCategory', 'Insights_OverviewWidgetTitle', 'Insights', 'getInsightsOverview');
+ WidgetsList::add('Insights_WidgetCategory', 'Insights_MoversAndShakersWidgetTitle', 'Insights', 'getOverallMoversAndShakers');
}
public function getStylesheetFiles(&$stylesheets)
diff --git a/plugins/Insights/Visualizations/Insight.php b/plugins/Insights/Visualizations/Insight.php
index f16c913b0f..cd68023dea 100644
--- a/plugins/Insights/Visualizations/Insight.php
+++ b/plugins/Insights/Visualizations/Insight.php
@@ -25,7 +25,7 @@ class Insight extends Visualization
{
const ID = 'insightsVisualization';
const TEMPLATE_FILE = '@Insights/insightVisualization.twig';
- const FOOTER_ICON_TITLE = 'InsightsVisualization';
+ const FOOTER_ICON_TITLE = 'Insights';
const FOOTER_ICON = 'plugins/Insights/images/idea.png';
public function beforeLoadDataTable()
@@ -80,8 +80,6 @@ class Insight extends Visualization
public function afterAllFiltersAreApplied()
{
- $this->assignTemplateVar('showNoDataMessage', true);
- $this->assignTemplateVar('showInsightsControls', true);
$this->assignTemplateVar('period', Common::getRequestVar('period', null, 'string'));
}
diff --git a/plugins/Insights/lang/en.json b/plugins/Insights/lang/en.json
index acc356241a..f142b6add0 100644
--- a/plugins/Insights/lang/en.json
+++ b/plugins/Insights/lang/en.json
@@ -1,7 +1,12 @@
{
"Insights": {
"OverviewWidgetTitle": "Insights Overview",
- "Category": "Insights",
- "NoResultMatchesCriteria": "No rows match the criteria"
+ "WidgetCategory": "Insights",
+ "NoResultMatchesCriteria": "No rows match the criteria",
+ "MoversAndShakersWidgetTitle": "Movers and Shakers",
+ "TitleConsideredVisits": "Considered rows having at least %s visits (%s%% of %s visits) with a growth of at least %s%% compared to %s.",
+ "TitleConsideredChanges": "Considered movers only if they increased or decreased by more than %s visits, new entries only if they increase by more than %s visits, and disappeared rows if they decreased by more than %s visits.",
+ "TitleReportBasedOn": "Based on %s %s, rows less than %s %s were ignored",
+ "TitleRowChangeDetails": "'%s' changed from %s (%s) to %s (%s) %s"
}
} \ No newline at end of file
diff --git a/plugins/Insights/stylesheets/insightVisualization.less b/plugins/Insights/stylesheets/insightVisualization.less
index b559c9e36a..a5ed362414 100644
--- a/plugins/Insights/stylesheets/insightVisualization.less
+++ b/plugins/Insights/stylesheets/insightVisualization.less
@@ -25,4 +25,11 @@
.notGrown {
color:red;
}
+
+ table td {
+ &.labelodd, &.labeleven {
+
+ background-image: none;
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/Insights/templates/index.twig b/plugins/Insights/templates/index.twig
deleted file mode 100644
index fc91a81330..0000000000
--- a/plugins/Insights/templates/index.twig
+++ /dev/null
@@ -1,5 +0,0 @@
-{% for dataTable in moversAndShakers.getDataTables() %}
-
- {% include "@Insights/insightVisualization.twig" %}
-
-{% endfor %} \ No newline at end of file
diff --git a/plugins/Insights/templates/insightControls.twig b/plugins/Insights/templates/insightControls.twig
index d976ecccf8..d2d3779bd6 100644
--- a/plugins/Insights/templates/insightControls.twig
+++ b/plugins/Insights/templates/insightControls.twig
@@ -1,5 +1,5 @@
<div style="padding: 10px;padding-bottom: 0px;">
- Minimum impact of
+ Minimum visits of
<select name="minVisitsPercent" title="Based on a total of {{ dataTable.getMetadata('totalValue') }} visitors or metricname">
{% for i in range(0, 10) %}
<option {% if i == properties.min_visits_percent %}selected{% endif %} value="{{ i }}">{{ i }}%</option>
@@ -7,7 +7,7 @@
{% for i in range(12, 30, 2) %}
<option {% if i == properties.min_visits_percent %}selected{% endif %} value="{{ i }}">{{ i }}%</option>
{% endfor %}
- {% for i in range(35, 100, 5) %}
+ {% for i in range(40, 100, 10) %}
<option {% if i == properties.min_visits_percent %}selected{% endif %} value="{{ i }}">{{ i }}%</option>
{% endfor %}
</select>
@@ -25,28 +25,30 @@
{% endfor %}
</select>
- compared to
- {% if period == 'day' %}
- <select size="1" name="comparedToXPeriodsAgo">
- <option value="1" {% if properties.compared_to_x_periods_ago == 1 %}selected{% endif %}>
- previous day
- </option>
- <option value="7" {% if properties.compared_to_x_periods_ago == 7 %}selected{% endif %}>
- same day in previous week
- </option>
- <option value="365" {% if properties.compared_to_x_periods_ago == 365 %}selected{% endif %}>
- same day in previous year
- </option>
- </select>
- {% elseif period == 'month' %}
- <select size="1" name="comparedToXPeriodsAgo">
- <option value="1" {% if properties.compared_to_x_periods_ago == 1 %}selected{% endif %}>
- previous month
- </option>
- <option value="12" {% if properties.compared_to_x_periods_ago == 12 %}selected{% endif %}>
- same month in previous year
- </option>
- </select>
+ {% if period == 'day' or period == 'month' %}
+ compared to
+ {% if period == 'day' %}
+ <select size="1" name="comparedToXPeriodsAgo">
+ <option value="1" {% if properties.compared_to_x_periods_ago == 1 %}selected{% endif %}>
+ previous day
+ </option>
+ <option value="7" {% if properties.compared_to_x_periods_ago == 7 %}selected{% endif %}>
+ same day in previous week
+ </option>
+ <option value="365" {% if properties.compared_to_x_periods_ago == 365 %}selected{% endif %}>
+ same day in previous year
+ </option>
+ </select>
+ {% elseif period == 'month' %}
+ <select size="1" name="comparedToXPeriodsAgo">
+ <option value="1" {% if properties.compared_to_x_periods_ago == 1 %}selected{% endif %}>
+ previous month
+ </option>
+ <option value="12" {% if properties.compared_to_x_periods_ago == 12 %}selected{% endif %}>
+ same month in previous year
+ </option>
+ </select>
+ {% endif %}
{% endif %}
<hr style="height: 1px;border: 0px;background-color: #cccccc;" />
diff --git a/plugins/Insights/templates/insightVisualization.twig b/plugins/Insights/templates/insightVisualization.twig
index 9c9f72c479..1ca0fac5ec 100644
--- a/plugins/Insights/templates/insightVisualization.twig
+++ b/plugins/Insights/templates/insightVisualization.twig
@@ -1,54 +1,24 @@
-<div class="insightsDataTable">
+{% set metadata = dataTable.getAllTableMetadata%}
+{% set consideredVisits = 'Insights_TitleConsideredVisits'|translate(metadata.minValue, metadata.minValuePercent, metadata.totalValue, metadata.minGrowthPercent, metadata.lastDate|prettyDate(metadata.period)) %}
+
+<div class="insightsDataTable" title="{{ consideredVisits|e('html_attr') }}">
{% if dataTable.getRowsCount > 0 %}
<table class="dataTable">
<thead>
- <tr title="Based on {{ dataTable.getMetadata('totalValue') }} {{ dataTable.getMetadata('metricName') }}, rows less than {{ dataTable.getMetadata('minVisits') }} {{ dataTable.getMetadata('metricName') }} were ignored">
- <th class="label">
- {{ dataTable.getMetadata('reportName') }}
- </th>
- <th class="label orderBy" name="orderBy" value="absolute"
- style="{% if 'absolute' == properties.order_by %}font-weight:bold;{% endif %}">
- {{ dataTable.getMetadata('metricName') }}
- </th>
- <th class="label orderBy" name="orderBy" value="relative"
- style="{% if 'relative' == properties.order_by %}font-weight:bold;{% endif %}">
- {{ 'MultiSites_Evolution'|translate }}
- </th>
- </tr>
+ {% include "@Insights/table_header.twig" %}
</thead>
- <tbody>
-
- {% for row in dataTable.getRows %}
- <tr title="{{ dataTable.getMetadata('metricName') }} changed from {{ row.getColumn('value_old') }} ({{ dataTable.getMetadata('lastDate') }}) to {{ row.getColumn('value_new') }} ({{ dataTable.getMetadata('date') }})">
- <td>
- <span class="title"
- title="{{ row.getColumn('label') }}">
- {{ row.getColumn('label') }}
- </span>
- </td>
- {% if row.getColumn('grown') %}
- <td>+{{ row.getColumn('difference') }}</td>
- <td class="grown">
- +{{ row.getColumn('growth_percent') }}
- </td>
- {% else %}
- <td>{{ row.getColumn('difference') }}</td>
- <td class="notGrown">
- {{ row.getColumn('growth_percent') }}
- </td>
- {% endif %}
- </tr>
- {% endfor %}
+ <tbody>
+ {% for row in dataTable.getRows %}
+ {% include "@Insights/table_row.twig" %}
+ {% endfor %}
</tbody>
</table>
- {% elseif showNoDataMessage %}
+ {% else %}
<div class="pk-emptyDataTable">
{{ 'Insights_NoResultMatchesCriteria'|translate }}
</div>
{% endif %}
- {% if showInsightsControls %}
- {% include "@Insights/insightControls.twig" %}
- {% endif %}
+ {% include "@Insights/insightControls.twig" %}
</div> \ No newline at end of file
diff --git a/plugins/Insights/templates/overviewWidget.twig b/plugins/Insights/templates/overviewWidget.twig
new file mode 100644
index 0000000000..ca6898b398
--- /dev/null
+++ b/plugins/Insights/templates/overviewWidget.twig
@@ -0,0 +1,37 @@
+{% set allMetadata = reports.getFirstRow.getAllTableMetadata %}
+
+{% set consideredVisits = 'Insights_TitleConsideredVisits'|translate(allMetadata.minValue, allMetadata.minValuePercent, allMetadata.totalValue, allMetadata.minGrowthPercent, allMetadata.lastDate|prettyDate(allMetadata.period)) %}
+{% set consideredChanges = '' %}
+
+{% if allMetadata.minChangeMovers or allMetadata.minIncreaseNew or allMetadata.minDecreaseDisappeared %}
+ {% set consideredChanges = 'Insights_TitleConsideredChanges'|translate(allMetadata.minChangeMovers, allMetadata.minIncreaseNew, allMetadata.minDecreaseDisappeared) %}
+{% endif %}
+
+<div class="insightsDataTable" title="{{ consideredVisits|e('html_attr') }} {{ consideredChanges|e('html_attr') }}">
+ {% if reports.getColumns|length > 0 %}
+
+ <table class="dataTable">
+ {% for dataTable in reports.getDataTables() if dataTable.getRowsCount > 0 %}
+ {% set metadata = dataTable.getAllTableMetadata %}
+
+ <thead>
+ {% include "@Insights/table_header.twig" %}
+ </thead>
+
+ <tbody>
+ {% for row in dataTable.getRows %}
+ {% include "@Insights/table_row.twig" %}
+ {% endfor %}
+ </tbody>
+
+ {% endfor %}
+ </table>
+
+ {% else %}
+
+ <div class="pk-emptyDataTable">
+ {{ 'Insights_NoResultMatchesCriteria'|translate }}
+ </div>
+
+ {% endif %}
+</div> \ No newline at end of file
diff --git a/plugins/Insights/templates/table_header.twig b/plugins/Insights/templates/table_header.twig
new file mode 100644
index 0000000000..7226f88450
--- /dev/null
+++ b/plugins/Insights/templates/table_header.twig
@@ -0,0 +1,13 @@
+<tr>
+ <th class="label">
+ {{ metadata.reportName }}
+ </th>
+ <th class="label orderBy" name="orderBy" value="absolute"
+ style="{% if 'absolute' == properties.order_by %}font-weight:bold;{% endif %}">
+ {{ metadata.metricName }}
+ </th>
+ <th class="label orderBy" name="orderBy" value="relative"
+ style="{% if 'relative' == properties.order_by %}font-weight:bold;{% endif %}">
+ {{ 'MultiSites_Evolution'|translate }}
+ </th>
+</tr> \ No newline at end of file
diff --git a/plugins/Insights/templates/table_row.twig b/plugins/Insights/templates/table_row.twig
new file mode 100644
index 0000000000..bd3b04a2e7
--- /dev/null
+++ b/plugins/Insights/templates/table_row.twig
@@ -0,0 +1,15 @@
+<tr title="{{ 'Insights_TitleRowChangeDetails'|translate(row.getColumn('label'), row.getColumn('value_old'), metadata.lastDate|prettyDate(metadata.period), row.getColumn('value_new'), metadata.date|prettyDate(metadata.period), metadata.metricName)|e('html_attr') }}">
+ <td>
+ <span class="title">
+ {{ row.getColumn('label') }}
+ </span>
+ </td>
+
+ {% if row.getColumn('grown') %}
+ <td>+{{ row.getColumn('difference') }}</td>
+ <td class="grown">+{{ row.getColumn('growth_percent') }}</td>
+ {% else %}
+ <td>{{ row.getColumn('difference') }}</td>
+ <td class="notGrown">{{ row.getColumn('growth_percent') }}</td>
+ {% endif %}
+</tr> \ No newline at end of file
diff --git a/plugins/Insights/tests/FilterExcludeLowValueTest.php b/plugins/Insights/tests/FilterExcludeLowValueTest.php
index e9080c85da..45ddf8075e 100644
--- a/plugins/Insights/tests/FilterExcludeLowValueTest.php
+++ b/plugins/Insights/tests/FilterExcludeLowValueTest.php
@@ -29,17 +29,17 @@ class FilterExcludeLowValueTest extends \PHPUnit_Framework_TestCase
{
$this->table = new DataTable();
$this->table->addRowsFromArray(array(
- array(Row::COLUMNS => array('label' => 'val1', 'growth' => 22)),
- array(Row::COLUMNS => array('label' => 'val2', 'growth' => 14)),
- array(Row::COLUMNS => array('label' => 'val3', 'growth' => 18)),
- array(Row::COLUMNS => array('label' => 'val4', 'growth' => 20)),
- array(Row::COLUMNS => array('label' => 'val5', 'growth' => 22)),
- array(Row::COLUMNS => array('label' => 'val6', 'growth' => 25)),
- array(Row::COLUMNS => array('label' => 'val7', 'growth' => 17)),
- array(Row::COLUMNS => array('label' => 'val8', 'growth' => 20)),
- array(Row::COLUMNS => array('label' => 'val9', 'growth' => 0)),
- array(Row::COLUMNS => array('label' => 'val10', 'growth' => 15)),
- array(Row::COLUMNS => array('label' => 'val11', 'growth' => 16))
+ array(Row::COLUMNS => array('label' => 'val1', 'growth' => 22, 'isFooBar' => false)),
+ array(Row::COLUMNS => array('label' => 'val2', 'growth' => 14, 'isFooBar' => true)),
+ array(Row::COLUMNS => array('label' => 'val3', 'growth' => 18, 'isFooBar' => false)),
+ array(Row::COLUMNS => array('label' => 'val4', 'growth' => 20, 'isFooBar' => true)),
+ array(Row::COLUMNS => array('label' => 'val5', 'growth' => 22, 'isFooBar' => true)),
+ array(Row::COLUMNS => array('label' => 'val6', 'growth' => 25, 'isFooBar' => true)),
+ array(Row::COLUMNS => array('label' => 'val7', 'growth' => 17, 'isFooBar' => false)),
+ array(Row::COLUMNS => array('label' => 'val8', 'growth' => 20, 'isFooBar' => false)),
+ array(Row::COLUMNS => array('label' => 'val9', 'growth' => 0, 'isFooBar' => false)),
+ array(Row::COLUMNS => array('label' => 'val10', 'growth' => 15, 'isFooBar' => false)),
+ array(Row::COLUMNS => array('label' => 'val11', 'growth' => 16, 'isFooBar' => true))
));
}
@@ -74,15 +74,22 @@ class FilterExcludeLowValueTest extends \PHPUnit_Framework_TestCase
$this->assertOrder(array());
}
+ public function testShouldRemoveValuesOnlyIfColumnToCheckIsTrue()
+ {
+ $this->excludeLowValues(21, 'isFooBar');
+
+ $this->assertOrder(array('val1', 'val3', 'val5', 'val6', 'val7', 'val8', 'val9', 'val10'));
+ }
+
private function assertOrder($expectedOrder)
{
$this->assertEquals($expectedOrder, $this->table->getColumn('label'));
$this->assertEquals(count($expectedOrder), $this->table->getRowsCount());
}
- private function excludeLowValues($minimumValue)
+ private function excludeLowValues($minimumValue, $columnToCheck = null)
{
- $filter = new ExcludeLowValue($this->table, 'growth', $minimumValue);
+ $filter = new ExcludeLowValue($this->table, 'growth', $minimumValue, $columnToCheck);
$filter->filter($this->table);
}
diff --git a/plugins/Insights/tests/FilterInsightTest.php b/plugins/Insights/tests/FilterInsightTest.php
index 4a6431ce8a..f122f93aa7 100644
--- a/plugins/Insights/tests/FilterInsightTest.php
+++ b/plugins/Insights/tests/FilterInsightTest.php
@@ -148,6 +148,29 @@ class FilterInsightTest extends \PHPUnit_Framework_TestCase
$this->assertColumnValues($values);
}
+ public function testShouldDetectWhetherRowIsNewMoverOrDisappeared()
+ {
+ $this->applyInsightConsiderAll();
+
+ $values = array(
+ array('label' => 'val1', 'isNew' => false, 'isMover' => true, 'isDisappeared' => false),
+ array('label' => 'val2', 'isNew' => true, 'isMover' => false, 'isDisappeared' => false),
+ array('label' => 'val3', 'isNew' => true, 'isMover' => false, 'isDisappeared' => false),
+ array('label' => 'val4', 'isNew' => false, 'isMover' => true, 'isDisappeared' => false),
+ array('label' => 'val5', 'isNew' => true, 'isMover' => false, 'isDisappeared' => false),
+ array('label' => 'val6', 'isNew' => false, 'isMover' => true, 'isDisappeared' => false),
+ array('label' => 'val7', 'isNew' => true, 'isMover' => false, 'isDisappeared' => false),
+ array('label' => 'val8', 'isNew' => false, 'isMover' => true, 'isDisappeared' => false),
+ array('label' => 'val9', 'isNew' => false, 'isMover' => true, 'isDisappeared' => false),
+ array('label' => 'val10', 'isNew' => false, 'isMover' => true, 'isDisappeared' => false),
+ array('label' => 'val102', 'isNew' => false, 'isMover' => false, 'isDisappeared' => true),
+ array('label' => 'val109', 'isNew' => false, 'isMover' => false, 'isDisappeared' => true),
+ array('label' => 'val107', 'isNew' => false, 'isMover' => false, 'isDisappeared' => true)
+ );
+
+ $this->assertColumnValues($values);
+ }
+
public function testShouldCalculateDifferenceAndGrowthPercentage()
{
$this->applyInsightConsiderAll();