Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved chart tooltip #125

Merged
merged 3 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 47 additions & 24 deletions app/components/TimeSeriesChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
ComposedChart,
} from "recharts";

import { Card } from "./ui/card";

interface TimeSeriesChartProps {
data: Array<{
date: string;
Expand All @@ -17,13 +19,52 @@
bounceRate: number;
}>;
intervalType?: string;
timezone?: string;
}

function dateStringToLocalDateObj(dateString: string): Date {
const date = new Date(dateString);
date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
return date;
}

function CustomTooltip(props: any) {

Check warning on line 30 in app/components/TimeSeriesChart.tsx

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
const { active, payload, label } = props;

const date = dateStringToLocalDateObj(label);

const formattedDate = date.toLocaleString("en-us", {
month: "short",
day: "numeric",
hour: "numeric",
minute: "numeric",
timeZoneName: "short",
});
if (active && payload && payload.length) {
return (
<Card className="p-2 shadow-lg leading-normal">
<div className="font-semibold">{formattedDate}</div>
<div className="before:content-['•'] before:text-barchart before:font-bold">
{" "}
{`${payload[0].value} views`}
</div>
<div className="before:content-['•'] before:text-border before:font-bold">
{" "}
{`${payload[1].value} visitors`}
</div>
<div className="before:content-['•'] before:text-paldarkgrey before:font-bold">
{" "}
{`${payload[2].value}% bounce rate`}
</div>
</Card>

Check warning on line 58 in app/components/TimeSeriesChart.tsx

View check run for this annotation

Codecov / codecov/patch

app/components/TimeSeriesChart.tsx#L43-L58

Added lines #L43 - L58 were not covered by tests
);
} else {
return null;
}
}

export default function TimeSeriesChart({
data,
intervalType,
timezone,
}: TimeSeriesChartProps) {
// chart doesn't really work no data points, so just bail out
if (data.length === 0) {
Expand All @@ -36,10 +77,7 @@
const maxViews = Math.max(...data.map((item) => item.views));

function xAxisDateFormatter(date: string): string {
const dateObj = new Date(date);

// convert from utc to local time
dateObj.setMinutes(dateObj.getMinutes() - dateObj.getTimezoneOffset());
const dateObj = dateStringToLocalDateObj(date);

switch (intervalType) {
case "DAY":
Expand All @@ -58,23 +96,6 @@
}
}

function tooltipDateFormatter(date: string): string {
const dateObj = new Date(date);

// convert from utc to local time
dateObj.setMinutes(dateObj.getMinutes() - dateObj.getTimezoneOffset());

return (
dateObj.toLocaleString("en-us", {
weekday: "short",
month: "short",
day: "numeric",
hour: "numeric",
minute: "numeric",
}) + ` ${timezone}`
);
}

return (
<ResponsiveContainer width="100%" height="100%" minWidth={100}>
<ComposedChart
Expand Down Expand Up @@ -104,7 +125,9 @@
hide={true}
/>

<Tooltip labelFormatter={tooltipDateFormatter} />
<Tooltip content={<CustomTooltip />} />

{/* NOTE: colors defined in globals.css/tailwind.config.js */}
<Area
yAxisId="count"
dataKey="views"
Expand Down
2 changes: 1 addition & 1 deletion app/components/ui/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const TableRow = React.forwardRef<
style={
width !== undefined
? {
background: `linear-gradient(90deg, #F7BA70 ${width}, transparent ${width})`,
background: `linear-gradient(90deg, hsl(var(--barchart)) ${width}, transparent ${width})`,
}
: {}
}
Expand Down
3 changes: 3 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
--destructive-foreground: 210 40% 98%;

--border: 15 90% 60%;
--barchart: 32.89 89.4% 70.39%;

--palette-darkgrey: 167.14, 14%, 39.22%;
--input: 15 90% 60%;
--ring: 222.2 84% 4.9%;

Expand Down
1 change: 0 additions & 1 deletion app/routes/resources.timeseries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ export const TimeSeriesCard = ({
<TimeSeriesChart
data={chartData}
intervalType={intervalType}
timezone={timezone}
/>
)}
</div>
Expand Down
3 changes: 3 additions & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
barchart: "hsl(var(--barchart))",

Check warning on line 33 in tailwind.config.ts

View check run for this annotation

Codecov / codecov/patch

tailwind.config.ts#L33

Added line #L33 was not covered by tests
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",

paldarkgrey: "hsl(var(--palette-darkgrey))", // palette

Check warning on line 37 in tailwind.config.ts

View check run for this annotation

Codecov / codecov/patch

tailwind.config.ts#L37

Added line #L37 was not covered by tests
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
Expand Down
Loading