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

Yii2:图表小部件开发中下拉框数据处理及代码完善求助

Yii2 Charts Widget: Complete Code & Dropdown Data Integration

Let's walk through fixing your incomplete ChartsWidget code first, then implement the dropdown data passing functionality step by step.

1. Complete the ChartsWidget Class

First, let's fill in the missing parts of your widget code, add proper validation for the type parameter, and finish the GetTopTen database query:

<?php

namespace app\widgets; // Adjust the namespace to match your project structure

use yii\base\Widget;
use yii\db\Connection;

class ChartsWidget extends Widget
{
    public $limit;
    public $topten;
    public $type;
    // Add a property to receive dropdown-selected filter value
    public $selectedFilter;

    public function init()
    {
        parent::init();
        
        // Set default limit if not provided
        if ($this->limit === null) {
            $this->limit = 10;
        }
        
        // Validate and restrict chart type to allowed options
        $allowedTypes = ['column', 'bar', 'line', 'pie'];
        if ($this->type === null || !in_array($this->type, $allowedTypes)) {
            $this->type = "column";
        }
        
        // Fetch top ten data, with optional filter from dropdown
        $this->topten = $this->GetTopTen();
    }

    private function GetTopTen()
    {
        /** @var Connection $connection */
        $connection = \Yii::$app->getDb();
        
        // Build query - adjust table/columns to match your actual database
        $query = $connection->createCommand()
            ->select(['id', 'item_name', 'count']) // Replace with your real columns
            ->from('your_target_table') // Replace with your table name
            ->orderBy(['count' => SORT_DESC]);
        
        // Apply dropdown filter if value exists
        if (!empty($this->selectedFilter)) {
            $query->andWhere(['category' => $this->selectedFilter]); // Adjust filter column as needed
        }
        
        // Apply limit
        $query->limit($this->limit);
        
        // Execute and return results
        return $query->queryAll();
    }

    public function run()
    {
        // Pass processed data to the widget's view file
        return $this->render('charts', [
            'toptenData' => $this->topten,
            'chartType' => $this->type,
        ]);
    }
}

2. Implement Dropdown Data Passing to the Widget

Now let's build a view that includes a dropdown filter and passes its value to the widget:

Step 1: Create the Main View (e.g., views/site/chart-dashboard.php)

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use app\widgets\ChartsWidget;

// Get selected filter from request (default to empty if not set)
$selectedFilter = Yii::$app->request->get('filter', '');
?>

<h1>Top Ten Charts Dashboard</h1>

<!-- Dropdown Filter Form -->
<?php $form = ActiveForm::begin(['method' => 'get']) ?>
    <div class="mb-3">
        <?= Html::label('Filter by Category:', null, ['class' => 'form-label']) ?>
        <?= Html::dropDownList('filter', $selectedFilter, [
            '' => 'All Categories',
            'electronics' => 'Electronics',
            'clothing' => 'Clothing',
            'homegoods' => 'Home Goods',
        ], ['class' => 'form-control']) ?>
    </div>
    <?= Html::submitButton('Apply Filter', ['class' => 'btn btn-primary']) ?>
<?php ActiveForm::end() ?>

<!-- Render the Charts Widget with dropdown value -->
<?= ChartsWidget::widget([
    'limit' => 10,
    'type' => 'column',
    'selectedFilter' => $selectedFilter,
]) ?>

Step 2: Create the Widget's Partial View (e.g., widgets/views/charts.php)

This is where you'll render the actual chart (using a library like Chart.js). Here's a basic working example:

<div class="chart-container" style="height: 400px;">
    <canvas id="topTenChart"></canvas>
</div>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const ctx = document.getElementById('topTenChart').getContext('2d');
const rawData = <?= json_encode($toptenData) ?>;

// Format data for Chart.js
const labels = rawData.map(item => item.item_name);
const values = rawData.map(item => item.count);

new Chart(ctx, {
    type: '<?= $chartType ?>',
    data: {
        labels: labels,
        datasets: [{
            label: 'Top Items by Count',
            data: values,
            backgroundColor: 'rgba(75, 192, 192, 0.2)',
            borderColor: 'rgba(75, 192, 192, 1)',
            borderWidth: 1
        }]
    },
    options: {
        responsive: true,
        scales: {
            y: {
                beginAtZero: true,
                title: {
                    display: true,
                    text: 'Count'
                }
            },
            x: {
                title: {
                    display: true,
                    text: 'Item Name'
                }
            }
        }
    }
});
</script>

Key Notes

  • Parameter Safety: We added an allowedTypes array to prevent invalid chart types from breaking the widget.
  • Filter Flexibility: The selectedFilter property lets the widget dynamically adjust its database query based on the user's dropdown selection.
  • Clean Separation: The widget uses a separate view file for chart rendering, keeping your logic organized and reusable across multiple pages.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:31:56