diff --git a/src/app/(main)/websites/[websiteId]/WebsiteChart.tsx b/src/app/(main)/websites/[websiteId]/WebsiteChart.tsx index 48da23776c..fa5ab69423 100644 --- a/src/app/(main)/websites/[websiteId]/WebsiteChart.tsx +++ b/src/app/(main)/websites/[websiteId]/WebsiteChart.tsx @@ -1,6 +1,5 @@ import { useMemo } from 'react'; import PageviewsChart from 'components/metrics/PageviewsChart'; -import { getDateArray } from 'lib/date'; import useWebsitePageviews from 'components/hooks/queries/useWebsitePageviews'; import { useDateRange } from 'components/hooks'; @@ -19,8 +18,8 @@ export function WebsiteChart({ const chartData = useMemo(() => { if (data) { const result = { - pageviews: getDateArray(pageviews, startDate, endDate, unit), - sessions: getDateArray(sessions, startDate, endDate, unit), + pageviews, + sessions, }; if (compare) { @@ -43,7 +42,15 @@ export function WebsiteChart({ return { pageviews: [], sessions: [] }; }, [data, startDate, endDate, unit]); - return ; + return ( + + ); } export default WebsiteChart; diff --git a/src/components/charts/BarChart.tsx b/src/components/charts/BarChart.tsx index cfcbe74350..b96812210e 100644 --- a/src/components/charts/BarChart.tsx +++ b/src/components/charts/BarChart.tsx @@ -12,6 +12,8 @@ export interface BarChartProps extends ChartProps { renderYLabel?: (label: string, index: number, values: any[]) => string; XAxisType?: string; YAxisType?: string; + minDate?: number | string; + maxDate?: number | string; } export function BarChart(props: BarChartProps) { @@ -24,6 +26,8 @@ export function BarChart(props: BarChartProps) { XAxisType = 'time', YAxisType = 'linear', stacked = false, + minDate, + maxDate, } = props; const options: any = useMemo(() => { @@ -32,6 +36,8 @@ export function BarChart(props: BarChartProps) { x: { type: XAxisType, stacked: true, + min: minDate, + max: maxDate, time: { unit, }, diff --git a/src/components/metrics/EventsChart.tsx b/src/components/metrics/EventsChart.tsx index 0bb65eb298..ee7f866cb3 100644 --- a/src/components/metrics/EventsChart.tsx +++ b/src/components/metrics/EventsChart.tsx @@ -1,7 +1,6 @@ import { useMemo } from 'react'; import { colord } from 'colord'; import BarChart from 'components/charts/BarChart'; -import { getDateArray } from 'lib/date'; import { useLocale, useDateRange, useWebsiteEventsSeries } from 'components/hooks'; import { CHART_COLORS } from 'lib/constants'; import { renderDateLabels } from 'lib/charts'; @@ -31,10 +30,6 @@ export function EventsChart({ websiteId, className }: EventsChartProps) { return obj; }, {}); - Object.keys(map).forEach(key => { - map[key] = getDateArray(map[key], startDate, endDate, unit); - }); - return { datasets: Object.keys(map).map((key, index) => { const color = colord(CHART_COLORS[index % CHART_COLORS.length]); diff --git a/src/components/metrics/RealtimeChart.tsx b/src/components/metrics/RealtimeChart.tsx index b24eedb50c..b2819f9c88 100644 --- a/src/components/metrics/RealtimeChart.tsx +++ b/src/components/metrics/RealtimeChart.tsx @@ -1,7 +1,6 @@ import { useMemo, useRef } from 'react'; import { startOfMinute, subMinutes, isBefore } from 'date-fns'; import PageviewsChart from './PageviewsChart'; -import { getDateArray } from 'lib/date'; import { DEFAULT_ANIMATION_DURATION, REALTIME_RANGE } from 'lib/constants'; import { RealtimeData } from 'lib/types'; @@ -22,8 +21,8 @@ export function RealtimeChart({ data, unit, ...props }: RealtimeChartProps) { } return { - pageviews: getDateArray(data.series.views, startDate, endDate, unit), - sessions: getDateArray(data.series.visitors, startDate, endDate, unit), + pageviews: data.series.views, + sessions: data.series.visitors, }; }, [data, startDate, endDate, unit]); @@ -37,7 +36,14 @@ export function RealtimeChart({ data, unit, ...props }: RealtimeChartProps) { }, [endDate]); return ( - + ); } diff --git a/src/lib/date.ts b/src/lib/date.ts index b8bfa6c765..b731140cf2 100644 --- a/src/lib/date.ts +++ b/src/lib/date.ts @@ -273,19 +273,6 @@ export function getMinimumUnit(startDate: number | Date, endDate: number | Date) return 'year'; } -export function getDateFromString(str: string) { - const [ymd, hms] = str.split(' '); - const [year, month, day] = ymd.split('-'); - - if (hms) { - const [hour, min, sec] = hms.split(':'); - - return new Date(+year, +month - 1, +day, +hour, +min, +sec); - } - - return new Date(+year, +month - 1, +day); -} - export function getDateArray(data: any[], startDate: Date, endDate: Date, unit: string) { const arr = []; const { diff, add, start } = DATE_FUNCTIONS[unit]; diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts index c450f1f023..110b4750e2 100644 --- a/src/lib/prisma.ts +++ b/src/lib/prisma.ts @@ -12,19 +12,11 @@ import { filtersToArray } from './params'; const log = debug('umami:prisma'); const MYSQL_DATE_FORMATS = { - minute: '%Y-%m-%d %H:%i:00', - hour: '%Y-%m-%d %H:00:00', - day: '%Y-%m-%d', - month: '%Y-%m-01', - year: '%Y-01-01', -}; - -const POSTGRESQL_DATE_FORMATS = { - minute: 'YYYY-MM-DD HH24:MI:00', - hour: 'YYYY-MM-DD HH24:00:00', - day: 'YYYY-MM-DD', - month: 'YYYY-MM-01', - year: 'YYYY-01-01', + minute: '%Y-%m-%dT%H:%i:00Z', + hour: '%Y-%m-%dT%H:00:00Z', + day: '%Y-%m-%dT00:00:00Z', + month: '%Y-%m-01T00:00:00Z', + year: '%Y-01-01T00:00:00Z', }; function getAddIntervalQuery(field: string, interval: string): string { @@ -68,9 +60,9 @@ function getDateSQL(field: string, unit: string, timezone?: string): string { if (db === POSTGRESQL) { if (timezone) { - return `to_char(date_trunc('${unit}', ${field} at time zone '${timezone}'), '${POSTGRESQL_DATE_FORMATS[unit]}')`; + return `date_trunc('${unit}', ${field} at time zone '${timezone}')`; } - return `to_char(date_trunc('${unit}', ${field}), '${POSTGRESQL_DATE_FORMATS[unit]}')`; + return `date_trunc('${unit}', ${field})`; } if (db === MYSQL) { diff --git a/src/queries/analytics/sessions/getSessionStats.ts b/src/queries/analytics/sessions/getSessionStats.ts index ee16e42560..cd04976155 100644 --- a/src/queries/analytics/sessions/getSessionStats.ts +++ b/src/queries/analytics/sessions/getSessionStats.ts @@ -22,14 +22,21 @@ async function relationalQuery(websiteId: string, filters: QueryFilters) { return rawQuery( ` select - ${getDateSQL('website_event.created_at', unit, timezone)} x, - count(distinct website_event.session_id) y - from website_event + ${getDateSQL('g.created_at', unit, timezone)} as x, + count(distinct g.session_id) as y + from ( + select + website_event.session_id, + min(website_event.created_at) as created_at, + count(*) y + from website_event ${joinSession} - where website_event.website_id = {{websiteId::uuid}} + where website_event.website_id = {{websiteId::uuid}} and website_event.created_at between {{startDate}} and {{endDate}} - and event_type = {{eventType}} + and event_type = {{eventType}} ${filterQuery} + group by website_event.session_id, website_event.created_at + ) as g group by 1 `, params,