2010-11-09 25 views
6

Tôi thường không thích sử dụng các sản phẩm Excel và Microsoft nói chung, nhưng Excel 2007/2010 có một số tính năng định dạng có điều kiện rất đẹp, đáng buồn thay, tôi chưa từng thấy ở nhiều nơi khác cho đến nay. Một trong số đó tôi sử dụng rộng rãi trong các báo cáo kinh doanh là các thanh dữ liệu. http://blogs.msdn.com/b/excel/archive/2009/08/07/data-bar-improvements-in-excel-2010.aspxThanh dữ liệu trong ô trong jqGrid - có thể hay không?

Theo ý kiến ​​của tôi, các thanh dữ liệu này cực kỳ hữu ích trong việc hiểu ý nghĩa của dữ liệu vượt quá số. Mặc dù sự khác biệt giữa 200 và 2000 người dùng chỉ là một chữ số khó nắm bắt đối với mắt người, một thanh dài gấp 10 lần trực quan hơn nhiều.

Câu hỏi của tôi: Có cách nào để bao gồm các thanh dữ liệu có điều kiện trong ô cho mỗi giá trị của một cột trong jqGrid, phản ánh chức năng Excel không? Đây sẽ là cách duy nhất tôi thấy để loại bỏ các trang tính Excel của chúng tôi và triển khai các báo cáo trong một hệ thống báo cáo trực tuyến. Các thanh dữ liệu đơn giản là không thể thiếu một khi bạn quen với chúng, và chúng là lý do duy nhất chúng tôi vẫn sử dụng Excel cho các báo cáo.

Nếu, như tôi giả định, không có chức năng tích hợp như thế này trong jqGrid, bạn có nghĩ rằng sẽ có rất nhiều công việc để tùy chỉnh xây dựng nó? Bạn có ý tưởng nào về cách tốt nhất để tiếp cận điều này không?

Trả lời

9

Đây là một tính năng thú vị của Excel mà bạn đã viết trong câu hỏi của mình. Tôi chưa biết về điều này trước đây.

Điều bạn cần là triển khai hàm custom formater. Nói chung là rất dễ dàng. Bạn nên viết một hàm nhỏ hiển thị ô chứa dựa trên giá trị (văn bản trên thanh màu). Hơn nữa bạn nên xác định cũng Unformatting custom function mà sẽ rất dễ dàng trong trường hợp của bạn. Hàm không định dạng có thể được sử dụng trong quá trình phân loại và hoạt động jqGrid khác, nơi người ta cần lấy giá trị từ ô lưới.

Vì vậy, sự cố của bạn có thể bị giảm để hiển thị số trên thanh màu.

CẬP NHẬT: Tôi mặc dù một lần nữa và một lần nữa về câu hỏi của bạn vì tôi thấy rằng việc sử dụng màu sắc để tạo thành số có thể thực sự hữu ích. Vì vậy, tôi dành chút thời gian và tạo ra các mã ví dụ tương ứng mà tạo ra kết quả sau

alt text

và có thể được nhìn thấy sống here.

Nhận xét nhỏ cho mã. Tôi đã phải tạo ra một số các lớp CSS sản xuất thanh gradient trong bất kỳ trình duyệt hiện tại ngoại trừ Opera nơi lưới điện được coi là

alt text

Các lớp CSS được định nghĩa như sau:

.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; 
} 

và jqGrid mã bên trong của $(document).ready(function() {/*code*/});:

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 }); 

CẬP NHẬT: Phiên bản thực tế của bản demo là here.

+0

Cảm ơn, điều đó rất hữu ích. Tôi vẫn không chắc liệu chính xác chức năng định dạng sẽ làm gì để tạo thanh dữ liệu. –

+0

@M. Cypher: Có lẽ tôi sẽ tạo một ví dụ demo cho bạn sau này một chút. – Oleg

+0

@M. Cypher: Tôi có điều tốt cho bạn. Nhìn vào câu trả lời cập nhật của tôi. – Oleg

1

Tôi nghĩ có thể, nhưng với một chút lập kế hoạch và một vài giả định.

Giả định:

Nếu bạn có một cột số có chiều rộng cho phép nói 100px, sau đó đưa ra một quyết định trước xác định có 10 độ rộng thanh dữ liệu càng tốt. (0, 10px, 20px, .... 100px). Mỗi số này có thể được lưu lại dưới dạng hình ảnh, bạn có thể có đẹp chút dốc cuối cùng của bạn quá :)

Hãy gọi cho họ 0.png, 10.png, 20.png, .... 100.png

Bây giờ phương pháp này sẽ là một cái gì đó dọc theo những dòng:

  1. Hãy jqGrid làm việc của nó, làm cho lưới điện, vv
  2. cháy một số jQuery khi nó kết thúc chọn ra các cột mà bạn muốn các thanh dữ liệu
  3. Đối mỗi cột
  4. Đối với mỗi ô ở cột trên
  5. xem xét giá trị số và chia tỷ lệ bằng/nhân với yếu tố (có thể cần dựa trên giá trị lớn nhất trong cột) để bạn nhận được bội số từ 10 đến 0 100
  6. Lấy giá trị được chia tỷ lệ này, cho phép nói 20 và đặt 20.png làm nền cho ô này.
  7. Rửa sạch và lặp lại :)
+0

Đó chắc chắn là một khởi đầu tốt. Tuy nhiên tôi nghĩ tôi thích một giải pháp dựa trên CSS hoặc JS, vì tôi muốn sử dụng các thanh dữ liệu (1) cho các cột có độ dài khác nhau và (2) với chiều rộng pixel hoàn hảo, trái ngược với 10px-bước. Nó cũng sẽ được tốt đẹp để có thể thay đổi kích thước một cột và có các thanh dữ liệu điều chỉnh chiều rộng của họ tự động. –

+0

Tôi nghĩ rằng điều này cũng có thể đạt được, bằng cách sử dụng một logic tương tự, nhưng chèn một hình ảnh thực tế vào tế bào và thay đổi chiều rộng của nó bằng một tỷ lệ phần trăm, không phải là một đơn vị. định vị tuyệt đối/z-index sẽ được yêu cầu để đảm bảo văn bản nằm trên đầu hình ảnh của thanh dữ liệu. –

Các vấn đề liên quan