diff --git a/core/API/DocumentationGenerator.php b/core/API/DocumentationGenerator.php index 3f010a441d094e765fd4d0104c242f12190caef1..975cb3736fe7f3dcdf3bc3ff2dde3fc5936c0bf5 100644 --- a/core/API/DocumentationGenerator.php +++ b/core/API/DocumentationGenerator.php @@ -191,6 +191,8 @@ class Piwik_API_DocumentationGenerator $aParameters['label'] = false; $aParameters['flat'] = false; $aParameters['include_aggregate_rows'] = false; + $aParameters['filter_limit'] = false; //@review without adding this, I can not set filter_limit in $otherRequestParameters integration tests + $aParameters['filter_sort_column'] = false; //@review without adding this, I can not set filter_sort_column in $otherRequestParameters integration tests $aParameters['filter_truncate'] = false; $aParameters['hideColumns'] = false; $aParameters['showColumns'] = false; diff --git a/core/DataTable/Filter/AddColumnsProcessedMetrics.php b/core/DataTable/Filter/AddColumnsProcessedMetrics.php index 35fc3d09087c9766dd8796aed6ecfca3d74da6f5..08e1f592517a727efec31c627047c6a8f8c9dfb7 100644 --- a/core/DataTable/Filter/AddColumnsProcessedMetrics.php +++ b/core/DataTable/Filter/AddColumnsProcessedMetrics.php @@ -43,8 +43,18 @@ class Piwik_DataTable_Filter_AddColumnsProcessedMetrics extends Piwik_DataTable_ { $nbVisits = $this->getColumn($row, Piwik_Archive::INDEX_NB_VISITS); $nbActions = $this->getColumn($row, Piwik_Archive::INDEX_NB_ACTIONS); + + // @review Filter AddColumnsProcessedMetrics should not normally be called on Goals.* DataTables + // However, calling API.getRowEvolution with module=Goals method=getVisitsUntilConversion does trigger this filter + // because API.loadRowEvolutionDataFromAPI sets filter_add_columns_when_show_all_columns + // Goals.getVisitsUntilConversion contains only the nb_conversions metric, therefore, every DataTable Row are removed in this filter + // + // The other way to solve this issue is to add the following exceptions in API.getRowEvolution: module=Goals AND (method=getVisitsUntilConversion OR getDaysToConversion) + $conversions = $this->getColumn($row, Piwik_Archive::INDEX_NB_CONVERSIONS); + if($nbVisits == 0 && $nbActions == 0 + && $conversions == 0 && $this->deleteRowsWithNoVisit) { // case of keyword/website/campaign with a conversion for this day, diff --git a/core/ReportRenderer.php b/core/ReportRenderer.php index a4072255aa39336e7f7077b655112f19d9506d2b..192a7c8a6d0b2d29bb6efd6f81e44f32f11d6257 100644 --- a/core/ReportRenderer.php +++ b/core/ReportRenderer.php @@ -35,8 +35,6 @@ abstract class Piwik_ReportRenderer self::HTML_FORMAT, ); - protected $renderImageInline = false; - /** * Return the ReportRenderer associated to the renderer type $rendererType * @@ -65,18 +63,6 @@ abstract class Piwik_ReportRenderer } } - /** - * Currently only used for HTML reports. - * When sent by mail, images are attached to the mail: renderImageInline = false - * When downloaded, images are included base64 encoded in the report body: renderImageInline = true - * - * @param boolean $renderImageInline - */ - public function setRenderImageInline($renderImageInline) - { - $this->renderImageInline = $renderImageInline; - } - /** * Initialize locale settings. * If not called, locale settings defaults to 'en' @@ -234,7 +220,14 @@ abstract class Piwik_ReportRenderer ); } - public static function getStaticGraph($imageGraphUrl, $width, $height) { + public static function getStaticGraph($reportMetadata, $width, $height, $evolution) { + + $imageGraphUrl = $reportMetadata['imageGraphUrl']; + + if($evolution && !empty($reportMetadata['imageGraphEvolutionUrl'])) + { + $imageGraphUrl = $reportMetadata['imageGraphEvolutionUrl']; + } $request = new Piwik_API_Request( $imageGraphUrl . diff --git a/core/ReportRenderer/Html.php b/core/ReportRenderer/Html.php index 91d99a4b88ac1a34eaa9acde73a9188b0acb8f68..5b6a2fe5972b427f41d9f9e89b413887eeaac84c 100644 --- a/core/ReportRenderer/Html.php +++ b/core/ReportRenderer/Html.php @@ -28,6 +28,8 @@ class Piwik_ReportRenderer_Html extends Piwik_ReportRenderer const HTML_CONTENT_TYPE = 'text/html'; const HTML_FILE_EXTENSION = 'html'; + protected $renderImageInline = false; + private $rendering = ""; public function setLocale($locale) @@ -35,6 +37,18 @@ class Piwik_ReportRenderer_Html extends Piwik_ReportRenderer //Nothing to do } + /** + * Currently only used for HTML reports. + * When sent by mail, images are attached to the mail: renderImageInline = false + * When downloaded, images are included base64 encoded in the report body: renderImageInline = true + * + * @param boolean $renderImageInline + */ + public function setRenderImageInline($renderImageInline) + { + $this->renderImageInline = $renderImageInline; + } + public function sendToDisk($filename) { $this->epilogue(); @@ -116,6 +130,7 @@ class Piwik_ReportRenderer_Html extends Piwik_ReportRenderer $smarty->assign("displayTable", $processedReport['displayTable']); $displayGraph = $processedReport['displayGraph']; + $evolutionGraph = $processedReport['evolutionGraph']; $smarty->assign("displayGraph", $displayGraph); if($displayGraph) @@ -126,8 +141,7 @@ class Piwik_ReportRenderer_Html extends Piwik_ReportRenderer if($this->renderImageInline) { - $imageGraphUrl = $reportMetadata['imageGraphUrl']; - $staticGraph = parent::getStaticGraph($imageGraphUrl, self::IMAGE_GRAPH_WIDTH, self::IMAGE_GRAPH_HEIGHT); + $staticGraph = parent::getStaticGraph($reportMetadata, self::IMAGE_GRAPH_WIDTH, self::IMAGE_GRAPH_HEIGHT, $evolutionGraph); $smarty->assign("generatedImageGraph", base64_encode($staticGraph)); unset($generatedImageGraph); } diff --git a/core/ReportRenderer/Pdf.php b/core/ReportRenderer/Pdf.php index 51ef108e06683860594a016927f48653e1da3411..40bcf94ad720820ae44758876f1c692f8f613b05 100644 --- a/core/ReportRenderer/Pdf.php +++ b/core/ReportRenderer/Pdf.php @@ -66,6 +66,7 @@ class Piwik_ReportRenderer_Pdf extends Piwik_ReportRenderer private $report; private $reportMetadata; private $displayGraph; + private $evolutionGraph; private $displayTable; private $reportColumns; private $reportRowsMetadata; @@ -274,6 +275,7 @@ class Piwik_ReportRenderer_Pdf extends Piwik_ReportRenderer $this->reportMetadata = $processedReport['metadata']; $this->reportRowsMetadata = $processedReport['reportMetadata']; $this->displayGraph = $processedReport['displayGraph']; + $this->evolutionGraph = $processedReport['evolutionGraph']; $this->displayTable = $processedReport['displayTable']; list($this->report, $this->reportColumns) = self::processTableFormat($this->reportMetadata, $processedReport['reportData'], $processedReport['columns']); @@ -403,10 +405,15 @@ class Piwik_ReportRenderer_Pdf extends Piwik_ReportRenderer } else { $imageWidth = self::IMAGE_GRAPH_WIDTH_LANDSCAPE; $imageHeight = self::IMAGE_GRAPH_HEIGHT_LANDSCAPE; + + // evolution graphs in landscape are better looking if they have the same height as in portrait + if(empty($this->reportMetadata['dimension']) || ($this->evolutionGraph && !empty($this->reportMetadata['imageGraphEvolutionUrl']))) + { + $imageHeight = self::IMAGE_GRAPH_HEIGHT_PORTRAIT; + } } - $imageGraphUrl = $this->reportMetadata['imageGraphUrl']; - $imageGraph = parent::getStaticGraph($imageGraphUrl, $imageWidth, $imageHeight); + $imageGraph = parent::getStaticGraph($this->reportMetadata, $imageWidth, $imageHeight, $this->evolutionGraph); $this->TCPDF->Image( '@'.$imageGraph, diff --git a/lang/en.php b/lang/en.php index abd94f3625c63c33de762d5ad68e689ca02d02ad..8e612290b91d4c583c97208cb2ce2e13a34e4b4f 100644 --- a/lang/en.php +++ b/lang/en.php @@ -1622,6 +1622,7 @@ And thank you for using Piwik!', 'PDFReports_AggregateReportsFormat_TablesAndGraphs' => 'Display Report tables and Graphs for all reports', 'PDFReports_DisplayFormat_TablesOnly' => 'Display Tables only (no graphs)', 'PDFReports_SentToMe' => 'Send to me', + 'PDFReports_EvolutionGraph' => 'Show Historical Graphs for the top 5 values', 'PDFReports_CreateAndScheduleReport' => 'Create and Schedule a report', 'PDFReports_CancelAndReturnToReports' => 'Cancel and %sreturn to the list of reports%s', 'PDFReports_DescriptionOnFirstPage' => 'The report description will be displayed on the first page of the report.', diff --git a/plugins/API/API.php b/plugins/API/API.php index 2921bbb19914c118d7a455a050bc643fbc3d9383..2f5a335c4646d310ef57bb7cd2f4d5885f60a632 100644 --- a/plugins/API/API.php +++ b/plugins/API/API.php @@ -1117,24 +1117,47 @@ class Piwik_API_API * * @return array */ - public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label, $segment = false, $column = false, $language = false) + public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $column = false, $language = false, $idGoal = false) { // this is needed because Piwik_API_Proxy uses Piwik_Common::getRequestVar which in turn // uses Piwik_Common::sanitizeInputValue. This causes the > that separates recursive labels // to become > and we need to undo that here. $label = Piwik_Common::unsanitizeInputValue($label); - - $labels = explode(',', $label); - $labels = array_map('urldecode', $labels); - $labels = array_unique($labels); - + + if($label) + { + $labels = explode(',', $label); + $labels = array_map('urldecode', $labels); + $labels = array_unique($labels); + } + else + { + // retrieve top labels + $dataTableArray = $this->loadRowEvolutionDataFromAPI( + $idSite, + $period, + $date, + $apiModule, + $apiAction, + null, + $segment, + $idGoal + ); + + // get the last, ie. most recent, datatable + $dataTables = $dataTableArray->getArray(); + $mostRecentDataTable = end($dataTables); + + $labels = $mostRecentDataTable->getColumn('label'); + } + if (count($labels) > 1) { - $data = $this->getMultiRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $column, $language); + $data = $this->getMultiRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $column, $language, $idGoal); } else { - $data = $this->getSingleRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels[0], $segment, $language); + $data = $this->getSingleRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels[0], $segment, $language, $idGoal); } return $data; } @@ -1143,12 +1166,12 @@ class Piwik_API_API * Get row evolution for a single label * @return array containing report data, metadata, label, logo */ - private function getSingleRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label, $segment, $language=false) + private function getSingleRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label, $segment, $language=false, $idGoal = false) { - $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language); + $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal); $metricNames = array_keys($metadata['metrics']); - $dataTable = $this->loadRowEvolutionDataFromAPI($idSite, $period, $date, $apiModule, $apiAction, $label, $segment); + $dataTable = $this->loadRowEvolutionDataFromAPI($idSite, $period, $date, $apiModule, $apiAction, $label, $segment, $idGoal); $logo = $actualLabel = false; $urlFound = false; @@ -1219,10 +1242,11 @@ class Piwik_API_API * @param $apiAction * @param $label * @param $segment + * @param $idGoal * @throws Exception * @return Piwik_DataTable_Array */ - private function loadRowEvolutionDataFromAPI($idSite, $period, $date, $apiModule, $apiAction, $label, $segment) + private function loadRowEvolutionDataFromAPI($idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $idGoal = false) { if ($period == 'range') { @@ -1239,10 +1263,11 @@ class Piwik_API_API 'format' => 'original', 'serialize' => '0', 'segment' => $segment, + 'idGoal' => $idGoal ); // add "processed metrics" like actions per visit or bounce rate - if ($apiModule != 'Actions') + if ($apiModule != 'Actions' && $label) { $parameters['filter_add_columns_when_show_all_columns'] = '1'; } @@ -1274,12 +1299,17 @@ class Piwik_API_API * @param $apiModule * @param $apiAction * @param $language + * @param $idGoal * @throws Exception * @return array */ - private function getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language) + private function getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal = false) { - $reportMetadata = $this->getMetadata($idSite, $apiModule, $apiAction, $apiParameters = false, $language, $period, $date); + $apiParameters = array(); + if(!empty($idGoal)) { + $apiParameters = array( 'idGoal' => $idGoal); + } + $reportMetadata = $this->getMetadata($idSite, $apiModule, $apiAction, $apiParameters, $language, $period, $date); if (empty($reportMetadata)) { @@ -1384,11 +1414,11 @@ class Piwik_API_API } /** Get row evolution for a multiple labels */ - private function getMultiRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $column, $language=false) + private function getMultiRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $column, $language=false, $idGoal=false) { $actualLabels = $logos = array(); - $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language); + $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal); if (!isset($metadata['metrics'][$column])) { @@ -1402,7 +1432,7 @@ class Piwik_API_API $dataTableMetadata = false; foreach ($labels as $labelIndex => $label) { - $dataTable = $this->loadRowEvolutionDataFromAPI($idSite, $period, $date, $apiModule, $apiAction, $label, $segment); + $dataTable = $this->loadRowEvolutionDataFromAPI($idSite, $period, $date, $apiModule, $apiAction, $label, $segment, $idGoal); $dataTablesPerLabel[$labelIndex] = $dataTable->getArray(); if (!$dataTableMetadata) diff --git a/plugins/Goals/Goals.php b/plugins/Goals/Goals.php index 40dc474a8264e9610fb42977b155951bd154feb1..c70e3010e3946f36a4c36316205b35c02678e233 100644 --- a/plugins/Goals/Goals.php +++ b/plugins/Goals/Goals.php @@ -159,6 +159,7 @@ class Piwik_Goals extends Piwik_Plugin 'module' => 'Goals', 'action' => 'getVisitsUntilConversion', 'dimension' => Piwik_Translate('Goals_VisitsUntilConv'), + 'constantRowsCount' => true, 'parameters' => array(), 'metrics' => $conversionReportMetrics, 'order' => 5 @@ -171,6 +172,7 @@ class Piwik_Goals extends Piwik_Plugin 'module' => 'Goals', 'action' => 'getDaysToConversion', 'dimension' => Piwik_Translate('Goals_DaysToConv'), + 'constantRowsCount' => true, 'parameters' => array(), 'metrics' => $conversionReportMetrics, 'order' => 10 @@ -199,6 +201,7 @@ class Piwik_Goals extends Piwik_Plugin 'module' => 'Goals', 'action' => 'getVisitsUntilConversion', 'dimension' => Piwik_Translate('Goals_VisitsUntilConv'), + 'constantRowsCount' => true, 'parameters' => array('idGoal' => $goal['idgoal']), 'metrics' => $conversionReportMetrics, 'order' => 51 + $goal['idgoal'] * 3 @@ -211,6 +214,7 @@ class Piwik_Goals extends Piwik_Plugin 'module' => 'Goals', 'action' => 'getDaysToConversion', 'dimension' => Piwik_Translate('Goals_DaysToConv'), + 'constantRowsCount' => true, 'parameters' => array('idGoal' => $goal['idgoal']), 'metrics' => $conversionReportMetrics, 'order' => 52 + $goal['idgoal'] * 3 @@ -248,6 +252,7 @@ class Piwik_Goals extends Piwik_Plugin 'module' => 'Goals', 'action' => 'getVisitsUntilConversion', 'dimension' => Piwik_Translate('Goals_VisitsUntilConv'), + 'constantRowsCount' => true, 'metrics' => $conversionReportMetrics, 'parameters' => array('idGoal' => Piwik_Archive::LABEL_ECOMMERCE_ORDER), 'order' => 11 @@ -258,6 +263,7 @@ class Piwik_Goals extends Piwik_Plugin 'module' => 'Goals', 'action' => 'getDaysToConversion', 'dimension' => Piwik_Translate('Goals_DaysToConv'), + 'constantRowsCount' => true, 'metrics' => $conversionReportMetrics, 'parameters' => array('idGoal' => Piwik_Archive::LABEL_ECOMMERCE_ORDER), 'order' => 12 @@ -288,6 +294,7 @@ class Piwik_Goals extends Piwik_Plugin 'module' => 'Goals', 'action' => 'getVisitsUntilConversion', 'dimension' => Piwik_Translate('Goals_VisitsUntilConv'), + 'constantRowsCount' => true, 'metrics' => $conversionReportMetrics, 'parameters' => array('idGoal' => Piwik_Archive::LABEL_ECOMMERCE_CART), 'order' => 20 @@ -298,6 +305,7 @@ class Piwik_Goals extends Piwik_Plugin 'module' => 'Goals', 'action' => 'getDaysToConversion', 'dimension' => Piwik_Translate('Goals_DaysToConv'), + 'constantRowsCount' => true, 'metrics' => $conversionReportMetrics, 'parameters' => array('idGoal' => Piwik_Archive::LABEL_ECOMMERCE_CART), 'order' => 25 diff --git a/plugins/ImageGraph/API.php b/plugins/ImageGraph/API.php index 8f337ec2e89436f0e4035b3728993f46a54a1dfe..96dec92eb8345e326a00c88c6744213486268e88 100644 --- a/plugins/ImageGraph/API.php +++ b/plugins/ImageGraph/API.php @@ -66,7 +66,14 @@ class Piwik_ImageGraph_API ); static private $DEFAULT_GRAPH_TYPE_OVERRIDE = array( - 'UserSettings_getPlugin' => Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_HORIZONTAL_BAR, + 'UserSettings_getPlugin' => array( + false // override if !$isMultiplePeriod + => Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_HORIZONTAL_BAR, + ), + 'Referers_getRefererType' => array( + false // override if !$isMultiplePeriod + => Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_HORIZONTAL_BAR, + ), ); const GRAPH_OUTPUT_INLINE = 0; @@ -79,6 +86,10 @@ class Piwik_ImageGraph_API const UNICODE_FONT = 'unifont.ttf'; const DEFAULT_FONT_SIZE = 9; + // number of row evolutions to plot when no labels are specified, can be overridden using &filter_limit + const DEFAULT_NB_ROW_EVOLUTIONS = 5; + const MAX_NB_ROW_LABELS = 10; + static private $instance = null; /** @@ -95,7 +106,7 @@ class Piwik_ImageGraph_API } public function get($idSite, $period, $date, $apiModule, $apiAction, $graphType = false, - $outputType = Piwik_ImageGraph_API::GRAPH_OUTPUT_INLINE, $column = false, $showMetricTitle = true, + $outputType = Piwik_ImageGraph_API::GRAPH_OUTPUT_INLINE, $columns = false, $labels = false, $showLegend = true, $width = false, $height = false, $fontSize = Piwik_ImageGraph_API::DEFAULT_FONT_SIZE, $aliasedGraph = true, $idGoal = false, $colors = false, $idSubtable = false) { @@ -141,14 +152,18 @@ class Piwik_ImageGraph_API $constantRowsCount = !empty($metadata['constantRowsCount']); $isMultiplePeriod = Piwik_Archive::isMultiplePeriod($date, $period); - if(($reportHasDimension && $isMultiplePeriod) || (!$reportHasDimension && !$isMultiplePeriod)) + if(!$reportHasDimension && !$isMultiplePeriod) { throw new Exception('The graph cannot be drawn for this combination of \'date\' and \'period\' parameters.'); } if(empty($graphType)) { - if($reportHasDimension) + if($isMultiplePeriod) + { + $graphType = Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_BASIC_LINE; + } + else { if($constantRowsCount) { @@ -159,15 +174,11 @@ class Piwik_ImageGraph_API $graphType = Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_HORIZONTAL_BAR; } } - else - { - $graphType = Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_BASIC_LINE; - } $reportUniqueId = $metadata['uniqueId']; - if(isset(self::$DEFAULT_GRAPH_TYPE_OVERRIDE[$reportUniqueId])) + if(isset(self::$DEFAULT_GRAPH_TYPE_OVERRIDE[$reportUniqueId][$isMultiplePeriod])) { - $graphType = self::$DEFAULT_GRAPH_TYPE_OVERRIDE[$reportUniqueId]; + $graphType = self::$DEFAULT_GRAPH_TYPE_OVERRIDE[$reportUniqueId][$isMultiplePeriod]; } } else @@ -194,20 +205,11 @@ class Piwik_ImageGraph_API { $height = self::$DEFAULT_PARAMETERS[$graphType][self::HEIGHT_KEY]; } + // Cap width and height to a safe amount $width = min($width, self::MAX_WIDTH); $height = min($height, self::MAX_HEIGHT); - if($reportHasDimension) - { - $abscissaColumn = 'label'; - } - else - { - // if it's a dimension-less report, the abscissa column can only be the date-index - $abscissaColumn = 'date'; - } - $reportColumns = array_merge( !empty($metadata['metrics']) ? $metadata['metrics'] : array(), !empty($metadata['processedMetrics']) ? $metadata['processedMetrics'] : array(), @@ -215,27 +217,30 @@ class Piwik_ImageGraph_API !empty($metadata['processedMetricsGoal']) ? $metadata['processedMetricsGoal'] : array() ); - $ordinateColumn = $column; - if(empty($ordinateColumn)) + $ordinateColumns = array(); + if(empty($columns)) { - $ordinateColumn = self::DEFAULT_ORDINATE_METRIC; - - // if default ordinate metric not available for this report - if(empty($reportColumns[$ordinateColumn])) + $ordinateColumns[] = + empty($reportColumns[self::DEFAULT_ORDINATE_METRIC]) ? key($metadata['metrics']) : self::DEFAULT_ORDINATE_METRIC; + } + else + { + $ordinateColumns = explode(',', $columns); + foreach($ordinateColumns as $column) { - // take the first metric returned in the metadata - $ordinateColumn = key($metadata['metrics']); + if(empty($reportColumns[$column])) + { + throw new Exception(Piwik_Translate('ImageGraph_ColumnOrdinateMissing', $column)); + } } } - - // if we still don't have an ordinate column or the one provided by the API caller is invalid - if(empty($ordinateColumn) || empty($reportColumns[$ordinateColumn])) + + $ordinateLabels = array(); + foreach($ordinateColumns as $column) { - throw new Exception(Piwik_Translate('ImageGraph_ColumnOrdinateMissing', $ordinateColumn)); + $ordinateLabels[$column] = $reportColumns[$column]; } - $ordinateLabel = $reportColumns[$ordinateColumn]; - // sort and truncate filters $defaultFilterTruncate = self::$DEFAULT_PARAMETERS[$graphType][self::TRUNCATE_KEY]; switch($graphType) @@ -243,43 +248,116 @@ class Piwik_ImageGraph_API case Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_3D_PIE: case Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_BASIC_PIE: - $_GET['filter_sort_column'] = $ordinateColumn; + if(count($ordinateColumns) > 1) + { + // pChart doesn't support multiple series on pie charts + throw new Exception("Pie charts do not currently support multiple series"); + } + + $_GET['filter_sort_column'] = reset($ordinateColumns); $this->setFilterTruncate($defaultFilterTruncate); break; case Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_VERTICAL_BAR: case Piwik_ImageGraph_StaticGraph::GRAPH_TYPE_BASIC_LINE: - if($reportHasDimension && !$constantRowsCount) + if(!$isMultiplePeriod && !$constantRowsCount) { $this->setFilterTruncate($defaultFilterTruncate); } break; } - $processedReport = Piwik_API_API::getInstance()->getProcessedReport( - $idSite, - $period, - $date, - $apiModule, - $apiAction, - $segment = false, - $apiParameters = false, - $idGoal, - $languageLoaded, - $showTimer = true, - $hideMetricsDoc = false, - $idSubtable - ); + // row evolutions + if($isMultiplePeriod && $reportHasDimension) + { + $plottedMetric = reset($ordinateColumns); + + // when no labels are specified, getRowEvolution returns the top N=filter_limit row evolutions + // rows are sorted using filter_sort_column (see Piwik_API_DataTableGenericFilter for more info) + if(!$labels) + { + $savedFilterSortColumnValue = Piwik_Common::getRequestVar('filter_sort_column', ''); + $_GET['filter_sort_column'] = $plottedMetric; + + $savedFilterLimitValue = Piwik_Common::getRequestVar('filter_limit', -1, 'int'); + if($savedFilterLimitValue == -1 || $savedFilterLimitValue > self::MAX_NB_ROW_LABELS) + { + $_GET['filter_limit'] = self::DEFAULT_NB_ROW_EVOLUTIONS; + } + } + + $processedReport = Piwik_API_API::getInstance()->getRowEvolution( + $idSite, + $period, + $date, + $apiModule, + $apiAction, + $labels, + $segment = false, + $plottedMetric, + $languageLoaded, + $idGoal, + $plottedMetric + ); + + // restoring generic filter parameters + if(!$labels) + { + $_GET['filter_sort_column'] = $savedFilterSortColumnValue; + if($savedFilterLimitValue != -1) + { + $_GET['filter_limit'] = $savedFilterLimitValue; + } + } + + // retrieve metric names & labels + $metrics = $processedReport['metadata']['metrics']; + $ordinateLabels = array(); + + // getRowEvolution returned more than one label + if(!array_key_exists($plottedMetric, $metrics)) + { + $ordinateColumns = array(); + $i = 0; + foreach($metrics as $metric => $info) + { + $ordinateColumn = $plottedMetric . '_' . $i++; + $ordinateColumns[] = $metric; + $ordinateLabels[$ordinateColumn] = $info['name']; + } + } + else + { + $ordinateLabels[$plottedMetric] = $processedReport['label'] . ' (' . $metrics[$plottedMetric]['name'] . ')'; + } + } + else + { + $processedReport = Piwik_API_API::getInstance()->getProcessedReport( + $idSite, + $period, + $date, + $apiModule, + $apiAction, + $segment = false, + $apiParameters = false, + $idGoal, + $languageLoaded, + $showTimer = true, + $hideMetricsDoc = false, + $idSubtable + ); + } // prepare abscissa and ordinate series - $abscissaSerie = array(); - $ordinateSerie = array(); + $abscissaSeries = array(); + $ordinateSeries = array(); $ordinateLogos = array(); $reportData = $processedReport['reportData']; $hasData = false; $hasNonZeroValue = false; - if($reportHasDimension) + if(!$isMultiplePeriod) { $reportMetadata = $processedReport['reportMetadata']->getRows(); @@ -289,17 +367,19 @@ class Piwik_ImageGraph_API { // $row instanceof Piwik_DataTable_Row $rowData = $row->getColumns(); // Associative Array - $abscissaSerie[] = Piwik_Common::unsanitizeInputValue($rowData[$abscissaColumn]); - $parsedOrdinateValue = $this->parseOrdinateValue($rowData[$ordinateColumn]); + $abscissaSeries[] = Piwik_Common::unsanitizeInputValue($rowData['label']); - $hasData = true; - - if($parsedOrdinateValue != 0) + foreach($ordinateColumns as $column) { - $hasNonZeroValue = true; - } + $parsedOrdinateValue = $this->parseOrdinateValue($rowData[$column]); + $hasData = true; - $ordinateSerie[] = $parsedOrdinateValue; + if($parsedOrdinateValue != 0) + { + $hasNonZeroValue = true; + } + $ordinateSeries[$column][] = $parsedOrdinateValue; + } if(isset($reportMetadata[$i])) { @@ -330,27 +410,36 @@ class Piwik_ImageGraph_API if(array_key_exists(0, $rows)) { $rowData = $rows[0]->getColumns(); // associative Array - $ordinateValue = $rowData[$ordinateColumn]; - $parsedOrdinateValue = $this->parseOrdinateValue($ordinateValue); - - $hasData = true; - if(!empty($parsedOrdinateValue)) + foreach($ordinateColumns as $column) { - $hasNonZeroValue = true; + $ordinateValue = $rowData[$column]; + $parsedOrdinateValue = $this->parseOrdinateValue($ordinateValue); + + $hasData = true; + + if(!empty($parsedOrdinateValue)) + { + $hasNonZeroValue = true; + } + + $ordinateSeries[$column][] = $parsedOrdinateValue; } + } else { - $parsedOrdinateValue = 0; + foreach($ordinateColumns as $column) + { + $ordinateSeries[$column][] = 0; + } } $rowId = $periodsMetadata[$i]['period']->getLocalizedShortString(); - - $abscissaSerie[] = Piwik_Common::unsanitizeInputValue($rowId); - $ordinateSerie[] = $parsedOrdinateValue; + $abscissaSeries[] = Piwik_Common::unsanitizeInputValue($rowId); } } + if(!$hasData || !$hasNonZeroValue) { throw new Exception(Piwik_Translate('General_NoDataForGraph')); @@ -362,11 +451,11 @@ class Piwik_ImageGraph_API $graph->setHeight($height); $graph->setFont($font); $graph->setFontSize($fontSize); - $graph->setMetricTitle($ordinateLabel); - $graph->setShowMetricTitle($showMetricTitle); + $graph->setOrdinateLabels($ordinateLabels); + $graph->setShowLegend($showLegend); $graph->setAliasedGraph($aliasedGraph); - $graph->setAbscissaSerie($abscissaSerie); - $graph->setOrdinateSerie($ordinateSerie); + $graph->setAbscissaSeries($abscissaSeries); + $graph->setOrdinateSeries($ordinateSeries); $graph->setOrdinateLogos($ordinateLogos); $graph->setColors(!empty($colors) ? explode(',', $colors) : array()); diff --git a/plugins/ImageGraph/ImageGraph.php b/plugins/ImageGraph/ImageGraph.php index c32325344a93232e12571d3c26e4aac2274b51a8..db0e79e8ca34af24c25868f9be448977cfd18f67 100644 --- a/plugins/ImageGraph/ImageGraph.php +++ b/plugins/ImageGraph/ImageGraph.php @@ -12,6 +12,9 @@ class Piwik_ImageGraph extends Piwik_Plugin { + static private $CONSTANT_ROW_COUNT_REPORT_EXCEPTIONS = array( + 'Referers_getRefererType', + ); public function getInformation() { @@ -101,12 +104,16 @@ class Piwik_ImageGraph extends Piwik_Plugin $urlPrefix = "index.php?"; foreach($reports as &$report) { + $reportModule = $report['module']; + $reportAction = $report['action']; + $reportUniqueId = $reportModule.'_'.$reportAction; + $parameters = array(); $parameters['module'] = 'API'; $parameters['method'] = 'ImageGraph.get'; $parameters['idSite'] = $idSite; - $parameters['apiModule'] = $report['module']; - $parameters['apiAction'] = $report['action']; + $parameters['apiModule'] = $reportModule; + $parameters['apiAction'] = $reportAction; if(!empty($token_auth)) { $parameters['token_auth'] = $token_auth; @@ -136,7 +143,16 @@ class Piwik_ImageGraph extends Piwik_Plugin } $report['imageGraphUrl'] = $urlPrefix . Piwik_Url::getQueryStringFromParameters($parameters); + + // thanks to API.getRowEvolution, reports with dimensions can now be plotted using an evolution graph + // however, most reports with a fixed set of dimension values are excluded + // this is done so Piwik Mobile and Scheduled Reports do not display them + if(empty($report['constantRowsCount']) || in_array($reportUniqueId,self::$CONSTANT_ROW_COUNT_REPORT_EXCEPTIONS)) + { + $parameters['period'] = $periodForMultiplePeriodGraph; + $parameters['date'] = $dateForMultiplePeriodGraph; + $report['imageGraphEvolutionUrl'] = $urlPrefix . Piwik_Url::getQueryStringFromParameters($parameters); + } } - } } diff --git a/plugins/ImageGraph/StaticGraph.php b/plugins/ImageGraph/StaticGraph.php index 084ccda5c0a4f809e3056368a7f454f8369ee071..2b7da10913f0f52523983dcba23f7cde79b64bfc 100644 --- a/plugins/ImageGraph/StaticGraph.php +++ b/plugins/ImageGraph/StaticGraph.php @@ -44,10 +44,10 @@ abstract class Piwik_ImageGraph_StaticGraph protected $pImage; protected $pData; - protected $metricTitle; - protected $showMetricTitle; - protected $abscissaSerie; - protected $ordinateSerie; + protected $ordinateLabels; + protected $showLegend; + protected $abscissaSeries; + protected $ordinateSeries; protected $ordinateLogos; protected $colors; protected $font; @@ -140,9 +140,9 @@ abstract class Piwik_ImageGraph_StaticGraph $this->font = $font; } - public function setOrdinateSerie($ordinateSerie) + public function setOrdinateSeries($ordinateSeries) { - $this->ordinateSerie = $ordinateSerie; + $this->ordinateSeries = $ordinateSeries; } public function setOrdinateLogos($ordinateLogos) @@ -150,19 +150,19 @@ abstract class Piwik_ImageGraph_StaticGraph $this->ordinateLogos = $ordinateLogos; } - public function setAbscissaSerie($abscissaSerie) + public function setAbscissaSeries($abscissaSeries) { - $this->abscissaSerie = $abscissaSerie; + $this->abscissaSeries = $abscissaSeries; } - public function setShowMetricTitle($showMetricTitle) + public function setShowLegend($showLegend) { - $this->showMetricTitle = $showMetricTitle; + $this->showLegend = $showLegend; } - public function setMetricTitle($metricTitle) + public function setOrdinateLabels($ordinateLabels) { - $this->metricTitle = $metricTitle; + $this->ordinateLabels = $ordinateLabels; } public function setAliasedGraph($aliasedGraph) @@ -208,10 +208,13 @@ abstract class Piwik_ImageGraph_StaticGraph { $this->pData = new pData(); - $this->pData->addPoints($this->ordinateSerie, $this->metricTitle); - $this->pData->setAxisName(0, '', $this->metricTitle); + foreach($this->ordinateSeries as $column => $data) + { + $this->pData->addPoints($data, $column); + $this->pData->setSerieDescription($column,$this->ordinateLabels[$column]); + } - $this->pData->addPoints($this->abscissaSerie, self::ABSCISSA_SERIE_NAME); + $this->pData->addPoints($this->abscissaSeries, self::ABSCISSA_SERIE_NAME); $this->pData->setAbscissa(self::ABSCISSA_SERIE_NAME); } @@ -240,22 +243,30 @@ abstract class Piwik_ImageGraph_StaticGraph protected function maxWidthHeight($values) { + if(array_values($values) === $values) + { + $values = array('' => $values); + } + $maxWidth = 0; $maxHeight = 0; - foreach($values as $value) + foreach($values as $column => $data) { - $valueWidthHeight = $this->getTextWidthHeight($value); - $valueWidth= $valueWidthHeight[self::WIDTH_KEY]; - $valueHeight= $valueWidthHeight[self::HEIGHT_KEY]; - - if($valueWidth > $maxWidth) - { - $maxWidth = $valueWidth; - } - - if($valueHeight > $maxHeight) + foreach($data as $value) { - $maxHeight = $valueHeight; + $valueWidthHeight = $this->getTextWidthHeight($value); + $valueWidth= $valueWidthHeight[self::WIDTH_KEY]; + $valueHeight= $valueWidthHeight[self::HEIGHT_KEY]; + + if($valueWidth > $maxWidth) + { + $maxWidth = $valueWidth; + } + + if($valueHeight > $maxHeight) + { + $maxHeight = $valueHeight; + } } } diff --git a/plugins/ImageGraph/StaticGraph/GridGraph.php b/plugins/ImageGraph/StaticGraph/GridGraph.php index 118e1c9288d593bfbdd2f705a0635d9281b030f4..9a4658def6bfd9306d98ceda59f2009ad2993d69 100644 --- a/plugins/ImageGraph/StaticGraph/GridGraph.php +++ b/plugins/ImageGraph/StaticGraph/GridGraph.php @@ -18,11 +18,8 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_StaticGraph { const GRAPHIC_COLOR_KEY = 'GRAPHIC_COLOR'; - const DEFAULT_GRAPHIC_COLOR = '5170AE'; const VALUE_COLOR_KEY = 'VALUE_COLOR'; - const DEFAULT_VALUE_COLOR = '444444'; const GRID_COLOR_KEY = 'GRID_COLOR'; - const DEFAULT_GRID_COLOR = 'CCCCCC'; const DEFAULT_TICK_ALPHA = 20; const DEFAULT_SERIE_WEIGHT = 0.5; @@ -39,9 +36,14 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_S protected function getDefaultColors() { return array( - self::GRAPHIC_COLOR_KEY => self::DEFAULT_GRAPHIC_COLOR, - self::VALUE_COLOR_KEY => self::DEFAULT_VALUE_COLOR, - self::GRID_COLOR_KEY => self::DEFAULT_GRID_COLOR, + self::VALUE_COLOR_KEY => '444444', + self::GRID_COLOR_KEY => 'CCCCCC', + self::GRAPHIC_COLOR_KEY . '1' => '5170AE', + self::GRAPHIC_COLOR_KEY . '2' => 'F29007', + self::GRAPHIC_COLOR_KEY . '3' => 'CC3399', + self::GRAPHIC_COLOR_KEY . '4' => '9933CC', + self::GRAPHIC_COLOR_KEY . '5' => '80A033', + self::GRAPHIC_COLOR_KEY . '6' => '246AD2' ); } @@ -54,9 +56,13 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_S { $this->initpData(); - $this->pData->setSerieWeight($this->metricTitle, self::DEFAULT_SERIE_WEIGHT); - $graphicColor = $this->colors[self::GRAPHIC_COLOR_KEY]; - $this->pData->setPalette($this->metricTitle, $graphicColor); + $colorIndex = 1; + foreach($this->ordinateSeries as $column => $data) + { + $this->pData->setSerieWeight($column, self::DEFAULT_SERIE_WEIGHT); + $graphicColor = $this->colors[self::GRAPHIC_COLOR_KEY . $colorIndex++]; + $this->pData->setPalette($column, $graphicColor); + } $this->initpImage(); @@ -77,17 +83,17 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_S $skippedLabels = 0; if(!$horizontalGraph) { - $abscissaMaxWidthHeight = $this->maxWidthHeight($this->abscissaSerie); + $abscissaMaxWidthHeight = $this->maxWidthHeight($this->abscissaSeries); $abscissaMaxWidth = $abscissaMaxWidthHeight[self::WIDTH_KEY]; $graphWidth = $bottomRightXValue - $topLeftXValue; $maxNumOfLabels = floor($graphWidth / ($abscissaMaxWidth + self::LABEL_SPACE_VERTICAL_GRAPH)); - $abscissaSerieCount = count($this->abscissaSerie); - if($maxNumOfLabels < $abscissaSerieCount) + $abscissaSeriesCount = count($this->abscissaSeries); + if($maxNumOfLabels < $abscissaSeriesCount) { - for($candidateSkippedLabels = 1 ; $candidateSkippedLabels < $abscissaSerieCount; $candidateSkippedLabels++) + for($candidateSkippedLabels = 1 ; $candidateSkippedLabels < $abscissaSeriesCount; $candidateSkippedLabels++) { - $numberOfSegments = $abscissaSerieCount / ($candidateSkippedLabels + 1); + $numberOfSegments = $abscissaSeriesCount / ($candidateSkippedLabels + 1); $numberOfCompleteSegments = floor($numberOfSegments); $numberOfLabels = $numberOfCompleteSegments; @@ -105,9 +111,19 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_S } } - $ordinateAxisLength = $horizontalGraph ? $bottomRightXValue - $topLeftXValue : $this->getGraphHeight($horizontalGraph); + $ordinateAxisLength = + $horizontalGraph ? $bottomRightXValue - $topLeftXValue : $this->getGraphHeight($horizontalGraph); + + $maxOrdinateValue = 0; + foreach($this->ordinateSeries as $column => $data) + { + $currentMax = $this->pData->getMax($column); - $maxOrdinateValue = $this->pData->getMax($this->metricTitle); + if($currentMax > $maxOrdinateValue) + { + $maxOrdinateValue = $currentMax; + } + } $gridColor = $this->colors[self::GRID_COLOR_KEY]; @@ -138,16 +154,18 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_S ) ); - if($this->showMetricTitle) + if($this->showLegend) { + $legendColor = $this->colors[self::VALUE_COLOR_KEY]; $this->pImage->drawLegend( $topLeftXValue + self::LEGEND_LEFT_MARGIN, - $this->getMetricTitleHeight() / 2, + $this->getLegendHeight() / 2, array( 'Style' => LEGEND_NOBORDER, - 'FontR' => $graphicColor['R'], - 'FontG' => $graphicColor['G'], - 'FontB' => $graphicColor['B'], + 'Mode' => LEGEND_HORIZONTAL, + 'FontR' => $legendColor['R'], + 'FontG' => $legendColor['G'], + 'FontB' => $legendColor['B'], ) ); } @@ -164,7 +182,7 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_S if($withLabel) { - $maxWidthHeight = $this->maxWidthHeight($horizontalGraph ? $this->abscissaSerie : $this->ordinateSerie); + $maxWidthHeight = $this->maxWidthHeight($horizontalGraph ? $this->abscissaSeries : $this->ordinateSeries); $gridLeftMargin += $maxWidthHeight[self::WIDTH_KEY]; } @@ -173,7 +191,7 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_S protected function getGridTopMargin($horizontalGraph) { - $ordinateMaxWidthHeight = $this->maxWidthHeight($this->ordinateSerie); + $ordinateMaxWidthHeight = $this->maxWidthHeight($this->ordinateSeries); $ordinateMaxHeight = $ordinateMaxWidthHeight[self::HEIGHT_KEY]; if($horizontalGraph) @@ -185,18 +203,28 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_S $topMargin = $ordinateMaxHeight / 2; } - if($this->showMetricTitle) + if($this->showLegend) { - $topMargin += $this->getMetricTitleHeight() + self::LEGEND_BOTTOM_MARGIN; + $topMargin += $this->getLegendHeight() + self::LEGEND_BOTTOM_MARGIN; } return $topMargin; } - private function getMetricTitleHeight() + private function getLegendHeight() { - $metricTitleWidthHeight = $this->getTextWidthHeight($this->metricTitle); - return $metricTitleWidthHeight[self::HEIGHT_KEY]; + $maxMetricLegendHeight = 0; + foreach($this->ordinateLabels as $column => $label) + { + $metricTitleWidthHeight = $this->getTextWidthHeight($label); + $metricTitleHeight = $metricTitleWidthHeight[self::HEIGHT_KEY]; + if($metricTitleHeight > $maxMetricLegendHeight) + { + $maxMetricLegendHeight = $metricTitleHeight; + } + } + + return $maxMetricLegendHeight; } protected function getGraphHeight($horizontalGraph) @@ -206,7 +234,7 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_S private function getGridBottomMargin() { - $abscissaMaxWidthHeight = $this->maxWidthHeight($this->abscissaSerie); + $abscissaMaxWidthHeight = $this->maxWidthHeight($this->abscissaSeries); return $abscissaMaxWidthHeight[self::HEIGHT_KEY] + self::BOTTOM_GRID_MARGIN; } @@ -214,7 +242,7 @@ abstract class Piwik_ImageGraph_StaticGraph_GridGraph extends Piwik_ImageGraph_S { if($horizontalGraph) { - $ordinateMaxWidthHeight = $this->maxWidthHeight($this->ordinateSerie); + $ordinateMaxWidthHeight = $this->maxWidthHeight($this->ordinateSeries); return self::RIGHT_GRID_MARGIN_HORIZONTAL_GRAPH + $ordinateMaxWidthHeight[self::WIDTH_KEY]; } else diff --git a/plugins/ImageGraph/StaticGraph/HorizontalBar.php b/plugins/ImageGraph/StaticGraph/HorizontalBar.php index 13ca962b25a801f4f5ae8addf610f803cc5d6c08..e9acf68b0dde7680ae8371a929962261ae5b40f1 100644 --- a/plugins/ImageGraph/StaticGraph/HorizontalBar.php +++ b/plugins/ImageGraph/StaticGraph/HorizontalBar.php @@ -54,36 +54,61 @@ class Piwik_ImageGraph_StaticGraph_HorizontalBar extends Piwik_ImageGraph_Static // truncate report $graphHeight = $this->getGraphBottom() - $this->getGridTopMargin($horizontalGraph = true); - $abscissaMaxWidthHeight = $this->maxWidthHeight($this->abscissaSerie); + + $abscissaMaxWidthHeight = $this->maxWidthHeight($this->abscissaSeries); $abscissaMaxHeight = $abscissaMaxWidthHeight[self::HEIGHT_KEY]; - $minLineWidth = ($abscissaMaxHeight > $maxLogoHeight ? $abscissaMaxHeight : $maxLogoHeight) + self::MIN_SPACE_BETWEEN_HORIZONTAL_VALUES; + + $ordinateMaxWidthHeight = $this->maxWidthHeight($this->ordinateSeries); + $numberOfSeries = count($this->ordinateSeries); + $ordinateMaxHeight = $ordinateMaxWidthHeight[self::HEIGHT_KEY] * $numberOfSeries; + + $textMaxHeight = $abscissaMaxHeight > $ordinateMaxHeight ? $abscissaMaxHeight : $ordinateMaxHeight; + + $minLineWidth = ($textMaxHeight > $maxLogoHeight ? $textMaxHeight : $maxLogoHeight) + (self::MIN_SPACE_BETWEEN_HORIZONTAL_VALUES * $numberOfSeries); $maxNumOfValues = floor($graphHeight / $minLineWidth); - $abscissaSerieCount = count($this->abscissaSerie); - - if($maxNumOfValues < $abscissaSerieCount - 1) + $abscissaSeriesCount = count($this->abscissaSeries); + + if($maxNumOfValues < $abscissaSeriesCount - 1) { - $truncatedOrdinateSerie = array(); + $sumOfOthers = array(); + $truncatedOrdinateSeries = array(); $truncatedOrdinateLogos = array(); - $truncatedAbscissaSerie = array(); + $truncatedAbscissaSeries = array(); + foreach($this->ordinateSeries as $column => $data) + { + $truncatedOrdinateSeries[$column] = array(); + $sumOfOthers[$column] = 0; + } $i = 0; for(; $i < $maxNumOfValues; $i++) { - $truncatedOrdinateSerie[] = $this->ordinateSerie[$i]; + foreach($this->ordinateSeries as $column => $data) + { + $truncatedOrdinateSeries[$column][] = $data[$i]; + } + $truncatedOrdinateLogos[] = isset($this->ordinateLogos[$i]) ? $this->ordinateLogos[$i] : null; - $truncatedAbscissaSerie[] = $this->abscissaSerie[$i]; + $truncatedAbscissaSeries[] = $this->abscissaSeries[$i]; + } + + for(; $i < $abscissaSeriesCount; $i++) + { + foreach($this->ordinateSeries as $column => $data) + { + $sumOfOthers[$column] += $data[$i]; + } } - $sumOfOthers = 0; - for(; $i < $abscissaSerieCount; $i++) + foreach($this->ordinateSeries as $column => $data) { - $sumOfOthers += $this->ordinateSerie[$i]; + $truncatedOrdinateSeries[$column][] = $sumOfOthers[$column]; } - $truncatedOrdinateSerie[] = $sumOfOthers; - $truncatedAbscissaSerie[] = Piwik_Translate('General_Others'); - $this->ordinateSerie = $truncatedOrdinateSerie; + + $truncatedAbscissaSeries[] = Piwik_Translate('General_Others'); + $this->abscissaSeries = $truncatedAbscissaSeries; + $this->ordinateSeries = $truncatedOrdinateSeries; $this->ordinateLogos = $truncatedOrdinateLogos; - $this->abscissaSerie = $truncatedAbscissaSerie; } // blank characters are used to pad labels so the logo can be displayed @@ -103,9 +128,16 @@ class Piwik_ImageGraph_StaticGraph_HorizontalBar extends Piwik_ImageGraph_Static $gridRightMargin = $this->getGridRightMargin($horizontalGraph = true); $minGraphSize = ($this->width - $gridRightMargin) / 2; - $metricTitleWidthHeight = $this->getTextWidthHeight($this->metricTitle); - $legendWidth = $metricTitleWidthHeight[self::WIDTH_KEY] + self::LEGEND_LEFT_MARGIN + self::LEGEND_SQUARE_WIDTH; - if($this->showMetricTitle) + + $metricLegendWidth = 0; + foreach($this->ordinateLabels as $column => $label) + { + $metricTitleWidthHeight = $this->getTextWidthHeight($label); + $metricLegendWidth += $metricTitleWidthHeight[self::WIDTH_KEY]; + } + + $legendWidth = $metricLegendWidth + ((self::LEGEND_LEFT_MARGIN + self::LEGEND_SQUARE_WIDTH) * $numberOfSeries); + if($this->showLegend) { if($legendWidth > $minGraphSize) { @@ -124,7 +156,7 @@ class Piwik_ImageGraph_StaticGraph_HorizontalBar extends Piwik_ImageGraph_Static // truncate labels if needed $truncationTextWidthHeight = $this->getTextWidthHeight(self::TRUNCATION_TEXT); $truncationTextWidth = $truncationTextWidthHeight[self::WIDTH_KEY]; - foreach($this->abscissaSerie as &$label) + foreach($this->abscissaSeries as &$label) { $labelWidthHeight = $this->getTextWidthHeight($label); $labelWidth = $labelWidthHeight[self::WIDTH_KEY]; @@ -139,7 +171,7 @@ class Piwik_ImageGraph_StaticGraph_HorizontalBar extends Piwik_ImageGraph_Static $gridLeftMarginBeforePadding = $this->getGridLeftMargin($horizontalGraph = true, $withLabel = true); // pad labels for logo space - foreach($this->abscissaSerie as &$label) + foreach($this->abscissaSeries as &$label) { $label .= $paddingText; } @@ -162,33 +194,32 @@ class Piwik_ImageGraph_StaticGraph_HorizontalBar extends Piwik_ImageGraph_Static ) ); - // display icons +// // display icons $graphData = $this->pData->getData(); - $sizeOfOrdinateSerie = sizeof($this->ordinateSerie); - $logoInterleave = $this->getGraphHeight(true) / $sizeOfOrdinateSerie; - for($i = 0; $i < $sizeOfOrdinateSerie; $i++) + $numberOfRows = count($this->abscissaSeries); + $logoInterleave = $this->getGraphHeight(true) / $numberOfRows; + for($i = 0; $i < $numberOfRows; $i++) { if(isset($this->ordinateLogos[$i])) { $logoPath = $this->ordinateLogos[$i]; $absoluteLogoPath = self::getAbsoluteLogoPath($logoPath); - - + if(isset($logoPathToSizes[$absoluteLogoPath])) { $logoWidthHeight = $logoPathToSizes[$absoluteLogoPath]; - + $pathInfo = pathinfo($logoPath); $logoExtension = strtoupper($pathInfo['extension']); $drawingFunction = 'drawFrom' . $logoExtension; - + $logoYPosition = ($logoInterleave * $i) + $this->getGridTopMargin(true) + $graphData['Axis'][1]['Margin'] - $logoWidthHeight[self::HEIGHT_KEY] / 2 + 1; - + $this->pImage->$drawingFunction( $gridLeftMarginBeforePadding, $logoYPosition, diff --git a/plugins/ImageGraph/StaticGraph/PieGraph.php b/plugins/ImageGraph/StaticGraph/PieGraph.php index e9b4a6855b5163ebc72770b2dcd7958bb085e08d..07e0f75ae961a16fe2c3d72868c37bf823011178 100644 --- a/plugins/ImageGraph/StaticGraph/PieGraph.php +++ b/plugins/ImageGraph/StaticGraph/PieGraph.php @@ -22,23 +22,23 @@ abstract class Piwik_ImageGraph_StaticGraph_PieGraph extends Piwik_ImageGraph_St const PIE_RIGHT_MARGIN = 20; const SECTOR_GAP = 2.5; + const SLICE_COLOR_KEY = "SLICE_COLOR"; + protected $pieChart; protected $xPosition; protected $yPosition; protected $pieConfig; - static private $DEFAULT_SLICE_COLORS = array( - 'SLICE_1' => '3C5A69', - 'SLICE_2' => '679BB5', - 'SLICE_3' => '695A3C', - 'SLICE_4' => 'B58E67', - 'SLICE_5' => '8AA68A', - 'SLICE_6' => 'A4D2A6' - ); - protected function getDefaultColors() { - return self::$DEFAULT_SLICE_COLORS; + return array( + self::SLICE_COLOR_KEY . '1' => '3C5A69', + self::SLICE_COLOR_KEY . '2' => '679BB5', + self::SLICE_COLOR_KEY . '3' => '695A3C', + self::SLICE_COLOR_KEY . '4' => 'B58E67', + self::SLICE_COLOR_KEY . '5' => '8AA68A', + self::SLICE_COLOR_KEY . '6' => 'A4D2A6', + ); } protected function initPieGraph($showLegend) @@ -58,15 +58,15 @@ abstract class Piwik_ImageGraph_StaticGraph_PieGraph extends Piwik_ImageGraph_St $this->pieChart = new pPie($this->pImage, $this->pData); - $i = 0; - foreach($this->colors as $color) + $numberOfSlices = count($this->abscissaSeries); + $numberOfAvailableColors = count($this->colors); + for($i = 0; $i < $numberOfSlices; $i++) { - $this->pieChart->setSliceColor($i, $color); - $i++; + $this->pieChart->setSliceColor($i, $this->colors[self::SLICE_COLOR_KEY . (($i % $numberOfAvailableColors) + 1)]); } // max abscissa label width is used to set the pie right margin - $abscissaMaxWidthHeight = $this->maxWidthHeight($this->abscissaSerie); + $abscissaMaxWidthHeight = $this->maxWidthHeight($this->abscissaSeries); $maxAbscissaLabelWidth = $abscissaMaxWidthHeight[self::WIDTH_KEY]; $this->xPosition = $this->width - $radius - $maxAbscissaLabelWidth - self::PIE_RIGHT_MARGIN; @@ -95,23 +95,27 @@ abstract class Piwik_ImageGraph_StaticGraph_PieGraph extends Piwik_ImageGraph_St */ private function truncateSmallValues() { + $metricColumns = array_keys($this->ordinateSeries); + $metricColumn = $metricColumns[0]; + $ordinateValuesSum = 0; - foreach($this->ordinateSerie as $ordinateValue) + foreach($this->ordinateSeries[$metricColumn] as $ordinateValue) { $ordinateValuesSum += $ordinateValue; } - $ordinateValuesCount = count($this->ordinateSerie); - $truncatedOrdinateSerie = array(); - $truncatedAbscissaSerie = array(); + $truncatedOrdinateSeries[$metricColumn] = array(); + $truncatedAbscissaSeries = array(); $smallValuesSum = 0; + + $ordinateValuesCount = count($this->ordinateSeries[$metricColumn]); for($i = 0; $i < $ordinateValuesCount - 1 ; $i++) { - $ordinateValue = $this->ordinateSerie[$i]; + $ordinateValue = $this->ordinateSeries[$metricColumn][$i]; if($ordinateValue / $ordinateValuesSum > 0.01) { - $truncatedOrdinateSerie[] = $ordinateValue; - $truncatedAbscissaSerie[] = $this->abscissaSerie[$i]; + $truncatedOrdinateSeries[$metricColumn][] = $ordinateValue; + $truncatedAbscissaSeries[] = $this->abscissaSeries[$i]; } else { @@ -119,14 +123,14 @@ abstract class Piwik_ImageGraph_StaticGraph_PieGraph extends Piwik_ImageGraph_St } } - $smallValuesSum += $this->ordinateSerie[$ordinateValuesCount - 1]; + $smallValuesSum += $this->ordinateSeries[$metricColumn][$ordinateValuesCount - 1]; if(($smallValuesSum / $ordinateValuesSum) > 0.01) { - $truncatedOrdinateSerie[] = $smallValuesSum; - $truncatedAbscissaSerie[] = $this->abscissaSerie[$ordinateValuesCount - 1]; + $truncatedOrdinateSeries[$metricColumn][] = $smallValuesSum; + $truncatedAbscissaSeries[] = Piwik_Translate('General_Others'); } - $this->ordinateSerie = $truncatedOrdinateSerie; - $this->abscissaSerie = $truncatedAbscissaSerie; + $this->ordinateSeries = $truncatedOrdinateSeries; + $this->abscissaSeries = $truncatedAbscissaSeries; } } diff --git a/plugins/PDFReports/API.php b/plugins/PDFReports/API.php index f5f366ed5878f39232d12447a1b0e10f1e5334a3..b4dc3fa16600cd854517ccad0f3cfc99989a952e 100644 --- a/plugins/PDFReports/API.php +++ b/plugins/PDFReports/API.php @@ -41,6 +41,7 @@ class Piwik_PDFReports_API const OUTPUT_RETURN = 4; const REPORT_TYPE_INFO_KEY = 'reportType'; + const OUTPUT_TYPE_INFO_KEY = 'outputType'; const ID_SITE_INFO_KEY = 'idSite'; const REPORT_KEY = 'report'; const REPORT_CONTENT_KEY = 'contents'; @@ -324,18 +325,11 @@ class Piwik_PDFReports_API $reportFormat = $report['format']; } - // override report parameters - if(!empty($parameters)) - { - $report['parameters'] = Piwik_Common::json_decode( - self::validateReportParameters($reportType, $parameters), - true - ); - } - else - { - $parameters = $report['parameters']; - } + // override and/or validate report parameters + $report['parameters'] = Piwik_Common::json_decode( + self::validateReportParameters($reportType, empty($parameters) ? $report['parameters'] : $parameters), + true + ); // decode report list $reportUniqueIds = $report['reports']; @@ -416,6 +410,7 @@ class Piwik_PDFReports_API $notificationInfo = array( self::REPORT_TYPE_INFO_KEY => $reportType, + self::OUTPUT_TYPE_INFO_KEY => $outputType, self::REPORT_KEY => $report, ); @@ -436,7 +431,6 @@ class Piwik_PDFReports_API // init report renderer $reportRenderer->setLocale($language); - $reportRenderer->setRenderImageInline($outputType != self::OUTPUT_SAVE_ON_DISK); // render report $websiteName = Piwik_Site::getNameFor($idSite); @@ -462,9 +456,10 @@ class Piwik_PDFReports_API $additionalFile['cid'] = $report['metadata']['uniqueId']; $additionalFile['content'] = Piwik_ReportRenderer::getStaticGraph( - $report['metadata']['imageGraphUrl'], + $report['metadata'], Piwik_ReportRenderer_Html::IMAGE_GRAPH_WIDTH, - Piwik_ReportRenderer_Html::IMAGE_GRAPH_HEIGHT + Piwik_ReportRenderer_Html::IMAGE_GRAPH_HEIGHT, + $report['evolutionGraph'] ); $additionalFile['mimeType'] = 'image/png'; $additionalFile['encoding'] = Zend_Mime::ENCODING_BASE64; diff --git a/plugins/PDFReports/PDFReports.php b/plugins/PDFReports/PDFReports.php index be87c0b4a3e15b883739d5acb3f486a18c9c8f90..d0c6178935309c1e85192ef555a6e4bc5a0c8b2f 100644 --- a/plugins/PDFReports/PDFReports.php +++ b/plugins/PDFReports/PDFReports.php @@ -26,14 +26,17 @@ class Piwik_PDFReports extends Piwik_Plugin const DEFAULT_PERIOD = 'week'; const EMAIL_ME_PARAMETER = 'emailMe'; + const EVOLUTION_GRAPH_PARAMETER = 'evolutionGraph'; const ADDITIONAL_EMAILS_PARAMETER = 'additionalEmails'; const DISPLAY_FORMAT_PARAMETER = 'displayFormat'; const EMAIL_ME_PARAMETER_DEFAULT_VALUE = true; + const EVOLUTION_GRAPH_PARAMETER_DEFAULT_VALUE = false; const EMAIL_TYPE = 'email'; static private $availableParameters = array( self::EMAIL_ME_PARAMETER => false, + self::EVOLUTION_GRAPH_PARAMETER => false, self::ADDITIONAL_EMAILS_PARAMETER => false, self::DISPLAY_FORMAT_PARAMETER => true, ); @@ -135,7 +138,17 @@ class Piwik_PDFReports extends Piwik_Plugin } else { - $parameters[self::EMAIL_ME_PARAMETER] = (bool)$parameters[self::EMAIL_ME_PARAMETER]; + $parameters[self::EMAIL_ME_PARAMETER] = self::valueIsTrue($parameters[self::EMAIL_ME_PARAMETER]); + } + + // evolutionGraph is an optional parameter + if(!isset($parameters[self::EVOLUTION_GRAPH_PARAMETER])) + { + $parameters[self::EVOLUTION_GRAPH_PARAMETER] = self::EVOLUTION_GRAPH_PARAMETER_DEFAULT_VALUE; + } + else + { + $parameters[self::EVOLUTION_GRAPH_PARAMETER] = self::valueIsTrue($parameters[self::EVOLUTION_GRAPH_PARAMETER]); } // additionalEmails is an optional parameter @@ -146,6 +159,12 @@ class Piwik_PDFReports extends Piwik_Plugin } } + // based on http://www.php.net/manual/en/filter.filters.validate.php -> FILTER_VALIDATE_BOOLEAN + static private function valueIsTrue($value) + { + return $value == 'true' || $value == 1 || $value == '1' || $value === true; + } + /** * @param Piwik_Event_Notification $notification notification object */ @@ -222,6 +241,7 @@ class Piwik_PDFReports extends Piwik_Plugin $report = $notificationInfo[Piwik_PDFReports_API::REPORT_KEY]; $displayFormat = $report['parameters'][self::DISPLAY_FORMAT_PARAMETER]; + $evolutionGraph = $report['parameters'][self::EVOLUTION_GRAPH_PARAMETER]; foreach ($processedReports as &$processedReport) { @@ -240,6 +260,8 @@ class Piwik_PDFReports extends Piwik_Plugin && Piwik_PluginsManager::getInstance()->isPluginActivated('ImageGraph') && !empty($metadata['imageGraphUrl']); + $processedReport['evolutionGraph'] = $evolutionGraph; + // remove evolution metrics from MultiSites.getAll if($metadata['module'] == 'MultiSites') { @@ -268,8 +290,14 @@ class Piwik_PDFReports extends Piwik_Plugin $notificationInfo = $notification->getNotificationInfo(); $reportFormat = $notificationInfo[Piwik_PDFReports_API::REPORT_KEY]['format']; + $outputType = $notificationInfo[Piwik_PDFReports_API::OUTPUT_TYPE_INFO_KEY]; $reportRenderer = Piwik_ReportRenderer::factory($reportFormat); + + if($reportFormat == Piwik_ReportRenderer::HTML_FORMAT) + { + $reportRenderer->setRenderImageInline($outputType != Piwik_PDFReports_API::OUTPUT_SAVE_ON_DISK); + } } } @@ -445,7 +473,8 @@ class Piwik_PDFReports extends Piwik_Plugin $view->displayFormats = self::getDisplayFormats(); $view->reportType = self::EMAIL_TYPE; $view->defaultDisplayFormat = self::DEFAULT_DISPLAY_FORMAT; - $view->defaultEmailMe = self::EMAIL_ME_PARAMETER_DEFAULT_VALUE; + $view->defaultEmailMe = self::EMAIL_ME_PARAMETER_DEFAULT_VALUE ? 'true' : 'false'; + $view->defaultEvolutionGraph = self::EVOLUTION_GRAPH_PARAMETER_DEFAULT_VALUE ? 'true' : 'false'; $out .= $view->render(); } diff --git a/plugins/PDFReports/templates/report_parameters.tpl b/plugins/PDFReports/templates/report_parameters.tpl index d009d331bc722fd0471f4c84d303622de14faf71..1d487aea1c2bef26300eed3fcd612bfe4694a3c1 100644 --- a/plugins/PDFReports/templates/report_parameters.tpl +++ b/plugins/PDFReports/templates/report_parameters.tpl @@ -5,7 +5,8 @@ var reportParameters = {ldelim} 'displayFormat' : '{$defaultDisplayFormat}', - 'emailMe' : {$defaultEmailMe} == 1, + 'emailMe' : {$defaultEmailMe}, + 'evolutionGraph' : {$defaultEvolutionGraph}, 'additionalEmails' : null {rdelim}; @@ -24,6 +25,11 @@ else $('#report_email_me').removeProp('checked'); + if(reportParameters.evolutionGraph === true) + $('#report_evolution_graph').prop('checked', 'checked'); + else + $('#report_evolution_graph').removeProp('checked'); + if(reportParameters.additionalEmails != null) $('#report_additional_emails').text(reportParameters.additionalEmails.join('\n')); else @@ -37,6 +43,7 @@ parameters.displayFormat = $('#display_format option:selected').val(); parameters.emailMe = $('#report_email_me').prop('checked'); + parameters.evolutionGraph = $('#report_evolution_graph').prop('checked'); additionalEmails = $('#report_additional_emails').val(); parameters.additionalEmails = @@ -69,5 +76,8 @@ <option {if $formatValue==1}selected{/if} value="{$formatValue}">{$formatLabel}</option> {/foreach} </select> + <br/><br/> + <input type="checkbox" id="report_evolution_graph"/> + <label for="report_evolution_graph">{'PDFReports_EvolutionGraph'|translate} </label> </td> </tr> diff --git a/plugins/Referers/Referers.php b/plugins/Referers/Referers.php index 6537c6052bcc0ebe46dc5571ccf8656d83f407d8..ed2ad1e23b328f45dafceb4baec3f2f0f7b97f59 100644 --- a/plugins/Referers/Referers.php +++ b/plugins/Referers/Referers.php @@ -64,6 +64,7 @@ class Piwik_Referers extends Piwik_Plugin 'module' => 'Referers', 'action' => 'getRefererType', 'dimension' => Piwik_Translate('Referers_ColumnRefererType'), + 'constantRowsCount' => true, 'documentation' => Piwik_Translate('Referers_TypeReportDocumentation').'<br />' .'<b>'.Piwik_Translate('Referers_DirectEntry').':</b> '.Piwik_Translate('Referers_DirectEntryDocumentation').'<br />' .'<b>'.Piwik_Translate('Referers_SearchEngines').':</b> '.Piwik_Translate('Referers_SearchEnginesDocumentation', diff --git a/tests/PHPUnit/Integration/RowEvolutionTest.php b/tests/PHPUnit/Integration/RowEvolutionTest.php index e24696ea600f71bad486552153165bf340286d12..788e19b2ddd3dfa50b0dec68c1e4a51848900f7d 100755 --- a/tests/PHPUnit/Integration/RowEvolutionTest.php +++ b/tests/PHPUnit/Integration/RowEvolutionTest.php @@ -114,6 +114,30 @@ class Test_Piwik_Integration_RowEvolution extends IntegrationTestCase $config['otherRequestParameters']['label'] = 'my>dir>' . urlencode('/page3?foo=bar&baz=bar'); $return[] = array('API.getRowEvolution', $config); + // Goals > Visits Until Conversion, idGoal != 0 + $config['testSuffix'] = '_goals_visitsUntilConversion'; + $config['periods'] = array('day'); + $config['otherRequestParameters']['date'] = '2010-02-06,2010-03-06'; + $config['otherRequestParameters']['period'] = 'day'; + $config['otherRequestParameters']['apiModule'] = 'Goals'; + $config['otherRequestParameters']['apiAction'] = 'getVisitsUntilConversion'; + $config['otherRequestParameters']['label'] = '1 visit, 2 visits'; + $config['otherRequestParameters']['idGoal'] = '2'; + $return[] = array('API.getRowEvolution', $config); + + // Goals > Visits Until Conversion, idGoal != 0, without specifying labels + $config['testSuffix'] = '_goals_visitsUntilConversion_WithoutLabels'; + $config['periods'] = array('day'); + $config['otherRequestParameters']['date'] = '2010-02-06,2010-03-06'; + $config['otherRequestParameters']['period'] = 'day'; + $config['otherRequestParameters']['apiModule'] = 'Goals'; + $config['otherRequestParameters']['apiAction'] = 'getVisitsUntilConversion'; + $config['otherRequestParameters']['label'] = false; + $config['otherRequestParameters']['filter_limit'] = 2; + $config['otherRequestParameters']['filter_sort_column'] = 'nb_conversions'; + $config['otherRequestParameters']['idGoal'] = '2'; + $return[] = array('API.getRowEvolution', $config); + return $return; } @@ -125,7 +149,9 @@ class Test_Piwik_Integration_RowEvolution extends IntegrationTestCase protected static function setUpWebsitesAndGoals() { self::createWebsite('2010-02-01 11:22:33'); - } + Piwik_Goals_API::getInstance()->addGoal(self::$idSite, 'triggered php', 'manually', '', ''); + Piwik_Goals_API::getInstance()->addGoal(self::$idSite, 'another triggered php', 'manually', '', '', false, false, true); + } protected static function trackVisits() { @@ -141,6 +167,14 @@ class Test_Piwik_Integration_RowEvolution extends IntegrationTestCase $t->setForceVisitDateTime($visitDateTime); self::checkResponse($t->doTrackPageView('incredible title ' . ($daysIntoPast % 3))); + // Trigger goal n°1 once + self::checkResponse($t->doTrackGoal(1)); + + // Trigger goal n°2 twice + self::checkResponse($t->doTrackGoal(2)); + $t->setForceVisitDateTime(Piwik_Date::factory($visitDateTime)->addHour(0.1)->getDatetime()); + self::checkResponse($t->doTrackGoal(2)); + // VISIT 2: search engine $t->setForceVisitDateTime(Piwik_Date::factory($visitDateTime)->addHour(3)->getDatetime()); $t->setUrlReferrer('http://google.com/search?q=' . urlencode(self::$keywords[$daysIntoPast % 3])); diff --git a/tests/integration/expected/test_RowEvolution_goals_visitsUntilConversion_WithoutLabels__API.getRowEvolution_day.xml b/tests/integration/expected/test_RowEvolution_goals_visitsUntilConversion_WithoutLabels__API.getRowEvolution_day.xml new file mode 100644 index 0000000000000000000000000000000000000000..c37aa61388476efeda5d15239807e4e4cee15015 --- /dev/null +++ b/tests/integration/expected/test_RowEvolution_goals_visitsUntilConversion_WithoutLabels__API.getRowEvolution_day.xml @@ -0,0 +1,203 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <column>nb_conversions</column> + <reportData> + <result date="2010-02-06"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-07"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-08"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-09"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-10"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-11"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-12"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-13"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-14"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-15"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-16"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-17"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-18"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-19"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-20"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-21"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-22"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-23"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-24"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-25"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-26"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-27"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-28"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-01"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-02"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-03"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-04"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-05"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-06"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + </reportData> + <metadata> + <metrics> + <nb_conversions_0> + <name>1 visit (Conversions)</name> + <min>2</min> + <max>2</max> + <change>0%</change> + + </nb_conversions_0> + <nb_conversions_1> + <name>2 visits (Conversions)</name> + + </nb_conversions_1> + + </metrics> + <dimension>Visits to Conversion</dimension> + <columns> + <nb_conversions>Conversions</nb_conversions> + + </columns> + + </metadata> + +</result> \ No newline at end of file diff --git a/tests/integration/expected/test_RowEvolution_goals_visitsUntilConversion__API.getRowEvolution_day.xml b/tests/integration/expected/test_RowEvolution_goals_visitsUntilConversion__API.getRowEvolution_day.xml new file mode 100644 index 0000000000000000000000000000000000000000..327d28bfa00b68f518ad3fc0bc4889f3aab08ef3 --- /dev/null +++ b/tests/integration/expected/test_RowEvolution_goals_visitsUntilConversion__API.getRowEvolution_day.xml @@ -0,0 +1,203 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <column>nb_conversions</column> + <reportData> + <result date="2010-02-06"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-07"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-08"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-09"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-10"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-11"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-12"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-13"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-14"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-15"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-16"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-17"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-18"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-19"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-20"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-21"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-22"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-23"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-24"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-25"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-26"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-27"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-02-28"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-01"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-02"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-03"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-04"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-05"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + <result date="2010-03-06"> + <row> + <nb_conversions_0>2</nb_conversions_0> + <nb_conversions_1>0</nb_conversions_1> + </row> + </result> + </reportData> + <metadata> + <metrics> + <nb_conversions_0> + <name>1 visit (Conversions)</name> + <min>2</min> + <max>2</max> + <change>0%</change> + + </nb_conversions_0> + <nb_conversions_1> + <name> 2 visits (Conversions)</name> + + </nb_conversions_1> + + </metrics> + <dimension>Visits to Conversion</dimension> + <columns> + <nb_conversions>Conversions</nb_conversions> + + </columns> + + </metadata> + +</result> diff --git a/tests/integration/expected/test_RowEvolution_referrer1__API.getRowEvolution_day.xml b/tests/integration/expected/test_RowEvolution_referrer1__API.getRowEvolution_day.xml index 6485cc50540a693da98d1eca288ca8a66aec4c52..fe2893adaf5d6eebc2f7fd65a37813323a5549e6 100644 --- a/tests/integration/expected/test_RowEvolution_referrer1__API.getRowEvolution_day.xml +++ b/tests/integration/expected/test_RowEvolution_referrer1__API.getRowEvolution_day.xml @@ -9,7 +9,7 @@ <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>0</avg_time_on_site> + <avg_time_on_site>365</avg_time_on_site> <bounce_rate>100%</bounce_rate> </row> @@ -24,7 +24,7 @@ <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>0</avg_time_on_site> + <avg_time_on_site>365</avg_time_on_site> <bounce_rate>100%</bounce_rate> </row> @@ -39,7 +39,7 @@ <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>0</avg_time_on_site> + <avg_time_on_site>365</avg_time_on_site> <bounce_rate>100%</bounce_rate> </row> @@ -54,7 +54,7 @@ <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>0</avg_time_on_site> + <avg_time_on_site>365</avg_time_on_site> <bounce_rate>100%</bounce_rate> </row> @@ -69,7 +69,7 @@ <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>0</avg_time_on_site> + <avg_time_on_site>365</avg_time_on_site> <bounce_rate>100%</bounce_rate> </row> @@ -84,7 +84,7 @@ <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>0</avg_time_on_site> + <avg_time_on_site>365</avg_time_on_site> <bounce_rate>100%</bounce_rate> </row> @@ -120,6 +120,8 @@ </nb_actions_per_visit> <avg_time_on_site> <name>Avg. Time on Website</name> + <min>0</min> + <max>365</max> </avg_time_on_site> <bounce_rate> diff --git a/tests/integration/expected/test_RowEvolution_referrer2__API.getRowEvolution_day.xml b/tests/integration/expected/test_RowEvolution_referrer2__API.getRowEvolution_day.xml index 25489ab443d975deab5547b9385c482b25775888..17a380abf5fade185bb3bd8f46f4f634702fa0cf 100644 --- a/tests/integration/expected/test_RowEvolution_referrer2__API.getRowEvolution_day.xml +++ b/tests/integration/expected/test_RowEvolution_referrer2__API.getRowEvolution_day.xml @@ -11,7 +11,7 @@ <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>0</avg_time_on_site> + <avg_time_on_site>365</avg_time_on_site> <bounce_rate>100%</bounce_rate> </row> </result> @@ -30,7 +30,7 @@ <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>0</avg_time_on_site> + <avg_time_on_site>365</avg_time_on_site> <bounce_rate>100%</bounce_rate> </row> </result> @@ -49,7 +49,7 @@ <nb_visits>1</nb_visits> <nb_actions>1</nb_actions> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>0</avg_time_on_site> + <avg_time_on_site>365</avg_time_on_site> <bounce_rate>100%</bounce_rate> </row> </result> @@ -87,6 +87,8 @@ </nb_actions_per_visit> <avg_time_on_site> <name>Avg. Time on Website</name> + <min>0</min> + <max>365</max> </avg_time_on_site> <bounce_rate>