Панели данных в ячейках в jqGrid - возможно или нет?

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

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

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

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


person M. Cypher    schedule 09.11.2010    source источник


Ответы (2)


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

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

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

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

alt text

и его можно увидеть в реальном времени здесь.

Небольшие комментарии к коду. Мне пришлось создать несколько классов 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 });

ОБНОВЛЕНО: актуализированная версия демонстрации находится здесь < / а>.

person Oleg    schedule 09.11.2010
comment
Спасибо, это полезно. Я все еще не уверен, что именно функция форматирования будет делать для создания панели данных. - person M. Cypher; 09.11.2010
comment
@M. Сайфер: Возможно, чуть позже я создам для вас демонстрационный пример. - person Oleg; 09.11.2010
comment
@M. Сайфер: У меня для тебя есть хорошая новость. Посмотрите мой обновленный ответ. - person Oleg; 13.11.2010

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

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

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

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

Теперь подход будет примерно таким:

  1. Пусть jQGrid сделает свое дело, отрендерит сетку и т. Д.
  2. Запустите jQuery, как только он закончится, выберите столбцы, в которых вы хотите, чтобы гистограммы
  3. Для каждого столбца
  4. Для каждой ячейки в столбце выше
  5. посмотрите на числовое значение и увеличьте / уменьшите его, умножив на коэффициент (возможно, он должен быть основан на наибольшем значении в столбце), чтобы вы получили число, кратное 10, от 0 до 100
  6. Возьмите это масштабированное значение, скажем 20, и установите 20.png в качестве фона для этой ячейки.
  7. Промыть и повторить :)
person Moin Zaman    schedule 09.11.2010
comment
Это определенно хорошее начало. Однако я думаю, что предпочел бы решение на основе CSS или JS, поскольку я хотел бы использовать панели данных (1) для столбцов различной длины и (2) с идеальной шириной в пикселях, а не с шагом в 10 пикселей. Также было бы неплохо иметь возможность изменять размер столбца и автоматически настраивать ширину гистограмм. - person M. Cypher; 09.11.2010
comment
Я думаю, что этого также можно достичь, используя аналогичную логику, но вставив фактическое изображение в ячейку и изменив его ширину на процент, а не на единицу. Абсолютное позиционирование / z-index потребуется, чтобы текст оставался поверх изображения панели данных. - person Moin Zaman; 10.11.2010