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

切换Program后图表消失求助(控制台可获取数据)

问题描述

默认仪表板中选择第一个Program时图表显示正常;切换至其他Program后,图表消失。控制台能成功获取对应数据,但图表无法渲染。

相关代码

Livewire组件类代码

public $program_id = "";
public $activites = [];
public $data = [];
public $budget = [];
public $documentCount = 0;

public function render()
{
    if ($this->program_id == "") {
        $program = Program::all()->first();
    } else {
        $program = Program::find($this->program_id);
    }

    if ($program) {
        $activites = $program->activities->groupBy('statut_id')->map->count();
        $statuts = Statut::whereIn('id', $activites->keys())->pluck('nom', 'id');

        $budgetProgramme = $program->budget;
        $this->documentCount = $program->documents->count();
        $budgetActivites = $program->activities->sum('budget');
        $this->budget = [
            'budget_programme' => $budgetProgramme,
            'budget_activite' => $budgetActivites,
        ];

        $this->data = [
            'cree' => $statuts->search('crée') !== false ? $activites->get($statuts->search('crée'), 0) : 0,
            'cours' => $statuts->search('en cours') !== false ? $activites->get($statuts->search('en cours'), 0) : 0,
            'finalisee' => $statuts->search('finalisée') !== false ? $activites->get($statuts->search('finalisée'), 0) : 0,
            'retard' => $statuts->search('retard') !== false ? $activites->get($statuts->search('retard'), 0) : 0,
        ];
        $this->dispatchBrowserEvent('updateChart', $this->data);
        $this->dispatchBrowserEvent('updateBudgetChart', $this->budget);

    }

    return view('livewire.programs.dashboard', [
        "programs" => Program::all(),
    ]);
}

Blade视图代码

<div>
    <div class="card">
        <div class="row">
            <div class="col-md-12">
                <h4 class="text-center"><span class="badge badge-secondary">Documents ressources total :{{$documentCount}} </span></h4>
                <hr>
                <div class="input-group input-group">
                    <span class="input-group-addon">Programme</span>
                    <select wire:model="program_id" id="program" class="form-control" required>

                        <option value="">Veuillez sélectionner le programme</option>
                        @foreach ($programs as $program)
                            <option value="{{ $program->id }}">
                                {{ $program->nom }}
                            </option>
                        @endforeach
                    </select>
                </div>

                <div class="row">
                    <div class="col-md-6">
                        <div class="chart-container" style="position: relative; height:50vh; width:100vw">
                            <canvas id="houseChart"></canvas>
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="chart-container" style="position: relative; height:40vh; width:80vw">
                            <canvas id="budgetHistogramme"></canvas>
                        </div>
                    </div>
                </div>

            </div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script>
        var houseChartCtx = document.getElementById('houseChart').getContext('2d');
        var houseChartData = {
            labels: ['Crée', 'En cours', 'Finalisé', 'En retard'],
            datasets: [{
                data: [
                    {{ $data['cree'] }},
                    {{ $data['cours'] }},
                    {{ $data['finalisee'] }},
                    {{ $data['retard'] }},
                ],
                backgroundColor: ['#3498DB', '#F39C12', '#00cc00', '#d9534f']
            }]
        };
        var myPieChart = new Chart(houseChartCtx, {
            type: 'pie',
            data: houseChartData
        });
        window.addEventListener('updateChart', data => {
            console.log(data);
            myPieChart.data.datasets[0].data = data;
            myPieChart.update();
            console.log("apres MAJ");
        });

        // section budget
        var budgetChartCtx = document.getElementById('budgetHistogramme').getContext('2d');
        var budgetChartData = {
            labels: ['Budget programme', 'Budget activités'],

            datasets: [{
                data: [
                    {{ $budget['budget_programme'] }},
                    {{ $budget['budget_activite'] }},
                ],
                backgroundColor: ['#3498DB', '#F39C12']
            }]
        };
        var budgetChart = new Chart(budgetChartCtx, {
            type: 'bar',
            data: budgetChartData
        });
        window.addEventListener('updateBudgetChart', data => {
            console.log(data);
            budgetChart.data = data;
            budgetChart.update();
            console.log("budget apres MAJ");
        });
    </script>

</div>
解决方案

问题出在前端事件监听的图表数据更新逻辑上,控制台能拿到数据但格式不符合Chart.js的要求:

  • 饼图(houseChart)更新错误
    后端dispatch的updateChart事件传递的是关联数组({cree: x, cours: y, ...}),但Chart.js的饼图data需要的是和labels顺序匹配的数组值。修改事件监听代码:

    window.addEventListener('updateChart', event => {
        const data = event.detail;
        myPieChart.data.datasets[0].data = [
            data.cree,
            data.cours,
            data.finalisee,
            data.retard
        ];
        myPieChart.update();
    });
    
  • 预算柱状图(budgetHistogramme)更新错误
    直接把后端传递的关联数组赋值给budgetChart.data会覆盖掉Chart.js需要的labels和datasets结构,只需要更新datasets里的data数组:

    window.addEventListener('updateBudgetChart', event => {
        const data = event.detail;
        budgetChart.data.datasets[0].data = [
            data.budget_programme,
            data.budget_activite
        ];
        budgetChart.update();
    });
    
  • 额外优化:避免重复渲染脚本
    Livewire每次更新都会重新渲染视图里的script,导致重复创建Chart实例和绑定事件。可以把脚本放到@push或者单独的JS文件中,或者在创建Chart前先销毁旧实例:

    // 饼图部分
    if (window.myPieChart) {
        window.myPieChart.destroy();
    }
    window.myPieChart = new Chart(houseChartCtx, {
        type: 'pie',
        data: houseChartData
    });
    
    // 预算图部分
    if (window.budgetChart) {
        window.budgetChart.destroy();
    }
    window.budgetChart = new Chart(budgetChartCtx, {
        type: 'bar',
        data: budgetChartData
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:26:01