2010-11-09 5 views
6

Generalnie nie lubię używać ogólnie produktów Excel i Microsoft, ale Excel 2007/2010 ma kilka bardzo dobrych funkcji warunkowego formatowania, których niestety nie widziałem w wielu innych miejscach. Jedną z nich, którą szeroko stosuję w raportach biznesowych, są paski danych. http://blogs.msdn.com/b/excel/archive/2009/08/07/data-bar-improvements-in-excel-2010.aspxPaski danych w komórce w jqGrid - możliwe czy nie?

Moim zdaniem te paski danych są niezwykle pomocne w zrozumieniu znaczenia danych poza liczbami. Podczas gdy różnica między 200 a 2000 użytkownikami jest po prostu trudną do uchwycenia cyfrą dla ludzkiego oka, pasek, który jest 10 razy dłuższy, jest znacznie bardziej intuicyjny.

Moje pytanie: czy istnieje sposób włączenia słupków danych warunkowych w komórce dla każdej wartości kolumny w jqGrid, dublowania funkcji programu Excel? Byłby to jedyny sposób, w jaki można pozbyć się arkuszy Excela i wdrożyć raporty w internetowym systemie raportowania. Paski danych są po prostu niezbędne, gdy się do nich przyzwyczaisz, i to jest jedyny powód, dla którego nadal używamy Excela do raportów.

Jeśli, jak przypuszczam, nie ma wbudowanej funkcji takiej jak ta w jqGrid, czy myślisz, że byłoby dużo pracy, aby ją zbudować niestandardowo? Czy masz jakieś pomysły na najlepszy sposób podejścia?

Odpowiedz

9

Jest to ciekawa funkcja programu Excel o którym pisał w swoim pytaniu. Nie wiedziałem o tym wcześniej.

Potrzebna jest funkcja custom formater. Na ogół jest to bardzo łatwe. Powinieneś napisać małą funkcję, która wyświetla zawartość komórki na podstawie wartości (tekst na pasku kolorów). Ponadto powinieneś zdefiniować także Unformatting custom function, która będzie bardzo łatwa w twoim przypadku. Funkcja unformating może być użyta podczas sortowania i innej operacji jqGrid, w której trzeba uzyskać wartość z komórki siatki.

Twój problem może zostać zredukowany do wyświetlania liczby na pasku kolorów.

AKTUALIZACJA: Ciągle powtarzam o twoim pytaniu, ponieważ uważam, że użycie kolorów do formowania liczb może być naprawdę pomocne. Więc poświęcić trochę czasu i stworzył odpowiedni przykład kodu, które produkują następujące wyniki

alt text

i można zobaczyć na żywo here.

Małe uwagi do kodu. Musiałem stworzyć kilka klas CSS, które produkują paskiem gradientu w jakichkolwiek aktualnych przeglądarek wyjątkiem Opery, gdzie siatka są postrzegane jako

alt text

Klasy CSS są zdefiniowane w następujący sposób:

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

i jqGrid Kod wewnątrz $(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 }); 

AKTUALIZACJA: Zaktualizowana wersja demo to here.

+0

Dzięki, to jest pomocne. Nadal nie jestem pewien, co dokładnie może zrobić funkcja formatowania, aby wygenerować pasek danych. –

+0

@M. Cypher: Prawdopodobnie dla ciebie stworzę przykład demo nieco później. – Oleg

+0

@M. Cypher: Mam dla ciebie nowe. Spójrz na moją zaktualizowaną odpowiedź. – Oleg

1

Myślę, że to możliwe, ale przy odrobinie planowania i kilku założeń.

Założenia:

Jeśli masz kolumnę numeryczną o szerokości powiedzmy, 100px, a następnie dokonać wstępnie ustaloną decyzję masz 10 możliwych szerokości pasek danych. (0, 10px, 20px, .... 100px). Każdy z nich może być zapisane jako obrazy, można mieć swój piękny końcowy gradientu trochę zbyt :)

Nazwijmy je 0.png, 10.png, 20.png, .... 100.png

teraz podejście byłoby coś wzdłuż tych linii:

  1. Let jqGrid, co robi, czyni siatkę itp
  2. Ogień niektóre jQuery po jego wykończone wyłowić kolumny gdzie chcesz bary danych
  3. Dla każda kolumna
  4. Dla każdej komórki w powyższej kolumnie
  5. spójrz na wartość liczbową i skaluj ją w dół/w górę, mnożąc ją przez współczynnik (może to być oparte na największej wartości w kolumnie), aby uzyskać wielokrotność 10 między 0 a 100
  6. Weź tę skalowaną wartość, powiedzmy 20 i ustaw 20.png jako tło dla tej komórki.
  7. spłukać i powtórzyć :)
+0

To na pewno dobry początek. Jednak myślę, że wolałbym rozwiązanie oparte na CSS lub JS, ponieważ chciałbym użyć pasków danych (1) dla kolumn o różnych długościach i (2) z szerokością idealną dla piksela, w przeciwieństwie do kroków 10px. Byłoby również miło móc zmienić rozmiar kolumny i automatycznie dopasować szerokość pasków danych. –

+0

Myślę, że można to osiągnąć, używając podobnej logiki, ale wstawiając rzeczywisty obraz do komórki i zmieniając jego szerokość o wartość procentową, a nie jednostkę. bezwzględne pozycjonowanie/indeks z-Z będzie wymagane, aby tekst pozostał na wierzchu obrazu paska danych. –