mirror of
https://github.com/kremalicious/umami.git
synced 2024-11-22 18:00:17 +01:00
Updated summary query. Added visit time.
This commit is contained in:
parent
da2d383b71
commit
efdbd1c632
@ -1,11 +1,12 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import MetricCard from './MetricCard';
|
import MetricCard from './MetricCard';
|
||||||
import { get } from '../lib/web';
|
import { get } from '../lib/web';
|
||||||
|
import { formatShortTime } from 'lib/format';
|
||||||
import styles from './WebsiteSummary.module.css';
|
import styles from './WebsiteSummary.module.css';
|
||||||
|
|
||||||
export default function WebsiteSummary({ websiteId, startDate, endDate }) {
|
export default function WebsiteSummary({ websiteId, startDate, endDate }) {
|
||||||
const [data, setData] = useState({});
|
const [data, setData] = useState({});
|
||||||
const { pageviews, uniques, bounces } = data;
|
const { pageviews, uniques, bounces, totaltime } = data;
|
||||||
|
|
||||||
async function loadData() {
|
async function loadData() {
|
||||||
setData(
|
setData(
|
||||||
@ -29,6 +30,11 @@ export default function WebsiteSummary({ websiteId, startDate, endDate }) {
|
|||||||
value={uniques ? (bounces / uniques) * 100 : 0}
|
value={uniques ? (bounces / uniques) * 100 : 0}
|
||||||
format={n => Number(n).toFixed(0) + '%'}
|
format={n => Number(n).toFixed(0) + '%'}
|
||||||
/>
|
/>
|
||||||
|
<MetricCard
|
||||||
|
label="Average visit time"
|
||||||
|
value={totaltime && pageviews ? totaltime / (pageviews - bounces) : 0}
|
||||||
|
format={n => formatShortTime(n, ['m', 's'], ' ')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
37
lib/db.js
37
lib/db.js
@ -184,28 +184,21 @@ export async function getSummary(website_id, start_at, end_at) {
|
|||||||
return runQuery(
|
return runQuery(
|
||||||
prisma.queryRaw(
|
prisma.queryRaw(
|
||||||
`
|
`
|
||||||
select
|
select sum(t.c) as "pageviews",
|
||||||
(select count(*)
|
count(distinct t.session_id) as "uniques",
|
||||||
from pageview
|
sum(case when t.c = 1 then t.c else 0 end) as "bounces",
|
||||||
where website_id=${website_id}
|
sum(t.time) as "totaltime"
|
||||||
and created_at between '${start_at}' and '${end_at}'
|
from (
|
||||||
) as "pageviews",
|
select session_id,
|
||||||
(select
|
date_trunc('hour', created_at),
|
||||||
count(distinct session_id)
|
count(*) c,
|
||||||
from pageview
|
floor(extract(epoch from max(created_at) - min(created_at))) as "time"
|
||||||
where website_id=${website_id}
|
from pageview
|
||||||
and created_at between '${start_at}' and '${end_at}'
|
where website_id=${website_id}
|
||||||
) as "uniques",
|
and created_at between '${start_at}' and '${end_at}'
|
||||||
(select sum(t.c) from
|
group by 1, 2
|
||||||
(select count(*) c
|
) t;
|
||||||
from pageview
|
`,
|
||||||
where website_id=${website_id}
|
|
||||||
and created_at between '${start_at}' and '${end_at}'
|
|
||||||
group by session_id
|
|
||||||
having count(*) = 1
|
|
||||||
) t
|
|
||||||
) as "bounces"
|
|
||||||
`,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
41
lib/format.js
Normal file
41
lib/format.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
export function parseTime(val) {
|
||||||
|
const days = ~~(val / 86400);
|
||||||
|
const hours = ~~(val / 3600) - days * 24;
|
||||||
|
const minutes = ~~(val / 60) - days * 1440 - hours * 60;
|
||||||
|
const seconds = ~~val - days * 86400 - hours * 3600 - minutes * 60;
|
||||||
|
const ms = (val - ~~val) * 1000;
|
||||||
|
|
||||||
|
return {
|
||||||
|
days,
|
||||||
|
hours,
|
||||||
|
minutes,
|
||||||
|
seconds,
|
||||||
|
ms,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatTime(val) {
|
||||||
|
const { hour, minutes, seconds } = parseTime(val);
|
||||||
|
const h = hour > 0 ? `${hour}:` : '';
|
||||||
|
const m = hour > 0 ? minutes.toString().padStart(2, '0') : minutes;
|
||||||
|
const s = seconds.toString().padStart(2, '0');
|
||||||
|
|
||||||
|
return `${h}${m}:${s}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatShortTime(val, formats = ['m', 's'], space = '') {
|
||||||
|
if (val === 0) {
|
||||||
|
return `0${formats[formats.length - 1]}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { days, hours, minutes, seconds, ms } = parseTime(val);
|
||||||
|
let t = '';
|
||||||
|
|
||||||
|
if (days > 0 && formats.indexOf('d') !== -1) t += `${days}d${space}`;
|
||||||
|
if (hours > 0 && formats.indexOf('h') !== -1) t += `${hours}h${space}`;
|
||||||
|
if (minutes > 0 && formats.indexOf('m') !== -1) t += `${minutes}m${space}`;
|
||||||
|
if (seconds > 0 && formats.indexOf('s') !== -1) t += `${seconds}s${space}`;
|
||||||
|
if (ms > 0 && formats.indexOf('ms') !== -1) t += `${ms}ms`;
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
@ -13,5 +13,10 @@ export default async (req, res) => {
|
|||||||
format(new Date(+end_at), 'yyyy-MM-dd hh:mm:ss'),
|
format(new Date(+end_at), 'yyyy-MM-dd hh:mm:ss'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).json(summary[0]);
|
const stats = Object.keys(summary[0]).reduce((obj, key) => {
|
||||||
|
obj[key] = +summary[0][key];
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return res.status(200).json(stats);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user