diff --git a/apps/webapp/app/components/primitives/Chart.tsx b/apps/webapp/app/components/primitives/Chart.tsx index b24b938c4..53d53c0ea 100644 --- a/apps/webapp/app/components/primitives/Chart.tsx +++ b/apps/webapp/app/components/primitives/Chart.tsx @@ -49,7 +49,7 @@ const ChartContainer = React.forwardRef< data-chart={chartId} ref={ref} className={cn( - "[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line-line]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none", + "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-text-dimmed/50 [&_.recharts-cartesian-grid_line]:stroke-grid-bright/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-grid-dimmed [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-grid-dimmed [&_.recharts-radial-bar-background-sector]:fill-grid-dimmed [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-grid-dimmed [&_.recharts-reference-line-line]:stroke-grid-dimmed [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none", className )} {...props} @@ -158,7 +158,7 @@ const ChartTooltipContent = React.forwardRef<
@@ -173,7 +173,7 @@ const ChartTooltipContent = React.forwardRef<
svg]:text-muted-foreground flex w-full items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5", + "flex w-full items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-text-dimmed", indicator === "dot" && "items-center" )} > @@ -207,18 +207,16 @@ const ChartTooltipContent = React.forwardRef< )}
{nestLabel ? tooltipLabel : null} - - {itemConfig?.label || item.name} - + {itemConfig?.label || item.name}
{item.value && ( - + {item.value.toLocaleString()} )} @@ -268,7 +266,7 @@ const ChartLegendContent = React.forwardRef<
svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3" + "flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-text-dimmed" )} > {itemConfig?.icon && !hideIcon ? ( diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.v3.usage/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.v3.usage/route.tsx index bf79275de..f18f4bc21 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.v3.usage/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.v3.usage/route.tsx @@ -3,7 +3,16 @@ import { Await } from "@remix-run/react"; import { LoaderFunctionArgs } from "@remix-run/server-runtime"; import { formatDurationMilliseconds } from "@trigger.dev/core/v3"; import { Suspense } from "react"; -import { Bar, BarChart, Rectangle, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts"; +import { + Bar, + BarChart, + CartesianGrid, + Rectangle, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from "recharts"; import { redirect, typeddefer, useTypedLoaderData } from "remix-typedjson"; import { UsageBar } from "~/components/billing/v3/UsageBar"; import { PageBody, PageContainer } from "~/components/layout/AppLayout"; @@ -26,7 +35,12 @@ import { requireUserId } from "~/services/session.server"; import { formatCurrency, formatCurrencyAccurate, formatNumber } from "~/utils/numberFormatter"; import { OrganizationParamsSchema, organizationPath } from "~/utils/pathBuilder"; import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route"; -import { ChartConfig } from "~/components/primitives/Chart"; +import { + ChartConfig, + ChartContainer, + ChartTooltip, + ChartTooltipContent, +} from "~/components/primitives/Chart"; export async function loader({ params, request }: LoaderFunctionArgs) { await requireUserId(request); @@ -227,25 +241,31 @@ const chartConfig = { } satisfies ChartConfig; function UsageChart({ data }: { data: UsageSeriesData }) { + const maxDollar = Math.max(...data.map((d) => d.dollars)); + const decimalPlaces = maxDollar < 1 ? 4 : 2; + return ( - + + { - if (!item.date) return ""; - const date = new Date(item.date); + tickMargin={10} + axisLine={false} + dataKey="date" + tickFormatter={(value) => { + if (!value) return ""; + const date = new Date(value); if (date.getDate() === 1) { return dateFormatter.format(date); } @@ -254,14 +274,14 @@ function UsageChart({ data }: { data: UsageSeriesData }) { className="text-xs" /> `$${value.toFixed(2)}`} + tickFormatter={(value) => `$${value.toFixed(decimalPlaces)}`} /> - { @@ -276,9 +296,24 @@ function UsageChart({ data }: { data: UsageSeriesData }) { const numValue = Number(value); return [` ${formatCurrencyAccurate(numValue)}`]; }} + /> */} + } + labelFormatter={(value, data) => { + const dateString = data.at(0)?.payload.date; + if (!dateString) { + return ""; + } + + return dateFormatter.format(new Date(dateString)); + }} + // formatter={(value) => { + // const numValue = Number(value); + // return [` ${formatCurrencyAccurate(numValue)}`]; + // }} /> - } /> + - + ); }