Koala logo Design

Charts

The Portal uses ApexCharts via CDN for data visualisation. Charts are initialised with vanilla JavaScript using data- attributes, not Alpine.js components.

Sparkline charts

Small inline trend lines rendered as SVG polylines inside stat cards on the dashboard. Each sparkline reads its data from data-sparkline, colour from data-sparkline-color, and optional labels from data-sparkline-labels. These are custom SVG sparklines, not ApexCharts.

New
24 +3
Accepted
18 +5
Expired
6 0
Cancelled
2 -1
<!-- Sparkline container in a stat card -->
<div class="w-14 sm:w-20 h-8 flex-shrink-0"
     data-sparkline="[2,5,3,8,6,12,9,15,11,18,14,24]"
     data-sparkline-color="#6B7280"
     data-sparkline-title="New"
     data-sparkline-labels='["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]'>
</div>

<!-- The Layout script reads data-sparkline and renders an SVG polyline -->
<!-- with hover tooltips showing the title + value -->

Area charts (ApexCharts)

Fee breakdown charts on the dashboard and partner detail pages use ApexCharts with the data-apex-chart attribute. Chart data is passed via data-chart-data as a JSON array of objects with label, totalFees, and referralFees properties.

Fees

<!-- Razor page -->
<div data-apex-chart
     data-chart-data="@Html.Raw(System.Text.Encodings.Web.HtmlEncoder.Default.Encode(
         Json.Serialize(Model.ChartData).ToString()!))">
</div>

<!-- ChartData is IReadOnlyList<ChartDataPoint> -->
<!-- Each point has: label (string), totalFees (decimal), referralFees (decimal) -->

<!-- The Layout script reads data-chart-data and creates an ApexCharts area chart -->
<!-- with custom tooltips, crosshair, dark mode support, and responsive tick amounts -->

Chart configuration pattern

Charts are initialised in the Portal's _Layout.cshtml script block, not in individual pages. The script queries all [data-apex-chart] elements and creates ApexCharts instances.

<!-- _Layout.cshtml script block -->
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>

document.querySelectorAll('[data-apex-chart]').forEach(function (el) {
    var raw = el.getAttribute('data-chart-data');
    var chartData = JSON.parse(raw);
    var isDark = document.documentElement.classList.contains('dark');

    var chart = new ApexCharts(el, {
        chart: {
            type: 'area',
            height: 300,
            fontFamily: 'Inter, sans-serif',
            toolbar: { show: false },
            zoom: { enabled: false },
            background: 'transparent'
        },
        series: [
            { name: 'Gross fees', data: chartData.map(p => p.totalFees) },
            { name: 'Referral fees', data: chartData.map(p => p.referralFees) }
        ],
        xaxis: {
            categories: chartData.map(p => p.label),
            labels: { style: { colors: isDark ? '#9CA3AF' : '#6B7280' } }
        },
        yaxis: {
            labels: {
                formatter: val => '\u00A3' + val.toLocaleString('en-GB'),
                style: { colors: isDark ? '#9CA3AF' : '#6B7280' }
            }
        },
        colors: ['#6B8E73', '#B8860B'],
        fill: { type: 'gradient', gradient: { opacityFrom: 0.55, opacityTo: 0.0 } },
        stroke: { curve: 'smooth', width: 3 },
        theme: { mode: isDark ? 'dark' : 'light' }
    });
    chart.render();
});

Dark mode integration

Charts detect dark mode at render time via document.documentElement.classList.contains('dark'). Key dark mode adjustments:

Property Light Dark
Axis label colour #6B7280 (gray-500) #9CA3AF (gray-400)
Theme mode 'light' 'dark'
Tooltip background bg-white bg-gray-700
Chart background transparent (inherits card bg)

Tooltip CSS override

The default ApexCharts tooltip is hidden via CSS in the layout. Custom floating tooltips are rendered as absolutely-positioned DOM elements managed by JavaScript event handlers.

<!-- _Layout.cshtml style block -->
.apexcharts-tooltip {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    padding: 0 !important;
}

<!-- Custom tooltips are created as fixed DOM elements -->
<!-- with classes: fixed z-50 px-2.5 py-1.5 text-sm rounded-lg -->
<!-- bg-white dark:bg-gray-700 border border-gray-200 -->
<!-- dark:border-gray-600 shadow-md pointer-events-none -->