2010-11-09 18 views
6

Por lo general, no me gusta usar productos de Excel y Microsoft en general, pero Excel 2007/2010 tiene algunas características de formato condicional muy agradables que, lamentablemente, no he visto hasta ahora en muchos otros lugares. Uno de estos que utilizo extensamente en informes comerciales es barras de datos. http://blogs.msdn.com/b/excel/archive/2009/08/07/data-bar-improvements-in-excel-2010.aspxBarras de datos dentro de la celda en jqGrid - posible o no?

En mi opinión, estas barras de datos son extremadamente útiles para comprender el significado de los datos más allá de los números. Si bien la diferencia entre 200 y 2000 usuarios es solo un dígito difícil de captar para el ojo humano, una barra que es 10 veces más larga es mucho más intuitiva.

Mi pregunta: ¿Hay alguna manera de incluir barras de datos condicionales dentro de la celda para cada valor de una columna en jqGrid, reflejando la funcionalidad de Excel? Esta sería la única forma en que veo deshacernos de nuestras hojas de Excel e implementar los informes en un sistema de informes en línea. Las barras de datos son simplemente indispensables una vez que se acostumbre a ellas, y son la única razón por la que aún utilizamos Excel para informes.

Si, como supongo, no existe una funcionalidad incorporada como esta en jqGrid, ¿cree que sería mucho trabajo crearla a medida? ¿Tiene alguna idea de cuál sería la mejor manera de abordar esto?

Respuesta

9

Es una característica interesante de Excel de la que usted escribió en su pregunta. No he sabido sobre esto antes.

Lo que necesita es implementar una función custom formater. En general, es muy fácil. Debe escribir una pequeña función que muestre la celda que contiene según el valor (texto sobre la barra de color). Además debe definir también Unformatting custom function que será muy fácil en su caso. La función no formateada se podría usar durante la clasificación y otras operaciones jqGrid donde se necesita obtener el valor de la celda de la grilla.

De modo que su problema podría reducirse a mostrar el número sobre la barra de color.

ACTUALIZADO: I aunque una y otra vez acerca de su pregunta, porque me parece que el uso de colores para el formateo de números podría ser realmente útil. Así que pasar algún tiempo y ha creado el ejemplo de código correspondiente que producen resultados siguientes

alt text

y puede ser visto en vivo here.

Comentarios pequeños al código. Tenía que crear algunas clases CSS que producen barra de degradado en los navegadores actuales con excepción de Opera, donde la red se ven como

alt text

Las clases CSS se definen de la siguiente manera:

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

y la jqGrid código dentro de $(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 }); 

ACTUALIZADO: la versión actualizada de la demostración es here.

+0

Gracias, eso es útil. Todavía no estoy seguro de qué haría exactamente la función de formateo para generar la barra de datos. –

+0

@M. Cypher: Probablemente crearé un ejemplo de demostración un poco más tarde. – Oleg

+0

@M. Cypher: tengo cosas nuevas para ti. Mira mi respuesta actualizada. – Oleg

1

Creo que es posible, pero con un poco de planificación y algunas suposiciones.

Supuestos:

Si usted tiene una columna numérica con un ancho de 100 píxeles que permite decir, a continuación, hacer un pre decisión determinó que 10 posibles anchos de las barras de datos. (0, 10px, 20px, .... 100px). Cada uno de éstos se pueden guardar como imágenes, Usted puede tener su buen poco extremo gradiente también :)

Deja llamada 0.png ellos, 10.png, 20.png, .... 100.png

ahora el enfoque sería algo como lo siguiente:

  1. Let jqGrid haga su trabajo, hacer que la rejilla etc.
  2. fuego algunos jQuery vez terminada su escoger las columnas en las que desea las barras de datos
  3. Para cada columna
  4. Para cada celda en la columna de arriba
  5. observe el valor numérico y aléjelo hacia abajo/arriba multiplicándolo por un factor (puede necesitar basarse en el valor más grande de la columna) para obtener un múltiplo de 10 entre 0 y 100
  6. Tome este valor escalado, digamos 20 y establezca 20.png como fondo para esta celda.
  7. aclarar y repetir :)
+0

Sin duda es un buen comienzo. Sin embargo, creo que preferiría una solución basada en CSS o JS, ya que me gustaría utilizar las barras de datos (1) para columnas de diferentes longitudes y (2) con un ancho de píxel perfecto, en lugar de 10px-steps. También sería bueno poder cambiar el tamaño de una columna y hacer que las barras de datos ajusten su ancho automáticamente. –

+0

Creo que esto también podría lograrse, usando una lógica similar, pero insertando una imagen real en la celda y alterando su ancho en un porcentaje, no en una unidad. Se necesitaría posicionamiento absoluto/índice z para garantizar que el texto permanezca en la parte superior de la imagen de la barra de datos. –

Cuestiones relacionadas