diff --git a/src/module-elasticsuite-analytics/Block/Adminhtml/Search/Usage/Chart/ViewOrigins.php b/src/module-elasticsuite-analytics/Block/Adminhtml/Search/Usage/Chart/ViewOrigins.php
new file mode 100644
index 000000000..cbfecda28
--- /dev/null
+++ b/src/module-elasticsuite-analytics/Block/Adminhtml/Search/Usage/Chart/ViewOrigins.php
@@ -0,0 +1,112 @@
+
+ * @copyright 2020 Smile
+ * @license Open Software License ("OSL") v. 3.0
+ */
+
+namespace Smile\ElasticsuiteAnalytics\Block\Adminhtml\Search\Usage\Chart;
+
+use Smile\ElasticsuiteAnalytics\Block\Adminhtml\Search\Usage\ChartInterface;
+
+/**
+ * View origins graph block.
+ *
+ * @category Smile
+ * @package Smile\ElasticsuiteAnalytics\Block\Adminhtml\Search\Usage
+ */
+class ViewOrigins extends \Magento\Backend\Block\Template implements ChartInterface
+{
+ /**
+ * @var \Smile\ElasticsuiteAnalytics\Model\Search\Usage\Kpi\Report
+ */
+ private $report;
+
+ /**
+ * @var \Magento\Framework\Serialize\Serializer\Json
+ */
+ private $serializer;
+
+ /**
+ * Constructor.
+ *
+ * @param \Magento\Backend\Block\Template\Context $context Context.
+ * @param \Smile\ElasticsuiteAnalytics\Model\Search\Usage\Kpi\Report $report KPI report model.
+ * @param \Magento\Framework\Serialize\Serializer\Json $serializer Json serializer.
+ * @param array $data Data.
+ */
+ public function __construct(
+ \Magento\Backend\Block\Template\Context $context,
+ \Smile\ElasticsuiteAnalytics\Model\Search\Usage\Kpi\Report $report,
+ \Magento\Framework\Serialize\Serializer\Json $serializer,
+ array $data = []
+ ) {
+ parent::__construct($context, $data);
+ $this->report = $report;
+ $this->serializer = $serializer;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getChartOptions()
+ {
+ $options = [
+ 'colors' => [
+ self::COLOR_RED,
+ self::COLOR_BLUE,
+ self::COLOR_GREEN,
+ self::COLOR_YELLOW,
+ self::COLOR_GRAY,
+ self::COLOR_PINK,
+ ],
+ ];
+
+ return $this->serializer->serialize($options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getChartData()
+ {
+ $rawData = [];
+ $data = [
+ 'cols' => [
+ ['type' => 'string', 'label' => __('Session type')],
+ ['type' => 'number', 'label' => __('Count')],
+ ],
+ 'rows' => [],
+ ];
+
+ try {
+ $reportData = $this->report->getData();
+ if (array_key_exists('product_views_count', $reportData)) {
+ unset($reportData['product_views_count']);
+ foreach ($reportData as $key => $value) {
+ if (str_starts_with($key, 'product_views_')) {
+ $label = $this->report->getLabel($key);
+ if (!array_key_exists($label, $rawData)) {
+ $rawData[$label] = 0;
+ }
+ $rawData[$label] += (int) $value;
+ }
+ }
+ foreach ($rawData as $label => $count) {
+ $data['rows'][] = ['c' => [['v' => $label], ['v' => $count]]];
+ }
+ }
+ } catch (\LogicException $e) {
+ ;
+ }
+
+ return $this->serializer->serialize($data);
+ }
+}
diff --git a/src/module-elasticsuite-analytics/Block/Adminhtml/Search/Usage/ChartInterface.php b/src/module-elasticsuite-analytics/Block/Adminhtml/Search/Usage/ChartInterface.php
index 9dc58dcc0..1b90b9dca 100644
--- a/src/module-elasticsuite-analytics/Block/Adminhtml/Search/Usage/ChartInterface.php
+++ b/src/module-elasticsuite-analytics/Block/Adminhtml/Search/Usage/ChartInterface.php
@@ -37,6 +37,21 @@ interface ChartInterface
*/
const COLOR_GREEN = '#25BC94';
+ /**
+ * Constant for yellow background/drawing chart color
+ */
+ const COLOR_YELLOW = '#FFB800';
+
+ /**
+ * Constant for gray background/drawing chart color
+ */
+ const COLOR_GRAY = '#6B7280';
+
+ /**
+ * Constant for pink background/drawing chart color
+ */
+ const COLOR_PINK = '#EC4899';
+
/**
* Return chart data in the format expected by Google Charts API as a JSON encoded string.
* (see https://developers.google.com/chart/interactive/docs/reference#dataparam)
diff --git a/src/module-elasticsuite-analytics/Model/Search/Usage/Kpi/AggregationProvider.php b/src/module-elasticsuite-analytics/Model/Search/Usage/Kpi/AggregationProvider.php
index 6669316b2..1d150422e 100644
--- a/src/module-elasticsuite-analytics/Model/Search/Usage/Kpi/AggregationProvider.php
+++ b/src/module-elasticsuite-analytics/Model/Search/Usage/Kpi/AggregationProvider.php
@@ -66,6 +66,7 @@ public function getAggregation()
'name' => 'data',
'queries' => $this->getQueries(),
'metrics' => $this->getMetrics(),
+ 'childBuckets' => $this->getChildBuckets(),
];
return $this->aggregationFactory->create(BucketInterface::TYPE_QUERY_GROUP, $aggParams);
@@ -143,4 +144,19 @@ private function getQueries()
return $queries;
}
+
+ /**
+ * Return child bucket for query group aggregation.
+ *
+ * @return array
+ */
+ private function getChildBuckets(): array
+ {
+ return [
+ 'origin' => $this->aggregationFactory->create(
+ BucketInterface::TYPE_TERM,
+ ['name' => 'origin', 'field' => 'previous_page.type.identifier.keyword']
+ ),
+ ];
+ }
}
diff --git a/src/module-elasticsuite-analytics/Model/Search/Usage/Kpi/Report.php b/src/module-elasticsuite-analytics/Model/Search/Usage/Kpi/Report.php
index 2e5f03796..f1f6868b8 100644
--- a/src/module-elasticsuite-analytics/Model/Search/Usage/Kpi/Report.php
+++ b/src/module-elasticsuite-analytics/Model/Search/Usage/Kpi/Report.php
@@ -41,6 +41,26 @@ class Report extends AbstractReport
'spellcheck_usage_rate',
];
+ /**
+ * Get data label.
+ *
+ * @param string $origin Origin code.
+ * @return string
+ */
+ public function getLabel(string $origin): string
+ {
+ switch ($origin) {
+ case 'product_views_catalog_category_view_count':
+ return __('Category');
+ case 'product_views_catalogsearch_result_index_count':
+ return __('Search');
+ case 'product_views_catalog_product_view_count':
+ return __('Recommender');
+ default:
+ return __('Other');
+ }
+ }
+
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.ElseExpression)
@@ -62,6 +82,15 @@ protected function processResponse(\Smile\ElasticsuiteCore\Search\Adapter\Elasti
} elseif (in_array($value->getValue(), ['product_views', 'category_views', 'add_to_cart', 'sales'])) {
$key = sprintf("%s_count", $value->getValue());
$data[$key] = (int) $value->getMetrics()['count'];
+ if ($value->getAggregations()->getBucket('origin')->getValues()) {
+ $originDetails = '';
+ foreach ($value->getAggregations()->getBucket('origin')->getValues() ?? [] as $originData) {
+ $key = sprintf("%s_%s_count", $value->getValue(), $originData->getValue());
+ $data[$key] = (int) $originData->getMetrics()['count'];
+ $originDetails .= "• {$this->getLabel($key)}: {$originData->getMetrics()['count']}\n";
+ }
+ $data[$value->getValue() . '_origin_details'] = $originDetails;
+ }
}
}
diff --git a/src/module-elasticsuite-analytics/view/adminhtml/layout/smile_elasticsuite_analytics_search_usage.xml b/src/module-elasticsuite-analytics/view/adminhtml/layout/smile_elasticsuite_analytics_search_usage.xml
index 5daa07c32..4878cb691 100644
--- a/src/module-elasticsuite-analytics/view/adminhtml/layout/smile_elasticsuite_analytics_search_usage.xml
+++ b/src/module-elasticsuite-analytics/view/adminhtml/layout/smile_elasticsuite_analytics_search_usage.xml
@@ -88,6 +88,12 @@