1. 设置固定列
<table id="reportGrid"> <!-- 表头 --> <thead> <tr> <th propName="reportId" floor="1">ID</th> <th propName="pointDate" floor="1" valCalc="formatDate">日期</th> <th propName="weekday" floor="1" valCalc="convertToWeekDay">星期</th> </tr> </thead> <!-- 数据 --> <tbody></tbody> </table>
propName -- 属性名
valCalc -- 设置值时, 特定回调函数
2. 动态生成可变列
这里模拟服务器获取数据
// 返回数据的格式: /* { points : Array, pointDate : Date, reportId : Number, reportDatas : Map } */ function getDate(date) { var datas = []; for (var i = 0; i < 5; i++) { var reportDatas = {}; reportDatas['1002'] = {reportVal:rd(203), reportTotal:203}; reportDatas['1003'] = {reportVal:rd(204), reportTotal:204}; reportDatas['1007'] = {reportVal:rd(205), reportTotal:205}; reportDatas['2003'] = {reportVal:rd(206), reportTotal:206}; reportDatas['2007'] = {reportVal:rd(207), reportTotal:207}; datas[i] = { reportId : 1000 - i, titles : ['1002', '1003', '1007', '2003', '2007'], pointDate : date.addDays(0 - i), reportDatas : reportDatas } }; return datas; }
Ps :
通常开发顺序是: 先设计前端UI, 再根据需要的数据项生成对应的 JSON 对象
这里生成剩余的表头信息
// 生成需要的表头信息 function initTitles(grid, titles) { var map = {}; // 留存数据 map["1002"] = "次日留存"; map["1003"] = "三日留存"; map["1007"] = "七日留存"; map["10015"] = "十五日留存"; // 保留数据 map["2003"] = "三日保留"; map["2007"] = "七日保留"; // 找到表头区域 var heads = grid.find("thead").find("tr"); $.each(titles, function(idx, val) { var title = $("<th />", { typeVal : val, html : map[val], floor : "2" }).appendTo(heads); }); }
3. 填充数据
// 填充数据 function fillDatas(grid, datas) { // 获取表头 var heads = grid.find("thead>tr>th"); // 填充值 var tbody = grid.find("tbody"); $.each(datas, function(dIdx, data) { // 每次循环数据数组, 得到一个新的行对象 var tr = $("<tr />").appendTo(tbody); $.each(heads, function(idx, head) { head = $(head); var floor = parseInt(head.attr("floor")); fillData(floor, grid, data, head).appendTo(tr); }); }); }
下面是填充单行数据时需要用到的回调函数
function fillData(floor, grid, data, head) { switch(floor) { // 一级属性 case 1 : // 获取一级属性值 var val = data[head.attr("propName")]; // 调用处理函数 var fn = head.attr("valCalc"); fn && (val = eval(fn)(data)); // 追加到数据区域 var td = $("<td />", { html : val }); return td; // 二级属性 case 2 : var td = $("<td />", { html : getPercent(head, data) }).css({ "text-align" : "right" }); return td; default : window.console && console.log("无匹配的floor值:" + floor); } }
如果对应的 floor 值为 1, 则表示可直接获取当前属性值. 否则需要解析后才能获取值(假设当前仅有两种属性层次定义), 作者当前需求很简单, 仅仅获取百分比
// 获取二级属性指定值 -- function getPercent(head, data) { var typeVal = head.attr("typeVal"); var thisData = data.reportDatas[typeVal]; var percent = thisData.reportVal / thisData.reportTotal * 10000; var val = parseInt(percent) / 100 + ""; var idx = val.lastIndexOf("."); if (idx == -1) { val += "."; idx = val.lastIndexOf("."); } if (idx == val.length - 1) { val += "00"; } return val + "%"; }
运行效果如图, 关于下面图表部分, 请参阅 HighCharts 文档