为什么在 livewire 应用程序中,chartjs 元素在数据刷新时会丢失画布属性?

问题描述 投票:0回答:1

在 laravel 10 / livewire 3 应用程序中,我根据 db 和 4 个过滤器的数据制作 Chartjs 报告。 它对我来说可以使用刀片文件:

    <div class="editor_field_block_wrapper">
        <div class="editor_field_block_device_splitter">
            <div class="w-4/12 pb-0 pl-2 md:pt-3 ">
                <label for="filterModelType" class="editor_field_block_device_label">Model type: <span
                        class="editor_form_aria_required" aria-required="true"> * </span></label>
            </div>
            <div class="p-2 w-full">
                <select wire:model.blur="filterModelType" class="editor_form_input" tabindex="20"
                        id="filterModelType">
                    <option value=""> - Select all -</option>
                    @foreach($modelTypeSelectionItems as $key=>$label)
                    <option value="{{$key}}">{{$label}}</option>
                    @endforeach
                </select>
                @error('filterModelType')
                <span class="error_text">{{$message}}</span>
                @enderror
            </div>
        </div>
    </div>

    <div class="editor_field_block_wrapper">
        <div class="editor_field_block_device_splitter">
            <div class="w-4/12 pb-0 pl-2 md:pt-3 ">
                <label for="filterDateFrom" class="editor_field_block_device_label">From date</label>
            </div>
            <div class="p-2 w-full">
                <x-inputs.datepicker id="filterDateFrom" wire:model.lazy="filterDateFrom" tabindex="20"/>
                @error('filterDateFrom') <span
                    class="editor_form_validation_error">{{ $message }}</span> @enderror
            </div>
        </div>
    </div>

    <div class="editor_field_block_wrapper">
        <div class="editor_field_block_device_splitter">
            <div class="w-4/12 pb-0 pl-2 md:pt-3 ">
                <label for="filterDateTill" class="editor_field_block_device_label">Till date</label>
            </div>
            <div class="p-2 w-full">
                <x-inputs.datepicker id="filterDateTill" wire:model.lazy="filterDateTill" tabindex="30"/>
                @error('filterDateTill') <span
                    class="editor_form_validation_error">{{ $message }}</span> @enderror
            </div>
        </div>
    </div>
</fieldset>

@if($this->totalReactionCount > 0)
    <div class="min-w-full">
            <canvas id="reactionsChartStatisticsChart" style="background: #000000"></canvas>
        </div>
        @else
        <div class="m-2 p-2 warning_text">
            {!! AppIconFacade::get(IconEnum::Warning ) !!}
            There are no data found !
        </div>
        @endif

        @assets
        <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
        @endassets

        @script
        <script>
            const ctx = document.getElementById('reactionsChartStatisticsChart');
            const reactions = $wire.reactions;
            const labels = reactions.map(item => item.action_label)
            const values = reactions.map(item => item.reaction_count)

            var chartObj = new Chart(ctx, {
                type: 'pie',
                data: {
                    labels: labels,
                    datasets: [{
                        label: '# of Reactions',
                        data: values,
                        borderWidth: 2
                    }]
                },
                options: {
                    scales: {
                        y: {
                            beginAtZero: true
                        }
                    },

                    plugins: {
                        legend: {
                            position: 'top',
                            labels: {
                                font: {
                                    size: 18
                                },
                                fontColor: 'white'
                            }
                        },
                        title: {
                            display: true,
                            text: 'Reactions by type with total quality {{ $totalReactionCount }}'
                        }
                    }
                }
            });

        </script>
        @endscript


        console.log(chartObj)
        // chartObj.update()   // IF TO UNCOMMENT - RAISED ERROR : Uncaught SyntaxError: Unexpected end of input
        // chartObj.refresh()  // IF TO UNCOMMENT - RAISED ERROR : chartObj.refresh is not a function


    </div>
</div>

当页面第一次重新加载时,我有一个有效的图表,其包装 html 元素的最大宽度:

当我更改某些过滤器参数时,数据会重新加载并且图表尺寸很小:

对于第三个过滤器,更改了reactionChartStatisticsChart元素丢失了其图表属性,并且我有黑色块:

在网络中搜索我发现了一些chartObj.update()方法,但它们对我不起作用。

我可以通过什么方式检查/修复图表?

数据源组件代码:

在ReactionsChartStatistics.php组件类中我有:

<?php

namespace App\Livewire\Admin;
use App\Enums\ReactionActionEnum;
use App\Models\Reaction;
...
class ReactionsChartStatistics extends Component
{
    public array $reactions = [];
    public int $totalReactionCount = 0;

    public function mount()
    {
        // Get data for filtering block
        $this->usersSelectionItems = User::get()->pluck('name','id')->toArray();
        $this->modelTypeSelectionItems = $this->getModelTypeSelectionItems();

        $statisticsDays = ConfigValueEnum::get(ConfigValueEnum::NEWS_REACTIONS_STATISTICS_DAYS);
        $this->filterDateFrom = Carbon::now()->addDays(-$statisticsDays)->startOfDay();
        $this->filterDateTill = Carbon::now()->endOfDay();
    }
    public function render(): View
    {

        $reactionTb = (new Reaction)->getTable();
        $this->totalReactionCount = 0;
            $this->reactions = Reaction
                ::getByCreatedAt($this->filterDateFrom, '>=')
                ->getByCreatedAt($this->filterDateTill, '<')
                ->groupBy('action')
                ->orderBy('reaction_count', 'desc')
                ->select(
                    $reactionTb . '.action',
                    DB::raw('count(' . $reactionTb . '.id) as reaction_count'))
                ->get()->toArray();
        }

        foreach ($this->reactions as $key => $reaction) {
            $this->reactions[$key]['action_label'] = ReactionActionEnum::getLabel($reaction['action']);
            $this->totalReactionCount += $reaction['reaction_count'];
        }

        return view('livewire.admin.reactions-chart-statistics')->layout('components.layouts.admin');
    }

}
javascript chart.js laravel-livewire
1个回答
0
投票

在包含图表的 中添加 wire:ignore

以防止 Livewire 更新它:

@if($this->totalReactionCount > 0)

    <div wire:ignore class="min-w-full">  {{--  HERE -- }}
© www.soinside.com 2019 - 2024. All rights reserved.