charts/chartjs
>

return function () {
    $self = url('/@object/@action/' . urlencode('charts/chartjs'));
    $charts = _class('charts');
    $intro = '<p class="docs-demo-intro">Charts from PHP arrays with <code>_class(\'charts\')->chartjs($type, $data, $extra)</code>, the Chart.js
        driver of the charts plugin (Chart.js 4, MIT, asset <code>chartjs</code>, vendored). The data is passed to the page as JSON, never
        as JavaScript, so labels from a database cannot inject script. Pick a chart type for the first chart: the type comes from a fixed
        list. The data is inline sample data. Classes: <code>yf_charts</code>, <code>yf_charts_plugin_chartjs</code>.</p>';
    $types = ['bar' => 'Bar', 'line' => 'Line', 'radar' => 'Radar'];
    $type = is_string($_GET['type'] ?? null) && isset($types[$_GET['type']]) ? $_GET['type'] : 'bar';
    $links = '';
    foreach ($types as $t => $label) {
        $links .= '<a class="btn btn-sm ' . ($t === $type ? 'btn-primary active' : 'btn-default btn-outline-primary') . '" href="' . $self . '?type=' . $t . '">' . $label . '</a> ';
    }
    // two series: [series name => [label => value]]
    $visits = [
        'Visits' => ['Jan' => 1200, 'Feb' => 1350, 'Mar' => 1610, 'Apr' => 1580, 'May' => 1820, 'Jun' => 2050],
        'Orders' => ['Jan' => 310, 'Feb' => 290, 'Mar' => 420, 'Apr' => 460, 'May' => 510, 'Jun' => 640],
    ];
    // one series: [label => value], here counted from the shipped product sample data
    $by_colour = [];
    foreach (_class('sample_products', YF_PATH . '.dev/samples/classes/')->load() as $row) {
        $by_colour[$row['colour']] = ($by_colour[$row['colour']] ?? 0) + 1;
    }
    arsort($by_colour);
    $rate = ['2025-07' => 0.857, '2025-08' => 0.861, '2025-09' => 0.853, '2025-10' => 0.862, '2025-11' => 0.866, '2025-12' => 0.851];
    return $intro
        . '<p class="docs-demo-chart-types">' . $links . '</p>'
        . '<div class="row"><div class="col-md-12">' . $charts->chartjs($type, $visits, ['title' => 'Visits and orders, first half year', 'height' => 280]) . '</div></div>'
        . '<div class="row docs-demo-charts"><div class="col-md-6">' . $charts->chartjs('doughnut', $by_colour, ['title' => 'Sample products by colour', 'height' => 260]) . '</div>'
        . '<div class="col-md-6">' . $charts->chartjs('line', ['USD to EUR' => $rate], ['title' => 'USD to EUR (sample)', 'height' => 260, 'fill' => true, 'colors' => ['#6f42c1']]) . '</div></div>';
};

Charts from PHP arrays with _class('charts')->chartjs($type, $data, $extra), the Chart.js driver of the charts plugin (Chart.js 4, MIT, asset chartjs, vendored). The data is passed to the page as JSON, never as JavaScript, so labels from a database cannot inject script. Pick a chart type for the first chart: the type comes from a fixed list. The data is inline sample data. Classes: yf_charts, yf_charts_plugin_chartjs.

Bar Line Radar