You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel Filament中用ChartJS创建堆叠柱状图及问题排查

Laravel Filament 堆叠柱状图问题修复

需求说明

需要在Laravel Filament中使用ChartJS创建堆叠柱状图,展示每个客户的任务按优先级分组的统计情况。关联表结构如下:

Tasks表

  • ID
  • title
  • notes
  • priority
  • status
  • type
  • owner_id
  • client_id
  • created_at
  • updated_at

Clients表

  • id
  • client_name
  • city

原代码问题分析

原代码存在以下核心问题:

  1. 标签逻辑错误:array_keys(reset($data))获取的是Eloquent模型的属性名(如client_name),而非所需的客户/优先级标签。
  2. 数据集结构错误:直接遍历查询集合无法生成堆叠图所需的“按优先级分组、每个组对应所有客户任务数”的结构。
  3. 缺少堆叠配置:未开启ChartJS的堆叠模式,无法实现预期的堆叠效果。

修正后的完整代码

<?php

namespace App\Filament\Widgets;

use App\Models\Tasks;
use Filament\Widgets\ChartWidget;
use Illuminate\Support\Facades\DB;

class TasksByPriority extends ChartWidget
{
    protected static ?string $heading = 'Tasks By Priority';

    public function getDescription(): ?string
    {
        return 'Summary of tasks created by priority per client';
    }

    protected static ?string $maxHeight = '300px';
    protected static ?string $pollingInterval = null;

    protected function getData(): array
    {
        $data = Tasks::select('clients.client_name as client_name', 'tasks.priority', DB::raw('COUNT(tasks.id) as task_count'))
            ->join('clients', 'tasks.client_id', '=', 'clients.id')
            ->groupBy('clients.client_name', 'tasks.priority')
            ->orderBy('clients.client_name')
            ->orderBy('tasks.priority')
            ->get();

        // 获取所有唯一客户名称作为X轴标签
        $clients = $data->pluck('client_name')->unique()->sort()->values()->toArray();

        // 获取所有唯一优先级
        $priorities = $data->pluck('priority')->unique()->sort()->values()->toArray();

        // 优先级-颜色映射表
        $colorMap = [
            'high' => 'rgba(255, 99, 132, 0.8)',
            'medium' => 'rgba(54, 162, 235, 0.8)',
            'low' => 'rgba(255, 206, 86, 0.8)',
            'urgent' => 'rgba(75, 192, 192, 0.8)',
        ];

        $datasets = [];
        foreach ($priorities as $priority) {
            $datasetData = [];
            foreach ($clients as $client) {
                // 匹配当前客户当前优先级的任务数,无数据则填0
                $taskCount = $data->where('client_name', $client)
                    ->where('priority', $priority)
                    ->pluck('task_count')
                    ->first() ?? 0;

                $datasetData[] = $taskCount;
            }

            $datasets[] = [
                'label' => ucfirst($priority),
                'backgroundColor' => $colorMap[$priority] ?? 'rgba(153, 102, 255, 0.8)',
                'data' => $datasetData,
            ];
        }

        return [
            'datasets' => $datasets,
            'labels' => $clients,
            'options' => [
                'scales' => [
                    'x' => ['stacked' => true],
                    'y' => [
                        'stacked' => true,
                        'beginAtZero' => true,
                    ],
                ],
            ],
        ];
    }

    protected function getType(): string
    {
        return 'bar';
    }
}

关键修改说明

  1. 数据结构重构:

    • 提取唯一的客户列表作为X轴标签,确保每个数据集的长度与标签数量一致。
    • 针对每个优先级,遍历所有客户填充任务数,缺失数据补0,避免图表错位。
  2. 堆叠模式开启:

    • 在返回的options配置中,开启X轴和Y轴的stacked属性,实现柱状图堆叠效果。
  3. 视觉一致性优化:

    • 给每个优先级分配固定颜色,确保图表展示统一。

内容的提问来源于stack exchange,提问作者kgori_dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 07:41:00