2010-11-09 3 views
6

Ich mag es generell nicht, Excel und Microsoft-Produkte zu verwenden, aber Excel 2007/2010 hat einige sehr schöne bedingte Formatierungsfunktionen, die ich leider an vielen anderen Orten bisher nicht gesehen habe. Eine davon, die ich in Geschäftsberichten ausführlich verwende, sind Datenleisten. http://blogs.msdn.com/b/excel/archive/2009/08/07/data-bar-improvements-in-excel-2010.aspxIn-cell Datenbalken in jqGrid - möglich oder nicht?

Meiner Meinung nach sind diese Datenbalken extrem hilfreich, um die Bedeutung von Daten jenseits der Zahlen zu verstehen. Während der Unterschied zwischen 200 und 2000 Benutzern nur eine schwer zu greifende Ziffer für das menschliche Auge ist, ist ein Balken, der 10 mal länger ist, viel intuitiver.

Meine Frage: Gibt es eine Möglichkeit, bedingte Datenbalken für jeden Wert einer Spalte in jqGrid in die Zelle einzuschließen und die Excel-Funktionalität zu spiegeln? Nur so kann ich unsere Excel-Tabellen loswerden und die Berichte in einem Online-Reporting-System implementieren. Datenleisten sind einfach unentbehrlich, sobald Sie sich daran gewöhnt haben, und sie sind der einzige Grund, warum wir Excel immer noch für Berichte verwenden.

Wenn, wie ich annehme, es in jqGrid keine eingebaute Funktionalität wie diese gibt, denken Sie, dass es viel Arbeit wäre, es kundenspezifisch zu bauen? Haben Sie Ideen, wie Sie am besten daran herangehen?

Antwort

9

Es ist ein interessantes Feature von Excel, über die Sie in Ihrer Frage geschrieben haben. Ich habe das vorher nicht gewusst.

Was Sie brauchen, ist eine custom formater Funktion zu implementieren. Im Allgemeinen ist es sehr einfach. Sie sollten eine kleine Funktion schreiben, die die Zelle basierend auf dem Wert anzeigt (Text über der Farbleiste). Außerdem sollten Sie auch Unformatting custom function definieren, was in Ihrem Fall sehr einfach ist. Die Unformatierungsfunktion könnte beim Sortieren und anderen jqGrid-Operationen verwendet werden, bei denen der Wert aus der Gitterzelle abgerufen werden muss.

So könnte Ihr Problem auf die Anzeige der Zahl über die Farbleiste reduziert werden.

AKTUALISIERT: Ich habe immer wieder über Ihre Frage, weil ich finde, dass die Verwendung von Farben für die Formatierung von Zahlen wirklich hilfreich sein könnte. So verbringe ich einige Zeit und erstellt das entsprechende Codebeispiel, die

folgende Ergebnisse produzieren

alt text

und kann live here zu sehen.

Kleine Kommentare zum Code. Ich hatte ein paar CSS-Klassen zu erstellen, die Verlaufsleiste in allen gängigen Browsern erzeugen Ausnahme Opera, wo das Gitter als

alt text

Die CSS-Klassen definiert sind wie folgt zu sehen sind:

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

und die jqGrid Code innerhalb von $(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 }); 

AKTUALISIERT: Die aktualisierte Version der Demo ist here.

+0

10 Danke, das ist hilfreich. Ich bin immer noch unsicher, was genau die Formatierungsfunktion tun würde, um die Datenleiste zu generieren. –

+0

@M. Cypher: Wahrscheinlich werde ich etwas später ein Demo-Beispiel für Sie erstellen. – Oleg

+0

@M. Cypher: Ich habe gute neue für Sie. Sehen Sie sich meine aktualisierte Antwort an. – Oleg

1

Ich denke, es ist möglich, aber mit ein wenig Planung und ein paar Annahmen.

Annahmen:

Wenn Sie eine numerische Spalte mit einer Breite von 100px sagen lässt, dann eine vorher bestimmt Entscheidung 10 möglichen Datenstrichbreiten zu haben. (0, 10px, 20px, .... 100px). Jeder von ihnen kann als Bilder gespeichert werden, können Sie haben Ihre schönen Farbverlauf Ende etwas zu :)

Lets nennen sie 0.png, 10.png, 20.png, .... 100.png

nun würde der Ansatz etwas in dieser Richtung sein:

  1. Let jqGrid nicht sein Ding, machen das Gitter usw.
  2. Feuer einige jQuery einmal seine fertigen die Spalten auswählen, wo Sie die Datenbalken wollen
  3. Für jede Spalte
  4. Für jede Zelle in der obigen Spalte
  5. betrachten Sie den numerischen Wert und skalieren Sie ihn nach unten/oben, indem Sie ihn mit einem Faktor multiplizieren (möglicherweise muss er auf dem größten Wert in der Spalte basieren), sodass Sie ein Vielfaches von 10 zwischen 0 und erhalten 100
  6. Nehmen Sie diesen skalierten Wert, sagen wir 20 und stellen Sie 20.png als Hintergrund für diese Zelle. und
  7. Rinse wiederholen :)
+0

Das ist sicherlich ein guter Anfang. im Gegensatz Aber ich denke, ich würde eine CSS oder lieber JS-basierte Lösung, da ich die Datenbalken (1) für die Spalten von unterschiedlicher Länge verwenden wollen würde und (2) mit pixelgenaue Breite, auf 10px-Schritte. Es wäre auch schön, die Größe einer Spalte ändern zu können und die Datenbalken automatisch anpassen zu lassen. –

+0

Ich denke, dies auch erreicht werden könnte, durch eine ähnliche Logik, sondern ein tatsächliches Bild in die Zelle eingefügt und seine Breite um einen Prozentsatz zu verändern, keine Einheit. absolute Positionierung/Z-Index wäre erforderlich, um sicherzustellen, dass der Text über dem Bild der Datenleiste bleibt. –