PDA

View Full Version : FastGridView


jack.slocum
11-10-2006, 06: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
11-20-2006, 09: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
11-21-2006, 07:12 AM
Does this actually create 1000 rows or share a set of rows or ?

ericwaldheim
11-22-2006, 10:34 AM
It creates new rows every time populate is clicked.

brian.moeskau
11-22-2006, 10: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
12-30-2006, 10: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
03-08-2007, 06: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
03-09-2007, 09:05 AM
Is this speed-boost implemented in Ext 1.0 alpha?

brian.moeskau
03-09-2007, 11: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
04-24-2007, 02:08 PM
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.

jgarcia@tdg-i.com
04-24-2007, 02:54 PM
why!? alpha3 is not supported. go w/ ext 1.0 .

jgarcia@tdg-i.com
04-24-2007, 02:59 PM
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
04-24-2007, 03:13 PM
Paging grid does not support sorting on the entire data set, does it?

jgarcia@tdg-i.com
04-24-2007, 03:22 PM
I'm using remote XHR and i am sorting w/ the sort and dir parameters

sort=oper
dir=ASC

nahte
06-19-2007, 01:52 AM
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!