Currently, when viewing a sparkline over a longer data range, then we're visualising the data of every single day in that range. When you fetch a period of one year, it means Matomo has to select 365 different archives and plot each single dot on the sparkline.
To improve performance, and also to see trends better, we want to change the period used to plot the sparkline depending on the selected date range.
Expected outcomes:
2018-06-21,2022-04-19
is selected, then we show the sparklines for the months from June 2018 to April 2022.2022-02-21,2022-10-19
is selected, then we show the sparklines for the week of 2022-02-21
to the week of 2022-10-19
. 2022-02-21,2022-10-19
we would say something like "This sparklines shows the evolution over time from $periodStart to $periodEnd. Each data point represents a $period."Technical note:
We don't need to change the Sparkline
visualisation itself but could simply change the Sparklines
visualisation in above cases to not use range
but week
or month
when needed. This way can then also more easily adjust the tooltip.
Example diff below (not taking into account yet the comparison feature)
diff --git a/plugins/CoreVisualizations/Visualizations/Sparklines.php b/plugins/CoreVisualizations/Visualizations/Sparklines.php
index 6ed99cea4f..e6e81c8979 100644
--- a/plugins/CoreVisualizations/Visualizations/Sparklines.php
+++ b/plugins/CoreVisualizations/Visualizations/Sparklines.php
@@ -13,6 +13,7 @@ namespace Piwik\Plugins\CoreVisualizations\Visualizations;
use Piwik\API\Request;
use Piwik\Common;
use Piwik\DataTable;
+use Piwik\Date;
use Piwik\Metrics;
use Piwik\Metrics\Formatter as MetricFormatter;
use Piwik\Period\Factory;
@@ -174,7 +175,8 @@ class Sparklines extends ViewDataTable
$originalDate = Common::getRequestVar('date');
$originalPeriod = Common::getRequestVar('period');
- if ($this->isComparing() && !empty($comparisons)) {
+ $isComparing = $this->isComparing() && !empty($comparisons);
+ if ($isComparing) {
$comparisonRows = [];
foreach ($comparisons->getRows() as $comparisonRow) {
$segment = $comparisonRow->getMetadata('compareSegment');
@@ -227,7 +229,23 @@ class Sparklines extends ViewDataTable
'action' => $this->requestConfig->getApiMethodToRequest()
]);
- if ($this->isComparing() && !empty($comparisons)) {
+ if ($originalPeriod === 'range' && !$isComparing) { // todo check for comparing segments it would still work to select different period but problem when comparing different periods
+ // when comparing, we have to fallback to a range because different periods might be selected.
+ // when not comparing and a longer range is selected, then we select a higher period for improved
+ // performance and also to see trends better
+ $periodObj = Factory::build($originalPeriod, $originalDate);
+ $numDaysInRange = $this->getNumDaysDifference($periodObj->getDateStart(), $periodObj->getDateEnd());
+ if ($numDaysInRange >= 730) {
+ $sparklineUrlParams['period'] = 'month';
+ $sparklineUrlParams['date'] = $originalDate;
+ } elseif ($numDaysInRange >= 180) {
+ $sparklineUrlParams['period'] = 'week';
+ $sparklineUrlParams['date'] = $originalDate;
+ }
+ }
+
+
+ if ($isComparing) {
$periodObj = Factory::build($originalPeriod, $originalDate);
$sparklineUrlParams['compareSegments'] = [];
@@ -285,6 +303,7 @@ class Sparklines extends ViewDataTable
'period' => $periodObj->getLabel(),
'date' => $periodObj->getLabel() === 'range' ? $periodObj->getRangeString() : $periodObj->getDateEnd(),
]);
+
$this->config->addSparkline($params, $metrics, $desc = null, null, ($order * 100) + $segmentIndex, $title, $sparklineMetricIndex, $seriesIndices, $graphParams);
}
} else {
@@ -322,6 +341,12 @@ class Sparklines extends ViewDataTable
}
}
+ private function getNumDaysDifference(Date $date1, Date $date2)
+ {
+ $days = (abs($date1->getTimestamp() - $date2->getTimestamp())) / 60 / 60 / 24;
+ return (int) round($days);
+ }
+
private function applyFilters(DataTable\DataTableInterface $table)
{
foreach ($this->config->getPriorityFilters() as $filter) {
diff --git a/plugins/CoreVisualizations/Visualizations/Sparklines/Config.php b/plugins/CoreVisualizations/Visualizations/Sparklines/Config.php
index caf77a7b11..6cd87f6e7f 100644
--- a/plugins/CoreVisualizations/Visualizations/Sparklines/Config.php
+++ b/plugins/CoreVisualizations/Visualizations/Sparklines/Config.php
@@ -13,6 +13,7 @@ use Piwik\DataTable\Filter\CalculateEvolutionFilter;
use Piwik\Metrics;
use Piwik\NoAccessException;
use Piwik\Period\Range;
+use Piwik\Piwik;
use Piwik\Site;
use Piwik\Url;
@@ -284,8 +285,15 @@ class Config extends \Piwik\ViewDataTable\Config
$groupedMetrics[$metricGroup][] = $metricInfo;
}
+ $tooltip = '';
+ if (!empty($requestParamsForSparkline['period'])) {
+ $tooltip = Piwik::translate('Each data point in the sparkline represents a %s.',
+ $requestParamsForSparkline['period'] === 'range' ? 'day' : $requestParamsForSparkline['period']);
+ }
+
$sparkline = array(
'url' => $this->getUrlSparkline($requestParamsForSparkline),
+ 'tooltip' => $tooltip,
'metrics' => $groupedMetrics,
'order' => $this->getSparklineOrder($order),
'title' => $title,
diff --git a/plugins/CoreVisualizations/templates/macros.twig b/plugins/CoreVisualizations/templates/macros.twig
index ea80c087bb..1c748b3bff 100644
--- a/plugins/CoreVisualizations/templates/macros.twig
+++ b/plugins/CoreVisualizations/templates/macros.twig
@@ -25,7 +25,9 @@
{% if sparkline.seriesIndices|default is not empty %}data-series-indices="{{ sparkline.seriesIndices|json_encode|e('html_attr') }}"{% endif %}
{% if sparkline.graphParams|default is not empty %}data-graph-params="{{ sparkline.graphParams|json_encode|e('html_attr') }}"{% endif %}
>
- <div>
+ <div
+ {% if sparkline.tooltip|default %}title="{{ sparkline.tooltip|e('html_attr') }}"{% endif %}
+ >
{% if sparkline.title|default is not empty %}<h6 class="sparkline-title" title="{{ sparkline.title|rawSafeDecoded|e('html_attr') }}">{{ sparkline.title }}</h6>{% endif %}
{% if sparkline.url %}{{ sparkline(sparkline.url)|raw }}{% endif %}
@mattab can you check out this one?