From c540c70e87e46f85c8ec0da1d99b91dd23fd9cab Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Fri, 22 Nov 2019 16:37:44 +0800 Subject: [PATCH] Show conversion rate when filtering for goal --- assets/js/dashboard/stats/visitor-graph.js | 18 ++++++++++++++-- lib/plausible/stats/stats.ex | 10 +++++++++ .../controllers/api/stats_controller.ex | 4 +++- .../api/stats_controller/main_graph_test.exs | 21 ++++++++++++++++--- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/assets/js/dashboard/stats/visitor-graph.js b/assets/js/dashboard/stats/visitor-graph.js index da230988f9..065a96dcd7 100644 --- a/assets/js/dashboard/stats/visitor-graph.js +++ b/assets/js/dashboard/stats/visitor-graph.js @@ -197,6 +197,19 @@ class LineGraph extends React.Component { } } + renderConversionRate() { + if (typeof(this.props.graphData.conversion_rate) === "number") { + return ( +
+
CONVERSION RATE
+
+ {this.props.graphData.conversion_rate}% +
+
+ ) + } + } + render() { const {graphData} = this.props const extraClass = graphData.interval === 'hour' ? '' : 'cursor-pointer' @@ -204,20 +217,21 @@ class LineGraph extends React.Component { return (
-
+
UNIQUE VISITORS
{numberFormatter(graphData.unique_visitors)}
{this.renderComparison(graphData.change_visitors)}
-
+
TOTAL {eventName(this.props.query)}
{numberFormatter(graphData.pageviews)}
{this.renderComparison(graphData.change_pageviews)}
+ { this.renderConversionRate() }
diff --git a/lib/plausible/stats/stats.ex b/lib/plausible/stats/stats.ex index 83b4ba513f..6b9e30497d 100644 --- a/lib/plausible/stats/stats.ex +++ b/lib/plausible/stats/stats.ex @@ -95,6 +95,16 @@ defmodule Plausible.Stats do )) end + def conversion_rate(site, query) do + {_, total_visitors} = pageviews_and_visitors(site, %{ query | filters: %{} }) + {_, converted_visitors} = pageviews_and_visitors(site, query) + if total_visitors > 0 do + Float.round(converted_visitors / total_visitors * 100, 1) + else + 0.0 + end + end + def top_referrers(site, query, limit \\ 5) do Repo.all(from e in base_query(site, query), select: %{name: e.referrer_source, count: count(e.user_id, :distinct)}, diff --git a/lib/plausible_web/controllers/api/stats_controller.ex b/lib/plausible_web/controllers/api/stats_controller.ex index 95312470ec..e98bca76f5 100644 --- a/lib/plausible_web/controllers/api/stats_controller.ex +++ b/lib/plausible_web/controllers/api/stats_controller.ex @@ -11,6 +11,7 @@ defmodule PlausibleWeb.Api.StatsController do plot_task = Task.async(fn -> Stats.calculate_plot(site, query) end) {pageviews, visitors} = Stats.pageviews_and_visitors(site, query) {change_pageviews, change_visitors} = Stats.compare_pageviews_and_visitors(site, query, {pageviews, visitors}) + conversion_rate = if query.filters["goal"], do: Stats.conversion_rate(site, query) {plot, labels, present_index} = Task.await(plot_task) json(conn, %{ @@ -21,7 +22,8 @@ defmodule PlausibleWeb.Api.StatsController do unique_visitors: visitors, change_pageviews: change_pageviews, change_visitors: change_visitors, - interval: query.step_type + conversion_rate: conversion_rate, + interval: query.step_type, }) end diff --git a/test/plausible_web/controllers/api/stats_controller/main_graph_test.exs b/test/plausible_web/controllers/api/stats_controller/main_graph_test.exs index 0a76932620..a517cc4c7f 100644 --- a/test/plausible_web/controllers/api/stats_controller/main_graph_test.exs +++ b/test/plausible_web/controllers/api/stats_controller/main_graph_test.exs @@ -6,7 +6,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do describe "GET /api/stats/main-graph - plot" do setup [:create_user, :log_in, :create_site] - test "displays pageviews for a day", %{conn: conn, site: site} do + test "displays visitors for a day", %{conn: conn, site: site} do insert(:pageview, hostname: site.domain, timestamp: ~N[2019-01-01 00:00:00]) insert(:pageview, hostname: site.domain, timestamp: ~N[2019-01-01 23:59:00]) @@ -33,7 +33,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do assert plot == [0, 1] ++ zeroes # Expecting pageview to show at 1am CET end - test "displays pageviews for a month", %{conn: conn, site: site} do + test "displays visitors for a month", %{conn: conn, site: site} do insert(:pageview, hostname: site.domain, timestamp: ~N[2019-01-01 12:00:00]) insert(:pageview, hostname: site.domain, timestamp: ~N[2019-01-31 12:00:00]) @@ -46,7 +46,7 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do assert List.last(plot) == 1 end - test "displays pageviews for 3 months", %{conn: conn, site: site} do + test "displays visitors for 3 months", %{conn: conn, site: site} do insert(:pageview, hostname: site.domain) insert(:pageview, hostname: site.domain, timestamp: months_ago(2)) @@ -155,6 +155,21 @@ defmodule PlausibleWeb.Api.StatsController.MainGraphTest do end end + describe "GET /api/stats/main-graph - conversion rate" do + setup [:create_user, :log_in, :create_site] + + test "returns conversion rate when filtering for a goal", %{conn: conn, site: site} do + insert(:pageview, hostname: site.domain, timestamp: ~N[2019-01-01 02:00:00]) + insert(:pageview, hostname: site.domain, user_id: @user_id, timestamp: ~N[2019-01-01 01:00:00]) + insert(:event, name: "Signup", hostname: site.domain, user_id: @user_id, timestamp: ~N[2019-01-01 02:00:00]) + + filters = Jason.encode!(%{goal: "Signup"}) + conn = get(conn, "/api/stats/#{site.domain}/main-graph?period=day&date=2019-01-01&filters=#{filters}") + + assert %{"conversion_rate" => 50} = json_response(conn, 200) + end + end + defp months_ago(months) do Timex.now() |> Timex.shift(months: -months) end