jqGrid 中的单元格数据栏 - 可能与否?

Posted

技术标签:

【中文标题】jqGrid 中的单元格数据栏 - 可能与否?【英文标题】:In-cell data bars in jqGrid - possible or not? 【发布时间】:2011-05-07 04:21:36 【问题描述】:

我一般不喜欢使用 Excel 和 Microsoft 产品,但 Excel 2007/2010 有一些非常好的条件格式功能,遗憾的是,到目前为止我还没有在其他许多地方看到这些功能。我在业务报告中广泛使用的其中之一是数据栏。 Link

在我看来,这些数据条对于理解数字之外的数据含义非常有帮助。虽然 200 和 2000 用户之间的差异只是人眼难以理解的数字,但长 10 倍的条更直观。

我的问题:有没有办法在 jqGrid 中为列的每个值包含单元格条件数据栏,以反映 Excel 功能?这将是我看到摆脱我们的 Excel 工作表并在在线报告系统中实施报告的唯一方法。一旦您习惯了数据栏,它们就变得不可或缺,它们是我们仍然使用 Excel 进行报告的唯一原因。

如果像我假设的那样,jqGrid 中没有这样的内置功能,你认为定制它会做很多工作吗?您有什么想法最好的方法是解决这个问题吗?

【问题讨论】:

【参考方案1】:

这是您在问题中所写的 Excel 的一个有趣功能。我以前不知道这件事。

您需要实现一个custom formater 函数。总的来说是很容易的。您应该编写一个小函数,根据值(颜色条上的文本)显示单元格包含的内容。此外,您还应该定义 Unformatting custom function 在您的情况下这将非常容易。在排序和其他需要从网格单元格中获取值的 jqGrid 操作期间,可以使用 unformating 函数。

因此您的问题可以简化为在彩条上显示数字。

更新:我一遍又一遍地考虑你的问题,因为我发现使用颜色来格式化数字可能真的很有帮助。所以我花了一些时间创建了相应的代码示例,产生以下结果

可以在here看到直播。

代码的小cmets。我必须创建一些 CSS 类,它们会在除 Opera 之外的任何当前浏览器中生成渐变条,其中网格被视为

CSS 类定义如下:

.cellDiv 

    left: 0px; top:5px; height:22px;
    position:relative;padding:0;margin-right:-4px;border:0;

.cellTextRight

    position:relative;
    margin-right:4px;
    text-align:right;
    float:right;

.gradient1
    /* fallback (Opera) */
    background: #008AEF;
    /* Mozilla: https://developer.mozilla.org/en/CSS/-moz-linear-gradient */
    background: -moz-linear-gradient(left, #008AEF, white);
    /* Chrome, Safari: http://webkit.org/blog/175/introducing-css-gradients/ */
    background: -webkit-gradient(linear, left top, right top, from(#008AEF), to(white));
    /* MSIE http://msdn.microsoft.com/en-us/library/ms532997(VS.85).aspx */
    filter: progid:DXImageTransform.Microsoft.Gradient(StartColorStr='#008AEF', EndColorStr='white', GradientType=1);
    /*ie8*/
    -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(StartColorStr='#008AEF', EndColorStr='white', GradientType=1)";
    position: absolute; left: -2px; top:-5px; right: 2px; height:22px; float:left;

.gradient2
    background: #63C384;
    background: -moz-linear-gradient(left, #63C384 0%, white 100%);
    background: -webkit-gradient(linear, left top, right top, from(#63C384), to(white));
    filter: progid:DXImageTransform.Microsoft.Gradient(StartColorStr='#63C384', EndColorStr='white', GradientType=1);
    -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(StartColorStr='#63C384', EndColorStr='white', GradientType=1)";
    position: absolute; left: -2px; top:-5px; right: 2px; height:22px; float:left;

还有$(document).ready(function () /*code*/);里面的jqGrid代码:

var grid = $("#list");
var gradientNumberFormat = function (cellvalue, gradientClass, minDataValue,
                                 maxDataValue, minDisplayValue, maxDisplayValue) 
    var dataAsNumber = parseFloat(cellvalue); /* parseInt(cellvalue, 10);*/
    if (dataAsNumber > maxDataValue) 
        dataAsNumber = maxDataValue;
    
    if (dataAsNumber < minDataValue) 
        dataAsNumber = minDataValue;
    
    var prozentVal = minDisplayValue+(dataAsNumber-minDataValue)*(maxDisplayValue-
                                      minDisplayValue)/(maxDataValue-minDataValue);
    return '<div class="cellDiv"><div class="'+gradientClass+'" style="width:'+
            prozentVal+'%;"></div><div class="cellTextRight">'+cellvalue +
            '</div></div>';
;
var mydata = [
     id: "1",  invdate: "2007-10-01", name: "test",  note: "note",
      amount: "200.00", tax: "10.00", total: "210.00" ,
     id: "2",  invdate: "2007-10-02", name: "test2", note: "note2",
      amount: "300.00", tax: "20.00", total: "320.00" ,
     id: "3",  invdate: "2007-09-01", name: "test3", note: "note3",
      amount: "400.00", tax: "30.00", total: "430.00" ,
     id: "4",  invdate: "2007-10-04", name: "test",  note: "note",
      amount: "200.00", tax: "10.00", total: "210.00" ,
     id: "5",  invdate: "2007-10-05", name: "test2", note: "note2",
      amount: "300.00", tax: "20.00", total: "320.00" ,
     id: "6",  invdate: "2007-09-06", name: "test3", note: "note3",
      amount: "400.00", tax: "30.00", total: "430.00" ,
     id: "7",  invdate: "2007-10-04", name: "test",  note: "note",
      amount: "200.00", tax: "10.00", total: "210.00" ,
     id: "8",  invdate: "2007-10-03", name: "test2", note: "note2",
      amount: "300.00", tax: "20.00", total: "320.00" ,
     id: "9",  invdate: "2007-09-01", name: "test3", note: "note3",
      amount: "400.00", tax: "30.00", total: "430.00" ,
     id: "10", invdate: "2007-10-01", name: "test",  note: "note",
      amount: "200.00", tax: "10.00", total: "210.00" ,
     id: "11", invdate: "2007-10-02", name: "test2", note: "note2",
      amount: "300.00", tax: "20.00", total: "320.00" ,
     id: "12", invdate: "2007-09-01", name: "test3", note: "note3",
      amount: "400.00", tax: "30.00", total: "430.00" ,
     id: "13", invdate: "2007-10-04", name: "test",  note: "note",
      amount: "200.00", tax: "10.00", total: "210.00" ,
     id: "14", invdate: "2007-10-05", name: "test2", note: "note2",
      amount: "300.00", tax: "20.00", total: "320.00" ,
     id: "15", invdate: "2007-09-06", name: "test3", note: "note3",
      amount: "400.00", tax: "30.00", total: "430.00" ,
     id: "16", invdate: "2007-10-04", name: "test",  note: "note",
      amount: "200.00", tax: "10.00", total: "210.00" ,
     id: "17", invdate: "2007-10-03", name: "test2", note: "note2",
      amount: "300.00", tax: "20.00", total: "320.00" ,
     id: "18", invdate: "2007-09-01", name: "test3", note: "note3",
      amount: "400.00", tax: "30.00", total: "430.00" 
];
grid.jqGrid(
    data: mydata,
    datatype: "local",
    colNames: ['Inv No', 'Date', 'Client', 'Amount', 'Tax', 'Total', 'Notes'],
    colModel: [
         name:'id', index:'id', key:true, width:70, align:"right", sorttype:"int",
            formatter: function (cellvalue) 
                // the number 1  will be mapped to no color bar
                // the number 18 will be mapped to the color bar with 100% filled
                return gradientNumberFormat(cellvalue, "gradient1", 1, 18, 0, 100);
            
        ,
         name:'invdate', index:'invdate', width:90, sorttype:"date" ,
         name:'name', index:'name', width:100 ,
         name:'amount', index:'amount', width:80, align:"right", sorttype:"float",
            formatter: function (cellvalue) 
                // the number 200 will be mapped to the 10% filled color bar
                // the number 400 will be mapped to the 90% filled color bar
                return gradientNumberFormat(cellvalue,"gradient2",200,400,10,90);
            
        ,
         name:'tax', index:'tax', width:80, align:"right", sorttype:"float" ,
         name:'total', index:'total', width:80, align:"right", sorttype:"float" ,
         name:'note', index:'note', width:150, sortable:false 
    ],
    pager: '#pager',
    rowNum: 10,
    rowList: [5, 10, 20, 50],
    sortname: 'id',
    sortorder: 'desc',
    viewrecords: true,
    height: "100%",
    caption: "Numbers with gradient color"
);
grid.jqGrid('navGrid', '#pager',
             add:false, edit:false, del:false, search:false, refresh:true );

更新:演示的实际版本是here。

【讨论】:

谢谢,这很有帮助。我仍然不确定格式化函数究竟会做什么来生成数据栏。 @M. Cypher:稍后我可能会为您创建一个演示示例。 @M. Cypher:我有好消息要给你。看看我更新的答案。【参考方案2】:

我认为这是可能的,但需要一点计划和一些假设。

假设:

如果您有一个宽度为 100 像素的数字列,那么请做出一个预先确定的决定,使其具有 10 种可能的数据栏宽度。 (0、10 像素、20 像素、.... 100 像素)。这些中的每一个都可以保存为图像,您也可以拥有漂亮的渐变结束位:)

我们称它们为 0.png, 10.png, 20.png, .... 100.png

现在的方法应该是这样的:

    让 jQGrid 做它的事情,渲染网格等。 在 jQuery 完成后触发一些你想要数据栏的列 对于每一列 对于上列中的每个单元格 查看数值并通过乘以一个因子来缩小/放大它(它可能需要基于列中的最大值),这样你就可以得到 0 到 100 之间的 10 的倍数 取这个缩放值,比如 20 并将 20.png 设置为此单元格的背景。 冲洗并重复 :)

【讨论】:

这当然是一个好的开始。但是我认为我更喜欢基于 CSS 或 JS 的解决方案,因为我想将数据栏 (1) 用于不同长度的列和 (2) 具有像素完美宽度,而不是 10 像素步长。能够调整列的大小并让数据栏自动调整其宽度也很好。 我认为这也可以通过使用类似的逻辑来实现,但将实际图像插入单元格并按百分比而不是单位更改其宽度。需要绝对定位/z-index 以确保文本保持在数据栏图像的顶部。

以上是关于jqGrid 中的单元格数据栏 - 可能与否?的主要内容,如果未能解决你的问题,请参考以下文章

jqGrid 单元格编辑 - 双击编辑?

jQgrid单元格编辑最后一个无法自动保存解决办法

更改 jqGrid 中的导航栏图标

jqgrid加载时获得表格中某个单元格的值怎么获取?

请问jqgrid怎么向合并后的单元格赋值?

jqgrid 不能选中行, 每次点击单元格都自动选中第一行