PDA

View Full Version : FastGridView



jack.slocum
10 Nov 2006, 3:45 AM
Since Eric hasn't posted it, I will post it for him. :)

Here's the original thread: http://www.jackslocum.com/forum/viewtopic.php?t=424


YAHOO.ext.grid.FastGridView = function(){
YAHOO.ext.grid.FastGridView.superclass.constructor.call(this);
this.rendered = [];
};
YAHOO.extendX(YAHOO.ext.grid.FastGridView, YAHOO.ext.grid.GridView);

YAHOO.ext.grid.FastGridView.prototype.init = function(grid){
YAHOO.ext.grid.FastGridView.superclass.init.call(this, grid);
this.grid.maxRowsToMeasure = 1; // hack
this.grid.addListener('bodyscroll', this.lazyRender, this, true);
}

YAHOO.ext.grid.FastGridView.prototype.insertRows
= function(dataModel, firstRow, lastRow)
{
this.updateBodyHeight();
this.adjustForScroll(true);
var renderers = this.getColumnRenderers();
var dindexes = this.getDataIndexes();
var colCount = this.grid.colModel.getColumnCount();
var beforeRow = null;
var bt = this.getBodyTable();
if(firstRow < bt.childNodes.length){
beforeRow = bt.childNodes[firstRow];
}
if (firstRow == 0 && lastRow == dataModel.getRowCount() - 1)
{
var s = [];
var stripeRows = this.grid.stripeRows;
var stripe = false;
for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
s[s.length] = "<span class='ygrid-row";
s[s.length] = stripe && stripeRows ? ' ygrid-row-alt' : '';
s[s.length] = "' style='top:";
s[s.length] = rowIndex * this.rowHeight;
s[s.length] = "px'></span>";
this.rendered[rowIndex] = false;
stripe = !stripe;
}
bt.innerHTML = s.join("");
var rows = bt.childNodes;
for (var rowIndex = 0; rowIndex < rows.length; rowIndex++)
{
rows[rowIndex].rowIndex = rowIndex;
}
}
else
{
for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
var row = document.createElement('span');
row.className = 'ygrid-row';
row.style.top = (rowIndex * this.rowHeight) + 'px';
this.rendered[rowIndex] = false;
if(beforeRow){
bt.insertBefore(row, beforeRow);
}else{
bt.appendChild(row);
}
}
this.updateRowIndexes(firstRow);
}
this.adjustForScroll();
this.lazyRender();
};

YAHOO.ext.grid.FastGridView.prototype.lazyRender = function()
{
var indexes = this.getRowsToRender();
var rowIndex = indexes[0];
var lastRowIndex = indexes[1];
var grid = this.grid;
var dataModel = grid.getDataModel();
var colCount = grid.colModel.getColumnCount();
var renderers = this.getColumnRenderers();
var dindexes = this.getDataIndexes();
while (rowIndex <= lastRowIndex)
{
if (!this.rendered[rowIndex])
{
var row = grid.getRow(rowIndex);
this.renderRow(dataModel, row, rowIndex, colCount, renderers, dindexes);
this.rendered[rowIndex] = true;
}
++rowIndex;
}
}

YAHOO.ext.grid.FastGridView.prototype.getRowsToRender = function()
{
var y = this.wrap.scrollTop;
var rowHeight = this.getRowHeight();
var rowIndex = (y == 0 ? 0 : Math.floor(y / rowHeight));
var grid = this.grid;
var dataModel = grid.getDataModel();
var rowCount = dataModel.getRowCount();
if (rowIndex >= rowCount) { return [0, -1]; }
var numDisplayedRows = Math.ceil(this.wrap.clientHeight / rowHeight);
var lastRowIndex = Math.min(rowCount - 1, rowIndex + numDisplayedRows * 2);
return [rowIndex, lastRowIndex];
}


YAHOO.ext.grid.FastGridView.prototype.deleteRows
= function(dataModel, firstRow, lastRow)
{
this.updateBodyHeight();
// first make sure they are deselected
var bt = this.getBodyTable();

if (!this.grid.dataModel.getRowCount())
{
this.grid.selModel.clearSelections();
bt.innerHTML = "";
}
else
{
this.grid.selModel.deselectRange(firstRow, lastRow);
var rows = []; // get references because the rowIndex will change
for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
rows.push(bt.childNodes[rowIndex]);
}
for(var i = 0; i < rows.length; i++){
bt.removeChild(rows[i]);
rows[i] = null;
}
rows = null;
this.updateRowIndexes(firstRow);
this.adjustForScroll();
}
};

YAHOO.ext.grid.FastGridView.prototype.updateRows
= function(dataModel, firstRow, lastRow)
{
var bt = this.getBodyTable();
var dindexes = this.getDataIndexes();
var renderers = this.getColumnRenderers();
var grid = this.grid;
var colCount = grid.colModel.getColumnCount();
var indexes = this.getRowsToRender();
var firstRenderedRow = indexes[0];
var lastRenderedRow = indexes[1];
for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
var row = bt.rows[rowIndex];
if (rowIndex >= firstRenderedRow && rowIndex <= lastRenderedRow)
{
if (!this.rendered[rowIndex])
{
var row = grid.getRow(rowIndex);
this.renderRow(dataModel, row, rowIndex, colCount, renderers,
dindexes);
this.rendered[rowIndex] = true;
}
else
{
var cells = row.childNodes;
for(var colIndex = 0; colIndex < colCount; colIndex++){
var td = cells[colIndex];
var val = renderers[colIndex](dataModel.getValueAt(rowIndex, dindexes[colIndex]), rowIndex, colIndex);
if(typeof val == 'undefined' || val === '') val = '';
td.firstChild.innerHTML = val;
}
}
}
else
{
row.innerHTML = "";
this.rendered[rowIndex] = false;
}
}
};

ericwaldheim
20 Nov 2006, 6:49 AM
I was waiting until I made time for a demo:

http://ericwaldheim.50megs.com/viewperf.html

(If anyone can save it from its ad-filled host, that'd be great)

jack.slocum
21 Nov 2006, 4:12 AM
Does this actually create 1000 rows or share a set of rows or ?

ericwaldheim
22 Nov 2006, 7:34 AM
It creates new rows every time populate is clicked.

brian.moeskau
22 Nov 2006, 7:57 AM
Wow, that's pretty nice. Is that something that will find it's way into the library, or do we just add in this code manually if we want it?


(If anyone can save it from its ad-filled host, that'd be great)
According to the site, I won some big prize just for looking at your grid ;)

Choleriker
30 Dec 2006, 7:29 AM
(If anyone can save it from its ad-filled host, that'd be great)

do you want webspace you can use without any ad's? Let me know mb@tecbehind.de, you can get space from me i have more than enough!

mtran
8 Mar 2007, 3:41 PM
I ran into an error when trying to autosize a column. I think it's because FastGridView uses lazy rendering, so not all rows are rendered when it calculates the new column width. The bolded line in GridView.calcColumnWidth() is where it throws error:

var bt = this.getBodyTable();
var rows = bt.childNodes;
...
for(var i = 0; i < stopIndex; i++){
var cell = rows[i].childNodes[colIndex].firstChild;
maxWidth = Math.max(maxWidth, cell.scrollWidth);
}

So the work around is to simply put an if statement around those 2 lines.


for(var i = 0; i < stopIndex; i++){
if (rows[i].childNodes[colIndex] != null) {
var cell = rows[i].childNodes[colIndex].firstChild;
maxWidth = Math.max(maxWidth, cell.scrollWidth);
}
}


I left GridView.js alone and instead override calcColumnWidth in FastGridView.js.

Again, thanks for yui-ext and this awesome speed boost. The grid now loads 200 rows x 30 columns in less than 3 seconds, and it autosizes columns in reasonably fast too.

KimH
9 Mar 2007, 6:05 AM
Is this speed-boost implemented in Ext 1.0 alpha?

brian.moeskau
9 Mar 2007, 8:39 AM
If you follow the dates on this thread, this is an older piece of code that was introduced by another user under .33. I don't think this was ever officially part of yui-ext, and I'm positive that it has nothing to do with 1.0.

agajwani
24 Apr 2007, 10:08 AM
Hi Guys,
Can anybody help me out on this, I am trying to apply the same code in ext 1.0 alpha3 but the problem is that most of the properties or methods from this post is not valid in ext 1.0 alpha3, please help. I really need it.

Regards,
Abhay.

jay@moduscreate.com
24 Apr 2007, 10:54 AM
why!? alpha3 is not supported. go w/ ext 1.0 .

jay@moduscreate.com
24 Apr 2007, 10:59 AM
What a huge speed difference in the generation.

What i'm seeing problems with is the scrolling. it seems to be doing something CPU intensive. you trade off the render time for crappy scroll time. :(

Verified this w/ FF2.0 and IE6.x

i'll stick w/ the old grid :) + paging.

ganesh
24 Apr 2007, 11:13 AM
Paging grid does not support sorting on the entire data set, does it?

jay@moduscreate.com
24 Apr 2007, 11:22 AM
I'm using remote XHR and i am sorting w/ the sort and dir parameters

sort=oper
dir=ASC

nahte
18 Jun 2007, 9:52 PM
Hi everyone,

I am currently working on upgrading a web application to use the ExtJS framework. Unfortunately, I am running into the same situation where the grid component is performing very poorly due to the amount of data that my web app has to handle....and paging the data is something I cannot resort to because it would seriously hinder its usability.

I was searching the forum on grid performance issues and I came across this thread. The lazy-row-rendering in FastGridView is the perfect solution for my problem. However, I am not very familiar with Yahoo UI and its relation to ExtJS code-wise, so it is unclear to me on how I can get this piece of code to work with ExtJS (if that is even the case).

I was under the impression that this solution would require me to use YUI in conjunction with ExtJS...but Mtran posted something that looked like it was done purely in ExtJS? Could someone point me in the right direction on this issue?

Thanks in advance!