diff --git a/apps/dashboard/src/lib/features/analytics/components/trend-chart.svelte b/apps/dashboard/src/lib/features/analytics/components/trend-chart.svelte index 055047cb..640e5b80 100644 --- a/apps/dashboard/src/lib/features/analytics/components/trend-chart.svelte +++ b/apps/dashboard/src/lib/features/analytics/components/trend-chart.svelte @@ -26,37 +26,80 @@ const chartConfig = $derived({ views: { label: $t('analytics.trend.views'), - color: 'var(--primary)' + color: 'var(--chart-4)' }, enrollments: { label: $t('analytics.trend.enrollments'), - color: 'var(--chart-2, var(--primary))' + color: 'var(--chart-2)' } } satisfies ChartConfig); - const series = [ - { key: 'views', value: 'views', label: 'Views', color: 'var(--color-views)' }, - { key: 'enrollments', value: 'enrollments', label: 'Enrollments', color: 'var(--color-enrollments)' } - ]; + const series = $derived([ + { + key: 'views', + label: chartConfig.views.label, + color: chartConfig.views.color + }, + { + key: 'enrollments', + label: chartConfig.enrollments.label, + color: chartConfig.enrollments.color + } + ]); - const hasData = $derived( - (data?.sparkline.length ?? 0) > 0 && data?.sparkline.some((r) => r.views > 0 || r.enrollments > 0) + let chartData = $derived( + data?.sparkline.map((d) => { + const [year, month, day] = d.date.split('-'); + const date = new Date(Number(year), Number(month) - 1, Number(day)); + return { ...d, date }; + }) ); + + const hasData = $derived((chartData?.length ?? 0) > 0 && chartData?.some((r) => r.views > 0 || r.enrollments > 0)); {#snippet children()} - {#if loading && !data} + {#if loading && !chartData}
- {:else if browser && hasData && data} + {:else if browser && hasData && chartData} {#await loadChart() then C} - + + d.toLocaleDateString('en-US', { + month: 'short', + day: 'numeric' + }) + } + }} + > + {#snippet tooltip()} + + d.toLocaleDateString('en-US', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + })} + /> + {/snippet} + {/await} - {:else if hasData && data} + {:else if hasData && chartData}
diff --git a/apps/dashboard/src/routes/(app)/org/[slug]/analytics/+page.svelte b/apps/dashboard/src/routes/(app)/org/[slug]/analytics/+page.svelte index 63683bf8..d873ed52 100644 --- a/apps/dashboard/src/routes/(app)/org/[slug]/analytics/+page.svelte +++ b/apps/dashboard/src/routes/(app)/org/[slug]/analytics/+page.svelte @@ -1,5 +1,4 @@ {#snippet TooltipLabel()} @@ -85,6 +97,7 @@
- {#each tooltipCtx.payload as item, i (item.key + i)} - {@const key = `${nameKey || item.key || item.name || 'value'}`} - {@const itemConfig = getPayloadConfigFromPayload(chart.config, item, key)} - {@const indicatorColor = color || item.payload?.color || item.color} + {#each visibleSeries as item, i (item.key + i)} + {@const key = `${nameKey || item.key || item.label || 'value'}`} + {@const itemConfig = getPayloadConfigFromPayload(chart.config, item, key, chartCtx.tooltip.data)} + {@const indicatorColor = color || item.config?.color || item.color}
svg]:text-muted-foreground ui:flex ui:w-full ui:flex-wrap ui:items-stretch ui:gap-2 ui:[&>svg]:size-2.5', indicator === 'dot' && 'ui:items-center' )} > - {#if formatter && item.value !== undefined && item.name} + {#if formatter && item.value !== undefined && item.label} {@render formatter({ value: item.value, - name: item.name, + name: item.label, item, index: i, - payload: tooltipCtx.payload + payload: visibleSeries })} {:else} {#if itemConfig?.icon} @@ -138,7 +151,7 @@ {@render TooltipLabel()} {/if} - {itemConfig?.label || item.name} + {itemConfig?.label || item.label}
{#if item.value !== undefined} diff --git a/packages/ui/src/base/chart/chart-utils.ts b/packages/ui/src/base/chart/chart-utils.ts index d86976e4..6910f5fb 100644 --- a/packages/ui/src/base/chart/chart-utils.ts +++ b/packages/ui/src/base/chart/chart-utils.ts @@ -1,5 +1,5 @@ import type { Tooltip } from 'layerchart'; -import { getContext, setContext, type Component, type ComponentProps, type Snippet } from 'svelte'; +import { getContext, setContext, type Snippet } from 'svelte'; import type { ChartConfig } from './types'; export type { ChartConfig } from './types'; @@ -14,31 +14,37 @@ export type ChartLegendItem = { export type ExtractSnippetParams = T extends Snippet<[infer P]> ? P : never; -export type TooltipPayload = ExtractSnippetParams['children']>['payload'][number]; +export type TooltipPayload = Tooltip.TooltipSeries; // Helper to extract item config from a payload. -export function getPayloadConfigFromPayload(config: ChartConfig, payload: TooltipPayload, key: string) { +export function getPayloadConfigFromPayload( + config: ChartConfig, + payload: TooltipPayload, + key: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + data?: Record | null +) { if (typeof payload !== 'object' || payload === null) return undefined; - const payloadPayload = - 'payload' in payload && typeof payload.payload === 'object' && payload.payload !== null - ? payload.payload - : undefined; + const payloadConfig = + 'config' in payload && typeof payload.config === 'object' && payload.config !== null ? payload.config : undefined; let configLabelKey: string = key; if (payload.key === key) { configLabelKey = payload.key; - } else if (payload.name === key) { - configLabelKey = payload.name; + } else if (payload.label === key) { + configLabelKey = payload.label; } else if (key in payload && typeof payload[key as keyof typeof payload] === 'string') { configLabelKey = payload[key as keyof typeof payload] as string; } else if ( - payloadPayload !== undefined && - key in payloadPayload && - typeof payloadPayload[key as keyof typeof payloadPayload] === 'string' + payloadConfig !== undefined && + key in payloadConfig && + typeof payloadConfig[key as keyof typeof payloadConfig] === 'string' ) { - configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string; + configLabelKey = payloadConfig[key as keyof typeof payloadConfig] as string; + } else if (data != null && key in data && typeof data[key] === 'string') { + configLabelKey = data[key] as string; } return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config]; diff --git a/patches/layerchart@2.0.0-next.27.patch b/patches/layerchart@2.0.0-next.27.patch deleted file mode 100644 index 51be7801..00000000 --- a/patches/layerchart@2.0.0-next.27.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git a/dist/components/MonthPath.svelte b/dist/components/MonthPath.svelte -index 3ca6c1ec5bf10f2ebacceb0743d7844860bac057..5e3d4246a5d66b4643839c749eee00c8319c788c 100644 ---- a/dist/components/MonthPath.svelte -+++ b/dist/components/MonthPath.svelte -@@ -30,7 +30,7 @@ - - -