fix: convert areachart to working barchart in trend-chart.svelte and fixed empty data issue (#930)

Co-authored-by: richarddkenneth <richard-kenneth@users.noreply.github.com>
This commit is contained in:
Richard Kenneth
2026-08-18 17:20:57 +01:00
committed by GitHub
co-authored by richarddkenneth
parent 913db2a525
commit ce663fe365
9 changed files with 210 additions and 169 deletions
@@ -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));
</script>
<AnalyticsPanelCard title={$t('analytics.trend.heading')} description={$t('analytics.trend.description')}>
{#snippet children()}
{#if loading && !data}
{#if loading && !chartData}
<div class="flex h-[280px] items-center justify-center">
<Spinner class="ui:text-muted-foreground size-6" />
</div>
{:else if browser && hasData && data}
{:else if browser && hasData && chartData}
{#await loadChart() then C}
<C.ChartContainer class="h-[280px] w-full" config={chartConfig}>
<C.AreaChart data={data.sparkline} x="date" axis="x" {series} />
<C.BarChart
data={chartData}
xScale={C.scaleBand().padding(0.25)}
x="date"
axis="x"
seriesLayout="group"
legend
{series}
props={{
xAxis: {
format: (d: Date) =>
d.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric'
})
}
}}
>
{#snippet tooltip()}
<C.Tooltip
labelFormatter={(d: Date) =>
d.toLocaleDateString('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
})}
/>
{/snippet}
</C.BarChart>
</C.ChartContainer>
{/await}
{:else if hasData && data}
{:else if hasData && chartData}
<div class="flex h-[280px] items-center justify-center">
<Spinner class="ui:text-muted-foreground size-6" />
</div>
@@ -1,5 +1,4 @@
<script lang="ts">
import { onMount } from 'svelte';
import { t } from '$lib/utils/functions/translations';
import { currentOrg } from '$lib/utils/store/org';
import * as Page from '@cio/ui/base/page';
@@ -15,9 +14,8 @@
analyticsApi
} from '$features/analytics';
onMount(() => {
const orgId = $currentOrg.id;
if (orgId) analyticsApi.ensureFetched(orgId);
$effect(() => {
analyticsApi.ensureFetched($currentOrg.id);
});
function handleRangeChange(days: 7 | 30 | 90) {
@@ -1,5 +1,4 @@
<script lang="ts">
import { onMount } from 'svelte';
import { t } from '$lib/utils/functions/translations';
import { currentOrg } from '$lib/utils/store/org';
import * as Page from '@cio/ui/base/page';
@@ -10,9 +9,8 @@
import { StatusTiles, CourseBreakdown, LearnersTable, complianceApi } from '$features/compliance';
import type { ComplianceLearnerRow } from '$features/compliance/utils/types';
onMount(() => {
const orgId = $currentOrg.id;
if (orgId) complianceApi.ensureFetched(orgId);
$effect(() => {
complianceApi.ensureFetched($currentOrg.id);
});
function handleRefresh() {