2010-11-09 2 views
6

Мне вообще не нравится использование продуктов Excel и Microsoft в целом, но Excel 2007/2010 имеет некоторые очень приятные условные функции форматирования, которые, к сожалению, я еще не видел во многих других местах. Один из них, который я широко использую в бизнес-отчетах, - это бары данных. http://blogs.msdn.com/b/excel/archive/2009/08/07/data-bar-improvements-in-excel-2010.aspxВ ячейках данных в jqGrid - возможно или нет?

На мой взгляд, эти бары данных чрезвычайно полезны в понимании значения данных за пределами чисел. В то время как разница между 200 и 2000 пользователями - это всего лишь сложная цифра для человеческого глаза, бар, который в 10 раз длиннее, гораздо более интуитивно понятен.

Мой вопрос: Можно ли включить в ячейку условных баров данных для каждого значения столбца в jqGrid, зеркалируя функциональность Excel? Это было бы единственным способом избавиться от наших листов Excel и реализовать отчеты в онлайн-системе отчетности. Базы данных просто необходимы, как только вы привыкаете к ним, и это единственная причина, по которой мы все еще используем Excel для отчетов.

Если, как я полагаю, в jqGrid нет встроенных функций, подобных этому, как вы думаете, будет ли это большой объем работы по его созданию? Есть ли у вас какие-нибудь идеи, как наилучшим образом подходит подход к этому?

ответ

9

Это интересная особенность Excel, о котором вы писали в вашем вопросе. Об этом я раньше не знал.

Что нужно для реализации функции custom formater. В общем, это очень легко. Вы должны написать небольшую функцию, которая отображает ячейку, содержащуюся на основе значения (текст над полосой цвета). Кроме того, вы должны определить также Unformatting custom function, который будет очень простым в вашем случае. Функция форматирования может использоваться во время сортировки и другой операции jqGrid, где нужно получить значение из ячейки сетки.

Таким образом, ваша проблема может быть уменьшена до отображения номера над цветовой полосой.

ОБНОВЛЕНО: Я снова и снова о вашем вопросе, потому что считаю, что использование цветов для формирования чисел может быть действительно полезным. Так я провожу некоторое время и создал соответствующий пример кода, который производит следующие результаты

alt text

и можно увидеть вживую here.

Небольшие комментарии к коду. Я должен был создать некоторые классы CSS, которые производят градиент бар в любых современных браузерах исключая Opera, где сетки рассматриваются как

alt text

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

и jqGrid код внутри $(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 }); 

ОБНОВЛЕНО: Актуализированная версия демо - here.

+0

Спасибо, это полезно. Я все еще не уверен, что именно функция форматирования будет делать для создания панели данных. –

+0

@M. Cypher: Вероятно, я создам демонстрационный пример для вас чуть позже. – Oleg

+0

@M. Cypher: У меня к вам новое новое. Посмотрите мой обновленный ответ. – Oleg

1

Я думаю, что это возможно, но с небольшим планированием и несколькими предположениями.

Предположение:

Если у вас есть числовой столбец с шириной 100px позволяет сказать, то сделать заранее определенное решение, чтобы иметь 10 возможной штриховые данные ширины. (0, 10px, 20px, .... 100px). Каждый из них может быть сохранен в виде изображений, Вы можете иметь свой хороший конечный градиент немного тоже :)

Назовём их 0.png, 10.png, 20.png, .... 100.png

Сейчас этот подход будет что-то вдоль этих линий:

  1. Пусть jQGrid делать свое дело, делают сетку и т.д.
  2. Огонь некоторые JQuery однажды законченную выбрать столбцы, где вы хотите гистограмм
  3. Для каждая колонка
  4. Для каждой ячейки в колонке выше
  5. Посмотрите на числовое значение и уменьшите его вверх/вверх, умножив его на коэффициент (возможно, оно должно быть основано на наибольшем значении в столбце), поэтому вы получите кратное 10 между 0 и 100
  6. Возьмите это масштабированное значение, скажем 20 и установите 20.png в качестве фона для этой ячейки.
  7. полоскание и повторить :)
+0

Это, безусловно, хорошее начало. Однако я думаю, что я предпочел бы решение на основе CSS или JS, так как я хотел бы использовать строки данных (1) для столбцов различной длины и (2) с идеальной шириной пикселя, а не 10px-шагов. Также было бы неплохо иметь возможность изменять размер столбца и автоматически настраивать их ширину. –

+0

Я думаю, что это также может быть достигнуто, используя аналогичную логику, но вставляя фактическое изображение в ячейку и изменяя ее ширину на процент, а не единицу. абсолютное позиционирование/z-index потребуется для обеспечения того, чтобы текст находился поверх изображения панели данных. –