Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change sparklines visualisation depending on the selected date range #20066

Closed
tsteur opened this issue Nov 30, 2022 · 0 comments · Fixed by #20090
Closed

Change sparklines visualisation depending on the selected date range #20066

tsteur opened this issue Nov 30, 2022 · 0 comments · Fixed by #20090
Assignees
Labels
c: Performance For when we could improve the performance / speed of Matomo. c: Usability For issues that let users achieve a defined goal more effectively or efficiently. not-in-changelog For issues or pull requests that should not be included in our release changelog on matomo.org.

Comments

@tsteur
Copy link
Member

tsteur commented Nov 30, 2022

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.

Example:
image

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:

  • If a range of 24+ months is selected, then in the UI show the sparklines for the selected range for months.
  • For example, if a date range of 2018-06-21,2022-04-19 is selected, then we show the sparklines for the months from June 2018 to April 2022.
  • If a range of 6+ months is selected, then in the UI show the sparklines for the selected range for weeks.
    • For example, if a date range of 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.
  • If a range of less than 6 months is selected, then we keep showing it as before.
  • In the user interface, when hovering a sparkline, we should show a tooltip which data/period is shown in the sparkline graphs. Meaning which period and which dates. Like in the case of a selected date range 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."
  • When comparison different dates feature is used, then people might be comparing different ranges. This means we can maybe only convert to week/month if both the original range and the comparison range is of a certain length. When comparing only different periods then we can still easily use the same 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?

@tsteur tsteur added c: Performance For when we could improve the performance / speed of Matomo. c: Usability For issues that let users achieve a defined goal more effectively or efficiently. To Triage An issue awaiting triage by a Matomo core team member labels Nov 30, 2022
@mattab mattab added this to the 5.1.0 milestone Dec 7, 2022
@tsteur tsteur self-assigned this Dec 10, 2022
@bx80 bx80 removed the To Triage An issue awaiting triage by a Matomo core team member label Dec 11, 2022
@justinvelluppillai justinvelluppillai added the not-in-changelog For issues or pull requests that should not be included in our release changelog on matomo.org. label Jan 12, 2023
@mattab mattab removed this from the 5.1.0 milestone Mar 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: Performance For when we could improve the performance / speed of Matomo. c: Usability For issues that let users achieve a defined goal more effectively or efficiently. not-in-changelog For issues or pull requests that should not be included in our release changelog on matomo.org.
Projects
None yet
4 participants