返回
Highcharts数据筛选:CodeIgniter实战问题解决
mysql
2025-03-07 04:48:03
Highcharts 数据筛选:CodeIgniter 实战中的问题与解决
直接说问题吧,就是在使用 Highcharts 结合 CodeIgniter 框架展示 MySQL 数据表中的出库数据时,需要按商品 (item) 对图表进行筛选。虽然代码已经有了雏形,但是下拉列表无法正常显示商品,而且筛选功能也没法使用。
问题根源分析
问题的源头主要集中在几个地方:
- 数据获取流程有误: 前端 JavaScript 没有在
select
选项变化的时候发送新的请求获取对应商品的数据. 控制器里只是初始页面的时候,加载所有item,没有针对item的查询方法。 - Model 层方法名不匹配: Controller 中调用的是
$this->data->get_issued_data()
,但是 Model 中缺少参数。 - SQL 查询逻辑: 模型中
get_issued_data
的 SQL 查询,逻辑和预想的可能不太一致。 - View层没有处理筛选的逻辑: 前端没有发送ajax请求获取数据。
$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>
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 的数据筛选功能.