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

CodeIgniter中Highcharts分支筛选失效,图表空白求助

问题排查与修复

核心错误点

  • Controller层缺失关键接口与数据传递

    • index方法未将$data['branch_list']传递给视图,导致下拉框无法渲染分支选项
    • 未实现AJAX调用的branch_data接口方法,前端请求无响应
    • 原有data方法调用Model的get_data时未传参,而修改后的get_data需要分支参数,引发报错
  • Model层参数处理不当

    • get_data方法强制要求$branch参数,但原有调用场景(加载全部分支数据)无参数传入,导致执行失败
    • 未做分支参数的空值判断,无法兼容全部分支查询的场景
  • View层JS语法错误与功能缺失

    • load_branchwise_data函数参数定义错误,缺少逗号分隔参数
    • AJAX请求的语法完全混乱:url:od:"POST"、data"..."、meth:{...}都是无效写法
    • 缺少drawBranchWiseChart函数,无法接收后端数据并渲染图表
    • 初始图表加载后未处理旧实例,切换分支时可能导致DOM冲突

修正后的完整代码

1. Controller(Chart.php)

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Chart extends CI_Controller {

    public function __construct()
    {
        parent::__construct();
        $this->load->model('data');
    }

    public function index()
    {
        $data['branch_list'] = $this->data->getBranch();
        // 必须将$data传递给视图,否则分支列表无法渲染
        $this->load->view('chart', $data);
    }

    // 原有全部分支数据接口,兼容无参数场景
    public function data()
    {
        // 传null表示查询全部分支
        $data = $this->data->get_data(null);

        $category = array();
        $category['name'] = 'Branch';

        $series1 = array();
        $series1['name'] = 'Issued Quantity';

        foreach ($data as $row)
        {
            $category['data'][] = $row->branch;
            $series1['data'][] = $row->issued_qty;
        }

        $result = array();
        array_push($result,$category);
        array_push($result,$series1);

        print json_encode($result, JSON_NUMERIC_CHECK);
    }

    // 新增分支筛选数据接口
    public function branch_data()
    {
        if ($this->input->post('branch')) {
            $branch = $this->input->post('branch');
            $data = $this->data->get_data($branch);

            $category = array();
            $category['name'] = 'Item'; // 筛选单分支时,X轴显示物品名称更合理
            $series1 = array();
            $series1['name'] = 'Issued Quantity';

            foreach ($data as $row)
            {
                $category['data'][] = $row->item;
                $series1['data'][] = $row->issued_qty;
            }

            $result = array();
            array_push($result,$category);
            array_push($result,$series1);

            print json_encode($result, JSON_NUMERIC_CHECK);
        } else {
            echo json_encode(array());
        }
    }
}

2. Model(Data.php)

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Data extends CI_Model {

    function __construct()
    {
        parent::__construct();
    }

    // 给$branch参数设置默认值,兼容全部分支查询
    function get_data($branch = null)
    {    
         $this->db->select('sur.update_stock_id, sus.branch_id, sus.request_no, sus.billed_date, 
         store_branch.branch_name AS branch,
         si.item_id, si.item_name AS item,  tf.avqty,   sur.r_qty as r_qty, sur.ap_qty as ap_qty, 
         tf1.issued_qty');
         $this->db->from('store_update_request sur');
         $this->db->join('store_update_stock sus', 'sus.update_stock_id=sur.update_stock_id', 'left');      
         $this->db->join('store_branch', 'sus.branch_id=store_branch.branch_id', 'left');
         $this->db->join('store_item si', 'sur.item=si.item_id', 'left');       
         
         $this->db->join('(select update_stock_id, item, is_qty AS issued_qty 
             from store_update_issue            
             where store_update_issue.status=1 
             ) AS tf1', 
             'si.item_id=tf1.item AND sur.update_stock_id = tf1.update_stock_id','left' );
                     
         $this->db->join('(select item, sum(qty)  AS avqty 
             from store_update_stock_details            
             where store_update_stock_details.status=1 
             group by item) AS tf', 'si.item_id=tf.item', 'left');
         $this->db->where('sus.status', 1);     
         
         // 仅当$branch不为空时,添加分支筛选条件
         if ($branch !== null) {
             $this->db->where('store_branch.branch_id', $branch);
         }
         
         $query = $this->db->get();
         if ($query->num_rows() > 0) {
             return $query->result();
         }
         return array(); // 返回空数组而非false,避免foreach报错
    }

    function getBranch()
    {
        $this->db->select('branch_id, branch_name');
        $this->db->from('store_branch');        
        $this->db->order_by('branch_id', 'ASC');
        return $this->db->get();
    } 
}

3. View(chart.php)

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type='text/javascript' src='<?php echo base_url(); ?>assets/js/highcharts.js'></script>
<script type='text/javascript' src='<?php echo base_url(); ?>assets/js/exporting.js'></script>

<!-- 分支筛选下拉框 -->
<div class="row">
    <div class="col-md-6">
        <div class="col-md-3">
            <select name="branch" id="branch" class="form-control">
                <option value="">Select Branch</option>
                <?php
                foreach ($branch_list->result_array() as $row) {
                    echo '<option value="' . $row["branch_id"] . '">' . $row["branch_name"] . '</option>';
                }
                ?>
            </select>
        </div>
    </div>
</div>

<a href="<?= site_url('welcome') ?>"> <input type="button" class="btn btn-warning" value="Back to Home"></a>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto;"></div>

<script type="text/javascript">
    var chart; // 全局存储图表实例,方便后续更新或销毁

    $(document).ready(function() {
        // 初始化加载全部分支图表
        load_initial_chart();

        // 分支选择事件
        $('#branch').change(function(){
            var branch = $(this).val();
            if(branch != '')
            {
                load_branchwise_data(branch, 'Item Issuing Summary - ');
            } else {
                // 选择"Select Branch"时重新加载全部分支图表
                load_initial_chart();
            }
        });
    });

    // 加载初始全部分支图表
    function load_initial_chart() {
        var options = {
            chart: {
                renderTo: 'container',
                type: 'line',
                marginRight: 130,
                marginBottom: 25
            },
            title: {
                text: 'Stationary / Consumables Issuing Status',
                x: -20 //center
            },
            subtitle: {
                text: '',
                x: -20
            },
            xAxis: {
                categories: []
            },
            yAxis: {
                title: {
                    text: 'Qty'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                formatter: function() {
                    return '<b>' + this.series.name + '</b><br/>' +
                        this.x + ': ' + this.y;
                }
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'top',
                x: -10,
                y: 100,
                borderWidth: 0
            },
            series: []
        };

        $.getJSON("<?= site_url('chart/data') ?>", function(json) {
            options.xAxis.categories = json[0]['data'];
            options.series[0] = json[1];
            
            // 销毁旧图表实例(如果存在)
            if (chart) {
                chart.destroy();
            }
            chart = new Highcharts.Chart(options);
        });
    }

    // 加载指定分支的图表数据
    function load_branchwise_data(branch, title) {
        var temp_title = title + branch;
        $.ajax({
            url: "<?= site_url('chart/branch_data') ?>",
            method: "POST",
            data: {branch: branch},
            dataType: "JSON",
            success:function(data) {
                drawBranchWiseChart(data, temp_title);
            },
            error: function() {
                alert('加载数据失败,请重试');
            }
        });
    }

    // 渲染分支专属图表
    function drawBranchWiseChart(data, chartTitle) {
        var options = {
            chart: {
                renderTo: 'container',
                type: 'line',
                marginRight: 130,
                marginBottom: 25
            },
            title: {
                text: chartTitle,
                x: -20 //center
            },
            subtitle: {
                text: '',
                x: -20
            },
            xAxis: {
                categories: data[0] ? data[0]['data'] : []
            },
            yAxis: {
                title: {
                    text: 'Qty'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                formatter: function() {
                    return '<b>' + this.series.name + '</b><br/>' +
                        this.x + ': ' + this.y;
                }
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'top',
                x: -10,
                y: 100,
                borderWidth: 0
            },
            series: data[1] ? [data[1]] : []
        };

        // 销毁旧图表实例
        if (chart) {
            chart.destroy();
        }
        chart = new Highcharts.Chart(options);
    }
</script>

额外说明

  • 筛选单分支时,X轴从"分支名称"改为"物品名称",更符合业务逻辑(单分支下展示各物品的发放量)
  • 增加了AJAX错误处理,方便排查请求失败问题
  • 全局维护chart实例,避免重复创建图表导致的DOM冲突
  • Model的get_data方法返回空数组而非false,避免前端foreach循环报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:12:33