返回

Highcharts数据筛选:CodeIgniter实战问题解决

mysql

Highcharts 数据筛选:CodeIgniter 实战中的问题与解决

直接说问题吧,就是在使用 Highcharts 结合 CodeIgniter 框架展示 MySQL 数据表中的出库数据时,需要按商品 (item) 对图表进行筛选。虽然代码已经有了雏形,但是下拉列表无法正常显示商品,而且筛选功能也没法使用。

问题根源分析

问题的源头主要集中在几个地方:

  1. 数据获取流程有误: 前端 JavaScript 没有在 select 选项变化的时候发送新的请求获取对应商品的数据. 控制器里只是初始页面的时候,加载所有item,没有针对item的查询方法。
  2. Model 层方法名不匹配: Controller 中调用的是 $this->data->get_issued_data(),但是 Model 中缺少参数。
  3. SQL 查询逻辑: 模型中get_issued_data 的 SQL 查询,逻辑和预想的可能不太一致。
  4. View层没有处理筛选的逻辑: 前端没有发送ajax请求获取数据。
  5. $this->data->fetch_item();获取数据方法不存在。

解决方案

咱们一步一步来解决这些问题。下面是具体的步骤:

1. 完善 Controller 的功能

原理:

  • index() 方法: 除了加载视图外,还要获取所有可供筛选的商品列表。
  • data() 方法:需要接收来自前端的商品 ID (item_id),根据这个 ID 来查询对应的数据,然后以 JSON 格式返回。

代码示例 (Chart_issue.php):

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

class Chart_issue extends CI_Controller {

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

    public function index()
    {
        $data['item_list'] = $this->data->fetch_item(); // 获取所有商品列表
        $this->load->view('charts/chart_issue', $data);
    }

    public function data()
    {
        $item_id = $this->input->post('item_id'); // 获取前端传来的 item_id

        if ($item_id) {
            $data = $this->data->get_issued_data($item_id); // 传入 item_id

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

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

            $series2 = array();
            $series2['name'] = 'Date';

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

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

            print json_encode($result, JSON_NUMERIC_CHECK);
        }
    }
}

2. 修改 Model 中的方法

原理:

  • get_issued_data($id): 现在接收 $id 参数,用来进行 WHERE 条件的过滤。

代码示例 (Data.php):

<?php
// Data.php

class Data extends CI_Model {

    function get_issued_data($id)
    {
        $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(array('sus.status' => 1 )); //原先是 store_item.item_id,现改为传入参数。
        $this->db->where('si.item_id', $id); // 增加商品ID过滤条件

    $query = $this->db->get();
        if ($query->num_rows() > 0) {
            return $query->result();
        }
        return false;
    }

    //新增方法: 获取item 列表。
    function fetch_item()
    {
        $this->db->select('item_id, item_name');
        $this->db->from('store_item');
        $query = $this->db->get();
        return $query;
    }

}

3. 更新 View 中的 JavaScript 代码

原理:

  • 添加事件监听: 给下拉列表 (#item) 添加 change 事件监听,当选项改变时,触发数据获取操作。
  • 发送 AJAX 请求: 使用 jQuery 的 $.post() 方法向服务器发送请求, 并带上新的item_id.
  • 更新图表: 服务器响应后,用新的数据更新 Highcharts 图表。

代码示例 (chart_issue.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>

<script type="text/javascript">
$(document).ready(function() {
    var options = {
        chart: {
            renderTo: 'container',
            type: 'line',
            marginRight: 130,
            marginBottom: 25
        },
        title: {
            text: 'Item Issued Summary',
            x: -20 //center
        },
        subtitle: {
            text: '',
            x: -20
        },
        xAxis: {
            categories: ['']
        },
        yAxis: [{
            title: {
                text: 'Issues'
            },
            plotLines: [{
                value: 0,
                width: 1,
                color: '#808080'
            }]
        },

        ],

        tooltip: {
            formatter: function() {
                return '<b>'+ this.series.name +'</b>'+
                this.x +': '+ this.y;
            }
        },

        legend: {
            layout: 'vertical',
            align: 'right',
            verticalAlign: 'top',
            x: -10,
            y: 100,
            borderWidth: 0
        },
        plotOptions: {
             column: {
                dataLabels: {
                    enabled: true
                }
            }
        },
        series: []
    };

     // 初始加载图表(可选,可以先加载一个默认的图表)

     // 下拉列表改变事件
    $('#item').change(function() {
        var item_id = $(this).val(); // 获取选中的 item_id

        if (item_id != '') {
            // 发送 AJAX 请求
            $.post("<?php echo site_url('chart_issue/data'); ?>", { item_id: item_id }, function(json) {
                options.xAxis.categories = json[0]['data'];
                options.series[0] = json[1];
                options.series[1] = json[2];
                chart = new Highcharts.Chart(options); // 重新创建图表
            }, 'json');
        } else
        {
            // 这里增加处理item_id为空的情况, 比如清空图表, 显示提示等.
             options.xAxis.categories = ['']; //比如清空x轴数据.
             options.series = [];  //清空数据
            chart = new Highcharts.Chart(options);  // 重绘.
        }
    });
     // 手动触发一次 change 事件,用于页面加载时首次显示图表, 避免初始图表空白.
      $('#item').trigger('change');


});
</script>

<a href="<?= site_url('welcome') ?>"> <input type="button" class="btn btn-warning" value="Back to Home"></a>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Item Issued Data</
                    
<body>
   
<div class="col-md-3">
    <select name="item" id="item" class="form-control">
        <option value="">Select Item</option>
    <?php
    foreach($item_list->result_array() as $row)
    {
        echo '<option value="'.$row["item_id"].'">'.$row["item_name"].'</option>';
    }
    ?>
    </select>
</div>

<div id="container" style="min-width: 400px; height: 500px; margin: 0 auto;"></div>
</body>

进阶使用技巧:

  • 加载指示器: 在 AJAX 请求过程中,可以在图表区域显示一个加载动画(如旋转的图标),提升用户体验。在$.post前显示, 在数据返回后,隐藏.
  • 错误处理: 在 AJAX 请求的 error 回调函数中处理请求失败的情况,比如给用户一个提示。
  • 数据缓存: 如果数据不经常变化,可以考虑在前端使用 JavaScript 变量缓存已经获取过的数据, 避免重复请求,提高效率。
  • 图表初始状态 可以在没有选择任何item的时候, 展示一个总体的图表数据. 可以创建一个新的方法,获取所有数据.

经过这些改动,下拉菜单就能显示商品列表,也能根据选择展示对应的数据图表,实现了 Highcharts 的数据筛选功能.