Skip to content

Commit

Permalink
Chart now supports every interval (1 day -> 90 days)
Browse files Browse the repository at this point in the history
  • Loading branch information
benvinegar committed Jan 13, 2024
1 parent 51c25b1 commit e1f0439
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 32 deletions.
44 changes: 18 additions & 26 deletions app/analytics/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,6 @@ export class AnalyticsEngineAPI {
}
}

getIntervalBucketSQLParams(sinceDays: number): [string, number] {
let intervalType = 'DAY';
let intervalCount = 1;

if (sinceDays < 7) {
intervalType = 'HOUR';
intervalCount = 24;
} else if (sinceDays <= 30) {
intervalType = 'DAY';
intervalCount = 1;
}
return [intervalType, intervalCount];
}

/**
* returns an object with keys of the form "YYYY-MM-DD HH:00:00" and values of 0
* example:
Expand All @@ -91,23 +77,24 @@ export class AnalyticsEngineAPI {
* }
*
* */
generateInitialRows(intervalType: string, intervalCount: number): any {
generateInitialRows(intervalType: string, daysAgo: number): any {
const startDateTime = new Date();
let intervalMs = 0;

console.log("intervalType", intervalType);
console.log("intervalCount", intervalCount);

// get start date in the past by subtracting interval * type
if (intervalType === 'DAY') {
// get intervalCount days in the past
startDateTime.setDate(startDateTime.getDate() - intervalCount);
startDateTime.setDate(startDateTime.getDate() - daysAgo);
startDateTime.setHours(0);

// assumes interval is 24 hours
intervalMs = 24 * 60 * 60 * 1000;

} else if (intervalType === 'HOUR') {
// get intervalCount hours in the past
startDateTime.setHours(startDateTime.getHours() - intervalCount);
startDateTime.setHours(startDateTime.getHours() - daysAgo * 24);

// assumes interval is hourly
intervalMs = 60 * 60 * 1000;
}

Expand All @@ -126,18 +113,23 @@ export class AnalyticsEngineAPI {
return initialRows;
}

async getViewsGroupedByInterval(siteId: string, sinceDays: number): Promise<any> {
async getViewsGroupedByInterval(siteId: string, intervalType: string, sinceDays: number): Promise<any> {
// defaults to 1 day if not specified
const interval = sinceDays || 1;
const siteIdColumn = ColumnMappings['siteId'];

const [intervalType, intervalCount] = this.getIntervalBucketSQLParams(sinceDays);

// get start date in the past by subtracting interval * type
const dataStartDate = new Date();
let intervalCount = 0;;
switch (intervalType) {
case 'DAY':
intervalCount = 1;
break;
case 'HOUR':
intervalCount = 24;
break;
}

// note interval count hard-coded to hours at the moment
const initialRows = this.generateInitialRows(intervalType, intervalCount);
const initialRows = this.generateInitialRows(intervalType, sinceDays);

// NOTE: when using toStartOfInterval, cannot group by other columns
// like double1 (isVisitor) or double2 (isSession/isVisit). This
Expand Down
13 changes: 10 additions & 3 deletions app/components/TimeSeriesChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ import PropTypes, { InferProps } from 'prop-types';

import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';

export default function TimeSeriesChart({ data }: InferProps<typeof TimeSeriesChart.propTypes>) {
export default function TimeSeriesChart({ data, intervalType }: InferProps<typeof TimeSeriesChart.propTypes>) {
// get the max integer value of data views
const maxViews = Math.max(...data.map((item: any) => item.views));

function dateFormatter(date: string, index: number): string {
const dateObj = new Date(date);

return dateObj.toLocaleDateString('en-us', { weekday: "short", month: "short", day: "numeric" });
switch (intervalType) {
case 'DAY':
return dateObj.toLocaleDateString('en-us', { weekday: "short", month: "short", day: "numeric" });
case 'HOUR':
return dateObj.toLocaleTimeString('en-us', { hour: "numeric", minute: "numeric" });
default:
throw new Error('Invalid interval type');
}
}
return (
<ResponsiveContainer width="100%" height="100%">
Expand Down Expand Up @@ -39,5 +46,5 @@ export default function TimeSeriesChart({ data }: InferProps<typeof TimeSeriesCh

TimeSeriesChart.propTypes = {
data: PropTypes.any,

intervalType: PropTypes.string
}
24 changes: 21 additions & 3 deletions app/routes/dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,24 @@ export const loader = async ({ context, request }: LoaderFunctionArgs) => {
const countByBrowser = analyticsEngine.getCountByBrowser(actualSiteId, interval);
const countByDevice = analyticsEngine.getCountByDevice(actualSiteId, interval);

const viewsGroupedByInterval = analyticsEngine.getViewsGroupedByInterval(actualSiteId, interval);
let intervalType = 'DAY';
switch (interval) {
case 1:
intervalType = 'HOUR';
break;
case 7:
intervalType = 'DAY';
break;
case 30:
intervalType = 'DAY';
break;
case 90:
intervalType = 'DAY';
break;
}
console.log(interval, intervalType);

const viewsGroupedByInterval = analyticsEngine.getViewsGroupedByInterval(actualSiteId, intervalType, interval);

return json({
siteId: siteId || '@unknown',
Expand All @@ -75,7 +92,8 @@ export const loader = async ({ context, request }: LoaderFunctionArgs) => {
countByCountry: await countByCountry,
countByReferrer: await countByReferrer,
countByDevice: await countByDevice,
viewsGroupedByInterval: await viewsGroupedByInterval
viewsGroupedByInterval: await viewsGroupedByInterval,
intervalType
});
};

Expand Down Expand Up @@ -173,7 +191,7 @@ export default function Dashboard() {
<Card>
<CardContent>
<div className="h-80 pt-6">
<TimeSeriesChart data={chartData}></TimeSeriesChart>
<TimeSeriesChart data={chartData} intervalType={data.intervalType}></TimeSeriesChart>
</div>
</CardContent>
</Card>
Expand Down

0 comments on commit e1f0439

Please sign in to comment.