Skip to content

Commit

Permalink
improve trend curve
Browse files Browse the repository at this point in the history
  • Loading branch information
sebald committed Nov 7, 2023
1 parent ea2f7a0 commit c62b6cb
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 13 deletions.
19 changes: 17 additions & 2 deletions __test__/lib/utils/date.utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import { toDate } from '@/lib/utils/date.utils';
import { monthRange, toDate } from '@/lib/utils/date.utils';

test('date range', () => {
test('to date range', () => {
expect(
toDate(new Date(2023, 0, 1), new Date(2023, 1, 1))
).toMatchInlineSnapshot(`"2023-01-01/2023-02-01"`);
expect(toDate(new Date(2023, 0, 1))).toMatchInlineSnapshot(`"2023-01-01"`);
});

test('create date range', () => {
expect(
monthRange(new Date(2000, 0, 1), new Date(2000, 5, 1))).
toMatchInlineSnapshot(`
[
"2000-01",
"2000-02",
"2000-03",
"2000-04",
"2000-05",
"2000-06",
]
`);
});
42 changes: 33 additions & 9 deletions app/(stats)/composition/[id]/_component/trend-curve.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
'use client';

import { toPercentage } from '@/lib/utils';
import { formatMonth } from '@/lib/utils/date.utils';
import {
formatMonth,
fromDate,
monthRange,
today,
} from '@/lib/utils/date.utils';
import { linearGradientDef } from '@nivo/core';
import { ResponsiveLine } from '@nivo/line';

// Props
// ---------------
export interface TrendCurveProps {
/**
* Date format 'YYYY-MM-DD'
*/
from: string;
/**
* Date format 'YYYY-MM-DD'
*/
to?: string;
value: {
/**
* Date format YYYY-MM
Expand All @@ -20,12 +33,16 @@ export interface TrendCurveProps {

// Components
// ---------------
export const TrendCurve = ({ value }: TrendCurveProps) => {
const data = value.map(({ date, percentile, count }) => ({
x: date,
y: percentile,
count,
}));
export const TrendCurve = ({ from, to, value }: TrendCurveProps) => {
const range = monthRange(fromDate(from), to ? fromDate(to) : today());
const data = range.map(month => {
const datum = value.find(v => v.date === month);
return {
x: month,
y: datum?.percentile,
count: datum?.count || 0,
};
});

return (
<div className="grid h-64 auto-cols-fr">
Expand Down Expand Up @@ -55,10 +72,17 @@ export const TrendCurve = ({ value }: TrendCurveProps) => {
pointLabel={data =>
`${toPercentage(data.y as number)} (${(data as any).count})`
}
pointSymbol={({ datum }) => (
<circle
r={5 * Math.max(Math.log(datum.count), 1)}
fill="#5155b1"
style={{ pointerEvents: 'none' }}
/>
)}
pointLabelYOffset={-15}
enablePointLabel
enableArea
enableGridX={false}
pointSize={8}
defs={[
linearGradientDef('gradient', [
{ offset: 0, color: '#5155b1' },
Expand All @@ -67,7 +91,7 @@ export const TrendCurve = ({ value }: TrendCurveProps) => {
]}
colors="#5155b1"
fill={[{ match: '*', id: 'gradient' }]}
margin={{ top: 20, right: 30, bottom: 30, left: 60 }}
margin={{ top: 30, right: 30, bottom: 30, left: 60 }}
isInteractive={false}
animate={false}
/>
Expand Down
2 changes: 1 addition & 1 deletion app/(stats)/composition/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ const Page = async ({ params }: PageParams) => {
<Card.Title>Trend</Card.Title>
</Card.Header>
<Card.Body>
<TrendCurve value={stats.trend} />
<TrendCurve from={pointsUpdateDate} value={stats.trend} />
</Card.Body>
</Card>
</div>
Expand Down
18 changes: 17 additions & 1 deletion lib/utils/date.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,23 @@ export const formatDate = (date: Date) => {
};

/**
* Formats motn date ('YYYY-MM') to a human readable format.
* Formats month date ('YYYY-MM') to a human readable format.
*/
export const formatMonth = (val: string) =>
dayjs(val, 'YYYY-MM').format('MMM YY');

/**
* Creates a list of months, formatted 'YYYY-MM'.
*/
export const monthRange = (from: Date, to: Date) => {
let current = dayjs(from).startOf('month');
const end = dayjs(to).startOf('month');
const range = [current.format('YYYY-MM')];

while (current.isBefore(end)) {
current = current.add(1, 'month');
range.push(current.format('YYYY-MM'));
}

return range;
};

0 comments on commit c62b6cb

Please sign in to comment.