mirror of
https://github.com/plausible/analytics.git
synced 2024-12-25 10:33:01 +03:00
Remove comparison line (#232)
* Fix svg attributes in React * Remove comparison line on visitor graph
This commit is contained in:
parent
f7b37fe9ea
commit
d266cfd60a
@ -98,10 +98,10 @@ class DatePicker extends React.Component {
|
||||
return (
|
||||
<div className="flex rounded shadow bg-white mr-4 cursor-pointer">
|
||||
<Link to={{search: this.queryWithPeriod(period, {date: prevDate})}} className="flex items-center px-2 border-r border-gray-300">
|
||||
<svg className="feather h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>
|
||||
<svg className="feather h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="15 18 9 12 15 6"></polyline></svg>
|
||||
</Link>
|
||||
<Link to={{search: this.queryWithPeriod(period, {date: nextDate})}} className="flex items-center px-2">
|
||||
<svg class="feather h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
|
||||
<svg className="feather h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
@ -132,7 +132,7 @@ class DatePicker extends React.Component {
|
||||
<div className="relative" style={{height: '35.5px', width: '190px'}} ref={node => this.dropDownNode = node}>
|
||||
<div onClick={this.open.bind(this)} className="flex items-center justify-between rounded bg-white shadow px-4 pr-3 py-2 leading-tight cursor-pointer text-sm font-medium text-gray-800 h-full">
|
||||
<span className="mr-2">{this.timeFrameText()}</span>
|
||||
<svg class="text-pink-500 h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<svg className="text-pink-500 h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polyline points="6 9 12 15 18 9"></polyline>
|
||||
</svg>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@ export default function MoreLink({site, list, endpoint}) {
|
||||
return (
|
||||
<div className="text-center w-full absolute bottom-0 left-0 p-4">
|
||||
<Link to={`/${encodeURIComponent(site.domain)}/${endpoint}${window.location.search}`} className="leading-snug font-bold text-sm text-gray-500 hover:text-red-500 transition tracking-wide">
|
||||
<svg className="feather mr-1" style={{marginTop: '-2px'}} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/></svg>
|
||||
<svg className="feather mr-1" style={{marginTop: '-2px'}} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/></svg>
|
||||
MORE
|
||||
</Link>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@ import { eventName } from '../query'
|
||||
import numberFormatter, {durationFormatter} from '../number-formatter'
|
||||
import * as api from '../api'
|
||||
|
||||
function mainSet(plot, present_index, ctx, label) {
|
||||
function buildDataSet(plot, present_index, ctx, label) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, 0, 300);
|
||||
gradient.addColorStop(0, 'rgba(101,116,205, 0.2)');
|
||||
gradient.addColorStop(1, 'rgba(101,116,205, 0)');
|
||||
@ -47,57 +47,6 @@ function mainSet(plot, present_index, ctx, label) {
|
||||
}
|
||||
}
|
||||
|
||||
function compareSet(plot, present_index, ctx) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, 0, 300);
|
||||
gradient.addColorStop(0, 'rgba(255, 68, 87, .2)');
|
||||
gradient.addColorStop(1, 'rgba(255, 68, 87, 0)');
|
||||
|
||||
if (present_index) {
|
||||
var dashedPart = plot.slice(present_index - 1);
|
||||
var dashedPlot = (new Array(plot.length - dashedPart.length)).concat(dashedPart)
|
||||
for(var i = present_index; i < plot.length; i++) {
|
||||
plot[i] = undefined
|
||||
}
|
||||
|
||||
return [{
|
||||
label: 'Conversions',
|
||||
data: plot,
|
||||
borderWidth: 3,
|
||||
borderColor: 'rgba(255, 68, 87, 1)',
|
||||
pointBackgroundColor: 'rgba(255, 68, 87, 1)',
|
||||
backgroundColor: gradient,
|
||||
},
|
||||
{
|
||||
label: 'Conversions',
|
||||
data: dashedPlot,
|
||||
borderWidth: 3,
|
||||
borderDash: [5, 10],
|
||||
borderColor: 'rgba(255, 68, 87, 1)',
|
||||
pointBackgroundColor: 'rgba(255, 68, 87, 1)',
|
||||
backgroundColor: gradient,
|
||||
}]
|
||||
} else {
|
||||
return [{
|
||||
label: 'Conversions',
|
||||
data: plot,
|
||||
borderWidth: 3,
|
||||
borderColor: 'rgba(255, 68, 87, 1)',
|
||||
pointBackgroundColor: 'rgba(255, 68, 87, 1)',
|
||||
backgroundColor: gradient,
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
function dataSets(graphData, ctx) {
|
||||
const dataSets = mainSet(graphData.plot, graphData.present_index, ctx, graphData.interval === 'minute' ? 'Pageviews' : 'Visitors')
|
||||
|
||||
if (graphData.compare_plot) {
|
||||
return dataSets.concat(compareSet(graphData.compare_plot, graphData.present_index, ctx))
|
||||
} else {
|
||||
return dataSets
|
||||
}
|
||||
}
|
||||
|
||||
const MONTHS = [
|
||||
"January", "February", "March",
|
||||
"April", "May", "June", "July",
|
||||
@ -136,12 +85,14 @@ class LineGraph extends React.Component {
|
||||
componentDidMount() {
|
||||
const {graphData} = this.props
|
||||
this.ctx = document.getElementById("main-graph-canvas").getContext('2d');
|
||||
const label = this.props.query.filters.goal ? 'Converted visitors' : graphData.interval === 'minute' ? 'Pageviews' : 'Visitors'
|
||||
const dataSet = buildDataSet(graphData.plot, graphData.present_index, this.ctx, label)
|
||||
|
||||
this.chart = new Chart(this.ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: graphData.labels,
|
||||
datasets: dataSets(graphData, this.ctx)
|
||||
datasets: dataSet
|
||||
},
|
||||
options: {
|
||||
animation: false,
|
||||
@ -296,7 +247,7 @@ class LineGraph extends React.Component {
|
||||
|
||||
return (
|
||||
<a href={endpoint} download>
|
||||
<svg className="feather w-4 h-5 absolute text-gray-700" style={{right: '2rem', top: '-2rem'}} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
|
||||
<svg className="feather w-4 h-5 absolute text-gray-700" style={{right: '2rem', top: '-2rem'}} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ defmodule Plausible.Stats.Clickhouse do
|
||||
|
||||
groups =
|
||||
Clickhouse.all(
|
||||
from e in base_query(site, %{query | filters: %{}}),
|
||||
from e in base_query(site, query),
|
||||
select:
|
||||
{fragment("toStartOfMonth(toTimeZone(?, ?)) as month", e.timestamp, ^site.timezone),
|
||||
fragment("uniq(?) as visitors", e.user_id)},
|
||||
@ -44,30 +44,15 @@ defmodule Plausible.Stats.Clickhouse do
|
||||
|> Enum.map(fn row -> {row["month"], row["visitors"]} end)
|
||||
|> Enum.into(%{})
|
||||
|
||||
compare_groups =
|
||||
if query.filters["goal"] do
|
||||
Clickhouse.all(
|
||||
from e in base_query(site, query),
|
||||
select:
|
||||
{fragment("toStartOfMonth(toTimeZone(?, ?)) as month", e.timestamp, ^site.timezone),
|
||||
fragment("uniq(?) as visitors", e.user_id)},
|
||||
group_by: fragment("month"),
|
||||
order_by: fragment("month")
|
||||
)
|
||||
|> Enum.map(fn row -> {row["month"], row["visitors"]} end)
|
||||
|> Enum.into(%{})
|
||||
end
|
||||
|
||||
present_index =
|
||||
Enum.find_index(steps, fn step ->
|
||||
step == Timex.now(site.timezone) |> Timex.to_date() |> Timex.beginning_of_month()
|
||||
end)
|
||||
|
||||
plot = Enum.map(steps, fn step -> groups[step] || 0 end)
|
||||
compare_plot = compare_groups && Enum.map(steps, fn step -> compare_groups[step] || 0 end)
|
||||
labels = Enum.map(steps, fn step -> Timex.format!(step, "{ISOdate}") end)
|
||||
|
||||
{plot, compare_plot, labels, present_index}
|
||||
{plot, labels, present_index}
|
||||
end
|
||||
|
||||
def calculate_plot(site, %Query{step_type: "date"} = query) do
|
||||
@ -75,7 +60,7 @@ defmodule Plausible.Stats.Clickhouse do
|
||||
|
||||
groups =
|
||||
Clickhouse.all(
|
||||
from e in base_query(site, %{query | filters: %{}}),
|
||||
from e in base_query(site, query),
|
||||
select:
|
||||
{fragment("toDate(toTimeZone(?, ?)) as day", e.timestamp, ^site.timezone),
|
||||
fragment("uniq(?) as visitors", e.user_id)},
|
||||
@ -85,29 +70,14 @@ defmodule Plausible.Stats.Clickhouse do
|
||||
|> Enum.map(fn row -> {row["day"], row["visitors"]} end)
|
||||
|> Enum.into(%{})
|
||||
|
||||
compare_groups =
|
||||
if query.filters["goal"] do
|
||||
Clickhouse.all(
|
||||
from e in base_query(site, query),
|
||||
select:
|
||||
{fragment("toDate(toTimeZone(?, ?)) as day", e.timestamp, ^site.timezone),
|
||||
fragment("uniq(?) as visitors", e.user_id)},
|
||||
group_by: fragment("day"),
|
||||
order_by: fragment("day")
|
||||
)
|
||||
|> Enum.map(fn row -> {row["day"], row["visitors"]} end)
|
||||
|> Enum.into(%{})
|
||||
end
|
||||
|
||||
present_index =
|
||||
Enum.find_index(steps, fn step -> step == Timex.now(site.timezone) |> Timex.to_date() end)
|
||||
|
||||
steps_to_show = if present_index, do: present_index + 1, else: Enum.count(steps)
|
||||
plot = Enum.map(steps, fn step -> groups[step] || 0 end) |> Enum.take(steps_to_show)
|
||||
compare_plot = compare_groups && Enum.map(steps, fn step -> compare_groups[step] || 0 end)
|
||||
labels = Enum.map(steps, fn step -> Timex.format!(step, "{ISOdate}") end)
|
||||
|
||||
{plot, compare_plot, labels, present_index}
|
||||
{plot, labels, present_index}
|
||||
end
|
||||
|
||||
def calculate_plot(site, %Query{step_type: "hour"} = query) do
|
||||
@ -115,7 +85,7 @@ defmodule Plausible.Stats.Clickhouse do
|
||||
|
||||
groups =
|
||||
Clickhouse.all(
|
||||
from e in base_query(site, %{query | filters: %{}}),
|
||||
from e in base_query(site, query),
|
||||
select:
|
||||
{fragment("toHour(toTimeZone(?, ?)) as hour", e.timestamp, ^site.timezone),
|
||||
fragment("uniq(?) as visitors", e.user_id)},
|
||||
@ -125,20 +95,6 @@ defmodule Plausible.Stats.Clickhouse do
|
||||
|> Enum.map(fn row -> {row["hour"], row["visitors"]} end)
|
||||
|> Enum.into(%{})
|
||||
|
||||
compare_groups =
|
||||
if query.filters["goal"] do
|
||||
Clickhouse.all(
|
||||
from e in base_query(site, query),
|
||||
select:
|
||||
{fragment("toHour(toTimeZone(?, ?)) as hour", e.timestamp, ^site.timezone),
|
||||
fragment("uniq(?) as visitors", e.user_id)},
|
||||
group_by: fragment("hour"),
|
||||
order_by: fragment("hour")
|
||||
)
|
||||
|> Enum.map(fn row -> {row["hour"], row["visitors"]} end)
|
||||
|> Enum.into(%{})
|
||||
end
|
||||
|
||||
now = Timex.now(site.timezone)
|
||||
is_today = Timex.to_date(now) == query.date_range.first
|
||||
present_index = is_today && Enum.find_index(steps, fn step -> step == now.hour end)
|
||||
@ -152,8 +108,7 @@ defmodule Plausible.Stats.Clickhouse do
|
||||
end)
|
||||
|
||||
plot = Enum.map(steps, fn step -> groups[step] || 0 end) |> Enum.take(steps_to_show)
|
||||
compare_plot = compare_groups && Enum.map(steps, fn step -> compare_groups[step] || 0 end)
|
||||
{plot, compare_plot, labels, present_index}
|
||||
{plot, labels, present_index}
|
||||
end
|
||||
|
||||
def calculate_plot(site, %Query{period: "realtime"}) do
|
||||
@ -174,7 +129,7 @@ defmodule Plausible.Stats.Clickhouse do
|
||||
|
||||
labels = Enum.into(-30..-1, [])
|
||||
plot = Enum.map(labels, fn label -> groups[label] || 0 end)
|
||||
{plot, nil, labels, nil}
|
||||
{plot, labels, nil}
|
||||
end
|
||||
|
||||
def bounce_rate(site, query) do
|
||||
|
@ -11,11 +11,10 @@ defmodule PlausibleWeb.Api.StatsController do
|
||||
|
||||
plot_task = Task.async(fn -> Stats.calculate_plot(site, query) end)
|
||||
top_stats = fetch_top_stats(site, query)
|
||||
{plot, compare_plot, labels, present_index} = Task.await(plot_task)
|
||||
{plot, labels, present_index} = Task.await(plot_task)
|
||||
|
||||
json(conn, %{
|
||||
plot: plot,
|
||||
compare_plot: compare_plot,
|
||||
labels: labels,
|
||||
present_index: present_index,
|
||||
top_stats: top_stats,
|
||||
|
@ -44,7 +44,7 @@ defmodule PlausibleWeb.StatsController do
|
||||
site = conn.assigns[:site]
|
||||
|
||||
query = Query.from(site.timezone, conn.params)
|
||||
{plot, _, labels, _} = Stats.calculate_plot(site, query)
|
||||
{plot, labels, _} = Stats.calculate_plot(site, query)
|
||||
|
||||
csv_content =
|
||||
Enum.zip(labels, plot)
|
||||
|
Loading…
Reference in New Issue
Block a user