add piwik installation
This commit is contained in:
parent
90aa4ef157
commit
8c5d4f0c31
29 changed files with 563902 additions and 0 deletions
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations;
|
||||
|
||||
require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/JqplotDataGenerator.php';
|
||||
require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/Cloud.php';
|
||||
require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/HtmlTable.php';
|
||||
require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/JqplotGraph.php';
|
||||
|
||||
/**
|
||||
* This plugin contains all core visualizations, such as the normal HTML table and
|
||||
* jqPlot graphs.
|
||||
*/
|
||||
class CoreVisualizations extends \Piwik\Plugin
|
||||
{
|
||||
/**
|
||||
* @see Piwik\Plugin::getListHooksRegistered
|
||||
*/
|
||||
public function getListHooksRegistered()
|
||||
{
|
||||
return array(
|
||||
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
|
||||
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
|
||||
'ViewDataTable.addViewDataTable' => 'getAvailableDataTableVisualizations',
|
||||
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys'
|
||||
);
|
||||
}
|
||||
|
||||
public function getAvailableDataTableVisualizations(&$visualizations)
|
||||
{
|
||||
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\Sparkline';
|
||||
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\HtmlTable';
|
||||
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\HtmlTable\\AllColumns';
|
||||
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\Cloud';
|
||||
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Pie';
|
||||
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Bar';
|
||||
$visualizations[] = 'Piwik\\Plugins\\CoreVisualizations\\Visualizations\\JqplotGraph\\Evolution';
|
||||
}
|
||||
|
||||
public function getStylesheetFiles(&$stylesheets)
|
||||
{
|
||||
$stylesheets[] = "plugins/CoreVisualizations/stylesheets/dataTableVisualizations.less";
|
||||
$stylesheets[] = "plugins/CoreVisualizations/stylesheets/jqplot.css";
|
||||
}
|
||||
|
||||
public function getJsFiles(&$jsFiles)
|
||||
{
|
||||
$jsFiles[] = "plugins/CoreVisualizations/javascripts/seriesPicker.js";
|
||||
$jsFiles[] = "plugins/CoreVisualizations/javascripts/jqplot.js";
|
||||
$jsFiles[] = "plugins/CoreVisualizations/javascripts/jqplotBarGraph.js";
|
||||
$jsFiles[] = "plugins/CoreVisualizations/javascripts/jqplotPieGraph.js";
|
||||
$jsFiles[] = "plugins/CoreVisualizations/javascripts/jqplotEvolutionGraph.js";
|
||||
}
|
||||
|
||||
public function getClientSideTranslationKeys(&$translationKeys)
|
||||
{
|
||||
$translationKeys[] = 'General_MetricsToPlot';
|
||||
$translationKeys[] = 'General_MetricToPlot';
|
||||
$translationKeys[] = 'General_RecordsToPlot';
|
||||
$translationKeys[] = 'General_SaveImageOnYourComputer';
|
||||
$translationKeys[] = 'General_ExportAsImage';
|
||||
$translationKeys[] = 'General_NoDataForGraph';
|
||||
}
|
||||
}
|
||||
160
www/analytics/plugins/CoreVisualizations/JqplotDataGenerator.php
Normal file
160
www/analytics/plugins/CoreVisualizations/JqplotDataGenerator.php
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations;
|
||||
|
||||
use Exception;
|
||||
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator\Chart;
|
||||
|
||||
require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/JqplotDataGenerator/Evolution.php';
|
||||
|
||||
/**
|
||||
* Generates JSON data used to configure and populate JQPlot graphs.
|
||||
*
|
||||
* Supports pie graphs, bar graphs and time serieses (aka, evolution graphs).
|
||||
*/
|
||||
class JqplotDataGenerator
|
||||
{
|
||||
/**
|
||||
* View properties. @see Piwik\ViewDataTable for more info.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $properties;
|
||||
|
||||
|
||||
protected $graphType;
|
||||
|
||||
/**
|
||||
* Creates a new JqplotDataGenerator instance for a graph type and view properties.
|
||||
*
|
||||
* @param string $type 'pie', 'bar', or 'evolution'
|
||||
* @param array $properties The view properties.
|
||||
* @throws \Exception
|
||||
* @return JqplotDataGenerator
|
||||
*/
|
||||
public static function factory($type, $properties)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'evolution':
|
||||
return new JqplotDataGenerator\Evolution($properties, $type);
|
||||
case 'pie':
|
||||
case 'bar':
|
||||
return new JqplotDataGenerator($properties, $type);
|
||||
default:
|
||||
throw new Exception("Unknown JqplotDataGenerator type '$type'.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $properties
|
||||
* @param string $graphType
|
||||
*
|
||||
* @internal param \Piwik\Plugin\ViewDataTable $visualization
|
||||
*/
|
||||
public function __construct($properties, $graphType)
|
||||
{
|
||||
$this->properties = $properties;
|
||||
$this->graphType = $graphType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates JSON graph data and returns it.
|
||||
*
|
||||
* @param DataTable|DataTable\Map $dataTable
|
||||
* @return string
|
||||
*/
|
||||
public function generate($dataTable)
|
||||
{
|
||||
$visualization = new Chart();
|
||||
|
||||
if ($dataTable->getRowsCount() > 0) {
|
||||
// if addTotalRow was called in GenerateGraphHTML, add a row containing totals of
|
||||
// different metrics
|
||||
if ($this->properties['add_total_row']) {
|
||||
$dataTable->queueFilter('AddSummaryRow', Piwik::translate('General_Total'));
|
||||
}
|
||||
|
||||
$dataTable->applyQueuedFilters();
|
||||
$this->initChartObjectData($dataTable, $visualization);
|
||||
}
|
||||
|
||||
return $visualization->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DataTable|DataTable\Map $dataTable
|
||||
* @param $visualization
|
||||
*/
|
||||
protected function initChartObjectData($dataTable, $visualization)
|
||||
{
|
||||
// We apply a filter to the DataTable, decoding the label column (useful for keywords for example)
|
||||
$dataTable->filter('ColumnCallbackReplace', array('label', 'urldecode'));
|
||||
|
||||
$xLabels = $dataTable->getColumn('label');
|
||||
|
||||
$columnNames = $this->properties['columns_to_display'];
|
||||
if (($labelColumnIndex = array_search('label', $columnNames)) !== false) {
|
||||
unset($columnNames[$labelColumnIndex]);
|
||||
}
|
||||
|
||||
$columnNameToTranslation = $columnNameToValue = array();
|
||||
foreach ($columnNames as $columnName) {
|
||||
$columnNameToTranslation[$columnName] = @$this->properties['translations'][$columnName];
|
||||
|
||||
$columnNameToValue[$columnName] = $dataTable->getColumn($columnName);
|
||||
}
|
||||
|
||||
$visualization->dataTable = $dataTable;
|
||||
$visualization->properties = $this->properties;
|
||||
|
||||
$visualization->setAxisXLabels($xLabels);
|
||||
$visualization->setAxisYValues($columnNameToValue);
|
||||
$visualization->setAxisYLabels($columnNameToTranslation);
|
||||
|
||||
$units = $this->getUnitsForColumnsToDisplay();
|
||||
$visualization->setAxisYUnits($units);
|
||||
}
|
||||
|
||||
protected function getUnitsForColumnsToDisplay()
|
||||
{
|
||||
// derive units from column names
|
||||
$units = $this->deriveUnitsFromRequestedColumnNames();
|
||||
if (!empty($this->properties['y_axis_unit'])) {
|
||||
$units = array_fill(0, count($units), $this->properties['y_axis_unit']);
|
||||
}
|
||||
|
||||
// the bar charts contain the labels a first series
|
||||
// this series has to be removed from the units
|
||||
if ($this->graphType == 'bar') {
|
||||
array_shift($units);
|
||||
}
|
||||
|
||||
return $units;
|
||||
}
|
||||
|
||||
private function deriveUnitsFromRequestedColumnNames()
|
||||
{
|
||||
$idSite = Common::getRequestVar('idSite', null, 'int');
|
||||
|
||||
$units = array();
|
||||
foreach ($this->properties['columns_to_display'] as $columnName) {
|
||||
$derivedUnit = Metrics::getUnit($columnName, $idSite);
|
||||
$units[$columnName] = empty($derivedUnit) ? false : $derivedUnit;
|
||||
}
|
||||
return $units;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
|
||||
|
||||
use Piwik\Common;
|
||||
use Piwik\ProxyHttp;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Chart
|
||||
{
|
||||
// the data kept here conforms to the jqplot data layout
|
||||
// @see http://www.jqplot.com/docs/files/jqPlotOptions-txt.html
|
||||
protected $series = array();
|
||||
protected $data = array();
|
||||
protected $axes = array();
|
||||
|
||||
// temporary
|
||||
public $properties;
|
||||
|
||||
public function setAxisXLabels($xLabels)
|
||||
{
|
||||
$xSteps = $this->properties['x_axis_step_size'];
|
||||
$showAllTicks = $this->properties['show_all_ticks'];
|
||||
|
||||
$this->axes['xaxis']['labels'] = array_values($xLabels);
|
||||
|
||||
$ticks = array_values($xLabels);
|
||||
|
||||
if (!$showAllTicks) {
|
||||
// unset labels so there are $xSteps number of blank ticks between labels
|
||||
foreach ($ticks as $i => &$label) {
|
||||
if ($i % $xSteps != 0) {
|
||||
$label = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->axes['xaxis']['ticks'] = $ticks;
|
||||
}
|
||||
|
||||
public function setAxisXOnClick(&$onClick)
|
||||
{
|
||||
$this->axes['xaxis']['onclick'] = & $onClick;
|
||||
}
|
||||
|
||||
public function setAxisYValues(&$values)
|
||||
{
|
||||
foreach ($values as $label => &$data) {
|
||||
$this->series[] = array(
|
||||
'label' => $label,
|
||||
'internalLabel' => $label
|
||||
);
|
||||
|
||||
array_walk($data, function (&$v) {
|
||||
$v = (float)$v;
|
||||
});
|
||||
$this->data[] = & $data;
|
||||
}
|
||||
}
|
||||
|
||||
public function setAxisYUnits($yUnits)
|
||||
{
|
||||
$yUnits = array_values(array_map('strval', $yUnits));
|
||||
|
||||
// generate axis IDs for each unique y unit
|
||||
$axesIds = array();
|
||||
foreach ($yUnits as $idx => $unit) {
|
||||
if (!isset($axesIds[$unit])) {
|
||||
// handle axes ids: first y[]axis, then y[2]axis, y[3]axis...
|
||||
$nextAxisId = empty($axesIds) ? '' : count($axesIds) + 1;
|
||||
|
||||
$axesIds[$unit] = 'y' . $nextAxisId . 'axis';
|
||||
}
|
||||
}
|
||||
|
||||
// generate jqplot axes config
|
||||
foreach ($axesIds as $unit => $axisId) {
|
||||
$this->axes[$axisId]['tickOptions']['formatString'] = '%s' . $unit;
|
||||
}
|
||||
|
||||
// map each series to appropriate yaxis
|
||||
foreach ($yUnits as $idx => $unit) {
|
||||
$this->series[$idx]['yaxis'] = $axesIds[$unit];
|
||||
}
|
||||
}
|
||||
|
||||
public function setAxisYLabels($labels)
|
||||
{
|
||||
foreach ($this->series as &$series) {
|
||||
$label = $series['internalLabel'];
|
||||
if (isset($labels[$label])) {
|
||||
$series['label'] = $labels[$label];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
ProxyHttp::overrideCacheControlHeaders();
|
||||
|
||||
// See http://www.jqplot.com/docs/files/jqPlotOptions-txt.html
|
||||
$data = array(
|
||||
'params' => array(
|
||||
'axes' => &$this->axes,
|
||||
'series' => &$this->series
|
||||
),
|
||||
'data' => &$this->data
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
|
||||
|
||||
|
||||
use Piwik\Archive\DataTableFactory;
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\Menu\MenuMain;
|
||||
use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
|
||||
use Piwik\Url;
|
||||
|
||||
/**
|
||||
* Generates JQPlot JSON data/config for evolution graphs.
|
||||
*/
|
||||
class Evolution extends JqplotDataGenerator
|
||||
{
|
||||
/**
|
||||
* @param DataTable|DataTable\Map $dataTable
|
||||
* @param $visualization
|
||||
*/
|
||||
protected function initChartObjectData($dataTable, $visualization)
|
||||
{
|
||||
// if the loaded datatable is a simple DataTable, it is most likely a plugin plotting some custom data
|
||||
// we don't expect plugin developers to return a well defined Set
|
||||
|
||||
if ($dataTable instanceof DataTable) {
|
||||
parent::initChartObjectData($dataTable, $visualization);
|
||||
return;
|
||||
}
|
||||
|
||||
// the X label is extracted from the 'period' object in the table's metadata
|
||||
$xLabels = array();
|
||||
foreach ($dataTable->getDataTables() as $metadataDataTable) {
|
||||
$xLabels[] = $metadataDataTable->getMetadata(DataTableFactory::TABLE_METADATA_PERIOD_INDEX)->getLocalizedShortString(); // eg. "Aug 2009"
|
||||
}
|
||||
|
||||
$units = $this->getUnitsForColumnsToDisplay();
|
||||
|
||||
// if rows to display are not specified, default to all rows (TODO: perhaps this should be done elsewhere?)
|
||||
$rowsToDisplay = $this->properties['rows_to_display']
|
||||
? : array_unique($dataTable->getColumn('label'))
|
||||
? : array(false) // make sure that a series is plotted even if there is no data
|
||||
;
|
||||
|
||||
// collect series data to show. each row-to-display/column-to-display permutation creates a series.
|
||||
$allSeriesData = array();
|
||||
$seriesUnits = array();
|
||||
foreach ($rowsToDisplay as $rowLabel) {
|
||||
foreach ($this->properties['columns_to_display'] as $columnName) {
|
||||
$seriesLabel = $this->getSeriesLabel($rowLabel, $columnName);
|
||||
$seriesData = $this->getSeriesData($rowLabel, $columnName, $dataTable);
|
||||
|
||||
$allSeriesData[$seriesLabel] = $seriesData;
|
||||
$seriesUnits[$seriesLabel] = $units[$columnName];
|
||||
}
|
||||
}
|
||||
|
||||
$visualization->dataTable = $dataTable;
|
||||
$visualization->properties = $this->properties;
|
||||
|
||||
$visualization->setAxisXLabels($xLabels);
|
||||
$visualization->setAxisYValues($allSeriesData);
|
||||
$visualization->setAxisYUnits($seriesUnits);
|
||||
|
||||
$dataTables = $dataTable->getDataTables();
|
||||
|
||||
if ($this->isLinkEnabled()) {
|
||||
$idSite = Common::getRequestVar('idSite', null, 'int');
|
||||
$periodLabel = reset($dataTables)->getMetadata(DataTableFactory::TABLE_METADATA_PERIOD_INDEX)->getLabel();
|
||||
|
||||
$axisXOnClick = array();
|
||||
$queryStringAsHash = $this->getQueryStringAsHash();
|
||||
foreach ($dataTable->getDataTables() as $idDataTable => $metadataDataTable) {
|
||||
$dateInUrl = $metadataDataTable->getMetadata(DataTableFactory::TABLE_METADATA_PERIOD_INDEX)->getDateStart();
|
||||
$parameters = array(
|
||||
'idSite' => $idSite,
|
||||
'period' => $periodLabel,
|
||||
'date' => $dateInUrl->toString(),
|
||||
'segment' => \Piwik\API\Request::getRawSegmentFromRequest()
|
||||
);
|
||||
$hash = '';
|
||||
if (!empty($queryStringAsHash)) {
|
||||
$hash = '#' . Url::getQueryStringFromParameters($queryStringAsHash + $parameters);
|
||||
}
|
||||
$link = 'index.php?' .
|
||||
Url::getQueryStringFromParameters(array(
|
||||
'module' => 'CoreHome',
|
||||
'action' => 'index',
|
||||
) + $parameters)
|
||||
. $hash;
|
||||
$axisXOnClick[] = $link;
|
||||
}
|
||||
$visualization->setAxisXOnClick($axisXOnClick);
|
||||
}
|
||||
}
|
||||
|
||||
private function getSeriesData($rowLabel, $columnName, DataTable\Map $dataTable)
|
||||
{
|
||||
$seriesData = array();
|
||||
foreach ($dataTable->getDataTables() as $childTable) {
|
||||
// get the row for this label (use the first if $rowLabel is false)
|
||||
if ($rowLabel === false) {
|
||||
$row = $childTable->getFirstRow();
|
||||
} else {
|
||||
$row = $childTable->getRowFromLabel($rowLabel);
|
||||
}
|
||||
|
||||
// get series data point. defaults to 0 if no row or no column value.
|
||||
if ($row === false) {
|
||||
$seriesData[] = 0;
|
||||
} else {
|
||||
$seriesData[] = $row->getColumn($columnName) ? : 0;
|
||||
}
|
||||
}
|
||||
return $seriesData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive the series label from the row label and the column name.
|
||||
* If the row label is set, both the label and the column name are displayed.
|
||||
* @param string $rowLabel
|
||||
* @param string $columnName
|
||||
* @return string
|
||||
*/
|
||||
private function getSeriesLabel($rowLabel, $columnName)
|
||||
{
|
||||
$metricLabel = @$this->properties['translations'][$columnName];
|
||||
|
||||
if ($rowLabel !== false) {
|
||||
// eg. "Yahoo! (Visits)"
|
||||
$label = "$rowLabel ($metricLabel)";
|
||||
} else {
|
||||
// eg. "Visits"
|
||||
$label = $metricLabel;
|
||||
}
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* We link the graph dots to the same report as currently being displayed (only the date would change).
|
||||
*
|
||||
* In some cases the widget is loaded within a report that doesn't exist as such.
|
||||
* For example, the dashboards loads the 'Last visits graph' widget which can't be directly linked to.
|
||||
* Instead, the graph must link back to the dashboard.
|
||||
*
|
||||
* In other cases, like Visitors>Overview or the Goals graphs, we can link the graph clicks to the same report.
|
||||
*
|
||||
* To detect whether or not we can link to a report, we simply check if the current URL from which it was loaded
|
||||
* belongs to the menu or not. If it doesn't belong to the menu, we do not append the hash to the URL,
|
||||
* which results in loading the dashboard.
|
||||
*
|
||||
* @return array Query string array to append to the URL hash or false if the dashboard should be displayed
|
||||
*/
|
||||
private function getQueryStringAsHash()
|
||||
{
|
||||
$queryString = Url::getArrayFromCurrentQueryString();
|
||||
$piwikParameters = array('idSite', 'date', 'period', 'XDEBUG_SESSION_START', 'KEY');
|
||||
foreach ($piwikParameters as $parameter) {
|
||||
unset($queryString[$parameter]);
|
||||
}
|
||||
if (MenuMain::getInstance()->isUrlFound($queryString)) {
|
||||
return $queryString;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isLinkEnabled()
|
||||
{
|
||||
static $linkEnabled;
|
||||
if (!isset($linkEnabled)) {
|
||||
// 1) Custom Date Range always have link disabled, otherwise
|
||||
// the graph data set is way too big and fails to display
|
||||
// 2) disableLink parameter is set in the Widgetize "embed" code
|
||||
$linkEnabled = !Common::getRequestVar('disableLink', 0, 'int')
|
||||
&& Common::getRequestVar('period', 'day') != 'range';
|
||||
}
|
||||
return $linkEnabled;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations;
|
||||
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Plugin\Visualization;
|
||||
use Piwik\View;
|
||||
|
||||
/**
|
||||
* Generates a tag cloud from a given data array.
|
||||
* The generated tag cloud can be in PHP format, or in HTML.
|
||||
*
|
||||
* Inspired from Derek Harvey (www.derekharvey.co.uk)
|
||||
*
|
||||
* @property Cloud\Config $config
|
||||
*
|
||||
*/
|
||||
class Cloud extends Visualization
|
||||
{
|
||||
const ID = 'cloud';
|
||||
const TEMPLATE_FILE = "@CoreVisualizations/_dataTableViz_tagCloud.twig";
|
||||
const FOOTER_ICON = 'plugins/Zeitgeist/images/tagcloud.png';
|
||||
const FOOTER_ICON_TITLE = 'General_TagCloud';
|
||||
|
||||
/** Used by integration tests to make sure output is consistent. */
|
||||
public static $debugDisableShuffle = false;
|
||||
public $truncatingLimit = 50;
|
||||
|
||||
protected $wordsArray = array();
|
||||
|
||||
public static function getDefaultConfig()
|
||||
{
|
||||
return new Cloud\Config();
|
||||
}
|
||||
|
||||
public function beforeRender()
|
||||
{
|
||||
$this->config->show_exclude_low_population = false;
|
||||
$this->config->show_offset_information = false;
|
||||
$this->config->show_limit_control = false;
|
||||
}
|
||||
|
||||
public function afterAllFiltersAreApplied()
|
||||
{
|
||||
if ($this->dataTable->getRowsCount() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$columnToDisplay = isset($this->config->columns_to_display[1]) ? $this->config->columns_to_display[1] : 'nb_visits';
|
||||
$labelMetadata = array();
|
||||
|
||||
foreach ($this->dataTable->getRows() as $row) {
|
||||
$logo = false;
|
||||
if ($this->config->display_logo_instead_of_label) {
|
||||
$logo = $row->getMetadata('logo');
|
||||
}
|
||||
|
||||
$label = $row->getColumn('label');
|
||||
|
||||
$labelMetadata[$label] = array(
|
||||
'logo' => $logo,
|
||||
'url' => $row->getMetadata('url'),
|
||||
);
|
||||
|
||||
$this->addWord($label, $row->getColumn($columnToDisplay));
|
||||
}
|
||||
|
||||
$cloudValues = $this->getCloudValues();
|
||||
foreach ($cloudValues as &$value) {
|
||||
$value['logoWidth'] = round(max(16, $value['percent']));
|
||||
}
|
||||
|
||||
$this->assignTemplateVar('labelMetadata', $labelMetadata);
|
||||
$this->assignTemplateVar('cloudValues', $cloudValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign word to array
|
||||
* @param string $word
|
||||
* @param int $value
|
||||
* @return string
|
||||
*/
|
||||
public function addWord($word, $value = 1)
|
||||
{
|
||||
if (isset($this->wordsArray[$word])) {
|
||||
$this->wordsArray[$word] += $value;
|
||||
} else {
|
||||
$this->wordsArray[$word] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
private function getCloudValues()
|
||||
{
|
||||
$this->shuffleCloud();
|
||||
|
||||
if (empty($this->wordsArray)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$return = array();
|
||||
$maxValue = max($this->wordsArray);
|
||||
|
||||
foreach ($this->wordsArray as $word => $popularity) {
|
||||
|
||||
$wordTruncated = $this->truncateWordIfNeeded($word);
|
||||
$percent = $this->getPercentage($popularity, $maxValue);
|
||||
$sizeRange = $this->getClassFromPercent($percent);
|
||||
|
||||
$return[$word] = array(
|
||||
'word' => $word,
|
||||
'wordTruncated' => $wordTruncated,
|
||||
'value' => $popularity,
|
||||
'size' => $sizeRange,
|
||||
'percent' => $percent,
|
||||
);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffle associated names in array
|
||||
*/
|
||||
protected function shuffleCloud()
|
||||
{
|
||||
if (self::$debugDisableShuffle) {
|
||||
return;
|
||||
}
|
||||
|
||||
$keys = array_keys($this->wordsArray);
|
||||
|
||||
shuffle($keys);
|
||||
|
||||
if (count($keys) && is_array($keys)) {
|
||||
|
||||
$tmpArray = $this->wordsArray;
|
||||
|
||||
$this->wordsArray = array();
|
||||
foreach ($keys as $key => $value) {
|
||||
$this->wordsArray[$value] = $tmpArray[$value];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class range using a percentage
|
||||
*
|
||||
* @param $percent
|
||||
*
|
||||
* @return int class
|
||||
*/
|
||||
protected function getClassFromPercent($percent)
|
||||
{
|
||||
$mapping = array(95, 70, 50, 30, 15, 5, 0);
|
||||
foreach ($mapping as $key => $value) {
|
||||
if ($percent >= $value) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $word
|
||||
* @return string
|
||||
*/
|
||||
private function truncateWordIfNeeded($word)
|
||||
{
|
||||
if (Common::mb_strlen($word) > $this->truncatingLimit) {
|
||||
return Common::mb_substr($word, 0, $this->truncatingLimit - 3) . '...';
|
||||
}
|
||||
|
||||
return $word;
|
||||
}
|
||||
|
||||
private function getPercentage($popularity, $maxValue)
|
||||
{
|
||||
// case hideFutureHoursWhenToday=1 shows hours with no visits
|
||||
if ($maxValue == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$percent = ($popularity / $maxValue) * 100;
|
||||
|
||||
return $percent;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations\Cloud;
|
||||
|
||||
use Piwik\ViewDataTable\Config as VisualizationConfig;
|
||||
|
||||
/**
|
||||
* DataTable Visualization that derives from HtmlTable and sets show_extra_columns to true.
|
||||
*/
|
||||
class Config extends VisualizationConfig
|
||||
{
|
||||
|
||||
/**
|
||||
* Whether to display the logo assocatied with a DataTable row (stored as 'logo' row metadata)
|
||||
* instead of the label in Tag Clouds.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $display_logo_instead_of_label = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->addPropertiesThatCanBeOverwrittenByQueryParams(array('display_logo_instead_of_label'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations;
|
||||
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\Visualization;
|
||||
|
||||
/**
|
||||
* This is an abstract visualization that should be the base of any 'graph' visualization.
|
||||
* This class defines certain visualization properties that are specific to all graph types.
|
||||
* Derived visualizations can decide for themselves whether they should support individual
|
||||
* properties.
|
||||
*
|
||||
* @property Graph\Config $config
|
||||
*/
|
||||
abstract class Graph extends Visualization
|
||||
{
|
||||
const ID = 'graph';
|
||||
|
||||
public $selectableRows = array();
|
||||
|
||||
public static function getDefaultConfig()
|
||||
{
|
||||
return new Graph\Config();
|
||||
}
|
||||
|
||||
public static function getDefaultRequestConfig()
|
||||
{
|
||||
$config = parent::getDefaultRequestConfig();
|
||||
$config->addPropertiesThatShouldBeAvailableClientSide(array('columns'));
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function beforeRender()
|
||||
{
|
||||
if ($this->config->show_goals) {
|
||||
$this->config->translations['nb_conversions'] = Piwik::translate('Goals_ColumnConversions');
|
||||
$this->config->translations['revenue'] = Piwik::translate('General_TotalRevenue');
|
||||
}
|
||||
}
|
||||
|
||||
public function beforeLoadDataTable()
|
||||
{
|
||||
// TODO: this should not be required here. filter_limit should not be a view property, instead HtmlTable should use 'limit' or something,
|
||||
// and manually set request_parameters_to_modify['filter_limit'] based on that. (same for filter_offset).
|
||||
$this->requestConfig->request_parameters_to_modify['filter_limit'] = false;
|
||||
|
||||
if ($this->config->max_graph_elements) {
|
||||
$this->requestConfig->request_parameters_to_modify['filter_truncate'] = $this->config->max_graph_elements - 1;
|
||||
}
|
||||
|
||||
$this->requestConfig->request_parameters_to_modify['disable_queued_filters'] = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines what rows are selectable and stores them in the selectable_rows property in
|
||||
* a format the SeriesPicker JavaScript class can use.
|
||||
*/
|
||||
public function determineWhichRowsAreSelectable()
|
||||
{
|
||||
if ($this->config->row_picker_match_rows_by === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// collect all selectable rows
|
||||
$self = $this;
|
||||
|
||||
$this->dataTable->filter(function ($dataTable) use ($self) {
|
||||
/** @var DataTable $dataTable */
|
||||
|
||||
foreach ($dataTable->getRows() as $row) {
|
||||
$rowLabel = $row->getColumn('label');
|
||||
|
||||
if (false === $rowLabel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// build config
|
||||
if (!isset($self->selectableRows[$rowLabel])) {
|
||||
$self->selectableRows[$rowLabel] = array(
|
||||
'label' => $rowLabel,
|
||||
'matcher' => $rowLabel,
|
||||
'displayed' => $self->isRowVisible($rowLabel)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function isRowVisible($rowLabel)
|
||||
{
|
||||
$isVisible = true;
|
||||
if ('label' == $this->config->row_picker_match_rows_by) {
|
||||
$isVisible = in_array($rowLabel, $this->config->rows_to_display);
|
||||
}
|
||||
|
||||
return $isVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defaults the selectable_columns property if it has not been set and then transforms
|
||||
* it into something the SeriesPicker JavaScript class can use.
|
||||
*/
|
||||
public function afterAllFiltersAreApplied()
|
||||
{
|
||||
$this->determineWhichRowsAreSelectable();
|
||||
|
||||
$this->config->selectable_rows = array_values($this->selectableRows);
|
||||
|
||||
if ($this->config->add_total_row) {
|
||||
$totalTranslation = Piwik::translate('General_Total');
|
||||
$this->config->selectable_rows[] = array(
|
||||
'label' => $totalTranslation,
|
||||
'matcher' => $totalTranslation,
|
||||
'displayed' => $this->isRowVisible($totalTranslation)
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->config->show_goals) {
|
||||
$this->config->addTranslations(array(
|
||||
'nb_conversions' => Piwik::translate('Goals_ColumnConversions'),
|
||||
'revenue' => Piwik::translate('General_TotalRevenue')
|
||||
));
|
||||
}
|
||||
|
||||
// set default selectable columns, if none specified
|
||||
$selectableColumns = $this->config->selectable_columns;
|
||||
if (false === $selectableColumns) {
|
||||
$selectableColumns = array('nb_visits', 'nb_actions', 'nb_uniq_visitors');
|
||||
|
||||
if ($this->config->show_goals) {
|
||||
$goalMetrics = array('nb_conversions', 'revenue');
|
||||
$selectableColumns = array_merge($selectableColumns, $goalMetrics);
|
||||
}
|
||||
}
|
||||
|
||||
$transformed = array();
|
||||
foreach ($selectableColumns as $column) {
|
||||
$transformed[] = array(
|
||||
'column' => $column,
|
||||
'translation' => @$this->config->translations[$column],
|
||||
'displayed' => in_array($column, $this->config->columns_to_display)
|
||||
);
|
||||
}
|
||||
|
||||
$this->config->selectable_columns = $transformed;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations\Graph;
|
||||
|
||||
use Piwik\ViewDataTable\Config as VisualizationConfig;
|
||||
|
||||
/**
|
||||
* DataTable Visualization that derives from HtmlTable and sets show_extra_columns to true.
|
||||
*/
|
||||
class Config extends VisualizationConfig
|
||||
{
|
||||
|
||||
/**
|
||||
* Whether the series picker should allow picking more than one series or not.
|
||||
*
|
||||
* Default value: true
|
||||
*/
|
||||
public $allow_multi_select_series_picker = true;
|
||||
|
||||
/**
|
||||
* The maximum number of rows to render. All other rows will be aggregated in an 'Others' row.
|
||||
*
|
||||
* Default value: false (no limit)
|
||||
*/
|
||||
public $max_graph_elements = false;
|
||||
|
||||
/**
|
||||
* Array property that contains the names of columns that can be selected in the Series Picker.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $selectable_columns = false;
|
||||
|
||||
/**
|
||||
* Contains the column (if any) of the values used in the Row Picker.
|
||||
*
|
||||
* @see self::ROWS_TO_DISPLAY
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $row_picker_match_rows_by = false;
|
||||
|
||||
/**
|
||||
* Contains the list of values identifying rows that should be displayed as separate series.
|
||||
* The values are of a specific column determined by the row_picker_match_rows_by column.
|
||||
*
|
||||
* @see self::ROW_PICKER_VALUE_COLUMN
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $rows_to_display = false;
|
||||
|
||||
/**
|
||||
* Contains the list of values available for the Row Picker. Currently set to be all visible
|
||||
* rows, if the row_picker_match_rows_by property is set.
|
||||
*
|
||||
* @see self::ROW_PICKER_VALUE_COLUMN
|
||||
*/
|
||||
public $selectable_rows = 'selectable_rows';
|
||||
|
||||
/**
|
||||
* Controls whether all ticks & labels are shown on a graph's x-axis or just some.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $show_all_ticks = false;
|
||||
|
||||
/**
|
||||
* If true, a row with totals of each DataTable column is added.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $add_total_row = false;
|
||||
|
||||
/**
|
||||
* Controls whether the Series Picker is shown or not. The Series Picker allows users to
|
||||
* choose between displaying data of different columns.
|
||||
*
|
||||
* Default value: true
|
||||
*/
|
||||
public $show_series_picker = true;
|
||||
|
||||
/**
|
||||
* Controls whether the percentage of the total is displayed as a tooltip when hovering over
|
||||
* data points.
|
||||
*
|
||||
* NOTE: Sometimes this percentage is meaningless (when the total of the column values is
|
||||
* not the total number of elements in the set). In this case the tooltip should not be
|
||||
* displayed.
|
||||
*
|
||||
* Default value: true
|
||||
*/
|
||||
public $display_percentage_in_tooltip = true;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->show_limit_control = false;
|
||||
|
||||
$this->addPropertiesThatShouldBeAvailableClientSide(array(
|
||||
'show_series_picker',
|
||||
'allow_multi_select_series_picker',
|
||||
'selectable_columns',
|
||||
'selectable_rows',
|
||||
'display_percentage_in_tooltip'
|
||||
));
|
||||
|
||||
$this->addPropertiesThatCanBeOverwrittenByQueryParams(array(
|
||||
'show_all_ticks',
|
||||
'show_series_picker'
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations;
|
||||
|
||||
use Piwik\Plugin\Visualization;
|
||||
use Piwik\View;
|
||||
use Piwik\Common;
|
||||
use Piwik\Period;
|
||||
use Piwik\API\Request as ApiRequest;
|
||||
|
||||
/**
|
||||
* DataTable visualization that shows DataTable data in an HTML table.
|
||||
*
|
||||
* @property HtmlTable\Config $config
|
||||
*/
|
||||
class HtmlTable extends Visualization
|
||||
{
|
||||
const ID = 'table';
|
||||
const TEMPLATE_FILE = "@CoreVisualizations/_dataTableViz_htmlTable.twig";
|
||||
const FOOTER_ICON = 'plugins/Zeitgeist/images/table.png';
|
||||
const FOOTER_ICON_TITLE = 'General_DisplaySimpleTable';
|
||||
|
||||
public static function getDefaultConfig()
|
||||
{
|
||||
return new HtmlTable\Config();
|
||||
}
|
||||
|
||||
public static function getDefaultRequestConfig()
|
||||
{
|
||||
return new HtmlTable\RequestConfig();
|
||||
}
|
||||
|
||||
public function beforeRender()
|
||||
{
|
||||
if ($this->requestConfig->idSubtable
|
||||
&& $this->config->show_embedded_subtable) {
|
||||
|
||||
$this->config->show_visualization_only = true;
|
||||
}
|
||||
|
||||
// we do not want to get a datatable\map
|
||||
$period = Common::getRequestVar('period', 'day', 'string');
|
||||
if (Period\Range::parseDateRange($period)) {
|
||||
$period = 'range';
|
||||
}
|
||||
|
||||
if ($this->dataTable->getRowsCount()) {
|
||||
|
||||
$request = new ApiRequest(array(
|
||||
'method' => 'API.get',
|
||||
'module' => 'API',
|
||||
'action' => 'get',
|
||||
'format' => 'original',
|
||||
'filter_limit' => '-1',
|
||||
'disable_generic_filters' => 1,
|
||||
'expanded' => 0,
|
||||
'flat' => 0,
|
||||
'filter_offset' => 0,
|
||||
'period' => $period,
|
||||
'showColumns' => implode(',', $this->config->columns_to_display),
|
||||
'columns' => implode(',', $this->config->columns_to_display)
|
||||
));
|
||||
|
||||
$dataTable = $request->process();
|
||||
$this->assignTemplateVar('siteSummary', $dataTable);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
|
||||
|
||||
use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
|
||||
use Piwik\View;
|
||||
|
||||
/**
|
||||
* DataTable Visualization that derives from HtmlTable and sets show_extra_columns to true.
|
||||
*/
|
||||
class AllColumns extends HtmlTable
|
||||
{
|
||||
const ID = 'tableAllColumns';
|
||||
const FOOTER_ICON = 'plugins/Zeitgeist/images/table_more.png';
|
||||
const FOOTER_ICON_TITLE = 'General_DisplayTableWithMoreMetrics';
|
||||
|
||||
public function beforeRender()
|
||||
{
|
||||
$this->config->show_extra_columns = true;
|
||||
$this->config->datatable_css_class = 'dataTableVizAllColumns';
|
||||
$this->config->show_exclude_low_population = true;
|
||||
|
||||
parent::beforeRender();
|
||||
}
|
||||
|
||||
public function beforeGenericFiltersAreAppliedToLoadedDataTable()
|
||||
{
|
||||
$this->dataTable->filter('AddColumnsProcessedMetrics');
|
||||
|
||||
$properties = $this->config;
|
||||
|
||||
$this->dataTable->filter(function ($dataTable) use ($properties) {
|
||||
$columnsToDisplay = array('label', 'nb_visits');
|
||||
|
||||
if (in_array('nb_uniq_visitors', $dataTable->getColumns())) {
|
||||
$columnsToDisplay[] = 'nb_uniq_visitors';
|
||||
}
|
||||
|
||||
$columnsToDisplay = array_merge(
|
||||
$columnsToDisplay, array('nb_actions', 'nb_actions_per_visit', 'avg_time_on_site', 'bounce_rate')
|
||||
);
|
||||
|
||||
// only display conversion rate for the plugins that do not provide "per goal" metrics
|
||||
// otherwise, conversion rate is meaningless as a whole (since we don't process 'cross goals' conversions)
|
||||
if (!$properties->show_goals) {
|
||||
$columnsToDisplay[] = 'conversion_rate';
|
||||
}
|
||||
|
||||
$properties->columns_to_display = $columnsToDisplay;
|
||||
});
|
||||
}
|
||||
|
||||
public function afterGenericFiltersAreAppliedToLoadedDataTable()
|
||||
{
|
||||
$prettifyTime = array('\Piwik\MetricsFormatter', 'getPrettyTimeFromSeconds');
|
||||
|
||||
$this->dataTable->filter('ColumnCallbackReplace', array('avg_time_on_site', $prettifyTime));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
|
||||
|
||||
use Piwik\ViewDataTable\Config as VisualizationConfig;
|
||||
|
||||
/**
|
||||
* DataTable Visualization that derives from HtmlTable and sets show_extra_columns to true.
|
||||
*/
|
||||
class Config extends VisualizationConfig
|
||||
{
|
||||
|
||||
/**
|
||||
* If this property is set to true, subtables will be shown as embedded in the original table.
|
||||
* If false, subtables will be shown as whole tables between rows.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $show_embedded_subtable = false;
|
||||
|
||||
/**
|
||||
* Controls whether the entire DataTable should be rendered (including subtables) or just one
|
||||
* specific table in the tree.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $show_expanded = false;
|
||||
|
||||
/**
|
||||
* When showing an expanded datatable, this property controls whether rows with subtables are
|
||||
* replaced with their subtables, or if they are shown alongside their subtables.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $replace_row_with_subtable = false;
|
||||
|
||||
/**
|
||||
* Controls whether any DataTable Row Action icons are shown. If true, no icons are shown.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $disable_row_actions = false;
|
||||
|
||||
/**
|
||||
* Controls whether the row evolution DataTable Row Action icon is shown or not.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $disable_row_evolution = false;
|
||||
|
||||
/**
|
||||
* If true, the 'label', 'nb_visits', 'nb_uniq_visitors' (if present), 'nb_actions',
|
||||
* 'nb_actions_per_visit', 'avg_time_on_site', 'bounce_rate' and 'conversion_rate' (if
|
||||
* goals view is not allowed) are displayed.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $show_extra_columns = false;
|
||||
|
||||
/**
|
||||
* If true, conversions for each existing goal will be displayed for the visits in
|
||||
* each row.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $show_goals_columns = false;
|
||||
|
||||
/**
|
||||
* If true, subtables will not be loaded when rows are clicked, but only if the
|
||||
* 'show_goals_columns' property is also true.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $disable_subtable_when_show_goals = false;
|
||||
|
||||
/**
|
||||
* If true, the summary row will be colored differently than all other DataTable rows.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $highlight_summary_row = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->enable_sort = true;
|
||||
$this->datatable_js_type = 'DataTable';
|
||||
|
||||
$this->addPropertiesThatShouldBeAvailableClientSide(array(
|
||||
'show_extra_columns',
|
||||
'show_goals_columns',
|
||||
'disable_row_evolution',
|
||||
'disable_row_actions',
|
||||
'enable_sort',
|
||||
'keep_summary_row',
|
||||
'subtable_controller_action',
|
||||
));
|
||||
|
||||
$this->addPropertiesThatCanBeOverwrittenByQueryParams(array(
|
||||
'show_expanded',
|
||||
'disable_row_actions',
|
||||
'disable_row_evolution',
|
||||
'show_extra_columns',
|
||||
'show_goals_columns',
|
||||
'disable_subtable_when_show_goals',
|
||||
'keep_summary_row',
|
||||
'highlight_summary_row',
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
|
||||
|
||||
use Piwik\Common;
|
||||
use Piwik\Config as PiwikConfig;
|
||||
use Piwik\ViewDataTable\RequestConfig as VisualizationRequestConfig;
|
||||
|
||||
/**
|
||||
* DataTable Visualization that derives from HtmlTable and sets show_extra_columns to true.
|
||||
*/
|
||||
class RequestConfig extends VisualizationRequestConfig
|
||||
{
|
||||
|
||||
/**
|
||||
* Controls whether the summary row is displayed on every page of the datatable view or not.
|
||||
* If false, the summary row will be treated as the last row of the dataset and will only visible
|
||||
* when viewing the last rows.
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $keep_summary_row = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->filter_limit = PiwikConfig::getInstance()->General['datatable_default_limit'];
|
||||
|
||||
if (Common::getRequestVar('enable_filter_excludelowpop', false) == '1') {
|
||||
$this->filter_excludelowpop = 'nb_visits';
|
||||
$this->filter_excludelowpop_value = false;
|
||||
}
|
||||
|
||||
$this->addPropertiesThatShouldBeAvailableClientSide(array(
|
||||
'search_recursive',
|
||||
'filter_limit',
|
||||
'filter_offset',
|
||||
'filter_sort_column',
|
||||
'filter_sort_order',
|
||||
'keep_summary_row'
|
||||
));
|
||||
|
||||
$this->addPropertiesThatCanBeOverwrittenByQueryParams(array(
|
||||
'keep_summary_row',
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations;
|
||||
|
||||
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
|
||||
use Piwik\View;
|
||||
|
||||
/**
|
||||
* DataTable visualization that displays DataTable data in a JQPlot graph.
|
||||
* TODO: should merge all this logic w/ jqplotdatagenerator & 'Chart' visualizations.
|
||||
*
|
||||
* @property JqplotGraph\Config $config
|
||||
*/
|
||||
abstract class JqplotGraph extends Graph
|
||||
{
|
||||
const ID = 'jqplot_graph';
|
||||
const TEMPLATE_FILE = '@CoreVisualizations/_dataTableViz_jqplotGraph.twig';
|
||||
|
||||
public static function getDefaultConfig()
|
||||
{
|
||||
return new JqplotGraph\Config();
|
||||
}
|
||||
|
||||
public function getGraphData($dataTable, $properties)
|
||||
{
|
||||
$dataGenerator = $this->makeDataGenerator($properties);
|
||||
|
||||
return $dataGenerator->generate($dataTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $properties
|
||||
* @return JqplotDataGenerator
|
||||
*/
|
||||
abstract protected function makeDataGenerator($properties);
|
||||
}
|
||||
|
||||
require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/JqplotGraph/Bar.php';
|
||||
require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/JqplotGraph/Pie.php';
|
||||
require_once PIWIK_INCLUDE_PATH . '/plugins/CoreVisualizations/Visualizations/JqplotGraph/Evolution.php';
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
|
||||
|
||||
use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
|
||||
use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
|
||||
|
||||
/**
|
||||
* Visualization that renders HTML for a Bar graph using jqPlot.
|
||||
*/
|
||||
class Bar extends JqplotGraph
|
||||
{
|
||||
const ID = 'graphVerticalBar';
|
||||
const FOOTER_ICON = 'plugins/Zeitgeist/images/chart_bar.png';
|
||||
const FOOTER_ICON_TITLE = 'General_VBarGraph';
|
||||
|
||||
public function beforeRender()
|
||||
{
|
||||
parent::beforeRender();
|
||||
|
||||
$this->config->datatable_js_type = 'JqplotBarGraphDataTable';
|
||||
}
|
||||
|
||||
public static function getDefaultConfig()
|
||||
{
|
||||
$config = new Config();
|
||||
$config->max_graph_elements = 6;
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
protected function makeDataGenerator($properties)
|
||||
{
|
||||
return JqplotDataGenerator::factory('bar', $properties);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
|
||||
|
||||
use Piwik\Plugins\CoreVisualizations\Visualizations\Graph\Config as GraphConfig;
|
||||
|
||||
/**
|
||||
* DataTable Visualization that derives from HtmlTable and sets show_extra_columns to true.
|
||||
*/
|
||||
class Config extends GraphConfig
|
||||
{
|
||||
/**
|
||||
* The name of the JavaScript class to use as this graph's external series toggle. The class
|
||||
* must be a subclass of JQPlotExternalSeriesToggle.
|
||||
*
|
||||
* @see self::EXTERNAL_SERIES_TOGGLE_SHOW_ALL
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $external_series_toggle = false;
|
||||
|
||||
/**
|
||||
* Whether the graph should show all loaded series upon initial display.
|
||||
*
|
||||
* @see self::EXTERNAL_SERIES_TOGGLE
|
||||
*
|
||||
* Default value: false
|
||||
*/
|
||||
public $external_series_toggle_show_all = false;
|
||||
|
||||
/**
|
||||
* The number of x-axis ticks for each x-axis label.
|
||||
*
|
||||
* Default: 2
|
||||
*/
|
||||
public $x_axis_step_size = 2;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->show_exclude_low_population = false;
|
||||
$this->show_offset_information = false;
|
||||
$this->show_pagination_control = false;
|
||||
$this->show_exclude_low_population = false;
|
||||
$this->show_search = false;
|
||||
$this->show_export_as_image_icon = true;
|
||||
$this->y_axis_unit = '';
|
||||
|
||||
$this->addPropertiesThatShouldBeAvailableClientSide(array(
|
||||
'external_series_toggle',
|
||||
'external_series_toggle_show_all'
|
||||
));
|
||||
|
||||
$this->addPropertiesThatCanBeOverwrittenByQueryParams(array('x_axis_step_size'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
|
||||
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Period\Range;
|
||||
use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
|
||||
use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
|
||||
use Piwik\Site;
|
||||
|
||||
/**
|
||||
* Visualization that renders HTML for a line graph using jqPlot.
|
||||
*
|
||||
* @property Evolution\Config $config
|
||||
*/
|
||||
class Evolution extends JqplotGraph
|
||||
{
|
||||
const ID = 'graphEvolution';
|
||||
const SERIES_COLOR_COUNT = 8;
|
||||
|
||||
public static function getDefaultConfig()
|
||||
{
|
||||
return new Evolution\Config();
|
||||
}
|
||||
|
||||
public function beforeRender()
|
||||
{
|
||||
parent::beforeRender();
|
||||
|
||||
$this->config->datatable_js_type = 'JqplotEvolutionGraphDataTable';
|
||||
}
|
||||
|
||||
public function beforeLoadDataTable()
|
||||
{
|
||||
$this->calculateEvolutionDateRange();
|
||||
|
||||
parent::beforeLoadDataTable();
|
||||
|
||||
// period will be overridden when 'range' is requested in the UI
|
||||
// but the graph will display for each day of the range.
|
||||
// Default 'range' behavior is to return the 'sum' for the range
|
||||
if (Common::getRequestVar('period', false) == 'range') {
|
||||
$this->requestConfig->request_parameters_to_modify['period'] = 'day';
|
||||
}
|
||||
|
||||
$this->config->custom_parameters['columns'] = $this->config->columns_to_display;
|
||||
}
|
||||
|
||||
public function afterAllFiltersAreApplied()
|
||||
{
|
||||
parent::afterAllFiltersAreApplied();
|
||||
|
||||
if (false === $this->config->x_axis_step_size) {
|
||||
$rowCount = $this->dataTable->getRowsCount();
|
||||
|
||||
$this->config->x_axis_step_size = $this->getDefaultXAxisStepSize($rowCount);
|
||||
}
|
||||
}
|
||||
|
||||
protected function makeDataGenerator($properties)
|
||||
{
|
||||
return JqplotDataGenerator::factory('evolution', $properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on the period, date and evolution_{$period}_last_n query parameters,
|
||||
* calculates the date range this evolution chart will display data for.
|
||||
*/
|
||||
private function calculateEvolutionDateRange()
|
||||
{
|
||||
$period = Common::getRequestVar('period');
|
||||
|
||||
$defaultLastN = self::getDefaultLastN($period);
|
||||
$originalDate = Common::getRequestVar('date', 'last' . $defaultLastN, 'string');
|
||||
|
||||
if ('range' != $period) { // show evolution limit if the period is not a range
|
||||
$this->config->show_limit_control = true;
|
||||
|
||||
// set the evolution_{$period}_last_n query param
|
||||
if (Range::parseDateRange($originalDate)) {
|
||||
// if a multiple period
|
||||
|
||||
// overwrite last_n param using the date range
|
||||
$oPeriod = new Range($period, $originalDate);
|
||||
$lastN = count($oPeriod->getSubperiods());
|
||||
|
||||
} else {
|
||||
|
||||
// if not a multiple period
|
||||
list($newDate, $lastN) = self::getDateRangeAndLastN($period, $originalDate, $defaultLastN);
|
||||
$this->requestConfig->request_parameters_to_modify['date'] = $newDate;
|
||||
$this->config->custom_parameters['dateUsedInGraph'] = $newDate;
|
||||
}
|
||||
|
||||
$lastNParamName = self::getLastNParamName($period);
|
||||
$this->config->custom_parameters[$lastNParamName] = $lastN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entire date range and lastN value for the current request, based on
|
||||
* a period type and end date.
|
||||
*
|
||||
* @param string $period The period type, 'day', 'week', 'month' or 'year'
|
||||
* @param string $endDate The end date.
|
||||
* @param int|null $defaultLastN The default lastN to use. If null, the result of
|
||||
* getDefaultLastN is used.
|
||||
* @return array An array w/ two elements. The first is a whole date range and the second
|
||||
* is the lastN number used, ie, array('2010-01-01,2012-01-02', 2).
|
||||
*/
|
||||
public static function getDateRangeAndLastN($period, $endDate, $defaultLastN = null)
|
||||
{
|
||||
if ($defaultLastN === null) {
|
||||
$defaultLastN = self::getDefaultLastN($period);
|
||||
}
|
||||
|
||||
$lastNParamName = self::getLastNParamName($period);
|
||||
$lastN = Common::getRequestVar($lastNParamName, $defaultLastN, 'int');
|
||||
|
||||
$site = new Site(Common::getRequestVar('idSite'));
|
||||
|
||||
$dateRange = Range::getRelativeToEndDate($period, 'last' . $lastN, $endDate, $site);
|
||||
|
||||
return array($dateRange, $lastN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default last N number of dates to display for a given period.
|
||||
*
|
||||
* @param string $period 'day', 'week', 'month' or 'year'
|
||||
* @return int
|
||||
*/
|
||||
public static function getDefaultLastN($period)
|
||||
{
|
||||
switch ($period) {
|
||||
case 'week':
|
||||
return 26;
|
||||
case 'month':
|
||||
return 24;
|
||||
case 'year':
|
||||
return 5;
|
||||
case 'day':
|
||||
default:
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query parameter that stores the lastN number of periods to get for
|
||||
* the evolution graph.
|
||||
*
|
||||
* @param string $period The period type, 'day', 'week', 'month' or 'year'.
|
||||
* @return string
|
||||
*/
|
||||
public static function getLastNParamName($period)
|
||||
{
|
||||
return "evolution_{$period}_last_n";
|
||||
}
|
||||
|
||||
public function getDefaultXAxisStepSize($countGraphElements)
|
||||
{
|
||||
// when the number of elements plotted can be small, make sure the X legend is useful
|
||||
if ($countGraphElements <= 7) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$periodLabel = Common::getRequestVar('period');
|
||||
|
||||
switch ($periodLabel) {
|
||||
case 'day':
|
||||
case 'range':
|
||||
$steps = 5;
|
||||
break;
|
||||
case 'week':
|
||||
$steps = 4;
|
||||
break;
|
||||
case 'month':
|
||||
$steps = 5;
|
||||
break;
|
||||
case 'year':
|
||||
$steps = 5;
|
||||
break;
|
||||
default:
|
||||
$steps = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
$paddedCount = $countGraphElements + 2; // pad count so last label won't be cut off
|
||||
|
||||
return ceil($paddedCount / $steps);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Evolution;
|
||||
|
||||
use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Config as JqplotGraphConfig;
|
||||
|
||||
/**
|
||||
* DataTable Visualization that derives from HtmlTable and sets show_extra_columns to true.
|
||||
*/
|
||||
class Config extends JqplotGraphConfig
|
||||
{
|
||||
/**
|
||||
* Whether to show a line graph or a bar graph.
|
||||
*
|
||||
* Default value: true
|
||||
*/
|
||||
public $show_line_graph = true;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->show_all_views_icons = false;
|
||||
$this->show_table = false;
|
||||
$this->show_table_all_columns = false;
|
||||
$this->hide_annotations_view = false;
|
||||
$this->x_axis_step_size = false;
|
||||
$this->show_line_graph = true;
|
||||
|
||||
$this->addPropertiesThatShouldBeAvailableClientSide(array('show_line_graph'));
|
||||
$this->addPropertiesThatCanBeOverwrittenByQueryParams(array('show_line_graph'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
|
||||
|
||||
use Piwik\Plugins\CoreVisualizations\JqplotDataGenerator;
|
||||
use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph;
|
||||
|
||||
/**
|
||||
* Visualization that renders HTML for a Pie graph using jqPlot.
|
||||
*/
|
||||
class Pie extends JqplotGraph
|
||||
{
|
||||
const ID = 'graphPie';
|
||||
const FOOTER_ICON = 'plugins/Zeitgeist/images/chart_pie.png';
|
||||
const FOOTER_ICON_TITLE = 'General_Piechart';
|
||||
|
||||
public static function getDefaultConfig()
|
||||
{
|
||||
$config = new Config();
|
||||
$config->max_graph_elements = 6;
|
||||
$config->allow_multi_select_series_picker = false;
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function beforeRender()
|
||||
{
|
||||
parent::beforeRender();
|
||||
|
||||
$this->config->show_all_ticks = true;
|
||||
$this->config->datatable_js_type = 'JqplotPieGraphDataTable';
|
||||
}
|
||||
|
||||
public function afterAllFiltersAreApplied()
|
||||
{
|
||||
parent::afterAllFiltersAreApplied();
|
||||
|
||||
$metricColumn = reset($this->config->columns_to_display);
|
||||
|
||||
if ($metricColumn == 'label') {
|
||||
$metricColumn = next($this->config->columns_to_display);
|
||||
}
|
||||
|
||||
$this->config->columns_to_display = array($metricColumn ? : 'nb_visits');
|
||||
}
|
||||
|
||||
protected function makeDataGenerator($properties)
|
||||
{
|
||||
return JqplotDataGenerator::factory('pie', $properties);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
namespace Piwik\Plugins\CoreVisualizations\Visualizations;
|
||||
|
||||
use Exception;
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Plugin\ViewDataTable;
|
||||
|
||||
/**
|
||||
* Reads the requested DataTable from the API and prepare data for the Sparkline view.
|
||||
*
|
||||
*/
|
||||
class Sparkline extends ViewDataTable
|
||||
{
|
||||
const ID = 'sparkline';
|
||||
|
||||
/**
|
||||
* @see ViewDataTable::main()
|
||||
* @return mixed
|
||||
*/
|
||||
protected function buildView()
|
||||
{
|
||||
// If period=range, we force the sparkline to draw daily data points
|
||||
$period = Common::getRequestVar('period');
|
||||
if ($period == 'range') {
|
||||
$_GET['period'] = 'day';
|
||||
}
|
||||
|
||||
$this->loadDataTableFromAPI();
|
||||
|
||||
// then revert the hack for potentially subsequent getRequestVar
|
||||
$_GET['period'] = $period;
|
||||
|
||||
$values = $this->getValuesFromDataTable($this->dataTable);
|
||||
if (empty($values)) {
|
||||
$values = array_fill(0, 30, 0);
|
||||
}
|
||||
|
||||
$graph = new \Piwik\Visualization\Sparkline();
|
||||
$graph->setValues($values);
|
||||
|
||||
$height = Common::getRequestVar('height', 0, 'int');
|
||||
if (!empty($height)) {
|
||||
$graph->setHeight($height);
|
||||
}
|
||||
|
||||
$width = Common::getRequestVar('width', 0, 'int');
|
||||
if (!empty($width)) {
|
||||
$graph->setWidth($width);
|
||||
}
|
||||
|
||||
$graph->main();
|
||||
|
||||
return $graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DataTable\Map $dataTableMap
|
||||
* @param string $columnToPlot
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getValuesFromDataTableMap($dataTableMap, $columnToPlot)
|
||||
{
|
||||
$dataTableMap->applyQueuedFilters();
|
||||
|
||||
$values = array();
|
||||
|
||||
foreach ($dataTableMap->getDataTables() as $table) {
|
||||
|
||||
if ($table->getRowsCount() > 1) {
|
||||
throw new Exception("Expecting only one row per DataTable");
|
||||
}
|
||||
|
||||
$value = 0;
|
||||
$onlyRow = $table->getFirstRow();
|
||||
|
||||
if (false !== $onlyRow) {
|
||||
if (!empty($columnToPlot)) {
|
||||
$value = $onlyRow->getColumn($columnToPlot);
|
||||
} // if not specified, we load by default the first column found
|
||||
// eg. case of getLastDistinctCountriesGraph
|
||||
else {
|
||||
$columns = $onlyRow->getColumns();
|
||||
$value = current($columns);
|
||||
}
|
||||
}
|
||||
|
||||
$values[] = $value;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
protected function getValuesFromDataTable($dataTable)
|
||||
{
|
||||
$columns = $this->config->columns_to_display;
|
||||
|
||||
$columnToPlot = false;
|
||||
|
||||
if (!empty($columns)) {
|
||||
$columnToPlot = reset($columns);
|
||||
if ($columnToPlot == 'label') {
|
||||
$columnToPlot = next($columns);
|
||||
}
|
||||
}
|
||||
|
||||
// a Set is returned when using the normal code path to request data from Archives, in all core plugins
|
||||
// however plugins can also return simple datatable, hence why the sparkline can accept both data types
|
||||
if ($this->dataTable instanceof DataTable\Map) {
|
||||
$values = $this->getValuesFromDataTableMap($dataTable, $columnToPlot);
|
||||
} elseif ($this->dataTable instanceof DataTable) {
|
||||
$values = $this->dataTable->getColumn($columnToPlot);
|
||||
} else {
|
||||
$values = false;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
}
|
||||
1100
www/analytics/plugins/CoreVisualizations/javascripts/jqplot.js
Normal file
1100
www/analytics/plugins/CoreVisualizations/javascripts/jqplot.js
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue