diff --git a/site/jest.config.ts b/site/jest.config.ts index a07fa22246..887b91fb9d 100644 --- a/site/jest.config.ts +++ b/site/jest.config.ts @@ -40,9 +40,7 @@ module.exports = { // can see many act warnings that may can help us to find the issue. "/usePaginatedQuery.test.ts", ], - transformIgnorePatterns: [ - "/node_modules/@chartjs-adapter-date-fns", - ], + transformIgnorePatterns: [], moduleDirectories: ["node_modules", "/src"], moduleNameMapper: { "\\.css$": "/src/testHelpers/styleMock.ts", diff --git a/site/package.json b/site/package.json index 5c74070e93..6483f207ac 100644 --- a/site/package.json +++ b/site/package.json @@ -78,8 +78,6 @@ "@xterm/xterm": "5.5.0", "ansi-to-html": "0.7.2", "axios": "1.8.2", - "chart.js": "4.4.0", - "chartjs-adapter-date-fns": "3.0.0", "chroma-js": "2.4.2", "class-variance-authority": "0.7.1", "clsx": "2.1.1", @@ -99,7 +97,6 @@ "monaco-editor": "0.52.0", "pretty-bytes": "6.1.1", "react": "18.3.1", - "react-chartjs-2": "5.3.0", "react-color": "2.19.3", "react-confetti": "6.2.2", "react-date-range": "1.4.0", diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml index d7b57631e8..d4be944fa4 100644 --- a/site/pnpm-lock.yaml +++ b/site/pnpm-lock.yaml @@ -145,12 +145,6 @@ importers: axios: specifier: 1.8.2 version: 1.8.2 - chart.js: - specifier: 4.4.0 - version: 4.4.0 - chartjs-adapter-date-fns: - specifier: 3.0.0 - version: 3.0.0(chart.js@4.4.0)(date-fns@2.30.0) chroma-js: specifier: 2.4.2 version: 2.4.2 @@ -208,9 +202,6 @@ importers: react: specifier: 18.3.1 version: 18.3.1 - react-chartjs-2: - specifier: 5.3.0 - version: 5.3.0(chart.js@4.4.0)(react@18.3.1) react-color: specifier: 2.19.3 version: 2.19.3(react@18.3.1) @@ -1253,9 +1244,6 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, tarball: https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz} - '@kurkle/color@0.3.2': - resolution: {integrity: sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==, tarball: https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz} - '@leeoniya/ufuzzy@1.0.10': resolution: {integrity: sha512-OR1yiyN8cKBn5UiHjKHUl0LcrTQt4vZPUpIf96qIIZVLxgd4xyASuRvTZ3tjbWvuyQAMgvKsq61Nwu131YyHnA==, tarball: https://registry.npmjs.org/@leeoniya/ufuzzy/-/ufuzzy-1.0.10.tgz} @@ -3122,16 +3110,6 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==, tarball: https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz} - chart.js@4.4.0: - resolution: {integrity: sha512-vQEj6d+z0dcsKLlQvbKIMYFHd3t8W/7L2vfJIbYcfyPcRx92CsHqECpueN8qVGNlKyDcr5wBrYAYKnfu/9Q1hQ==, tarball: https://registry.npmjs.org/chart.js/-/chart.js-4.4.0.tgz} - engines: {pnpm: '>=7'} - - chartjs-adapter-date-fns@3.0.0: - resolution: {integrity: sha512-Rs3iEB3Q5pJ973J93OBTpnP7qoGwvq3nUnoMdtxO+9aoJof7UFcRbWcIDteXuYd1fgAvct/32T9qaLyLuZVwCg==, tarball: https://registry.npmjs.org/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-3.0.0.tgz} - peerDependencies: - chart.js: '>=2.8.0' - date-fns: '>=2.0.0' - check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==, tarball: https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz} engines: {node: '>= 16'} @@ -5306,12 +5284,6 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==, tarball: https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz} engines: {node: '>= 0.8'} - react-chartjs-2@5.3.0: - resolution: {integrity: sha512-UfZZFnDsERI3c3CZGxzvNJd02SHjaSJ8kgW1djn65H1KK8rehwTjyrRKOG3VTMG8wtHZ5rgAO5oTHtHi9GCCmw==, tarball: https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-5.3.0.tgz} - peerDependencies: - chart.js: ^4.1.1 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-color@2.19.3: resolution: {integrity: sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==, tarball: https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz} peerDependencies: @@ -7362,8 +7334,6 @@ snapshots: '@jridgewell/sourcemap-codec': 1.5.0 optional: true - '@kurkle/color@0.3.2': {} - '@leeoniya/ufuzzy@1.0.10': {} '@mdx-js/react@3.0.1(@types/react@18.3.12)(react@18.3.1)': @@ -9356,15 +9326,6 @@ snapshots: character-reference-invalid@2.0.1: {} - chart.js@4.4.0: - dependencies: - '@kurkle/color': 0.3.2 - - chartjs-adapter-date-fns@3.0.0(chart.js@4.4.0)(date-fns@2.30.0): - dependencies: - chart.js: 4.4.0 - date-fns: 2.30.0 - check-error@2.1.1: {} chokidar@3.6.0: @@ -12148,11 +12109,6 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - react-chartjs-2@5.3.0(chart.js@4.4.0)(react@18.3.1): - dependencies: - chart.js: 4.4.0 - react: 18.3.1 - react-color@2.19.3(react@18.3.1): dependencies: '@icons/material': 0.2.4(react@18.3.1) diff --git a/site/src/components/ActiveUserChart/ActiveUserChart.stories.tsx b/site/src/components/ActiveUserChart/ActiveUserChart.stories.tsx index 4f28d7243a..f4961f0ced 100644 --- a/site/src/components/ActiveUserChart/ActiveUserChart.stories.tsx +++ b/site/src/components/ActiveUserChart/ActiveUserChart.stories.tsx @@ -6,19 +6,37 @@ const meta: Meta = { component: ActiveUserChart, args: { data: [ - { date: "1/1/2024", amount: 5 }, - { date: "1/2/2024", amount: 6 }, - { date: "1/3/2024", amount: 7 }, - { date: "1/4/2024", amount: 8 }, - { date: "1/5/2024", amount: 9 }, - { date: "1/6/2024", amount: 10 }, - { date: "1/7/2024", amount: 11 }, + { date: "2024-01-01", amount: 5 }, + { date: "2024-01-02", amount: 6 }, + { date: "2024-01-03", amount: 7 }, + { date: "2024-01-04", amount: 8 }, + { date: "2024-01-05", amount: 9 }, + { date: "2024-01-06", amount: 10 }, + { date: "2024-01-07", amount: 11 }, ], - interval: "day", }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], }; export default meta; type Story = StoryObj; export const Example: Story = {}; + +export const ManyDataPoints: Story = { + args: { + data: Array.from({ length: 30 }).map((_, i) => { + const date = new Date(2024, 0, i + 1); + return { + date: date.toISOString().split("T")[0], + amount: 5 + Math.floor(Math.random() * 15), + }; + }), + }, +}; diff --git a/site/src/components/ActiveUserChart/ActiveUserChart.tsx b/site/src/components/ActiveUserChart/ActiveUserChart.tsx index 41345ea8f0..faf92a8238 100644 --- a/site/src/components/ActiveUserChart/ActiveUserChart.tsx +++ b/site/src/components/ActiveUserChart/ActiveUserChart.tsx @@ -1,19 +1,9 @@ -import "chartjs-adapter-date-fns"; -import { useTheme } from "@emotion/react"; import { - CategoryScale, - Chart as ChartJS, - type ChartOptions, - Filler, - Legend, - LineElement, - LinearScale, - PointElement, - TimeScale, - Title, - Tooltip, - defaults, -} from "chart.js"; + type ChartConfig, + ChartContainer, + ChartTooltip, + ChartTooltipContent, +} from "components/Chart/Chart"; import { HelpTooltip, HelpTooltipContent, @@ -21,95 +11,99 @@ import { HelpTooltipTitle, HelpTooltipTrigger, } from "components/HelpTooltip/HelpTooltip"; -import dayjs from "dayjs"; import type { FC } from "react"; -import { Line } from "react-chartjs-2"; - -ChartJS.register( - CategoryScale, - LinearScale, - TimeScale, - LineElement, - PointElement, - Filler, - Title, - Tooltip, - Legend, -); +import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts"; +const chartConfig = { + amount: { + label: "Active Users", + color: "hsl(var(--highlight-purple))", + }, +} satisfies ChartConfig; export interface ActiveUserChartProps { - data: readonly { date: string; amount: number }[]; - interval: "day" | "week"; + data: { date: string; amount: number }[]; } -export const ActiveUserChart: FC = ({ - data, - interval, -}) => { - const theme = useTheme(); - - const labels = data.map((val) => dayjs(val.date).format("YYYY-MM-DD")); - const chartData = data.map((val) => val.amount); - - defaults.font.family = theme.typography.fontFamily as string; - defaults.color = theme.palette.text.secondary; - - const options: ChartOptions<"line"> = { - responsive: true, - animation: false, - plugins: { - legend: { - display: false, - }, - tooltip: { - displayColors: false, - callbacks: { - title: (context) => { - const date = new Date(context[0].parsed.x); - return date.toLocaleDateString(); - }, - }, - }, - }, - scales: { - y: { - grid: { color: theme.palette.divider }, - suggestedMin: 0, - ticks: { - precision: 0, - }, - }, - x: { - grid: { color: theme.palette.divider }, - ticks: { - stepSize: data.length > 10 ? 2 : undefined, - }, - type: "time", - time: { - unit: interval, - }, - }, - }, - maintainAspectRatio: false, - }; - +export const ActiveUserChart: FC = ({ data }) => { return ( - + + + + + new Date(value).toLocaleDateString(undefined, { + month: "short", + day: "numeric", + }) + } + /> + { + return value === 0 ? "" : value.toLocaleString(); + }} + /> + { + const item = p[0]; + return `${item.value} active users`; + }} + formatter={(v, n, item) => { + const date = new Date(item.payload.date); + return date.toLocaleString(undefined, { + month: "long", + day: "2-digit", + }); + }} + /> + } + /> + + + + + + + + + + ); }; diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx index 8aa1ac57a5..081d49c68c 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx @@ -257,7 +257,6 @@ const ActiveUsersPanel: FC = ({ {data && data.length === 0 && } {data && data.length > 0 && ( ({ amount: d.active_users, date: d.start_time,